aboutsummaryrefslogtreecommitdiff
path: root/layers/core_validation.cpp
diff options
context:
space:
mode:
authorMark Young <marky@lunarg.com>2016-04-11 17:45:37 -0600
committerTobin Ehlis <tobine@google.com>2016-04-14 16:21:21 -0600
commit06786cdf240f54f63f0477a622f9ba0f34a8c20a (patch)
treee4c1b8ec5040dc140f5ad43ad3d46c9dd7dbae29 /layers/core_validation.cpp
parentd976114de79ff37172009b7bb9bf2f1575500c7a (diff)
downloadusermoji-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.cpp94
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);
}