diff options
| author | John Zulauf <jzulauf@lunarg.com> | 2018-03-02 09:13:09 -0700 |
|---|---|---|
| committer | jzulauf-lunarg <32470354+jzulauf-lunarg@users.noreply.github.com> | 2018-03-05 11:48:31 -0700 |
| commit | 6202dcfbd9a59384b1eee2dd8bc9b84c07960742 (patch) | |
| tree | 1774003686ec5b3475399a9fad4c25862592e86d | |
| parent | 9ceac06c003b0bd2cc9005f200199b6393b9cc3d (diff) | |
| download | usermoji-6202dcfbd9a59384b1eee2dd8bc9b84c07960742.tar.xz | |
layers: Add VU checks for dedicated buffers/images
Add validation for the following valid usage for binding dedicated
allocations to buffers and images.
VALIDATION_ERROR_17000bc8 VUID-vkBindBufferMemory-memory-01508
VALIDATION_ERROR_17400bca VUID-vkBindImageMemory-memory-01509
The same code path checks the BindImage2/BufferMemory2, but there are no
matching VUID at this time.
Change-Id: I8b700059d8c0acdfabf0b30be3dca20f616b3be1
| -rw-r--r-- | layers/core_validation.cpp | 68 | ||||
| -rw-r--r-- | layers/core_validation.h | 5 | ||||
| -rw-r--r-- | layers/core_validation_types.h | 6 | ||||
| -rw-r--r-- | layers/vk_validation_error_database.txt | 4 |
4 files changed, 61 insertions, 22 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 74eae325..8f515460 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -353,18 +353,20 @@ static void add_mem_obj_info(layer_data *dev_data, void *object, const VkDeviceM const VkMemoryAllocateInfo *pAllocateInfo) { assert(object != NULL); - dev_data->memObjMap[mem] = unique_ptr<DEVICE_MEM_INFO>(new DEVICE_MEM_INFO(object, mem, pAllocateInfo)); - - if (pAllocateInfo->pNext) { - auto struct_header = reinterpret_cast<const GENERIC_HEADER *>(pAllocateInfo->pNext); - while (struct_header) { - if (VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR == struct_header->sType || - VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR == struct_header->sType) { - dev_data->memObjMap[mem]->global_valid = true; - break; - } - struct_header = reinterpret_cast<const GENERIC_HEADER *>(struct_header->pNext); - } + auto *mem_info = new DEVICE_MEM_INFO(object, mem, pAllocateInfo); + dev_data->memObjMap[mem] = unique_ptr<DEVICE_MEM_INFO>(mem_info); + + // TODO: If the number of things we search for goes much higher, need a map... + mem_info->global_valid = nullptr != lvl_find_in_chain<VkImportMemoryFdInfoKHR>(pAllocateInfo->pNext); +#ifdef VK_USE_PLATFORM_WIN32_KHR + mem_info->global_valid |= nullptr != lvl_find_in_chain<VkImportMemoryWin32HandleInfoKHR>(pAllocateInfo->pNext); +#endif + + auto dedicated = lvl_find_in_chain<VkMemoryDedicatedAllocateInfoKHR>(pAllocateInfo->pNext); + if (dedicated) { + mem_info->is_dedicated = true; + mem_info->dedicated_buffer = dedicated->buffer; + mem_info->dedicated_image = dedicated->image; } } @@ -3825,7 +3827,7 @@ static bool PreCallValidateBindBufferMemory(layer_data *dev_data, VkBuffer buffe } // Validate bound memory range information - auto mem_info = GetMemObjInfo(dev_data, mem); + const auto mem_info = GetMemObjInfo(dev_data, mem); if (mem_info) { skip |= ValidateInsertBufferMemoryRange(dev_data, buffer, mem_info, memoryOffset, buffer_state->requirements, api_name); skip |= ValidateMemoryTypes(dev_data, mem_info, buffer_state->requirements.memoryTypeBits, api_name, @@ -3843,8 +3845,8 @@ static bool PreCallValidateBindBufferMemory(layer_data *dev_data, VkBuffer buffe validation_error_map[VALIDATION_ERROR_17000818]); } - // Validate memory requirements size if (mem_info) { + // Validate memory requirements size if (buffer_state->requirements.size > (mem_info->alloc_info.allocationSize - memoryOffset)) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, buffer_handle, __LINE__, VALIDATION_ERROR_1700081a, "DS", @@ -3854,6 +3856,24 @@ static bool PreCallValidateBindBufferMemory(layer_data *dev_data, VkBuffer buffe api_name, mem_info->alloc_info.allocationSize - memoryOffset, buffer_state->requirements.size, validation_error_map[VALIDATION_ERROR_1700081a]); } + + // Validate dedicated allocation + if (mem_info->is_dedicated && ((mem_info->dedicated_buffer != buffer) || (memoryOffset != 0))) { + // TODO: Add vkBindBufferMemory2KHR error message when added to spec. + auto validation_error = VALIDATION_ERROR_UNDEFINED; + const char *validation_error_msg = ""; + if (strcmp(api_name, "vkBindBufferMemory()") == 0) { + validation_error = VALIDATION_ERROR_17000bc8; + validation_error_msg = validation_error_map[validation_error]; + } + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, + buffer_handle, __LINE__, validation_error, "DS", + "%s: for dedicated memory allocation 0x%" PRIxLEAST64 + ", VkMemoryDedicatedAllocateInfoKHR::buffer 0x%" PRIXLEAST64 + " must be equal to buffer 0x%" PRIxLEAST64 " and memoryOffset 0x%" PRIxLEAST64 " must be zero. %s", + api_name, HandleToUint64(mem), HandleToUint64(mem_info->dedicated_buffer), buffer_handle, + memoryOffset, validation_error_msg); + } } // Validate device limits alignments @@ -9513,8 +9533,8 @@ static bool PreCallValidateBindImageMemory(layer_data *dev_data, VkImage image, validation_error_map[VALIDATION_ERROR_17400830]); } - // Validate memory requirements size if (mem_info) { + // Validate memory requirements size if (image_state->requirements.size > mem_info->alloc_info.allocationSize - memoryOffset) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, __LINE__, VALIDATION_ERROR_17400832, "DS", @@ -9524,6 +9544,24 @@ static bool PreCallValidateBindImageMemory(layer_data *dev_data, VkImage image, api_name, mem_info->alloc_info.allocationSize - memoryOffset, image_state->requirements.size, validation_error_map[VALIDATION_ERROR_17400832]); } + + // Validate dedicated allocation + if (mem_info->is_dedicated && ((mem_info->dedicated_image != image) || (memoryOffset != 0))) { + // TODO: Add vkBindImageMemory2KHR error message when added to spec. + auto validation_error = VALIDATION_ERROR_UNDEFINED; + const char *validation_error_msg = ""; + if (strcmp(api_name, "vkBindImageMemory()") == 0) { + validation_error = VALIDATION_ERROR_17400bca; + validation_error_msg = validation_error_map[validation_error]; + } + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, + image_handle, __LINE__, validation_error, "DS", + "%s: for dedicated memory allocation 0x%" PRIxLEAST64 + ", VkMemoryDedicatedAllocateInfoKHR::image 0x%" PRIXLEAST64 + " must be equal to image 0x%" PRIxLEAST64 " and memoryOffset 0x%" PRIxLEAST64 " must be zero. %s", + api_name, HandleToUint64(mem), HandleToUint64(mem_info->dedicated_image), image_handle, + memoryOffset, validation_error_msg); + } } } return skip; diff --git a/layers/core_validation.h b/layers/core_validation.h index de1aeac5..79330d5f 100644 --- a/layers/core_validation.h +++ b/layers/core_validation.h @@ -68,11 +68,6 @@ // TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point? // TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used -struct GENERIC_HEADER { - VkStructureType sType; - const void *pNext; -}; - enum SyncScope { kSyncScopeInternal, kSyncScopeExternalTemporary, diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index bc5a554f..c7f0bead 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -318,6 +318,9 @@ struct DEVICE_MEM_INFO : public BASE_NODE { bool global_valid; // If allocation is mapped or external, set to "true" to be picked up by subsequently bound ranges VkDeviceMemory mem; VkMemoryAllocateInfo alloc_info; + bool is_dedicated; + VkBuffer dedicated_buffer; + VkImage dedicated_image; std::unordered_set<VK_OBJECT> obj_bindings; // objects bound to this memory std::unordered_map<uint64_t, MEMORY_RANGE> bound_ranges; // Map of object to its binding range // Convenience vectors image/buff handles to speed up iterating over images or buffers independently @@ -336,6 +339,9 @@ struct DEVICE_MEM_INFO : public BASE_NODE { global_valid(false), mem(in_mem), alloc_info(*p_alloc_info), + is_dedicated(false), + dedicated_buffer(VK_NULL_HANDLE), + dedicated_image(VK_NULL_HANDLE), mem_range{}, shadow_copy_base(0), shadow_copy(0), diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt index d71ef064..4e1a8e0f 100644 --- a/layers/vk_validation_error_database.txt +++ b/layers/vk_validation_error_database.txt @@ -1688,7 +1688,7 @@ VALIDATION_ERROR_1700081a~^~Y~^~BindInvalidMemory~^~vkBindBufferMemory~^~VUID-vk VALIDATION_ERROR_1700081c~^~N~^~Unknown~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-buffer-01038~^~(VK_NV_dedicated_allocation)~^~The spec valid usage text states 'If buffer was created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::buffer equal to a buffer handle created with identical creation parameters to buffer and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindBufferMemory-buffer-01038)~^~ VALIDATION_ERROR_1700081e~^~N~^~Unknown~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-buffer-01039~^~(VK_NV_dedicated_allocation)+!(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If buffer was not created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindBufferMemory-buffer-01039)~^~ VALIDATION_ERROR_17000b48~^~N~^~None~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-buffer-01444~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If buffer requires a dedicated allocation(as reported by vkGetBufferMemoryRequirements2KHR in VkMemoryDedicatedRequirementsKHR::requiresDedicatedAllocation for image), memory must have been created with VkMemoryDedicatedAllocateInfoKHR::buffer equal to buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindBufferMemory-buffer-01444)~^~ -VALIDATION_ERROR_17000bc8~^~N~^~None~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-memory-01508~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If the VkmemoryAllocateInfo provided when memory was allocated included an instance of VkMemoryDedicatedAllocateInfoKHR in its pNext chain, and VkMemoryDedicatedAllocateInfoKHR::buffer was not VK_NULL_HANDLE, then buffer must equal VkMemoryDedicatedAllocateInfoKHR::buffer and memoryOffset must be zero.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindBufferMemory-memory-01508)~^~ +VALIDATION_ERROR_17000bc8~^~Y~^~None~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-memory-01508~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If the VkmemoryAllocateInfo provided when memory was allocated included an instance of VkMemoryDedicatedAllocateInfoKHR in its pNext chain, and VkMemoryDedicatedAllocateInfoKHR::buffer was not VK_NULL_HANDLE, then buffer must equal VkMemoryDedicatedAllocateInfoKHR::buffer and memoryOffset must be zero.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindBufferMemory-memory-01508)~^~ VALIDATION_ERROR_17001a01~^~Y~^~VertexBufferInvalid~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-buffer-parameter~^~core~^~The spec valid usage text states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindBufferMemory-buffer-parameter)~^~implicit VALIDATION_ERROR_17001a07~^~Y~^~Unknown~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-buffer-parent~^~core~^~The spec valid usage text states 'buffer must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindBufferMemory-buffer-parent)~^~implicit VALIDATION_ERROR_17005601~^~Y~^~None~^~vkBindBufferMemory~^~VUID-vkBindBufferMemory-device-parameter~^~core~^~The spec valid usage text states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindBufferMemory-device-parameter)~^~implicit @@ -1706,7 +1706,7 @@ VALIDATION_ERROR_17400832~^~Y~^~BindInvalidMemory~^~vkBindImageMemory~^~VUID-vkB VALIDATION_ERROR_17400834~^~N~^~Unknown~^~vkBindImageMemory~^~VUID-vkBindImageMemory-image-01050~^~(VK_NV_dedicated_allocation)~^~The spec valid usage text states 'If image was created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::image equal to an image handle created with identical creation parameters to image and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindImageMemory-image-01050)~^~ VALIDATION_ERROR_17400836~^~N~^~Unknown~^~vkBindImageMemory~^~VUID-vkBindImageMemory-image-01051~^~(VK_NV_dedicated_allocation)+!(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If image was not created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindImageMemory-image-01051)~^~ VALIDATION_ERROR_17400b4a~^~N~^~None~^~vkBindImageMemory~^~VUID-vkBindImageMemory-image-01445~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If image requires a dedicated allocation (as reported by vkGetImageMemoryRequirements2KHR in VkMemoryDedicatedRequirementsKHR::requiresDedicatedAllocation for image), memory must have been created with VkMemoryDedicatedAllocateInfoKHR::image equal to image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindImageMemory-image-01445)~^~ -VALIDATION_ERROR_17400bca~^~N~^~None~^~vkBindImageMemory~^~VUID-vkBindImageMemory-memory-01509~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If the VkmemoryAllocateInfo provided when memory was allocated included an instance of VkMemoryDedicatedAllocateInfoKHR in its pNext chain, and VkMemoryDedicatedAllocateInfoKHR::image was not VK_NULL_HANDLE, then image must equal VkMemoryDedicatedAllocateInfoKHR::image and memoryOffset must be zero.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindImageMemory-memory-01509)~^~ +VALIDATION_ERROR_17400bca~^~Y~^~None~^~vkBindImageMemory~^~VUID-vkBindImageMemory-memory-01509~^~(VK_KHR_dedicated_allocation)~^~The spec valid usage text states 'If the VkmemoryAllocateInfo provided when memory was allocated included an instance of VkMemoryDedicatedAllocateInfoKHR in its pNext chain, and VkMemoryDedicatedAllocateInfoKHR::image was not VK_NULL_HANDLE, then image must equal VkMemoryDedicatedAllocateInfoKHR::image and memoryOffset must be zero.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindImageMemory-memory-01509)~^~ VALIDATION_ERROR_17400c90~^~N~^~None~^~vkBindImageMemory~^~VUID-vkBindImageMemory-image-01608~^~(VK_KHR_sampler_ycbcr_conversion)~^~The spec valid usage text states 'image must not have been created with the VK_IMAGE_CREATE_DISJOINT_BIT_KHR set.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkBindImageMemory-image-01608)~^~ VALIDATION_ERROR_17405601~^~Y~^~None~^~vkBindImageMemory~^~VUID-vkBindImageMemory-device-parameter~^~core~^~The spec valid usage text states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindImageMemory-device-parameter)~^~implicit VALIDATION_ERROR_1740a001~^~Y~^~BindMemoryToDestroyedObject~^~vkBindImageMemory~^~VUID-vkBindImageMemory-image-parameter~^~core~^~The spec valid usage text states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkBindImageMemory-image-parameter)~^~implicit |
