Skip to content

Commit

Permalink
encode: Init buffer after binding external memory
Browse files Browse the repository at this point in the history
  • Loading branch information
antonio-lunarg committed Dec 19, 2024
1 parent 4acfa69 commit b473716
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 3 deletions.
17 changes: 14 additions & 3 deletions framework/decode/vulkan_resource_initializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,20 @@ VulkanResourceInitializer::~VulkanResourceInitializer()
resource_allocator_->FreeMemoryDirect(staging_memory_, nullptr, staging_memory_data_);
}

device_table_->DestroySampler(device_, draw_sampler_, nullptr);
device_table_->DestroyDescriptorPool(device_, draw_pool_, nullptr);
device_table_->DestroyDescriptorSetLayout(device_, draw_set_layout_, nullptr);
if (draw_sampler_ != VK_NULL_HANDLE)
{
device_table_->DestroySampler(device_, draw_sampler_, nullptr);
}

if (draw_pool_ != VK_NULL_HANDLE)
{
device_table_->DestroyDescriptorPool(device_, draw_pool_, nullptr);
}

if (draw_set_layout_ != VK_NULL_HANDLE)
{
device_table_->DestroyDescriptorSetLayout(device_, draw_set_layout_, nullptr);
}
}

VkResult VulkanResourceInitializer::LoadData(VkDeviceSize size,
Expand Down
16 changes: 16 additions & 0 deletions framework/encode/api_capture_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,22 @@ class ApiCaptureManager
{
common_manager_->WriteFillMemoryCmd(api_family_, memory_id, offset, size, data);
}

void WriteBeginResourceInitCmd(format::HandleId device_id, uint64_t max_resource_size)
{
common_manager_->WriteBeginResourceInitCmd(api_family_, device_id, max_resource_size);
}

void WriteEndResourceInitCmd(format::HandleId device_id)
{
common_manager_->WriteEndResourceInitCmd(api_family_, device_id);
}

void WriteInitBufferCmd(format::HandleId device_id, format::HandleId buffer_id, uint64_t offset, uint64_t size, const void* data)
{
common_manager_->WriteInitBufferCmd(api_family_, device_id, buffer_id, offset, size, data);
}

void WriteCreateHeapAllocationCmd(uint64_t allocation_id, uint64_t allocation_size)
{
common_manager_->WriteCreateHeapAllocationCmd(api_family_, allocation_id, allocation_size);
Expand Down
113 changes: 113 additions & 0 deletions framework/encode/capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,119 @@ void CommonCaptureManager::WriteFillMemoryCmd(
}
}

void CommonCaptureManager::WriteBeginResourceInitCmd(format::ApiFamilyId api_family,
format::HandleId device_id,
uint64_t max_resource_size)
{
if ((capture_mode_ & kModeWrite) != kModeWrite)
{
return;
}

GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, max_resource_size);

format::BeginResourceInitCommand init_cmd;

auto thread_data = GetThreadData();
GFXRECON_ASSERT(thread_data != nullptr);

init_cmd.meta_header.block_header.type = format::BlockType::kMetaDataBlock;
init_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(init_cmd);
init_cmd.meta_header.meta_data_id =
format::MakeMetaDataId(api_family, format::MetaDataType::kBeginResourceInitCommand);
init_cmd.thread_id = thread_data->thread_id_;
init_cmd.device_id = device_id;
init_cmd.max_resource_size = max_resource_size;
init_cmd.max_copy_size = max_resource_size;

WriteToFile(&init_cmd, sizeof(init_cmd));
}

void CommonCaptureManager::WriteEndResourceInitCmd(format::ApiFamilyId api_family, format::HandleId device_id)
{
if ((capture_mode_ & kModeWrite) != kModeWrite)
{
return;
}

format::EndResourceInitCommand init_cmd;

auto thread_data = GetThreadData();
GFXRECON_ASSERT(thread_data != nullptr);

init_cmd.meta_header.block_header.type = format::BlockType::kMetaDataBlock;
init_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(init_cmd);
init_cmd.meta_header.meta_data_id =
format::MakeMetaDataId(api_family, format::MetaDataType::kEndResourceInitCommand);
init_cmd.thread_id = thread_data->thread_id_;
init_cmd.device_id = device_id;

WriteToFile(&init_cmd, sizeof(init_cmd));
}

void CommonCaptureManager::WriteInitBufferCmd(format::ApiFamilyId api_family,
format::HandleId device_id,
format::HandleId buffer_id,
uint64_t offset,
uint64_t size,
const void* data)
{
if ((capture_mode_ & kModeWrite) != kModeWrite)
{
return;
}

GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, size);

format::InitBufferCommandHeader init_cmd;
size_t header_size = sizeof(format::InitBufferCommandHeader);
const uint8_t* uncompressed_data = (static_cast<const uint8_t*>(data) + offset);
size_t uncompressed_size = static_cast<size_t>(size);

auto thread_data = GetThreadData();
assert(thread_data != nullptr);

init_cmd.meta_header.block_header.type = format::BlockType::kMetaDataBlock;
init_cmd.meta_header.meta_data_id = format::MakeMetaDataId(api_family, format::MetaDataType::kInitBufferCommand);
init_cmd.thread_id = thread_data->thread_id_;
init_cmd.device_id = device_id;
init_cmd.buffer_id = buffer_id;
init_cmd.data_size = size;

bool not_compressed = true;

if (compressor_ != nullptr)
{
size_t compressed_size =
compressor_->Compress(uncompressed_size, uncompressed_data, &thread_data->compressed_buffer_, header_size);

if ((compressed_size > 0) && (compressed_size < uncompressed_size))
{
not_compressed = false;

// We don't have a special header for compressed fill commands because the header always includes
// the uncompressed size, so we just change the type to indicate the data is compressed.
init_cmd.meta_header.block_header.type = format::BlockType::kCompressedMetaDataBlock;

// Calculate size of packet with uncompressed data size.
init_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(init_cmd) + compressed_size;

// Copy header to beginning of compressed_buffer_
util::platform::MemoryCopy(thread_data->compressed_buffer_.data(), header_size, &init_cmd, header_size);

WriteToFile(thread_data->compressed_buffer_.data(), header_size + compressed_size);
}
}

if (not_compressed)
{
// Calculate size of packet with compressed data size.
init_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(init_cmd) + uncompressed_size;

CombineAndWriteToFile({ { &init_cmd, header_size }, { uncompressed_data, uncompressed_size } });
}
}

void CommonCaptureManager::WriteCreateHeapAllocationCmd(format::ApiFamilyId api_family,
uint64_t allocation_id,
uint64_t allocation_size)
Expand Down
12 changes: 12 additions & 0 deletions framework/encode/capture_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,18 @@ class CommonCaptureManager
void WriteFillMemoryCmd(
format::ApiFamilyId api_family, format::HandleId memory_id, uint64_t offset, uint64_t size, const void* data);

void
WriteBeginResourceInitCmd(format::ApiFamilyId api_family, format::HandleId device_id, uint64_t max_resource_size);

void WriteEndResourceInitCmd(format::ApiFamilyId api_family, format::HandleId device_id);

void WriteInitBufferCmd(format::ApiFamilyId api_family,
format::HandleId device_id,
format::HandleId buffer_id,
uint64_t offset,
uint64_t size,
const void* data);

void WriteCreateHeapAllocationCmd(format::ApiFamilyId api_family, uint64_t allocation_id, uint64_t allocation_size);

void WriteToFile(const void* data, size_t size, util::FileOutputStream* file_stream = nullptr);
Expand Down
8 changes: 8 additions & 0 deletions framework/encode/vulkan_capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,14 @@ VkResult VulkanCaptureManager::OverrideAllocateMemory(VkDevice
}
}
#endif

if (auto import_memfd = graphics::vulkan_struct_get_pnext<VkImportMemoryFdInfoKHR>(pAllocateInfo_unwrapped))
{
if (import_memfd->fd >= 0)
{
memory_wrapper->imported_fd = import_memfd->fd;
}
}
}
else if (external_memory != nullptr)
{
Expand Down
33 changes: 33 additions & 0 deletions framework/encode/vulkan_capture_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,39 @@ class VulkanCaptureManager : public ApiCaptureManager
assert(state_tracker_ != nullptr);
state_tracker_->TrackBufferMemoryBinding(device, buffer, memory, memoryOffset);
}
else if (IsCaptureModeWrite() && (result == VK_SUCCESS))
{
auto* device_wrapper = vulkan_wrappers::GetWrapper<vulkan_wrappers::DeviceWrapper>(device);
auto* buffer_wrapper = vulkan_wrappers::GetWrapper<vulkan_wrappers::BufferWrapper>(buffer);
auto* memory_wrapper = vulkan_wrappers::GetWrapper<vulkan_wrappers::DeviceMemoryWrapper>(memory);

if (memory_wrapper->imported_fd >= 0)
{
// create staging buffer, bind this memory, write init buffer command
graphics::VulkanResourcesUtil resource_util(device_wrapper->handle,
device_wrapper->physical_device->handle,
device_wrapper->layer_table,
*device_wrapper->physical_device->layer_table_ref,
device_wrapper->physical_device->memory_properties);
VkResult staging_result = resource_util.CreateStagingBuffer(buffer_wrapper->size);
if (staging_result == VK_SUCCESS)
{
std::vector<uint8_t> data;
staging_result = resource_util.ReadFromBufferResource(
buffer, buffer_wrapper->size, memoryOffset, buffer_wrapper->queue_family_index, data);
if (staging_result == VK_SUCCESS)
{
WriteBeginResourceInitCmd(device_wrapper->handle_id, buffer_wrapper->size);
WriteInitBufferCmd(device_wrapper->handle_id,
buffer_wrapper->handle_id,
memoryOffset,
buffer_wrapper->size,
data.data());
WriteEndResourceInitCmd(device_wrapper->handle_id);
}
}
}
}
}

void PostProcess_vkBindBufferMemory2(VkResult result,
Expand Down
1 change: 1 addition & 0 deletions framework/encode/vulkan_handle_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ struct DeviceMemoryWrapper : public HandleWrapper<VkDeviceMemory>
uintptr_t shadow_allocation{ util::PageGuardManager::kNullShadowHandle };
AHardwareBuffer* hardware_buffer{ nullptr };
format::HandleId hardware_buffer_memory_id{ format::kNullHandleId };
int imported_fd{ -1 };

// State tracking info for memory with device addresses.
format::HandleId device_id{ format::kNullHandleId };
Expand Down

0 comments on commit b473716

Please sign in to comment.