From 706b34a2e4dbd372dc4255a9b6f021b9c7ee34ac Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 3 Aug 2020 13:46:43 -0700 Subject: Few fixes to render passes --- .../src/GraphicsAccessories.cpp | 10 +- .../GraphicsEngine/include/DeviceContextBase.hpp | 26 +++++ Graphics/GraphicsEngine/interface/GraphicsTypes.h | 39 ++++--- .../src/D3D12TypeConversions.cpp | 7 +- .../src/DeviceContextVkImpl.cpp | 3 + .../GraphicsEngineVulkan/src/FramebufferVkImpl.cpp | 1 + .../GraphicsEngineVulkan/src/RenderPassVkImpl.cpp | 1 + .../src/VulkanTypeConversions.cpp | 13 ++- Tests/DiligentCoreAPITest/src/RenderPassTest.cpp | 128 ++++++++++++++------- 9 files changed, 155 insertions(+), 73 deletions(-) diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index fff50193..0a4afd54 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -1133,7 +1133,7 @@ Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height, Uint32 Depth) bool VerifyResourceStates(RESOURCE_STATE State, bool IsTexture) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "Please update this function to handle the new resource state"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "Please update this function to handle the new resource state"); // clang-format off #define VERIFY_EXCLUSIVE_STATE(ExclusiveState)\ @@ -1165,7 +1165,7 @@ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ { LOG_ERROR_MESSAGE("State ", GetResourceStateString(State), " is invalid: states RESOURCE_STATE_VERTEX_BUFFER, " "RESOURCE_STATE_CONSTANT_BUFFER, RESOURCE_STATE_INDEX_BUFFER, RESOURCE_STATE_STREAM_OUT, " - "RESOURCE_STATE_INDIRECT_ARGUMENT are not applicable to a texture"); + "RESOURCE_STATE_INDIRECT_ARGUMENT are not applicable to textures"); return false; } // clang-format on @@ -1179,11 +1179,13 @@ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ RESOURCE_STATE_DEPTH_READ | RESOURCE_STATE_RESOLVE_SOURCE | RESOURCE_STATE_RESOLVE_DEST | - RESOURCE_STATE_PRESENT)) + RESOURCE_STATE_PRESENT | + RESOURCE_STATE_INPUT_ATTACHMENT)) { LOG_ERROR_MESSAGE("State ", GetResourceStateString(State), " is invalid: states RESOURCE_STATE_RENDER_TARGET, " "RESOURCE_STATE_DEPTH_WRITE, RESOURCE_STATE_DEPTH_READ, RESOURCE_STATE_RESOLVE_SOURCE, " - "RESOURCE_STATE_RESOLVE_DEST, RESOURCE_STATE_PRESENT are not applicable to a buffer"); + "RESOURCE_STATE_RESOLVE_DEST, RESOURCE_STATE_PRESENT, RESOURCE_STATE_INPUT_ATTACHMENT " + "are not applicable to buffers"); return false; } // clang-format on diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp index 68f9ec4e..9e478675 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp @@ -856,6 +856,32 @@ inline void DeviceContextBase::BeginRenderP VERIFY(m_pActiveRenderPass == nullptr, "Attempting to begin render pass while another render pass ('", m_pActiveRenderPass->GetDesc().Name, "') is active."); VERIFY(Attribs.pRenderPass != nullptr, "Render pass must not be null"); VERIFY(Attribs.pFramebuffer != nullptr, "Framebuffer must not be null"); +#ifdef DILIGENT_DEBUG + { + const auto& RPDesc = Attribs.pRenderPass->GetDesc(); + + Uint32 NumRequiredClearValues = 0; + for (Uint32 i = 0; i < RPDesc.AttachmentCount; ++i) + { + const auto& Attchmnt = RPDesc.pAttachments[i]; + if (Attchmnt.LoadOp == ATTACHMENT_LOAD_OP_CLEAR) + NumRequiredClearValues = i + 1; + + const auto& FmtAttribs = GetTextureFormatAttribs(Attchmnt.Format); + if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) + { + if (Attchmnt.StencilLoadOp == ATTACHMENT_LOAD_OP_CLEAR) + NumRequiredClearValues = i + 1; + } + } + VERIFY(Attribs.ClearValueCount >= NumRequiredClearValues, + "Begin render pass operation requiers at least ", NumRequiredClearValues, + " clear values, but only ", Attribs.ClearValueCount, " are given."); + VERIFY(Attribs.ClearValueCount == 0 || Attribs.pClearValues != nullptr, + "pClearValues must not be null when ClearValueCount is not zero"); + } +#endif + ResetRenderTargets(); m_pActiveRenderPass = ValidatedCast(Attribs.pRenderPass); diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 796d7449..3c0ca99a 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -2152,57 +2152,60 @@ DEFINE_FLAG_ENUM_OPERATORS(ACCESS_FLAGS) DILIGENT_TYPED_ENUM(RESOURCE_STATE, Uint32) { /// The resource state is not known to the engine and is managed by the application - RESOURCE_STATE_UNKNOWN = 0x0000, + RESOURCE_STATE_UNKNOWN = 0x00000, /// The resource state is known to the engine, but is undefined. A resource is typically in an undefined state right after initialization. - RESOURCE_STATE_UNDEFINED = 0x0001, + RESOURCE_STATE_UNDEFINED = 0x00001, /// The resource is accessed as vertex buffer - RESOURCE_STATE_VERTEX_BUFFER = 0x0002, + RESOURCE_STATE_VERTEX_BUFFER = 0x00002, /// The resource is accessed as constant (uniform) buffer - RESOURCE_STATE_CONSTANT_BUFFER = 0x0004, + RESOURCE_STATE_CONSTANT_BUFFER = 0x00004, /// The resource is accessed as index buffer - RESOURCE_STATE_INDEX_BUFFER = 0x0008, + RESOURCE_STATE_INDEX_BUFFER = 0x00008, /// The resource is accessed as render target - RESOURCE_STATE_RENDER_TARGET = 0x0010, + RESOURCE_STATE_RENDER_TARGET = 0x00010, /// The resource is used for unordered access - RESOURCE_STATE_UNORDERED_ACCESS = 0x0020, + RESOURCE_STATE_UNORDERED_ACCESS = 0x00020, /// The resource is used in a writable depth-stencil view or in clear operation - RESOURCE_STATE_DEPTH_WRITE = 0x0040, + RESOURCE_STATE_DEPTH_WRITE = 0x00040, /// The resource is used in a read-only depth-stencil view - RESOURCE_STATE_DEPTH_READ = 0x0080, + RESOURCE_STATE_DEPTH_READ = 0x00080, /// The resource is accessed from a shader - RESOURCE_STATE_SHADER_RESOURCE = 0x0100, + RESOURCE_STATE_SHADER_RESOURCE = 0x00100, /// The resource is used as the destination for stream output - RESOURCE_STATE_STREAM_OUT = 0x0200, + RESOURCE_STATE_STREAM_OUT = 0x00200, /// The resource is used as indirect draw/dispatch arguments buffer - RESOURCE_STATE_INDIRECT_ARGUMENT = 0x0400, + RESOURCE_STATE_INDIRECT_ARGUMENT = 0x00400, /// The resource is used as the destination in a copy operation - RESOURCE_STATE_COPY_DEST = 0x0800, + RESOURCE_STATE_COPY_DEST = 0x00800, /// The resource is used as the source in a copy operation - RESOURCE_STATE_COPY_SOURCE = 0x1000, + RESOURCE_STATE_COPY_SOURCE = 0x01000, /// The resource is used as the destination in a resolve operation - RESOURCE_STATE_RESOLVE_DEST = 0x2000, + RESOURCE_STATE_RESOLVE_DEST = 0x02000, /// The resource is used as the source in a resolve operation - RESOURCE_STATE_RESOLVE_SOURCE = 0x4000, + RESOURCE_STATE_RESOLVE_SOURCE = 0x04000, + + /// The resource is used as input attachment in a render pass subpass + RESOURCE_STATE_INPUT_ATTACHMENT = 0x08000, /// The resource is used for present - RESOURCE_STATE_PRESENT = 0x8000, + RESOURCE_STATE_PRESENT = 0x10000, - RESOURCE_STATE_MAX_BIT = 0x8000, + RESOURCE_STATE_MAX_BIT = 0x10000, RESOURCE_STATE_GENERIC_READ = RESOURCE_STATE_VERTEX_BUFFER | RESOURCE_STATE_CONSTANT_BUFFER | diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 124201ff..6043cac5 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -329,7 +329,7 @@ D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 Bord static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STATE StateFlag) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -349,6 +349,7 @@ static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STAT case RESOURCE_STATE_COPY_SOURCE: return D3D12_RESOURCE_STATE_COPY_SOURCE; case RESOURCE_STATE_RESOLVE_DEST: return D3D12_RESOURCE_STATE_RESOLVE_DEST; case RESOURCE_STATE_RESOLVE_SOURCE: return D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + case RESOURCE_STATE_INPUT_ATTACHMENT: UNSUPPORTED("Input attachments are not currently supported in D3D12"); return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case RESOURCE_STATE_PRESENT: return D3D12_RESOURCE_STATE_PRESENT; // clang-format on default: @@ -376,7 +377,7 @@ public: } private: - static constexpr Uint32 MaxFlagBitPos = 15; + static constexpr Uint32 MaxFlagBitPos = 16; std::array FlagBitPosToResStateMap; }; @@ -398,7 +399,7 @@ D3D12_RESOURCE_STATES ResourceStateFlagsToD3D12ResourceStates(RESOURCE_STATE Sta static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STATES state) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((state & (state - 1)) == 0, "Only single state must be set"); switch (state) { diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 0eb778f0..3214c30f 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -1298,18 +1298,21 @@ void DeviceContextVkImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) pVkClearValues = m_vkClearValues.data(); } + EnsureVkCmdBuffer(); m_CommandBuffer.BeginRenderPass(m_vkRenderPass, m_vkFramebuffer, m_FramebufferWidth, m_FramebufferHeight, Attribs.ClearValueCount, pVkClearValues); } void DeviceContextVkImpl::NextSubpass() { TDeviceContextBase::NextSubpass(); + EnsureVkCmdBuffer(); m_CommandBuffer.NextSubpass(); } void DeviceContextVkImpl::EndRenderPass(bool UpdateResourceStates) { TDeviceContextBase::EndRenderPass(UpdateResourceStates); + EnsureVkCmdBuffer(); m_CommandBuffer.EndRenderPass(); } diff --git a/Graphics/GraphicsEngineVulkan/src/FramebufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FramebufferVkImpl.cpp index 2fc81319..54b77e36 100644 --- a/Graphics/GraphicsEngineVulkan/src/FramebufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FramebufferVkImpl.cpp @@ -78,6 +78,7 @@ FramebufferVkImpl::FramebufferVkImpl(IReferenceCounters* pRefCounters, FramebufferVkImpl::~FramebufferVkImpl() { + m_pDevice->SafeReleaseDeviceObject(std::move(m_VkFramebuffer), ~Uint64{0}); } } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp index 37bdc106..a0a25f89 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp @@ -157,6 +157,7 @@ RenderPassVkImpl::RenderPassVkImpl(IReferenceCounters* pRefCounters, RenderPassVkImpl::~RenderPassVkImpl() { + m_pDevice->SafeReleaseDeviceObject(std::move(m_VkRenderPass), ~Uint64{0}); } } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index 90ca6909..4dc4872a 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1140,7 +1140,6 @@ VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[]) static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag) { // Currently not used: - //VK_ACCESS_INPUT_ATTACHMENT_READ_BIT //VK_ACCESS_HOST_READ_BIT //VK_ACCESS_HOST_WRITE_BIT //VK_ACCESS_MEMORY_READ_BIT @@ -1155,7 +1154,7 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag) //VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX //VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -1175,6 +1174,7 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag) case RESOURCE_STATE_COPY_SOURCE: return VK_ACCESS_TRANSFER_READ_BIT; case RESOURCE_STATE_RESOLVE_DEST: return VK_ACCESS_MEMORY_READ_BIT; case RESOURCE_STATE_RESOLVE_SOURCE: return VK_ACCESS_MEMORY_WRITE_BIT; + case RESOURCE_STATE_INPUT_ATTACHMENT: return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; case RESOURCE_STATE_PRESENT: return VK_ACCESS_MEMORY_READ_BIT; // clang-format on @@ -1203,7 +1203,7 @@ public: } private: - static constexpr const Uint32 MaxFlagBitPos = 15; + static constexpr const Uint32 MaxFlagBitPos = 16; std::array FlagBitPosToVkAccessFlagsMap; }; @@ -1235,7 +1235,7 @@ RESOURCE_STATE VkAccessFlagsToResourceStates(VkAccessFlagBits AccessFlagBit) case VK_ACCESS_INDEX_READ_BIT: return RESOURCE_STATE_INDEX_BUFFER; case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: return RESOURCE_STATE_VERTEX_BUFFER; case VK_ACCESS_UNIFORM_READ_BIT: return RESOURCE_STATE_CONSTANT_BUFFER; - case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: return RESOURCE_STATE_UNKNOWN; + case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: return RESOURCE_STATE_INPUT_ATTACHMENT; case VK_ACCESS_SHADER_READ_BIT: return RESOURCE_STATE_SHADER_RESOURCE; case VK_ACCESS_SHADER_WRITE_BIT: return RESOURCE_STATE_UNORDERED_ACCESS; case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: return RESOURCE_STATE_RENDER_TARGET; @@ -1317,7 +1317,7 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag) //VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, //VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -1337,6 +1337,7 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag) case RESOURCE_STATE_COPY_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case RESOURCE_STATE_RESOLVE_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case RESOURCE_STATE_RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case RESOURCE_STATE_INPUT_ATTACHMENT: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; case RESOURCE_STATE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; // clang-format on @@ -1348,7 +1349,7 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag) RESOURCE_STATE VkImageLayoutToResourceState(VkImageLayout Layout) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); switch (Layout) { // clang-format off diff --git a/Tests/DiligentCoreAPITest/src/RenderPassTest.cpp b/Tests/DiligentCoreAPITest/src/RenderPassTest.cpp index 4453b41f..28156bae 100644 --- a/Tests/DiligentCoreAPITest/src/RenderPassTest.cpp +++ b/Tests/DiligentCoreAPITest/src/RenderPassTest.cpp @@ -39,9 +39,10 @@ namespace TEST(RenderPassTest, CreateRenderPassAndFramebuffer) { - auto* pDevice = TestingEnvironment::GetInstance()->GetDevice(); + auto* pDevice = TestingEnvironment::GetInstance()->GetDevice(); + auto* pContext = TestingEnvironment::GetInstance()->GetDeviceContext(); - RenderPassAttachmentDesc Attachments[5]; + RenderPassAttachmentDesc Attachments[6]; Attachments[0].Format = TEX_FORMAT_RGBA8_UNORM; Attachments[0].SampleCount = 4; Attachments[0].InitialState = RESOURCE_STATE_SHADER_RESOURCE; @@ -49,14 +50,12 @@ TEST(RenderPassTest, CreateRenderPassAndFramebuffer) Attachments[0].LoadOp = ATTACHMENT_LOAD_OP_LOAD; Attachments[0].StoreOp = ATTACHMENT_STORE_OP_STORE; - Attachments[1].Format = TEX_FORMAT_D32_FLOAT_S8X24_UINT; - Attachments[1].SampleCount = 4; - Attachments[1].InitialState = RESOURCE_STATE_SHADER_RESOURCE; - Attachments[1].FinalState = RESOURCE_STATE_DEPTH_WRITE; - Attachments[1].LoadOp = ATTACHMENT_LOAD_OP_CLEAR; - Attachments[1].StoreOp = ATTACHMENT_STORE_OP_DISCARD; - Attachments[1].StencilLoadOp = ATTACHMENT_LOAD_OP_CLEAR; - Attachments[1].StencilStoreOp = ATTACHMENT_STORE_OP_DISCARD; + Attachments[1].Format = TEX_FORMAT_RGBA8_UNORM; + Attachments[1].SampleCount = 4; + Attachments[1].InitialState = RESOURCE_STATE_SHADER_RESOURCE; + Attachments[1].FinalState = RESOURCE_STATE_RENDER_TARGET; + Attachments[1].LoadOp = ATTACHMENT_LOAD_OP_CLEAR; + Attachments[1].StoreOp = ATTACHMENT_STORE_OP_DISCARD; Attachments[2].Format = TEX_FORMAT_RGBA8_UNORM; Attachments[2].SampleCount = 1; @@ -65,42 +64,70 @@ TEST(RenderPassTest, CreateRenderPassAndFramebuffer) Attachments[2].LoadOp = ATTACHMENT_LOAD_OP_DISCARD; Attachments[2].StoreOp = ATTACHMENT_STORE_OP_STORE; - Attachments[3].Format = TEX_FORMAT_RGBA32_FLOAT; - Attachments[3].SampleCount = 1; - Attachments[3].InitialState = RESOURCE_STATE_SHADER_RESOURCE; - Attachments[3].FinalState = RESOURCE_STATE_SHADER_RESOURCE; - Attachments[3].LoadOp = ATTACHMENT_LOAD_OP_LOAD; - Attachments[3].StoreOp = ATTACHMENT_STORE_OP_STORE; + Attachments[3].Format = TEX_FORMAT_D32_FLOAT_S8X24_UINT; + Attachments[3].SampleCount = 4; + Attachments[3].InitialState = RESOURCE_STATE_SHADER_RESOURCE; + Attachments[3].FinalState = RESOURCE_STATE_DEPTH_WRITE; + Attachments[3].LoadOp = ATTACHMENT_LOAD_OP_CLEAR; + Attachments[3].StoreOp = ATTACHMENT_STORE_OP_DISCARD; + Attachments[3].StencilLoadOp = ATTACHMENT_LOAD_OP_CLEAR; + Attachments[3].StencilStoreOp = ATTACHMENT_STORE_OP_DISCARD; - Attachments[4].Format = TEX_FORMAT_RGBA8_UNORM; + Attachments[4].Format = TEX_FORMAT_RGBA32_FLOAT; Attachments[4].SampleCount = 1; Attachments[4].InitialState = RESOURCE_STATE_SHADER_RESOURCE; Attachments[4].FinalState = RESOURCE_STATE_SHADER_RESOURCE; - Attachments[4].LoadOp = ATTACHMENT_LOAD_OP_LOAD; + Attachments[4].LoadOp = ATTACHMENT_LOAD_OP_CLEAR; Attachments[4].StoreOp = ATTACHMENT_STORE_OP_STORE; - SubpassDesc Subpasses[2] = {}; - - Subpasses[0].InputAttachmentCount = 1; - AttachmentReference InputAttachmentRef{3, RESOURCE_STATE_SHADER_RESOURCE}; - Subpasses[0].pInputAttachments = &InputAttachmentRef; - Subpasses[0].RenderTargetAttachmentCount = 1; - AttachmentReference RTAttachmentRef{0, RESOURCE_STATE_RENDER_TARGET}; - Subpasses[0].pRenderTargetAttachments = &RTAttachmentRef; - AttachmentReference ResolveAttachmentRef{2, RESOURCE_STATE_RESOLVE_DEST}; - Subpasses[0].pResolveAttachments = &ResolveAttachmentRef; - AttachmentReference DSAttachmentRef{1, RESOURCE_STATE_DEPTH_WRITE}; - Subpasses[0].pDepthStencilAttachment = &DSAttachmentRef; - Uint32 PreserveAttachment = 4; - Subpasses[0].PreserveAttachmentCount = 1; - Subpasses[0].pPreserveAttachments = &PreserveAttachment; - - Subpasses[1].InputAttachmentCount = 1; - AttachmentReference InputAttachment2Ref{2, RESOURCE_STATE_SHADER_RESOURCE}; - Subpasses[1].pInputAttachments = &InputAttachment2Ref; - Subpasses[1].RenderTargetAttachmentCount = 1; - AttachmentReference RT2AttachmentRef{4, RESOURCE_STATE_RENDER_TARGET}; - Subpasses[1].pRenderTargetAttachments = &RT2AttachmentRef; + Attachments[5].Format = TEX_FORMAT_RGBA8_UNORM; + Attachments[5].SampleCount = 1; + Attachments[5].InitialState = RESOURCE_STATE_SHADER_RESOURCE; + Attachments[5].FinalState = RESOURCE_STATE_SHADER_RESOURCE; + Attachments[5].LoadOp = ATTACHMENT_LOAD_OP_LOAD; + Attachments[5].StoreOp = ATTACHMENT_STORE_OP_STORE; + + SubpassDesc Subpasses[2]; + + // clang-format off + AttachmentReference RTAttachmentRefs0[] = + { + {0, RESOURCE_STATE_RENDER_TARGET}, + {1, RESOURCE_STATE_RENDER_TARGET} + }; + AttachmentReference RslvAttachmentRefs0[] = + { + {ATTACHMENT_UNUSED, RESOURCE_STATE_RENDER_TARGET}, + {2, RESOURCE_STATE_RENDER_TARGET} + }; + // clang-format on + AttachmentReference DSAttachmentRef0{3, RESOURCE_STATE_DEPTH_WRITE}; + Subpasses[0].RenderTargetAttachmentCount = _countof(RTAttachmentRefs0); + Subpasses[0].pRenderTargetAttachments = RTAttachmentRefs0; + Subpasses[0].pResolveAttachments = RslvAttachmentRefs0; + Subpasses[0].pDepthStencilAttachment = &DSAttachmentRef0; + + // clang-format off + AttachmentReference RTAttachmentRefs1[] = + { + {4, RESOURCE_STATE_RENDER_TARGET} + }; + AttachmentReference InptAttachmentRefs1[] = + { + {2, RESOURCE_STATE_INPUT_ATTACHMENT}, + {5, RESOURCE_STATE_INPUT_ATTACHMENT} + }; + Uint32 PrsvAttachmentRefs1[] = + { + 0 + }; + // clang-format on + Subpasses[1].InputAttachmentCount = _countof(InptAttachmentRefs1); + Subpasses[1].pInputAttachments = InptAttachmentRefs1; + Subpasses[1].RenderTargetAttachmentCount = _countof(RTAttachmentRefs1); + Subpasses[1].pRenderTargetAttachments = RTAttachmentRefs1; + Subpasses[1].PreserveAttachmentCount = _countof(PrsvAttachmentRefs1); + Subpasses[1].pPreserveAttachments = PrsvAttachmentRefs1; SubpassDependencyDesc Dependencies[2] = {}; Dependencies[0].SrcSubpass = 0; @@ -149,7 +176,9 @@ TEST(RenderPassTest, CreateRenderPassAndFramebuffer) for (Uint32 i = 0; i < _countof(pTextures); ++i) { TextureDesc TexDesc; - TexDesc.Name = "Test framebuffer attachment"; + std::string Name = "Test framebuffer attachment "; + Name += std::to_string(i); + TexDesc.Name = Name.c_str(); TexDesc.Type = RESOURCE_DIM_TEX_2D; TexDesc.Format = Attachments[i].Format; TexDesc.Width = 1024; @@ -163,9 +192,13 @@ TEST(RenderPassTest, CreateRenderPassAndFramebuffer) else TexDesc.BindFlags = BIND_RENDER_TARGET; - if (i == 2 || i == 3) + if (i == 2 || i == 5) TexDesc.BindFlags |= BIND_INPUT_ATTACHMENT; + const auto InitialState = Attachments[i].InitialState; + if (InitialState == RESOURCE_STATE_SHADER_RESOURCE) + TexDesc.BindFlags |= BIND_SHADER_RESOURCE; + pDevice->CreateTexture(TexDesc, nullptr, &pTextures[i]); if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || @@ -188,6 +221,17 @@ TEST(RenderPassTest, CreateRenderPassAndFramebuffer) EXPECT_EQ(FBDesc2.AttachmentCount, FBDesc.AttachmentCount); for (Uint32 i = 0; i < std::min(FBDesc.AttachmentCount, FBDesc2.AttachmentCount); ++i) EXPECT_EQ(FBDesc2.ppAttachments[i], FBDesc.ppAttachments[i]); + + BeginRenderPassAttribs RPBeginInfo; + RPBeginInfo.pRenderPass = pRenderPass; + RPBeginInfo.pFramebuffer = pFramebuffer; + OptimizedClearValue ClearValues[5]; + RPBeginInfo.pClearValues = ClearValues; + RPBeginInfo.ClearValueCount = _countof(ClearValues); + RPBeginInfo.StateTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION; + pContext->BeginRenderPass(RPBeginInfo); + pContext->NextSubpass(); + pContext->EndRenderPass(true); } } // namespace -- cgit v1.2.3