unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_NODE>> frameBufferMap;
unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
- unordered_map<VkRenderPass, RENDER_PASS_NODE *> renderPassMap;
+ unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_NODE>> renderPassMap;
unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap;
VkDevice device;
if (it == my_data->renderPassMap.end()) {
return nullptr;
}
- return it->second;
+ return it->second.get();
}
static FRAMEBUFFER_NODE *getFramebuffer(const layer_data *my_data, VkFramebuffer framebuffer) {
(pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline);
if (pCB->activeRenderPass) {
- const VkRenderPassCreateInfo *render_pass_info = pCB->activeRenderPass->pCreateInfo;
+ auto const render_pass_info = pCB->activeRenderPass->createInfo.ptr();
const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
uint32_t i;
if (pCB->activeRenderPass) {
std::string err_string;
if ((pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) &&
- !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->pCreateInfo, pPipeline->render_pass_ci.ptr(),
+ !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->createInfo.ptr(), pPipeline->render_pass_ci.ptr(),
err_string)) {
// renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
skip_call |=
// produces nonsense errors that confuse users. Other layers should already
// emit errors for renderpass being invalid.
auto renderPass = getRenderPass(my_data, pPipeline->graphicsPipelineCI.renderPass);
- if (renderPass &&
- pPipeline->graphicsPipelineCI.subpass >= renderPass->pCreateInfo->subpassCount) {
+ if (renderPass && pPipeline->graphicsPipelineCI.subpass >= renderPass->createInfo.subpassCount) {
skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Subpass index %u "
"is out of range for this renderpass (0..%u)",
- pPipeline->graphicsPipelineCI.subpass, renderPass->pCreateInfo->subpassCount - 1);
+ pPipeline->graphicsPipelineCI.subpass, renderPass->createInfo.subpassCount - 1);
}
if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->phys_dev_properties.features,
// If rasterization is not disabled, and subpass uses a depth/stencil
// attachment, pDepthStencilState must be a pointer to a valid structure
- auto subpass_desc = renderPass ? &renderPass->pCreateInfo->pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
+ auto subpass_desc = renderPass ? &renderPass->createInfo.pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
if (subpass_desc && subpass_desc->pDepthStencilAttachment &&
subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
if (!pPipeline->graphicsPipelineCI.pDepthStencilState) {
}
// prototype
-static void deleteRenderPasses(layer_data *);
VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
// TODOSC : Shouldn't need any customization here
dispatch_key key = get_dispatch_key(device);
// Free all the memory
std::unique_lock<std::mutex> lock(global_lock);
deletePipelines(dev_data);
- deleteRenderPasses(dev_data);
+ dev_data->renderPassMap.clear();
deleteCommandBuffers(dev_data);
// This will also delete all sets in the pool & remove them from setMap
deletePools(dev_data);
invalidateCommandBuffers(rp_state->cb_bindings, obj_struct);
}
if (!skip) {
- // TODO: leaking all the guts of the renderpass node here!
dev_data->renderPassMap.erase(renderPass);
lock.unlock();
dev_data->device_dispatch_table->DestroyRenderPass(device, renderPass, pAllocator);
for (i = 0; i < count; i++) {
pPipeNode[i] = new PIPELINE_NODE;
pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
- pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->pCreateInfo);
+ pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr());
pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
if (framebuffer) {
if ((framebuffer->createInfo.renderPass != pInfo->renderPass) &&
!verify_renderpass_compatibility(dev_data, framebuffer->renderPassCreateInfo.ptr(),
- getRenderPass(dev_data, pInfo->renderPass)->pCreateInfo,
+ getRenderPass(dev_data, pInfo->renderPass)->createInfo.ptr(),
errorString)) {
// renderPass that framebuffer was created with must be compatible with local renderPass
skip_call |= log_msg(
if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) {
auto renderPass = getRenderPass(dev_data, pInfo->renderPass);
if (renderPass) {
- if (pInfo->subpass >= renderPass->pCreateInfo->subpassCount) {
+ if (pInfo->subpass >= renderPass->createInfo.subpassCount) {
skip_call |= log_msg(
dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
(uint64_t)commandBuffer, __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
"vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must has a subpass index (%d) "
"that is less than the number of subpasses (%d).",
- (void *)commandBuffer, pInfo->subpass, renderPass->pCreateInfo->subpassCount);
+ (void *)commandBuffer, pInfo->subpass, renderPass->createInfo.subpassCount);
}
}
}
// Validate that attachment is in reference list of active subpass
if (pCB->activeRenderPass) {
- const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->pCreateInfo;
+ const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->createInfo.ptr();
const VkSubpassDescription *pSD = &pRPCI->pSubpasses[pCB->activeSubpass];
for (uint32_t attachment_idx = 0; attachment_idx < attachmentCount; attachment_idx++) {
auto rp_node = getRenderPass(dev_data, pCreateInfo->renderPass);
if (rp_node) {
- const VkRenderPassCreateInfo *rpci = rp_node->pCreateInfo;
+ const VkRenderPassCreateInfo *rpci = rp_node->createInfo.ptr();
if (rpci->attachmentCount != pCreateInfo->attachmentCount) {
skip_call |= log_msg(
dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
static void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) {
// Shadow create info and store in map
std::unique_ptr<FRAMEBUFFER_NODE> fb_node(
- new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->pCreateInfo));
+ new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->createInfo.ptr()));
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
VkImageView view = pCreateInfo->pAttachments[i];
static bool ValidateDependencies(const layer_data *my_data, FRAMEBUFFER_NODE const * framebuffer,
RENDER_PASS_NODE const * renderPass) {
bool skip_call = false;
- const safe_VkFramebufferCreateInfo *pFramebufferInfo = &framebuffer->createInfo;
- const VkRenderPassCreateInfo *pCreateInfo = renderPass->pCreateInfo;
+ auto const pFramebufferInfo = framebuffer->createInfo.ptr();
+ auto const pCreateInfo = renderPass->createInfo.ptr();
auto const & subpass_to_node = renderPass->subpassToNode;
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<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
- // Shadow create info and store in map
- VkRenderPassCreateInfo *localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
- if (pCreateInfo->pAttachments) {
- localRPCI->pAttachments = new VkAttachmentDescription[localRPCI->attachmentCount];
- memcpy((void *)localRPCI->pAttachments, pCreateInfo->pAttachments,
- localRPCI->attachmentCount * sizeof(VkAttachmentDescription));
- }
- if (pCreateInfo->pSubpasses) {
- localRPCI->pSubpasses = new VkSubpassDescription[localRPCI->subpassCount];
- memcpy((void *)localRPCI->pSubpasses, pCreateInfo->pSubpasses, localRPCI->subpassCount * sizeof(VkSubpassDescription));
-
- for (uint32_t i = 0; i < localRPCI->subpassCount; i++) {
- VkSubpassDescription *subpass = (VkSubpassDescription *)&localRPCI->pSubpasses[i];
- const uint32_t attachmentCount = subpass->inputAttachmentCount +
- subpass->colorAttachmentCount * (1 + (subpass->pResolveAttachments ? 1 : 0)) +
- ((subpass->pDepthStencilAttachment) ? 1 : 0) + subpass->preserveAttachmentCount;
- VkAttachmentReference *attachments = new VkAttachmentReference[attachmentCount];
-
- memcpy(attachments, subpass->pInputAttachments, sizeof(attachments[0]) * subpass->inputAttachmentCount);
- subpass->pInputAttachments = attachments;
- attachments += subpass->inputAttachmentCount;
-
- memcpy(attachments, subpass->pColorAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
- subpass->pColorAttachments = attachments;
- attachments += subpass->colorAttachmentCount;
-
- if (subpass->pResolveAttachments) {
- memcpy(attachments, subpass->pResolveAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
- subpass->pResolveAttachments = attachments;
- attachments += subpass->colorAttachmentCount;
- }
-
- if (subpass->pDepthStencilAttachment) {
- memcpy(attachments, subpass->pDepthStencilAttachment, sizeof(attachments[0]) * 1);
- subpass->pDepthStencilAttachment = attachments;
- attachments += 1;
- }
-
- memcpy(attachments, subpass->pPreserveAttachments, sizeof(attachments[0]) * subpass->preserveAttachmentCount);
- subpass->pPreserveAttachments = &attachments->attachment;
- }
- }
- if (pCreateInfo->pDependencies) {
- localRPCI->pDependencies = new VkSubpassDependency[localRPCI->dependencyCount];
- memcpy((void *)localRPCI->pDependencies, pCreateInfo->pDependencies,
- localRPCI->dependencyCount * sizeof(VkSubpassDependency));
- }
-
- auto render_pass = new RENDER_PASS_NODE(localRPCI);
+ auto render_pass = unique_ptr<RENDER_PASS_NODE>(new RENDER_PASS_NODE(pCreateInfo));
render_pass->renderPass = *pRenderPass;
render_pass->hasSelfDependency = has_self_dependency;
render_pass->subpassToNode = subpass_to_node;
}
}
- dev_data->renderPassMap[*pRenderPass] = render_pass;
+ dev_data->renderPassMap[*pRenderPass] = std::move(render_pass);
}
return result;
}
-// Free the renderpass shadow
-static void deleteRenderPasses(layer_data *my_data) {
- for (auto renderPass : my_data->renderPassMap) {
- const VkRenderPassCreateInfo *pRenderPassInfo = renderPass.second->pCreateInfo;
- delete[] pRenderPassInfo->pAttachments;
- if (pRenderPassInfo->pSubpasses) {
- for (uint32_t i = 0; i < pRenderPassInfo->subpassCount; ++i) {
- // Attachements are all allocated in a block, so just need to
- // find the first non-null one to delete
- if (pRenderPassInfo->pSubpasses[i].pInputAttachments) {
- delete[] pRenderPassInfo->pSubpasses[i].pInputAttachments;
- } else if (pRenderPassInfo->pSubpasses[i].pColorAttachments) {
- delete[] pRenderPassInfo->pSubpasses[i].pColorAttachments;
- } else if (pRenderPassInfo->pSubpasses[i].pResolveAttachments) {
- delete[] pRenderPassInfo->pSubpasses[i].pResolveAttachments;
- } else if (pRenderPassInfo->pSubpasses[i].pPreserveAttachments) {
- delete[] pRenderPassInfo->pSubpasses[i].pPreserveAttachments;
- }
- }
- delete[] pRenderPassInfo->pSubpasses;
- }
- delete[] pRenderPassInfo->pDependencies;
- delete pRenderPassInfo;
- delete renderPass.second;
- }
- my_data->renderPassMap.clear();
-}
-
static bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin) {
bool skip_call = false;
- const VkRenderPassCreateInfo *pRenderPassInfo = dev_data->renderPassMap[pRenderPassBegin->renderPass]->pCreateInfo;
+ auto const pRenderPassInfo = getRenderPass(dev_data, pRenderPassBegin->renderPass)->createInfo.ptr();
auto const & framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer]->createInfo;
if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) {
skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
if (!framebuffer)
return;
- const VkSubpassDescription &subpass = renderPass->pCreateInfo->pSubpasses[subpass_index];
+ auto const &subpass = renderPass->createInfo.pSubpasses[subpass_index];
for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, subpass.pInputAttachments[j]);
}
if (!renderPass)
return;
- const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->pCreateInfo;
+ const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr();
auto framebuffer = getFramebuffer(dev_data, pRenderPassBegin->framebuffer);
if (!framebuffer)
return;
if (renderPass) {
uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
- for (size_t i = 0; i < renderPass->pCreateInfo->attachmentCount; ++i) {
+ for (size_t i = 0; i < renderPass->createInfo.attachmentCount; ++i) {
MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
- auto pAttachment = &renderPass->pCreateInfo->pAttachments[i];
+ auto pAttachment = &renderPass->createInfo.pAttachments[i];
if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
pAttachment->stencilLoadOp,
VK_ATTACHMENT_LOAD_OP_CLEAR)) {
skip_call |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()");
skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass");
- auto subpassCount = pCB->activeRenderPass->pCreateInfo->subpassCount;
+ auto subpassCount = pCB->activeRenderPass->createInfo.subpassCount;
if (pCB->activeSubpass == subpassCount - 1) {
skip_call |=
log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
RENDER_PASS_NODE* pRPNode = pCB->activeRenderPass;
auto framebuffer = getFramebuffer(dev_data, pCB->activeFramebuffer);
if (pRPNode) {
- if (pCB->activeSubpass != pRPNode->pCreateInfo->subpassCount - 1) {
+ if (pCB->activeSubpass != pRPNode->createInfo.subpassCount - 1) {
skip_call |=
log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_INVALID_SUBPASS_INDEX, "DS",
"vkCmdEndRenderPass(): Called before reaching final subpass");
}
- for (size_t i = 0; i < pRPNode->pCreateInfo->attachmentCount; ++i) {
+ for (size_t i = 0; i < pRPNode->createInfo.attachmentCount; ++i) {
MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
- auto pAttachment = &pRPNode->pCreateInfo->pAttachments[i];
+ auto pAttachment = &pRPNode->createInfo.pAttachments[i];
if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp,
pAttachment->stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE)) {
std::function<bool()> function = [=]() {
auto cb_renderpass = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
if (cb_renderpass->renderPass != fb->createInfo.renderPass) {
skip_call |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->renderPassCreateInfo.ptr(), secondaryBuffer,
- cb_renderpass->pCreateInfo);
+ cb_renderpass->createInfo.ptr());
}
}
return skip_call;
} else {
// Make sure render pass is compatible with parent command buffer pass if has continue
if (pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) {
- skip_call |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->pCreateInfo,
- pCommandBuffers[i], secondary_rp_node->pCreateInfo);
+ skip_call |=
+ validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(),
+ pCommandBuffers[i], secondary_rp_node->createInfo.ptr());
}
// If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB
skip_call |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB);
string errorString = "";
// secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass
if ((pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) &&
- !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->pCreateInfo, secondary_rp_node->pCreateInfo,
- errorString)) {
+ !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(),
+ secondary_rp_node->createInfo.ptr(), errorString)) {
skip_call |= log_msg(
dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
(uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",