Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR: Reduced the number of buffer maps (close #48) #51

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Hydrogent/src/Tasks/HnPostProcessTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ void HnPostProcessTask::Prepare(pxr::HdTaskContext* TaskCtx,
VERIFY(m_PostProcessAttribsCB, "Failed to create post process attribs CB");
}


if (!m_PostFXContext)
{
m_PostFXContext = std::make_unique<PostFXContext>(pDevice);
Expand All @@ -234,8 +233,11 @@ void HnPostProcessTask::Prepare(pxr::HdTaskContext* TaskCtx,
m_SSR = std::make_unique<ScreenSpaceReflection>(pDevice);
}

const TextureDesc& FinalColorDesc = m_FinalColorRTV->GetTexture()->GetDesc();
m_SSR->SetBackBufferSize(pDevice, pCtx, FinalColorDesc.Width, FinalColorDesc.Height);
const HnRenderParam* pRenderParam = static_cast<const HnRenderParam*>(RenderDelegate->GetRenderParam());
const TextureDesc& FinalColorDesc = m_FinalColorRTV->GetTexture()->GetDesc();

m_PostFXContext->PrepareResources({pRenderParam->GetFrameNumber(), FinalColorDesc.Width, FinalColorDesc.Height});
m_SSR->PrepareResources(pDevice, m_PostFXContext.get());

PreparePSO(m_FinalColorRTV->GetDesc().Format, TaskCtx);
if (std::shared_ptr<HnRenderPassState> RenderPassState = GetRenderPassState(TaskCtx))
Expand Down Expand Up @@ -395,7 +397,6 @@ void HnPostProcessTask::Execute(pxr::HdTaskContext* TaskCtx)
PostFXContext::RenderAttributes PostFXAttribs{};
PostFXAttribs.pDevice = pDevice;
PostFXAttribs.pDeviceContext = pCtx;
PostFXAttribs.FrameIndex = pRenderParam->GetFrameNumber();

pxr::VtValue PBRFrameAttribsVal = (*TaskCtx)[HnRenderResourceTokens->frameShaderAttribs];
if (PBRFrameAttribsVal.IsHolding<HLSL::PBRFrameAttribs*>())
Expand All @@ -409,7 +410,7 @@ void HnPostProcessTask::Execute(pxr::HdTaskContext* TaskCtx)
{
UNEXPECTED("PBR frame attribs are not set in the task context");
}
m_PostFXContext->PrepareResources(PostFXAttribs);
m_PostFXContext->Execute(PostFXAttribs);

HLSL::ScreenSpaceReflectionAttribs SSRAttribs{};
SSRAttribs.IBLFactor = 1.0;
Expand Down
38 changes: 32 additions & 6 deletions PostProcess/Common/interface/PostFXContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ struct CameraAttribs;
class PostFXContext
{
public:
struct FrameDesc
{
Uint32 Index = 0;
Uint32 Width = 0;
Uint32 Height = 0;
};

struct RenderAttributes
{
/// Render device that may be used to create new objects needed for this frame, if any.
Expand All @@ -66,8 +73,6 @@ class PostFXContext

/// If this parameter is null, the effect will use its own buffer.
IBuffer* pCameraAttribsCB = nullptr;

Uint32 FrameIndex = {};
};

enum BLUE_NOISE_DIMENSION : Uint32
Expand All @@ -77,18 +82,38 @@ class PostFXContext
BLUE_NOISE_DIMENSION_COUNT
};

struct SupportedDeviceFeatures
{
bool TransitionSubresources = false;
bool TextureSubresourceViews = false;
bool CopyDepthToColor = false;

/// Indicates whether the Base Vertex is added to the VertexID
/// in the vertex shader.
bool ShaderBaseVertexOffset = false;
};

public:
PostFXContext(IRenderDevice* pDevice);

~PostFXContext();

void PrepareResources(const RenderAttributes& RenderAttribs);
void PrepareResources(const FrameDesc& Desc);
void Execute(const RenderAttributes& RenderAttribs);

ITextureView* Get2DBlueNoiseSRV(BLUE_NOISE_DIMENSION Dimension) const;

IBuffer* GetCameraAttribsCB() const;

Uint32 GetFrameIndex() const;
const SupportedDeviceFeatures& GetSupportedFeatures() const
{
return m_SupportedFeatures;
}

const FrameDesc& GetFrameDesc() const
{
return m_FrameDesc;
}

private:
using RenderTechnique = PostFXRenderTechnique;
Expand All @@ -103,7 +128,7 @@ class PostFXContext
enum RESOURCE_IDENTIFIER : Uint32
{
RESOURCE_IDENTIFIER_CONSTANT_BUFFER = 0,
RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE,
RESOURCE_IDENTIFIER_INDEX_BUFFER_INTERMEDIATE,
RESOURCE_IDENTIFIER_SOBOL_BUFFER,
RESOURCE_IDENTIFIER_SCRAMBLING_TILE_BUFFER,
RESOURCE_IDENTIFIER_BLUE_NOISE_TEXTURE_XY,
Expand All @@ -115,7 +140,8 @@ class PostFXContext

ResourceRegistry m_Resources{RESOURCE_IDENTIFIER_COUNT};

Uint32 m_CurrentFrameIndex = 0;
FrameDesc m_FrameDesc = {};
SupportedDeviceFeatures m_SupportedFeatures = {};
};

} // namespace Diligent
61 changes: 43 additions & 18 deletions PostProcess/Common/src/PostFXContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ namespace NoiseBuffers
PostFXContext::PostFXContext(IRenderDevice* pDevice)
{
DEV_CHECK_ERR(pDevice != nullptr, "pDevice must not be null");
const auto& DeviceInfo = pDevice->GetDeviceInfo();

m_SupportedFeatures.TransitionSubresources = DeviceInfo.Type == RENDER_DEVICE_TYPE_D3D12 || DeviceInfo.Type == RENDER_DEVICE_TYPE_VULKAN;
m_SupportedFeatures.TextureSubresourceViews = DeviceInfo.Features.TextureSubresourceViews;
m_SupportedFeatures.CopyDepthToColor = DeviceInfo.IsD3DDevice();
m_SupportedFeatures.ShaderBaseVertexOffset = !DeviceInfo.IsD3DDevice();

RenderDeviceWithCache_N Device{pDevice};
{
Expand Down Expand Up @@ -111,14 +117,26 @@ PostFXContext::PostFXContext(IRenderDevice* pDevice)
m_Resources.Insert(TextureIdx, Device.CreateTexture(Desc, nullptr));
}

RefCntAutoPtr<IBuffer> pBuffer;
CreateUniformBuffer(pDevice, 2 * sizeof(HLSL::CameraAttribs), "PostFXContext::IntermediateConstantBuffer", &pBuffer);
m_Resources.Insert(RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE, pBuffer);
if (!m_SupportedFeatures.ShaderBaseVertexOffset)
{
BufferDesc Desc;
Desc.Name = "PostFXContext::IndexBufferIntermediate";
Desc.BindFlags = BIND_INDEX_BUFFER;
Desc.Size = 3 * sizeof(Uint32);
Desc.CPUAccessFlags = CPU_ACCESS_WRITE;
Desc.Usage = USAGE_DYNAMIC;
m_Resources.Insert(RESOURCE_IDENTIFIER_INDEX_BUFFER_INTERMEDIATE, Device.CreateBuffer(Desc, nullptr));
}
}

PostFXContext::~PostFXContext() = default;

void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
void PostFXContext::PrepareResources(const FrameDesc& Desc)
{
m_FrameDesc = Desc;
}

void PostFXContext::Execute(const RenderAttributes& RenderAttribs)
{
DEV_CHECK_ERR(RenderAttribs.pDevice != nullptr, "RenderAttribs.pDevice must not be null");
DEV_CHECK_ERR(RenderAttribs.pDeviceContext != nullptr, "RenderAttribs.pDeviceContext must not be null");
Expand Down Expand Up @@ -146,18 +164,11 @@ void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
m_Resources.Insert(RESOURCE_IDENTIFIER_CONSTANT_BUFFER, RenderAttribs.pCameraAttribsCB);
}

{
MapHelper<Uint32> FrameAttibs{RenderAttribs.pDeviceContext, m_Resources[RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE], MAP_WRITE, MAP_FLAG_DISCARD};
*FrameAttibs = RenderAttribs.FrameIndex;
m_CurrentFrameIndex = RenderAttribs.FrameIndex;
}

auto& RenderTech = m_RenderTech[RENDER_TECH_COMPUTE_BLUE_NOISE_TEXTURE];
if (!RenderTech.IsInitialized())
{
PipelineResourceLayoutDescX ResourceLayout;
ResourceLayout
.AddVariable(SHADER_TYPE_PIXEL, "cbBlueNoiseAttribs", SHADER_RESOURCE_VARIABLE_TYPE_STATIC)
.AddVariable(SHADER_TYPE_PIXEL, "g_SobolBuffer", SHADER_RESOURCE_VARIABLE_TYPE_STATIC)
.AddVariable(SHADER_TYPE_PIXEL, "g_ScramblingTileBuffer", SHADER_RESOURCE_VARIABLE_TYPE_STATIC);

Expand All @@ -174,7 +185,6 @@ void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
TEX_FORMAT_UNKNOWN,
DSS_DisableDepth, BS_Default, false);

ShaderResourceVariableX{RenderTech.PSO, SHADER_TYPE_PIXEL, "cbBlueNoiseAttribs"}.Set(m_Resources[RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE].AsBuffer());
ShaderResourceVariableX{RenderTech.PSO, SHADER_TYPE_PIXEL, "g_SobolBuffer"}.Set(m_Resources[RESOURCE_IDENTIFIER_SOBOL_BUFFER].GetTextureSRV());
ShaderResourceVariableX{RenderTech.PSO, SHADER_TYPE_PIXEL, "g_ScramblingTileBuffer"}.Set(m_Resources[RESOURCE_IDENTIFIER_SCRAMBLING_TILE_BUFFER].GetTextureSRV());
RenderTech.InitializeSRB(true);
Expand All @@ -190,7 +200,27 @@ void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
RenderAttribs.pDeviceContext->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
RenderAttribs.pDeviceContext->SetPipelineState(RenderTech.PSO);
RenderAttribs.pDeviceContext->CommitShaderResources(RenderTech.SRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
RenderAttribs.pDeviceContext->Draw({3, DRAW_FLAG_VERIFY_ALL, 1});

// We pass the frame number to the shader through StartVertexLocation in Vulkan and OpenGL (we do not use a separate
// constant buffer because in WebGL, the glMapBuffer function has a significant impact on CPU-side performance).
// For D3D11 and D3D12, we pass the frame number using a index buffer. Unfortunately, in DXIL / DXBC, the indexing of
// SV_VertexID always starts from zero regardless of StartVertexLocation, unlike SPIRV / GLSL.
const Uint32 StartVertexLocation = m_SupportedFeatures.ShaderBaseVertexOffset ? 3u * m_FrameDesc.Index : 0u;
if (m_SupportedFeatures.ShaderBaseVertexOffset)
{
RenderAttribs.pDeviceContext->Draw({3, DRAW_FLAG_VERIFY_ALL, 1, StartVertexLocation});
}
else
{
{
MapHelper<Uint32> IndexBuffer{RenderAttribs.pDeviceContext, m_Resources[RESOURCE_IDENTIFIER_INDEX_BUFFER_INTERMEDIATE], MAP_WRITE, MAP_FLAG_DISCARD};
IndexBuffer[0] = 3 * m_FrameDesc.Index + 0;
IndexBuffer[1] = 3 * m_FrameDesc.Index + 1;
IndexBuffer[2] = 3 * m_FrameDesc.Index + 2;
}
RenderAttribs.pDeviceContext->SetIndexBuffer(m_Resources[RESOURCE_IDENTIFIER_INDEX_BUFFER_INTERMEDIATE].AsBuffer(), 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
RenderAttribs.pDeviceContext->DrawIndexed({3, VT_UINT32, DRAW_FLAG_VERIFY_ALL, 1});
}
RenderAttribs.pDeviceContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE);
}

Expand All @@ -204,9 +234,4 @@ IBuffer* PostFXContext::GetCameraAttribsCB() const
return m_Resources[RESOURCE_IDENTIFIER_CONSTANT_BUFFER];
}

Uint32 PostFXContext::GetFrameIndex() const
{
return m_CurrentFrameIndex;
}

} // namespace Diligent
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ScreenSpaceReflection

~ScreenSpaceReflection();

void SetBackBufferSize(IRenderDevice* pDevice, IDeviceContext* pDeviceContext, Uint32 BackBufferWidth, Uint32 BackBufferHeight);
void PrepareResources(IRenderDevice* pDevice, PostFXContext* pPostFXContext);

void Execute(const RenderAttributes& RenderAttribs);

Expand Down Expand Up @@ -135,7 +135,6 @@ class ScreenSpaceReflection
RESOURCE_IDENTIFIER_INPUT_MATERIAL_PARAMETERS,
RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS,
RESOURCE_IDENTIFIER_CONSTANT_BUFFER,
RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE,
RESOURCE_IDENTIFIER_DEPTH_HIERARCHY,
RESOURCE_IDENTIFIER_DEPTH_HIERARCHY_INTERMEDIATE,
RESOURCE_IDENTIFIER_DEPTH_STENCIL_MASK,
Expand All @@ -162,13 +161,6 @@ class ScreenSpaceReflection
std::vector<RefCntAutoPtr<ITextureView>> m_HierarchicalDepthMipMapSRV;
RefCntAutoPtr<ITextureView> m_DepthStencilMaskDSVReadOnly;

struct SupportedDeviceFeatures
{
bool TransitionSubresources = false;
bool TextureSubresourceViews = false;
bool CopyDepthToColor = false;
} m_SupportedFeatures;

Uint32 m_BackBufferWidth = 0;
Uint32 m_BackBufferHeight = 0;
};
Expand Down
Loading