layers: Add Idx buffer alignment check to DrawState
authorTobin Ehlis <tobin@lunarg.com>
Thu, 17 Sep 2015 18:24:13 +0000 (12:24 -0600)
committerTobin Ehlis <tobin@lunarg.com>
Mon, 21 Sep 2015 17:41:54 +0000 (11:41 -0600)
At vkCmdBindIndexBuffer() time, verify that offset param falls on an aligment boundary as set by indexType param. New check enum is DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR.
Removed checks for this from the driver and added a validation test and documentation for the new check.
ParamChecker has a check to verify indexType param is an acceptable value, but it's after the call so documented a TODO for ParamChecker to push this check prior to call.

layers/draw_state.cpp
layers/draw_state.h
layers/vk_validation_layer_details.md

index 4a894f2494df4160d3edbf5e9edc7338fdb9ec5f..cf101b73e408e72109425bfbd03d8010f60f9b29 100644 (file)
@@ -2381,15 +2381,29 @@ VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer
             if (!pCB->activeRenderPass) {
                 skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
                         "Incorrect call to vkCmdBindIndexBuffer() without an active RenderPass.");
-            } else {
-                // TODO : Can be more exact in tracking/validating details for Idx buffer, for now just make sure *something* was bound
-                pCB->status |= CBSTATUS_INDEX_BUFFER_BOUND;
-                updateCBTracking(cmdBuffer);
-                skipCall |= addCmd(pCB, CMD_BINDINDEXBUFFER);
+            }
+            VkDeviceSize offset_align = 0;
+            switch (indexType) {
+                case VK_INDEX_TYPE_UINT16:
+                    offset_align = 2;
+                    break;
+                case VK_INDEX_TYPE_UINT32:
+                    offset_align = 4;
+                    break;
+                default:
+                    // ParamChecker should catch bad enum, we'll also throw alignment error below if offset_align stays 0
+                    break;
+            }
+            if (!offset_align || (offset % offset_align)) {
+                skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS",
+                    "vkCmdBindIndexBuffer() offset (%#" PRIxLEAST64 ") does not fall on alignment (%s) boundary.", offset, string_VkIndexType(indexType));
             }
         } else {
             skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
         }
+        pCB->status |= CBSTATUS_INDEX_BUFFER_BOUND;
+        updateCBTracking(cmdBuffer);
+        skipCall |= addCmd(pCB, CMD_BINDINDEXBUFFER);
     }
     if (VK_FALSE == skipCall)
         get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
index a3fc2ebcc1b1bebb197e43df483716688aeaa8d3..5492cd7c0b2585659c40db6ea160d3c765f154bd 100644 (file)
@@ -40,6 +40,7 @@ typedef enum _DRAW_STATE_ERROR
     DRAWSTATE_INVALID_PIPELINE_CREATE_STATE,    // Attempt to create a pipeline with invalid state
     DRAWSTATE_INVALID_CMD_BUFFER,               // Invalid CmdBuffer referenced
     DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS,          // binding in vkCmdBindVertexData() too large for PSO's pVertexBindingDescriptions array
+    DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR,        // binding offset in vkCmdBindIndexBuffer() out of alignment based on indexType
     DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT,     // Invalid dyn state object
     //DRAWSTATE_MISSING_DOT_PROGRAM,              // No "dot" program in order to generate png image
     DRAWSTATE_OUT_OF_MEMORY,                    // malloc failed
index 683a35434d93b82bd00ee86aa478830bbf26590d..8dd8b411ef3b158ffe63c9550415c32315acf07d 100644 (file)
@@ -24,6 +24,7 @@ The DrawState layer tracks state leading into Draw cmds. This includes the Pipel
 | Valid CmdBuffer | Validates that the command buffer object was properly created and is currently valid | INVALID_CMD_BUFFER | vkQueueSubmit vkBeginCommandBuffer vkEndCommandBuffer vkCmdBindPipeline vkCmdBindDynamicViewportState vkCmdBindDynamicLineWidthState vkCmdBindDynamicDepthBiasState vkCmdBindDynamicBlendState vkCmdBindDynamicDepthBoundsState vkCmdBindDynamicStencilState vkCmdBindDescriptorSets vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorAttachment vkCmdClearDepthStencilAttachment vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdWaitEvents vkCmdPipelineBarrier vkCmdBeginQuery vkCmdEndQuery vkCmdResetQueryPool vkCmdWriteTimestamp vkCmdBeginRenderPass vkCmdNextSubpass vkCmdEndRenderPass vkCmdExecuteCommands vkCmdDbgMarkerBegin vkCmdDbgMarkerEnd vkCreateCommandBuffer | None | NA |
 | Valid Dynamic State | Validates that each of the 4 DSOs are valid, properly constructed objects of the correct type | INVALID_DYNAMIC_STATE_OBJECT | vkCmdBindDynamicViewportState vkCmdBindDynamicLineWidthState vkCmdBindDynamicDepthBiasState vkCmdBindDynamicBlendState vkCmdBindDynamicDepthBoundsState vkCmdBindDynamicStencilState | None | NA |
 | Vtx Buffer Bounds | Check if VBO index too large for PSO Vtx binding count, and that at least one vertex buffer is attached to pipeline object | VTX_INDEX_OUT_OF_BOUNDS | vkCmdBindDescriptorSets vkCmdBindVertexBuffers | VtxBufferBadIndex | NA |
+| Idx Buffer Alignment | Verify that offset of Index buffer falls on an alignment boundary as defined by IdxBufferAlignmentError param | VTX_INDEX_ALIGNMENT_ERROR | vkCmdBindIndexBuffer | IdxBufferAlignmentError | NA |
 | Cmd Buffer End | Verifies that EndCommandBuffer was called for this cmdBuffer at QueueSubmit time | NO_END_CMD_BUFFER | vkQueueSubmit | NoEndCmdBuffer | NA |
 | Cmd Buffer Begin | Check that BeginCommandBuffer was called for this command buffer when binding commands or calling end | NO_BEGIN_CMD_BUFFER | vkEndCommandBuffer vkCmdBindPipeline vkCmdBindDynamicViewportState vkCmdBindDynamicLineWidthState vkCmdBindDynamicDepthBiasState vkCmdBindDynamicBlendState vkCmdBindDynamicDepthBoundsState vkCmdBindDynamicStencilState vkCmdBindDescriptorSets vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorAttachment vkCmdClearDepthStencilAttachment vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdWaitEvents vkCmdPipelineBarrier vkCmdBeginQuery vkCmdEndQuery vkCmdResetQueryPool vkCmdWriteTimestamp | NoBeginCmdBuffer | NA |
 | Cmd Buffer Submit Count | Verify that ONE_TIME submit cmdbuffer is not submitted multiple times | CMD_BUFFER_SINGLE_SUBMIT_VIOLATION | vkBeginCommandBuffer, vkQueueSubmit | CmdBufferTwoSubmits | NA |
@@ -99,6 +100,7 @@ Additional work to be done
  5. Flag error on VkBufferCreateInfo if buffer size is 0
  6. VkImageViewCreateInfo.format must be set
  7. For vkCreateGraphicsPipelines, correctly handle array of pCreateInfos and array of pStages within each element of pCreatInfos
+ 8. Check for valid VkIndexType in vkCmdBindIndexBuffer() should be in PreCmdBindIndexBuffer() call
 
 ## Image