Skip to content
Open
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
150 changes: 103 additions & 47 deletions trinity/Raytracing/Tr2RaytracingGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#include <../trinityal/dx12/Tr2BufferALDx12.h>
#endif

CCP_STATS_DECLARE( rtShaderTableShaders, "Trinity/RT/shaderTableShaders", true, CST_COUNTER_HIGH, "Distinct shaders resolved for the shader table this frame." );
CCP_STATS_DECLARE( rtShaderTableLibraries, "Trinity/RT/shaderTableLibraries", true, CST_COUNTER_HIGH, "Distinct raytracing libraries seen by the shader table this frame." );
CCP_STATS_DECLARE( rtTransformMeshesSkipped, "Trinity/RT/transformMeshesSkipped", true, CST_COUNTER_HIGH, "TransformMeshes returned early because no skinned or morphed geometry was added this frame." );
CCP_STATS_DECLARE( rtShaderTableMaterialApplies, "Trinity/RT/shaderTableMaterialApplies", true, CST_COUNTER_HIGH, "Shader table entries whose RT material data was built and applied this frame." );

namespace
{
std::mutex s_geometryConstantsMutex;
Expand Down Expand Up @@ -613,6 +618,7 @@ void Tr2RaytracingGeometry::BeginSceneUpdate()
{
m_geometryData.clear();
m_usedResources.Clear();
m_hasDeformedGeometry.store( false, std::memory_order_relaxed );
}


Expand Down Expand Up @@ -642,80 +648,108 @@ void Tr2RaytracingGeometry::PrepareShaderTableDescription( Tr2RenderContext& ren
TRINITY_STATS_ZONE( __FUNCTION__ );
for( int32_t i = 0; i < numRaycasters; i++ )
{
*shaderTableDescs[i] = Tr2RtShaderTableDescriptionAL();
shaderTableDescs[i]->Clear();
shaderTableDescs[i]->Reserve( m_geometryData.size() );
}

std::vector<std::map<uint32_t, std::pair<BlueSharedStringW, uint32_t>>> seenLibraries;
seenLibraries.resize( numRaycasters );
// A handful of shaders and libraries per frame, so linear search over reused vectors beats maps
m_rtShaderStates.clear();
m_rtLibraryStates.clear();
m_rtLibraryHitGroupNames.clear();

uint32_t materialIndex = 0;
for( auto it = begin( m_geometryData ); it != end( m_geometryData ); ++it )
for( auto& geometry : m_geometryData )
{
Tr2RtLocalMaterialDescriptionAL material;
if( !it->material )
if( !geometry.material )
{
continue;
}
auto shader = it->material->GetShaderStateInterface();
auto shader = geometry.material->GetShaderStateInterface();
if( !shader )
{
continue;
}
uint32_t techniqueIndex;
if( !shader->GetTechniqueIndex( m_rtShadowTechniqueName, techniqueIndex ) )

auto shaderState = std::find_if( begin( m_rtShaderStates ), end( m_rtShaderStates ), [&]( const RtShaderState& state ) { return state.shader == shader; } );
if( shaderState == end( m_rtShaderStates ) )
{
continue;
m_rtShaderStates.push_back( { shader } );
shaderState = std::prev( end( m_rtShaderStates ) );
uint32_t techniqueIndex;
if( shader->GetTechniqueIndex( m_rtShadowTechniqueName, techniqueIndex ) )
{
auto& libs = shader->GetEffectDescription().techniques[techniqueIndex].libraries;
if( !libs.empty() )
{
const uint32_t handle = libs[0].libraryHandle;
auto libState = std::find_if( begin( m_rtLibraryStates ), end( m_rtLibraryStates ), [&]( const RtLibraryState& state ) { return state.handle == handle; } );
if( libState == end( m_rtLibraryStates ) )
{
m_rtLibraryStates.push_back( { handle, &libs[0], uint32_t( m_rtLibraryHitGroupNames.size() ) } );
libState = std::prev( end( m_rtLibraryStates ) );
libState->addsRecords = !libs[0].localInput.signature.registers.empty();
m_rtLibraryHitGroupNames.resize( m_rtLibraryHitGroupNames.size() + numRaycasters );
}
shaderState->techniqueIndex = techniqueIndex;
shaderState->libIndex = uint32_t( libState - begin( m_rtLibraryStates ) );
}
}
}
auto& desc = shader->GetEffectDescription();
if( desc.techniques[techniqueIndex].libraries.empty() )
if( shaderState->libIndex == INVALID_MATERIAL )
{
continue;
}
auto& lib = desc.techniques[techniqueIndex].libraries[0];
auto& libState = m_rtLibraryStates[shaderState->libIndex];
auto& lib = *libState.lib;
auto hitGroupNames = &m_rtLibraryHitGroupNames[libState.hitGroupNamesOffset];
if( !lib.anyHitName.empty() )
{
it->isTransparent = true;
geometry.isTransparent = true;
}
if( libState.seen && !libState.addsRecords )
{
geometry.materialIndex = libState.materialIndex;
continue;
}

if( it->perObjectData )
CCP_STATS_INC( rtShaderTableMaterialApplies );
Tr2RtLocalMaterialDescriptionAL material;
if( geometry.perObjectData )
{
material.SetConstants( Tr2Renderer::GetPerObjectPSStartRegister(), *it->perObjectData );
material.SetConstants( Tr2Renderer::GetPerObjectPSStartRegister(), *geometry.perObjectData );
}
if( it->vertexBufferData )
if( geometry.vertexBufferData )
{
material.SetConstants( Tr2Renderer::GetPerObjectRTVertexBufferDataRegister(), *it->vertexBufferData );
material.SetConstants( Tr2Renderer::GetPerObjectRTVertexBufferDataRegister(), *geometry.vertexBufferData );
}
it->material->ApplyMaterialDataForRtMaterial( techniqueIndex, material, renderContext );
geometry.material->ApplyMaterialDataForRtMaterial( shaderState->techniqueIndex, material, renderContext );

bool consumedMaterialIndex = false;
for( int32_t i = 0; i < numRaycasters; i++ )
if( !libState.seen )
{
auto foundLib = seenLibraries[i].find( lib.libraryHandle );
if( foundLib == end( seenLibraries[i] ) )
libState.seen = true;
libState.materialIndex = materialIndex;
for( int32_t i = 0; i < numRaycasters; i++ )
{
auto hitGroupName = pipelineManagers[i]->AddHitGroup( lib );
seenLibraries[i][lib.libraryHandle] = std::make_pair( hitGroupName, materialIndex );
shaderTableDescs[i]->AddHitGroup( hitGroupName.c_str(), material );
it->materialIndex = materialIndex;
consumedMaterialIndex = true;
hitGroupNames[i] = pipelineManagers[i]->AddHitGroup( lib );
shaderTableDescs[i]->AddHitGroup( hitGroupNames[i].c_str(), material );
}
else if( !lib.localInput.signature.registers.empty() )
{
shaderTableDescs[i]->AddHitGroup( foundLib->second.first.c_str(), material );
it->materialIndex = materialIndex;
consumedMaterialIndex = true;
}
else
geometry.materialIndex = materialIndex++;
}
else if( libState.addsRecords )
{
for( int32_t i = 0; i < numRaycasters; i++ )
{
it->materialIndex = foundLib->second.second;
shaderTableDescs[i]->AddHitGroup( hitGroupNames[i].c_str(), material );
}
geometry.materialIndex = materialIndex++;
}
if( consumedMaterialIndex )
else
{
materialIndex++;
geometry.materialIndex = libState.materialIndex;
}
}
CCP_STATS_ADD( rtShaderTableShaders, m_rtShaderStates.size() );
CCP_STATS_ADD( rtShaderTableLibraries, m_rtLibraryStates.size() );
}

namespace
Expand Down Expand Up @@ -751,6 +785,21 @@ void Tr2RaytracingGeometry::TransformMeshes( Tr2RenderContext& renderContext )
ON_BLOCK_EXIT( [&] { renderContext.PopDisableUAVBarriersDx12(); } );
#endif

{
TRINITY_STATS_ZONE( "Prepare BoneTransformBuffer" );
Tr2RingBuffer::GetInstance<Float4x3>().PrepareBuffer( renderContext );
}
{
TRINITY_STATS_ZONE( "Prepare MorphTargetAnimationDataBuffer" );
Tr2RingBuffer::GetInstance<Tr2MorphTargetAnimationData>().PrepareBuffer( renderContext );
}

if( !m_hasDeformedGeometry.load( std::memory_order_relaxed ) )
{
CCP_STATS_INC( rtTransformMeshesSkipped );
return;
}

for( auto& geom : m_geometryData )
{
if( geom.materialIndex == INVALID_MATERIAL )
Expand All @@ -766,15 +815,6 @@ void Tr2RaytracingGeometry::TransformMeshes( Tr2RenderContext& renderContext )
std::vector<GeometryData*> outdatedMeshes;
outdatedMeshes.reserve( m_geometryData.size() );

{
TRINITY_STATS_ZONE( "Prepare BoneTransformBuffer" );
Tr2RingBuffer::GetInstance<Float4x3>().PrepareBuffer( renderContext );
}
{
TRINITY_STATS_ZONE( "Prepare MorphTargetAnimationDataBuffer" );
Tr2RingBuffer::GetInstance<Tr2MorphTargetAnimationData>().PrepareBuffer( renderContext );
}

uint32_t skinnedVertexCount = 0;

for( auto it = begin( m_geometryData ); it != end( m_geometryData ); ++it )
Expand Down Expand Up @@ -1031,6 +1071,21 @@ void Tr2RaytracingGeometry::AddGeometry( Tr2RaytracingMesh& mesh, Tr2RaytracingM
obj.isTransparent = false;
obj.bakedMorphOffset = bakedMorphOffset;
m_threadLocalGeometryData.local().push_back( obj );
NoteDeformedGeometry( mesh, area );
}

void Tr2RaytracingGeometry::NoteDeformedGeometry( Tr2RaytracingMesh& mesh, Tr2RaytracingMeshArea& area )
{
auto lod = mesh.GetCurrentLodData();
if( !lod )
{
return;
}
auto& lodArea = lod->m_areas[area.GetAreaIndex()];
if( lodArea.m_isSkinned || lodArea.m_isMorphed )
{
m_hasDeformedGeometry.store( true, std::memory_order_relaxed );
}
}

void Tr2RaytracingGeometry::AddGeometry( Tr2RaytracingMesh& mesh, Tr2RaytracingMeshArea& area, Tr2Material* material, const Tr2ConstantBufferAL* perObjectData, const Tr2ConstantBufferAL* vertexBufferData, const Float4x3* worldTransforms, size_t instanceCount, uint32_t bakedMorphOffset )
Expand All @@ -1052,6 +1107,7 @@ void Tr2RaytracingGeometry::AddGeometry( Tr2RaytracingMesh& mesh, Tr2RaytracingM
obj.isTransparent = false;
obj.bakedMorphOffset = bakedMorphOffset;
m_threadLocalGeometryData.local().push_back( obj );
NoteDeformedGeometry( mesh, area );
}

bool Tr2RaytracingGeometry::HasGeometry() const
Expand Down
24 changes: 24 additions & 0 deletions trinity/Raytracing/Tr2RaytracingGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "../TbbStub.h"
#include "./Tr2RingBuffer.h"

class Tr2Shader;

BLUE_DECLARE( Tr2MeshArea );
BLUE_DECLARE_VECTOR( Tr2MeshArea );

Expand Down Expand Up @@ -161,11 +163,33 @@ BLUE_CLASS( Tr2RaytracingGeometry ) :
void PrepareShaderTableDescription( Tr2RenderContext & renderContext, int32_t numRaycasters, Tr2RtShaderTableDescriptionAL** shaderTableDescs, Tr2RaytracingPipelineStateManager** pipelineManagers );
void TransformMeshes( Tr2RenderContext & renderContext );
void BuildAccelerationStructures( Tr2RenderContext & renderContext );
void NoteDeformedGeometry( Tr2RaytracingMesh & mesh, Tr2RaytracingMeshArea & area );

VtxOffsets FindOffsets( unsigned declHandle );

struct RtLibraryState
{
uint32_t handle = 0;
const Tr2EffectLibrary* lib = nullptr;
uint32_t hitGroupNamesOffset = 0;
uint32_t materialIndex = 0;
bool seen = false;
bool addsRecords = false;
};

struct RtShaderState
{
const Tr2Shader* shader = nullptr;
uint32_t techniqueIndex = 0;
uint32_t libIndex = INVALID_MATERIAL;
};

std::vector<GeometryData> m_geometryData;
Tr2EnumerableThreadSpecific<std::vector<GeometryData>> m_threadLocalGeometryData;
std::vector<RtShaderState> m_rtShaderStates;
std::vector<RtLibraryState> m_rtLibraryStates;
std::vector<BlueSharedStringW> m_rtLibraryHitGroupNames;
std::atomic<bool> m_hasDeformedGeometry{ false };
Tr2RtTopLevelAccelerationStructureAL m_tlas;

Tr2EffectPtr m_skinVerticesEffect;
Expand Down
2 changes: 1 addition & 1 deletion trinity/Raytracing/Tr2RaytracingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Tr2GpuResourcePool::Texture Tr2RaytracingManager::RenderShadows(
TRINITY_STATS_ZONE( "Create shader table" );
m_shaderTableDesc.AddRayGenShader( rayGenName.c_str() );
m_shaderTableDesc.AddMissShader( missName.c_str() );
m_shadowShaderTable.Create( m_shaderTableDesc, pipelineState, renderContext.GetPrimaryRenderContext() );
m_shadowShaderTable.Update( m_shaderTableDesc, pipelineState, renderContext.GetPrimaryRenderContext() );
}

if( !m_shadowPerFrameData.IsValid() )
Expand Down
2 changes: 1 addition & 1 deletion trinity/Tr2LightManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ Tr2GpuResourcePool::Texture Tr2LightManager::RenderRaytracedShadows(

m_Raytracing.m_shaderTableDesc.AddRayGenShader( rayGenName.c_str(), material );
m_Raytracing.m_shaderTableDesc.AddMissShader( missName.c_str(), material );
m_Raytracing.m_shaderTable.Create( m_Raytracing.m_shaderTableDesc, pipelineState, renderContext.GetPrimaryRenderContext() );
m_Raytracing.m_shaderTable.Update( m_Raytracing.m_shaderTableDesc, pipelineState, renderContext.GetPrimaryRenderContext() );
}

const uint32_t clearValue[] = { 0, 0, 0, 0 };
Expand Down
Loading
Loading