diff options
| author | Mark Young <marky@lunarg.com> | 2016-04-11 17:45:37 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-04-14 16:21:21 -0600 |
| commit | 06786cdf240f54f63f0477a622f9ba0f34a8c20a (patch) | |
| tree | e4c1b8ec5040dc140f5ad43ad3d46c9dd7dbae29 /layers/core_validation.cpp | |
| parent | d976114de79ff37172009b7bb9bf2f1575500c7a (diff) | |
| download | usermoji-06786cdf240f54f63f0477a622f9ba0f34a8c20a.tar.xz | |
layers: lx464 Add drawtime validation of bound buffer memory.
Add a drawtime check to validate that storage or uniform buffers
have valid memory bound to them at draw time before using.
Change-Id: Ia0a07f221dfcb2ea4315e4f52ee04d7cdda22cf7
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 94 |
1 files changed, 66 insertions, 28 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index ce15dd90..a51d7bdd 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -2736,42 +2736,80 @@ static bool validate_and_update_drawtime_descriptor_state( switch (set_node->pDescriptorUpdates[i]->sType) { case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: pWDS = (VkWriteDescriptorSet *)set_node->pDescriptorUpdates[i]; - if ((pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || + + // Verify uniform and storage buffers actually are bound to valid memory at draw time. + if ((pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || + (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || + (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) || (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { for (uint32_t j = 0; j < pWDS->descriptorCount; ++j) { - bufferSize = dev_data->bufferMap[pWDS->pBufferInfo[j].buffer].createInfo.size; - uint32_t dynOffset = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].dynamicOffsets[dynOffsetIndex]; - if (pWDS->pBufferInfo[j].range == VK_WHOLE_SIZE) { - if ((dynOffset + pWDS->pBufferInfo[j].offset) > bufferSize) { + auto buffer_node = dev_data->bufferMap.find(pWDS->pBufferInfo[j].buffer); + if (buffer_node == dev_data->bufferMap.end()) { + result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, + reinterpret_cast<const uint64_t &>(set_node->set), __LINE__, + DRAWSTATE_INVALID_BUFFER, "DS", + "VkDescriptorSet (%#" PRIxLEAST64 ") %s (%#" PRIxLEAST64 ") at index #%u" + " is not defined! Has vkCreateBuffer been called?", + reinterpret_cast<const uint64_t &>(set_node->set), + string_VkDescriptorType(pWDS->descriptorType), + reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), i); + } else { + auto mem_entry = dev_data->memObjMap.find(buffer_node->second.mem); + if (mem_entry == dev_data->memObjMap.end()) { result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, reinterpret_cast<const uint64_t &>(set_node->set), __LINE__, - DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS", - "VkDescriptorSet (%#" PRIxLEAST64 ") bound as set #%u has range of " - "VK_WHOLE_SIZE but dynamic offset %#" PRIxLEAST32 ". " - "combined with offset %#" PRIxLEAST64 " oversteps its buffer (%#" PRIxLEAST64 - ") which has a size of %#" PRIxLEAST64 ".", - reinterpret_cast<const uint64_t &>(set_node->set), i, dynOffset, - pWDS->pBufferInfo[j].offset, - reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), bufferSize); + DRAWSTATE_INVALID_BUFFER, "DS", + "VkDescriptorSet (%#" PRIxLEAST64 ") %s (%#" PRIxLEAST64 ") at index" + " #%u, has no memory bound to it!", + reinterpret_cast<const uint64_t &>(set_node->set), + string_VkDescriptorType(pWDS->descriptorType), + reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), i); } - } else if ((dynOffset + pWDS->pBufferInfo[j].offset + pWDS->pBufferInfo[j].range) > bufferSize) { - result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, - reinterpret_cast<const uint64_t &>(set_node->set), __LINE__, - DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS", - "VkDescriptorSet (%#" PRIxLEAST64 - ") bound as set #%u has dynamic offset %#" PRIxLEAST32 ". " - "Combined with offset %#" PRIxLEAST64 " and range %#" PRIxLEAST64 - " from its update, this oversteps its buffer " - "(%#" PRIxLEAST64 ") which has a size of %#" PRIxLEAST64 ".", - reinterpret_cast<const uint64_t &>(set_node->set), i, dynOffset, - pWDS->pBufferInfo[j].offset, pWDS->pBufferInfo[j].range, - reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), bufferSize); } - dynOffsetIndex++; + // If it's a dynamic buffer, make sure the offsets are within the buffer. + if ((pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || + (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { + bufferSize = dev_data->bufferMap[pWDS->pBufferInfo[j].buffer].createInfo.size; + uint32_t dynOffset = + pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].dynamicOffsets[dynOffsetIndex]; + if (pWDS->pBufferInfo[j].range == VK_WHOLE_SIZE) { + if ((dynOffset + pWDS->pBufferInfo[j].offset) > bufferSize) { + result |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, + reinterpret_cast<const uint64_t &>(set_node->set), __LINE__, + DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS", + "VkDescriptorSet (%#" PRIxLEAST64 ") bound as set #%u has range of " + "VK_WHOLE_SIZE but dynamic offset %#" PRIxLEAST32 ". " + "combined with offset %#" PRIxLEAST64 " oversteps its buffer (%#" PRIxLEAST64 + ") which has a size of %#" PRIxLEAST64 ".", + reinterpret_cast<const uint64_t &>(set_node->set), i, dynOffset, + pWDS->pBufferInfo[j].offset, + reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), bufferSize); + } + } else if ((dynOffset + pWDS->pBufferInfo[j].offset + pWDS->pBufferInfo[j].range) > + bufferSize) { + result |= + log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, + reinterpret_cast<const uint64_t &>(set_node->set), __LINE__, + DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS", + "VkDescriptorSet (%#" PRIxLEAST64 + ") bound as set #%u has dynamic offset %#" PRIxLEAST32 ". " + "Combined with offset %#" PRIxLEAST64 " and range %#" PRIxLEAST64 + " from its update, this oversteps its buffer " + "(%#" PRIxLEAST64 ") which has a size of %#" PRIxLEAST64 ".", + reinterpret_cast<const uint64_t &>(set_node->set), i, dynOffset, + pWDS->pBufferInfo[j].offset, pWDS->pBufferInfo[j].range, + reinterpret_cast<const uint64_t &>(pWDS->pBufferInfo[j].buffer), bufferSize); + } + dynOffsetIndex++; + } } - } else if (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { + } + if (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { for (uint32_t j = 0; j < pWDS->descriptorCount; ++j) { pCB->updateImages.insert(pWDS->pImageInfo[j].imageView); } |
