layers: Add VK_KHR_dynamic_rendering
Add VU for VK_KHR_dynamic_rendering extension.
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp
index e918cc2..3e433dd 100644
--- a/layers/buffer_validation.cpp
+++ b/layers/buffer_validation.cpp
@@ -3307,18 +3307,9 @@
}
bool CoreChecks::ValidateClearAttachmentExtent(VkCommandBuffer command_buffer, uint32_t attachment_index,
- const FRAMEBUFFER_STATE *framebuffer, uint32_t fb_attachment,
- const VkRect2D &render_area, uint32_t rect_count, const VkClearRect *clear_rects,
- const CMD_BUFFER_STATE *primary_cb_state) const {
+ const IMAGE_VIEW_STATE* image_view_state,
+ const VkRect2D &render_area, uint32_t rect_count, const VkClearRect *clear_rects) const {
bool skip = false;
- const IMAGE_VIEW_STATE *image_view_state = nullptr;
- if (framebuffer && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < framebuffer->createInfo.attachmentCount)) {
- if (primary_cb_state) {
- image_view_state = primary_cb_state->GetActiveAttachmentImageViewState(fb_attachment);
- } else {
- image_view_state = GetCBState(command_buffer)->GetActiveAttachmentImageViewState(fb_attachment);
- }
- }
for (uint32_t j = 0; j < rect_count; j++) {
if (!ContainsRect(render_area, clear_rects[j].rect)) {
@@ -3378,26 +3369,28 @@
attachment_index);
} else if (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) {
uint32_t color_attachment = VK_ATTACHMENT_UNUSED;
- if (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount) {
- color_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
- if ((color_attachment != VK_ATTACHMENT_UNUSED) && (color_attachment >= renderpass_attachment_count)) {
- skip |= LogError(
- commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
- "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u is not VK_ATTACHMENT_UNUSED "
- "and not a valid attachment for %s attachmentCount=%u. Subpass %u pColorAttachment[%u]=%u.",
- attachment_index, clear_desc->colorAttachment,
- report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(), cb_node->activeSubpass,
- clear_desc->colorAttachment, color_attachment, renderpass_attachment_count);
+ if (cb_node->activeRenderPass->use_dynamic_rendering == false) {
+ if (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount) {
+ color_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
+ if ((color_attachment != VK_ATTACHMENT_UNUSED) && (color_attachment >= renderpass_attachment_count)) {
+ skip |= LogError(
+ commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
+ "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u is not VK_ATTACHMENT_UNUSED "
+ "and not a valid attachment for %s attachmentCount=%u. Subpass %u pColorAttachment[%u]=%u.",
+ attachment_index, clear_desc->colorAttachment,
+ report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(), cb_node->activeSubpass,
+ clear_desc->colorAttachment, color_attachment, renderpass_attachment_count);
- color_attachment = VK_ATTACHMENT_UNUSED; // Defensive, prevent lookup past end of renderpass attachment
+ color_attachment = VK_ATTACHMENT_UNUSED; // Defensive, prevent lookup past end of renderpass attachment
+ }
+ } else {
+ skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
+ "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u out of range for %s"
+ " subpass %u. colorAttachmentCount=%u",
+ attachment_index, clear_desc->colorAttachment,
+ report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(),
+ cb_node->activeSubpass, subpass_desc->colorAttachmentCount);
}
- } else {
- skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
- "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u out of range for %s"
- " subpass %u. colorAttachmentCount=%u",
- attachment_index, clear_desc->colorAttachment,
- report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(),
- cb_node->activeSubpass, subpass_desc->colorAttachmentCount);
}
fb_attachment = color_attachment;
@@ -3411,38 +3404,44 @@
} else { // Must be depth and/or stencil
bool subpass_depth = false;
bool subpass_stencil = false;
- if (subpass_desc->pDepthStencilAttachment &&
- (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
- auto index = subpass_desc->pDepthStencilAttachment->attachment;
- subpass_depth = FormatHasDepth(renderpass_create_info->pAttachments[index].format);
- subpass_stencil = FormatHasStencil(renderpass_create_info->pAttachments[index].format);
- }
- if (!subpass_desc->pDepthStencilAttachment ||
- (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
- if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !subpass_depth) {
- skip |= LogError(
- commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02502",
- "vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_DEPTH_BIT but there is no "
- "depth attachment in subpass",
- attachment_index);
+ if (subpass_desc) {
+ if (subpass_desc->pDepthStencilAttachment &&
+ (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
+ auto index = subpass_desc->pDepthStencilAttachment->attachment;
+ subpass_depth = FormatHasDepth(renderpass_create_info->pAttachments[index].format);
+ subpass_stencil = FormatHasStencil(renderpass_create_info->pAttachments[index].format);
}
- if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !subpass_stencil) {
+ if (!subpass_desc->pDepthStencilAttachment ||
+ (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
+ if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !subpass_depth) {
+ skip |= LogError(
+ commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02502",
+ "vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_DEPTH_BIT but there is no "
+ "depth attachment in subpass",
+ attachment_index);
+ }
+ if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !subpass_stencil) {
skip |= LogError(
commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02503",
"vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_STENCIL_BIT but there is no "
- "stencil attachment in subpass",
- attachment_index);
+ "stencil attachment in subpass",
+ attachment_index);
+ }
+ } else {
+ fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
}
- } else {
- fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
- }
- if (subpass_depth) {
- skip |= ValidateClearDepthStencilValue(commandBuffer, clear_desc->clearValue.depthStencil,
- "vkCmdClearAttachments()");
+ if (subpass_depth) {
+ skip |= ValidateClearDepthStencilValue(commandBuffer, clear_desc->clearValue.depthStencil,
+ "vkCmdClearAttachments()");
+ }
}
}
if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
- skip |= ValidateClearAttachmentExtent(commandBuffer, attachment_index, framebuffer, fb_attachment, render_area,
+ const IMAGE_VIEW_STATE* image_view_state = nullptr;
+ if (framebuffer && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < framebuffer->createInfo.attachmentCount)) {
+ image_view_state = cb_node->GetActiveAttachmentImageViewState(fb_attachment);
+ }
+ skip |= ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, render_area,
rectCount, pRects);
}
@@ -3458,16 +3457,16 @@
"VUID-vkCmdClearAttachments-commandBuffer-02505");
}
}
- }
- // When a subpass uses a non-zero view mask, multiview functionality is considered to be enabled
- if (subpass_desc->viewMask > 0) {
- for (uint32_t i = 0; i < rectCount; ++i) {
- if (pRects[i].baseArrayLayer != 0 || pRects[i].layerCount != 1) {
- skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-baseArrayLayer-00018",
- "vkCmdClearAttachments(): pRects[%" PRIu32 "] baseArrayLayer is %" PRIu32
- " and layerCount is %" PRIu32 ", but the render pass instance uses multiview.",
- i, pRects[i].baseArrayLayer, pRects[i].layerCount);
+ // When a subpass uses a non-zero view mask, multiview functionality is considered to be enabled
+ if (subpass_desc && (subpass_desc->viewMask > 0)) {
+ for (uint32_t i = 0; i < rectCount; ++i) {
+ if (pRects[i].baseArrayLayer != 0 || pRects[i].layerCount != 1) {
+ skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-baseArrayLayer-00018",
+ "vkCmdClearAttachments(): pRects[%" PRIu32 "] baseArrayLayer is %" PRIu32
+ " and layerCount is %" PRIu32 ", but the render pass instance uses multiview.",
+ i, pRects[i].baseArrayLayer, pRects[i].layerCount);
+ }
}
}
}
@@ -3480,37 +3479,89 @@
const VkClearRect *pRects) {
auto *cb_node = GetCBState(commandBuffer);
if (cb_node->activeRenderPass && (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)) {
- const VkRenderPassCreateInfo2 *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr();
- const VkSubpassDescription2 *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass];
std::shared_ptr<std::vector<VkClearRect>> clear_rect_copy;
- for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
- const auto clear_desc = &pAttachments[attachment_index];
- uint32_t fb_attachment = VK_ATTACHMENT_UNUSED;
- if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
- (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount)) {
- fb_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
- } else if ((clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) &&
- subpass_desc->pDepthStencilAttachment) {
- fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
- }
- if (fb_attachment != VK_ATTACHMENT_UNUSED) {
- if (!clear_rect_copy) {
- // We need a copy of the clear rectangles that will persist until the last lambda executes
- // but we want to create it as lazily as possible
- clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+ if (cb_node->activeRenderPass->use_dynamic_rendering) {
+ if (cb_node->activeRenderPass->use_dynamic_rendering_inherited)
+ {
+ for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
+ const auto clear_desc = &pAttachments[attachment_index];
+ auto colorAttachmentCount = cb_node->activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
+ int image_index = -1;
+ if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
+ (clear_desc->colorAttachment < colorAttachmentCount)) {
+ image_index = cb_node->GetDynamicColorAttachmentImageIndex(clear_desc->colorAttachment);
+ }
+ else if (clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT)) {
+ image_index = cb_node->GetDynamicDepthAttachmentImageIndex();
+ }
+ else if (clear_desc->aspectMask & (VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ image_index = cb_node->GetDynamicStencilAttachmentImageIndex();
+ }
+
+ if (image_index != -1) {
+ if (!clear_rect_copy) {
+ // We need a copy of the clear rectangles that will persist until the last lambda executes
+ // but we want to create it as lazily as possible
+ clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+ }
+ // if a secondary level command buffer inherits the framebuffer from the primary command buffer
+ // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
+ auto val_fn = [this, commandBuffer, attachment_index, image_index, rectCount, clear_rect_copy](
+ const CMD_BUFFER_STATE* prim_cb, const FRAMEBUFFER_STATE* fb) {
+ assert(rectCount == clear_rect_copy->size());
+ bool skip = false;
+ const IMAGE_VIEW_STATE* image_view_state = nullptr;
+ if (image_index != -1) {
+ image_view_state = (*prim_cb->active_attachments)[image_index];
+ }
+ skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, prim_cb->activeRenderPass->dynamic_rendering_info.renderArea, rectCount,
+ clear_rect_copy->data());
+ return skip;
+ };
+ cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+ }
}
- // if a secondary level command buffer inherits the framebuffer from the primary command buffer
- // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
- auto val_fn = [this, commandBuffer, attachment_index, fb_attachment, rectCount, clear_rect_copy](
- const CMD_BUFFER_STATE *prim_cb, const FRAMEBUFFER_STATE *fb) {
- assert(rectCount == clear_rect_copy->size());
- const auto &render_area = prim_cb->activeRenderPassBeginInfo.renderArea;
- bool skip = false;
- skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, fb, fb_attachment, render_area, rectCount,
- clear_rect_copy->data(), prim_cb);
- return skip;
- };
- cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+ }
+ }
+ else
+ {
+ const VkRenderPassCreateInfo2* renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr();
+ const VkSubpassDescription2* subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass];
+
+ for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
+ const auto clear_desc = &pAttachments[attachment_index];
+ uint32_t fb_attachment = VK_ATTACHMENT_UNUSED;
+ if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
+ (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount)) {
+ fb_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
+ }
+ else if ((clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) &&
+ subpass_desc->pDepthStencilAttachment) {
+ fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
+ }
+ if (fb_attachment != VK_ATTACHMENT_UNUSED) {
+ if (!clear_rect_copy) {
+ // We need a copy of the clear rectangles that will persist until the last lambda executes
+ // but we want to create it as lazily as possible
+ clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+ }
+ // if a secondary level command buffer inherits the framebuffer from the primary command buffer
+ // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
+ auto val_fn = [this, commandBuffer, attachment_index, fb_attachment, rectCount, clear_rect_copy](
+ const CMD_BUFFER_STATE* prim_cb, const FRAMEBUFFER_STATE* fb) {
+ assert(rectCount == clear_rect_copy->size());
+ const auto& render_area = prim_cb->activeRenderPassBeginInfo.renderArea;
+ bool skip = false;
+ const IMAGE_VIEW_STATE* image_view_state = nullptr;
+ if (fb && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < fb->createInfo.attachmentCount)) {
+ image_view_state = prim_cb->GetActiveAttachmentImageViewState(fb_attachment);
+ }
+ skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, render_area, rectCount,
+ clear_rect_copy->data());
+ return skip;
+ };
+ cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+ }
}
}
}
diff --git a/layers/cmd_buffer_state.cpp b/layers/cmd_buffer_state.cpp
index 1c77a16..44cec54 100644
--- a/layers/cmd_buffer_state.cpp
+++ b/layers/cmd_buffer_state.cpp
@@ -681,6 +681,74 @@
activeFramebuffer = VK_NULL_HANDLE;
}
+void CMD_BUFFER_STATE::BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfoKHR *pRenderingInfo) {
+ RecordCmd(cmd_type);
+ activeRenderPass = std::make_shared<RENDER_PASS_STATE>(pRenderingInfo);
+
+ auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupRenderPassBeginInfo>(pRenderingInfo->pNext);
+ if (chained_device_group_struct) {
+ active_render_pass_device_mask = chained_device_group_struct->deviceMask;
+ } else {
+ active_render_pass_device_mask = initial_device_mask;
+ }
+
+ activeSubpassContents = ((pRenderingInfo->flags & VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR) ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE);
+
+ active_attachments = nullptr;
+ uint32_t attachment_count = (pRenderingInfo->colorAttachmentCount + 2) * 2;
+
+ // Set cb_state->active_attachments & cb_state->attachments_view_states
+ active_attachments = std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(attachment_count);
+ auto &attachments = *(active_attachments.get());
+
+ for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; ++i) {
+ auto& colorAttachment = attachments[GetDynamicColorAttachmentImageIndex(i)];
+ auto& colorResolveAttachment = attachments[GetDynamicColorResolveAttachmentImageIndex(i)];
+ colorAttachment = nullptr;
+ colorResolveAttachment = nullptr;
+
+ if (pRenderingInfo->pColorAttachments[i].imageView != VK_NULL_HANDLE) {
+ auto res = attachments_view_states.insert(
+ dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pColorAttachments[i].imageView));
+ colorAttachment = res.first->get();
+ if (pRenderingInfo->pColorAttachments[i].resolveMode != VK_RESOLVE_MODE_NONE &&
+ pRenderingInfo->pColorAttachments[i].resolveImageView != VK_NULL_HANDLE) {
+ colorResolveAttachment = res.first->get();
+ }
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment && pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+ auto& depthAttachment = attachments[GetDynamicDepthAttachmentImageIndex()];
+ auto& depthResolveAttachment = attachments[GetDynamicDepthResolveAttachmentImageIndex()];
+ depthAttachment = nullptr;
+ depthResolveAttachment = nullptr;
+
+ auto res =
+ attachments_view_states.insert(dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pDepthAttachment->imageView));
+ depthAttachment = res.first->get();
+ if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+ pRenderingInfo->pDepthAttachment->resolveImageView != VK_NULL_HANDLE) {
+ depthResolveAttachment = res.first->get();
+ }
+ }
+
+ if (pRenderingInfo->pStencilAttachment && pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+ auto& stencilAttachment = attachments[GetDynamicStencilAttachmentImageIndex()];
+ auto& stencilResolveAttachment = attachments[GetDynamicStencilResolveAttachmentImageIndex()];
+ stencilAttachment = nullptr;
+ stencilResolveAttachment = nullptr;
+
+ auto res =
+ attachments_view_states.insert(dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pStencilAttachment->imageView));
+ stencilAttachment = res.first->get();
+ if (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+ pRenderingInfo->pStencilAttachment->resolveImageView != VK_NULL_HANDLE) {
+ stencilResolveAttachment = res.first->get();
+ }
+ }
+}
+
void CMD_BUFFER_STATE::Begin(const VkCommandBufferBeginInfo *pBeginInfo) {
if (CB_RECORDED == state || CB_INVALID_COMPLETE == state) {
Reset();
@@ -694,33 +762,42 @@
// If we are a secondary command-buffer and inheriting. Update the items we should inherit.
if ((createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
(beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
- activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(beginInfo.pInheritanceInfo->renderPass);
- activeSubpass = beginInfo.pInheritanceInfo->subpass;
+ if (beginInfo.pInheritanceInfo->renderPass) {
+ activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(beginInfo.pInheritanceInfo->renderPass);
+ activeSubpass = beginInfo.pInheritanceInfo->subpass;
- if (beginInfo.pInheritanceInfo->framebuffer) {
- activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(beginInfo.pInheritanceInfo->framebuffer);
- active_subpasses = nullptr;
- active_attachments = nullptr;
+ if (beginInfo.pInheritanceInfo->framebuffer) {
+ activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(beginInfo.pInheritanceInfo->framebuffer);
+ active_subpasses = nullptr;
+ active_attachments = nullptr;
- if (activeFramebuffer) {
- framebuffers.insert(activeFramebuffer);
+ if (activeFramebuffer) {
+ framebuffers.insert(activeFramebuffer);
- // Set active_subpasses
- active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
- const auto &subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
- UpdateSubpassAttachments(subpass, *active_subpasses);
+ // Set active_subpasses
+ active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
+ const auto& subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
+ UpdateSubpassAttachments(subpass, *active_subpasses);
- // Set active_attachments & attachments_view_states
- active_attachments =
- std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(activeFramebuffer->createInfo.attachmentCount);
- UpdateAttachmentsView(nullptr);
+ // Set active_attachments & attachments_view_states
+ active_attachments =
+ std::make_shared<std::vector<IMAGE_VIEW_STATE*>>(activeFramebuffer->createInfo.attachmentCount);
+ UpdateAttachmentsView(nullptr);
- // Connect this framebuffer and its children to this cmdBuffer
- if (!dev_data->disabled[command_buffer_state]) {
- AddChild(activeFramebuffer.get());
+ // Connect this framebuffer and its children to this cmdBuffer
+ if (!dev_data->disabled[command_buffer_state]) {
+ AddChild(activeFramebuffer.get());
+ }
}
}
}
+ else
+ {
+ auto inheritance_rendering_info = lvl_find_in_chain<VkCommandBufferInheritanceRenderingInfoKHR>(beginInfo.pInheritanceInfo->pNext);
+ if (inheritance_rendering_info) {
+ activeRenderPass = std::make_shared<RENDER_PASS_STATE>(inheritance_rendering_info);
+ }
+ }
// Check for VkCommandBufferInheritanceViewportScissorInfoNV (VK_NV_inherited_viewport_scissor)
auto p_inherited_viewport_scissor_info =
diff --git a/layers/cmd_buffer_state.h b/layers/cmd_buffer_state.h
index 40bff88..bd67f59 100644
--- a/layers/cmd_buffer_state.h
+++ b/layers/cmd_buffer_state.h
@@ -401,6 +401,8 @@
void NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents);
void EndRenderPass(CMD_TYPE cmd_type);
+ void BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfoKHR *pRenderingInfo);
+
void ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers);
void UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point, const PIPELINE_LAYOUT_STATE *pipeline_layout,
@@ -442,6 +444,24 @@
void Submit(uint32_t perf_submit_pass);
void Retire(uint32_t perf_submit_pass);
+ uint32_t GetDynamicColorAttachmentCount() {
+ if (activeRenderPass) {
+ if (activeRenderPass->use_dynamic_rendering_inherited) {
+ return activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
+ }
+ if (activeRenderPass->use_dynamic_rendering) {
+ return activeRenderPass->dynamic_rendering_info.colorAttachmentCount;
+ }
+ }
+ return 0;
+ }
+ uint32_t GetDynamicColorAttachmentImageIndex(uint32_t index) { return index; }
+ uint32_t GetDynamicColorResolveAttachmentImageIndex(uint32_t index) { return index + GetDynamicColorAttachmentCount(); }
+ uint32_t GetDynamicDepthAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount(); }
+ uint32_t GetDynamicDepthResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 1; }
+ uint32_t GetDynamicStencilAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 2; }
+ uint32_t GetDynamicStencilResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 3; }
+
protected:
void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 7ebaa3a..119fe2d 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -851,48 +851,53 @@
if (!create_info.pRasterizationState || (create_info.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
VkSampleCountFlagBits pso_num_samples = GetNumSamples(pPipeline);
if (pCB->activeRenderPass) {
- const auto render_pass_info = pCB->activeRenderPass->createInfo.ptr();
- const VkSubpassDescription2 *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
- uint32_t i;
- unsigned subpass_num_samples = 0;
+ if (pCB->activeRenderPass->use_dynamic_rendering) {
+ // TODO: Mirror the below VUs but using dynamic rendering
+ const auto dynamic_rendering_info = pCB->activeRenderPass->dynamic_rendering_info;
+ } else {
+ const auto render_pass_info = pCB->activeRenderPass->createInfo.ptr();
+ const VkSubpassDescription2 *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
+ uint32_t i;
+ unsigned subpass_num_samples = 0;
- for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
- const auto attachment = subpass_desc->pColorAttachments[i].attachment;
- if (attachment != VK_ATTACHMENT_UNUSED) {
- subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
+ for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
+ const auto attachment = subpass_desc->pColorAttachments[i].attachment;
+ if (attachment != VK_ATTACHMENT_UNUSED) {
+ subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
- const auto *imageview_state = pCB->GetActiveAttachmentImageViewState(attachment);
- if (imageview_state != nullptr &&
- attachment < pPipeline->create_info.graphics.pColorBlendState->attachmentCount) {
- if ((imageview_state->format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) == 0 &&
+ const auto *imageview_state = pCB->GetActiveAttachmentImageViewState(attachment);
+ if (imageview_state != nullptr &&
+ attachment < pPipeline->create_info.graphics.pColorBlendState->attachmentCount) {
+ if ((imageview_state->format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) == 0 &&
pPipeline->create_info.graphics.pColorBlendState->pAttachments[attachment].blendEnable != VK_FALSE) {
skip |= LogError(pPipeline->pipeline(), vuid.blend_enable,
"%s: Image view's format features of the color attachment (%" PRIu32
") of the active subpass do not contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT "
"bit, but active pipeline's pAttachments[%" PRIu32 "].blendEnable is not VK_FALSE.",
caller, attachment, attachment);
+ }
}
}
}
- }
- if (subpass_desc->pDepthStencilAttachment &&
- subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
- const auto attachment = subpass_desc->pDepthStencilAttachment->attachment;
- subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
- }
+ if (subpass_desc->pDepthStencilAttachment &&
+ subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+ const auto attachment = subpass_desc->pDepthStencilAttachment->attachment;
+ subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
+ }
- if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
- IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples)) &&
- ((subpass_num_samples & static_cast<unsigned>(pso_num_samples)) != subpass_num_samples)) {
- LogObjectList objlist(pPipeline->pipeline());
- objlist.add(pCB->activeRenderPass->renderPass());
+ if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
+ IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples)) &&
+ ((subpass_num_samples & static_cast<unsigned>(pso_num_samples)) != subpass_num_samples)) {
+ LogObjectList objlist(pPipeline->pipeline());
+ objlist.add(pCB->activeRenderPass->renderPass());
skip |=
LogError(objlist, vuid.rasterization_samples,
"%s: In %s the sample count is %s while the current %s has %s and they need to be the same.", caller,
report_data->FormatHandle(pPipeline->pipeline()).c_str(), string_VkSampleCountFlagBits(pso_num_samples),
- report_data->FormatHandle(pCB->activeRenderPass->renderPass()).c_str(),
- string_VkSampleCountFlags(static_cast<VkSampleCountFlags>(subpass_num_samples)).c_str());
+ report_data->FormatHandle(pCB->activeRenderPass->renderPass()).c_str(),
+ string_VkSampleCountFlags(static_cast<VkSampleCountFlags>(subpass_num_samples)).c_str());
+ }
}
} else {
skip |= LogError(pPipeline->pipeline(), kVUID_Core_DrawState_NoActiveRenderpass,
@@ -901,7 +906,7 @@
}
}
// Verify that PSO creation renderPass is compatible with active renderPass
- if (pCB->activeRenderPass) {
+ if (pCB->activeRenderPass && !pCB->activeRenderPass->use_dynamic_rendering) {
// TODO: AMD extension codes are included here, but actual function entrypoints are not yet intercepted
if (pCB->activeRenderPass->renderPass() != pPipeline->rp_state->renderPass()) {
// renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
@@ -1249,22 +1254,31 @@
if (create_info.pColorBlendState) {
const auto *subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
- for (uint32_t i = 0; i < pPipeline->attachments.size() && i < subpass_desc->colorAttachmentCount; ++i) {
- const auto attachment = subpass_desc->pColorAttachments[i].attachment;
- if (attachment == VK_ATTACHMENT_UNUSED) continue;
+ uint32_t numberColorAttachments = (pPipeline->rp_state->use_dynamic_rendering)
+ ? pPipeline->rp_state->rendering_create_info.colorAttachmentCount
+ : subpass_desc->colorAttachmentCount;
- const auto attachment_desc = pPipeline->rp_state->createInfo.pAttachments[attachment];
- const VkFormatFeatureFlags format_features = GetPotentialFormatFeatures(attachment_desc.format);
+ for (uint32_t i = 0; i < pPipeline->attachments.size() && i < numberColorAttachments; ++i) {
+ VkFormatFeatureFlags format_features;
- if (create_info.pRasterizationState &&
- !create_info.pRasterizationState->rasterizerDiscardEnable &&
- pPipeline->attachments[i].blendEnable && !(format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) {
+ if (pPipeline->rp_state->use_dynamic_rendering) {
+ format_features = GetPotentialFormatFeatures(pPipeline->rp_state->rendering_create_info.pColorAttachmentFormats[i]);
+ } else {
+ const auto attachment = subpass_desc->pColorAttachments[i].attachment;
+ if (attachment == VK_ATTACHMENT_UNUSED) continue;
+
+ const auto attachment_desc = pPipeline->rp_state->createInfo.pAttachments[attachment];
+ format_features = GetPotentialFormatFeatures(attachment_desc.format);
+
+ if (create_info.pRasterizationState && !create_info.pRasterizationState->rasterizerDiscardEnable &&
+ pPipeline->attachments[i].blendEnable && !(format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) {
skip |=
LogError(device, "VUID-VkGraphicsPipelineCreateInfo-blendEnable-04717",
- "vkCreateGraphicsPipelines(): pipeline.pColorBlendState.pAttachments[%" PRIu32
- "].blendEnable is VK_TRUE but format %s of the corresponding attachment description (subpass %" PRIu32
- ", attachment %" PRIu32 ") does not support VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.",
- i, string_VkFormat(attachment_desc.format), create_info.subpass, attachment);
+ "vkCreateGraphicsPipelines(): pipeline.pColorBlendState.pAttachments[%" PRIu32
+ "].blendEnable is VK_TRUE but format %s of the corresponding attachment description (subpass %" PRIu32
+ ", attachment %" PRIu32 ") does not support VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.",
+ i, string_VkFormat(attachment_desc.format), create_info.subpass, attachment);
+ }
}
}
}
@@ -1363,16 +1377,20 @@
bool skip = false;
const auto &create_info = pPipeline->create_info.graphics;
- // Ensure the subpass index is valid. If not, then ValidateGraphicsPipelineShaderState
- // produces nonsense errors that confuse users. Other layers should already
- // emit errors for renderpass being invalid.
- auto subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
- if (create_info.subpass >= pPipeline->rp_state->createInfo.subpassCount) {
- skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-subpass-00759",
- "Invalid Pipeline CreateInfo[%" PRIu32
- "] State: Subpass index %u is out of range for this renderpass (0..%u).",
- pipelineIndex, create_info.subpass, pPipeline->rp_state->createInfo.subpassCount - 1);
- subpass_desc = nullptr;
+ safe_VkSubpassDescription2 *subpass_desc = nullptr;
+
+ if (!pPipeline->rp_state->use_dynamic_rendering) {
+ // Ensure the subpass index is valid. If not, then ValidateGraphicsPipelineShaderState
+ // produces nonsense errors that confuse users. Other layers should already
+ // emit errors for renderpass being invalid.
+ subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
+ if (create_info.subpass >= pPipeline->rp_state->createInfo.subpassCount) {
+ skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-subpass-00759",
+ "Invalid Pipeline CreateInfo[%" PRIu32
+ "] State: Subpass index %u is out of range for this renderpass (0..%u).",
+ pipelineIndex, create_info.subpass, pPipeline->rp_state->createInfo.subpassCount - 1);
+ subpass_desc = nullptr;
+ }
}
if (create_info.pColorBlendState != NULL) {
@@ -1781,28 +1799,28 @@
"subpass uses color attachments.",
pipelineIndex);
}
- }
- constexpr int num_bits = sizeof(subpass_desc->viewMask) * CHAR_BIT;
- std::bitset<num_bits> view_bits(subpass_desc->viewMask);
- uint32_t view_bits_count = static_cast<uint32_t>(view_bits.count());
- if (view_bits_count > 1) {
- if (!enabled_features.multiview_features.multiviewTessellationShader &&
- (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
- pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
- skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00760",
- "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
- " bits set in viewMask and pStages includes tessellation shaders, but the "
- "VkPhysicalDeviceMultiviewFeatures::multiviewTessellationShader features is not enabled.",
- pipelineIndex, view_bits_count);
- }
- if (!enabled_features.multiview_features.multiviewGeometryShader &&
- pPipeline->active_shaders & VK_SHADER_STAGE_GEOMETRY_BIT) {
- skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00761",
- "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
- " bits set in viewMask and pStages includes geometry shader, but the "
- "VkPhysicalDeviceMultiviewFeatures::multiviewGeometryShader features is not enabled.",
- pipelineIndex, view_bits_count);
+ constexpr int num_bits = sizeof(subpass_desc->viewMask) * CHAR_BIT;
+ std::bitset<num_bits> view_bits(subpass_desc->viewMask);
+ uint32_t view_bits_count = static_cast<uint32_t>(view_bits.count());
+ if (view_bits_count > 1) {
+ if (!enabled_features.multiview_features.multiviewTessellationShader &&
+ (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
+ pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
+ skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00760",
+ "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
+ " bits set in viewMask and pStages includes tessellation shaders, but the "
+ "VkPhysicalDeviceMultiviewFeatures::multiviewTessellationShader features is not enabled.",
+ pipelineIndex, view_bits_count);
+ }
+ if (!enabled_features.multiview_features.multiviewGeometryShader &&
+ pPipeline->active_shaders & VK_SHADER_STAGE_GEOMETRY_BIT) {
+ skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00761",
+ "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
+ " bits set in viewMask and pStages includes geometry shader, but the "
+ "VkPhysicalDeviceMultiviewFeatures::multiviewGeometryShader features is not enabled.",
+ pipelineIndex, view_bits_count);
+ }
}
}
}
@@ -2433,12 +2451,14 @@
bool CoreChecks::ValidateCmdSubpassState(const CMD_BUFFER_STATE *pCB, const CMD_TYPE cmd_type) const {
if (!pCB->activeRenderPass) return false;
bool skip = false;
- if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS &&
+ if (pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY &&
+ pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS &&
(cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS &&
cmd_type != CMD_NEXTSUBPASS2 && cmd_type != CMD_NEXTSUBPASS2KHR && cmd_type != CMD_ENDRENDERPASS2 &&
cmd_type != CMD_ENDRENDERPASS2KHR)) {
skip |= LogError(pCB->commandBuffer(), kVUID_Core_DrawState_InvalidCommandBuffer,
- "Commands cannot be called in a subpass using secondary command buffers.");
+ "%s() cannot be called in a subpass using secondary command buffers.",
+ kGeneratedCommandNameList[cmd_type]);
} else if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_INLINE && cmd_type == CMD_EXECUTECOMMANDS) {
skip |= LogError(pCB->commandBuffer(), kVUID_Core_DrawState_InvalidCommandBuffer,
"vkCmdExecuteCommands() cannot be called in a subpass using inline commands.");
@@ -5454,14 +5474,8 @@
"].renderPass is VK_NULL_HANDLE but dynamicRendering is not enabled.",
i);
- } else {
- skip |= LogError(device, "UNASSIGNED-VkGraphicsPipelineCreateInfo-dynamicRendering-not-supported",
- "vkCreateGraphicsPipeline: pCreateInfos[%" PRIu32
- "].renderPass is VK_NULL_HANDLE. VK_KHR_dynamic_rendering is currently unsupported",
- i);
- }
- // it is unsafe to continue validating so we need to always fail creation of the pipeline.
- return true;
+ return true;
+ }
}
}
@@ -6392,6 +6406,475 @@
"vkUpdateDescriptorSets()");
}
+bool CoreChecks::PreCallValidateCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+ const VkRenderingInfoKHR *pRenderingInfo) const {
+ const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
+ if (!cb_state) return false;
+ bool skip = false;
+
+ if (pRenderingInfo->viewMask != 0 && pRenderingInfo->layerCount == 0) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-viewMask-06069",
+ "vkCmdBeginRenderingKHR(): If viewMask is not 0 (%u), layerCount must not be 0 (%u)",
+ pRenderingInfo->viewMask, pRenderingInfo->layerCount);
+ }
+
+ if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
+ IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples))) {
+ uint32_t first_sample_count_attachment = VK_ATTACHMENT_UNUSED;
+ for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+ auto image_view = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+ first_sample_count_attachment = (j == 0u) ? static_cast<uint32_t>(image_view->samples) : first_sample_count_attachment;
+
+ if (first_sample_count_attachment != image_view->samples) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-imageView-06070",
+ "vkCmdBeginRenderingKHR(): Color attachment ref %u has sample count %s, whereas first color attachment ref has "
+ "sample count %u.",
+ j, string_VkSampleCountFlagBits(image_view->samples), (first_sample_count_attachment));
+ }
+ }
+ }
+
+ if (!(pRenderingInfo->colorAttachmentCount <= phys_dev_props.limits.maxColorAttachments)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06106",
+ "vkCmdBeginRenderingKHR(): colorAttachmentCount (%u) must be less than or equal to "
+ "VkPhysicalDeviceLimits::maxColorAttachments (%u)",
+ pRenderingInfo->colorAttachmentCount, phys_dev_props.limits.maxColorAttachments);
+ }
+
+ if ((enabled_features.core11.multiview == VK_FALSE) && (pRenderingInfo->viewMask != 0)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-multiview-06127",
+ "vkCmdBeginRenderingKHR(): If the multiview feature is not enabled, viewMask must be 0 (%u)",
+ pRenderingInfo->viewMask);
+ }
+
+ auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupRenderPassBeginInfo>(pRenderingInfo->pNext);
+ if (!chained_device_group_struct || (chained_device_group_struct && chained_device_group_struct->deviceRenderAreaCount == 0)) {
+ if (pRenderingInfo->renderArea.offset.x < 0) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06077",
+ "vkCmdBeginRenderingKHR(): renderArea.offset.x is %d and must be greater than 0",
+ pRenderingInfo->renderArea.offset.x);
+ }
+
+ if (pRenderingInfo->renderArea.offset.y < 0) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06078",
+ "vkCmdBeginRenderingKHR(): renderArea.offset.y is %d and must be greater than 0",
+ pRenderingInfo->renderArea.offset.y);
+ }
+
+ for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+ if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+ auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+ IMAGE_STATE *image_state = image_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >=
+ pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+ skip |=
+ LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+ "vkCmdBeginRenderingKHR(): width of the pColorAttachments[%u].imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ j, image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >=
+ pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+ skip |=
+ LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+ "vkCmdBeginRenderingKHR(): height of the pColorAttachments[%u].imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ j, image_state->createInfo.extent.height);
+ }
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment != VK_NULL_HANDLE && pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+ auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+ IMAGE_STATE *image_state = depth_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >=
+ pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+ "vkCmdBeginRenderingKHR(): width of the pDepthAttachment->imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >=
+ pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+ "vkCmdBeginRenderingKHR(): height of the pDepthAttachment->imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ image_state->createInfo.extent.height);
+ }
+ }
+
+ if (pRenderingInfo->pStencilAttachment != VK_NULL_HANDLE && pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+ auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+ IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >=
+ pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+ "vkCmdBeginRenderingKHR(): width of the pStencilAttachment->imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >=
+ pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+ "vkCmdBeginRenderingKHR(): height of the pStencilAttachment->imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ image_state->createInfo.extent.height);
+ }
+ }
+ }
+
+ if (chained_device_group_struct) {
+ for (uint32_t deviceRenderAreaIndex = 0; deviceRenderAreaIndex < chained_device_group_struct->deviceRenderAreaCount;
+ ++deviceRenderAreaIndex) {
+ auto offset_x = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].offset.x;
+ auto width = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].extent.width;
+ if (!(offset_x >= 0)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06081",
+ "vkCmdBeginRenderingKHR(): pDeviceRenderAreas[%u].offset.x: %d must be greater than or equal to 0",
+ deviceRenderAreaIndex, offset_x);
+ }
+ auto offset_y = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].offset.y;
+ auto height = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].extent.height;
+ if (!(offset_y >= 0)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06082",
+ "vkCmdBeginRenderingKHR(): pDeviceRenderAreas[%u].offset.y: %d must be greater than or equal to 0",
+ deviceRenderAreaIndex, offset_y);
+ }
+
+ for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+ if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+ auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+ IMAGE_STATE *image_state = image_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+ "vkCmdBeginRenderingKHR(): width of the pColorAttachments[%u].imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ j, image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+ "vkCmdBeginRenderingKHR(): height of the pColorAttachments[%u].imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ j, image_state->createInfo.extent.height);
+ }
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment != VK_NULL_HANDLE) {
+ auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+ IMAGE_STATE *image_state = depth_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+ "vkCmdBeginRenderingKHR(): width of the pDepthAttachment->imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+ "vkCmdBeginRenderingKHR(): height of the pDepthAttachment->imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ image_state->createInfo.extent.height);
+ }
+ }
+
+ if (pRenderingInfo->pStencilAttachment != VK_NULL_HANDLE) {
+ auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+ IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+ if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+ "vkCmdBeginRenderingKHR(): width of the pStencilAttachment->imageView: %u must be greater than"
+ "renderArea.offset.x + renderArea.extent.width",
+ image_state->createInfo.extent.width);
+ }
+ if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+ "vkCmdBeginRenderingKHR(): height of the pStencilAttachment->imageView: %u must be greater than"
+ "renderArea.offset.y + renderArea.extent.height",
+ image_state->createInfo.extent.height);
+ }
+ }
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment != NULL && pRenderingInfo->pStencilAttachment != NULL) {
+ if (pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE &&
+ pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+ if (!(pRenderingInfo->pDepthAttachment->imageView == pRenderingInfo->pStencilAttachment->imageView)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06085",
+ "vkCmdBeginRenderingKHR(): imageView of pDepthAttachment and pStencilAttachment must be the same");
+ }
+
+ if ((phys_dev_props_core12.independentResolveNone == VK_FALSE) &&
+ (pRenderingInfo->pDepthAttachment->resolveMode != pRenderingInfo->pStencilAttachment->resolveMode)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06104",
+ "vkCmdBeginRenderingKHR(): The values of depthResolveMode (%u) and stencilResolveMode (%u) must be identical.",
+ pRenderingInfo->pDepthAttachment->resolveMode, pRenderingInfo->pStencilAttachment->resolveMode);
+ }
+
+ if ((phys_dev_props_core12.independentResolve == VK_FALSE) &&
+ (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) &&
+ (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) &&
+ (pRenderingInfo->pStencilAttachment->resolveMode != pRenderingInfo->pDepthAttachment->resolveMode)) {
+ skip |= LogError(device, "VUID-VkRenderingInfoKHR-pDepthAttachment-06105",
+ "vkCmdBeginRenderingKHR(): The values of depthResolveMode (%u) and stencilResolveMode (%u) must "
+ "be identical, or "
+ "one of them must be %u.",
+ pRenderingInfo->pDepthAttachment->resolveMode, pRenderingInfo->pStencilAttachment->resolveMode,
+ VK_RESOLVE_MODE_NONE);
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+ pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (!(pRenderingInfo->pDepthAttachment->resolveImageView == pRenderingInfo->pStencilAttachment->resolveImageView)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06086",
+ "vkCmdBeginRenderingKHR(): resolveImageView of pDepthAttachment and pStencilAttachment must be the same");
+ }
+ }
+ }
+
+ for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+ skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, &pRenderingInfo->pColorAttachments[j]);
+
+ if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+ auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+ IMAGE_STATE *image_state = image_view_state->image_state.get();
+ if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06087",
+ "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT");
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06090",
+ "vkCmdBeginRenderingKHR(): imageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or "
+ "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06091",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or "
+ "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
+ }
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06096",
+ "vkCmdBeginRenderingKHR(): imageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL "
+ "or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (pRenderingInfo->pColorAttachments[j].resolveImageLayout ==
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].resolveImageLayout ==
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06097",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL or "
+ "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+ }
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06100",
+ "vkCmdBeginRenderingKHR(): imageLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL"
+ " or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"
+ " or VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL"
+ " or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
+ pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06101",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or "
+ "VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL");
+ }
+ }
+ }
+ }
+
+ if (pRenderingInfo->pDepthAttachment != NULL) {
+ skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, pRenderingInfo->pDepthAttachment);
+
+ if (pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+ auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+ IMAGE_STATE *image_state = depth_view_state->image_state.get();
+ if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06088",
+ "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT");
+ }
+
+ if (pRenderingInfo->pDepthAttachment->imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06092",
+ "vkCmdBeginRenderingKHR(): image must not have been created with VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (pRenderingInfo->pDepthAttachment->resolveImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06093",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pDepthAttachment->resolveImageLayout ==
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06098",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL");
+ }
+
+ if (!(pRenderingInfo->pDepthAttachment->resolveMode & phys_dev_props_core12.supportedDepthResolveModes)) {
+ skip |= LogError(device, "VUID-VkRenderingInfoKHR-pDepthAttachment-06102",
+ "vkCmdBeginRenderingKHR(): Includes a resolveMode structure with invalid mode=%u.",
+ pRenderingInfo->pDepthAttachment->resolveMode);
+ }
+ }
+
+ }
+ }
+
+ if (pRenderingInfo->pStencilAttachment != NULL) {
+ skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, pRenderingInfo->pStencilAttachment);
+
+ if (pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+ auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+ IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+ if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06089",
+ "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT");
+ }
+
+ if (pRenderingInfo->pStencilAttachment->imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06094",
+ "vkCmdBeginRenderingKHR(): imageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+ }
+
+ if (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (pRenderingInfo->pStencilAttachment->resolveImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06095",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+ }
+ if (pRenderingInfo->pStencilAttachment->resolveImageLayout ==
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06099",
+ "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+ "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+ }
+ if (!(pRenderingInfo->pStencilAttachment->resolveMode & phys_dev_props_core12.supportedStencilResolveModes)) {
+ skip |= LogError(device, "VUID-VkRenderingInfoKHR-pStencilAttachment-06103",
+ "vkCmdBeginRenderingKHR(): Includes a resolveMode structure with invalid mode (%s).",
+ string_VkResolveModeFlagBits(pRenderingInfo->pStencilAttachment->resolveMode));
+ }
+ }
+
+ }
+ }
+
+ return skip;
+}
+
+bool CoreChecks::ValidateRenderingAttachmentInfoKHR(VkCommandBuffer commandBuffer,
+ const VkRenderingAttachmentInfoKHR *pAttachments) const {
+ const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
+ if (!cb_state) return false;
+ bool skip = false;
+
+ if (pAttachments->imageView != VK_NULL_HANDLE) {
+ auto image_view_state = GetImageViewState(pAttachments->imageView);
+ if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06132",
+ "Image sample count must not have a VK_SAMPLE_COUNT_1_BIT for Resolve Mode %s",
+ string_VkResolveModeFlags(pAttachments->resolveMode).c_str());
+ }
+
+ auto resolve_view_state = GetImageViewState(pAttachments->resolveImageView);
+ if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE && resolve_view_state->samples != VK_SAMPLE_COUNT_1_BIT) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06133",
+ "resolveImageView sample count must have a VK_SAMPLE_COUNT_1_BIT for Resolve Mode %s",
+ string_VkResolveModeFlags(pAttachments->resolveMode).c_str());
+ }
+
+ if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE) {
+ if (image_view_state->create_info.format != resolve_view_state->create_info.format) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06134",
+ "resolveImageView format (%u) and ImageView format (%u) must have the same VkFormat",
+ resolve_view_state->create_info.format, image_view_state->create_info.format);
+ }
+
+ if (((pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_UNDEFINED) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_PREINITIALIZED))) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06136",
+ "resolveImageLayout (%s) must not be VK_IMAGE_LAYOUT_UNDEFINED, "
+ "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "
+ "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, or VK_IMAGE_LAYOUT_PREINITIALIZED",
+ string_VkImageLayout(pAttachments->resolveImageLayout));
+ }
+
+ if (((pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL) ||
+ (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06137",
+ "resolveImageLayout (%s) must not be VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, "
+ "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL",
+ string_VkImageLayout(pAttachments->resolveImageLayout));
+ }
+ }
+
+ if ((pAttachments->imageLayout == VK_IMAGE_LAYOUT_UNDEFINED) ||
+ (pAttachments->imageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) ||
+ (pAttachments->imageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) ||
+ (pAttachments->imageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) ||
+ (pAttachments->imageLayout == VK_IMAGE_LAYOUT_PREINITIALIZED)) {
+ skip |= LogError(
+ commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06135",
+ "layout (%s) must not be VK_IMAGE_LAYOUT_UNDEFINED VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "
+ "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, or VK_IMAGE_LAYOUT_PREINITIALIZED",
+ string_VkImageLayout(pAttachments->imageLayout));
+ }
+
+ if (pAttachments->imageLayout == VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06138",
+ "layout (%s) must not be VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV",
+ string_VkImageLayout(pAttachments->imageLayout));
+ }
+
+ if (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV) {
+ skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06139",
+ "layout (%s) must not be VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV",
+ string_VkImageLayout(pAttachments->resolveImageLayout));
+ }
+ }
+
+ return skip;
+}
+
bool CoreChecks::PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo *pBeginInfo) const {
const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
@@ -6422,7 +6905,6 @@
report_data->FormatHandle(commandBuffer).c_str());
} else {
if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
- assert(info->renderPass);
const auto *framebuffer = GetFramebufferState(info->framebuffer);
if (framebuffer) {
if (framebuffer->createInfo.renderPass != info->renderPass) {
@@ -6433,6 +6915,22 @@
"VUID-VkCommandBufferBeginInfo-flags-00055");
}
}
+
+ if (info->renderPass != VK_NULL_HANDLE) {
+ const auto* render_pass = GetRenderPassState(info->renderPass);
+ if (!render_pass) {
+ skip |= LogError(commandBuffer, "VUID-VkCommandBufferBeginInfo-flags-06000",
+ "Renderpass must be a valid VkRenderPass");
+ }
+ } else {
+ auto p_inherited_rendering_info = LvlFindInChain<VkCommandBufferInheritanceRenderingInfoKHR>(info->pNext);
+ if (!p_inherited_rendering_info) {
+ // The pNext chain of pInheritanceInfo must include a VkCommandBufferInheritanceRenderingInfoKHR structure
+ skip |= LogError(commandBuffer, "VUID-VkCommandBufferBeginInfo-flags-06002",
+ "The pNext chain of pInheritanceInfo must include a "
+ "VkCommandBufferInheritanceRenderingInfoKHR structure");
+ }
+ }
}
if ((info->occlusionQueryEnable == VK_FALSE || enabled_features.core.occlusionQueryPrecise == VK_FALSE) &&
(info->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) {
@@ -6441,8 +6939,7 @@
"occulusionQuery is disabled or the device does not support precise occlusion queries.",
report_data->FormatHandle(commandBuffer).c_str());
}
- auto p_inherited_viewport_scissor_info =
- LvlFindInChain<VkCommandBufferInheritanceViewportScissorInfoNV>(info->pNext);
+ auto p_inherited_viewport_scissor_info = LvlFindInChain<VkCommandBufferInheritanceViewportScissorInfoNV>(info->pNext);
if (p_inherited_viewport_scissor_info != nullptr && p_inherited_viewport_scissor_info->viewportScissor2D) {
if (!enabled_features.inherited_viewport_scissor_features.inheritedViewportScissor2D)
{
@@ -8487,9 +8984,8 @@
skip |= ValidatePipelineStage(objects, loc.dot(Field::srcStageMask), queue_flags, srcStageMask);
skip |= ValidatePipelineStage(objects, loc.dot(Field::dstStageMask), queue_flags, dstStageMask);
-
skip |= ValidateCmd(cb_state, CMD_PIPELINEBARRIER);
- if (cb_state->activeRenderPass) {
+ if (cb_state->activeRenderPass && !cb_state->activeRenderPass->use_dynamic_rendering) {
skip |= ValidateRenderPassPipelineBarriers(loc, cb_state, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
imageMemoryBarrierCount, pImageMemoryBarriers);
@@ -12487,7 +12983,7 @@
"VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT set in VkCommandBufferBeginInfo::flags when "
"the vkBeginCommandBuffer() was called.",
report_data->FormatHandle(pCommandBuffers[i]).c_str());
- } else if (cb_state->activeRenderPass &&
+ } else if (cb_state->activeRenderPass && (cb_state->activeRenderPass->use_dynamic_rendering == false) &&
(sub_cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
// Make sure render pass is compatible with parent command buffer pass if has continue
if (cb_state->activeRenderPass->renderPass() != secondary_rp_state->renderPass()) {
diff --git a/layers/core_validation.h b/layers/core_validation.h
index 170b6b2..5579f78 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -621,9 +621,8 @@
const char* param_name) const;
bool ValidateClearAttachmentExtent(VkCommandBuffer command_buffer, uint32_t attachment_index,
- const FRAMEBUFFER_STATE* framebuffer, uint32_t fb_attachment, const VkRect2D& render_area,
- uint32_t rect_count, const VkClearRect* clear_rects,
- const CMD_BUFFER_STATE* primary_cb_state = nullptr) const;
+ const IMAGE_VIEW_STATE *image_view_state, const VkRect2D& render_area,
+ uint32_t rect_count, const VkClearRect* clear_rects) const;
template <typename ImageCopyRegionType>
bool ValidateImageCopyData(const uint32_t regionCount, const ImageCopyRegionType* ic_regions, const IMAGE_STATE* src_state,
@@ -1085,6 +1084,9 @@
const VkCopyDescriptorSet* pDescriptorCopies) const override;
bool PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo* pBeginInfo) const override;
+ bool PreCallValidateCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+ const VkRenderingInfoKHR* pRenderingInfo) const override;
+ bool ValidateRenderingAttachmentInfoKHR(VkCommandBuffer commandBuffer, const VkRenderingAttachmentInfoKHR* pAttachments) const;
bool PreCallValidateEndCommandBuffer(VkCommandBuffer commandBuffer) const override;
bool PreCallValidateResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) const override;
bool PreCallValidateCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
@@ -1630,4 +1632,4 @@
bool PreCallValidateGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
Display* dpy, VisualID visualID) const override;
#endif // VK_USE_PLATFORM_XLIB_KHR
-}; // Class CoreChecks
+}; // Class CoreChecks
diff --git a/layers/generated/layer_chassis_dispatch.cpp b/layers/generated/layer_chassis_dispatch.cpp
index 26c3a0a..1c10fc9 100644
--- a/layers/generated/layer_chassis_dispatch.cpp
+++ b/layers/generated/layer_chassis_dispatch.cpp
@@ -264,6 +264,12 @@
}
}
+ auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[idx0].pNext);
+ if (dynamic_rendering) {
+ uses_color_attachment = (dynamic_rendering->colorAttachmentCount > 0);
+ uses_depthstencil_attachment = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+ }
+
local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);
if (pCreateInfos[idx0].basePipelineHandle) {
diff --git a/layers/object_tracker_utils.cpp b/layers/object_tracker_utils.cpp
index 649454a..55b0890 100644
--- a/layers/object_tracker_utils.cpp
+++ b/layers/object_tracker_utils.cpp
@@ -495,8 +495,8 @@
ValidateObject(begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
"VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
skip |=
- ValidateObject(begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
- "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
+ ValidateObject(begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, true,
+ "VUID-VkCommandBufferBeginInfo-flags-06000", "VUID-VkCommandBufferInheritanceInfo-commonparent");
}
}
}
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index f78a39d..0f1f39d 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -4126,6 +4126,8 @@
if (info) {
const VkStructureType allowed_structs_vk_command_buffer_inheritance_info[] = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,
+ VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV};
skip |= validate_struct_pnext(
cmd_name, "pBeginInfo->pInheritanceInfo->pNext", "VkCommandBufferInheritanceConditionalRenderingInfoEXT",
diff --git a/layers/pipeline_state.cpp b/layers/pipeline_state.cpp
index 84b2eb6..4669859 100644
--- a/layers/pipeline_state.cpp
+++ b/layers/pipeline_state.cpp
@@ -28,7 +28,6 @@
#include "pipeline_state.h"
#include "descriptor_sets.h"
#include "cmd_buffer_state.h"
-#include "render_pass_state.h"
#include "state_tracker.h"
#include "shader_module.h"
@@ -360,8 +359,7 @@
std::shared_ptr<const RENDER_PASS_STATE> &&rpstate,
std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
: BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
- create_info(pCreateInfo, rpstate->UsesColorAttachment(pCreateInfo->subpass),
- rpstate->UsesDepthStencilAttachment(pCreateInfo->subpass)),
+ create_info(pCreateInfo, rpstate),
pipeline_layout(std::move(layout)),
rp_state(rpstate),
stage_state(GetStageStates(state_data, create_info.graphics.pStages, create_info.graphics.stageCount)),
diff --git a/layers/pipeline_state.h b/layers/pipeline_state.h
index 4397db3..b4e5eee 100644
--- a/layers/pipeline_state.h
+++ b/layers/pipeline_state.h
@@ -30,6 +30,7 @@
#include "base_node.h"
#include "sampler_state.h"
#include "ray_tracing_state.h"
+#include "render_pass_state.h"
#include "shader_module.h"
// Fwd declarations -- including descriptor_set.h creates an ugly include loop
@@ -163,8 +164,24 @@
class PIPELINE_STATE : public BASE_NODE {
public:
union CreateInfo {
- CreateInfo(const VkGraphicsPipelineCreateInfo *ci, bool uses_color, bool uses_depth_stencil)
- : graphics(ci, uses_color, uses_depth_stencil) {}
+ CreateInfo(const VkGraphicsPipelineCreateInfo *ci, std::shared_ptr<const RENDER_PASS_STATE> rpstate) {
+ bool use_color = false;
+ bool use_depth = false;
+
+
+ if (ci->renderPass == VK_NULL_HANDLE) {
+ auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(ci->pNext);
+ if (dynamic_rendering) {
+ use_color = (dynamic_rendering->colorAttachmentCount > 0);
+ use_depth = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+ }
+ } else {
+ use_color = rpstate->UsesColorAttachment(ci->subpass);
+ use_depth = rpstate->UsesDepthStencilAttachment(ci->subpass);
+ }
+
+ graphics.initialize(ci, use_color, use_depth);
+ }
CreateInfo(const VkComputePipelineCreateInfo *ci) : compute(ci) {}
CreateInfo(const VkRayTracingPipelineCreateInfoKHR *ci) : raytracing(ci) {}
CreateInfo(const VkRayTracingPipelineCreateInfoNV *ci) : raytracing(ci) {}
diff --git a/layers/render_pass_state.cpp b/layers/render_pass_state.cpp
index db0d71e..f372cef 100644
--- a/layers/render_pass_state.cpp
+++ b/layers/render_pass_state.cpp
@@ -239,7 +239,7 @@
}
RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo2 const *pCreateInfo)
- : BASE_NODE(rp, kVulkanObjectTypeRenderPass), createInfo(pCreateInfo) {
+ : BASE_NODE(rp, kVulkanObjectTypeRenderPass), use_dynamic_rendering(false), use_dynamic_rendering_inherited(false), createInfo(pCreateInfo) {
InitRenderPassState(this);
}
@@ -250,10 +250,26 @@
}
RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo const *pCreateInfo)
- : BASE_NODE(rp, kVulkanObjectTypeRenderPass), createInfo(ConvertCreateInfo(*pCreateInfo)) {
+ : BASE_NODE(rp, kVulkanObjectTypeRenderPass), use_dynamic_rendering(false), use_dynamic_rendering_inherited(false), createInfo(ConvertCreateInfo(*pCreateInfo)) {
InitRenderPassState(this);
}
+const VkPipelineRenderingCreateInfoKHR VkPipelineRenderingCreateInfoKHR_default = {
+ VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
+ nullptr,
+ 0,
+ 0,
+ nullptr,
+ VK_FORMAT_UNDEFINED,
+ VK_FORMAT_UNDEFINED
+};
+
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkPipelineRenderingCreateInfoKHR const *pPipelineRenderingCreateInfo)
+ : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+ use_dynamic_rendering(true),
+ use_dynamic_rendering_inherited(false),
+ rendering_create_info(pPipelineRenderingCreateInfo ? pPipelineRenderingCreateInfo : &VkPipelineRenderingCreateInfoKHR_default) {}
+
bool RENDER_PASS_STATE::UsesColorAttachment(uint32_t subpass_num) const {
bool result = false;
@@ -281,6 +297,18 @@
return result;
}
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderingInfoKHR const *pRenderingInfo)
+ : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+ use_dynamic_rendering(true),
+ use_dynamic_rendering_inherited(false),
+ dynamic_rendering_info(pRenderingInfo) {}
+
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkCommandBufferInheritanceRenderingInfoKHR const* pInheritanceRenderingInfo)
+ : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+ use_dynamic_rendering(true),
+ use_dynamic_rendering_inherited(true),
+ inheritance_rendering_info(pInheritanceRenderingInfo) {}
+
FRAMEBUFFER_STATE::FRAMEBUFFER_STATE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo,
std::shared_ptr<RENDER_PASS_STATE> &&rpstate,
std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> &&attachments)
@@ -294,10 +322,9 @@
}
void FRAMEBUFFER_STATE::Destroy() {
- for (auto& view: attachments_view_state) {
+ for (auto &view : attachments_view_state) {
view->RemoveParent(this);
}
attachments_view_state.clear();
BASE_NODE::Destroy();
}
-
diff --git a/layers/render_pass_state.h b/layers/render_pass_state.h
index f094469..502a7d5 100644
--- a/layers/render_pass_state.h
+++ b/layers/render_pass_state.h
@@ -88,6 +88,11 @@
AttachmentTransition(uint32_t prev_pass_, uint32_t attachment_, VkImageLayout old_layout_, VkImageLayout new_layout_)
: prev_pass(prev_pass_), attachment(attachment_), old_layout(old_layout_), new_layout(new_layout_) {}
};
+ const bool use_dynamic_rendering;
+ const bool use_dynamic_rendering_inherited;
+ safe_VkRenderingInfoKHR dynamic_rendering_info;
+ const safe_VkPipelineRenderingCreateInfoKHR rendering_create_info;
+ const safe_VkCommandBufferInheritanceRenderingInfoKHR inheritance_rendering_info;
const safe_VkRenderPassCreateInfo2 createInfo;
using SubpassVec = std::vector<uint32_t>;
using SelfDepVec = std::vector<SubpassVec>;
@@ -108,6 +113,10 @@
RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo2 const *pCreateInfo);
RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo const *pCreateInfo);
+ RENDER_PASS_STATE(VkPipelineRenderingCreateInfoKHR const *pPipelineRenderingCreateInfo);
+ RENDER_PASS_STATE(VkRenderingInfoKHR const *pRenderingInfo);
+ RENDER_PASS_STATE(VkCommandBufferInheritanceRenderingInfoKHR const *pInheritanceRenderingInfo);
+
VkRenderPass renderPass() const { return handle_.Cast<VkRenderPass>(); }
bool UsesColorAttachment(uint32_t subpass) const;
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index fca93d5..87a045e 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -200,8 +200,6 @@
PIPELINE_STATE const *pipeline, uint32_t subpass_index) const {
bool skip = false;
- const auto rpci = pipeline->rp_state->createInfo.ptr();
-
struct Attachment {
const VkAttachmentReference2 *reference = nullptr;
const VkAttachmentDescription2 *attachment = nullptr;
@@ -209,13 +207,16 @@
};
std::map<uint32_t, Attachment> location_map;
- const auto subpass = rpci->pSubpasses[subpass_index];
- for (uint32_t i = 0; i < subpass.colorAttachmentCount; ++i) {
- auto const &reference = subpass.pColorAttachments[i];
- location_map[i].reference = &reference;
- if (reference.attachment != VK_ATTACHMENT_UNUSED &&
- rpci->pAttachments[reference.attachment].format != VK_FORMAT_UNDEFINED) {
- location_map[i].attachment = &rpci->pAttachments[reference.attachment];
+ if (pipeline->rp_state && !pipeline->rp_state->use_dynamic_rendering) {
+ const auto rpci = pipeline->rp_state->createInfo.ptr();
+ const auto subpass = rpci->pSubpasses[subpass_index];
+ for (uint32_t i = 0; i < subpass.colorAttachmentCount; ++i) {
+ auto const &reference = subpass.pColorAttachments[i];
+ location_map[i].reference = &reference;
+ if (reference.attachment != VK_ATTACHMENT_UNUSED &&
+ rpci->pAttachments[reference.attachment].format != VK_FORMAT_UNDEFINED) {
+ location_map[i].attachment = &rpci->pAttachments[reference.attachment];
+ }
}
}
@@ -1054,7 +1055,6 @@
}
break;
}
-
}
}
@@ -1109,8 +1109,13 @@
}
if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
- // "For the fragment shader stage the framebuffer color attachments also count against this limit"
- total_resources += pipeline->rp_state->createInfo.pSubpasses[pipeline->create_info.graphics.subpass].colorAttachmentCount;
+ if (pipeline->rp_state->use_dynamic_rendering) {
+ total_resources += pipeline->rp_state->rendering_create_info.colorAttachmentCount;
+ } else {
+ // "For the fragment shader stage the framebuffer color attachments also count against this limit"
+ total_resources +=
+ pipeline->rp_state->createInfo.pSubpasses[pipeline->create_info.graphics.subpass].colorAttachmentCount;
+ }
}
// TODO: This reuses a lot of GetDescriptorCountMaxPerStage but currently would need to make it agnostic in a way to handle
@@ -2546,23 +2551,25 @@
if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
auto input_attachment_uses = module->CollectInterfaceByInputAttachmentIndex(accessible_ids);
- auto rpci = pipeline->rp_state->createInfo.ptr();
- auto subpass = pipeline->create_info.graphics.subpass;
+ if (!pipeline->rp_state->use_dynamic_rendering) {
+ auto rpci = pipeline->rp_state->createInfo.ptr();
+ auto subpass = pipeline->create_info.graphics.subpass;
+ for (auto use : input_attachment_uses) {
+ auto input_attachments = rpci->pSubpasses[subpass].pInputAttachments;
+ auto index = (input_attachments && use.first < rpci->pSubpasses[subpass].inputAttachmentCount)
+ ? input_attachments[use.first].attachment
+ : VK_ATTACHMENT_UNUSED;
- for (auto use : input_attachment_uses) {
- auto input_attachments = rpci->pSubpasses[subpass].pInputAttachments;
- auto index = (input_attachments && use.first < rpci->pSubpasses[subpass].inputAttachmentCount)
- ? input_attachments[use.first].attachment
- : VK_ATTACHMENT_UNUSED;
-
- if (index == VK_ATTACHMENT_UNUSED) {
- skip |= LogError(device, kVUID_Core_Shader_MissingInputAttachment,
- "Shader consumes input attachment index %d but not provided in subpass", use.first);
- } else if (!(GetFormatType(rpci->pAttachments[index].format) & module->GetFundamentalType(use.second.type_id))) {
- skip |=
- LogError(device, kVUID_Core_Shader_InputAttachmentTypeMismatch,
- "Subpass input attachment %u format of %s does not match type used in shader `%s`", use.first,
- string_VkFormat(rpci->pAttachments[index].format), module->DescribeType(use.second.type_id).c_str());
+ if (index == VK_ATTACHMENT_UNUSED) {
+ skip |= LogError(device, kVUID_Core_Shader_MissingInputAttachment,
+ "Shader consumes input attachment index %d but not provided in subpass", use.first);
+ }
+ else if (!(GetFormatType(rpci->pAttachments[index].format) & module->GetFundamentalType(use.second.type_id))) {
+ skip |=
+ LogError(device, kVUID_Core_Shader_InputAttachmentTypeMismatch,
+ "Subpass input attachment %u format of %s does not match type used in shader `%s`", use.first,
+ string_VkFormat(rpci->pAttachments[index].format), module->DescribeType(use.second.type_id).c_str());
+ }
}
}
}
@@ -2766,7 +2773,6 @@
ValidateInterfaceBetweenStages(producer.module.get(), producer.entrypoint, &shader_stage_attribs[producer_id],
consumer.module.get(), consumer.entrypoint, &shader_stage_attribs[consumer_id]);
}
-
}
}
diff --git a/layers/state_tracker.cpp b/layers/state_tracker.cpp
index 489ab4f..0ff3a29 100644
--- a/layers/state_tracker.cpp
+++ b/layers/state_tracker.cpp
@@ -182,7 +182,6 @@
void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
VkImageLayout imageLayout, const VkClearColorValue *pColor,
uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
-
if (disabled[command_buffer_state]) return;
auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
@@ -392,7 +391,6 @@
void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
-
if (disabled[command_buffer_state]) return;
auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
@@ -1819,13 +1817,15 @@
cgpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
cgpl_state->pipe_state.reserve(count);
for (uint32_t i = 0; i < count; i++) {
- // Avoid crashes if VK_KHR_dynamic_rendering is in use.
if (pCreateInfos[i].renderPass != VK_NULL_HANDLE) {
cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
GetRenderPassShared(pCreateInfos[i].renderPass),
GetPipelineLayoutShared(pCreateInfos[i].layout)));
- } else {
- cgpl_state->pipe_state.push_back(std::shared_ptr<PIPELINE_STATE>());
+ } else if (enabled_features.dynamic_rendering_features.dynamicRendering) {
+ auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[i].pNext);
+ cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
+ std::make_shared<RENDER_PASS_STATE>(dynamic_rendering),
+ GetPipelineLayoutShared(pCreateInfos[i].layout)));
}
}
return false;
@@ -2427,7 +2427,6 @@
cb_state->RecordStateCmd(CMD_SETSTENCILREFERENCE, CBSTATUS_STENCIL_REFERENCE_SET);
}
-
// Update the bound state for the bind point, including the effects of incompatible pipeline layouts
void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
@@ -2793,6 +2792,28 @@
cb_state->conditional_rendering_subpass = 0;
}
+void ValidationStateTracker::RecordCmdBeginRenderingRenderPassState(VkCommandBuffer commandBuffer,
+ const VkRenderingInfoKHR *pRenderingInfo) {
+ auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+ cb_state->activeRenderPass = std::make_shared<RENDER_PASS_STATE>(pRenderingInfo);
+}
+
+void ValidationStateTracker::RecordCmdEndRenderingRenderPassState(VkCommandBuffer commandBuffer) {
+ auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+ cb_state->activeRenderPass = nullptr;
+}
+
+void ValidationStateTracker::PreCallRecordCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+ const VkRenderingInfoKHR *pRenderingInfo) {
+ RecordCmdBeginRenderingRenderPassState(commandBuffer, pRenderingInfo);
+ CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+ cb_state->BeginRendering(CMD_BEGINRENDERINGKHR, pRenderingInfo);
+}
+
+void ValidationStateTracker::PreCallRecordCmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
+ RecordCmdEndRenderingRenderPassState(commandBuffer);
+}
+
void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
const VkSubpassBeginInfo *pSubpassBeginInfo) {
@@ -2800,7 +2821,6 @@
cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
}
-
void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
cb_state->NextSubpass(CMD_NEXTSUBPASS, contents);
@@ -3847,7 +3867,6 @@
cb_state->hasTraceRaysCmd = true;
}
-
void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
diff --git a/layers/state_tracker.h b/layers/state_tracker.h
index 535e224..1d57bd9 100644
--- a/layers/state_tracker.h
+++ b/layers/state_tracker.h
@@ -414,6 +414,7 @@
std::shared_ptr<RENDER_PASS_STATE> GetRenderPassShared(VkRenderPass renderpass) {
return GetShared<RENDER_PASS_STATE>(renderpass);
}
+
const RENDER_PASS_STATE* GetRenderPassState(VkRenderPass renderpass) const { return Get<RENDER_PASS_STATE>(renderpass); }
RENDER_PASS_STATE* GetRenderPassState(VkRenderPass renderpass) { return Get<RENDER_PASS_STATE>(renderpass); }
@@ -909,6 +910,8 @@
VkQueryControlFlags flags, uint32_t index) override;
void PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents) override;
+ void PreCallRecordCmdBeginRenderingKHR(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo) override;
+ void PreCallRecordCmdEndRenderingKHR(VkCommandBuffer commandBuffer) override;
void PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
const VkSubpassBeginInfo* pSubpassBeginInfo) override;
void PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
@@ -1197,6 +1200,8 @@
void RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
void RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void** ppData);
+ void RecordCmdBeginRenderingRenderPassState(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo);
+ void RecordCmdEndRenderingRenderPassState(VkCommandBuffer commandBuffer);
void RecordVulkanSurface(VkSurfaceKHR* pSurface);
void RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout, VkResult result);
void RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t* pValue, VkResult result);
diff --git a/scripts/layer_chassis_dispatch_generator.py b/scripts/layer_chassis_dispatch_generator.py
index 5508a05..cb9fdc7 100644
--- a/scripts/layer_chassis_dispatch_generator.py
+++ b/scripts/layer_chassis_dispatch_generator.py
@@ -190,6 +190,12 @@
}
}
+ auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[idx0].pNext);
+ if (dynamic_rendering) {
+ uses_color_attachment = (dynamic_rendering->colorAttachmentCount > 0);
+ uses_depthstencil_attachment = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+ }
+
local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);
if (pCreateInfos[idx0].basePipelineHandle) {
diff --git a/tests/vklayertests_command.cpp b/tests/vklayertests_command.cpp
index 2de98c1..bffd23d 100644
--- a/tests/vklayertests_command.cpp
+++ b/tests/vklayertests_command.cpp
@@ -703,7 +703,7 @@
cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
- m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-00053");
+ m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-06002");
vk::BeginCommandBuffer(cb.handle(), &cmd_buf_info);
m_errorMonitor->VerifyFound();
}