From 1763e52898ccd8de38f9b0456d063ff82deb8852 Mon Sep 17 00:00:00 2001 From: ziga-lunarg Date: Tue, 15 Oct 2024 20:44:44 +0200 Subject: [PATCH] Add support for copying ahb without cpu read mask --- framework/decode/api_decoder.h | 2 + framework/decode/custom_ags_decoder.h | 2 + framework/decode/dx12_decoder_base.cpp | 4 +- framework/decode/dx12_decoder_base.h | 2 + framework/decode/file_processor.cpp | 79 +++ framework/decode/info_decoder.h | 2 + framework/decode/metadata_consumer_base.h | 4 +- framework/decode/metadata_json_consumer.h | 6 +- framework/decode/stat_decoder_base.h | 2 + framework/decode/vulkan_cpp_consumer_base.cpp | 2 + framework/decode/vulkan_cpp_consumer_base.h | 4 +- framework/decode/vulkan_decoder_base.cpp | 4 +- framework/decode/vulkan_decoder_base.h | 2 + .../decode/vulkan_replay_consumer_base.cpp | 591 ++++++++++++++++-- .../decode/vulkan_replay_consumer_base.h | 6 +- framework/encode/vulkan_capture_manager.cpp | 585 ++++++++++++++++- framework/encode/vulkan_capture_manager.h | 4 +- framework/encode/vulkan_handle_wrappers.h | 1 + framework/encode/vulkan_state_writer.cpp | 14 +- framework/encode/vulkan_state_writer.h | 10 +- framework/format/format.h | 87 ++- 21 files changed, 1322 insertions(+), 91 deletions(-) diff --git a/framework/decode/api_decoder.h b/framework/decode/api_decoder.h index 6fc22d846..7899591cd 100644 --- a/framework/decode/api_decoder.h +++ b/framework/decode/api_decoder.h @@ -106,6 +106,8 @@ class ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/custom_ags_decoder.h b/framework/decode/custom_ags_decoder.h index 8b59257c5..aadb57536 100644 --- a/framework/decode/custom_ags_decoder.h +++ b/framework/decode/custom_ags_decoder.h @@ -80,6 +80,8 @@ class AgsDecoder : public ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/dx12_decoder_base.cpp b/framework/decode/dx12_decoder_base.cpp index c84f9dbf7..f20636a03 100644 --- a/framework/decode/dx12_decoder_base.cpp +++ b/framework/decode/dx12_decoder_base.cpp @@ -109,6 +109,8 @@ void Dx12DecoderBase::DispatchResizeWindowCommand2( void Dx12DecoderBase::DispatchCreateHardwareBufferCommand( format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, @@ -124,7 +126,7 @@ void Dx12DecoderBase::DispatchCreateHardwareBufferCommand( for (auto consumer : consumers_) { consumer->ProcessCreateHardwareBufferCommand( - memory_id, buffer_id, format, width, height, stride, usage, layers, plane_info); + device_id, queue_id, memory_id, buffer_id, format, width, height, stride, usage, layers, plane_info); } } diff --git a/framework/decode/dx12_decoder_base.h b/framework/decode/dx12_decoder_base.h index 63b0261b2..5c9f8f5a2 100644 --- a/framework/decode/dx12_decoder_base.h +++ b/framework/decode/dx12_decoder_base.h @@ -125,6 +125,8 @@ class Dx12DecoderBase : public ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/file_processor.cpp b/framework/decode/file_processor.cpp index 304fe3bc2..a9f0c7341 100644 --- a/framework/decode/file_processor.cpp +++ b/framework/decode/file_processor.cpp @@ -973,6 +973,81 @@ bool FileProcessor::ProcessMetaData(const format::BlockHeader& block_header, for if (decoder->SupportsMetaDataId(meta_data_id)) { decoder->DispatchCreateHardwareBufferCommand(header.thread_id, + 0u, + 0u, + header.memory_id, + header.buffer_id, + header.format, + header.width, + header.height, + header.stride, + header.usage, + header.layers, + entries); + } + } + } + else + { + if (format::IsBlockCompressed(block_header.type)) + { + HandleBlockReadError(kErrorReadingCompressedBlockData, + "Failed to read create hardware buffer meta-data block"); + } + else + { + HandleBlockReadError(kErrorReadingBlockData, + "Failed to read create hardware buffer meta-data block"); + } + } + } + else + { + HandleBlockReadError(kErrorReadingBlockHeader, + "Failed to read create hardware buffer meta-data block header"); + } + } + else if (meta_data_type == format::MetaDataType::kCreateHardwareBufferCommand_deprecated2) + { + format::CreateHardwareBufferCommandHeader_deprecated2 header; + + success = ReadBytes(&header.thread_id, sizeof(header.thread_id)); + success = success && ReadBytes(&header.memory_id, sizeof(header.memory_id)); + success = success && ReadBytes(&header.buffer_id, sizeof(header.buffer_id)); + success = success && ReadBytes(&header.format, sizeof(header.format)); + success = success && ReadBytes(&header.width, sizeof(header.width)); + success = success && ReadBytes(&header.height, sizeof(header.height)); + success = success && ReadBytes(&header.stride, sizeof(header.stride)); + success = success && ReadBytes(&header.usage, sizeof(header.usage)); + success = success && ReadBytes(&header.layers, sizeof(header.layers)); + success = success && ReadBytes(&header.planes, sizeof(header.planes)); + + if (success) + { + std::vector entries; + + for (uint64_t i = 0; i < header.planes; ++i) + { + format::HardwareBufferPlaneInfo entry; + + if (!ReadBytes(&entry, sizeof(entry))) + { + success = false; + break; + } + + entries.emplace_back(std::move(entry)); + } + + if (success) + { + for (auto decoder : decoders_) + { + if (decoder->SupportsMetaDataId(meta_data_id)) + { + decoder->DispatchCreateHardwareBufferCommand(header.thread_id, + 0u, + 0u, header.memory_id, header.buffer_id, header.format, @@ -1010,6 +1085,8 @@ bool FileProcessor::ProcessMetaData(const format::BlockHeader& block_header, for format::CreateHardwareBufferCommandHeader header; success = ReadBytes(&header.thread_id, sizeof(header.thread_id)); + success = success && ReadBytes(&header.device_id, sizeof(header.device_id)); + success = success && ReadBytes(&header.queue_id, sizeof(header.queue_id)); success = success && ReadBytes(&header.memory_id, sizeof(header.memory_id)); success = success && ReadBytes(&header.buffer_id, sizeof(header.buffer_id)); success = success && ReadBytes(&header.format, sizeof(header.format)); @@ -1044,6 +1121,8 @@ bool FileProcessor::ProcessMetaData(const format::BlockHeader& block_header, for if (decoder->SupportsMetaDataId(meta_data_id)) { decoder->DispatchCreateHardwareBufferCommand(header.thread_id, + header.device_id, + header.queue_id, header.memory_id, header.buffer_id, header.format, diff --git a/framework/decode/info_decoder.h b/framework/decode/info_decoder.h index 790f699f0..cdb82b4d6 100644 --- a/framework/decode/info_decoder.h +++ b/framework/decode/info_decoder.h @@ -100,6 +100,8 @@ class InfoDecoder : public ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/metadata_consumer_base.h b/framework/decode/metadata_consumer_base.h index c3d950414..e0d27e537 100644 --- a/framework/decode/metadata_consumer_base.h +++ b/framework/decode/metadata_consumer_base.h @@ -46,7 +46,9 @@ class MetadataConsumerBase virtual void ProcessResizeWindowCommand2(format::HandleId surface_id, uint32_t width, uint32_t height, uint32_t pre_transform) {} - virtual void ProcessCreateHardwareBufferCommand(format::HandleId memory_id, + virtual void ProcessCreateHardwareBufferCommand(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, uint64_t buffer_id, uint32_t format, uint32_t width, diff --git a/framework/decode/metadata_json_consumer.h b/framework/decode/metadata_json_consumer.h index 1126f797e..e022fb926 100644 --- a/framework/decode/metadata_json_consumer.h +++ b/framework/decode/metadata_json_consumer.h @@ -121,7 +121,9 @@ class MetadataJsonConsumer : public Base } virtual void - ProcessCreateHardwareBufferCommand(format::HandleId memory_id, + ProcessCreateHardwareBufferCommand(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, uint64_t buffer_id, uint32_t format, uint32_t width, @@ -133,6 +135,8 @@ class MetadataJsonConsumer : public Base { const util::JsonOptions& json_options = GetOptions(); auto& jdata = WriteMetaCommandStart("CreateHardwareBufferCommand"); + HandleToJson(jdata["device_id"], device_id, json_options); + HandleToJson(jdata["queue_id"], queue_id, json_options); HandleToJson(jdata["memory_id"], memory_id, json_options); HandleToJson(jdata["buffer_id"], buffer_id, json_options); FieldToJson(jdata["format"], format, json_options); diff --git a/framework/decode/stat_decoder_base.h b/framework/decode/stat_decoder_base.h index ceba9c616..f4daa4553 100644 --- a/framework/decode/stat_decoder_base.h +++ b/framework/decode/stat_decoder_base.h @@ -100,6 +100,8 @@ class StatDecoderBase : public ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/vulkan_cpp_consumer_base.cpp b/framework/decode/vulkan_cpp_consumer_base.cpp index d5df045a6..5e6c52e89 100644 --- a/framework/decode/vulkan_cpp_consumer_base.cpp +++ b/framework/decode/vulkan_cpp_consumer_base.cpp @@ -3143,6 +3143,8 @@ void VulkanCppConsumerBase::ProcessResizeWindowCommand2(format::HandleId surface } void VulkanCppConsumerBase::ProcessCreateHardwareBufferCommand( + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/vulkan_cpp_consumer_base.h b/framework/decode/vulkan_cpp_consumer_base.h index dc6c7a812..adb94a24a 100644 --- a/framework/decode/vulkan_cpp_consumer_base.h +++ b/framework/decode/vulkan_cpp_consumer_base.h @@ -657,7 +657,9 @@ class VulkanCppConsumerBase : public VulkanConsumer uint32_t height, uint32_t pre_transform) override; virtual void - ProcessCreateHardwareBufferCommand(format::HandleId memory_id, + ProcessCreateHardwareBufferCommand(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, uint64_t buffer_id, uint32_t format, uint32_t width, diff --git a/framework/decode/vulkan_decoder_base.cpp b/framework/decode/vulkan_decoder_base.cpp index 93f60b68b..e66d42723 100644 --- a/framework/decode/vulkan_decoder_base.cpp +++ b/framework/decode/vulkan_decoder_base.cpp @@ -126,6 +126,8 @@ void VulkanDecoderBase::DispatchResizeWindowCommand2( void VulkanDecoderBase::DispatchCreateHardwareBufferCommand( format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, @@ -141,7 +143,7 @@ void VulkanDecoderBase::DispatchCreateHardwareBufferCommand( for (auto consumer : consumers_) { consumer->ProcessCreateHardwareBufferCommand( - memory_id, buffer_id, format, width, height, stride, usage, layers, plane_info); + device_id, queue_id, memory_id, buffer_id, format, width, height, stride, usage, layers, plane_info); } } diff --git a/framework/decode/vulkan_decoder_base.h b/framework/decode/vulkan_decoder_base.h index ddaa8bd2b..9a4c7e0de 100644 --- a/framework/decode/vulkan_decoder_base.h +++ b/framework/decode/vulkan_decoder_base.h @@ -107,6 +107,8 @@ class VulkanDecoderBase : public ApiDecoder virtual void DispatchCreateHardwareBufferCommand(format::ThreadId thread_id, + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index cad7059ce..5cd20b80f 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -333,53 +333,568 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t memory_id void* buffer_data = nullptr; const HardwareBufferMemoryInfo& buffer_info = entry->second; - int lock_result = AHardwareBuffer_lock( - buffer_info.hardware_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr, &buffer_data); + AHardwareBuffer_Desc desc; + AHardwareBuffer_describe(buffer_info.hardware_buffer, &desc); - if (lock_result == 0) + if ((desc.usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) != 0) { - assert(buffer_data != nullptr); - if (buffer_info.plane_info.size() == 1) + int lock_result = AHardwareBuffer_lock( + buffer_info.hardware_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr, &buffer_data); + + if (lock_result == 0) { - GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, size); - GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, offset); - - size_t data_size = static_cast(size); - size_t data_offset = static_cast(offset); - size_t capture_row_pitch = buffer_info.plane_info[0].capture_row_pitch; - size_t replay_row_pitch = buffer_info.plane_info[0].replay_row_pitch; - uint32_t height = buffer_info.plane_info[0].height; - - resource::CopyImageSubresourceMemory(static_cast(buffer_data), - data, - data_offset, - data_size, - replay_row_pitch, - capture_row_pitch, - height); + assert(buffer_data != nullptr); + + if (buffer_info.plane_info.size() == 1) + { + GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, size); + GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, offset); + + size_t data_size = static_cast(size); + size_t data_offset = static_cast(offset); + size_t capture_row_pitch = buffer_info.plane_info[0].capture_row_pitch; + size_t replay_row_pitch = buffer_info.plane_info[0].replay_row_pitch; + uint32_t height = buffer_info.plane_info[0].height; + + resource::CopyImageSubresourceMemory(static_cast(buffer_data), + data, + data_offset, + data_size, + replay_row_pitch, + capture_row_pitch, + height); + } + else + { + // TODO: multi-plane image format support when strides do not match. + GFXRECON_LOG_WARNING( + "Ignoring fill memory command for AHardwareBuffer with multi-plane format and " + "mismatched capture/replay strides (Memory ID = %" PRIu64 "): support not yet implemented", + memory_id); + } + + lock_result = AHardwareBuffer_unlock(buffer_info.hardware_buffer, nullptr); + if (lock_result != 0) + { + GFXRECON_LOG_WARNING( + "AHardwareBuffer_unlock failed for AHardwareBuffer object (Memory ID = %" PRIu64 ")", + memory_id); + } } else { - // TODO: multi-plane image format support when strides do not match. - GFXRECON_LOG_WARNING("Ignoring fill memory command for AHardwareBuffer with multi-plane format and " - "mismatched capture/replay strides (Memory ID = %" PRIu64 - "): support not yet implemented", - memory_id); + GFXRECON_LOG_WARNING( + "AHardwareBuffer_lock failed for AHardwareBuffer object (Memory ID = %" PRIu64 ")", memory_id); + } + } + else if (buffer_info.device_id != 0) + { + DeviceInfo* device_info = object_info_table_.GetDeviceInfo(buffer_info.device_id); + QueueInfo* queue_info = object_info_table_.GetQueueInfo(buffer_info.queue_id); + VkDevice device = device_info->handle; + auto device_table = GetDeviceTable(device); + auto table = GetDeviceTable(device); + auto physical_device_info = object_info_table_.GetPhysicalDeviceInfo(device_info->parent_id); + auto memory_properties = &physical_device_info->capture_memory_properties; + + VkResult vk_result = VK_SUCCESS; + + VkExternalFormatANDROID externalFormat; + externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID; + externalFormat.pNext = nullptr; + externalFormat.externalFormat = desc.format; + + VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo; + externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; + externalMemoryImageCreateInfo.pNext = &externalFormat; + externalMemoryImageCreateInfo.handleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; + + const uint32_t imageHeight = 1024; + const uint32_t imageWidth = size / imageHeight / sizeof(uint32_t); + + VkImageCreateInfo imageCreateInfo; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.pNext = &externalMemoryImageCreateInfo; + imageCreateInfo.flags = 0u; + imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; + imageCreateInfo.format = VK_FORMAT_UNDEFINED; + imageCreateInfo.extent = { imageWidth, imageHeight, 1u }; + imageCreateInfo.mipLevels = 1u; + imageCreateInfo.arrayLayers = 1u; + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCreateInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT; + imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageCreateInfo.queueFamilyIndexCount = 0u; + imageCreateInfo.pQueueFamilyIndices = nullptr; + imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImage ahbImage = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateImage(device, &imageCreateInfo, nullptr, &ahbImage); + + VkMemoryRequirements imageMemoryRequirements; + if (vk_result == VK_SUCCESS) + device_table->GetImageMemoryRequirements(device, ahbImage, &imageMemoryRequirements); + + VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo; + memoryDedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + memoryDedicatedAllocateInfo.pNext = nullptr; + memoryDedicatedAllocateInfo.image = ahbImage; + memoryDedicatedAllocateInfo.buffer = VK_NULL_HANDLE; + + VkImportAndroidHardwareBufferInfoANDROID importAHBInfo; + importAHBInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID; + importAHBInfo.pNext = &memoryDedicatedAllocateInfo; + importAHBInfo.buffer = buffer_info.hardware_buffer; + + VkMemoryAllocateInfo imageMemoryAllocateInfo; + imageMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + imageMemoryAllocateInfo.pNext = &importAHBInfo; + imageMemoryAllocateInfo.allocationSize = imageMemoryRequirements.size; + + uint32_t memoryIndex = memory_properties->memoryTypeCount; + for (uint32_t i = 0; i < memory_properties->memoryTypeCount; ++i) + { + if ((imageMemoryRequirements.memoryTypeBits & (1 << i)) && + (memory_properties->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) > 0) + { + memoryIndex = i; + } + } + assert(memoryIndex < memory_properties->memoryTypeCount); + imageMemoryAllocateInfo.memoryTypeIndex = memoryIndex; + + VkDeviceMemory imageMemory = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->AllocateMemory(device, &imageMemoryAllocateInfo, nullptr, &imageMemory); + if (vk_result == VK_SUCCESS) + vk_result = device_table->BindImageMemory(device, ahbImage, imageMemory, 0u); + + VkImageViewCreateInfo imageViewCreateInfo; + imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCreateInfo.pNext = nullptr; + imageViewCreateInfo.flags = 0u; + imageViewCreateInfo.image = ahbImage; + imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewCreateInfo.format = VK_FORMAT_R32_UINT; + imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + imageViewCreateInfo.subresourceRange.baseMipLevel = 0u; + imageViewCreateInfo.subresourceRange.levelCount = 1u; + imageViewCreateInfo.subresourceRange.baseArrayLayer = 0u; + imageViewCreateInfo.subresourceRange.layerCount = 1u; + + VkImageView imageView = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateImageView(device, &imageViewCreateInfo, nullptr, &imageView); + + VkBufferCreateInfo bufferCreateInfo; + bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCreateInfo.pNext = nullptr; + bufferCreateInfo.flags = 0u; + bufferCreateInfo.size = size; + bufferCreateInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bufferCreateInfo.queueFamilyIndexCount = 0u; + bufferCreateInfo.pQueueFamilyIndices = nullptr; + + VkBuffer buffer = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateBuffer(device, &bufferCreateInfo, nullptr, &buffer); + + VkMemoryRequirements bufferMemeryRequirements; + if (vk_result == VK_SUCCESS) + device_table->GetBufferMemoryRequirements(device, buffer, &bufferMemeryRequirements); + + VkMemoryAllocateInfo bufferMemoryAllocateInfo; + bufferMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + bufferMemoryAllocateInfo.pNext = nullptr; + bufferMemoryAllocateInfo.allocationSize = bufferMemeryRequirements.size; + + uint32_t bufferMemoryIndex = memory_properties->memoryTypeCount; + for (uint32_t i = 0; i < memory_properties->memoryTypeCount; ++i) + { + if ((bufferMemeryRequirements.memoryTypeBits & (1 << i)) && + (memory_properties->memoryTypes[i].propertyFlags & + (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) == + (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + { + bufferMemoryIndex = i; + break; + } } + assert(bufferMemoryIndex < memory_properties->memoryTypeCount); + bufferMemoryAllocateInfo.memoryTypeIndex = bufferMemoryIndex; - lock_result = AHardwareBuffer_unlock(buffer_info.hardware_buffer, nullptr); - if (lock_result != 0) + VkDeviceMemory bufferMemory = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->AllocateMemory(device, &bufferMemoryAllocateInfo, nullptr, &bufferMemory); + if (vk_result == VK_SUCCESS) + vk_result = device_table->BindBufferMemory(device, buffer, bufferMemory, 0); + + void* bufferData; + if (vk_result == VK_SUCCESS) { - GFXRECON_LOG_WARNING( - "AHardwareBuffer_unlock failed for AHardwareBuffer object (Memory ID = %" PRIu64 ")", - memory_id); + vk_result = device_table->MapMemory(device, bufferMemory, 0u, size, 0u, &bufferData); + memcpy(bufferData, data, size); + } + + // #version 450 + // layout(local_size_x = 16, local_size_y = 16) in; + // + // layout(binding = 0, r32ui) writeonly uniform uimage2D image; + // layout(binding = 1, std430) readonly buffer InputBuffer { + // uint data[]; + // }; + // + // void main() { + // uvec2 gid = gl_GlobalInvocationID.xy; + // ivec2 size = imageSize(image); + // if (gid.x >= uint(size.x) || gid.y >= uint(size.y)) return; + // + // uint index = gid.y * uint(size.x) + gid.x; + // uint pixel = data[index]; + // imageStore(image, ivec2(gid), uvec4(pixel, 0, 0, 0)); + // } + + std::vector shader = { + 0x07230203, 0x00010000, 0x0008000b, 0x0000004c, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x00000032, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, + 0x00000000, 0x00000001, 0x0006000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000c, + 0x00060010, 0x00000004, 0x00000011, 0x00000010, 0x00000010, 0x00000001, 0x00030003, 0x00000002, + 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00030005, 0x00000009, 0x00646967, + 0x00080005, 0x0000000c, 0x475f6c67, 0x61626f6c, 0x766e496c, 0x7461636f, 0x496e6f69, 0x00000044, + 0x00040005, 0x00000012, 0x657a6973, 0x00000000, 0x00040005, 0x00000015, 0x67616d69, 0x00000065, + 0x00040005, 0x00000030, 0x65646e69, 0x00000078, 0x00040005, 0x0000003a, 0x65786970, 0x0000006c, + 0x00050005, 0x0000003c, 0x75706e49, 0x66754274, 0x00726566, 0x00050006, 0x0000003c, 0x00000000, + 0x61746164, 0x00000000, 0x00030005, 0x0000003e, 0x00000000, 0x00040047, 0x0000000c, 0x0000000b, + 0x0000001c, 0x00040047, 0x00000015, 0x00000022, 0x00000000, 0x00040047, 0x00000015, 0x00000021, + 0x00000000, 0x00030047, 0x00000015, 0x00000019, 0x00040047, 0x0000003b, 0x00000006, 0x00000004, + 0x00040048, 0x0000003c, 0x00000000, 0x00000018, 0x00050048, 0x0000003c, 0x00000000, 0x00000023, + 0x00000000, 0x00030047, 0x0000003c, 0x00000003, 0x00040047, 0x0000003e, 0x00000022, 0x00000000, + 0x00040047, 0x0000003e, 0x00000021, 0x00000001, 0x00040047, 0x0000004b, 0x0000000b, 0x00000019, + 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015, 0x00000006, 0x00000020, + 0x00000000, 0x00040017, 0x00000007, 0x00000006, 0x00000002, 0x00040020, 0x00000008, 0x00000007, + 0x00000007, 0x00040017, 0x0000000a, 0x00000006, 0x00000003, 0x00040020, 0x0000000b, 0x00000001, + 0x0000000a, 0x0004003b, 0x0000000b, 0x0000000c, 0x00000001, 0x00040015, 0x0000000f, 0x00000020, + 0x00000001, 0x00040017, 0x00000010, 0x0000000f, 0x00000002, 0x00040020, 0x00000011, 0x00000007, + 0x00000010, 0x00090019, 0x00000013, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000021, 0x00040020, 0x00000014, 0x00000000, 0x00000013, 0x0004003b, 0x00000014, + 0x00000015, 0x00000000, 0x00020014, 0x00000018, 0x0004002b, 0x00000006, 0x00000019, 0x00000000, + 0x00040020, 0x0000001a, 0x00000007, 0x00000006, 0x00040020, 0x0000001d, 0x00000007, 0x0000000f, + 0x0004002b, 0x00000006, 0x00000025, 0x00000001, 0x0003001d, 0x0000003b, 0x00000006, 0x0003001e, + 0x0000003c, 0x0000003b, 0x00040020, 0x0000003d, 0x00000002, 0x0000003c, 0x0004003b, 0x0000003d, + 0x0000003e, 0x00000002, 0x0004002b, 0x0000000f, 0x0000003f, 0x00000000, 0x00040020, 0x00000041, + 0x00000002, 0x00000006, 0x00040017, 0x00000048, 0x00000006, 0x00000004, 0x0004002b, 0x00000006, + 0x0000004a, 0x00000010, 0x0006002c, 0x0000000a, 0x0000004b, 0x0000004a, 0x0000004a, 0x00000025, + 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, + 0x00000008, 0x00000009, 0x00000007, 0x0004003b, 0x00000011, 0x00000012, 0x00000007, 0x0004003b, + 0x0000001a, 0x00000030, 0x00000007, 0x0004003b, 0x0000001a, 0x0000003a, 0x00000007, 0x0004003d, + 0x0000000a, 0x0000000d, 0x0000000c, 0x0007004f, 0x00000007, 0x0000000e, 0x0000000d, 0x0000000d, + 0x00000000, 0x00000001, 0x0003003e, 0x00000009, 0x0000000e, 0x0004003d, 0x00000013, 0x00000016, + 0x00000015, 0x00040068, 0x00000010, 0x00000017, 0x00000016, 0x0003003e, 0x00000012, 0x00000017, + 0x00050041, 0x0000001a, 0x0000001b, 0x00000009, 0x00000019, 0x0004003d, 0x00000006, 0x0000001c, + 0x0000001b, 0x00050041, 0x0000001d, 0x0000001e, 0x00000012, 0x00000019, 0x0004003d, 0x0000000f, + 0x0000001f, 0x0000001e, 0x0004007c, 0x00000006, 0x00000020, 0x0000001f, 0x000500ae, 0x00000018, + 0x00000021, 0x0000001c, 0x00000020, 0x000400a8, 0x00000018, 0x00000022, 0x00000021, 0x000300f7, + 0x00000024, 0x00000000, 0x000400fa, 0x00000022, 0x00000023, 0x00000024, 0x000200f8, 0x00000023, + 0x00050041, 0x0000001a, 0x00000026, 0x00000009, 0x00000025, 0x0004003d, 0x00000006, 0x00000027, + 0x00000026, 0x00050041, 0x0000001d, 0x00000028, 0x00000012, 0x00000025, 0x0004003d, 0x0000000f, + 0x00000029, 0x00000028, 0x0004007c, 0x00000006, 0x0000002a, 0x00000029, 0x000500ae, 0x00000018, + 0x0000002b, 0x00000027, 0x0000002a, 0x000200f9, 0x00000024, 0x000200f8, 0x00000024, 0x000700f5, + 0x00000018, 0x0000002c, 0x00000021, 0x00000005, 0x0000002b, 0x00000023, 0x000300f7, 0x0000002e, + 0x00000000, 0x000400fa, 0x0000002c, 0x0000002d, 0x0000002e, 0x000200f8, 0x0000002d, 0x000100fd, + 0x000200f8, 0x0000002e, 0x00050041, 0x0000001a, 0x00000031, 0x00000009, 0x00000025, 0x0004003d, + 0x00000006, 0x00000032, 0x00000031, 0x00050041, 0x0000001d, 0x00000033, 0x00000012, 0x00000019, + 0x0004003d, 0x0000000f, 0x00000034, 0x00000033, 0x0004007c, 0x00000006, 0x00000035, 0x00000034, + 0x00050084, 0x00000006, 0x00000036, 0x00000032, 0x00000035, 0x00050041, 0x0000001a, 0x00000037, + 0x00000009, 0x00000019, 0x0004003d, 0x00000006, 0x00000038, 0x00000037, 0x00050080, 0x00000006, + 0x00000039, 0x00000036, 0x00000038, 0x0003003e, 0x00000030, 0x00000039, 0x0004003d, 0x00000006, + 0x00000040, 0x00000030, 0x00060041, 0x00000041, 0x00000042, 0x0000003e, 0x0000003f, 0x00000040, + 0x0004003d, 0x00000006, 0x00000043, 0x00000042, 0x0003003e, 0x0000003a, 0x00000043, 0x0004003d, + 0x00000013, 0x00000044, 0x00000015, 0x0004003d, 0x00000007, 0x00000045, 0x00000009, 0x0004007c, + 0x00000010, 0x00000046, 0x00000045, 0x0004003d, 0x00000006, 0x00000047, 0x0000003a, 0x00070050, + 0x00000048, 0x00000049, 0x00000047, 0x00000019, 0x00000019, 0x00000019, 0x00040063, 0x00000044, + 0x00000046, 0x00000049, 0x000100fd, 0x00010038, + }; + + VkShaderModuleCreateInfo shaderModuleCreateInfo; + shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shaderModuleCreateInfo.pNext = nullptr; + shaderModuleCreateInfo.flags = 0u; + shaderModuleCreateInfo.codeSize = shader.size() * sizeof(uint32_t); + shaderModuleCreateInfo.pCode = shader.data(); + VkShaderModule computeShaderModule = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateShaderModule( + device, &shaderModuleCreateInfo, nullptr, &computeShaderModule); + + VkPipelineShaderStageCreateInfo shaderStageCreateInfo; + shaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageCreateInfo.pNext = nullptr; + shaderStageCreateInfo.flags = 0u; + shaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + shaderStageCreateInfo.module = computeShaderModule; + shaderStageCreateInfo.pName = "main"; + shaderStageCreateInfo.pSpecializationInfo = nullptr; + + VkDescriptorSetLayoutBinding bindings[2]; + bindings[0].binding = 0u; + bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + bindings[0].descriptorCount = 1u; + bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + bindings[0].pImmutableSamplers = nullptr; + bindings[1].binding = 1u; + bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + bindings[1].descriptorCount = 1u; + bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + bindings[1].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo; + descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.pNext = nullptr; + descriptorSetLayoutCreateInfo.flags = 0u; + descriptorSetLayoutCreateInfo.bindingCount = 2u; + descriptorSetLayoutCreateInfo.pBindings = bindings; + + VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateDescriptorSetLayout( + device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout); + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo; + pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.pNext = nullptr; + pipelineLayoutCreateInfo.flags = 0u; + pipelineLayoutCreateInfo.setLayoutCount = 1u; + pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout; + pipelineLayoutCreateInfo.pushConstantRangeCount = 0u; + pipelineLayoutCreateInfo.pPushConstantRanges = nullptr; + + VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->CreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout); + + VkComputePipelineCreateInfo computePipelineCreateInfo; + computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.pNext = nullptr; + computePipelineCreateInfo.flags = 0u; + computePipelineCreateInfo.stage = shaderStageCreateInfo; + computePipelineCreateInfo.layout = pipelineLayout; + computePipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + computePipelineCreateInfo.basePipelineIndex = -1; + + VkPipeline computePipeline = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateComputePipelines( + device, VK_NULL_HANDLE, 1u, &computePipelineCreateInfo, nullptr, &computePipeline); + + VkDescriptorPoolSize poolSizes[2]; + poolSizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + poolSizes[0].descriptorCount = 1u; + poolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + poolSizes[1].descriptorCount = 1u; + + VkDescriptorPoolCreateInfo descriptorPoolCreateInfo; + descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolCreateInfo.pNext = nullptr; + descriptorPoolCreateInfo.flags = 0u; + descriptorPoolCreateInfo.maxSets = 1u; + descriptorPoolCreateInfo.poolSizeCount = 2u; + descriptorPoolCreateInfo.pPoolSizes = poolSizes; + + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->CreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool); + + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo; + descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptorSetAllocateInfo.pNext = nullptr; + descriptorSetAllocateInfo.descriptorPool = descriptorPool; + descriptorSetAllocateInfo.descriptorSetCount = 1u; + descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayout; + + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet); + + VkDescriptorImageInfo imageInfo = {}; + imageInfo.sampler = VK_NULL_HANDLE; + imageInfo.imageView = imageView; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + + VkDescriptorBufferInfo bufferInfo; + bufferInfo.buffer = buffer; + bufferInfo.offset = 0u; + bufferInfo.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet descriptorWrites[2]; + descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[0].pNext = nullptr; + descriptorWrites[0].dstSet = descriptorSet; + descriptorWrites[0].dstBinding = 0u; + descriptorWrites[0].dstArrayElement = 0u; + descriptorWrites[0].descriptorCount = 1u; + descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + descriptorWrites[0].pImageInfo = &imageInfo; + descriptorWrites[0].pBufferInfo = nullptr; + descriptorWrites[0].pTexelBufferView = nullptr; + descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[1].pNext = nullptr; + descriptorWrites[1].dstSet = descriptorSet; + descriptorWrites[1].dstBinding = 1u; + descriptorWrites[1].dstArrayElement = 0u; + descriptorWrites[1].descriptorCount = 1u; + descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrites[1].pImageInfo = nullptr; + descriptorWrites[1].pBufferInfo = &bufferInfo; + descriptorWrites[1].pTexelBufferView = nullptr; + + if (vk_result == VK_SUCCESS) + device_table->UpdateDescriptorSets(device, 2u, descriptorWrites, 0u, nullptr); + + VkCommandPoolCreateInfo commandPoolCreateInfo; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.pNext = nullptr; + commandPoolCreateInfo.flags = 0u; + commandPoolCreateInfo.queueFamilyIndex = queue_info->family_index; + + VkCommandPool commandPool = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateCommandPool(device, &commandPoolCreateInfo, nullptr, &commandPool); + + VkCommandBufferAllocateInfo commandBufferAllocateInfo; + commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.pNext = nullptr; + commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocateInfo.commandPool = commandPool; + commandBufferAllocateInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer); + + VkCommandBufferBeginInfo commandBufferBeginInfo; + commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + commandBufferBeginInfo.pNext = nullptr; + commandBufferBeginInfo.flags = 0u; + commandBufferBeginInfo.pInheritanceInfo = nullptr; + if (vk_result == VK_SUCCESS) + vk_result = device_table->BeginCommandBuffer(commandBuffer, &commandBufferBeginInfo); + + if (vk_result == VK_SUCCESS) + { + VkImageMemoryBarrier barrier = {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.pNext = nullptr; + barrier.srcAccessMask = 0u; + barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = ahbImage; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.baseMipLevel = 0u; + barrier.subresourceRange.levelCount = 1u; + barrier.subresourceRange.baseArrayLayer = 0u; + barrier.subresourceRange.layerCount = 1u; + + device_table->CmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); + + device_table->CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline); + device_table->CmdBindDescriptorSets(commandBuffer, + VK_PIPELINE_BIND_POINT_COMPUTE, + pipelineLayout, + 0, + 1, + &descriptorSet, + 0, + nullptr); + device_table->CmdDispatch(commandBuffer, (imageWidth + 15) / 16, (imageHeight + 15) / 16, 1u); + + VkMemoryBarrier memoryBarrier; + memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + memoryBarrier.pNext = nullptr; + memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + memoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + + device_table->CmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0u, + 1u, + &memoryBarrier, + 0u, + nullptr, + 0u, + nullptr); + + device_table->EndCommandBuffer(commandBuffer); + } + + VkSubmitInfo submitInfo; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 0u; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + submitInfo.commandBufferCount = 1u; + submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.signalSemaphoreCount = 0u; + submitInfo.pSignalSemaphores = nullptr; + + VkFenceCreateInfo fenceCreateInfo; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.pNext = nullptr; + fenceCreateInfo.flags = 0u; + + VkFence fence = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateFence(device, &fenceCreateInfo, nullptr, &fence); + + if (vk_result == VK_SUCCESS) + vk_result = device_table->QueueSubmit(queue_info->handle, 1, &submitInfo, fence); + if (vk_result == VK_SUCCESS) + vk_result = device_table->WaitForFences(device, 1u, &fence, VK_TRUE, UINT64_MAX); + + device_table->DestroyFence(device, fence, nullptr); + device_table->DestroyCommandPool(device, commandPool, nullptr); + device_table->DestroyDescriptorPool(device, descriptorPool, nullptr); + device_table->DestroyPipeline(device, computePipeline, nullptr); + device_table->DestroyPipelineLayout(device, pipelineLayout, nullptr); + device_table->DestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + device_table->DestroyShaderModule(device, computeShaderModule, nullptr); + device_table->FreeMemory(device, bufferMemory, nullptr); + device_table->DestroyBuffer(device, buffer, nullptr); + device_table->DestroyImageView(device, imageView, nullptr); + device_table->FreeMemory(device, imageMemory, nullptr); + device_table->DestroyImage(device, ahbImage, nullptr); + + if (vk_result != VK_SUCCESS) + { + GFXRECON_LOG_ERROR("Failed to copy data for AHardwareBuffer object (Memory ID = %" PRIu64 ")", + memory_id); } - } - else - { - GFXRECON_LOG_WARNING("AHardwareBuffer_lock failed for AHardwareBuffer object (Memory ID = %" PRIu64 ")", - memory_id); } } } @@ -471,6 +986,8 @@ void VulkanReplayConsumerBase::ProcessResizeWindowCommand2(format::HandleId surf } void VulkanReplayConsumerBase::ProcessCreateHardwareBufferCommand( + format::HandleId device_id, + format::HandleId queue_id, format::HandleId memory_id, uint64_t buffer_id, uint32_t format, @@ -543,6 +1060,8 @@ void VulkanReplayConsumerBase::ProcessCreateHardwareBufferCommand( HardwareBufferMemoryInfo& memory_info = hardware_buffer_memory_info_[memory_id]; memory_info.hardware_buffer = buffer; + memory_info.device_id = device_id; + memory_info.queue_id = queue_id; memory_info.compatible_strides = true; // Check for matching strides. diff --git a/framework/decode/vulkan_replay_consumer_base.h b/framework/decode/vulkan_replay_consumer_base.h index a5cb4712d..105d624cd 100644 --- a/framework/decode/vulkan_replay_consumer_base.h +++ b/framework/decode/vulkan_replay_consumer_base.h @@ -106,7 +106,9 @@ class VulkanReplayConsumerBase : public VulkanConsumer uint32_t pre_transform) override; virtual void - ProcessCreateHardwareBufferCommand(format::HandleId memory_id, + ProcessCreateHardwareBufferCommand(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, uint64_t buffer_id, uint32_t format, uint32_t width, @@ -1460,6 +1462,8 @@ class VulkanReplayConsumerBase : public VulkanConsumer struct HardwareBufferMemoryInfo { AHardwareBuffer* hardware_buffer; + format::HandleId device_id; + format::HandleId queue_id; bool compatible_strides; std::vector plane_info; }; diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index 9284d48b6..29b1c73aa 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -195,7 +195,9 @@ void VulkanCaptureManager::WriteResizeWindowCmd2(format::HandleId s } } -void VulkanCaptureManager::WriteCreateHardwareBufferCmd(format::HandleId memory_id, +void VulkanCaptureManager::WriteCreateHardwareBufferCmd(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, AHardwareBuffer* buffer, const std::vector& plane_info) { @@ -214,6 +216,8 @@ void VulkanCaptureManager::WriteCreateHardwareBufferCmd(format::HandleId create_buffer_cmd.meta_header.meta_data_id = format::MakeMetaDataId( format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kCreateHardwareBufferCommand); create_buffer_cmd.thread_id = thread_data->thread_id_; + create_buffer_cmd.device_id = device_id; + create_buffer_cmd.queue_id = queue_id; create_buffer_cmd.memory_id = memory_id; create_buffer_cmd.buffer_id = reinterpret_cast(buffer); @@ -775,12 +779,14 @@ VkResult VulkanCaptureManager::OverrideCreateDevice(VkPhysicalDevice wrapper->physical_device = physical_device_wrapper; } + wrapper->queue_family_indices.resize(pCreateInfo_unwrapped->queueCreateInfoCount); for (uint32_t q = 0; q < pCreateInfo_unwrapped->queueCreateInfoCount; ++q) { const VkDeviceQueueCreateInfo* queue_create_info = &pCreateInfo_unwrapped->pQueueCreateInfos[q]; assert(wrapper->queue_family_creation_flags.find(queue_create_info->queueFamilyIndex) == wrapper->queue_family_creation_flags.end()); wrapper->queue_family_creation_flags[queue_create_info->queueFamilyIndex] = queue_create_info->flags; + wrapper->queue_family_indices[q] = pCreateInfo_unwrapped->pQueueCreateInfos[q].queueFamilyIndex; } } @@ -1753,7 +1759,7 @@ void VulkanCaptureManager::ProcessReferenceToAndroidHardwareBuffer(VkDevice devi ahb_info.reference_count = 0; // Write CreateHardwareBufferCmd with or without the AHB payload - WriteCreateHardwareBufferCmd(memory_id, hardware_buffer, plane_info); + WriteCreateHardwareBufferCmd(0, 0, memory_id, hardware_buffer, plane_info); // Query the AHB size VkAndroidHardwareBufferPropertiesANDROID properties = { @@ -1834,18 +1840,583 @@ void VulkanCaptureManager::ProcessReferenceToAndroidHardwareBuffer(VkDevice devi } else { - // The AHB is not CPU-readable, so store only the creation command. - // Only store buffer IDs and reference count if a creation command is written to the capture file. + // The AHB is not CPU-readable, so create a VkBuffer and copy the data to it from AHB with vkCmdCopyBuffer format::HandleId memory_id = GetUniqueId(); HardwareBufferInfo& ahb_info = hardware_buffers_[hardware_buffer]; ahb_info.memory_id = memory_id; ahb_info.reference_count = 0; - WriteCreateHardwareBufferCmd(memory_id, hardware_buffer, plane_info); + auto physical_device_wrapper = device_wrapper->physical_device; + auto physical_device = physical_device_wrapper->handle; + const VulkanInstanceTable* instance_table = vulkan_wrappers::GetInstanceTable(physical_device); + auto memory_properties = &physical_device_wrapper->memory_properties; + + uint32_t deviceQueueIndex = -1; + uint32_t queueFamilyIndex = -1; + + uint32_t queueFamilyCount; + instance_table->GetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, nullptr); + std::vector queueFamilyProperties(queueFamilyCount); + instance_table->GetPhysicalDeviceQueueFamilyProperties( + physical_device, &queueFamilyCount, queueFamilyProperties.data()); + + for (size_t i = 0; i < device_wrapper->queue_family_indices.size(); ++i) + { + uint32_t qfi = device_wrapper->queue_family_indices[i]; + if ((queueFamilyProperties[qfi].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0) + { + deviceQueueIndex = i; + queueFamilyIndex = qfi; + break; + } + } + + if (deviceQueueIndex == -1 || queueFamilyIndex == -1) + return; + + auto queue_wrapper = device_wrapper->child_queues[deviceQueueIndex]; + + WriteCreateHardwareBufferCmd( + device_wrapper->handle_id, queue_wrapper->handle_id, memory_id, hardware_buffer, plane_info); + + VkResult vk_result = VK_SUCCESS; + + // Query the AHB size + VkAndroidHardwareBufferFormatPropertiesANDROID formatProperties; + formatProperties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID; + formatProperties.pNext = nullptr; + + VkAndroidHardwareBufferPropertiesANDROID properties; + properties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID; + properties.pNext = &formatProperties; + + if (vk_result == VK_SUCCESS) + vk_result = device_table->GetAndroidHardwareBufferPropertiesANDROID( + device_unwrapped, hardware_buffer, &properties); + + const size_t ahb_size = properties.allocationSize; + assert(ahb_size); + + VkExternalFormatANDROID externalFormat; + externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID; + externalFormat.pNext = nullptr; + externalFormat.externalFormat = formatProperties.externalFormat; + + VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo; + externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; + externalMemoryImageCreateInfo.pNext = &externalFormat; + externalMemoryImageCreateInfo.handleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; + + const uint32_t imageHeight = 1024; + const uint32_t imageWidth = ahb_size / imageHeight / sizeof(uint32_t); + + VkImageCreateInfo imageCreateInfo; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.pNext = &externalMemoryImageCreateInfo; + imageCreateInfo.flags = 0u; + imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; + imageCreateInfo.format = VK_FORMAT_UNDEFINED; + imageCreateInfo.extent = { imageWidth, imageHeight, 1u }; + imageCreateInfo.mipLevels = 1u; + imageCreateInfo.arrayLayers = 1u; + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCreateInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT; + imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageCreateInfo.queueFamilyIndexCount = 0u; + imageCreateInfo.pQueueFamilyIndices = nullptr; + imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImage ahbImage = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateImage(device_unwrapped, &imageCreateInfo, nullptr, &ahbImage); + + VkMemoryRequirements imageMemoryRequirements; + if (vk_result == VK_SUCCESS) + device_table->GetImageMemoryRequirements(device, ahbImage, &imageMemoryRequirements); + + VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo; + memoryDedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; + memoryDedicatedAllocateInfo.pNext = nullptr; + memoryDedicatedAllocateInfo.image = ahbImage; + memoryDedicatedAllocateInfo.buffer = VK_NULL_HANDLE; + + VkImportAndroidHardwareBufferInfoANDROID importAHBInfo; + importAHBInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID; + importAHBInfo.pNext = &memoryDedicatedAllocateInfo; + importAHBInfo.buffer = hardware_buffer; + + VkMemoryAllocateInfo imageMemoryAllocateInfo; + imageMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + imageMemoryAllocateInfo.pNext = &importAHBInfo; + imageMemoryAllocateInfo.allocationSize = imageMemoryRequirements.size; + + uint32_t imageMemoryIndex = -1; + for (uint32_t i = 0; i < memory_properties->memoryTypeCount; ++i) + { + if ((imageMemoryRequirements.memoryTypeBits & (1 << i)) && + (memory_properties->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) > 0) + { + imageMemoryIndex = i; + break; + } + } + if (imageMemoryIndex == -1) + return; + imageMemoryAllocateInfo.memoryTypeIndex = imageMemoryIndex; + + VkDeviceMemory imageMemory = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateMemory(device_unwrapped, &imageMemoryAllocateInfo, nullptr, &imageMemory); + if (vk_result == VK_SUCCESS) + vk_result = device_table->BindImageMemory(device_unwrapped, ahbImage, imageMemory, 0u); + + VkImageViewCreateInfo imageViewCreateInfo; + imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCreateInfo.pNext = nullptr; + imageViewCreateInfo.flags = 0u; + imageViewCreateInfo.image = ahbImage; + imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewCreateInfo.format = VK_FORMAT_R32_UINT; + imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + imageViewCreateInfo.subresourceRange.baseMipLevel = 0u; + imageViewCreateInfo.subresourceRange.levelCount = 1u; + imageViewCreateInfo.subresourceRange.baseArrayLayer = 0u; + imageViewCreateInfo.subresourceRange.layerCount = 1u; + + VkImageView imageView = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateImageView(device_unwrapped, &imageViewCreateInfo, nullptr, &imageView); + + VkBufferCreateInfo bufferCreateInfo; + bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCreateInfo.pNext = nullptr; + bufferCreateInfo.flags = 0u; + bufferCreateInfo.size = ahb_size; + bufferCreateInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bufferCreateInfo.queueFamilyIndexCount = 0u; + bufferCreateInfo.pQueueFamilyIndices = nullptr; + + VkBuffer buffer = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateBuffer(device_unwrapped, &bufferCreateInfo, nullptr, &buffer); + + VkMemoryRequirements bufferMemeryRequirements; + if (vk_result == VK_SUCCESS) + device_table->GetBufferMemoryRequirements(device_unwrapped, buffer, &bufferMemeryRequirements); + + VkMemoryAllocateInfo bufferMemoryAllocateInfo; + bufferMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + bufferMemoryAllocateInfo.pNext = nullptr; + bufferMemoryAllocateInfo.allocationSize = bufferMemeryRequirements.size; + + uint32_t bufferMemoryIndex = -1; + for (uint32_t i = 0; i < memory_properties->memoryTypeCount; ++i) + { + if ((bufferMemeryRequirements.memoryTypeBits & (1 << i)) && + (memory_properties->memoryTypes[i].propertyFlags & + (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) == + (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + { + bufferMemoryIndex = i; + break; + } + } + if (bufferMemoryIndex == -1) + return; + bufferMemoryAllocateInfo.memoryTypeIndex = bufferMemoryIndex; + + VkDeviceMemory bufferMemory = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateMemory(device_unwrapped, &bufferMemoryAllocateInfo, nullptr, &bufferMemory); + if (vk_result == VK_SUCCESS) + vk_result = device_table->BindBufferMemory(device_unwrapped, buffer, bufferMemory, 0); + + // #version 450 + // layout(local_size_x = 16, local_size_y = 16) in; + // + // layout(binding = 0, r32ui) readonly uniform uimage2D image; + // layout(binding = 1, std430) buffer OutputBuffer { + // uint data[]; + // }; + // + // void main() { + // uvec2 gid = gl_GlobalInvocationID.xy; + // ivec2 size = imageSize(image); + // if (gid.x >= uint(size.x) || gid.y >= uint(size.y)) return; + // + // uvec4 pixel = imageLoad(image, ivec2(gid)); + // uint index = gid.y * uint(size.x) + gid.x; + // data[index] = pixel.x; + // } + + std::vector shader = { + 0x07230203, 0x00010000, 0x0008000b, 0x0000004d, 0x00000000, 0x00020011, 0x00000001, 0x00020011, + 0x00000032, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, + 0x00000000, 0x00000001, 0x0006000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000c, + 0x00060010, 0x00000004, 0x00000011, 0x00000010, 0x00000010, 0x00000001, 0x00030003, 0x00000002, + 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00030005, 0x00000009, 0x00646967, + 0x00080005, 0x0000000c, 0x475f6c67, 0x61626f6c, 0x766e496c, 0x7461636f, 0x496e6f69, 0x00000044, + 0x00040005, 0x00000012, 0x657a6973, 0x00000000, 0x00040005, 0x00000015, 0x67616d69, 0x00000065, + 0x00040005, 0x00000032, 0x65786970, 0x0000006c, 0x00040005, 0x00000037, 0x65646e69, 0x00000078, + 0x00060005, 0x00000042, 0x7074754f, 0x75427475, 0x72656666, 0x00000000, 0x00050006, 0x00000042, + 0x00000000, 0x61746164, 0x00000000, 0x00030005, 0x00000044, 0x00000000, 0x00040047, 0x0000000c, + 0x0000000b, 0x0000001c, 0x00040047, 0x00000015, 0x00000022, 0x00000000, 0x00040047, 0x00000015, + 0x00000021, 0x00000000, 0x00030047, 0x00000015, 0x00000018, 0x00040047, 0x00000041, 0x00000006, + 0x00000004, 0x00050048, 0x00000042, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000042, + 0x00000003, 0x00040047, 0x00000044, 0x00000022, 0x00000000, 0x00040047, 0x00000044, 0x00000021, + 0x00000001, 0x00040047, 0x0000004c, 0x0000000b, 0x00000019, 0x00020013, 0x00000002, 0x00030021, + 0x00000003, 0x00000002, 0x00040015, 0x00000006, 0x00000020, 0x00000000, 0x00040017, 0x00000007, + 0x00000006, 0x00000002, 0x00040020, 0x00000008, 0x00000007, 0x00000007, 0x00040017, 0x0000000a, + 0x00000006, 0x00000003, 0x00040020, 0x0000000b, 0x00000001, 0x0000000a, 0x0004003b, 0x0000000b, + 0x0000000c, 0x00000001, 0x00040015, 0x0000000f, 0x00000020, 0x00000001, 0x00040017, 0x00000010, + 0x0000000f, 0x00000002, 0x00040020, 0x00000011, 0x00000007, 0x00000010, 0x00090019, 0x00000013, + 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000021, 0x00040020, + 0x00000014, 0x00000000, 0x00000013, 0x0004003b, 0x00000014, 0x00000015, 0x00000000, 0x00020014, + 0x00000018, 0x0004002b, 0x00000006, 0x00000019, 0x00000000, 0x00040020, 0x0000001a, 0x00000007, + 0x00000006, 0x00040020, 0x0000001d, 0x00000007, 0x0000000f, 0x0004002b, 0x00000006, 0x00000025, + 0x00000001, 0x00040017, 0x00000030, 0x00000006, 0x00000004, 0x00040020, 0x00000031, 0x00000007, + 0x00000030, 0x0003001d, 0x00000041, 0x00000006, 0x0003001e, 0x00000042, 0x00000041, 0x00040020, + 0x00000043, 0x00000002, 0x00000042, 0x0004003b, 0x00000043, 0x00000044, 0x00000002, 0x0004002b, + 0x0000000f, 0x00000045, 0x00000000, 0x00040020, 0x00000049, 0x00000002, 0x00000006, 0x0004002b, + 0x00000006, 0x0000004b, 0x00000010, 0x0006002c, 0x0000000a, 0x0000004c, 0x0000004b, 0x0000004b, + 0x00000025, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, + 0x0004003b, 0x00000008, 0x00000009, 0x00000007, 0x0004003b, 0x00000011, 0x00000012, 0x00000007, + 0x0004003b, 0x00000031, 0x00000032, 0x00000007, 0x0004003b, 0x0000001a, 0x00000037, 0x00000007, + 0x0004003d, 0x0000000a, 0x0000000d, 0x0000000c, 0x0007004f, 0x00000007, 0x0000000e, 0x0000000d, + 0x0000000d, 0x00000000, 0x00000001, 0x0003003e, 0x00000009, 0x0000000e, 0x0004003d, 0x00000013, + 0x00000016, 0x00000015, 0x00040068, 0x00000010, 0x00000017, 0x00000016, 0x0003003e, 0x00000012, + 0x00000017, 0x00050041, 0x0000001a, 0x0000001b, 0x00000009, 0x00000019, 0x0004003d, 0x00000006, + 0x0000001c, 0x0000001b, 0x00050041, 0x0000001d, 0x0000001e, 0x00000012, 0x00000019, 0x0004003d, + 0x0000000f, 0x0000001f, 0x0000001e, 0x0004007c, 0x00000006, 0x00000020, 0x0000001f, 0x000500ae, + 0x00000018, 0x00000021, 0x0000001c, 0x00000020, 0x000400a8, 0x00000018, 0x00000022, 0x00000021, + 0x000300f7, 0x00000024, 0x00000000, 0x000400fa, 0x00000022, 0x00000023, 0x00000024, 0x000200f8, + 0x00000023, 0x00050041, 0x0000001a, 0x00000026, 0x00000009, 0x00000025, 0x0004003d, 0x00000006, + 0x00000027, 0x00000026, 0x00050041, 0x0000001d, 0x00000028, 0x00000012, 0x00000025, 0x0004003d, + 0x0000000f, 0x00000029, 0x00000028, 0x0004007c, 0x00000006, 0x0000002a, 0x00000029, 0x000500ae, + 0x00000018, 0x0000002b, 0x00000027, 0x0000002a, 0x000200f9, 0x00000024, 0x000200f8, 0x00000024, + 0x000700f5, 0x00000018, 0x0000002c, 0x00000021, 0x00000005, 0x0000002b, 0x00000023, 0x000300f7, + 0x0000002e, 0x00000000, 0x000400fa, 0x0000002c, 0x0000002d, 0x0000002e, 0x000200f8, 0x0000002d, + 0x000100fd, 0x000200f8, 0x0000002e, 0x0004003d, 0x00000013, 0x00000033, 0x00000015, 0x0004003d, + 0x00000007, 0x00000034, 0x00000009, 0x0004007c, 0x00000010, 0x00000035, 0x00000034, 0x00050062, + 0x00000030, 0x00000036, 0x00000033, 0x00000035, 0x0003003e, 0x00000032, 0x00000036, 0x00050041, + 0x0000001a, 0x00000038, 0x00000009, 0x00000025, 0x0004003d, 0x00000006, 0x00000039, 0x00000038, + 0x00050041, 0x0000001d, 0x0000003a, 0x00000012, 0x00000019, 0x0004003d, 0x0000000f, 0x0000003b, + 0x0000003a, 0x0004007c, 0x00000006, 0x0000003c, 0x0000003b, 0x00050084, 0x00000006, 0x0000003d, + 0x00000039, 0x0000003c, 0x00050041, 0x0000001a, 0x0000003e, 0x00000009, 0x00000019, 0x0004003d, + 0x00000006, 0x0000003f, 0x0000003e, 0x00050080, 0x00000006, 0x00000040, 0x0000003d, 0x0000003f, + 0x0003003e, 0x00000037, 0x00000040, 0x0004003d, 0x00000006, 0x00000046, 0x00000037, 0x00050041, + 0x0000001a, 0x00000047, 0x00000032, 0x00000019, 0x0004003d, 0x00000006, 0x00000048, 0x00000047, + 0x00060041, 0x00000049, 0x0000004a, 0x00000044, 0x00000045, 0x00000046, 0x0003003e, 0x0000004a, + 0x00000048, 0x000100fd, 0x00010038, + }; - GFXRECON_LOG_WARNING("AHardwareBuffer cannot be read: hardware buffer data will be omitted " - "from the capture file"); + VkShaderModuleCreateInfo shaderModuleCreateInfo; + shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shaderModuleCreateInfo.pNext = nullptr; + shaderModuleCreateInfo.flags = 0u; + shaderModuleCreateInfo.codeSize = shader.size() * sizeof(uint32_t); + shaderModuleCreateInfo.pCode = shader.data(); + VkShaderModule computeShaderModule = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateShaderModule( + device_unwrapped, &shaderModuleCreateInfo, nullptr, &computeShaderModule); + + VkPipelineShaderStageCreateInfo shaderStageCreateInfo; + shaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageCreateInfo.pNext = nullptr; + shaderStageCreateInfo.flags = 0u; + shaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + shaderStageCreateInfo.module = computeShaderModule; + shaderStageCreateInfo.pName = "main"; + shaderStageCreateInfo.pSpecializationInfo = nullptr; + + VkDescriptorSetLayoutBinding bindings[2]; + bindings[0].binding = 0u; + bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + bindings[0].descriptorCount = 1u; + bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + bindings[0].pImmutableSamplers = nullptr; + bindings[1].binding = 1u; + bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + bindings[1].descriptorCount = 1u; + bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + bindings[1].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo; + descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.pNext = nullptr; + descriptorSetLayoutCreateInfo.flags = 0u; + descriptorSetLayoutCreateInfo.bindingCount = 2u; + descriptorSetLayoutCreateInfo.pBindings = bindings; + + VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateDescriptorSetLayout( + device_unwrapped, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout); + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo; + pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.pNext = nullptr; + pipelineLayoutCreateInfo.flags = 0u; + pipelineLayoutCreateInfo.setLayoutCount = 1u; + pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout; + pipelineLayoutCreateInfo.pushConstantRangeCount = 0u; + pipelineLayoutCreateInfo.pPushConstantRanges = nullptr; + + VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreatePipelineLayout( + device_unwrapped, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout); + + VkComputePipelineCreateInfo computePipelineCreateInfo; + computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.pNext = nullptr; + computePipelineCreateInfo.flags = 0u; + computePipelineCreateInfo.stage = shaderStageCreateInfo; + computePipelineCreateInfo.layout = pipelineLayout; + computePipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + computePipelineCreateInfo.basePipelineIndex = -1; + + VkPipeline computePipeline = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateComputePipelines( + device_unwrapped, VK_NULL_HANDLE, 1u, &computePipelineCreateInfo, nullptr, &computePipeline); + + VkDescriptorPoolSize poolSizes[2]; + poolSizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + poolSizes[0].descriptorCount = 1u; + poolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + poolSizes[1].descriptorCount = 1u; + + VkDescriptorPoolCreateInfo descriptorPoolCreateInfo; + descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolCreateInfo.pNext = nullptr; + descriptorPoolCreateInfo.flags = 0u; + descriptorPoolCreateInfo.maxSets = 1u; + descriptorPoolCreateInfo.poolSizeCount = 2u; + descriptorPoolCreateInfo.pPoolSizes = poolSizes; + + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateDescriptorPool( + device_unwrapped, &descriptorPoolCreateInfo, nullptr, &descriptorPool); + + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo; + descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptorSetAllocateInfo.pNext = nullptr; + descriptorSetAllocateInfo.descriptorPool = descriptorPool; + descriptorSetAllocateInfo.descriptorSetCount = 1u; + descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayout; + + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateDescriptorSets(device_unwrapped, &descriptorSetAllocateInfo, &descriptorSet); + + VkDescriptorImageInfo imageInfo = {}; + imageInfo.sampler = VK_NULL_HANDLE; + imageInfo.imageView = imageView; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + + VkDescriptorBufferInfo bufferInfo; + bufferInfo.buffer = buffer; + bufferInfo.offset = 0u; + bufferInfo.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet descriptorWrites[2]; + descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[0].pNext = nullptr; + descriptorWrites[0].dstSet = descriptorSet; + descriptorWrites[0].dstBinding = 0u; + descriptorWrites[0].dstArrayElement = 0u; + descriptorWrites[0].descriptorCount = 1u; + descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + descriptorWrites[0].pImageInfo = &imageInfo; + descriptorWrites[0].pBufferInfo = nullptr; + descriptorWrites[0].pTexelBufferView = nullptr; + descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[1].pNext = nullptr; + descriptorWrites[1].dstSet = descriptorSet; + descriptorWrites[1].dstBinding = 1u; + descriptorWrites[1].dstArrayElement = 0u; + descriptorWrites[1].descriptorCount = 1u; + descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrites[1].pImageInfo = nullptr; + descriptorWrites[1].pBufferInfo = &bufferInfo; + descriptorWrites[1].pTexelBufferView = nullptr; + + if (vk_result == VK_SUCCESS) + device_table->UpdateDescriptorSets(device, 2u, descriptorWrites, 0u, nullptr); + + VkCommandPoolCreateInfo commandPoolCreateInfo; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.pNext = nullptr; + commandPoolCreateInfo.flags = 0u; + commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex; + + VkCommandPool commandPool = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->CreateCommandPool(device_unwrapped, &commandPoolCreateInfo, nullptr, &commandPool); + + VkCommandBufferAllocateInfo commandBufferAllocateInfo; + commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.pNext = nullptr; + commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocateInfo.commandPool = commandPool; + commandBufferAllocateInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = + device_table->AllocateCommandBuffers(device_unwrapped, &commandBufferAllocateInfo, &commandBuffer); + + VkCommandBufferBeginInfo commandBufferBeginInfo; + commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + commandBufferBeginInfo.pNext = nullptr; + commandBufferBeginInfo.flags = 0u; + commandBufferBeginInfo.pInheritanceInfo = nullptr; + if (vk_result == VK_SUCCESS) + vk_result = device_table->BeginCommandBuffer(commandBuffer, &commandBufferBeginInfo); + + if (vk_result == VK_SUCCESS) + { + VkImageMemoryBarrier barrier = {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.pNext = nullptr; + barrier.srcAccessMask = 0u; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = ahbImage; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.baseMipLevel = 0u; + barrier.subresourceRange.levelCount = 1u; + barrier.subresourceRange.baseArrayLayer = 0u; + barrier.subresourceRange.layerCount = 1u; + + device_table->CmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); + + device_table->CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline); + device_table->CmdBindDescriptorSets( + commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); + device_table->CmdDispatch(commandBuffer, (imageWidth + 15) / 16, (imageHeight + 15) / 16, 1u); + + VkBufferMemoryBarrier bufferBarrier; + bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + bufferBarrier.pNext = nullptr; + bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferBarrier.buffer = buffer; + bufferBarrier.offset = 0; + bufferBarrier.size = VK_WHOLE_SIZE; + + device_table->CmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + 0, + 0, + nullptr, + 1, + &bufferBarrier, + 0, + nullptr); + + device_table->EndCommandBuffer(commandBuffer); + } + + VkSubmitInfo submitInfo; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 0u; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + submitInfo.commandBufferCount = 1u; + submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.signalSemaphoreCount = 0u; + submitInfo.pSignalSemaphores = nullptr; + + VkFenceCreateInfo fenceCreateInfo; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.pNext = nullptr; + fenceCreateInfo.flags = 0u; + + VkFence fence = VK_NULL_HANDLE; + if (vk_result == VK_SUCCESS) + vk_result = device_table->CreateFence(device_unwrapped, &fenceCreateInfo, nullptr, &fence); + + if (vk_result == VK_SUCCESS) + vk_result = device_table->QueueSubmit(queue_wrapper->handle, 1, &submitInfo, fence); + if (vk_result == VK_SUCCESS) + vk_result = device_table->WaitForFences(device_unwrapped, 1u, &fence, VK_TRUE, UINT64_MAX); + + void* data; + if (vk_result == VK_SUCCESS) + { + vk_result = device_table->MapMemory(device, bufferMemory, 0u, ahb_size, 0u, &data); + WriteFillMemoryCmd(memory_id, 0, ahb_size, data); + } + + // Track the memory with the PageGuardManager + if ((GetMemoryTrackingMode() == CaptureSettings::MemoryTrackingMode::kPageGuard || + GetMemoryTrackingMode() == CaptureSettings::MemoryTrackingMode::kUserfaultfd) && + GetPageGuardTrackAhbMemory()) + { + GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, ahb_size); + + util::PageGuardManager* manager = util::PageGuardManager::Get(); + assert(manager != nullptr); + + manager->AddTrackedMemory(memory_id, + data, + 0, + static_cast(ahb_size), + util::PageGuardManager::kNullShadowHandle, + false, // No shadow memory for the imported AHB memory. + false); // Write watch is not supported for this case. + } + + device_table->DestroyFence(device_unwrapped, fence, nullptr); + device_table->DestroyCommandPool(device_unwrapped, commandPool, nullptr); + device_table->DestroyDescriptorPool(device_unwrapped, descriptorPool, nullptr); + device_table->DestroyPipeline(device_unwrapped, computePipeline, nullptr); + device_table->DestroyPipelineLayout(device_unwrapped, pipelineLayout, nullptr); + device_table->DestroyDescriptorSetLayout(device_unwrapped, descriptorSetLayout, nullptr); + device_table->DestroyShaderModule(device_unwrapped, computeShaderModule, nullptr); + device_table->FreeMemory(device_unwrapped, bufferMemory, nullptr); + device_table->DestroyBuffer(device_unwrapped, buffer, nullptr); + device_table->DestroyImageView(device_unwrapped, imageView, nullptr); + device_table->FreeMemory(device_unwrapped, imageMemory, nullptr); + device_table->DestroyImage(device_unwrapped, ahbImage, nullptr); + + if (vk_result != VK_SUCCESS) + { + GFXRECON_LOG_ERROR("Failed to capture data for AHardwareBuffer object (Memory ID = %" PRIu64 ")", + memory_id); + } } } #else diff --git a/framework/encode/vulkan_capture_manager.h b/framework/encode/vulkan_capture_manager.h index 284005e96..29c3a03de 100644 --- a/framework/encode/vulkan_capture_manager.h +++ b/framework/encode/vulkan_capture_manager.h @@ -1332,7 +1332,9 @@ class VulkanCaptureManager : public ApiCaptureManager uint32_t width, uint32_t height, VkSurfaceTransformFlagBitsKHR pre_transform); - void WriteCreateHardwareBufferCmd(format::HandleId memory_id, + void WriteCreateHardwareBufferCmd(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, AHardwareBuffer* buffer, const std::vector& plane_info); void WriteDestroyHardwareBufferCmd(AHardwareBuffer* buffer); diff --git a/framework/encode/vulkan_handle_wrappers.h b/framework/encode/vulkan_handle_wrappers.h index e131d8026..90bcf7cd9 100644 --- a/framework/encode/vulkan_handle_wrappers.h +++ b/framework/encode/vulkan_handle_wrappers.h @@ -165,6 +165,7 @@ struct DeviceWrapper : public HandleWrapper // Physical device property & feature state at device creation graphics::VulkanDevicePropertyFeatureInfo property_feature_info; std::unordered_map queue_family_creation_flags; + std::vector queue_family_indices; }; struct FenceWrapper : public HandleWrapper diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index 5b724681a..031c07f99 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -1108,7 +1108,8 @@ void VulkanStateWriter::WriteDeviceMemoryState(const VulkanStateTable& state_tab for (auto hardware_buffer : hardware_buffers) { const vulkan_wrappers::DeviceMemoryWrapper* wrapper = hardware_buffer.second; - ProcessHardwareBuffer(wrapper->hardware_buffer_memory_id, wrapper->hardware_buffer, wrapper->allocation_size); + ProcessHardwareBuffer( + wrapper->device_id, wrapper->hardware_buffer_memory_id, wrapper->hardware_buffer, wrapper->allocation_size); } #endif @@ -1245,7 +1246,8 @@ void VulkanStateWriter::WriteDeferredOperationJoinCommand(format::HandleId devic parameter_stream_.Clear(); } -void VulkanStateWriter::ProcessHardwareBuffer(format::HandleId memory_id, +void VulkanStateWriter::ProcessHardwareBuffer(format::HandleId device_id, + format::HandleId memory_id, AHardwareBuffer* hardware_buffer, VkDeviceSize allocation_size) { @@ -1288,7 +1290,7 @@ void VulkanStateWriter::ProcessHardwareBuffer(format::HandleId memory_id, #endif // Write CreateHardwareBufferCmd with or without the AHB payload - WriteCreateHardwareBufferCmd(memory_id, hardware_buffer, plane_info); + WriteCreateHardwareBufferCmd(0u, 0u, memory_id, hardware_buffer, plane_info); // If AHardwareBuffer_lockPlanes failed (or is not available) try AHardwareBuffer_lock if (result != 0) @@ -2894,7 +2896,9 @@ void VulkanStateWriter::WriteResizeWindowCmd2(format::HandleId surf // TODO: This is the same code used by CaptureManager to write command data. It could be moved to a format // utility. -void VulkanStateWriter::WriteCreateHardwareBufferCmd(format::HandleId memory_id, +void VulkanStateWriter::WriteCreateHardwareBufferCmd(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, AHardwareBuffer* hardware_buffer, const std::vector& plane_info) { @@ -2908,6 +2912,8 @@ void VulkanStateWriter::WriteCreateHardwareBufferCmd(format::HandleId memory_id, create_buffer_cmd.meta_header.meta_data_id = format::MakeMetaDataId( format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kCreateHardwareBufferCommand); create_buffer_cmd.thread_id = thread_id_; + create_buffer_cmd.device_id = device_id; + create_buffer_cmd.queue_id = queue_id; create_buffer_cmd.memory_id = memory_id; create_buffer_cmd.buffer_id = reinterpret_cast(hardware_buffer); diff --git a/framework/encode/vulkan_state_writer.h b/framework/encode/vulkan_state_writer.h index ee6e6c9b7..ba4b3b9b0 100644 --- a/framework/encode/vulkan_state_writer.h +++ b/framework/encode/vulkan_state_writer.h @@ -144,8 +144,10 @@ class VulkanStateWriter void WriteDeferredOperationJoinCommand(format::HandleId device_id, format::HandleId deferred_operation_id); - void - ProcessHardwareBuffer(format::HandleId memory_id, AHardwareBuffer* hardware_buffer, VkDeviceSize allocation_size); + void ProcessHardwareBuffer(format::HandleId device_id, + format::HandleId memory_id, + AHardwareBuffer* hardware_buffer, + VkDeviceSize allocation_size); void ProcessBufferMemory(const vulkan_wrappers::DeviceWrapper* device_wrapper, const std::vector& buffer_snapshot_info, @@ -280,7 +282,9 @@ class VulkanStateWriter uint32_t height, VkSurfaceTransformFlagBitsKHR pre_transform); - void WriteCreateHardwareBufferCmd(format::HandleId memory_id, + void WriteCreateHardwareBufferCmd(format::HandleId device_id, + format::HandleId queue_id, + format::HandleId memory_id, AHardwareBuffer* hardware_buffer, const std::vector& plane_info); diff --git a/framework/format/format.h b/framework/format/format.h index 00791ffad..26ca51cea 100644 --- a/framework/format/format.h +++ b/framework/format/format.h @@ -122,40 +122,41 @@ enum AdapterType enum class MetaDataType : uint16_t { - kUnknownMetaDataType = 0, - kDisplayMessageCommand = 1, - kFillMemoryCommand = 2, - kResizeWindowCommand = 3, - kSetSwapchainImageStateCommand = 4, - kBeginResourceInitCommand = 5, - kEndResourceInitCommand = 6, - kInitBufferCommand = 7, - kInitImageCommand = 8, - kCreateHardwareBufferCommand_deprecated = 9, - kDestroyHardwareBufferCommand = 10, - kSetDevicePropertiesCommand = 11, - kSetDeviceMemoryPropertiesCommand = 12, - kResizeWindowCommand2 = 13, - kSetOpaqueAddressCommand = 14, - kSetRayTracingShaderGroupHandlesCommand = 15, - kCreateHeapAllocationCommand = 16, - kInitSubresourceCommand = 17, - kExeFileInfoCommand = 18, - kInitDx12AccelerationStructureCommand = 19, - kFillMemoryResourceValueCommand = 20, - kDxgiAdapterInfoCommand = 21, - kDriverInfoCommand = 22, - kReserved23 = 23, - kCreateHardwareBufferCommand = 24, - kReserved25 = 25, - kDx12RuntimeInfoCommand = 26, - kParentToChildDependency = 27, - kReserved28 = 28, - kReserved29 = 29, - kReserved30 = 30, - kReserved31 = 31, - kSetEnvironmentVariablesCommand = 32, - kViewRelativeLocation = 33, + kUnknownMetaDataType = 0, + kDisplayMessageCommand = 1, + kFillMemoryCommand = 2, + kResizeWindowCommand = 3, + kSetSwapchainImageStateCommand = 4, + kBeginResourceInitCommand = 5, + kEndResourceInitCommand = 6, + kInitBufferCommand = 7, + kInitImageCommand = 8, + kCreateHardwareBufferCommand_deprecated = 9, + kDestroyHardwareBufferCommand = 10, + kSetDevicePropertiesCommand = 11, + kSetDeviceMemoryPropertiesCommand = 12, + kResizeWindowCommand2 = 13, + kSetOpaqueAddressCommand = 14, + kSetRayTracingShaderGroupHandlesCommand = 15, + kCreateHeapAllocationCommand = 16, + kInitSubresourceCommand = 17, + kExeFileInfoCommand = 18, + kInitDx12AccelerationStructureCommand = 19, + kFillMemoryResourceValueCommand = 20, + kDxgiAdapterInfoCommand = 21, + kDriverInfoCommand = 22, + kReserved23 = 23, + kCreateHardwareBufferCommand_deprecated2 = 24, + kReserved25 = 25, + kDx12RuntimeInfoCommand = 26, + kParentToChildDependency = 27, + kReserved28 = 28, + kReserved29 = 29, + kReserved30 = 30, + kReserved31 = 31, + kSetEnvironmentVariablesCommand = 32, + kViewRelativeLocation = 33, + kCreateHardwareBufferCommand = 34, }; // MetaDataId is stored in the capture file and its type must be uint32_t to avoid breaking capture file compatibility. @@ -404,10 +405,28 @@ struct CreateHardwareBufferCommandHeader_deprecated // HardwareBufferLayerInfo records. When unavailable, 'planes' is zero. }; +struct CreateHardwareBufferCommandHeader_deprecated2 +{ + MetaDataHeader meta_header; + ThreadId thread_id; + HandleId memory_id; // Globally unique ID assigned to the buffer for tracking memory modifications. + uint64_t buffer_id; // Address of the buffer object. + uint32_t format; + uint32_t width; + uint32_t height; + uint32_t stride; // Size of a row in pixels. + uint64_t usage; + uint32_t layers; + uint32_t planes; // When additional multi-plane data is available, header is followed by 'planes' count + // HardwareBufferLayerInfo records. When unavailable, 'planes' is zero. +}; + struct CreateHardwareBufferCommandHeader { MetaDataHeader meta_header; ThreadId thread_id; + HandleId device_id; + HandleId queue_id; HandleId memory_id; // Globally unique ID assigned to the buffer for tracking memory modifications. uint64_t buffer_id; // Address of the buffer object. uint32_t format;