Skip to content

Commit

Permalink
PBR Renderer: moved material shader attributes to a separate buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Nov 22, 2024
1 parent dd4f2da commit 395b4fa
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 73 deletions.
19 changes: 12 additions & 7 deletions PBR/interface/GLTF_PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,20 @@ class GLTF_PBR_Renderer : public PBR_Renderer
const float4x4* PrevSkinPreTransform = nullptr; // #if USE_JOINTS && USE_SKIN_PRE_TRANSFORM && COMPUTE_MOTION_VECTORS
const void* CustomData = nullptr;
size_t CustomDataSize = 0;
};
static void* WritePBRPrimitiveShaderAttribs(void* pDstShaderAttribs,
const PBRPrimitiveShaderAttribsData& AttribsData,
bool TransposeMatrices,
bool UseSkinPreTransform);

HLSL::PBRMaterialBasicAttribs** pMaterialBasicAttribsDstPtr = nullptr;
struct PBRMaterialShaderAttribsData
{
PSO_FLAGS PSOFlags = PSO_FLAG_NONE;
const std::array<int, TEXTURE_ATTRIB_ID_COUNT>& TextureAttribIndices;
const GLTF::Material& Material;
};
static void* WritePBRPrimitiveShaderAttribs(void* pDstShaderAttribs,
const PBRPrimitiveShaderAttribsData& AttribsData,
const std::array<int, TEXTURE_ATTRIB_ID_COUNT>& TextureAttribIndices,
const GLTF::Material& Material,
bool TransposeMatrices,
bool UseSkinPreTransform);
static void* WritePBRMaterialShaderAttribs(void* pDstShaderAttribs,
const PBRMaterialShaderAttribsData& AttribsData);

struct PBRLightShaderAttribsData
{
Expand Down
10 changes: 10 additions & 0 deletions PBR/interface/PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ class PBR_Renderer
/// If null, the renderer will allocate the buffer.
IBuffer* pPrimitiveAttribsCB = nullptr;

/// A pointer to the user-provided material attribs buffer.
/// If null, the renderer will allocate the buffer.
IBuffer* pMaterialAttribsCB = nullptr;

/// A pointer to the user-provided joints buffer.
/// If null, the renderer will allocate the buffer.
IBuffer* pJointsBuffer = nullptr;
Expand Down Expand Up @@ -462,6 +466,7 @@ class PBR_Renderer
ITextureView* GetBlackTexSRV() const { return m_pBlackTexSRV; }
ITextureView* GetDefaultNormalMapSRV() const { return m_pDefaultNormalMapSRV; }
IBuffer* GetPBRPrimitiveAttribsCB() const {return m_PBRPrimitiveAttribsCB;}
IBuffer* GetPBRMaterialAttribsCB() const {return m_PBRMaterialAttribsCB;}
IBuffer* GetJointsBuffer() const {return m_JointsBuffer;}
// clang-format on

Expand Down Expand Up @@ -692,6 +697,7 @@ class PBR_Renderer
void InitCommonSRBVars(IShaderResourceBinding* pSRB,
IBuffer* pFrameAttribs,
bool BindPrimitiveAttribsBuffer = true,
bool BindMaterialAttribsBuffer = true,
ITextureView* pShadowMap = nullptr) const;

void SetMaterialTexture(IShaderResourceBinding* pSRB, ITextureView* pTexSRV, TEXTURE_ATTRIB_ID TextureId) const;
Expand All @@ -705,6 +711,9 @@ class PBR_Renderer
/// Returns the PBR primitive attributes shader data size for the given PSO flags.
Uint32 GetPBRPrimitiveAttribsSize(PSO_FLAGS Flags, Uint32 CustomDataSize = sizeof(float4)) const;

/// Returns the PBR material attributes shader data size for the given PSO flags.
Uint32 GetPBRMaterialAttribsSize(PSO_FLAGS Flags) const;

/// Returns the PBR Frame attributes shader data size for the given light count.
static Uint32 GetPRBFrameAttribsSize(Uint32 LightCount, Uint32 ShadowCastingLightCount);

Expand Down Expand Up @@ -868,6 +877,7 @@ class PBR_Renderer
IBL_PipelineStateObjectCache m_IBL_PSOCache;

RefCntAutoPtr<IBuffer> m_PBRPrimitiveAttribsCB;
RefCntAutoPtr<IBuffer> m_PBRMaterialAttribsCB;
RefCntAutoPtr<IBuffer> m_PrecomputeEnvMapAttribsCB;
RefCntAutoPtr<IBuffer> m_JointsBuffer;

Expand Down
111 changes: 74 additions & 37 deletions PBR/src/GLTF_PBR_Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,9 @@ void GLTF_PBR_Renderer::Render(IDeviceContext* pCtx,
GLTF::Material::ALPHA_MODE_BLEND, // Transparent primitives - last (TODO: depth sorting)
};

IPipelineState* pCurrPSO = nullptr;
IShaderResourceBinding* pCurrSRB = nullptr;
IPipelineState* pCurrPSO = nullptr;
IShaderResourceBinding* pCurrSRB = nullptr;
const GLTF::Material* pCurrMaterial = nullptr;
PSOKey CurrPsoKey;

if (PrevTransforms == nullptr)
Expand Down Expand Up @@ -577,8 +578,9 @@ void GLTF_PBR_Renderer::Render(IDeviceContext* pCtx,
const PSOKey NewKey{PSOFlags, GltfAlphaModeToAlphaMode(AlphaMode), material.DoubleSided ? CULL_MODE_NONE : CULL_MODE_BACK, RenderParams.DebugView};
if (NewKey != CurrPsoKey)
{
CurrPsoKey = NewKey;
pCurrPSO = nullptr;
CurrPsoKey = NewKey;
pCurrPSO = nullptr;
pCurrMaterial = nullptr;
}

if (pCurrPSO == nullptr)
Expand Down Expand Up @@ -647,10 +649,6 @@ void GLTF_PBR_Renderer::Render(IDeviceContext* pCtx,
pCtx->MapBuffer(m_PBRPrimitiveAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD, pAttribsData);
if (pAttribsData != nullptr)
{
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_METALL_ROUGH) == PBR_WORKFLOW_METALL_ROUGH, "GLTF::Material::PBR_WORKFLOW_METALL_ROUGH != PBR_WORKFLOW_METALL_ROUGH");
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_SPEC_GLOSS) == PBR_WORKFLOW_SPEC_GLOSS, "GLTF::Material::PBR_WORKFLOW_SPEC_GLOSS != PBR_WORKFLOW_SPEC_GLOSS");
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_UNLIT) == PBR_WORKFLOW_UNLIT, "GLTF::Material::PBR_WORKFLOW_UNLIT != PBR_WORKFLOW_UNLIT");

const float4x4 NodeTransform = NodeGlobalMatrix * RenderParams.ModelTransform;
const float4x4& PrevNodeTransform = (CurrPsoKey.GetFlags() & PSO_FLAG_COMPUTE_MOTION_VECTORS) != 0 ?
PrevNodeGlobalMatrix * RenderParams.ModelTransform :
Expand All @@ -662,7 +660,7 @@ void GLTF_PBR_Renderer::Render(IDeviceContext* pCtx,
&PrevNodeTransform,
static_cast<Uint32>(JointCount),
};
auto* pEndPtr = WritePBRPrimitiveShaderAttribs(pAttribsData, AttribsData, m_Settings.TextureAttribIndices, material, !m_Settings.PackMatrixRowMajor, m_Settings.UseSkinPreTransform);
void* pEndPtr = WritePBRPrimitiveShaderAttribs(pAttribsData, AttribsData, !m_Settings.PackMatrixRowMajor, m_Settings.UseSkinPreTransform);

VERIFY(reinterpret_cast<uint8_t*>(pEndPtr) <= static_cast<uint8_t*>(pAttribsData) + m_PBRPrimitiveAttribsCB->GetDesc().Size,
"Not enough space in the buffer to store primitive attributes");
Expand All @@ -675,6 +673,36 @@ void GLTF_PBR_Renderer::Render(IDeviceContext* pCtx,
}
}

if (pCurrMaterial != &material)
{
void* pAttribsData = nullptr;
pCtx->MapBuffer(m_PBRMaterialAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD, pAttribsData);
if (pAttribsData != nullptr)
{
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_METALL_ROUGH) == PBR_WORKFLOW_METALL_ROUGH, "GLTF::Material::PBR_WORKFLOW_METALL_ROUGH != PBR_WORKFLOW_METALL_ROUGH");
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_SPEC_GLOSS) == PBR_WORKFLOW_SPEC_GLOSS, "GLTF::Material::PBR_WORKFLOW_SPEC_GLOSS != PBR_WORKFLOW_SPEC_GLOSS");
static_assert(static_cast<PBR_WORKFLOW>(GLTF::Material::PBR_WORKFLOW_UNLIT) == PBR_WORKFLOW_UNLIT, "GLTF::Material::PBR_WORKFLOW_UNLIT != PBR_WORKFLOW_UNLIT");

PBRMaterialShaderAttribsData AttribsData{
CurrPsoKey.GetFlags(),
m_Settings.TextureAttribIndices,
material,
};
void* pEndPtr = WritePBRMaterialShaderAttribs(pAttribsData, AttribsData);

VERIFY(reinterpret_cast<uint8_t*>(pEndPtr) <= static_cast<uint8_t*>(pAttribsData) + m_PBRMaterialAttribsCB->GetDesc().Size,
"Not enough space in the buffer to store material attributes");

pCtx->UnmapBuffer(m_PBRMaterialAttribsCB, MAP_WRITE);
}
else
{
UNEXPECTED("Unable to map the buffer");
}

pCurrMaterial = &material;
}

if (primitive.HasIndices())
{
DrawIndexedAttribs drawAttrs{primitive.IndexCount, VT_UINT32, DRAW_FLAG_VERIFY_ALL};
Expand Down Expand Up @@ -710,12 +738,10 @@ Uint8* WriteShaderAttribs(Uint8* pDstPtr, HostStructType* pSrc, const char* Debu
}


void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void* pDstShaderAttribs,
const PBRPrimitiveShaderAttribsData& AttribsData,
const std::array<int, TEXTURE_ATTRIB_ID_COUNT>& TextureAttribIndices,
const GLTF::Material& Material,
bool TransposeMatrices,
bool UseSkinPreTransform)
void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void* pDstShaderAttribs,
const PBRPrimitiveShaderAttribsData& AttribsData,
bool TransposeMatrices,
bool UseSkinPreTransform)
{
// When adding new members, don't forget to update PBR_Renderer::GetPBRPrimitiveAttribsSize!

Expand All @@ -740,16 +766,6 @@ void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void*
// float4x4 PrevSkinPreTransform; // #if USE_JOINTS && USE_SKIN_PRE_TRANSFORM && COMPUTE_MOTION_VECTORS
// } Transforms;
//
// struct PBRMaterialShaderInfo
// {
// PBRMaterialBasicAttribs Basic;
// PBRMaterialSheenAttribs Sheen; // #if ENABLE_SHEEN
// PBRMaterialAnisotropyAttribs Anisotropy; // #if ENABLE_ANISOTROPY
// PBRMaterialIridescenceAttribs Iridescence; // #if ENABLE_IRIDESCENCE
// PBRMaterialTransmissionAttribs Transmission; // #if ENABLE_TRANSMISSION
// PBRMaterialVolumeAttribs Volume; // #if ENABLE_VOLUME
// PBRMaterialTextureAttribs Textures[PBR_NUM_TEXTURE_ATTRIBUTES];
// } Material;
// UserDefined CustomData;
//};

Expand Down Expand Up @@ -823,8 +839,38 @@ void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void*
}
}

if (AttribsData.pMaterialBasicAttribsDstPtr != nullptr)
*AttribsData.pMaterialBasicAttribsDstPtr = reinterpret_cast<HLSL::PBRMaterialBasicAttribs*>(pDstPtr);
{
if (AttribsData.CustomData != nullptr)
{
VERIFY_EXPR(AttribsData.CustomDataSize > 0);
memcpy(pDstPtr, AttribsData.CustomData, AttribsData.CustomDataSize);
}
pDstPtr += AttribsData.CustomDataSize;
}

return pDstPtr;
}

void* GLTF_PBR_Renderer::WritePBRMaterialShaderAttribs(void* pDstShaderAttribs,
const PBRMaterialShaderAttribsData& AttribsData)
{
// When adding new members, don't forget to update PBR_Renderer::GetPBRMaterialAttribsSize!

// struct PBRMaterialShaderInfo
// {
// PBRMaterialBasicAttribs Basic;
// PBRMaterialSheenAttribs Sheen; // #if ENABLE_SHEEN
// PBRMaterialAnisotropyAttribs Anisotropy; // #if ENABLE_ANISOTROPY
// PBRMaterialIridescenceAttribs Iridescence; // #if ENABLE_IRIDESCENCE
// PBRMaterialTransmissionAttribs Transmission; // #if ENABLE_TRANSMISSION
// PBRMaterialVolumeAttribs Volume; // #if ENABLE_VOLUME
// PBRMaterialTextureAttribs Textures[PBR_NUM_TEXTURE_ATTRIBUTES];
// } Material;

const GLTF::Material& Material = AttribsData.Material;

Uint8* pDstPtr = reinterpret_cast<Uint8*>(pDstShaderAttribs);

pDstPtr = WriteShaderAttribs<HLSL::PBRMaterialBasicAttribs>(pDstPtr, &Material.Attribs, "Basic Attribs");

if (AttribsData.PSOFlags & PSO_FLAG_ENABLE_SHEEN)
Expand Down Expand Up @@ -859,7 +905,7 @@ void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void*
Uint32 NumTextureAttribs = 0;
ProcessTexturAttribs(AttribsData.PSOFlags, [&](int CurrIndex, PBR_Renderer::TEXTURE_ATTRIB_ID AttribId) //
{
const int SrcAttribIndex = TextureAttribIndices[AttribId];
const int SrcAttribIndex = AttribsData.TextureAttribIndices[AttribId];
if (SrcAttribIndex < 0)
{
UNEXPECTED("Shader attribute ", Uint32{AttribId}, " is not initialized");
Expand All @@ -875,15 +921,6 @@ void* GLTF_PBR_Renderer::WritePBRPrimitiveShaderAttribs(void*
pDstPtr = reinterpret_cast<Uint8*>(pDstTextures + NumTextureAttribs);
}

{
if (AttribsData.CustomData != nullptr)
{
VERIFY_EXPR(AttribsData.CustomDataSize > 0);
memcpy(pDstPtr, AttribsData.CustomData, AttribsData.CustomDataSize);
}
pDstPtr += AttribsData.CustomDataSize;
}

return pDstPtr;
}

Expand Down
Loading

0 comments on commit 395b4fa

Please sign in to comment.