blob: 2386ebd4bfa75a01668b2a1cb5f597722561dd15 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "magma.h"
#include "magma_sysmem.h"
#include "magma_util/command_buffer.h"
#include "magma_util/macros.h"
#include "platform_connection.h"
#include "platform_connection_client.h"
#include "platform_handle.h"
#include "platform_port.h"
#include "platform_semaphore.h"
#include "platform_sysmem_connection.h"
#include "platform_thread.h"
#include "platform_trace.h"
#include <chrono>
#include <vector>
magma_status_t magma_create_connection(int32_t file_descriptor, magma_connection_t* connection_out)
{
uint32_t primary_channel;
uint32_t notification_channel;
if (!magma::PlatformConnectionClient::GetHandles(file_descriptor, &primary_channel,
&notification_channel))
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "couldn't get handles from file_descriptor %d",
file_descriptor);
*connection_out =
magma::PlatformConnectionClient::Create(primary_channel, notification_channel).release();
return MAGMA_STATUS_OK;
}
void magma_release_connection(magma_connection_t connection)
{
// TODO(MA-109): close the connection
delete magma::PlatformConnectionClient::cast(connection);
}
magma_status_t magma_get_error(magma_connection_t connection)
{
return magma::PlatformConnectionClient::cast(connection)->GetError();
}
magma_status_t magma_query(int fd, uint64_t id, uint64_t* value_out)
{
if (!value_out)
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "bad value_out address");
if (!magma::PlatformConnectionClient::Query(fd, id, value_out))
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR,
"magma::PlatformConnectionClient::Query failed");
DLOG("magma_query id %" PRIu64 " returned 0x%" PRIx64, id, *value_out);
return MAGMA_STATUS_OK;
}
magma_status_t magma_query_returns_buffer(int fd, uint64_t id, uint32_t* result_out)
{
if (!result_out)
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "bad result_out address");
if (!magma::PlatformConnectionClient::QueryReturnsBuffer(fd, id, result_out))
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR,
"magma::PlatformConnectionClient::QueryReturnsBuffer failed");
DLOG("magma_query_returns_buffer id %" PRIu64 " returned buffer 0x%x", id, *result_out);
return MAGMA_STATUS_OK;
}
void magma_create_context(magma_connection_t connection, uint32_t* context_id_out)
{
magma::PlatformConnectionClient::cast(connection)->CreateContext(context_id_out);
}
void magma_release_context(magma_connection_t connection, uint32_t context_id)
{
magma::PlatformConnectionClient::cast(connection)->DestroyContext(context_id);
}
magma_status_t magma_create_buffer(magma_connection_t connection, uint64_t size, uint64_t* size_out,
magma_buffer_t* buffer_out)
{
auto platform_buffer = magma::PlatformBuffer::Create(size, "magma_create_buffer");
if (!platform_buffer)
return DRET(MAGMA_STATUS_MEMORY_ERROR);
magma_status_t result =
magma::PlatformConnectionClient::cast(connection)->ImportBuffer(platform_buffer.get());
if (result != MAGMA_STATUS_OK)
return DRET(result);
*size_out = platform_buffer->size();
*buffer_out =
reinterpret_cast<magma_buffer_t>(platform_buffer.release()); // Ownership passed across abi
return MAGMA_STATUS_OK;
}
void magma_release_buffer(magma_connection_t connection, magma_buffer_t buffer)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
magma::PlatformConnectionClient::cast(connection)->ReleaseBuffer(platform_buffer->id());
delete platform_buffer;
}
magma_status_t magma_set_cache_policy(magma_buffer_t buffer, magma_cache_policy_t policy)
{
bool result = reinterpret_cast<magma::PlatformBuffer*>(buffer)->SetCachePolicy(policy);
return result ? MAGMA_STATUS_OK : MAGMA_STATUS_INTERNAL_ERROR;
}
magma_status_t magma_set_buffer_mapping_address_range(magma_buffer_t buffer, uint32_t handle)
{
auto address_range =
magma::PlatformBuffer::MappingAddressRange::Create(magma::PlatformHandle::Create(handle));
if (!address_range)
return DRET(MAGMA_STATUS_INVALID_ARGS);
magma::Status status = reinterpret_cast<magma::PlatformBuffer*>(buffer)->SetMappingAddressRange(
std::move(address_range));
return status.get();
}
uint64_t magma_get_buffer_id(magma_buffer_t buffer)
{
return reinterpret_cast<magma::PlatformBuffer*>(buffer)->id();
}
uint64_t magma_get_buffer_size(magma_buffer_t buffer)
{
return reinterpret_cast<magma::PlatformBuffer*>(buffer)->size();
}
magma_status_t magma_duplicate_handle(uint32_t buffer_handle, uint32_t* buffer_handle_out)
{
if (!magma::PlatformHandle::duplicate_handle(buffer_handle, buffer_handle_out))
return DRET(MAGMA_STATUS_INTERNAL_ERROR);
return MAGMA_STATUS_OK;
}
magma_status_t magma_release_buffer_handle(uint32_t buffer_handle)
{
if (!magma::PlatformHandle::Create(buffer_handle)) {
return DRET(MAGMA_STATUS_INTERNAL_ERROR);
}
return MAGMA_STATUS_OK;
}
uint32_t magma_get_notification_channel_handle(magma_connection_t connection)
{
return magma::PlatformConnectionClient::cast(connection)->GetNotificationChannelHandle();
}
magma_status_t magma_wait_notification_channel(magma_connection_t connection, int64_t timeout_ns)
{
return magma::PlatformConnectionClient::cast(connection)->WaitNotificationChannel(timeout_ns);
}
magma_status_t magma_read_notification_channel(magma_connection_t connection, void* buffer,
uint64_t buffer_size, uint64_t* buffer_size_out)
{
return magma::PlatformConnectionClient::cast(connection)
->ReadNotificationChannel(buffer, buffer_size, buffer_size_out);
}
magma_status_t magma_clean_cache(magma_buffer_t buffer, uint64_t offset, uint64_t size,
magma_cache_operation_t operation)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
bool invalidate;
switch (operation) {
case MAGMA_CACHE_OPERATION_CLEAN:
invalidate = false;
break;
case MAGMA_CACHE_OPERATION_CLEAN_INVALIDATE:
invalidate = true;
break;
default:
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "invalid cache operations");
}
bool result = platform_buffer->CleanCache(offset, size, invalidate);
return result ? MAGMA_STATUS_OK : MAGMA_STATUS_INTERNAL_ERROR;
}
magma_status_t magma_import(magma_connection_t connection, uint32_t buffer_handle,
magma_buffer_t* buffer_out)
{
auto platform_buffer = magma::PlatformBuffer::Import(buffer_handle);
if (!platform_buffer)
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "PlatformBuffer::Import failed");
magma_status_t result =
magma::PlatformConnectionClient::cast(connection)->ImportBuffer(platform_buffer.get());
if (result != MAGMA_STATUS_OK)
return DRET_MSG(result, "ImportBuffer failed");
*buffer_out = reinterpret_cast<magma_buffer_t>(platform_buffer.release());
return MAGMA_STATUS_OK;
}
magma_status_t magma_export(magma_connection_t connection, magma_buffer_t buffer,
uint32_t* buffer_handle_out)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
if (!platform_buffer->duplicate_handle(buffer_handle_out))
return DRET(MAGMA_STATUS_INVALID_ARGS);
return MAGMA_STATUS_OK;
}
magma_status_t magma_map(magma_connection_t connection, magma_buffer_t buffer, void** addr_out)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
if (!platform_buffer->MapCpu(addr_out))
return DRET(MAGMA_STATUS_MEMORY_ERROR);
return MAGMA_STATUS_OK;
}
magma_status_t magma_map_aligned(magma_connection_t connection, magma_buffer_t buffer,
uint64_t alignment, void** addr_out)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
if (!platform_buffer->MapCpu(addr_out, alignment))
return DRET(MAGMA_STATUS_MEMORY_ERROR);
return MAGMA_STATUS_OK;
}
magma_status_t magma_map_specific(magma_connection_t connection, magma_buffer_t buffer,
uint64_t addr, uint64_t offset, uint64_t length)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
if (!platform_buffer->MapAtCpuAddr(addr, offset, length))
return DRET(MAGMA_STATUS_MEMORY_ERROR);
return MAGMA_STATUS_OK;
}
magma_status_t magma_unmap(magma_connection_t connection, magma_buffer_t buffer)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
if (!platform_buffer->UnmapCpu())
return DRET(MAGMA_STATUS_MEMORY_ERROR);
return MAGMA_STATUS_OK;
}
void magma_map_buffer_gpu(magma_connection_t connection, magma_buffer_t buffer,
uint64_t page_offset, uint64_t page_count, uint64_t gpu_va,
uint64_t map_flags)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
uint64_t buffer_id = platform_buffer->id();
magma::PlatformConnectionClient::cast(connection)
->MapBufferGpu(buffer_id, gpu_va, page_offset, page_count, map_flags);
}
magma_status_t magma_get_buffer_cache_policy(magma_buffer_t buffer,
magma_cache_policy_t* cache_policy_out)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
return platform_buffer->GetCachePolicy(cache_policy_out);
}
magma_status_t magma_get_buffer_is_mappable(magma_buffer_t buffer, uint32_t flags,
magma_bool_t* is_mappable_out)
{
if (flags) {
return DRET(MAGMA_STATUS_INVALID_ARGS);
}
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
return platform_buffer->GetIsMappable(is_mappable_out);
}
void magma_unmap_buffer_gpu(magma_connection_t connection, magma_buffer_t buffer, uint64_t gpu_va)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
uint64_t buffer_id = platform_buffer->id();
magma::PlatformConnectionClient::cast(connection)->UnmapBufferGpu(buffer_id, gpu_va);
}
void magma_commit_buffer(magma_connection_t connection, magma_buffer_t buffer, uint64_t page_offset,
uint64_t page_count)
{
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(buffer);
uint64_t buffer_id = platform_buffer->id();
magma::PlatformConnectionClient::cast(connection)
->CommitBuffer(buffer_id, page_offset, page_count);
}
magma_status_t magma_create_command_buffer(magma_connection_t connection, uint64_t size,
magma_buffer_t* buffer_out)
{
auto platform_buffer = magma::PlatformBuffer::Create(size, "magma_command_buffer");
if (!platform_buffer)
return DRET(MAGMA_STATUS_MEMORY_ERROR);
*buffer_out =
reinterpret_cast<magma_buffer_t>(platform_buffer.release()); // Ownership passed across abi
return MAGMA_STATUS_OK;
}
void magma_release_command_buffer(magma_connection_t connection, magma_buffer_t command_buffer)
{
delete reinterpret_cast<magma::PlatformBuffer*>(command_buffer);
}
void magma_submit_command_buffer(magma_connection_t connection, magma_buffer_t command_buffer,
uint32_t context_id)
{
TRACE_DURATION("magma", "submit_command_buffer");
auto platform_buffer = reinterpret_cast<magma::PlatformBuffer*>(command_buffer);
class CommandBufferInterpreter : public magma::CommandBuffer {
public:
CommandBufferInterpreter(magma::PlatformBuffer* platform_buffer)
: platform_buffer_(platform_buffer)
{
}
magma::PlatformBuffer* platform_buffer() override { return platform_buffer_; }
private:
magma::PlatformBuffer* platform_buffer_;
};
// The CommandBufferInterpreter maps the command buffer in order to validate its contents
// and retrieve the batch buffer resource index.
// A virtualized client may have mapped the command buffer into a different vmar, so here we
// ensure to map into the root vmar.
magma::Status status = platform_buffer->SetMappingAddressRange(
magma::PlatformBuffer::MappingAddressRange::CreateDefault());
if (!status.ok()) {
DLOG("Failed to set mapping address range");
return;
}
CommandBufferInterpreter interpreter(platform_buffer);
if (!interpreter.Initialize()) {
DLOG("failed to initialize interpreter");
return;
}
uint32_t buffer_handle;
if (!platform_buffer->duplicate_handle(&buffer_handle)) {
DLOG("failed to duplicate handle");
return;
}
uint64_t ATTRIBUTE_UNUSED batch_buffer_id =
interpreter.resource(interpreter.batch_buffer_resource_index()).buffer_id();
TRACE_FLOW_BEGIN("magma", "command_buffer", batch_buffer_id);
magma::PlatformConnectionClient::cast(connection)
->ExecuteCommandBuffer(buffer_handle, context_id);
delete platform_buffer;
}
// TODO(MA-580): remove (deprecated)
void magma_execute_immediate_commands(magma_connection_t connection, uint32_t context_id,
uint64_t command_count,
magma_system_inline_command_buffer* command_buffers)
{
// magma_inline_command_buffer is just renamed magma_system_inline_command_buffer
magma::PlatformConnectionClient::cast(connection)
->ExecuteImmediateCommands(context_id, command_count,
reinterpret_cast<magma_inline_command_buffer*>(command_buffers));
}
void magma_execute_immediate_commands2(magma_connection_t connection, uint32_t context_id,
uint64_t command_count,
magma_inline_command_buffer* command_buffers)
{
magma::PlatformConnectionClient::cast(connection)
->ExecuteImmediateCommands(context_id, command_count, command_buffers);
}
magma_status_t magma_create_semaphore(magma_connection_t connection,
magma_semaphore_t* semaphore_out)
{
auto semaphore = magma::PlatformSemaphore::Create();
if (!semaphore)
return MAGMA_STATUS_MEMORY_ERROR;
uint32_t handle;
if (!semaphore->duplicate_handle(&handle))
return DRET_MSG(MAGMA_STATUS_ACCESS_DENIED, "failed to duplicate handle");
magma_status_t result = magma::PlatformConnectionClient::cast(connection)
->ImportObject(handle, magma::PlatformObject::SEMAPHORE);
if (result != MAGMA_STATUS_OK)
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "failed to ImportObject");
*semaphore_out = reinterpret_cast<magma_semaphore_t>(semaphore.release());
return MAGMA_STATUS_OK;
}
void magma_release_semaphore(magma_connection_t connection, magma_semaphore_t semaphore)
{
auto platform_semaphore = reinterpret_cast<magma::PlatformSemaphore*>(semaphore);
magma::PlatformConnectionClient::cast(connection)
->ReleaseObject(platform_semaphore->id(), magma::PlatformObject::SEMAPHORE);
delete platform_semaphore;
}
uint64_t magma_get_semaphore_id(magma_semaphore_t semaphore)
{
return reinterpret_cast<magma::PlatformSemaphore*>(semaphore)->id();
}
void magma_signal_semaphore(magma_semaphore_t semaphore)
{
reinterpret_cast<magma::PlatformSemaphore*>(semaphore)->Signal();
}
void magma_reset_semaphore(magma_semaphore_t semaphore)
{
reinterpret_cast<magma::PlatformSemaphore*>(semaphore)->Reset();
}
magma_status_t magma_wait_semaphores(const magma_semaphore_t* semaphores, uint32_t count,
uint64_t timeout_ms, magma_bool_t wait_all)
{
if (count == 1) {
if (!reinterpret_cast<magma::PlatformSemaphore*>(semaphores[0])->WaitNoReset(timeout_ms))
return MAGMA_STATUS_TIMED_OUT;
return MAGMA_STATUS_OK;
}
std::unique_ptr<magma::PlatformPort> port = magma::PlatformPort::Create();
for (uint32_t i = 0; i < count; i++) {
if (!reinterpret_cast<magma::PlatformSemaphore*>(semaphores[i])->WaitAsync(port.get()))
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "WaitAsync failed");
}
if (!wait_all) {
uint64_t key;
return port->Wait(&key, timeout_ms).get();
}
auto end_time = timeout_ms == UINT64_MAX
? std::chrono::steady_clock::time_point::max()
: std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
for (uint32_t i = 0; i < count; i++) {
uint64_t key;
auto time_remaining = std::chrono::duration_cast<std::chrono::milliseconds>(
end_time - std::chrono::steady_clock::now());
magma::Status status =
port->Wait(&key, time_remaining.count() > 0 ? time_remaining.count() : 0);
if (!status)
return status.get();
}
return MAGMA_STATUS_OK;
}
magma_status_t magma_export_semaphore(magma_connection_t connection, magma_semaphore_t semaphore,
uint32_t* semaphore_handle_out)
{
auto platform_semaphore = reinterpret_cast<magma::PlatformSemaphore*>(semaphore);
if (!platform_semaphore->duplicate_handle(semaphore_handle_out))
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "duplicate_handle failed");
return MAGMA_STATUS_OK;
}
magma_status_t magma_import_semaphore(magma_connection_t connection, uint32_t semaphore_handle,
magma_semaphore_t* semaphore_out)
{
auto platform_semaphore = magma::PlatformSemaphore::Import(semaphore_handle);
if (!platform_semaphore)
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "PlatformSemaphore::Import failed");
uint32_t handle;
if (!platform_semaphore->duplicate_handle(&handle))
return DRET_MSG(MAGMA_STATUS_ACCESS_DENIED, "failed to duplicate handle");
magma_status_t result = magma::PlatformConnectionClient::cast(connection)
->ImportObject(handle, magma::PlatformObject::SEMAPHORE);
if (result != MAGMA_STATUS_OK)
return DRET_MSG(result, "ImportObject failed: %d", result);
*semaphore_out = reinterpret_cast<magma_semaphore_t>(platform_semaphore.release());
return MAGMA_STATUS_OK;
}
magma_status_t magma_sysmem_connection_create(magma_sysmem_connection_t* connection_out)
{
auto platform_connection = magma_sysmem::PlatformSysmemConnection::Create();
if (!platform_connection) {
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Failed to create sysmem connection");
}
*connection_out = reinterpret_cast<magma_sysmem_connection_t>(platform_connection.release());
return MAGMA_STATUS_OK;
}
void magma_sysmem_connection_release(magma_sysmem_connection_t connection)
{
delete reinterpret_cast<magma_sysmem::PlatformSysmemConnection*>(connection);
}
magma_status_t magma_sysmem_allocate_buffer(magma_sysmem_connection_t connection, uint32_t flags,
uint64_t size, uint32_t* buffer_handle_out)
{
std::unique_ptr<magma::PlatformBuffer> buffer;
auto sysmem_connection = reinterpret_cast<magma_sysmem::PlatformSysmemConnection*>(connection);
magma_status_t result;
result = sysmem_connection->AllocateBuffer(flags, size, &buffer);
if (result != MAGMA_STATUS_OK) {
return DRET_MSG(result, "AllocateBuffer failed: %d", result);
}
if (!buffer->duplicate_handle(buffer_handle_out)) {
return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "duplicate_handle failed");
}
return MAGMA_STATUS_OK;
}
void magma_buffer_format_description_release(magma_buffer_format_description_t description)
{
delete reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
}
// |image_planes_out| must be an array with MAGMA_MAX_IMAGE_PLANES elements.
magma_status_t
magma_get_buffer_format_plane_info_with_size(magma_buffer_format_description_t description,
uint32_t width, uint32_t height,
magma_image_plane_t* image_planes_out)
{
if (!description) {
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Null description");
}
auto buffer_description =
reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
if (!buffer_description->GetPlanes(width, height, image_planes_out)) {
return DRET(MAGMA_STATUS_INVALID_ARGS);
}
return MAGMA_STATUS_OK;
}
magma_status_t magma_get_buffer_format_modifier(magma_buffer_format_description_t description,
magma_bool_t* has_format_modifier_out,
uint64_t* format_modifier_out)
{
if (!description) {
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Null description");
}
auto buffer_description =
reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
*has_format_modifier_out = buffer_description->has_format_modifier();
*format_modifier_out = buffer_description->format_modifier();
return MAGMA_STATUS_OK;
}
magma_status_t magma_get_buffer_coherency_domain(magma_buffer_format_description_t description,
uint32_t* coherency_domain_out)
{
if (!description) {
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Null description");
}
auto buffer_description =
reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
*coherency_domain_out = buffer_description->coherency_domain();
return MAGMA_STATUS_OK;
}
magma_status_t magma_get_buffer_count(magma_buffer_format_description_t description,
uint32_t* count_out)
{
if (!description) {
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Null description");
}
auto buffer_description =
reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
*count_out = buffer_description->count();
return MAGMA_STATUS_OK;
}
magma_status_t magma_get_buffer_is_secure(magma_buffer_format_description_t description,
magma_bool_t* is_secure_out)
{
if (!description) {
return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "Null description");
}
auto buffer_description =
reinterpret_cast<magma_sysmem::PlatformBufferDescription*>(description);
*is_secure_out = buffer_description->is_secure();
return MAGMA_STATUS_OK;
}
magma_status_t magma_buffer_collection_import(magma_sysmem_connection_t connection, uint32_t handle,
magma_buffer_collection_t* collection_out)
{
auto sysmem_connection = reinterpret_cast<magma_sysmem::PlatformSysmemConnection*>(connection);
if (!handle) {
magma::Status status = sysmem_connection->CreateBufferCollectionToken(&handle);
if (!status.ok()) {
return DRET(status.get());
}
}
std::unique_ptr<magma_sysmem::PlatformBufferCollection> buffer_collection;
magma::Status status = sysmem_connection->ImportBufferCollection(handle, &buffer_collection);
if (!status.ok())
return status.get();
*collection_out = reinterpret_cast<magma_buffer_collection_t>(buffer_collection.release());
return MAGMA_STATUS_OK;
}
void magma_buffer_collection_release(magma_sysmem_connection_t connection,
magma_buffer_collection_t collection)
{
delete reinterpret_cast<magma_sysmem::PlatformBufferCollection*>(collection);
}
magma_status_t
magma_buffer_constraints_create(magma_sysmem_connection_t connection,
const magma_buffer_format_constraints_t* buffer_constraints_in,
magma_sysmem_buffer_constraints_t* constraints_out)
{
auto sysmem_connection = reinterpret_cast<magma_sysmem::PlatformSysmemConnection*>(connection);
std::unique_ptr<magma_sysmem::PlatformBufferConstraints> buffer_constraints;
magma::Status status =
sysmem_connection->CreateBufferConstraints(buffer_constraints_in, &buffer_constraints);
if (!status.ok())
return status.get();
*constraints_out =
reinterpret_cast<magma_sysmem_buffer_constraints_t>(buffer_constraints.release());
return MAGMA_STATUS_OK;
}
magma_status_t
magma_buffer_constraints_set_format(magma_sysmem_connection_t connection,
magma_sysmem_buffer_constraints_t constraints, uint32_t index,
const magma_image_format_constraints_t* format_constraints)
{
auto buffer_constraints =
reinterpret_cast<magma_sysmem::PlatformBufferConstraints*>(constraints);
return buffer_constraints->SetImageFormatConstraints(index, format_constraints).get();
}
void magma_buffer_constraints_release(magma_sysmem_connection_t connection,
magma_sysmem_buffer_constraints_t constraints)
{
delete reinterpret_cast<magma_sysmem::PlatformBufferConstraints*>(constraints);
}
magma_status_t
magma_buffer_collection_set_constraints(magma_sysmem_connection_t connection,
magma_buffer_collection_t collection,
magma_sysmem_buffer_constraints_t constraints)
{
auto buffer_collection = reinterpret_cast<magma_sysmem::PlatformBufferCollection*>(collection);
auto buffer_constraints =
reinterpret_cast<magma_sysmem::PlatformBufferConstraints*>(constraints);
return buffer_collection->SetConstraints(buffer_constraints).get();
}
magma_status_t
magma_get_buffer_format_description(const void* image_data, uint64_t image_data_size,
magma_buffer_format_description_t* description_out)
{
std::unique_ptr<magma_sysmem::PlatformBufferDescription> description;
magma_status_t status = magma_sysmem::PlatformSysmemConnection::DecodeBufferDescription(
static_cast<const uint8_t*>(image_data), image_data_size, &description);
if (status != MAGMA_STATUS_OK) {
return DRET_MSG(status, "DecodePlatformBufferDescription failed: %d", status);
}
*description_out = reinterpret_cast<magma_buffer_format_description_t>(description.release());
return MAGMA_STATUS_OK;
}
magma_status_t magma_sysmem_get_description_from_collection(
magma_sysmem_connection_t connection, magma_buffer_collection_t collection,
magma_buffer_format_description_t* buffer_format_description_out)
{
auto buffer_collection = reinterpret_cast<magma_sysmem::PlatformBufferCollection*>(collection);
std::unique_ptr<magma_sysmem::PlatformBufferDescription> description;
magma::Status status = buffer_collection->GetBufferDescription(&description);
if (!status.ok()) {
return DRET_MSG(status.get(), "GetBufferDescription failed");
}
*buffer_format_description_out =
reinterpret_cast<magma_buffer_format_description_t>(description.release());
return MAGMA_STATUS_OK;
}
magma_status_t magma_sysmem_get_buffer_handle_from_collection(magma_sysmem_connection_t connection,
magma_buffer_collection_t collection,
uint32_t index,
uint32_t* buffer_handle_out,
uint32_t* vmo_offset_out)
{
auto buffer_collection = reinterpret_cast<magma_sysmem::PlatformBufferCollection*>(collection);
return buffer_collection->GetBufferHandle(index, buffer_handle_out, vmo_offset_out).get();
}