summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-03 00:55:20 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-03 00:55:20 +0000
commit26003b33992221c28bc63b92afb5ab4719cce4bb (patch)
treead19cf2d1a0284188d532da4c3814b079e5e93e9 /Graphics/GraphicsEngine
parentFew improvements to render pass API (diff)
downloadDiligentCore-26003b33992221c28bc63b92afb5ab4719cce4bb.tar.gz
DiligentCore-26003b33992221c28bc63b92afb5ab4719cce4bb.zip
Added more render pass desc validation
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/src/FramebufferBase.cpp82
-rw-r--r--Graphics/GraphicsEngine/src/RenderPassBase.cpp186
2 files changed, 190 insertions, 78 deletions
diff --git a/Graphics/GraphicsEngine/src/FramebufferBase.cpp b/Graphics/GraphicsEngine/src/FramebufferBase.cpp
index 89b1aa5f..fa1f8d10 100644
--- a/Graphics/GraphicsEngine/src/FramebufferBase.cpp
+++ b/Graphics/GraphicsEngine/src/FramebufferBase.cpp
@@ -34,11 +34,11 @@ namespace Diligent
void ValidateFramebufferDesc(const FramebufferDesc& Desc)
{
-#define LOG_FRAMEBUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Framebuffer '", (Desc.Name ? Desc.Name : ""), "': ", ##__VA_ARGS__)
+#define LOG_FRAMEBUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of framebuffer '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
if (Desc.pRenderPass == nullptr)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("Render pass must not be null");
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("render pass must not be null.");
}
for (Uint32 i = 0; i < Desc.AttachmentCount; ++i)
@@ -48,30 +48,31 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// If flags does not include VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, and attachmentCount is not 0,
// pAttachments must be a valid pointer to an array of attachmentCount valid VkImageView handles.
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-flags-02778
- LOG_FRAMEBUFFER_ERROR_AND_THROW("Framebuffer attachment ", i, " is null");
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("framebuffer attachment ", i, " is null.");
}
}
const auto& RPDesc = Desc.pRenderPass->GetDesc();
if (Desc.AttachmentCount < RPDesc.AttachmentCount)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The number of framebuffer attachments (", Desc.AttachmentCount,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the number of framebuffer attachments (", Desc.AttachmentCount,
") is smaller than the number of attachments (", RPDesc.AttachmentCount,
") in the render pass '", RPDesc.Name, "'.");
}
for (Uint32 i = 0; i < RPDesc.AttachmentCount; ++i)
{
- const auto& AttDesc = RPDesc.pAttachments[i];
- const auto& TexDesc = Desc.ppAttachments[i]->GetTexture()->GetDesc();
+ const auto& AttDesc = RPDesc.pAttachments[i];
+ const auto& ViewDesc = Desc.ppAttachments[i]->GetDesc();
+ const auto& TexDesc = Desc.ppAttachments[i]->GetTexture()->GetDesc();
// If flags does not include VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments
// must have been created with a VkFormat value that matches the VkFormat specified by the corresponding
// VkAttachmentDescription in renderPass
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-00880
- if (TexDesc.Format != AttDesc.Format)
+ if (ViewDesc.Format != AttDesc.Format)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The format (", GetTextureFormatAttribs(TexDesc.Format).Name, ") of attachment ", i,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the format (", GetTextureFormatAttribs(ViewDesc.Format).Name, ") of attachment ", i,
" does not match the format (", GetTextureFormatAttribs(AttDesc.Format).Name,
") defined by the render pass for the same attachment.");
}
@@ -82,7 +83,7 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-00881
if (TexDesc.SampleCount != AttDesc.SampleCount)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The sample count (", Uint32{TexDesc.SampleCount}, ") of attachment ", i,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the sample count (", Uint32{TexDesc.SampleCount}, ") of attachment ", i,
" does not match the sample count (", Uint32{AttDesc.SampleCount},
") defined by the render pass for the same attachment.");
}
@@ -97,16 +98,9 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
continue;
- // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
- // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
- // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
- // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
- if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
- {
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment index (", AttchRef.AttachmentIndex, ") of input attachment reference ", input_attachment,
- " of subpass ", i, " of render pass '", RPDesc.Name,
- "' exceeds the number of attachments in the framebuffer (", Desc.AttachmentCount, ")");
- }
+ VERIFY(AttchRef.AttachmentIndex < Desc.AttachmentCount,
+ "Input attachment index (", AttchRef.AttachmentIndex, ") must be less than the attachment count (",
+ Desc.AttachmentCount, ") as this is ensured by ValidateRenderPassDesc.");
const auto& TexDesc = Desc.ppAttachments[AttchRef.AttachmentIndex]->GetTexture()->GetDesc();
@@ -116,7 +110,7 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-00879
if ((TexDesc.BindFlags & BIND_INPUT_ATTACHMENT) == 0)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
" is used as input attachment by subpass ",
i, " of render pass '", RPDesc.Name,
"', but was not created with BIND_INPUT_ATTACHMENT bind flag");
@@ -129,16 +123,9 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
continue;
- // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
- // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
- // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
- // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
- if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
- {
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment index (", AttchRef.AttachmentIndex, ") of render target attachment reference ", rt_attachment,
- " of subpass ", i, " of render pass '", RPDesc.Name,
- "' exceeds the number of attachments in the framebuffer (", Desc.AttachmentCount, ")");
- }
+ VERIFY(AttchRef.AttachmentIndex < Desc.AttachmentCount,
+ "Render target attachment index (", AttchRef.AttachmentIndex, ") must be less than the attachment count (",
+ Desc.AttachmentCount, ") as this is ensured by ValidateRenderPassDesc.");
const auto& TexDesc = Desc.ppAttachments[AttchRef.AttachmentIndex]->GetTexture()->GetDesc();
@@ -148,7 +135,7 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-00877
if ((TexDesc.BindFlags & BIND_RENDER_TARGET) == 0)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
" is used as render target attachment by subpass ",
i, " of render pass '", RPDesc.Name,
"', but was not created with BIND_RENDER_TARGET bind flag");
@@ -163,16 +150,9 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
continue;
- // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
- // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
- // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
- // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
- if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
- {
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment index (", AttchRef.AttachmentIndex, ") of resolve attachment reference ", rslv_attachment,
- " of subpass ", i, " of render pass '", RPDesc.Name,
- "' exceeds the number of attachments in the framebuffer (", Desc.AttachmentCount, ")");
- }
+ VERIFY(AttchRef.AttachmentIndex < Desc.AttachmentCount,
+ "Resolve attachment index (", AttchRef.AttachmentIndex, ") must be less than the attachment count (",
+ Desc.AttachmentCount, ") as this is ensured by ValidateRenderPassDesc.");
const auto& TexDesc = Desc.ppAttachments[AttchRef.AttachmentIndex]->GetTexture()->GetDesc();
@@ -182,7 +162,7 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-00877
if ((TexDesc.BindFlags & BIND_RENDER_TARGET) == 0)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
" is used as resolve attachment by subpass ",
i, " of render pass '", RPDesc.Name,
"', but was not created with BIND_RENDER_TARGET bind flag");
@@ -195,16 +175,9 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
const auto& AttchRef = *Subpass.pDepthStencilAttachment;
if (AttchRef.AttachmentIndex != ATTACHMENT_UNUSED)
{
- // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
- // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
- // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
- // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
- if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
- {
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment index (", AttchRef.AttachmentIndex, ") of depth-stencil attachment reference of subpass ", i,
- " of render pass '", RPDesc.Name,
- "' exceeds the number of attachments in the framebuffer (", Desc.AttachmentCount, ")");
- }
+ VERIFY(AttchRef.AttachmentIndex < Desc.AttachmentCount,
+ "Depth-stencil attachment index (", AttchRef.AttachmentIndex, ") must be less than the attachment count (",
+ Desc.AttachmentCount, ") as this is ensured by ValidateRenderPassDesc.");
const auto& TexDesc = Desc.ppAttachments[AttchRef.AttachmentIndex]->GetTexture()->GetDesc();
@@ -214,16 +187,13 @@ void ValidateFramebufferDesc(const FramebufferDesc& Desc)
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-pAttachments-02633
if ((TexDesc.BindFlags & BIND_DEPTH_STENCIL) == 0)
{
- LOG_FRAMEBUFFER_ERROR_AND_THROW("The attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
+ LOG_FRAMEBUFFER_ERROR_AND_THROW("the attachment '", TexDesc.Name, "' at index ", AttchRef.AttachmentIndex,
" is used as detph-stencil attachment by subpass ",
i, " of render pass '", RPDesc.Name,
"', but was not created with BIND_DEPTH_STENCIL bind flag");
}
}
}
-
- //for (Uint32 prsv_attachment = 0; prsv_attachment < Subpass.PreserveAttachmentCount; ++prsv_attachment)
- // ;
}
}
diff --git a/Graphics/GraphicsEngine/src/RenderPassBase.cpp b/Graphics/GraphicsEngine/src/RenderPassBase.cpp
index f060c8a0..683d86aa 100644
--- a/Graphics/GraphicsEngine/src/RenderPassBase.cpp
+++ b/Graphics/GraphicsEngine/src/RenderPassBase.cpp
@@ -35,27 +35,27 @@ namespace Diligent
void ValidateRenderPassDesc(const RenderPassDesc& Desc)
{
-#define LOG_RENDER_PASS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Render pass '", (Desc.Name ? Desc.Name : ""), "': ", ##__VA_ARGS__)
+#define LOG_RENDER_PASS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of render pass '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
if (Desc.AttachmentCount != 0 && Desc.pAttachments == nullptr)
{
// If attachmentCount is not 0, pAttachments must be a valid pointer to an
// array of attachmentCount valid VkAttachmentDescription structures.
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-pAttachments-parameter
- LOG_RENDER_PASS_ERROR_AND_THROW("The attachment count (", Desc.AttachmentCount, ") is not zero, but pAttachments is null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment count (", Desc.AttachmentCount, ") is not zero, but pAttachments is null.");
}
if (Desc.SubpassCount == 0)
{
// subpassCount must be greater than 0.
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-subpassCount-arraylength
- LOG_RENDER_PASS_ERROR_AND_THROW("Render pass must have at least one subpass");
+ LOG_RENDER_PASS_ERROR_AND_THROW("render pass must have at least one subpass.");
}
if (Desc.pSubpasses == nullptr)
{
// pSubpasses must be a valid pointer to an array of subpassCount valid VkSubpassDescription structures.
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-pSubpasses-parameter
- LOG_RENDER_PASS_ERROR_AND_THROW("pSubpasses must not be null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("pSubpasses must not be null.");
}
if (Desc.DependencyCount != 0 && Desc.pDependencies == nullptr)
@@ -63,20 +63,20 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
// If dependencyCount is not 0, pDependencies must be a valid pointer to an array of
// dependencyCount valid VkSubpassDependency structures.
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-pDependencies-parameter
- LOG_RENDER_PASS_ERROR_AND_THROW("The dependency count (", Desc.DependencyCount, ") is not zero, but pDependencies is null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the dependency count (", Desc.DependencyCount, ") is not zero, but pDependencies is null.");
}
for (Uint32 i = 0; i < Desc.AttachmentCount; ++i)
{
const auto& Attachment = Desc.pAttachments[i];
if (Attachment.Format == TEX_FORMAT_UNKNOWN)
- LOG_RENDER_PASS_ERROR_AND_THROW("the format of attachment ", i, " is unknown");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the format of attachment ", i, " is unknown.");
if (Attachment.SampleCount == 0)
- LOG_RENDER_PASS_ERROR_AND_THROW("the sample count of attachment ", i, " is zero");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the sample count of attachment ", i, " is zero.");
if (!IsPowerOfTwo(Attachment.SampleCount))
- LOG_RENDER_PASS_ERROR_AND_THROW("the sample count of attachment ", i, "(", Attachment.SampleCount, ") is not power of two");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the sample count (", Uint32{Attachment.SampleCount}, ") of attachment ", i, " is not power of two.");
const auto& FmtInfo = GetTextureFormatAttribs(Attachment.Format);
if (FmtInfo.ComponentType == COMPONENT_TYPE_DEPTH ||
@@ -89,7 +89,7 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
Attachment.InitialState != RESOURCE_STATE_RESOLVE_DEST &&
Attachment.InitialState != RESOURCE_STATE_RESOLVE_SOURCE)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the initial state of depth-stencil attachment ", i, " (", GetResourceStateString(Attachment.InitialState), ") is invalid");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the initial state of depth-stencil attachment ", i, " (", GetResourceStateString(Attachment.InitialState), ") is invalid.");
}
if (Attachment.FinalState != RESOURCE_STATE_DEPTH_WRITE &&
@@ -99,7 +99,7 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
Attachment.FinalState != RESOURCE_STATE_RESOLVE_DEST &&
Attachment.FinalState != RESOURCE_STATE_RESOLVE_SOURCE)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the final state of depth-stencil attachment ", i, " (", GetResourceStateString(Attachment.FinalState), ") is invalid");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the final state of depth-stencil attachment ", i, " (", GetResourceStateString(Attachment.FinalState), ") is invalid.");
}
}
else
@@ -110,7 +110,7 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
Attachment.InitialState != RESOURCE_STATE_RESOLVE_DEST &&
Attachment.InitialState != RESOURCE_STATE_RESOLVE_SOURCE)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the initial state of color attachment ", i, " (", GetResourceStateString(Attachment.InitialState), ") is invalid");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the initial state of color attachment ", i, " (", GetResourceStateString(Attachment.InitialState), ") is invalid.");
}
if (Attachment.FinalState != RESOURCE_STATE_RENDER_TARGET &&
@@ -119,28 +119,170 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
Attachment.FinalState != RESOURCE_STATE_RESOLVE_DEST &&
Attachment.FinalState != RESOURCE_STATE_RESOLVE_SOURCE)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the final state of color attachment ", i, " (", GetResourceStateString(Attachment.FinalState), ") is invalid");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the final state of color attachment ", i, " (", GetResourceStateString(Attachment.FinalState), ") is invalid.");
}
}
}
- for (Uint32 i = 0; i < Desc.SubpassCount; ++i)
+ for (Uint32 subpass = 0; subpass < Desc.SubpassCount; ++subpass)
{
- const auto& Subpass = Desc.pSubpasses[i];
+ const auto& Subpass = Desc.pSubpasses[subpass];
if (Subpass.InputAttachmentCount != 0 && Subpass.pInputAttachments == nullptr)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the input attachment count (", Subpass.InputAttachmentCount, ") of subpass ", i,
- " is not zero, while pInputAttachments is null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the input attachment count (", Subpass.InputAttachmentCount, ") of subpass ", subpass,
+ " is not zero, while pInputAttachments is null.");
}
if (Subpass.RenderTargetAttachmentCount != 0 && Subpass.pRenderTargetAttachments == nullptr)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the render target attachment count (", Subpass.RenderTargetAttachmentCount, ") of subpass ", i,
- " is not zero, while pRenderTargetAttachments is null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the render target attachment count (", Subpass.RenderTargetAttachmentCount, ") of subpass ", subpass,
+ " is not zero, while pRenderTargetAttachments is null.");
}
if (Subpass.PreserveAttachmentCount != 0 && Subpass.pPreserveAttachments == nullptr)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the preserve attachment count (", Subpass.PreserveAttachmentCount, ") of subpass ", i,
- " is not zero, while pPreserveAttachments is null");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the preserve attachment count (", Subpass.PreserveAttachmentCount, ") of subpass ", subpass,
+ " is not zero, while pPreserveAttachments is null.");
+ }
+
+ for (Uint32 input_attachment = 0; input_attachment < Subpass.InputAttachmentCount; ++input_attachment)
+ {
+ const auto& AttchRef = Subpass.pInputAttachments[input_attachment];
+ if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
+ continue;
+
+ // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
+ // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
+ // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
+ if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
+ {
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index (", AttchRef.AttachmentIndex, ") of input attachment reference ", input_attachment,
+ " of subpass ", subpass, " must be less than the number of attachments (", Desc.AttachmentCount, ").");
+ }
+ }
+
+ for (Uint32 rt_attachment = 0; rt_attachment < Subpass.RenderTargetAttachmentCount; ++rt_attachment)
+ {
+ const auto& AttchRef = Subpass.pRenderTargetAttachments[rt_attachment];
+ if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
+ continue;
+
+ // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
+ // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
+ // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
+ if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
+ {
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index (", AttchRef.AttachmentIndex, ") of render target attachment reference ", rt_attachment,
+ " of subpass ", subpass, " must be less than the number of attachments (", Desc.AttachmentCount, ").");
+ }
+ }
+
+ if (Subpass.pResolveAttachments != nullptr)
+ {
+ for (Uint32 rslv_attachment = 0; rslv_attachment < Subpass.RenderTargetAttachmentCount; ++rslv_attachment)
+ {
+ const auto& AttchRef = Subpass.pResolveAttachments[rslv_attachment];
+ if (AttchRef.AttachmentIndex == ATTACHMENT_UNUSED)
+ continue;
+
+ // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
+ // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
+ // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
+ if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
+ {
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index (", AttchRef.AttachmentIndex, ") of resolve attachment reference ", rslv_attachment,
+ " of subpass ", subpass, " must be less than the number of attachments (", Desc.AttachmentCount, ").");
+ }
+ }
+ }
+
+ if (Subpass.pDepthStencilAttachment != nullptr)
+ {
+ const auto& AttchRef = *Subpass.pDepthStencilAttachment;
+ if (AttchRef.AttachmentIndex != ATTACHMENT_UNUSED)
+ {
+ // If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments
+ // or pDepthStencilAttachment, or any element of pPreserveAttachments in any element of pSubpasses is not
+ // VK_ATTACHMENT_UNUSED, it must be less than attachmentCount
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-attachment-00834
+ if (AttchRef.AttachmentIndex >= Desc.AttachmentCount)
+ {
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index (", AttchRef.AttachmentIndex, ") of depth-stencil attachment reference of subpass ", subpass,
+ " must be less than the number of attachments (", Desc.AttachmentCount, ").");
+ }
+ }
+ }
+
+ for (Uint32 prsv_attachment = 0; prsv_attachment < Subpass.PreserveAttachmentCount; ++prsv_attachment)
+ {
+ const auto PrsvAttachment = Subpass.pPreserveAttachments[prsv_attachment];
+ if (PrsvAttachment == ATTACHMENT_UNUSED)
+ {
+ // The attachment member of each element of pPreserveAttachments must not be VK_ATTACHMENT_UNUSED
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubpassDescription-attachment-00853
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index of preserve attachment reference ", prsv_attachment,
+ " of subpass ", subpass, " is ATTACHMENT_UNUSED.");
+ }
+
+ if (PrsvAttachment >= Desc.AttachmentCount)
+ {
+ LOG_RENDER_PASS_ERROR_AND_THROW("the attachment index (", PrsvAttachment, ") of preserve attachment reference ", prsv_attachment,
+ " of subpass ", subpass, " exceeds the number of attachments (", Desc.AttachmentCount, ").");
+ }
+ }
+
+ if (Subpass.pResolveAttachments != nullptr)
+ {
+ for (Uint32 attchmnt = 0; attchmnt < Subpass.RenderTargetAttachmentCount; ++attchmnt)
+ {
+ const auto& RTAttachmentRef = Subpass.pRenderTargetAttachments[attchmnt];
+ const auto& RslvAttachmentRef = Subpass.pResolveAttachments[attchmnt];
+ if (RslvAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED && RTAttachmentRef.AttachmentIndex == ATTACHMENT_UNUSED)
+ {
+ // If pResolveAttachments is not NULL, for each resolve attachment that is not VK_ATTACHMENT_UNUSED,
+ // the corresponding color attachment must not be VK_ATTACHMENT_UNUSED
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubpassDescription-pResolveAttachments-00847
+ LOG_RENDER_PASS_ERROR_AND_THROW("pResolveAttachments of subpass ", subpass, " is not null and resolve attachment reference ", attchmnt,
+ " is not ATTACHMENT_UNUSED, but corresponding render target attachment reference is ATTACHMENT_UNUSED.");
+ }
+
+ if (RslvAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED && Desc.pAttachments[RTAttachmentRef.AttachmentIndex].SampleCount == 1)
+ {
+ // If pResolveAttachments is not NULL, for each resolve attachment that is not VK_ATTACHMENT_UNUSED,
+ // the corresponding color attachment must not have a sample count of VK_SAMPLE_COUNT_1_BIT
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubpassDescription-pResolveAttachments-00848
+ LOG_RENDER_PASS_ERROR_AND_THROW("Render target attachment at index ", RTAttachmentRef.AttachmentIndex, " referenced by",
+ " attachment reference ", attchmnt, " of subpass ", subpass,
+ " is used as the source of resolve operation, but its sample count is 1.");
+ }
+
+ if (RslvAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED && Desc.pAttachments[RslvAttachmentRef.AttachmentIndex].SampleCount != 1)
+ {
+ // If pResolveAttachments is not NULL, each resolve attachment that is not VK_ATTACHMENT_UNUSED must
+ // have a sample count of VK_SAMPLE_COUNT_1_BIT
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubpassDescription-pResolveAttachments-00849
+ LOG_RENDER_PASS_ERROR_AND_THROW("Resolve attachment at index ", RslvAttachmentRef.AttachmentIndex, " referenced by",
+ " attachment reference ", attchmnt, " of subpass ", subpass,
+ " must have sample count of 1.");
+ }
+
+ if (RTAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED && RslvAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED &&
+ Desc.pAttachments[RTAttachmentRef.AttachmentIndex].Format != Desc.pAttachments[RslvAttachmentRef.AttachmentIndex].Format)
+ {
+ // If pResolveAttachments is not NULL, each resolve attachment that is not VK_ATTACHMENT_UNUSED
+ // must have the same VkFormat as its corresponding color attachment.
+ // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubpassDescription-pResolveAttachments-00850
+ LOG_RENDER_PASS_ERROR_AND_THROW("The format (",
+ GetTextureFormatAttribs(Desc.pAttachments[RTAttachmentRef.AttachmentIndex].Format).Name,
+ ") of render target attachment at index ", RTAttachmentRef.AttachmentIndex,
+ " referenced by attachment reference ", attchmnt, " of subpass ", subpass,
+ " does not match the format (",
+ GetTextureFormatAttribs(Desc.pAttachments[RslvAttachmentRef.AttachmentIndex].Format).Name,
+ ") of the corresponding resolve attachment at index ",
+ RslvAttachmentRef.AttachmentIndex, ".");
+ }
+ }
}
}
@@ -150,11 +292,11 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc)
if (Dependency.SrcStageMask == PIPELINE_STAGE_FLAG_UNDEFINED)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the source stage mask of subpass dependency ", i, " is undefined");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the source stage mask of subpass dependency ", i, " is undefined.");
}
if (Dependency.DstStageMask == PIPELINE_STAGE_FLAG_UNDEFINED)
{
- LOG_RENDER_PASS_ERROR_AND_THROW("the destination stage mask of subpass dependency ", i, " is undefined");
+ LOG_RENDER_PASS_ERROR_AND_THROW("the destination stage mask of subpass dependency ", i, " is undefined.");
}
}
}