From ed9482b8f85fc76eea6ea3eb483e09b22b8a4a15 Mon Sep 17 00:00:00 2001 From: Patedam Date: Tue, 18 Feb 2025 21:12:36 -0500 Subject: [PATCH] End Render pass --- Juliet/include/Core/Common/CoreUtils.h | 3 +- Juliet/include/Graphics/Graphics.h | 1 + Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp | 44 +++++ Juliet/src/Graphics/D3D12/D3D12Texture.cpp | 170 ++++++++++++++++-- Juliet/src/Graphics/D3D12/D3D12Texture.h | 15 ++ .../src/Graphics/D3D12/DX12GraphicsDevice.cpp | 1 + Juliet/src/Graphics/Graphics.cpp | 10 ++ Juliet/src/Graphics/GraphicsDevice.h | 1 + JulietApp/Editor/EditorMain_win32.cpp | 11 +- 9 files changed, 231 insertions(+), 25 deletions(-) diff --git a/Juliet/include/Core/Common/CoreUtils.h b/Juliet/include/Core/Common/CoreUtils.h index 14f0de0..f88dfca 100644 --- a/Juliet/include/Core/Common/CoreUtils.h +++ b/Juliet/include/Core/Common/CoreUtils.h @@ -25,7 +25,8 @@ namespace Juliet extern void JULIET_API JulietAssert(const char* expression); #define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance)) -#define ZeroArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer) +#define ZeroArray(array) ZeroSize(sizeof((array)), (array)) +#define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer) inline void ZeroSize(size_t size, void* ptr) { auto Byte = (uint8*)ptr; diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h index 2a78f7a..b3d121c 100644 --- a/Juliet/include/Graphics/Graphics.h +++ b/Juliet/include/Graphics/Graphics.h @@ -97,6 +97,7 @@ namespace Juliet extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr commandList, ColorTargetInfo& colorTargetInfo); extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr commandList, NonNullPtr colorTargetInfos, uint32 colorTargetInfoCount); + extern JULIET_API void EndRenderPass(NonNullPtr renderPass); extern JULIET_API void SetGraphicsViewPort(NonNullPtr renderPass, const GraphicsViewPort& viewPort); extern JULIET_API void SetScissorRect(NonNullPtr renderPass, const Rectangle& rectangle); diff --git a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp index 06d4251..455d387 100644 --- a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp @@ -106,5 +106,49 @@ namespace Juliet::D3D12 void EndRenderPass(NonNullPtr commandList) { auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + + // Reset Color Target state and optionally resolve color texture + for (uint32 idx = 0; idx < GPUDriver::kMaxColorTargetInfo; ++idx) + { + if (d3d12CommandList->ColorTargetSubresources[idx]) + { + if (d3d12CommandList->ColorResolveSubresources[idx]) + { + TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, + d3d12CommandList->ColorTargetSubresources[idx]); + ID3D12GraphicsCommandList_ResolveSubresource( + d3d12CommandList->GraphicsCommandList.CommandList, + d3d12CommandList->ColorResolveSubresources[idx]->Parent->Resource, + d3d12CommandList->ColorResolveSubresources[idx]->Index, + d3d12CommandList->ColorTargetSubresources[idx]->Parent->Resource, + d3d12CommandList->ColorTargetSubresources[idx]->Index, + ConvertToD3D12TextureFormat( + d3d12CommandList->ColorTargetSubresources[idx]->Parent->Container->Header.CreateInfo.Format)); + + TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorTargetSubresources[idx], + D3D12_RESOURCE_STATE_RESOLVE_SOURCE); + + TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorResolveSubresources[idx], + D3D12_RESOURCE_STATE_RESOLVE_DEST); + } + else + { + TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorTargetSubresources[idx], + D3D12_RESOURCE_STATE_RENDER_TARGET); + } + } + } + + // TODO : Write Depth stencil + // TODO : Reset graphics pipeline + + ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, NULL, false, NULL); + + // Reset bind states + ZeroArray(d3d12CommandList->ColorTargetSubresources); + ZeroArray(d3d12CommandList->ColorResolveSubresources); + // TODO : reset depth stencil subresources + // TODO : vertex buffer + // TODO :Vertex sampler and fragment sampler } } // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp index f91388a..c16b727 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp @@ -9,6 +9,114 @@ namespace Juliet::D3D12 { namespace { + DXGI_FORMAT JulietToD3D12_TextureFormat[] = { + DXGI_FORMAT_UNKNOWN, // INVALID + DXGI_FORMAT_A8_UNORM, // A8_UNORM + DXGI_FORMAT_R8_UNORM, // R8_UNORM + DXGI_FORMAT_R8G8_UNORM, // R8G8_UNORM + DXGI_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM + DXGI_FORMAT_R16_UNORM, // R16_UNORM + DXGI_FORMAT_R16G16_UNORM, // R16G16_UNORM + DXGI_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM + DXGI_FORMAT_R10G10B10A2_UNORM, // R10G10B10A2_UNORM + DXGI_FORMAT_B5G6R5_UNORM, // B5G6R5_UNORM + DXGI_FORMAT_B5G5R5A1_UNORM, // B5G5R5A1_UNORM + DXGI_FORMAT_B4G4R4A4_UNORM, // B4G4R4A4_UNORM + DXGI_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM + DXGI_FORMAT_BC1_UNORM, // BC1_UNORM + DXGI_FORMAT_BC2_UNORM, // BC2_UNORM + DXGI_FORMAT_BC3_UNORM, // BC3_UNORM + DXGI_FORMAT_BC4_UNORM, // BC4_UNORM + DXGI_FORMAT_BC5_UNORM, // BC5_UNORM + DXGI_FORMAT_BC7_UNORM, // BC7_UNORM + DXGI_FORMAT_BC6H_SF16, // BC6H_FLOAT + DXGI_FORMAT_BC6H_UF16, // BC6H_UFLOAT + DXGI_FORMAT_R8_SNORM, // R8_SNORM + DXGI_FORMAT_R8G8_SNORM, // R8G8_SNORM + DXGI_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM + DXGI_FORMAT_R16_SNORM, // R16_SNORM + DXGI_FORMAT_R16G16_SNORM, // R16G16_SNORM + DXGI_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM + DXGI_FORMAT_R16_FLOAT, // R16_FLOAT + DXGI_FORMAT_R16G16_FLOAT, // R16G16_FLOAT + DXGI_FORMAT_R16G16B16A16_FLOAT, // R16G16B16A16_FLOAT + DXGI_FORMAT_R32_FLOAT, // R32_FLOAT + DXGI_FORMAT_R32G32_FLOAT, // R32G32_FLOAT + DXGI_FORMAT_R32G32B32A32_FLOAT, // R32G32B32A32_FLOAT + DXGI_FORMAT_R11G11B10_FLOAT, // R11G11B10_UFLOAT + DXGI_FORMAT_R8_UINT, // R8_UINT + DXGI_FORMAT_R8G8_UINT, // R8G8_UINT + DXGI_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT + DXGI_FORMAT_R16_UINT, // R16_UINT + DXGI_FORMAT_R16G16_UINT, // R16G16_UINT + DXGI_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT + DXGI_FORMAT_R32_UINT, // R32_UINT + DXGI_FORMAT_R32G32_UINT, // R32G32_UINT + DXGI_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT + DXGI_FORMAT_R8_SINT, // R8_INT + DXGI_FORMAT_R8G8_SINT, // R8G8_INT + DXGI_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT + DXGI_FORMAT_R16_SINT, // R16_INT + DXGI_FORMAT_R16G16_SINT, // R16G16_INT + DXGI_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT + DXGI_FORMAT_R32_SINT, // R32_INT + DXGI_FORMAT_R32G32_SINT, // R32G32_INT + DXGI_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, // R8G8B8A8_UNORM_SRGB + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, // B8G8R8A8_UNORM_SRGB + DXGI_FORMAT_BC1_UNORM_SRGB, // BC1_UNORM_SRGB + DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB + DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB + DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB + DXGI_FORMAT_R16_UNORM, // D16_UNORM + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM + DXGI_FORMAT_R32_FLOAT, // D32_FLOAT + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM_S8_UINT + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, // D32_FLOAT_S8_UINT + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT + }; + uint32 ComputeSubresourceIndex(uint32 mipLevel, uint32 layer, uint32 numLevels) { return mipLevel + (layer * numLevels); @@ -47,24 +155,6 @@ namespace Juliet::D3D12 Log(LogLevel::Error, LogCategory::Graphics, "Texture has no default usage mode!"); return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE; } - - void SetTextureSubresourceTransitionFromDefault(NonNullPtr commandList, - NonNullPtr subresource, - D3D12_RESOURCE_STATES newTextureUsage) - { - D3D12_RESOURCE_STATES defaultUsage = - GetDefaultTextureResourceState(subresource->Parent->Container->Header.CreateInfo.Flags); - TextureSubresourceBarrier(commandList, defaultUsage, newTextureUsage, subresource); - } - - void SetTextureTransitionFromDefault(NonNullPtr commandList, NonNullPtr texture, - D3D12_RESOURCE_STATES newTextureUsage) - { - for (uint32 i = 0; i < texture->SubresourceCount; ++i) - { - SetTextureSubresourceTransitionFromDefault(commandList, &texture->Subresources[i], newTextureUsage); - } - } } // namespace D3D12TextureSubresource* PrepareTextureSubresourceForWrite(NonNullPtr commandList, @@ -80,7 +170,7 @@ namespace Juliet::D3D12 subresource = FetchTextureSubresource(container, layer, level); } - SetTextureSubresourceTransitionFromDefault(commandList, subresource, newTextureUsage); + TextureSubresourceTransitionFromDefaultUsage(commandList, subresource, newTextureUsage); return subresource; } @@ -100,4 +190,46 @@ namespace Juliet::D3D12 ResourceBarrier(commandList, sourceState, destinationState, textureSubresource->Parent->Resource, textureSubresource->Index, needsUAVBarrier); } + + void TextureSubresourceTransitionFromDefaultUsage(NonNullPtr commandList, + NonNullPtr subresource, + D3D12_RESOURCE_STATES toTextureUsage) + { + D3D12_RESOURCE_STATES defaultUsage = + GetDefaultTextureResourceState(subresource->Parent->Container->Header.CreateInfo.Flags); + TextureSubresourceBarrier(commandList, defaultUsage, toTextureUsage, subresource); + } + + void TextureTransitionFromDefaultUsage(NonNullPtr commandList, NonNullPtr texture, + D3D12_RESOURCE_STATES toTextureUsage) + { + for (uint32 i = 0; i < texture->SubresourceCount; ++i) + { + TextureSubresourceTransitionFromDefaultUsage(commandList, &texture->Subresources[i], toTextureUsage); + } + } + + void TextureSubresourceTransitionToDefaultUsage(NonNullPtr commandList, + NonNullPtr subresource, D3D12_RESOURCE_STATES fromTextureUsage) + { + D3D12_RESOURCE_STATES defaultUsage = + GetDefaultTextureResourceState(subresource->Parent->Container->Header.CreateInfo.Flags); + TextureSubresourceBarrier(commandList, fromTextureUsage, defaultUsage, subresource); + } + + void TextureTransitionToDefaultUsage(NonNullPtr commandList, NonNullPtr texture, + D3D12_RESOURCE_STATES fromTextureUsage) + { + for (uint32 i = 0; i < texture->SubresourceCount; ++i) + { + TextureSubresourceTransitionToDefaultUsage(commandList, &texture->Subresources[i], fromTextureUsage); + } + } + + // Utils + DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format) + { + return JulietToD3D12_TextureFormat[ToUnderlying(format)]; + } + } // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/D3D12/D3D12Texture.h b/Juliet/src/Graphics/D3D12/D3D12Texture.h index 66435fa..a106cfc 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Texture.h +++ b/Juliet/src/Graphics/D3D12/D3D12Texture.h @@ -70,4 +70,19 @@ namespace Juliet::D3D12 extern void TextureSubresourceBarrier(NonNullPtr commandList, D3D12_RESOURCE_STATES sourceState, D3D12_RESOURCE_STATES destinationState, NonNullPtr textureSubresource); + + // Texture usage transition + extern void TextureSubresourceTransitionFromDefaultUsage(NonNullPtr commandList, + NonNullPtr subresource, + D3D12_RESOURCE_STATES toTextureUsage); + extern void TextureTransitionFromDefaultUsage(NonNullPtr commandList, + NonNullPtr texture, D3D12_RESOURCE_STATES toTextureUsage); + extern void TextureSubresourceTransitionToDefaultUsage(NonNullPtr commandList, + NonNullPtr subresource, + D3D12_RESOURCE_STATES fromTextureUsage); + extern void TextureTransitionToDefaultUsage(NonNullPtr commandList, + NonNullPtr texture, D3D12_RESOURCE_STATES fromTextureUsage); + + // Utils + extern DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format); } // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp index 9f01f94..42e8d85 100644 --- a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp @@ -551,6 +551,7 @@ namespace Juliet::D3D12 device->SubmitCommandLists = SubmitCommandLists; device->BeginRenderPass = BeginRenderPass; + device->EndRenderPass = EndRenderPass; device->SetViewPort = SetViewPort; device->SetScissorRect = SetScissorRect; diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp index db172dd..9bd5b39 100644 --- a/Juliet/src/Graphics/Graphics.cpp +++ b/Juliet/src/Graphics/Graphics.cpp @@ -130,6 +130,16 @@ namespace Juliet return reinterpret_cast(&header->RenderPass); } + void EndRenderPass(NonNullPtr renderPass) + { + auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; + auto* commandListHeader = reinterpret_cast(commandList); + + commandListHeader->Device->EndRenderPass(commandList); + + commandListHeader->RenderPass.IsInProgress = false; + } + void SetGraphicsViewPort(NonNullPtr renderPass, const GraphicsViewPort& viewPort) { auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index 5513843..0475ec2 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -51,6 +51,7 @@ namespace Juliet // RenderPass void (*BeginRenderPass)(NonNullPtr commandList, NonNullPtr colorTargetInfos, uint32 colorTargetInfoCount); + void (*EndRenderPass)(NonNullPtr commandList); void (*SetViewPort)(NonNullPtr commandList, const GraphicsViewPort& viewPort); void (*SetScissorRect)(NonNullPtr commandList, const Rectangle& viewPort); diff --git a/JulietApp/Editor/EditorMain_win32.cpp b/JulietApp/Editor/EditorMain_win32.cpp index be8ac9a..024c760 100644 --- a/JulietApp/Editor/EditorMain_win32.cpp +++ b/JulietApp/Editor/EditorMain_win32.cpp @@ -101,12 +101,13 @@ void Win32EditorApplication::Update() if (swapChainTexture) { ColorTargetInfo colorTargetInfo = {}; - colorTargetInfo.Texture = swapChainTexture; - colorTargetInfo.ClearColor = { .R = .5f, .G = .8f, .B = .0f, .A = 1.f }; - colorTargetInfo.LoadOperation = LoadOperation::Clear; - colorTargetInfo.StoreOperation = StoreOperation::Store; + colorTargetInfo.TargetTexture = swapChainTexture; + colorTargetInfo.ClearColor = { .R = .5f, .G = .8f, .B = .0f, .A = 1.f }; + colorTargetInfo.LoadOperation = LoadOperation::Clear; + colorTargetInfo.StoreOperation = StoreOperation::Store; - BeginRenderPass(cmdList, colorTargetInfo); + RenderPass* renderPass = BeginRenderPass(cmdList, colorTargetInfo); + EndRenderPass(renderPass); } // Submit Commands