Files
Juliet/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp
2025-02-18 21:12:36 -05:00

155 lines
7.4 KiB
C++

#include <pch.h>
#include <Graphics/D3D12/D3D12RenderPass.h>
#include <Graphics/D3D12/D3D12Texture.h>
#include <algorithm>
namespace Juliet::D3D12
{
void BeginRenderPass(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount)
{
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
uint32 frameBufferWidth = uint32Max;
uint32 frameBufferHeight = uint32Max;
for (uint32 idx = 0; idx < colorTargetInfoCount; ++idx)
{
auto* container = reinterpret_cast<D3D12TextureContainer*>(colorTargetInfos[idx].TargetTexture);
uint32 width = container->Header.CreateInfo.Width >> colorTargetInfos[idx].MipLevel;
uint32 height = container->Header.CreateInfo.Height >> colorTargetInfos[idx].MipLevel;
// Scale the framebuffer to fit the smallest target.
frameBufferWidth = Min(width, frameBufferWidth);
frameBufferHeight = Min(height, frameBufferHeight);
}
// TODO : Depth Stencil and DSV
D3D12_CPU_DESCRIPTOR_HANDLE RTVs[GPUDriver::kMaxColorTargetInfo];
for (uint32 idx = 0; idx < colorTargetInfoCount; ++idx)
{
auto* container = reinterpret_cast<D3D12TextureContainer*>(colorTargetInfos[idx].TargetTexture);
D3D12TextureSubresource* subresource = PrepareTextureSubresourceForWrite(
d3d12CommandList, container,
container->Header.CreateInfo.Type == TextureType::Texture_3D ? 0 : colorTargetInfos[idx].LayerIndex,
colorTargetInfos[idx].MipLevel, colorTargetInfos[idx].CycleTexture, D3D12_RESOURCE_STATE_RENDER_TARGET);
uint32 RTVIndex = container->Header.CreateInfo.Type == TextureType::Texture_3D ? colorTargetInfos[idx].DepthPlane : 0;
D3D12_CPU_DESCRIPTOR_HANDLE rtv = subresource->RTVHandles[RTVIndex].CpuHandle;
if (colorTargetInfos[idx].LoadOperation == LoadOperation::Clear)
{
float clearColor[4];
clearColor[0] = colorTargetInfos[idx].ClearColor.R;
clearColor[1] = colorTargetInfos[idx].ClearColor.G;
clearColor[2] = colorTargetInfos[idx].ClearColor.B;
clearColor[3] = colorTargetInfos[idx].ClearColor.A;
ID3D12GraphicsCommandList6_ClearRenderTargetView(d3d12CommandList->GraphicsCommandList.CommandList, rtv,
clearColor, 0, nullptr);
}
RTVs[idx] = rtv;
d3d12CommandList->ColorTargetSubresources[idx] = subresource;
// TODO: TrackTexture
if (colorTargetInfos[idx].StoreOperation == StoreOperation::Resolve ||
colorTargetInfos[idx].StoreOperation == StoreOperation::ResolveAndStore)
{
auto resolveContainer = reinterpret_cast<D3D12TextureContainer*>(colorTargetInfos[idx].ResolveTexture);
D3D12TextureSubresource* resolveSubresource =
PrepareTextureSubresourceForWrite(d3d12CommandList, resolveContainer, colorTargetInfos[idx].ResolveLayerIndex,
colorTargetInfos[idx].ResolveMipLevel, colorTargetInfos[idx].CycleResolveTexture,
D3D12_RESOURCE_STATE_RESOLVE_DEST);
d3d12CommandList->ColorResolveSubresources[idx] = resolveSubresource;
// TODO: TrackTexture Resolve
}
}
// TODO DSV
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList,
colorTargetInfoCount, RTVs, false, nullptr);
// Set defaults graphics states
GraphicsViewPort defaultViewport;
defaultViewport.X = 0.f;
defaultViewport.Y = 0.f;
defaultViewport.Width = static_cast<float>(frameBufferWidth);
defaultViewport.Height = static_cast<float>(frameBufferHeight);
defaultViewport.MinDepth = 0.f;
defaultViewport.MaxDepth = 1.f;
SetViewPort(commandList, defaultViewport);
Rectangle defaultScissor;
defaultScissor.X = 0;
defaultScissor.Y = 0;
defaultScissor.Width = static_cast<int32>(frameBufferWidth);
defaultScissor.Height = static_cast<int32>(frameBufferHeight);
SetScissorRect(commandList, defaultScissor);
SetStencilReference(commandList, 0);
FColor blendConstants;
blendConstants.R = 1.0f;
blendConstants.G = 1.0f;
blendConstants.B = 1.0f;
blendConstants.A = 1.0f;
SetBlendConstants(commandList, blendConstants);
}
void EndRenderPass(NonNullPtr<CommandList> commandList)
{
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(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