Skip to content
Merged
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
38 changes: 27 additions & 11 deletions layersvt/screenshot/screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,33 +1646,49 @@ VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCall
}
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue) {
DispatchMapStruct* dispMap = get_dispatch_info(device);
assert(dispMap);
VkuDeviceDispatchTable* pDisp = dispMap->device_dispatch_table;
pDisp->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
static void addDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, VkQueue queue, DispatchMapStruct* dispMap) {
if (queue == VK_NULL_HANDLE) return;

// Save the device queue in a map if we are taking screenshots.
std::lock_guard<std::mutex> lg(globalLock);

// Add this queue to deviceMap[device].queues, and queueFamilyIndex to deviceMap[device].queueIndexMap
if (deviceMap.find(device) != deviceMap.end()) {
deviceMap[device]->queues.emplace(*pQueue);
deviceMap[device]->queues.emplace(queue);

if (deviceMap[device]->queueIndexMap.find(*pQueue) != deviceMap[device]->queueIndexMap.end())
deviceMap[device]->queueIndexMap.erase(*pQueue);
deviceMap[device]->queueIndexMap.emplace(*pQueue, queueFamilyIndex);
if (deviceMap[device]->queueIndexMap.find(queue) != deviceMap[device]->queueIndexMap.end())
deviceMap[device]->queueIndexMap.erase(queue);
deviceMap[device]->queueIndexMap.emplace(queue, queueFamilyIndex);
}

// queues are dispatchable objects.
// Create dispatchMap entry with this queue as its key.
// Copy the device dispatch table to the new dispatch table.
VkDevice que = static_cast<VkDevice>(static_cast<void*>(*pQueue));
VkDevice que = static_cast<VkDevice>(static_cast<void*>(queue));
dispatchMap[que] = dispMap;
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue) {
DispatchMapStruct* dispMap = get_dispatch_info(device);
assert(dispMap);
VkuDeviceDispatchTable* pDisp = dispMap->device_dispatch_table;
pDisp->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);

if (pQueue) {
addDeviceQueue(device, queueFamilyIndex, *pQueue, dispMap);
}
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue) {
if (pQueueInfo) GetDeviceQueue(device, pQueueInfo->queueFamilyIndex, pQueueInfo->queueIndex, pQueue);
if (!pQueueInfo) return;
DispatchMapStruct* dispMap = get_dispatch_info(device);
assert(dispMap);
VkuDeviceDispatchTable* pDisp = dispMap->device_dispatch_table;
pDisp->GetDeviceQueue2(device, pQueueInfo, pQueue);

if (pQueue) {
addDeviceQueue(device, pQueueInfo->queueFamilyIndex, *pQueue, dispMap);
}
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo,
Expand Down
51 changes: 51 additions & 0 deletions layersvt/test/test_screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,54 @@ TEST_F(ScreenshotTests, init_layer) {
VkResult err = inst_builder.Init(settings);
EXPECT_EQ(err, VK_SUCCESS);
}

TEST_F(ScreenshotTests, get_device_queue2) {
TEST_DESCRIPTION("Test vkGetDeviceQueue2 forwards VkDeviceQueueInfo2 flags instead of downgrading to vkGetDeviceQueue");

layer_test::VulkanInstanceBuilder inst_builder;
VkResult err = inst_builder.Init(kLayerName);
ASSERT_EQ(err, VK_SUCCESS);

VkPhysicalDevice phys_dev = VK_NULL_HANDLE;
err = inst_builder.GetPhysicalDevice(&phys_dev);
if (err != VK_SUCCESS || phys_dev == VK_NULL_HANDLE) {
GTEST_SKIP() << "No Vulkan physical device available";
}

float queue_priority = 1.0f;
VkDeviceQueueCreateInfo queue_create_info = {};
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info.queueFamilyIndex = 0;
queue_create_info.queueCount = 1;
queue_create_info.pQueuePriorities = &queue_priority;

VkDeviceCreateInfo device_create_info = {};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.queueCreateInfoCount = 1;
device_create_info.pQueueCreateInfos = &queue_create_info;

VkDevice device = VK_NULL_HANDLE;
err = vkCreateDevice(phys_dev, &device_create_info, nullptr, &device);
ASSERT_EQ(err, VK_SUCCESS);
ASSERT_NE(device, VK_NULL_HANDLE);

VkDeviceQueueInfo2 queue_info = {};
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
queue_info.flags = 0;
queue_info.queueFamilyIndex = 0;
queue_info.queueIndex = 0;

VkQueue queue = VK_NULL_HANDLE;
vkGetDeviceQueue2(device, &queue_info, &queue);
EXPECT_NE(queue, VK_NULL_HANDLE);

// Querying a queue with mismatched flags (protected when created unprotected) must forward
// pQueueInfo to the driver's vkGetDeviceQueue2 rather than stripping flags via vkGetDeviceQueue.
VkDeviceQueueInfo2 protected_queue_info = queue_info;
protected_queue_info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
VkQueue protected_queue = queue;
vkGetDeviceQueue2(device, &protected_queue_info, &protected_queue);
EXPECT_EQ(protected_queue, VK_NULL_HANDLE);

vkDestroyDevice(device, nullptr);
}
Loading