aboutsummaryrefslogtreecommitdiff
path: root/layers/core_validation.cpp
diff options
context:
space:
mode:
authorKarl Schultz <karl@lunarg.com>2018-05-02 19:40:34 -0600
committerKarl Schultz <karl@lunarg.com>2018-05-04 07:34:25 -0600
commit17ecbde130b930d3e8515c0797785e07886ecf4b (patch)
tree559ba92f8878d62dcfc34ac134081c8aae3767dd /layers/core_validation.cpp
parent15206477a12149a175f2c1ca8e635692bdd3c8df (diff)
downloadusermoji-17ecbde130b930d3e8515c0797785e07886ecf4b.tar.xz
layers: Add checks for indexed draw count/offset
Check that the first index and index count are within the bounds of an index buffer for DrawIndexed, taking into account any offset specified in the binding of the index buffer. Fixes #2448 Change-Id: I47a1acbf0bb0e586692c75380d8d43a1c72450fd
Diffstat (limited to 'layers/core_validation.cpp')
-rw-r--r--layers/core_validation.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index ca854df8..755699bd 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -1944,6 +1944,7 @@ static void ResetCommandBufferState(layer_data *dev_data, const VkCommandBuffer
}
pCB->framebuffers.clear();
pCB->activeFramebuffer = VK_NULL_HANDLE;
+ memset(&pCB->index_buffer_binding, 0, sizeof(pCB->index_buffer_binding));
}
}
@@ -6708,6 +6709,10 @@ VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkB
if (skip) return;
cb_node->status |= CBSTATUS_INDEX_BUFFER_BOUND;
+ cb_node->index_buffer_binding.buffer = buffer;
+ cb_node->index_buffer_binding.size = buffer_state->createInfo.size;
+ cb_node->index_buffer_binding.offset = offset;
+ cb_node->index_buffer_binding.index_type = indexType;
lock.unlock();
dev_data->dispatch_table.CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
@@ -6812,9 +6817,31 @@ VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t verte
}
static bool PreCallValidateCmdDrawIndexed(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed,
- VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) {
- return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VK_QUEUE_GRAPHICS_BIT,
- VALIDATION_ERROR_1a402415, VALIDATION_ERROR_1a400017, VALIDATION_ERROR_1a40039c);
+ VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller,
+ uint32_t indexCount, uint32_t firstIndex) {
+ bool skip =
+ ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VK_QUEUE_GRAPHICS_BIT,
+ VALIDATION_ERROR_1a402415, VALIDATION_ERROR_1a400017, VALIDATION_ERROR_1a40039c);
+ if (!skip && ((*cb_state)->status & CBSTATUS_INDEX_BUFFER_BOUND)) {
+ unsigned int index_size = 0;
+ const auto &index_buffer_binding = (*cb_state)->index_buffer_binding;
+ if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT16) {
+ index_size = 2;
+ } else if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT32) {
+ index_size = 4;
+ }
+ VkDeviceSize end_offset = (index_size * ((VkDeviceSize)firstIndex + indexCount)) + index_buffer_binding.offset;
+ if (end_offset > index_buffer_binding.size) {
+ skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+ HandleToUint64(index_buffer_binding.buffer), VALIDATION_ERROR_1a40039e,
+ "vkCmdDrawIndexed() index size (%d) * (firstIndex (%d) + indexCount (%d)) "
+ "+ binding offset (%" PRIuLEAST64 ") = an ending offset of %" PRIuLEAST64
+ " bytes, "
+ "which is greater than the index buffer size (%" PRIuLEAST64 ").",
+ index_size, firstIndex, indexCount, index_buffer_binding.offset, end_offset, index_buffer_binding.size);
+ }
+ }
+ return skip;
}
static void PostCallRecordCmdDrawIndexed(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) {
@@ -6827,7 +6854,7 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_
GLOBAL_CB_NODE *cb_state = nullptr;
unique_lock_t lock(global_lock);
bool skip = PreCallValidateCmdDrawIndexed(dev_data, commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state,
- "vkCmdDrawIndexed()");
+ "vkCmdDrawIndexed()", indexCount, firstIndex);
lock.unlock();
if (!skip) {
dev_data->dispatch_table.CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);