From 48c40c950c223c23dac71a5f37513950c71a20a5 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Thu, 9 Jun 2016 17:01:19 -0600 Subject: [PATCH] layers: GH536, Update CmdFillBuffer validation Was ignoring VK_WHOLE_SIZE. Moved validation cases for Update/FillBuffer to Parameter Validation layer (as they were stateless) and added the remaining additional stateless valid usage checks. Change-Id: I0f41c6ba55f218a6db9fb34736a2abc52f856edf --- layers/device_limits.cpp | 57 ----------------------------------------- layers/device_limits.h | 1 - layers/parameter_validation.cpp | 57 +++++++++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 68 deletions(-) diff --git a/layers/device_limits.cpp b/layers/device_limits.cpp index 36d3d56..f70f421 100644 --- a/layers/device_limits.cpp +++ b/layers/device_limits.cpp @@ -587,61 +587,6 @@ UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWri } } -VKAPI_ATTR void VKAPI_CALL -CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, - VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) { - layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - - // dstOffset is the byte offset into the buffer to start updating and must be a multiple of 4. - if (dstOffset & 3) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, - DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", - "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) { - return; - } - } - - // dataSize is the number of bytes to update, which must be a multiple of 4. - if (dataSize & 3) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, - DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", - "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) { - return; - } - } - - dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); -} - -VKAPI_ATTR void VKAPI_CALL -CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) { - layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - - // dstOffset is the byte offset into the buffer to start filling and must be a multiple of 4. - if (dstOffset & 3) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, - DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", - "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) { - return; - } - } - - // size is the number of bytes to fill, which must be a multiple of 4. - if (size & 3) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, - DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", - "vkCmdFillBuffer parameter, VkDeviceSize size, is not a multiple of 4")) { - return; - } - } - - dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); -} - VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { @@ -799,9 +744,7 @@ intercept_core_device_command(const char *name) { { "vkAllocateCommandBuffers", reinterpret_cast(AllocateCommandBuffers) }, { "vkFreeCommandBuffers", reinterpret_cast(FreeCommandBuffers) }, { "vkBeginCommandBuffer", reinterpret_cast(BeginCommandBuffer) }, - { "vkCmdUpdateBuffer", reinterpret_cast(CmdUpdateBuffer) }, { "vkUpdateDescriptorSets", reinterpret_cast(UpdateDescriptorSets) }, - { "vkCmdFillBuffer", reinterpret_cast(CmdFillBuffer) }, { "vkCmdSetScissor", reinterpret_cast(CmdSetScissor) }, { "vkCmdSetViewport", reinterpret_cast(CmdSetViewport) }, }; diff --git a/layers/device_limits.h b/layers/device_limits.h index 5aa5448..44ae17c 100644 --- a/layers/device_limits.h +++ b/layers/device_limits.h @@ -38,7 +38,6 @@ enum DEV_LIMITS_ERROR { DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, // Invalid queue requested based on queue family properties DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, // Uniform buffer offset violates device limit granularity DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, // Storage buffer offset violates device limit granularity - DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, // Alignment requirement for buffer update is violated }; enum CALL_STATE{ diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp index fe9e391..4be5031 100644 --- a/layers/parameter_validation.cpp +++ b/layers/parameter_validation.cpp @@ -4137,29 +4137,66 @@ VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, V } } -VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, - VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) { - bool skipCall = false; +VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, + VkDeviceSize dataSize, const uint32_t *pData) { + bool skip_call = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); assert(my_data != NULL); - skipCall |= parameter_validation_vkCmdUpdateBuffer(my_data->report_data, dstBuffer, dstOffset, dataSize, pData); + skip_call |= parameter_validation_vkCmdUpdateBuffer(my_data->report_data, dstBuffer, dstOffset, dataSize, pData); - if (!skipCall) { + if (dstOffset & 3) { + skip_call |= + log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, + "PARAMCHECK", "CmdUpdateBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", + dstOffset); + } + + if ((dataSize <= 0) || (dataSize > 65536)) { + skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, + INVALID_USAGE, "PARAMCHECK", "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 + "), must be greater than zero and less than or equal to 65536", + dataSize); + } else if (dataSize & 3) { + skip_call |= + log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, + "PARAMCHECK", "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4", + dataSize); + } + + if (!skip_call) { get_dispatch_table(pc_device_table_map, commandBuffer) ->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); } } -VKAPI_ATTR void VKAPI_CALL -CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) { - bool skipCall = false; +VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, + VkDeviceSize size, uint32_t data) { + bool skip_call = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); assert(my_data != NULL); - skipCall |= parameter_validation_vkCmdFillBuffer(my_data->report_data, dstBuffer, dstOffset, size, data); + skip_call |= parameter_validation_vkCmdFillBuffer(my_data->report_data, dstBuffer, dstOffset, size, data); - if (!skipCall) { + if (dstOffset & 3) { + skip_call |= log_msg( + my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, "DL", + "vkCmdFillBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", dstOffset); + } + + if (size != VK_WHOLE_SIZE) { + if (size <= 0) { + skip_call |= log_msg( + my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, + "DL", "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero", size); + } else if (size & 3) { + skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, + INVALID_USAGE, "DL", + "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4", size); + } + } + + if (!skip_call) { get_dispatch_table(pc_device_table_map, commandBuffer)->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); } } -- 2.7.4