diff options
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 36dd1d1d..7db1142b 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -11754,6 +11754,33 @@ static bool PreCallValidateCreateSwapchainKHR(layer_data *dev_data, VkSwapchainC } } + // Validate pCreateInfo values with the results of + // vkGetPhysicalDeviceSurfacePresentModesKHR(): + if (physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState != QUERY_DETAILS) { + /* FIFO is required to always be supported */ + if (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR) { + if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, + reinterpret_cast<uint64_t>(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, + "DS", "vkCreateSwapchainKHR() called before calling " + "vkGetPhysicalDeviceSurfacePresentModesKHR().")) + return true; + } + } else { + // Validate pCreateInfo->presentMode against + // vkGetPhysicalDeviceSurfacePresentModesKHR(): + bool foundMatch = std::find(physical_device_state->present_modes.begin(), + physical_device_state->present_modes.end(), + pCreateInfo->presentMode) != physical_device_state->present_modes.end(); + if (!foundMatch) { + if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, + reinterpret_cast<uint64_t>(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_BAD_PRESENT_MODE, "DS", + "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->presentMode (i.e. %s).", + string_VkPresentModeKHR(pCreateInfo->presentMode))) + return true; + } + } + + return false; } @@ -12300,6 +12327,70 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevi return result; } + +VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + uint32_t *pPresentModeCount, + VkPresentModeKHR *pPresentModes) { + bool skip_call = false; + auto instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + std::unique_lock<std::mutex> lock(global_lock); + // TODO: this isn't quite right. available modes may differ by surface AND physical device. + auto physical_device_state = getPhysicalDeviceState(instance_data, physicalDevice); + auto & call_state = physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState; + + if (pPresentModes) { + // Compare the preliminary value of *pPresentModeCount with the value this time: + auto prev_mode_count = (uint32_t) physical_device_state->present_modes.size(); + switch (call_state) { + case UNCALLED: + skip_call |= log_msg( + instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, + reinterpret_cast<uint64_t>(physicalDevice), __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", + "vkGetPhysicalDeviceSurfacePresentModesKHR() called with non-NULL pPresentModeCount; but no prior positive " + "value has been seen for pPresentModeCount."); + break; + default: + // both query count and query details + if (*pPresentModeCount != prev_mode_count) { + skip_call |= log_msg( + instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, + reinterpret_cast<uint64_t>(physicalDevice), __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", + "vkGetPhysicalDeviceSurfacePresentModesKHR() called with *pPresentModeCount (%u) that differs from the value " + "(%u) that was returned when pPresentModes was NULL.", + *pPresentModeCount, prev_mode_count); + } + break; + } + } + lock.unlock(); + + if (skip_call) + return VK_ERROR_VALIDATION_FAILED_EXT; + + auto result = instance_data->dispatch_table.GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes); + + if (result == VK_SUCCESS || result == VK_INCOMPLETE) { + + lock.lock(); + + if (*pPresentModeCount) { + if (call_state < QUERY_COUNT) call_state = QUERY_COUNT; + if (*pPresentModeCount > physical_device_state->present_modes.size()) + physical_device_state->present_modes.resize(*pPresentModeCount); + } + if (pPresentModes) { + if (call_state < QUERY_DETAILS) call_state = QUERY_DETAILS; + for (uint32_t i = 0; i < *pPresentModeCount; i++) { + physical_device_state->present_modes[i] = pPresentModes[i]; + } + } + + } + } + + return result; +} + VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { @@ -12645,6 +12736,8 @@ intercept_khr_surface_command(const char *name, VkInstance instance) { &instance_layer_data::surfaceExtensionEnabled}, {"vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR), &instance_layer_data::surfaceExtensionEnabled}, + {"vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR), + &instance_layer_data::surfaceExtensionEnabled}, }; instance_layer_data *instance_data = nullptr; |
