Skip to content

Commit

Permalink
SSR: Reduced the number of buffer maps (close #48)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhailGorobets authored and TheMostDiligent committed Jan 17, 2024
1 parent c5a891e commit c1a8b1c
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 147 deletions.
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
57 changes: 42 additions & 15 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,19 @@ void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
m_Resources.Insert(RESOURCE_IDENTIFIER_CONSTANT_BUFFER, RenderAttribs.pCameraAttribsCB);
}

if (!m_SupportedFeatures.ShaderBaseVertexOffset)
{
MapHelper<Uint32> FrameAttibs{RenderAttribs.pDeviceContext, m_Resources[RESOURCE_IDENTIFIER_CONSTANT_BUFFER_INTERMEDIATE], MAP_WRITE, MAP_FLAG_DISCARD};
*FrameAttibs = RenderAttribs.FrameIndex;
m_CurrentFrameIndex = RenderAttribs.FrameIndex;
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;
}

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 +193,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 @@ -187,10 +205,24 @@ void PostFXContext::PrepareResources(const RenderAttributes& RenderAttribs)
m_Resources[RESOURCE_IDENTIFIER_BLUE_NOISE_TEXTURE_ZW].GetTextureRTV(),
};

// 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;
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});

if (m_SupportedFeatures.ShaderBaseVertexOffset)
{
RenderAttribs.pDeviceContext->Draw({3, DRAW_FLAG_VERIFY_ALL, 1, StartVertexLocation});
}
else
{
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 +236,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

0 comments on commit c1a8b1c

Please sign in to comment.