Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions framework/encode/vulkan_capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2239,12 +2239,18 @@ void VulkanCaptureManager::ProcessImportFdForBuffer(VkDevice device, VkBuffer bu
device_wrapper->property_feature_info,
device_wrapper->physical_device->memory_properties);

vulkan_wrappers::RegisterDeviceQueues(resource_util, device_wrapper);

VkResult result = resource_util.CreateStagingBuffer(buffer_wrapper->size);
if (result == VK_SUCCESS)
{
std::vector<uint8_t> data;
result = resource_util.ReadFromBufferResource(
buffer, buffer_wrapper->size, memoryOffset, buffer_wrapper->queue_family_index, data);
buffer,
buffer_wrapper->size,
memoryOffset,
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, buffer_wrapper->queue_family_index),
data);
if (result == VK_SUCCESS)
{
WriteBeginResourceInitCmd(device_wrapper->handle_id, buffer_wrapper->size, buffer_wrapper->size);
Expand Down Expand Up @@ -2273,6 +2279,8 @@ void VulkanCaptureManager::ProcessImportFdForImage(VkDevice device, VkImage imag
device_wrapper->property_feature_info,
device_wrapper->physical_device->memory_properties);

vulkan_wrappers::RegisterDeviceQueues(resource_util, device_wrapper);

std::vector<VkImageAspectFlagBits> aspects;
graphics::GetFormatAspects(image_wrapper->format, &aspects);

Expand Down Expand Up @@ -2316,7 +2324,8 @@ void VulkanCaptureManager::ProcessImportFdForImage(VkDevice device, VkImage imag
image_resource.tiling = image_wrapper->tiling;
image_resource.sample_count = image_wrapper->samples;
image_resource.layout = image_wrapper->current_layout;
image_resource.queue_family_index = image_wrapper->queue_family_index;
image_resource.queue_family_index =
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, image_wrapper->queue_family_index);
image_resource.external_format = image_wrapper->external_format;
image_resource.size = image_wrapper->size;
image_resource.aspect = aspect;
Expand Down
65 changes: 65 additions & 0 deletions framework/encode/vulkan_handle_wrapper_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "generated/generated_vulkan_dispatch_table.h"
#include "generated/generated_vulkan_state_table.h"
#include "util/defines.h"
#include "graphics/vulkan_resources_util.h"
#include "graphics/vulkan_util.h"

#include <algorithm>
Expand All @@ -43,6 +44,70 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon)
GFXRECON_BEGIN_NAMESPACE(encode)
GFXRECON_BEGIN_NAMESPACE(vulkan_wrappers)

const uint32_t kDefaultQueueFamilyIndex = 0;

inline bool IsSpecialQueueFamilyIndex(uint32_t queue_family_index)
{
return (queue_family_index == VK_QUEUE_FAMILY_IGNORED) || (queue_family_index == VK_QUEUE_FAMILY_EXTERNAL) ||
(queue_family_index == VK_QUEUE_FAMILY_FOREIGN_EXT);
}

/**
* @brief Validates a queue family index against the valid queue family indices of a device wrapper.
*
* If the provided queue_family_index is a special index (e.g. VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL,
* or VK_QUEUE_FAMILY_FOREIGN_EXT) or not present in the device's configured queue family indices, this function
* falls back to the device's primary queue family or the default queue family index (0).
*
* @param device_wrapper The device wrapper containing valid queue family indices from device creation.
* @param queue_family_index The queue family index to validate.
* @return A valid queue family index that belongs to the device.
*/
inline uint32_t GetValidQueueFamilyIndex(const DeviceWrapper* device_wrapper, uint32_t queue_family_index)
{
if ((device_wrapper != nullptr) && !device_wrapper->queue_family_indices.empty())
{
if (!IsSpecialQueueFamilyIndex(queue_family_index))
{
const auto& indices = device_wrapper->queue_family_indices;
if (std::find(indices.begin(), indices.end(), queue_family_index) != indices.end())
{
return queue_family_index;
}
}
return device_wrapper->queue_family_indices.front();
}
return !IsSpecialQueueFamilyIndex(queue_family_index) ? queue_family_index : kDefaultQueueFamilyIndex;
}

/**
* @brief Registers active child queues from a DeviceWrapper into a VulkanResourcesUtil instance.
*
* @param resource_util The resource utility instance to configure.
* @param device_wrapper The device wrapper holding active child queues.
*/
inline void RegisterDeviceQueues(graphics::VulkanResourcesUtil& resource_util, const DeviceWrapper* device_wrapper)
{
if (device_wrapper == nullptr)
{
return;
}

for (size_t i = 0; i < device_wrapper->child_queues.size(); ++i)
{
const auto* queue_wrapper = device_wrapper->child_queues[i];
if ((queue_wrapper != nullptr) && (queue_wrapper->handle != VK_NULL_HANDLE))
{
uint32_t qfi =
(i < device_wrapper->queue_family_indices.size())
? device_wrapper->queue_family_indices[i]
: ((!device_wrapper->queue_family_indices.empty()) ? device_wrapper->queue_family_indices.front()
: kDefaultQueueFamilyIndex);
resource_util.SetQueue(qfi, queue_wrapper->handle);
}
}
}

// Temporary resource IDs for state processing.
static const format::HandleId kTempQueueId = std::numeric_limits<format::HandleId>::max() - 1;
static const VkCommandPool kTempCommandPool =
Expand Down
12 changes: 11 additions & 1 deletion framework/encode/vulkan_state_tracker_initializers.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,22 @@ inline void InitializeState<VkPhysicalDevice, vulkan_wrappers::DeviceWrapper, Vk
assert(wrapper != nullptr);
assert(create_parameters != nullptr);

GFXRECON_UNREFERENCED_PARAMETER(create_info);
assert(create_info != nullptr);

wrapper->create_call_id = create_call_id;
wrapper->create_parameters = std::move(create_parameters);

wrapper->physical_device = vulkan_wrappers::GetWrapper<vulkan_wrappers::PhysicalDeviceWrapper>(parent_handle);

wrapper->queue_family_indices.clear();
if ((create_info != nullptr) && (create_info->pQueueCreateInfos != nullptr))
{
wrapper->queue_family_indices.reserve(create_info->queueCreateInfoCount);
for (uint32_t q = 0; q < create_info->queueCreateInfoCount; ++q)
{
wrapper->queue_family_indices.push_back(create_info->pQueueCreateInfos[q].queueFamilyIndex);
}
}
}

template <>
Expand Down
31 changes: 20 additions & 11 deletions framework/encode/vulkan_state_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
GFXRECON_BEGIN_NAMESPACE(gfxrecon)
GFXRECON_BEGIN_NAMESPACE(encode)

const uint32_t kDefaultQueueFamilyIndex = 0;

static bool IsMemoryCoherent(VkMemoryPropertyFlags property_flags)
{
return ((property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Expand Down Expand Up @@ -2312,7 +2310,8 @@ void VulkanStateWriter::ProcessBufferMemory(const vulkan_wrappers::DeviceWrapper
buffer_resource.buffer = buffer_wrapper->handle;
buffer_resource.size = buffer_wrapper->size;
buffer_resource.offset = 0;
buffer_resource.queue_family_index = buffer_wrapper->queue_family_index;
buffer_resource.queue_family_index =
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, buffer_wrapper->queue_family_index);

if (snapshot_entry.need_staging_copy)
{
Expand Down Expand Up @@ -2439,7 +2438,8 @@ void VulkanStateWriter::ProcessBufferMemoryWithAssetFile(const vulkan_wrappers::
buffer_resource.buffer = buffer_wrapper->handle;
buffer_resource.size = buffer_wrapper->size;
buffer_resource.offset = 0;
buffer_resource.queue_family_index = buffer_wrapper->queue_family_index;
buffer_resource.queue_family_index =
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, buffer_wrapper->queue_family_index);

if (snapshot_entry.need_staging_copy)
{
Expand Down Expand Up @@ -2570,7 +2570,8 @@ void VulkanStateWriter::ProcessImageMemory(const vulkan_wrappers::DeviceWrapper*
image_resource.tiling = image_wrapper->tiling;
image_resource.sample_count = image_wrapper->samples;
image_resource.layout = image_wrapper->current_layout;
image_resource.queue_family_index = image_wrapper->queue_family_index;
image_resource.queue_family_index =
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, image_wrapper->queue_family_index);
image_resource.external_format = image_wrapper->external_format;
image_resource.size = image_wrapper->size;
image_resource.resource_size = snapshot_entry.resource_size;
Expand Down Expand Up @@ -2750,7 +2751,8 @@ void VulkanStateWriter::ProcessImageMemoryWithAssetFile(const vulkan_wrappers::D
image_resource.tiling = image_wrapper->tiling;
image_resource.sample_count = image_wrapper->samples;
image_resource.layout = image_wrapper->current_layout;
image_resource.queue_family_index = image_wrapper->queue_family_index;
image_resource.queue_family_index =
vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, image_wrapper->queue_family_index);
image_resource.size = image_wrapper->size;
image_resource.resource_size = snapshot_entry.resource_size;
image_resource.level_sizes = &snapshot_entry.level_sizes;
Expand Down Expand Up @@ -2895,7 +2897,8 @@ void VulkanStateWriter::WriteBufferMemoryState(const VulkanStateTable& state_tab

// Group buffers with memory bindings by device for memory snapshot.
ResourceSnapshotQueueFamilyTable& snapshot_table = (*resources)[device_wrapper];
ResourceSnapshotInfo& snapshot_entry = snapshot_table[wrapper->queue_family_index];
ResourceSnapshotInfo& snapshot_entry = snapshot_table[vulkan_wrappers::GetValidQueueFamilyIndex(
device_wrapper, wrapper->queue_family_index)];

BufferSnapshotInfo snapshot_info;
snapshot_info.buffer_wrapper = wrapper;
Expand Down Expand Up @@ -3003,7 +3006,8 @@ void VulkanStateWriter::WriteBufferMemoryState(const VulkanStateTable& state_tab

// Group buffers with memory bindings by device for memory snapshot.
ResourceSnapshotQueueFamilyTable& snapshot_table = (*resources)[device_wrapper];
ResourceSnapshotInfo& snapshot_entry = snapshot_table[wrapper->queue_family_index];
ResourceSnapshotInfo& snapshot_entry =
snapshot_table[vulkan_wrappers::GetValidQueueFamilyIndex(device_wrapper, wrapper->queue_family_index)];

BufferSnapshotInfo snapshot_info;
snapshot_info.buffer_wrapper = wrapper;
Expand Down Expand Up @@ -3199,14 +3203,17 @@ void VulkanStateWriter::WriteImageMemoryState(const VulkanStateTable& state_tabl
{
// Group images with memory bindings by device for memory snapshot.
ResourceSnapshotQueueFamilyTable& snapshot_table = (*resources)[device_wrapper];
ResourceSnapshotInfo& snapshot_entry = snapshot_table[wrapper->queue_family_index];
graphics::VulkanResourcesUtil resource_util(device_wrapper->handle,
ResourceSnapshotInfo& snapshot_entry = snapshot_table[vulkan_wrappers::GetValidQueueFamilyIndex(
device_wrapper, wrapper->queue_family_index)];
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->property_feature_info,
device_wrapper->physical_device->memory_properties);

vulkan_wrappers::RegisterDeviceQueues(resource_util, device_wrapper);

// Sparse images require staging copy for the following process because dumping image data with mapping
// memory needs binding the entire image to a single memory range. Sparse image opaque binding allows
// binding to multiple memory objects and various memory ranges.
Expand Down Expand Up @@ -3349,6 +3356,8 @@ void VulkanStateWriter::WriteResourceMemoryState(const VulkanStateTable& state_t
device_wrapper->property_feature_info,
device_wrapper->physical_device->memory_properties);

vulkan_wrappers::RegisterDeviceQueues(resource_util, device_wrapper);

if (max_staging_copy_size > 0)
{
assert(device_wrapper != nullptr);
Expand Down Expand Up @@ -4021,7 +4030,7 @@ void VulkanStateWriter::WriteQueryPoolReset(
{
// Retrieve a queue and create a command buffer for query pool reset.
WriteCommandProcessingCreateCommands(device_id,
kDefaultQueueFamilyIndex,
vulkan_wrappers::kDefaultQueueFamilyIndex,
vulkan_wrappers::kTempQueueId,
vulkan_wrappers::kTempCommandPool,
vulkan_wrappers::kTempCommandBufferId);
Expand Down
23 changes: 21 additions & 2 deletions framework/graphics/vulkan_resources_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1506,19 +1506,38 @@ void VulkanResourcesUtil::CopyBuffer(VkCommandBuffer command_buffer,
nullptr);
}

void VulkanResourcesUtil::SetQueue(uint32_t queue_family_index, VkQueue queue)
{
if (queue != VK_NULL_HANDLE)
{
queue_map_[queue_family_index] = queue;
}
}

VkQueue VulkanResourcesUtil::GetQueue(uint32_t queue_family_index, uint32_t queue_index)
{
auto it = queue_map_.find(queue_family_index);
if (it != queue_map_.end() && it->second != VK_NULL_HANDLE)
{
return it->second;
}

VkQueue queue = VK_NULL_HANDLE;
device_table_.GetDeviceQueue(device_, queue_family_index, queue_index, &queue);
if (device_table_.GetDeviceQueue != nullptr)
{
device_table_.GetDeviceQueue(device_, queue_family_index, queue_index, &queue);
}

if (queue != VK_NULL_HANDLE)
{
// Because this queue was not allocated through the loader, it must be assigned a dispatch table.
*reinterpret_cast<void**>(queue) = *reinterpret_cast<void**>(device_);
queue_map_[queue_family_index] = queue;
}
else
{
GFXRECON_LOG_ERROR("Failed to retrieve a queue for resource memory snapshot");
GFXRECON_LOG_ERROR("Failed to retrieve a queue for queue family %u during resource memory snapshot",
queue_family_index);
}

return queue;
Expand Down
12 changes: 12 additions & 0 deletions framework/graphics/vulkan_resources_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ class VulkanResourcesUtil

~VulkanResourcesUtil();

/**
* @brief Registers an existing VkQueue handle for a specified queue family index.
*
* When set, GetQueue will prefer using registered queues instead of querying vkGetDeviceQueue,
* avoiding redundant driver/loader calls and potential issues during state snapshotting or replay.
*
* @param queue_family_index The Vulkan queue family index associated with the queue.
* @param queue The active VkQueue handle to use for commands on this queue family.
*/
void SetQueue(uint32_t queue_family_index, VkQueue queue);

// This function creates a staging buffer that will be used by the ReadFromImageResourceStaging() and
// ReadFromBufferResource() functions. It is not necessary to do so but can be useful when dumping multiple
// resource and the size of the biggest staging buffer necessary is known in advance.
Expand Down Expand Up @@ -374,6 +385,7 @@ class VulkanResourcesUtil

// map queue-family index -> command-pool/buffer
std::unordered_map<uint32_t, command_assets_t> command_asset_map_;
std::unordered_map<uint32_t, VkQueue> queue_map_;
StagingBufferContext staging_buffer_;

PFN_vkSetDebugUtilsObjectNameEXT set_debug_utils_object_name_fn_ = nullptr;
Expand Down
Loading