aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lentine <mlentine@google.com>2016-02-29 14:22:59 -0600
committerTobin Ehlis <tobine@google.com>2016-03-08 16:08:31 -0700
commit1e2a9b77e1d77e4460093ccc40b00f2a06219b93 (patch)
tree024636a20a4b77a96958508404419741431a0cc2
parent67ea0b9f11ea45de547dd55300e51465a3075d65 (diff)
downloadusermoji-1e2a9b77e1d77e4460093ccc40b00f2a06219b93.tar.xz
layers: Count attachments as the same if they have overlapping memory.
-rw-r--r--layers/draw_state.cpp213
-rw-r--r--layers/draw_state.h29
2 files changed, 181 insertions, 61 deletions
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 73fee548..43ad37f6 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -98,7 +98,7 @@ struct layer_data {
// Layer specific data
unordered_map<VkSampler, unique_ptr<SAMPLER_NODE>> sampleMap;
unordered_map<VkImageView, unique_ptr<VkImageViewCreateInfo>> imageViewMap;
- unordered_map<VkImage, unique_ptr<VkImageCreateInfo>> imageMap;
+ unordered_map<VkImage, IMAGE_NODE> imageMap;
unordered_map<VkBufferView, unique_ptr<VkBufferViewCreateInfo>> bufferViewMap;
unordered_map<VkBuffer, BUFFER_NODE> bufferMap;
unordered_map<VkPipeline, PIPELINE_NODE*> pipelineMap;
@@ -117,7 +117,7 @@ struct layer_data {
unordered_map<void*, GLOBAL_CB_NODE*> commandBufferMap;
unordered_map<VkFramebuffer, FRAMEBUFFER_NODE> frameBufferMap;
unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
- unordered_map<ImageSubresourcePair, IMAGE_NODE> imageLayoutMap;
+ unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
unordered_map<VkRenderPass, RENDER_PASS_NODE*> renderPassMap;
unordered_map<VkShaderModule, shader_module*> shaderModuleMap;
// Current render pass
@@ -2541,7 +2541,7 @@ static VkBool32 validateSampler(const layer_data* my_data, const VkSampler* pSam
// find layout(s) on the cmd buf level
bool FindLayout(const GLOBAL_CB_NODE *pCB, VkImage image,
- VkImageSubresource range, IMAGE_CMD_BUF_NODE &node) {
+ VkImageSubresource range, IMAGE_CMD_BUF_LAYOUT_NODE &node) {
ImageSubresourcePair imgpair = {image, true, range};
auto imgsubIt = pCB->imageLayoutMap.find(imgpair);
if (imgsubIt == pCB->imageLayoutMap.end()) {
@@ -2585,7 +2585,7 @@ bool FindLayouts(const layer_data *my_data, VkImage image,
// TODO: Make this robust for >1 aspect mask. Now it will just say ignore
// potential errors in this case.
if (sub_data->second.size() >=
- (imgIt->second->arrayLayers * imgIt->second->mipLevels + 1)) {
+ (imgIt->second.createInfo.arrayLayers * imgIt->second.createInfo.mipLevels + 1)) {
ignoreGlobal = true;
}
for (auto imgsubpair : sub_data->second) {
@@ -2629,7 +2629,7 @@ void SetLayout(layer_data *my_data, VkImage image, VkImageSubresource range,
// Set the layout on the cmdbuf level
void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image, ImageSubresourcePair imgpair,
- const IMAGE_CMD_BUF_NODE &node) {
+ const IMAGE_CMD_BUF_LAYOUT_NODE &node) {
pCB->imageLayoutMap[imgpair] = node;
// TODO (mlentine): Maybe make vector a set?
auto subresource =
@@ -2650,20 +2650,20 @@ void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image, ImageSubresourcePair imgpair,
} else {
// TODO (mlentine): Could be expensive and might need to be removed.
assert(imgpair.hasSubresource);
- IMAGE_CMD_BUF_NODE node;
+ IMAGE_CMD_BUF_LAYOUT_NODE node;
FindLayout(pCB, image, imgpair.subresource, node);
SetLayout(pCB, image, imgpair, {node.initialLayout, layout});
}
}
void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image,
- const IMAGE_CMD_BUF_NODE &node) {
+ const IMAGE_CMD_BUF_LAYOUT_NODE &node) {
ImageSubresourcePair imgpair = {image, false, VkImageSubresource()};
SetLayout(pCB, image, imgpair, node);
}
void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image, VkImageSubresource range,
- const IMAGE_CMD_BUF_NODE &node) {
+ const IMAGE_CMD_BUF_LAYOUT_NODE &node) {
ImageSubresourcePair imgpair = {image, true, range};
SetLayout(pCB, image, imgpair, node);
}
@@ -2714,7 +2714,7 @@ static VkBool32 validateImageView(const layer_data* my_data, const VkImageView*
VkFormat format = VK_FORMAT_MAX_ENUM;
auto imgIt = my_data->imageMap.find(image);
if (imgIt != my_data->imageMap.end()) {
- format = (*imgIt).second->format;
+ format = (*imgIt).second.createInfo.format;
}
else {
// Also need to check the swapchains.
@@ -4875,13 +4875,11 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, co
}
if (VK_SUCCESS == result) {
- IMAGE_NODE image_node;
+ IMAGE_LAYOUT_NODE image_node;
image_node.layout = pCreateInfo->initialLayout;
image_node.format = pCreateInfo->format;
- image_node.mipLevels = pCreateInfo->mipLevels;
- image_node.arrayLayers = pCreateInfo->arrayLayers;
loader_platform_thread_lock_mutex(&globalLock);
- dev_data->imageMap[*pImage] = unique_ptr<VkImageCreateInfo>(new VkImageCreateInfo(*pCreateInfo));
+ dev_data->imageMap[*pImage].createInfo = *pCreateInfo;
ImageSubresourcePair subpair = {*pImage, false, VkImageSubresource()};
dev_data->imageSubresourceMap[*pImage].push_back(subpair);
dev_data->imageLayoutMap[subpair] = image_node;
@@ -4903,12 +4901,12 @@ static void ResolveRemainingLevelsLayers(layer_data* dev_data,
*/
if (range->levelCount == VK_REMAINING_MIP_LEVELS) {
range->levelCount =
- image_node_it->second->mipLevels - range->baseMipLevel;
+ image_node_it->second.createInfo.mipLevels - range->baseMipLevel;
}
if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) {
range->layerCount =
- image_node_it->second->arrayLayers - range->baseArrayLayer;
+ image_node_it->second.createInfo.arrayLayers - range->baseArrayLayer;
}
}
}
@@ -6146,7 +6144,7 @@ VkBool32 VerifySourceImageLayout(VkCommandBuffer cmdBuffer, VkImage srcImage, Vk
for (uint32_t i = 0; i < subLayers.layerCount; ++i) {
uint32_t layer = i + subLayers.baseArrayLayer;
VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer};
- IMAGE_CMD_BUF_NODE node;
+ IMAGE_CMD_BUF_LAYOUT_NODE node;
if (!FindLayout(pCB, srcImage, sub, node)) {
SetLayout(pCB, srcImage, sub, {srcImageLayout, srcImageLayout});
continue;
@@ -6189,7 +6187,7 @@ VkBool32 VerifyDestImageLayout(VkCommandBuffer cmdBuffer, VkImage destImage, VkI
for (uint32_t i = 0; i < subLayers.layerCount; ++i) {
uint32_t layer = i + subLayers.baseArrayLayer;
VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer};
- IMAGE_CMD_BUF_NODE node;
+ IMAGE_CMD_BUF_LAYOUT_NODE node;
if (!FindLayout(pCB, destImage, sub, node)) {
SetLayout(pCB, destImage, sub, {destImageLayout, destImageLayout});
continue;
@@ -6520,7 +6518,7 @@ VkBool32 TransitionImageLayouts(VkCommandBuffer cmdBuffer, uint32_t memBarrierCo
mem_barrier->subresourceRange.baseArrayLayer + k;
VkImageSubresource sub = {
mem_barrier->subresourceRange.aspectMask, level, layer};
- IMAGE_CMD_BUF_NODE node;
+ IMAGE_CMD_BUF_LAYOUT_NODE node;
if (!FindLayout(pCB, mem_barrier->image, sub, node)) {
SetLayout(pCB, mem_barrier->image, sub,
{mem_barrier->oldLayout, mem_barrier->newLayout});
@@ -6678,7 +6676,7 @@ VkBool32 ValidateBarriers(const char* funcName,
if (image_data != dev_data->imageMap.end()) {
uint32_t src_q_f_index = mem_barrier->srcQueueFamilyIndex;
uint32_t dst_q_f_index = mem_barrier->dstQueueFamilyIndex;
- if (image_data->second->sharingMode == VK_SHARING_MODE_CONCURRENT) {
+ if (image_data->second.createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
// srcQueueFamilyIndex and dstQueueFamilyIndex must both
// be VK_QUEUE_FAMILY_IGNORED
if ((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) ||
@@ -6746,9 +6744,9 @@ VkBool32 ValidateBarriers(const char* funcName,
uint32_t arrayLayers, mipLevels;
bool imageFound = false;
if (image_data != dev_data->imageMap.end()) {
- format = image_data->second->format;
- arrayLayers = image_data->second->arrayLayers;
- mipLevels = image_data->second->mipLevels;
+ format = image_data->second.createInfo.format;
+ arrayLayers = image_data->second.createInfo.arrayLayers;
+ mipLevels = image_data->second.createInfo.mipLevels;
imageFound = true;
} else if (dev_data->device_extensions.wsi_enabled) {
auto imageswap_data =
@@ -7140,13 +7138,6 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice devi
return result;
}
-// Store the DAG.
-struct DAGNode {
- uint32_t pass;
- std::vector<uint32_t> prev;
- std::vector<uint32_t> next;
-};
-
VkBool32 FindDependency(const int index, const int dependent, const std::vector<DAGNode>& subpass_to_node, std::unordered_set<uint32_t>& processed_nodes) {
// If we have already checked this node we have not found a dependency path so return false.
if (processed_nodes.count(index))
@@ -7165,7 +7156,10 @@ VkBool32 FindDependency(const int index, const int dependent, const std::vector<
return VK_FALSE;
}
-VkBool32 CheckDependencyExists(const layer_data* my_data, VkDevice device, const int subpass, const std::vector<uint32_t>& dependent_subpasses, const std::vector<DAGNode>& subpass_to_node, VkBool32& skip_call) {
+VkBool32 CheckDependencyExists(const layer_data *my_data, const int subpass,
+ const std::vector<uint32_t> &dependent_subpasses,
+ const std::vector<DAGNode> &subpass_to_node,
+ VkBool32 &skip_call) {
VkBool32 result = VK_TRUE;
// Loop through all subpasses that share the same attachment and make sure a dependency exists
for (uint32_t k = 0; k < dependent_subpasses.size(); ++k) {
@@ -7195,7 +7189,11 @@ VkBool32 CheckDependencyExists(const layer_data* my_data, VkDevice device, const
return result;
}
-VkBool32 CheckPreserved(const layer_data* my_data, VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const int index, const uint32_t attachment, const std::vector<DAGNode>& subpass_to_node, int depth, VkBool32& skip_call) {
+VkBool32 CheckPreserved(const layer_data *my_data,
+ const VkRenderPassCreateInfo *pCreateInfo,
+ const int index, const uint32_t attachment,
+ const std::vector<DAGNode> &subpass_to_node, int depth,
+ VkBool32 &skip_call) {
const DAGNode& node = subpass_to_node[index];
// If this node writes to the attachment return true as next nodes need to preserve the attachment.
const VkSubpassDescription& subpass = pCreateInfo->pSubpasses[index];
@@ -7211,7 +7209,8 @@ VkBool32 CheckPreserved(const layer_data* my_data, VkDevice device, const VkRend
VkBool32 result = VK_FALSE;
// Loop through previous nodes and see if any of them write to the attachment.
for (auto elem : node.prev) {
- result |= CheckPreserved(my_data, device, pCreateInfo, elem, attachment, subpass_to_node, depth + 1, skip_call);
+ result |= CheckPreserved(my_data, pCreateInfo, elem, attachment,
+ subpass_to_node, depth + 1, skip_call);
}
// If the attachment was written to by a previous node than this node needs to preserve it.
if (result && depth > 0) {
@@ -7231,21 +7230,102 @@ VkBool32 CheckPreserved(const layer_data* my_data, VkDevice device, const VkRend
return result;
}
-VkBool32 ValidateDependencies(const layer_data* my_data, VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const std::vector<DAGNode>& subpass_to_node) {
+template <class T>
+bool isRangeOverlapping(T offset1, T size1, T offset2, T size2) {
+ return (((offset1 + size1) > offset2) &&
+ ((offset1 + size1) < (offset2 + size2))) ||
+ ((offset1 > offset2) && (offset1 < (offset2 + size2)));
+}
+
+bool isRegionOverlapping(VkImageSubresourceRange range1,
+ VkImageSubresourceRange range2) {
+ return (isRangeOverlapping(range1.baseMipLevel, range1.levelCount,
+ range2.baseMipLevel, range2.levelCount) &&
+ isRangeOverlapping(range1.baseArrayLayer, range1.layerCount,
+ range2.baseArrayLayer, range2.layerCount));
+}
+
+VkBool32 ValidateDependencies(const layer_data *my_data,
+ const VkRenderPassBeginInfo *pRenderPassBegin,
+ const std::vector<DAGNode> &subpass_to_node) {
VkBool32 skip_call = VK_FALSE;
+ const VkFramebufferCreateInfo *pFramebufferInfo =
+ &my_data->frameBufferMap.at(pRenderPassBegin->framebuffer).createInfo;
+ const VkRenderPassCreateInfo *pCreateInfo =
+ my_data->renderPassMap.at(pRenderPassBegin->renderPass)->pCreateInfo;
std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount);
std::vector<std::vector<uint32_t>> input_attachment_to_subpass(pCreateInfo->attachmentCount);
+ std::vector<std::vector<uint32_t>> overlapping_attachments(
+ pCreateInfo->attachmentCount);
+ for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
+ for (uint32_t j = i + 1; j < pCreateInfo->attachmentCount; ++j) {
+ VkImageView viewi = pFramebufferInfo->pAttachments[i];
+ VkImageView viewj = pFramebufferInfo->pAttachments[j];
+ if (viewi == viewj) {
+ overlapping_attachments[i].push_back(j);
+ overlapping_attachments[j].push_back(i);
+ continue;
+ }
+ auto view_data_i = my_data->imageViewMap.find(viewi);
+ auto view_data_j = my_data->imageViewMap.find(viewj);
+ if (view_data_i == my_data->imageViewMap.end() ||
+ view_data_j == my_data->imageViewMap.end()) {
+ continue;
+ }
+ if (view_data_i->second->image == view_data_j->second->image &&
+ isRegionOverlapping(view_data_i->second->subresourceRange,
+ view_data_j->second->subresourceRange)) {
+ overlapping_attachments[i].push_back(j);
+ overlapping_attachments[j].push_back(i);
+ continue;
+ }
+ auto image_data_i =
+ my_data->imageMap.find(view_data_i->second->image);
+ auto image_data_j =
+ my_data->imageMap.find(view_data_j->second->image);
+ if (image_data_i == my_data->imageMap.end() ||
+ image_data_j == my_data->imageMap.end()) {
+ continue;
+ }
+ if (image_data_i->second.mem == image_data_j->second.mem &&
+ isRangeOverlapping(image_data_i->second.memOffset,
+ image_data_i->second.memSize,
+ image_data_j->second.memOffset,
+ image_data_j->second.memSize)) {
+ overlapping_attachments[i].push_back(j);
+ overlapping_attachments[j].push_back(i);
+ }
+ }
+ }
// Find for each attachment the subpasses that use them.
for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
const VkSubpassDescription& subpass = pCreateInfo->pSubpasses[i];
for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
- input_attachment_to_subpass[subpass.pInputAttachments[j].attachment].push_back(i);
+ uint32_t attachment = subpass.pInputAttachments[j].attachment;
+ input_attachment_to_subpass[attachment].push_back(i);
+ for (auto overlapping_attachment :
+ overlapping_attachments[attachment]) {
+ input_attachment_to_subpass[attachment].push_back(
+ overlapping_attachment);
+ }
}
for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
- output_attachment_to_subpass[subpass.pColorAttachments[j].attachment].push_back(i);
+ uint32_t attachment = subpass.pColorAttachments[j].attachment;
+ output_attachment_to_subpass[attachment].push_back(i);
+ for (auto overlapping_attachment :
+ overlapping_attachments[attachment]) {
+ output_attachment_to_subpass[attachment].push_back(
+ overlapping_attachment);
+ }
}
if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
- output_attachment_to_subpass[subpass.pDepthStencilAttachment->attachment].push_back(i);
+ uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
+ output_attachment_to_subpass[attachment].push_back(i);
+ for (auto overlapping_attachment :
+ overlapping_attachments[attachment]) {
+ output_attachment_to_subpass[attachment].push_back(
+ overlapping_attachment);
+ }
}
}
// If there is a dependency needed make sure one exists
@@ -7254,25 +7334,37 @@ VkBool32 ValidateDependencies(const layer_data* my_data, VkDevice device, const
// If the attachment is an input then all subpasses that output must have a dependency relationship
for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
const uint32_t& attachment = subpass.pInputAttachments[j].attachment;
- CheckDependencyExists(my_data, device, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+ CheckDependencyExists(my_data, i,
+ output_attachment_to_subpass[attachment],
+ subpass_to_node, skip_call);
}
// If the attachment is an output then all subpasses that use the attachment must have a dependency relationship
for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
const uint32_t& attachment = subpass.pColorAttachments[j].attachment;
- CheckDependencyExists(my_data, device, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
- CheckDependencyExists(my_data, device, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+ CheckDependencyExists(my_data, i,
+ output_attachment_to_subpass[attachment],
+ subpass_to_node, skip_call);
+ CheckDependencyExists(my_data, i,
+ input_attachment_to_subpass[attachment],
+ subpass_to_node, skip_call);
}
if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
const uint32_t& attachment = subpass.pDepthStencilAttachment->attachment;
- CheckDependencyExists(my_data, device, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
- CheckDependencyExists(my_data, device, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+ CheckDependencyExists(my_data, i,
+ output_attachment_to_subpass[attachment],
+ subpass_to_node, skip_call);
+ CheckDependencyExists(my_data, i,
+ input_attachment_to_subpass[attachment],
+ subpass_to_node, skip_call);
}
}
// Loop through implicit dependencies, if this pass reads make sure the attachment is preserved for all passes after it was written.
for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
const VkSubpassDescription& subpass = pCreateInfo->pSubpasses[i];
for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
- CheckPreserved(my_data, device, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip_call);
+ CheckPreserved(my_data, pCreateInfo, i,
+ subpass.pInputAttachments[j].attachment,
+ subpass_to_node, 0, skip_call);
}
}
return skip_call;
@@ -7389,8 +7481,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice devic
std::vector<bool> has_self_dependency(pCreateInfo->subpassCount);
std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
- // Validate using DAG
- skip_call |= ValidateDependencies(dev_data, device, pCreateInfo, subpass_to_node);
+ // Validate
skip_call |= ValidateLayouts(dev_data, device, pCreateInfo);
if (VK_FALSE != skip_call) {
return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -7452,6 +7543,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice devic
}
dev_data->renderPassMap[*pRenderPass] = new RENDER_PASS_NODE(localRPCI);
dev_data->renderPassMap[*pRenderPass]->hasSelfDependency = has_self_dependency;
+ dev_data->renderPassMap[*pRenderPass]->subpassToNode = subpass_to_node;
loader_platform_thread_unlock_mutex(&globalLock);
}
return result;
@@ -7506,10 +7598,10 @@ VkBool32 VerifyFramebufferAndRenderPassLayouts(VkCommandBuffer cmdBuffer, const
const VkImageView &image_view = framebufferInfo.pAttachments[i];
auto image_data = dev_data->imageViewMap.find(image_view);
assert(image_data != dev_data->imageViewMap.end());
- const VkImage &image = image_data->second->image;
- const VkImageSubresourceRange &subRange =
+ const VkImage& image = image_data->second->image;
+ const VkImageSubresourceRange& subRange =
image_data->second->subresourceRange;
- IMAGE_CMD_BUF_NODE newNode = {
+ IMAGE_CMD_BUF_LAYOUT_NODE newNode = {
pRenderPassInfo->pAttachments[i].initialLayout,
pRenderPassInfo->pAttachments[i].initialLayout};
// TODO: Do not iterate over every possibility - consolidate where
@@ -7519,7 +7611,7 @@ VkBool32 VerifyFramebufferAndRenderPassLayouts(VkCommandBuffer cmdBuffer, const
for (uint32_t k = 0; k < subRange.layerCount; k++) {
uint32_t layer = subRange.baseArrayLayer + k;
VkImageSubresource sub = {subRange.aspectMask, level, layer};
- IMAGE_CMD_BUF_NODE node;
+ IMAGE_CMD_BUF_LAYOUT_NODE node;
if (!FindLayout(pCB, image, sub, node)) {
SetLayout(pCB, image, sub, newNode);
continue;
@@ -7618,6 +7710,13 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer
if (pCB) {
if (pRenderPassBegin && pRenderPassBegin->renderPass) {
skipCall |= VerifyFramebufferAndRenderPassLayouts(commandBuffer, pRenderPassBegin);
+ auto render_pass_data =
+ dev_data->renderPassMap.find(pRenderPassBegin->renderPass);
+ if (render_pass_data != dev_data->renderPassMap.end()) {
+ skipCall |= ValidateDependencies(
+ dev_data, pRenderPassBegin,
+ render_pass_data->second->subpassToNode);
+ }
skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass");
skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdBeginRenderPass");
skipCall |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
@@ -8040,8 +8139,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(
{
layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
VkResult result = dev_data->device_dispatch_table->BindImageMemory(device, image, mem, memOffset);
+ VkMemoryRequirements memRequirements;
+ dev_data->device_dispatch_table->GetImageMemoryRequirements(
+ device, image, &memRequirements);
loader_platform_thread_lock_mutex(&globalLock);
dev_data->memImageMap[mem] = image;
+ dev_data->imageMap[image].mem = mem;
+ dev_data->imageMap[image].memOffset = memOffset;
+ dev_data->imageMap[image].memSize = memRequirements.size;
loader_platform_thread_unlock_mutex(&globalLock);
return result;
}
@@ -8191,19 +8296,19 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
if (!pCount) return result;
loader_platform_thread_lock_mutex(&globalLock);
for (uint32_t i = 0; i < *pCount; ++i) {
- IMAGE_NODE image_node;
- image_node.layout = VK_IMAGE_LAYOUT_UNDEFINED;
+ IMAGE_LAYOUT_NODE image_layout_node;
+ image_layout_node.layout = VK_IMAGE_LAYOUT_UNDEFINED;
auto swapchain_node = dev_data->device_extensions.swapchainMap[swapchain];
- image_node.format = swapchain_node->createInfo.imageFormat;
- image_node.mipLevels = 1;
- image_node.arrayLayers =
+ image_layout_node.format = swapchain_node->createInfo.imageFormat;
+ dev_data->imageMap[pSwapchainImages[i]].createInfo.mipLevels = 1;
+ dev_data->imageMap[pSwapchainImages[i]].createInfo.arrayLayers =
swapchain_node->createInfo.imageArrayLayers;
swapchain_node->images.push_back(pSwapchainImages[i]);
ImageSubresourcePair subpair = {pSwapchainImages[i], false,
VkImageSubresource()};
dev_data->imageSubresourceMap[pSwapchainImages[i]].push_back(
subpair);
- dev_data->imageLayoutMap[subpair] = image_node;
+ dev_data->imageLayoutMap[subpair] = image_layout_node;
dev_data->device_extensions
.imageToSwapchainMap[pSwapchainImages[i]] = swapchain;
}
diff --git a/layers/draw_state.h b/layers/draw_state.h
index 3fba1b99..93c84ea5 100644
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -311,17 +311,23 @@ typedef struct _SAMPLER_NODE {
_SAMPLER_NODE(const VkSampler* ps, const VkSamplerCreateInfo* pci) : sampler(*ps), createInfo(*pci) {};
} SAMPLER_NODE;
-typedef struct _IMAGE_NODE {
+class IMAGE_NODE : public BASE_NODE {
+ public:
+ VkImageCreateInfo createInfo;
+ VkDeviceMemory mem;
+ VkDeviceSize memOffset;
+ VkDeviceSize memSize;
+};
+
+typedef struct _IMAGE_LAYOUT_NODE {
VkImageLayout layout;
VkFormat format;
- uint32_t mipLevels;
- uint32_t arrayLayers;
-} IMAGE_NODE;
+} IMAGE_LAYOUT_NODE;
-typedef struct _IMAGE_CMD_BUF_NODE {
+typedef struct _IMAGE_CMD_BUF_LAYOUT_NODE {
VkImageLayout initialLayout;
VkImageLayout layout;
-} IMAGE_CMD_BUF_NODE;
+} IMAGE_CMD_BUF_LAYOUT_NODE;
class BUFFER_NODE : public BASE_NODE {
public:
@@ -329,9 +335,17 @@ class BUFFER_NODE : public BASE_NODE {
unique_ptr<VkBufferCreateInfo> create_info;
};
+// Store the DAG.
+struct DAGNode {
+ uint32_t pass;
+ std::vector<uint32_t> prev;
+ std::vector<uint32_t> next;
+};
+
struct RENDER_PASS_NODE {
VkRenderPassCreateInfo const* pCreateInfo;
std::vector<bool> hasSelfDependency;
+ std::vector<DAGNode> subpassToNode;
vector<std::vector<VkFormat>> subpassColorFormats;
RENDER_PASS_NODE(VkRenderPassCreateInfo const *pCreateInfo) : pCreateInfo(pCreateInfo)
@@ -697,7 +711,8 @@ typedef struct _GLOBAL_CB_NODE {
unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available
unordered_set<QueryObject> activeQueries;
unordered_set<QueryObject> startedQueries;
- unordered_map<ImageSubresourcePair, IMAGE_CMD_BUF_NODE> imageLayoutMap;
+ unordered_map<ImageSubresourcePair, IMAGE_CMD_BUF_LAYOUT_NODE>
+ imageLayoutMap;
unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
vector<DRAW_DATA> drawData;