From 70f3ad1fcf6a5e29d413852677048a4826413305 Mon Sep 17 00:00:00 2001 From: JohnGreenCCP Date: Thu, 20 Aug 2026 14:29:04 +0100 Subject: [PATCH 1/5] WIP PLAT-9853: direct resource bindings (preliminary, pre-perf-tuning checkpoint) --- .../Children/EveCloudEditableVolume.cpp | 11 +- .../Children/EveCloudEditableVolume.h | 6 +- trinity/ITr2EffectValue.h | 14 +- trinity/Raytracing/Tr2RaytracingGeometry.cpp | 2 +- trinity/Raytracing/Tr2RaytracingManager.cpp | 2 +- .../Parameter/Tr2GeometryBufferParameter.cpp | 26 +- .../Parameter/Tr2GeometryBufferParameter.h | 12 +- .../Parameter/Tr2RuntimeTextureParameter.cpp | 24 +- .../Parameter/Tr2RuntimeTextureParameter.h | 12 +- .../Tr2TextureAnimationParameter.cpp | 19 +- .../Parameter/Tr2TextureAnimationParameter.h | 12 +- .../Shader/Parameter/TriTextureParameter.cpp | 16 +- .../Shader/Parameter/TriTextureParameter.h | 12 +- .../Shader/Parameter/TriVariableParameter.cpp | 21 +- .../Shader/Parameter/TriVariableParameter.h | 12 +- trinity/Shader/Tr2Effect.cpp | 15 +- trinity/Shader/Tr2EffectDescription.cpp | 27 +- trinity/Shader/Tr2EffectDescription.h | 6 +- trinity/Shader/Tr2Material.cpp | 137 +--- trinity/Shader/Tr2Material.h | 21 +- trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp | 4 + trinity/Sprite2d/Tr2Sprite2dDisplayList.h | 2 + trinity/Sprite2d/Tr2Sprite2dScene.cpp | 46 +- trinity/Tr2LightManager.cpp | 2 +- trinity/Tr2VolumetricsRenderer.cpp | 2 +- trinity/TriVariable.cpp | 38 +- trinity/TriVariable.h | 12 +- trinityal/CMakeLists.txt | 25 +- trinityal/dx11/Tr2BufferALDx11.h | 1 - trinityal/dx11/Tr2RenderContextDx11.cpp | 584 +++++++++++++---- trinityal/dx11/Tr2RenderContextDx11.h | 87 ++- trinityal/dx11/Tr2ResourceSetALDx11.cpp | 238 ------- trinityal/dx11/Tr2ResourceSetALDx11.h | 58 -- trinityal/dx11/Tr2SamplerStateALDx11.h | 1 - trinityal/dx11/Tr2ShaderProgramALDx11.h | 2 +- trinityal/dx11/Tr2TextureALDx11.h | 5 - trinityal/dx12/Tr2BufferALDx12.h | 1 - .../dx12/Tr2PrimaryRenderContextDx12.cpp | 2 +- trinityal/dx12/Tr2RenderContextDx12.cpp | 510 +++++++++++++-- trinityal/dx12/Tr2RenderContextDx12.h | 77 ++- trinityal/dx12/Tr2ResourceSetALDx12.cpp | 283 -------- trinityal/dx12/Tr2ResourceSetALDx12.h | 49 -- trinityal/dx12/Tr2SamplerStateALDx12.h | 1 - trinityal/dx12/Tr2ShaderProgramALDx12.h | 3 +- trinityal/dx12/Tr2StreamlineALDx12.h | 1 - trinityal/dx12/Tr2TextureALDx12.cpp | 3 +- trinityal/dx12/Tr2TextureALDx12.h | 2 - trinityal/dx12/upscaling/Tr2XessUpscaling.cpp | 2 +- .../dx12/util/DescriptorStateCacheDx12.cpp | 4 +- .../dx12/util/DescriptorStateCacheDx12.h | 10 +- trinityal/include/Tr2BufferAL.h | 2 - trinityal/include/Tr2RegisterMapAL.h | 28 + trinityal/include/Tr2ResourceSetAL.h | 146 ----- trinityal/include/Tr2RtPipelineStateAL.h | 2 - trinityal/include/Tr2RtShaderTableAL.h | 1 - trinityal/include/Tr2SamplerStateAL.h | 2 - trinityal/include/Tr2ShaderProgramAL.h | 2 - .../include/Tr2StaticResourceBindingsAL.h | 49 ++ trinityal/include/Tr2TextureAL.h | 2 - trinityal/include/TrinityAL.h | 3 +- .../include/upscaling/Tr2Fsr1Upscaling.h | 2 +- trinityal/metal/Tr2RenderContextMetal.h | 24 +- trinityal/metal/Tr2RenderContextMetal.mm | 83 +-- trinityal/metal/Tr2ResourceSetALMetal.h | 56 -- trinityal/metal/Tr2ResourceSetALMetal.mm | 326 ---------- trinityal/metal/Tr2RtPipelineStateALMetal.h | 1 - trinityal/metal/Tr2ShaderALMetal.h | 1 - trinityal/metal/Tr2ShaderProgramALMetal.h | 4 +- trinityal/src/Tr2RegisterMapAL.cpp | 125 ++++ trinityal/src/Tr2ResourceSetAL.cpp | 605 ------------------ trinityal/src/Tr2StaticResourceBindingsAL.cpp | 117 ++++ trinityal/src/upscaling/Tr2Fsr1Upscaling.cpp | 12 +- trinityal/stub/Tr2RenderContextStub.cpp | 42 +- trinityal/stub/Tr2RenderContextStub.h | 12 +- trinityal/stub/Tr2ResourceSetALStub.cpp | 47 -- trinityal/stub/Tr2ResourceSetALStub.h | 29 - trinityal/stub/Tr2ShaderProgramALStub.h | 2 +- trinityal/tests/Compute.cpp | 64 +- trinityal/tests/Raytracing.cpp | 71 +- trinityal/tests/Rendering.cpp | 217 ++----- 80 files changed, 1780 insertions(+), 2759 deletions(-) delete mode 100644 trinityal/dx11/Tr2ResourceSetALDx11.cpp delete mode 100644 trinityal/dx11/Tr2ResourceSetALDx11.h delete mode 100644 trinityal/dx12/Tr2ResourceSetALDx12.cpp delete mode 100644 trinityal/dx12/Tr2ResourceSetALDx12.h create mode 100644 trinityal/include/Tr2RegisterMapAL.h delete mode 100644 trinityal/include/Tr2ResourceSetAL.h create mode 100644 trinityal/include/Tr2StaticResourceBindingsAL.h delete mode 100644 trinityal/metal/Tr2ResourceSetALMetal.h delete mode 100644 trinityal/metal/Tr2ResourceSetALMetal.mm create mode 100644 trinityal/src/Tr2RegisterMapAL.cpp delete mode 100644 trinityal/src/Tr2ResourceSetAL.cpp create mode 100644 trinityal/src/Tr2StaticResourceBindingsAL.cpp delete mode 100644 trinityal/stub/Tr2ResourceSetALStub.cpp delete mode 100644 trinityal/stub/Tr2ResourceSetALStub.h diff --git a/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.cpp b/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.cpp index bbdc52061..2f7c396af 100644 --- a/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.cpp +++ b/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.cpp @@ -412,23 +412,22 @@ void EveCloudVolumeTextureParameter::RebuildEffectHandles( Tr2Shader* effectRes m_isUsedByEffect = true; } -bool EveCloudVolumeTextureParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void EveCloudVolumeTextureParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { TriTextureRes* resource = m_volume ? m_volume->GetTexture() : nullptr; bool isSrgb = ( flags & RESOURCE_FLAG_SRGB ) != 0; auto colorSpace = isSrgb ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; if( Tr2TextureAL* tex = ( resource ? resource->GetTexture() : nullptr ) ) { - - return resourceDesc.SetSrv( stage, registerIndex, *tex, colorSpace ); + renderContext.SetSrv( stage, registerIndex, *tex, colorSpace ); } else { - return resourceDesc.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( Tr2EffectResource::TEXTURE_3D, m_name.c_str() ), colorSpace ); + renderContext.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( Tr2EffectResource::TEXTURE_3D, m_name.c_str() ), colorSpace ); } } diff --git a/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.h b/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.h index 198b75f1e..cfdf6594d 100644 --- a/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.h +++ b/trinity/Eve/SpaceObject/Children/EveCloudEditableVolume.h @@ -155,11 +155,11 @@ BLUE_CLASS( EveCloudVolumeTextureParameter ) : ////////////////////////////////////////////////////////////////////////// // ITriEffectResourceParameter - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; unsigned GetHashValue( unsigned startingHash ) const; private: diff --git a/trinity/ITr2EffectValue.h b/trinity/ITr2EffectValue.h index 929f12c73..b3a31e25b 100644 --- a/trinity/ITr2EffectValue.h +++ b/trinity/ITr2EffectValue.h @@ -33,21 +33,19 @@ BLUE_INTERFACE( ITr2EffectValue ) : { } - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + virtual void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { - return false; } - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + virtual void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { - return false; } virtual void AddUsedTexture( Tr2BindlessResourcesAL & usedTextures ) const diff --git a/trinity/Raytracing/Tr2RaytracingGeometry.cpp b/trinity/Raytracing/Tr2RaytracingGeometry.cpp index 59b448999..8165b443e 100644 --- a/trinity/Raytracing/Tr2RaytracingGeometry.cpp +++ b/trinity/Raytracing/Tr2RaytracingGeometry.cpp @@ -942,8 +942,8 @@ void Tr2RaytracingGeometry::TransformMeshes( Tr2RenderContext& renderContext ) outOffset += lod->m_vertexCount; } } + renderContext.ResetResourceBindings(); #if TRINITY_PLATFORM != TRINITY_DIRECTX12 - renderContext.SetResourceSet( Tr2ResourceSetAL() ); inVbParam->SetGpuBuffer( static_cast( nullptr ) ); outVbParam->SetGpuBuffer( static_cast( nullptr ) ); #endif diff --git a/trinity/Raytracing/Tr2RaytracingManager.cpp b/trinity/Raytracing/Tr2RaytracingManager.cpp index f4efef0fb..b8a6e6048 100644 --- a/trinity/Raytracing/Tr2RaytracingManager.cpp +++ b/trinity/Raytracing/Tr2RaytracingManager.cpp @@ -166,7 +166,7 @@ Tr2GpuResourcePool::Texture Tr2RaytracingManager::RenderShadows( if( m_shadowShaderTable.IsValid() ) { - m_shadowEffect->ApplyMaterialDataForRtState( techniqueIndex, pipelineState, renderContext ); + m_shadowEffect->ApplyMaterialDataForRtState( techniqueIndex, renderContext ); renderContext.SetConstants( m_shadowPerFrameData, Tr2RenderContextEnum::COMPUTE_SHADER, 2 ); diff --git a/trinity/Shader/Parameter/Tr2GeometryBufferParameter.cpp b/trinity/Shader/Parameter/Tr2GeometryBufferParameter.cpp index 1864eadc5..7dbabcef1 100644 --- a/trinity/Shader/Parameter/Tr2GeometryBufferParameter.cpp +++ b/trinity/Shader/Parameter/Tr2GeometryBufferParameter.cpp @@ -101,40 +101,42 @@ void Tr2GeometryBufferParameter::RebuildEffectHandles( Tr2Shader* effectRes ) } // -------------------------------------------------------------------------------------- -bool Tr2GeometryBufferParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2GeometryBufferParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { if( !m_gpuBuffer ) { - return false; + return; } auto buffer = m_gpuBuffer->GetGpuBuffer( m_meshIndex ); if( !buffer ) { - return false; + return; } - return resourceDesc.SetSrv( stage, registerIndex, *buffer ); + renderContext.SetSrv( stage, registerIndex, *buffer ); } // -------------------------------------------------------------------------------------- -bool Tr2GeometryBufferParameter::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2GeometryBufferParameter::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { if( !m_gpuBuffer ) { - return resourceDesc.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); + return; } auto buffer = m_gpuBuffer->GetGpuBuffer( m_meshIndex ); if( !buffer ) { - return resourceDesc.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); + return; } - return resourceDesc.SetUav( stage, registerIndex, *buffer ); + renderContext.SetUav( stage, registerIndex, *buffer ); } // -------------------------------------------------------------------------------------- diff --git a/trinity/Shader/Parameter/Tr2GeometryBufferParameter.h b/trinity/Shader/Parameter/Tr2GeometryBufferParameter.h index fa8cc2512..b022f08da 100644 --- a/trinity/Shader/Parameter/Tr2GeometryBufferParameter.h +++ b/trinity/Shader/Parameter/Tr2GeometryBufferParameter.h @@ -31,15 +31,15 @@ BLUE_CLASS( Tr2GeometryBufferParameter ) : ////////////////////////////////////////////////////////////////////////// // ITriEffectResourceParameter - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; ///////////////////////////////////////////////////////////////////////////////////// // INotify diff --git a/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.cpp b/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.cpp index a37dd7903..85fe22058 100644 --- a/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.cpp +++ b/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.cpp @@ -20,44 +20,44 @@ bool Tr2RuntimeTextureParameter::OnModified( Be::Var* value ) { for( auto it = begin( m_materials ); it != end( m_materials ); ++it ) { - ( *it )->InvalidateResourceSets(); + ( *it )->ResourceChanged(); } } return true; } // -------------------------------------------------------------------------------------- -bool Tr2RuntimeTextureParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2RuntimeTextureParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { bool isSrgb = ( flags & RESOURCE_FLAG_SRGB ) != 0; auto colorSpace = isSrgb ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; if( Tr2TextureAL* tex = ( m_texture ? m_texture->GetTexture() : nullptr ) ) { - return resourceDesc.SetSrv( stage, registerIndex, *tex, colorSpace ); + renderContext.SetSrv( stage, registerIndex, *tex, colorSpace ); } else { - return resourceDesc.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( m_resourceType, m_name.c_str() ), colorSpace ); + renderContext.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( m_resourceType, m_name.c_str() ), colorSpace ); } } // -------------------------------------------------------------------------------------- -bool Tr2RuntimeTextureParameter::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2RuntimeTextureParameter::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { if( Tr2TextureAL* tex = ( m_texture ? m_texture->GetTexture() : nullptr ) ) { - return resourceDesc.SetUav( stage, registerIndex, *tex, m_uavMipLevel ); + renderContext.SetUav( stage, registerIndex, *tex, m_uavMipLevel ); } else { - return resourceDesc.SetUav( stage, registerIndex, Tr2TextureAL() ); + renderContext.SetUav( stage, registerIndex, Tr2TextureAL() ); } } @@ -116,7 +116,7 @@ void Tr2RuntimeTextureParameter::SetTextureProvider( ITr2TextureProvider* textur m_texture = texture; for( auto it = begin( m_materials ); it != end( m_materials ); ++it ) { - ( *it )->InvalidateResourceSets(); + ( *it )->ResourceChanged(); } } diff --git a/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.h b/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.h index 3d0541597..78150bb51 100644 --- a/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.h +++ b/trinity/Shader/Parameter/Tr2RuntimeTextureParameter.h @@ -16,15 +16,15 @@ BLUE_CLASS( Tr2RuntimeTextureParameter ) : bool OnModified( Be::Var * value ) override; - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; void AddUsedTexture( Tr2BindlessResourcesAL & usedTextures ) const override; virtual const char* GetParameterName() const; virtual void RebuildEffectHandles( Tr2Shader * effectRes ); diff --git a/trinity/Shader/Parameter/Tr2TextureAnimationParameter.cpp b/trinity/Shader/Parameter/Tr2TextureAnimationParameter.cpp index 0a535de06..1c542305a 100644 --- a/trinity/Shader/Parameter/Tr2TextureAnimationParameter.cpp +++ b/trinity/Shader/Parameter/Tr2TextureAnimationParameter.cpp @@ -19,36 +19,35 @@ bool Tr2TextureAnimationParameter::OnModified( Be::Var* value ) { for( auto it = begin( m_materials ); it != end( m_materials ); ++it ) { - ( *it )->InvalidateResourceSets(); + ( *it )->ResourceChanged(); } } return true; } -bool Tr2TextureAnimationParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2TextureAnimationParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { bool isSrgb = ( flags & RESOURCE_FLAG_SRGB ) != 0; auto colorSpace = isSrgb ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; if( m_animation ) { - return resourceDesc.SetSrv( stage, registerIndex, m_animation->GetTexture( m_channel ), colorSpace ); + renderContext.SetSrv( stage, registerIndex, m_animation->GetTexture( m_channel ), colorSpace ); } else { - return resourceDesc.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( m_resourceType, m_name.c_str() ), colorSpace ); + renderContext.SetSrv( stage, registerIndex, Tr2Renderer::GetFallbackTexture( m_resourceType, m_name.c_str() ), colorSpace ); } } -bool Tr2TextureAnimationParameter::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void Tr2TextureAnimationParameter::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { - return false; } const char* Tr2TextureAnimationParameter::GetParameterName() const diff --git a/trinity/Shader/Parameter/Tr2TextureAnimationParameter.h b/trinity/Shader/Parameter/Tr2TextureAnimationParameter.h index e03b5ef32..834482fd4 100644 --- a/trinity/Shader/Parameter/Tr2TextureAnimationParameter.h +++ b/trinity/Shader/Parameter/Tr2TextureAnimationParameter.h @@ -17,15 +17,15 @@ BLUE_CLASS( Tr2TextureAnimationParameter ) : bool OnModified( Be::Var * value ) override; - bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const override; - bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const override; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; const char* GetParameterName() const override; void RebuildEffectHandles( Tr2Shader * effectRes ) override; unsigned GetHashValue( unsigned startingHash ) const override; diff --git a/trinity/Shader/Parameter/TriTextureParameter.cpp b/trinity/Shader/Parameter/TriTextureParameter.cpp index b913d4beb..15a207043 100644 --- a/trinity/Shader/Parameter/TriTextureParameter.cpp +++ b/trinity/Shader/Parameter/TriTextureParameter.cpp @@ -174,24 +174,24 @@ void TriTextureParameter::AddUsedTexture( Tr2BindlessResourcesAL& usedTextures ) } // -------------------------------------------------------------------------------------- -bool TriTextureParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriTextureParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { bool isSrgb = ( flags & RESOURCE_FLAG_SRGB ) != 0; auto colorSpace = isSrgb ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; - return resourceDesc.SetSrv( stage, registerIndex, m_cachedTexture, colorSpace ); + renderContext.SetSrv( stage, registerIndex, m_cachedTexture, colorSpace ); } // -------------------------------------------------------------------------------------- -bool TriTextureParameter::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriTextureParameter::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { - return resourceDesc.SetUav( stage, registerIndex, m_cachedTexture, m_uavMipLevel ); + renderContext.SetUav( stage, registerIndex, m_cachedTexture, m_uavMipLevel ); } // --------------------------------------------------------------- diff --git a/trinity/Shader/Parameter/TriTextureParameter.h b/trinity/Shader/Parameter/TriTextureParameter.h index 2810e4b0b..5d147e932 100644 --- a/trinity/Shader/Parameter/TriTextureParameter.h +++ b/trinity/Shader/Parameter/TriTextureParameter.h @@ -39,15 +39,15 @@ BLUE_CLASS( TriTextureParameter ) : unsigned char* destHandle, size_t size, Tr2RenderContext& renderContext ) const override; - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; void AddUsedTexture( Tr2BindlessResourcesAL & usedTextures ) const override; unsigned GetHashValue( unsigned startingHash ) const; bool SupportsDirtyNotification() const override; diff --git a/trinity/Shader/Parameter/TriVariableParameter.cpp b/trinity/Shader/Parameter/TriVariableParameter.cpp index 31d996368..43c1fd83d 100644 --- a/trinity/Shader/Parameter/TriVariableParameter.cpp +++ b/trinity/Shader/Parameter/TriVariableParameter.cpp @@ -56,30 +56,31 @@ bool TriVariableParameter::Initialize() } // --------------------------------------------------------------- -bool TriVariableParameter::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriVariableParameter::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { if( !m_variable ) { - return false; + return; } - return m_variable->CopyToResourceSet( resourceDesc, stage, registerIndex, flags ); + m_variable->UseSRV( stage, registerIndex, flags, renderContext ); } // --------------------------------------------------------------- -bool TriVariableParameter::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriVariableParameter::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { if( m_variable ) { - return m_variable->ApplyUav( resourceDesc, stage, registerIndex ); + m_variable->UseUav( stage, registerIndex, renderContext ); + return; } - return resourceDesc.SetUav( stage, registerIndex, Tr2TextureAL() ); + renderContext.SetUav( stage, registerIndex, Tr2TextureAL() ); } void TriVariableParameter::CopyValueToEffect( Tr2RenderContextEnum::ShaderType inputType, diff --git a/trinity/Shader/Parameter/TriVariableParameter.h b/trinity/Shader/Parameter/TriVariableParameter.h index fd2bfc449..f442c81e3 100644 --- a/trinity/Shader/Parameter/TriVariableParameter.h +++ b/trinity/Shader/Parameter/TriVariableParameter.h @@ -36,15 +36,15 @@ class TriVariableParameter : public ITriEffectParameter, ///////////////////////////////////////////////////////////////////////////////////// // ITriEffectParameter ///////////////////////////////////////////////////////////////////////////////////// - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; virtual void CopyValueToEffect( Tr2RenderContextEnum::ShaderType inputType, unsigned char* destHandle, size_t size, diff --git a/trinity/Shader/Tr2Effect.cpp b/trinity/Shader/Tr2Effect.cpp index ec59b317a..be1bf87cb 100644 --- a/trinity/Shader/Tr2Effect.cpp +++ b/trinity/Shader/Tr2Effect.cpp @@ -620,13 +620,13 @@ void Tr2Effect::RebuildSamplerOverrides() USE_MAIN_THREAD_RENDER_CONTEXT(); - auto UpdateSamplers = [&]( ShaderType shaderType, const Tr2EffectStageInput& stage, Tr2ResourceSetDescriptionAL& resourceSetDesc ) { + auto UpdateSamplers = [&]( ShaderType shaderType, const Tr2EffectStageInput& stage, Tr2StaticResourceBindingsAL& staticBindings ) { bool modified = false; for( auto& samplerOverride : m_samplerOverrides ) { if( auto sampler = FindSamplerByName( stage.samplers, samplerOverride.name.c_str() ) ) { - modified |= resourceSetDesc.SetSampler( shaderType, sampler->first, samplerOverride.sampler ); + modified |= staticBindings.SetSampler( shaderType, sampler->first, samplerOverride.sampler ); } } return modified; @@ -648,7 +648,7 @@ void Tr2Effect::RebuildSamplerOverrides() continue; } - if( UpdateSamplers( ShaderType( i ), stage, pp.m_resourceSetDesc ) ) + if( UpdateSamplers( ShaderType( i ), stage, pp.m_staticBindings ) ) { pp.m_compatibleWithGdr = false; m_compatibleWithGdr = false; @@ -659,7 +659,7 @@ void Tr2Effect::RebuildSamplerOverrides() { auto& pp = *m_parametersForPasses[technique].libraries[passIx]; - UpdateSamplers( Tr2RenderContextEnum::COMPUTE_SHADER, desc.techniques[technique].libraries[passIx].globalInput, pp.m_globalResourceSetDesc ); + UpdateSamplers( Tr2RenderContextEnum::COMPUTE_SHADER, desc.techniques[technique].libraries[passIx].globalInput, pp.m_globalStaticBindings ); } } } @@ -705,9 +705,7 @@ void Tr2Effect::RebuildCachedDataInternal() { m_parametersForPasses[technique].passes[passIx].reset( CCP_NEW( "Tr2EffectPassParameters" ) Tr2EffectPassParameters() ); Tr2EffectPassParameters& pp = *m_parametersForPasses[technique].passes[passIx]; - pp.m_resourceSetDesc = desc.techniques[technique].passes[passIx].resourceSetDesc; - pp.m_resourceSetHash = 0; - pp.m_resourceSetDirty = true; + pp.m_staticBindings = desc.techniques[technique].passes[passIx].staticBindings; pp.m_compatibleWithGdr = true; uint32_t stageCount = 0; @@ -752,8 +750,7 @@ void Tr2Effect::RebuildCachedDataInternal() m_parametersForPasses[technique].libraries[libIx].reset( CCP_NEW( "Tr2EffectLibraryParameters" ) Tr2EffectLibraryParameters() ); auto& lib = *m_parametersForPasses[technique].libraries[libIx]; - lib.m_globalResourceSetDesc = desc.techniques[technique].libraries[libIx].globalResourceSetDesc; - lib.m_globalResourceSetDirty = true; + lib.m_globalStaticBindings = desc.techniques[technique].libraries[libIx].globalStaticBindings; bool compatibleWithGdr = true; //we don't care diff --git a/trinity/Shader/Tr2EffectDescription.cpp b/trinity/Shader/Tr2EffectDescription.cpp index 33b5bf635..9d2545145 100644 --- a/trinity/Shader/Tr2EffectDescription.cpp +++ b/trinity/Shader/Tr2EffectDescription.cpp @@ -516,9 +516,6 @@ bool Tr2EffectDescription::Read( const void* data, Tr2Pass& pass = techniques[technique].passes[passIx]; pass.shaderTypeMask = 0; - std::vector shaderTypes; - std::vector signatures; - for( unsigned stageIx = 0; stageIx != Tr2RenderContextEnum::SHADER_TYPE_COUNT; ++stageIx ) { pass.stageInputs[stageIx].m_exists = false; @@ -614,9 +611,6 @@ bool Tr2EffectDescription::Read( const void* data, return false; } - shaderTypes.push_back( type ); - signatures.push_back( pass.stageInputs[type].signature ); - for( auto& c : pass.stageInputs[type].constants ) { if( c.type != Tr2EffectConstant::UINT || c.dimension != 1 ) @@ -636,14 +630,13 @@ bool Tr2EffectDescription::Read( const void* data, } } - pass.resourceSetDesc = Tr2ResourceSetDescriptionAL( Tr2RegisterMapAL( shaderTypes.data(), signatures.data(), signatures.size() ) ); for( uint32_t stageIx = 0; stageIx < Tr2RenderContextEnum::SHADER_TYPE_COUNT; ++stageIx ) { if( pass.stageInputs[stageIx].m_exists ) { for( auto sampler = begin( pass.stageInputs[stageIx].samplers ); sampler != end( pass.stageInputs[stageIx].samplers ); ++sampler ) { - pass.resourceSetDesc.SetSampler( Tr2RenderContextEnum::ShaderType( stageIx ), sampler->first, sampler->second.sampler ); + pass.staticBindings.SetSampler( Tr2RenderContextEnum::ShaderType( stageIx ), sampler->first, sampler->second.sampler ); } } } @@ -710,10 +703,9 @@ bool Tr2EffectDescription::Read( const void* data, auto shaderType = Tr2RenderContextEnum::COMPUTE_SHADER; ReadRegisters( library.globalInput.signature, stream, version, shaderType ); ReadInput( library.globalInput, stream, version, shaderType, renderContext ); - library.globalResourceSetDesc = Tr2ResourceSetDescriptionAL( Tr2RegisterMapAL( &shaderType, &library.globalInput.signature, 1 ) ); for( auto sampler = begin( library.globalInput.samplers ); sampler != end( library.globalInput.samplers ); ++sampler ) { - library.globalResourceSetDesc.SetSampler( shaderType, sampler->first, sampler->second.sampler ); + library.globalStaticBindings.SetSampler( shaderType, sampler->first, sampler->second.sampler ); } ReadRegisters( library.localInput.signature, stream, version, shaderType ); @@ -764,21 +756,21 @@ bool Tr2EffectDescription::Read( const void* data, { if( IsHeapView( res.second.name ) ) { - library.globalResourceSetDesc.SetSrvHeapView( type, res.first ); + library.globalStaticBindings.SetSrvHeapView( type, res.first ); } } for( auto& res : library.globalInput.uavs ) { if( IsHeapView( res.second.name ) ) { - library.globalResourceSetDesc.SetUavHeapView( type, res.first ); + library.globalStaticBindings.SetUavHeapView( type, res.first ); } } for( auto& res : library.globalInput.samplers ) { if( IsHeapView( res.second.name ) ) { - library.globalResourceSetDesc.SetSamplerHeapView( type, res.first ); + library.globalStaticBindings.SetSamplerHeapView( type, res.first ); } } } @@ -792,26 +784,23 @@ bool Tr2EffectDescription::Read( const void* data, { for( auto& res : stage.resources ) { - auto isHeapView = IsHeapView( res.second.name ); if( IsHeapView( res.second.name ) ) { - pass.resourceSetDesc.SetSrvHeapView( Tr2RenderContextEnum::ShaderType( type ), res.first ); + pass.staticBindings.SetSrvHeapView( Tr2RenderContextEnum::ShaderType( type ), res.first ); } } for( auto& res : stage.uavs ) { - auto isHeapView = IsHeapView( res.second.name ); if( IsHeapView( res.second.name ) ) { - pass.resourceSetDesc.SetUavHeapView( Tr2RenderContextEnum::ShaderType( type ), res.first ); + pass.staticBindings.SetUavHeapView( Tr2RenderContextEnum::ShaderType( type ), res.first ); } } for( auto& sampler : stage.samplers ) { - auto isHeapView = IsHeapView( sampler.second.name ); if( IsHeapView( sampler.second.name ) ) { - pass.resourceSetDesc.SetSamplerHeapView( Tr2RenderContextEnum::ShaderType( type ), sampler.first ); + pass.staticBindings.SetSamplerHeapView( Tr2RenderContextEnum::ShaderType( type ), sampler.first ); } } } diff --git a/trinity/Shader/Tr2EffectDescription.h b/trinity/Shader/Tr2EffectDescription.h index 70f4d789a..532c415c0 100644 --- a/trinity/Shader/Tr2EffectDescription.h +++ b/trinity/Shader/Tr2EffectDescription.h @@ -7,6 +7,8 @@ #include "../Tr2IndirectDrawBuffer.h" +#include <../trinityal/include/Tr2StaticResourceBindingsAL.h> + extern const BlueSharedString DEFAULT_TECHNIQUE; extern const BlueSharedString ANY_TECHNIQUE; @@ -205,7 +207,7 @@ struct Tr2Pass unsigned int renderStates; unsigned int shaderTypeMask; unsigned int shaderProgram; - Tr2ResourceSetDescriptionAL resourceSetDesc; + Tr2StaticResourceBindingsAL staticBindings; #if TRINITY_PLATFORM == TRINITY_DIRECTX12 || TRINITY_PLATFORM == TRINITY_METAL Tr2IndirectDrawBufferLayout indirectLayout; @@ -226,7 +228,7 @@ struct Tr2EffectLibrary Tr2EffectStageInput globalInput; Tr2EffectStageInput localInput; - Tr2ResourceSetDescriptionAL globalResourceSetDesc; + Tr2StaticResourceBindingsAL globalStaticBindings; }; diff --git a/trinity/Shader/Tr2Material.cpp b/trinity/Shader/Tr2Material.cpp index b79f91723..7af042e37 100644 --- a/trinity/Shader/Tr2Material.cpp +++ b/trinity/Shader/Tr2Material.cpp @@ -9,7 +9,6 @@ #include "Include/ITriEffectParameter.h" CCP_STATS_DECLARE( effectCBLocks, "Trinity/effectCBLocks", true, CST_COUNTER_LOW, "number of CB locks for effect parameters" ); -CCP_STATS_DECLARE( effectResourceSetCreated, "Trinity/effectResourceSetCreated", true, CST_COUNTER_LOW, "number of resource sets created" ); Tr2SharedConstantBuffers g_sharedConstantBuffers; @@ -97,7 +96,7 @@ Tr2MaterialStageInput::~Tr2MaterialStageInput() } Tr2EffectLibraryParameters::Tr2EffectLibraryParameters() : - m_globalResourceSetDirty( true ) + m_usedTexturesDirty( true ) { } @@ -118,9 +117,8 @@ void Tr2EffectLibraryParameters::AddReroutable( ITriReroutable* reroutable ) Tr2EffectPassParameters::Tr2EffectPassParameters() : - m_resourceSetDirty( true ), m_compatibleWithGdr( true ), - m_resourceSetHash( 0 ) + m_usedTexturesDirty( true ) { } @@ -197,7 +195,6 @@ void Tr2MaterialStageInput::GetSharedConstantBuffer( const void* contents, uint3 Tr2Material::Tr2Material( IRoot* lockobj ) : - m_resourceSetHash( 0 ), m_compatibleWithGdr( false ) { } @@ -214,43 +211,20 @@ void Tr2Material::ApplyMaterialDataForPass( uint32_t techniqueIndex, unsigned in } unsigned mask = m_shader->GetShaderTypeMask( techniqueIndex ); auto& pp = *m_parametersForPasses[techniqueIndex].passes[passIndex]; - bool descChanged = pp.m_resourceSetDirty; + + renderContext.ResetResourceBindings(); + pp.m_staticBindings.Apply( renderContext ); + for( unsigned i = 0; i != Tr2RenderContextEnum::SHADER_TYPE_COUNT && mask; ++i ) { if( mask & ( 1 << i ) ) { - descChanged |= ApplyShaderInputs( techniqueIndex, passIndex, Tr2RenderContextEnum::ShaderType( i ), renderContext ); + auto& input = pp.m_stageInput[i]; + ApplyConstants( Tr2RenderContextEnum::ShaderType( i ), input, !pp.m_reroutedParameters.empty(), renderContext ); + SetResources( Tr2RenderContextEnum::ShaderType( i ), input, renderContext ); mask &= ~( 1 << i ); } } - - if( descChanged || !pp.m_resourceSet.IsValid() ) - { - USE_MAIN_THREAD_RENDER_CONTEXT(); - - CCP_STATS_INC( effectResourceSetCreated ); - - auto sp = renderContext.m_esm.GetShaderProgram( m_shader->GetEffect().techniques[techniqueIndex].passes[passIndex].shaderProgram ); - if( !sp ) - { - return; - } - pp.m_resourceSet.Create( pp.m_resourceSetDesc, *sp, renderContext ); - pp.m_resourceSetHash = pp.m_resourceSetDesc.ComputeHash(); - pp.m_resourceSetDirty = false; - - m_resourceSetHash = 0; - - for( auto& technique : m_parametersForPasses ) - { - for( auto& params : technique.passes ) - { - m_resourceSetHash = CcpHashFNV1( ¶ms->m_resourceSetHash, sizeof( params->m_resourceSetHash ), m_resourceSetHash ); - } - } - } - - renderContext.SetResourceSet( pp.m_resourceSet ); } void Tr2Material::ApplyMaterialDataForPassWithOverride( uint32_t techniqueIndex, unsigned int passIndex, uint32_t overrideProgram, Tr2RenderContext& renderContext ) const @@ -267,40 +241,19 @@ void Tr2Material::ApplyMaterialDataForPassWithOverride( uint32_t techniqueIndex, unsigned mask = m_shader->GetShaderTypeMask( techniqueIndex ); auto& pp = *m_parametersForPasses[techniqueIndex].passes[passIndex]; - auto resourceSetDesc = Tr2ResourceSetDescriptionAL( *sp ); + + renderContext.ResetResourceBindings(); + for( unsigned i = 0; i != Tr2RenderContextEnum::SHADER_TYPE_COUNT && mask; ++i ) { if( mask & ( 1 << i ) ) { auto& input = pp.m_stageInput[i]; ApplyConstants( Tr2RenderContextEnum::ShaderType( i ), input, !pp.m_reroutedParameters.empty(), renderContext ); - UpdateResourceSetDesc( Tr2RenderContextEnum::ShaderType( i ), input, resourceSetDesc ); + SetResources( Tr2RenderContextEnum::ShaderType( i ), input, renderContext ); mask &= ~( 1 << i ); } } - - CCP_STATS_INC( effectResourceSetCreated ); - - Tr2ResourceSetAL resourceSet; - resourceSet.Create( resourceSetDesc, *sp, renderContext.GetPrimaryRenderContext() ); - renderContext.SetResourceSet( resourceSet ); - - pp.m_resourceSetDirty = true; -} - -bool Tr2Material::ApplyShaderInputs( uint32_t techniqueIndex, unsigned int passIndex, Tr2RenderContextEnum::ShaderType shaderType, Tr2RenderContext& renderContext ) const -{ - auto& pp = *m_parametersForPasses[techniqueIndex].passes[passIndex]; - return ApplyShaderInputs( pp, shaderType, renderContext ); -} - -bool Tr2Material::ApplyShaderInputs( Tr2EffectPassParameters& pp, Tr2RenderContextEnum::ShaderType shaderType, Tr2RenderContext& renderContext ) const -{ - auto& input = pp.m_stageInput[shaderType]; - - ApplyConstants( shaderType, input, !pp.m_reroutedParameters.empty(), renderContext ); - - return UpdateResourceSetDesc( shaderType, input, pp.m_resourceSetDesc ); } void Tr2Material::ApplyConstants( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput& input, bool hasReroutables, Tr2RenderContext& renderContext ) const @@ -349,23 +302,16 @@ void Tr2Material::UpdateConstants( Tr2RenderContextEnum::ShaderType shaderType, } } -bool Tr2Material::UpdateResourceSetDesc( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput& input, Tr2ResourceSetDescriptionAL& desc ) const +void Tr2Material::SetResources( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput& input, Tr2RenderContext& renderContext ) const { - bool descChanged = false; for( auto it = input.m_textures.cbegin(); it != input.m_textures.cend(); ++it ) { - descChanged |= it->m_sourceValue->CopyToResourceSet( desc, shaderType, it->m_registerIndex, ITr2EffectValue::ResourceFlags( it->m_registerCount ) ); + it->m_sourceValue->UseSRV( shaderType, it->m_registerIndex, ITr2EffectValue::ResourceFlags( it->m_registerCount ), renderContext ); } for( auto it = input.m_uavs.cbegin(); it != input.m_uavs.cend(); ++it ) { - descChanged |= it->m_sourceValue->ApplyUav( desc, shaderType, it->m_registerIndex ); + it->m_sourceValue->UseUav( shaderType, it->m_registerIndex, renderContext ); } - return descChanged; -} - -uint64_t Tr2Material::GetSortValue() const -{ - return m_resourceSetHash; } Tr2Shader* Tr2Material::GetShaderStateInterface() const @@ -373,43 +319,12 @@ Tr2Shader* Tr2Material::GetShaderStateInterface() const return m_shader; } -Tr2EffectPassParameters* Tr2Material::GetPassDescription( uint32_t techniqueIndex, uint32_t passIndex ) -{ - return m_parametersForPasses[techniqueIndex].passes[passIndex].get(); -} - -void Tr2Material::InvalidateResourceSets() -{ - for( auto tit = begin( m_parametersForPasses ); tit != end( m_parametersForPasses ); ++tit ) - { - for( auto pit = begin( tit->passes ); pit != end( tit->passes ); ++pit ) - { - auto params = pit->get(); - params->m_resourceSet = Tr2ResourceSetAL(); - params->m_resourceSetDesc.ClearResources(); - params->m_resourceSetHash = 0; - params->m_resourceSetDirty = true; - - params->m_usedTexturesDirty = true; - } - for( auto pit = begin( tit->libraries ); pit != end( tit->libraries ); ++pit ) - { - auto params = pit->get(); - - params->m_usedTexturesDirty = true; - } - } - m_resourceSetHash = 0; -} - void Tr2Material::ResourceChanged() { for( auto& technique : m_parametersForPasses ) { for( auto& pass : technique.passes ) { - pass->m_resourceSetHash = 0; - pass->m_resourceSetDirty = true; pass->m_usedTexturesDirty = true; } for( auto& pass : technique.libraries ) @@ -417,7 +332,6 @@ void Tr2Material::ResourceChanged() pass->m_usedTexturesDirty = true; } } - m_resourceSetHash = 0; } void Tr2Material::MarkConstantBuffersDirty() @@ -446,7 +360,6 @@ void Tr2Material::MarkConstantBuffersDirty() } } } - m_resourceSetHash = 0; } void Tr2Material::UsedWithScreenSize( float screenSize, float worldRadius, const std::vector& uvDensities ) @@ -565,7 +478,7 @@ void Tr2Material::ApplyConstantBuffers( uint32_t techniqueIndex, unsigned int pa } } -void Tr2Material::ApplyMaterialDataForRtState( uint32_t techniqueIndex, const Tr2RtPipelineStateAL& rtPipelineState, Tr2RenderContext& renderContext ) const +void Tr2Material::ApplyMaterialDataForRtState( uint32_t techniqueIndex, Tr2RenderContext& renderContext ) const { if( !m_shader ) { @@ -573,19 +486,11 @@ void Tr2Material::ApplyMaterialDataForRtState( uint32_t techniqueIndex, const Tr } auto& pp = *m_parametersForPasses[techniqueIndex].libraries[0]; - ApplyConstants( Tr2RenderContextEnum::COMPUTE_SHADER, pp.m_globalInput, !pp.m_reroutedParameters.empty(), renderContext ); - - bool descChanged = pp.m_globalResourceSetDirty; - descChanged |= UpdateResourceSetDesc( Tr2RenderContextEnum::COMPUTE_SHADER, pp.m_globalInput, pp.m_globalResourceSetDesc ); + renderContext.ResetResourceBindings(); + pp.m_globalStaticBindings.Apply( renderContext ); - if( descChanged || !pp.m_globalResourceSet.IsValid() ) - { - USE_MAIN_THREAD_RENDER_CONTEXT(); - pp.m_globalResourceSet.Create( pp.m_globalResourceSetDesc, rtPipelineState, renderContext ); - pp.m_globalResourceSetDirty = false; - } - - renderContext.SetResourceSet( pp.m_globalResourceSet ); + ApplyConstants( Tr2RenderContextEnum::COMPUTE_SHADER, pp.m_globalInput, !pp.m_reroutedParameters.empty(), renderContext ); + SetResources( Tr2RenderContextEnum::COMPUTE_SHADER, pp.m_globalInput, renderContext ); } void Tr2Material::ApplyMaterialDataForRtMaterial( uint32_t techniqueIndex, Tr2RtLocalMaterialDescriptionAL& localMaterial, Tr2RenderContext& renderContext ) const diff --git a/trinity/Shader/Tr2Material.h b/trinity/Shader/Tr2Material.h index 7ca7760ec..6010fe668 100644 --- a/trinity/Shader/Tr2Material.h +++ b/trinity/Shader/Tr2Material.h @@ -138,12 +138,9 @@ class Tr2EffectPassParameters : public PassParametersOwner std::vector m_reroutedParameters; - Tr2ResourceSetDescriptionAL m_resourceSetDesc; - Tr2ResourceSetAL m_resourceSet; + Tr2StaticResourceBindingsAL m_staticBindings; std::vector m_usedResources; Tr2BindlessResourcesAL m_usedTextures; - uint32_t m_resourceSetHash; - bool m_resourceSetDirty; bool m_compatibleWithGdr; bool m_usedTexturesDirty; @@ -158,12 +155,10 @@ struct Tr2EffectLibraryParameters : public PassParametersOwner Tr2MaterialStageInput m_localInput; Tr2MaterialStageInput m_globalInput; - Tr2ResourceSetDescriptionAL m_globalResourceSetDesc; - Tr2ResourceSetAL m_globalResourceSet; + Tr2StaticResourceBindingsAL m_globalStaticBindings; std::vector m_reroutedParameters; std::vector m_usedResources; Tr2BindlessResourcesAL m_usedTextures; - bool m_globalResourceSetDirty; bool m_usedTexturesDirty; void AddUsedResource( ITr2EffectValuePtr resource ) override; @@ -211,9 +206,8 @@ BLUE_CLASS( Tr2Material ) : void ApplyMaterialDataForPass( uint32_t techniqueIndex, unsigned int passIndex, Tr2RenderContext& renderContext ) const; void ApplyMaterialDataForPassWithOverride( uint32_t techniqueIndex, unsigned int passIndex, uint32_t overrideProgram, Tr2RenderContext& renderContext ) const; - void ApplyMaterialDataForRtState( uint32_t techniqueIndex, const Tr2RtPipelineStateAL& rtPipelineState, Tr2RenderContext& renderContext ) const; + void ApplyMaterialDataForRtState( uint32_t techniqueIndex, Tr2RenderContext& renderContext ) const; void ApplyMaterialDataForRtMaterial( uint32_t techniqueIndex, Tr2RtLocalMaterialDescriptionAL& localMaterial, Tr2RenderContext& renderContext ) const; - uint64_t GetSortValue() const; Tr2Shader* GetShaderStateInterface() const; @@ -221,9 +215,6 @@ BLUE_CLASS( Tr2Material ) : { } - Tr2EffectPassParameters* GetPassDescription( uint32_t techniqueIndex, uint32_t passIndex ); - - void InvalidateResourceSets(); void ResourceChanged(); void MarkConstantBuffersDirty(); @@ -236,19 +227,15 @@ BLUE_CLASS( Tr2Material ) : void ApplyConstantBuffers( uint32_t techniqueIndex, unsigned int passIndex, Tr2IndirectDrawBufferWriter& indirectBuffer, Tr2RenderContext& renderContext ); protected: - bool ApplyShaderInputs( uint32_t techniqueIndex, unsigned int passIndex, Tr2RenderContextEnum::ShaderType shaderType, Tr2RenderContext& renderContext ) const; - bool ApplyShaderInputs( Tr2EffectPassParameters & pp, Tr2RenderContextEnum::ShaderType shaderType, Tr2RenderContext & renderContext ) const; - void ApplyConstants( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput & input, bool hasReroutables, Tr2RenderContext& renderContext ) const; void UpdateConstants( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput & input, bool hasReroutables, Tr2RenderContext& renderContext ) const; - bool UpdateResourceSetDesc( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput & input, Tr2ResourceSetDescriptionAL & desc ) const; + void SetResources( Tr2RenderContextEnum::ShaderType shaderType, Tr2MaterialStageInput & input, Tr2RenderContext & renderContext ) const; Tr2ShaderPtr m_shader; Tr2EffectTechniqueParametersVector m_parametersForPasses; Tr2EffectTechniqueParametersVector m_parametersForLibraries; std::vector m_lodTextureParameters; - mutable uint32_t m_resourceSetHash; bool m_compatibleWithGdr; }; diff --git a/trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp b/trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp index 3504c0894..013971fd6 100644 --- a/trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp +++ b/trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "Tr2Sprite2dDisplayList.h" #include "TriDevice.h" +#include "Tr2AtlasTexture.h" #include "Tr2Renderer.h" using namespace Tr2RenderContextEnum; @@ -65,6 +66,9 @@ void Tr2Sprite2dDisplayList::Entry::SubmitGeometry( Tr2RenderContext& renderCont transposedMatrixes[i] = Transpose( transformArray[i] ); } + renderContext.SetSrv( PIXEL_SHADER, textureRegisters[0], ( texture0 && texture0->GetTexture() ) ? *texture0->GetTexture() : Tr2TextureAL(), colorSpace ); + renderContext.SetSrv( PIXEL_SHADER, textureRegisters[1], ( texture1 && texture1->GetTexture() ) ? *texture1->GetTexture() : Tr2TextureAL(), colorSpace ); + FillAndSetConstants( *m_uiTransformsCb, transposedMatrixes, diff --git a/trinity/Sprite2d/Tr2Sprite2dDisplayList.h b/trinity/Sprite2d/Tr2Sprite2dDisplayList.h index c8799c2f9..6e08e587b 100644 --- a/trinity/Sprite2d/Tr2Sprite2dDisplayList.h +++ b/trinity/Sprite2d/Tr2Sprite2dDisplayList.h @@ -32,6 +32,8 @@ struct Tr2Sprite2dDisplayList : public Tr2DeviceResource Vector4 texelSize1; Tr2AtlasTexturePtr texture0; Tr2AtlasTexturePtr texture1; + uint32_t textureRegisters[2]; + Tr2RenderContextEnum::ColorSpace colorSpace; Tr2EffectPtr effect; //hardcoded due to need for CB slot//Tr2EffectConstant transformsHandle; Matrix transformArray[TR2_SS_MAX_TRANSFORM_COUNT]; diff --git a/trinity/Sprite2d/Tr2Sprite2dScene.cpp b/trinity/Sprite2d/Tr2Sprite2dScene.cpp index 29d9c2f12..09d4a6885 100644 --- a/trinity/Sprite2d/Tr2Sprite2dScene.cpp +++ b/trinity/Sprite2d/Tr2Sprite2dScene.cpp @@ -1125,27 +1125,6 @@ void Tr2Sprite2dScene::IssueDrawCall() } else { - if( auto desc = m_effect->GetPassDescription( 0, 0 ) ) - { - for( uint32_t i = 0; i < 2; ++i ) - { - Tr2TextureAL* texAL = nullptr; - if( m_texture[i] ) - { - texAL = m_texture[i]->GetTexture(); - if( !texAL ) - { - if( m_texture[i]->GetRenderTarget() ) - { - texAL = m_texture[i]->GetRenderTarget(); - } - } - } - auto colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; - desc->m_resourceSetDirty |= desc->m_resourceSetDesc.SetSrv( PIXEL_SHADER, m_textureRegisters[i], texAL ? *texAL : Tr2TextureAL(), colorSpace ); - } - } - m_drawCallStartIndex /= sizeof( uint32_t ); renderContext.m_esm.ApplyStreamSource( 0, m_vertexBuffer.GetBuffer(), vertexBufferOffset, sizeof( Tr2Sprite2dD3DVertex ) ); renderContext.m_esm.ApplyIndexBuffer( m_indexBuffer.GetBuffer() ); @@ -1175,6 +1154,24 @@ void Tr2Sprite2dScene::SubmitGeometry( Tr2RenderContext& renderContext ) transposedMatrixes[i] = Transpose( m_transformArray[i] ); } + for( uint32_t i = 0; i < 2; ++i ) + { + Tr2TextureAL* texAL = nullptr; + if( m_texture[i] ) + { + texAL = m_texture[i]->GetTexture(); + if( !texAL ) + { + if( m_texture[i]->GetRenderTarget() ) + { + texAL = m_texture[i]->GetRenderTarget(); + } + } + } + auto colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; + renderContext.SetSrv( PIXEL_SHADER, m_textureRegisters[i], texAL ? *texAL : Tr2TextureAL(), colorSpace ); + } + bool result = FillAndSetConstants( m_uiTransformsCb, transposedMatrixes, @@ -2112,10 +2109,9 @@ void Tr2Sprite2dScene::ReplayCapture( Tr2Sprite2dDisplayList* dl ) m_texelSizeVar[0] = entry.texelSize0; m_texelSizeVar[1] = entry.texelSize1; - auto desc = entry.effect->GetPassDescription( 0, 0 ); - auto colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; - desc->m_resourceSetDirty |= desc->m_resourceSetDesc.SetSrv( PIXEL_SHADER, m_textureRegisters[0], ( entry.texture0 && entry.texture0->GetTexture() ) ? *entry.texture0->GetTexture() : Tr2TextureAL(), colorSpace ); - desc->m_resourceSetDirty |= desc->m_resourceSetDesc.SetSrv( PIXEL_SHADER, m_textureRegisters[1], ( entry.texture1 && entry.texture1->GetTexture() ) ? *entry.texture1->GetTexture() : Tr2TextureAL(), colorSpace ); + entry.textureRegisters[0] = m_textureRegisters[0]; + entry.textureRegisters[1] = m_textureRegisters[1]; + entry.colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR; CCP_STATS_INC( spriteSceneDrawCallCount ); diff --git a/trinity/Tr2LightManager.cpp b/trinity/Tr2LightManager.cpp index ae20b7c3f..9e8e3a89a 100644 --- a/trinity/Tr2LightManager.cpp +++ b/trinity/Tr2LightManager.cpp @@ -912,7 +912,7 @@ Tr2GpuResourcePool::Texture Tr2LightManager::RenderRaytracedShadows( const uint32_t clearValue[] = { 0, 0, 0, 0 }; renderContext.ClearUav( destTex, 0, clearValue ); - m_Raytracing.m_effect->ApplyMaterialDataForRtState( techniqueIndex, pipelineState, renderContext ); + m_Raytracing.m_effect->ApplyMaterialDataForRtState( techniqueIndex, renderContext ); renderContext.UseAccelerationStructure( geometry->GetTLAS() ); { diff --git a/trinity/Tr2VolumetricsRenderer.cpp b/trinity/Tr2VolumetricsRenderer.cpp index 064451f31..281eddf11 100644 --- a/trinity/Tr2VolumetricsRenderer.cpp +++ b/trinity/Tr2VolumetricsRenderer.cpp @@ -730,7 +730,7 @@ Tr2GpuResourcePool::Texture Tr2VolumetricsRenderer::RenderFog( resources.rtCalculateFroxels->SetParameter( BlueSharedString( "RtFroxelOutputTexture" ), fogFroxels ); resources.rtCalculateFroxels->SetParameter( BlueSharedString( "RtShadowScene" ), raytracingGeometry ); - resources.rtCalculateFroxels->ApplyMaterialDataForRtState( techniqueIndex, pipelineState, renderContext ); + resources.rtCalculateFroxels->ApplyMaterialDataForRtState( techniqueIndex, renderContext ); renderContext.UseAccelerationStructure( raytracingGeometry->GetTLAS() ); { diff --git a/trinity/TriVariable.cpp b/trinity/TriVariable.cpp index 4db1c2902..7870e5ace 100644 --- a/trinity/TriVariable.cpp +++ b/trinity/TriVariable.cpp @@ -22,11 +22,11 @@ const Be::ClassInfo* TriVariable::ExposeToBlue() EXPOSURE_END() } -bool TriVariable::CopyToResourceSet( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriVariable::UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const + ResourceFlags flags, + Tr2RenderContext& renderContext ) const { switch( m_type ) { @@ -39,12 +39,13 @@ bool TriVariable::CopyToResourceSet( } if( tex ) { - return resourceDesc.SetSrv( stage, registerIndex, *tex, colorSpace ); + renderContext.SetSrv( stage, registerIndex, *tex, colorSpace ); } else { - return resourceDesc.SetSrv( stage, registerIndex, Tr2TextureAL(), colorSpace ); + renderContext.SetSrv( stage, registerIndex, Tr2TextureAL(), colorSpace ); } + break; } case TRIVARIABLE_GPUBUFFER: { Tr2BufferAL* buffer = nullptr; @@ -54,22 +55,23 @@ bool TriVariable::CopyToResourceSet( } if( buffer ) { - return resourceDesc.SetSrv( stage, registerIndex, *buffer ); + renderContext.SetSrv( stage, registerIndex, *buffer ); } else { - return resourceDesc.SetSrv( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetSrv( stage, registerIndex, Tr2BufferAL() ); } + break; } default: - return false; + break; } } -bool TriVariable::ApplyUav( - Tr2ResourceSetDescriptionAL& resourceDesc, +void TriVariable::UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const { switch( m_type ) { @@ -81,13 +83,13 @@ bool TriVariable::ApplyUav( } if( tex ) { - return resourceDesc.SetUav( stage, registerIndex, *tex ); + renderContext.SetUav( stage, registerIndex, *tex ); } else { - return resourceDesc.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); } - break; + return; } case TRIVARIABLE_GPUBUFFER: { Tr2BufferAL* buffer = nullptr; @@ -97,18 +99,18 @@ bool TriVariable::ApplyUav( } if( buffer ) { - return resourceDesc.SetUav( stage, registerIndex, *buffer ); + renderContext.SetUav( stage, registerIndex, *buffer ); } else { - return resourceDesc.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); } - break; + return; } default: break; } - return resourceDesc.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); } void TriVariable::CopyValueToEffect( Tr2RenderContextEnum::ShaderType inputType, diff --git a/trinity/TriVariable.h b/trinity/TriVariable.h index aa15f9852..c4d2a3fcd 100644 --- a/trinity/TriVariable.h +++ b/trinity/TriVariable.h @@ -245,15 +245,15 @@ BLUE_CLASS( TriVariable ) : return GetTypeSize(); } - virtual bool CopyToResourceSet( - Tr2ResourceSetDescriptionAL & resourceDesc, + void UseSRV( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, - ResourceFlags flags ) const; - virtual bool ApplyUav( - Tr2ResourceSetDescriptionAL & resourceDesc, + ResourceFlags flags, + Tr2RenderContext& renderContext ) const override; + void UseUav( Tr2RenderContextEnum::ShaderType stage, - uint32_t registerIndex ) const; + uint32_t registerIndex, + Tr2RenderContext& renderContext ) const override; virtual void CopyValueToEffect( Tr2RenderContextEnum::ShaderType inputType, unsigned char* destHandle, diff --git a/trinityal/CMakeLists.txt b/trinityal/CMakeLists.txt index df722a787..2e59ad954 100644 --- a/trinityal/CMakeLists.txt +++ b/trinityal/CMakeLists.txt @@ -29,12 +29,13 @@ set(PUBLIC_AL_HEADER_FILES include/Tr2OcclusionQueryAL.h include/Tr2PipelineStatsQueryAL.h include/Tr2PrimaryRenderContextAL.h + include/Tr2RegisterMapAL.h include/Tr2RenderContextAL.h include/Tr2RenderPassAL.h - include/Tr2ResourceSetAL.h include/Tr2SamplerStateAL.h include/Tr2ShaderAL.h include/Tr2ShaderProgramAL.h + include/Tr2StaticResourceBindingsAL.h include/Tr2SwapChainAL.h include/Tr2TextureAL.h include/Tr2VertexLayoutAL.h @@ -90,8 +91,6 @@ set(_SOURCES dx11/Tr2RenderContextDx11.h dx11/Tr2RenderStateEmulationDx11.cpp dx11/Tr2RenderStateEmulationDx11.h - dx11/Tr2ResourceSetALDx11.cpp - dx11/Tr2ResourceSetALDx11.h dx11/Tr2SamplerStateALDx11.cpp dx11/Tr2SamplerStateALDx11.h dx11/Tr2ShaderALDx11.cpp @@ -129,8 +128,6 @@ set(_SOURCES dx12/Tr2RenderContextDx12.h dx12/Tr2ResourceHelper.cpp dx12/Tr2ResourceHelper.h - dx12/Tr2ResourceSetALDx12.cpp - dx12/Tr2ResourceSetALDx12.h dx12/Tr2RtBottomLevelAccelerationStructureALDx12.cpp dx12/Tr2RtBottomLevelAccelerationStructureALDx12.h dx12/Tr2RtPipelineStateALDx12.cpp @@ -193,13 +190,14 @@ set(_SOURCES include/Tr2RtTopLevelAccelerationStructureAL.h include/Tr2PipelineStatsQueryAL.h include/Tr2PrimaryRenderContextAL.h + include/Tr2RegisterMapAL.h include/Tr2RenderContextAL.h include/Tr2RenderPassAL.h - include/Tr2ResourceSetAL.h include/Tr2SamplerStateAL.h include/Tr2ShaderAL.h - include/Tr2ShaderProgramAL.h - include/Tr2StreamlineAL.h + include/Tr2ShaderProgramAL.h + include/Tr2StaticResourceBindingsAL.h + include/Tr2StreamlineAL.h include/Tr2SwapChainAL.h include/Tr2TextureAL.h include/Tr2VertexLayoutAL.h @@ -239,8 +237,6 @@ set(_SOURCES metal/Tr2PrimaryRenderContextMetal.mm metal/Tr2RenderContextMetal.h metal/Tr2RenderContextMetal.mm - metal/Tr2ResourceSetALMetal.h - metal/Tr2ResourceSetALMetal.mm metal/Tr2RtBottomLevelAccelerationStructureALMetal.mm metal/Tr2RtBottomLevelAccelerationStructureALMetal.h metal/Tr2RtPipelineStateALMetal.mm @@ -273,15 +269,16 @@ set(_SOURCES src/Tr2GpuTimerAl.cpp src/Tr2OcclusionQueryAL.cpp src/Tr2PipelineStatsQueryAL.cpp - src/Tr2ResourceSetAL.cpp + src/Tr2RegisterMapAL.cpp src/Tr2RtBottomLevelAccelerationStructureAL.cpp src/Tr2RtPipelineStateAL.cpp src/Tr2RtShaderTableAL.cpp src/Tr2RtTopLevelAccelerationStructureAL.cpp src/Tr2SamplerStateAL.cpp src/Tr2ShaderAL.cpp - src/Tr2ShaderProgramAL.cpp - src/Tr2StreamlineAL.cpp + src/Tr2ShaderProgramAL.cpp + src/Tr2StaticResourceBindingsAL.cpp + src/Tr2StreamlineAL.cpp src/Tr2SwapChainAL.cpp src/Tr2TextureAL.cpp src/Tr2VertexLayoutAL.cpp @@ -304,8 +301,6 @@ set(_SOURCES stub/Tr2PrimaryRenderContextStub.h stub/Tr2RenderContextStub.cpp stub/Tr2RenderContextStub.h - stub/Tr2ResourceSetALStub.cpp - stub/Tr2ResourceSetALStub.h stub/Tr2SamplerStateALStub.cpp stub/Tr2SamplerStateALStub.h stub/Tr2ShaderALStub.cpp diff --git a/trinityal/dx11/Tr2BufferALDx11.h b/trinityal/dx11/Tr2BufferALDx11.h index 0724f8e33..5cf674400 100644 --- a/trinityal/dx11/Tr2BufferALDx11.h +++ b/trinityal/dx11/Tr2BufferALDx11.h @@ -57,7 +57,6 @@ class Tr2BufferAL : public Tr2DeviceResourceAL friend class Tr2RenderContextAL; friend class Tr2PrimaryRenderContextAL; - friend class Tr2ResourceSetAL; }; } diff --git a/trinityal/dx11/Tr2RenderContextDx11.cpp b/trinityal/dx11/Tr2RenderContextDx11.cpp index 09fa4ea73..d894e5c96 100644 --- a/trinityal/dx11/Tr2RenderContextDx11.cpp +++ b/trinityal/dx11/Tr2RenderContextDx11.cpp @@ -14,7 +14,6 @@ #include "Tr2ShaderALDx11.h" #include "Tr2HalHelperStructures.h" #include "Tr2ShaderProgramALDx11.h" -#include "Tr2ResourceSetALDx11.h" #include "Tr2BufferALDx11.h" #include "Tr2TextureALDx11.h" #include "Tr2ConstantBufferALDx11.h" @@ -763,9 +762,19 @@ struct NullContext : ID3D11DeviceContext #pragma warning( default : 4100 ) Tr2RenderContextAL::Tr2RenderContextAL() throw() : - m_topology( TOP_INVALID ), m_lastSetTopology( TOP_INVALID ), m_renderTargetHighWaterMark( 1 ), m_lastSetVertexLayoutVSHash( 0 ), m_stackDS( "Tr2RenderContextAL::m_stackDS" ), m_useReadOnlyDepthView( false ), m_isDepthReadOnly( false ), m_isSrgbRenderTarget( false ), m_previouslyHadHullShader( false ), m_events( nullptr ), m_aftermathContext( nullptr ), m_assignedUavCount( 0 ), m_assignedUavOffset( 0 ), m_assignedPsUavs( false ) + m_topology( TOP_INVALID ), m_lastSetTopology( TOP_INVALID ), m_renderTargetHighWaterMark( 1 ), m_lastSetVertexLayoutVSHash( 0 ), m_stackDS( "Tr2RenderContextAL::m_stackDS" ), m_useReadOnlyDepthView( false ), m_isDepthReadOnly( false ), m_isSrgbRenderTarget( false ), m_previouslyHadHullShader( false ), m_events( nullptr ), m_aftermathContext( nullptr ), + m_assignedUavOffset( 0 ), m_assignedUavCount( 0 ), m_assignedPsUavs( false ), m_bindingsCommitted( false ), m_bindingsSealed( false ), m_committedProgram( nullptr ) { m_dirtyFlag.mask = 0; + + m_pendingSRVs.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_pendingUAVs.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_pendingSamplers.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + memset( m_boundSrvs, 0, sizeof( m_boundSrvs ) ); + memset( m_boundSamplers, 0, sizeof( m_boundSamplers ) ); m_context.Attach( &Tr2RenderContextImpl::s_nullContext ); static_assert( D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT >= MAX_RENDER_TARGET, @@ -790,9 +799,6 @@ Tr2RenderContextAL::Tr2RenderContextAL() throw() : m_renderStateEmulation.m_currentRasterizer = defaultRasterizer; - std::fill( std::begin( m_samplerHashes ), std::end( m_samplerHashes ), 0 ); - std::fill( std::begin( m_resourceHashes ), std::end( m_resourceHashes ), 0 ); - m_allRenderStates[RS_SRGBWRITEENABLE] = 0; } @@ -825,9 +831,6 @@ void Tr2RenderContextAL::Destroy() throw() } m_secondaryDevice11 = nullptr; - m_assignedUavCount = 0; - m_assignedUavOffset = 0; - m_assignedPsUavs = false; m_secondaryDefaultBackBuffer = Tr2TextureAL(); if( m_aftermathContext ) @@ -882,10 +885,10 @@ void Tr2RenderContextAL::Destroy() throw() m_shaderProgram = Tr2ShaderProgramAL(); + DiscardResourceBindings(); + memset( m_allRenderStates, 0xff, sizeof( m_allRenderStates ) ); m_allRenderStates[RS_SRGBWRITEENABLE] = 0; - std::fill( std::begin( m_samplerHashes ), std::end( m_samplerHashes ), 0 ); - std::fill( std::begin( m_resourceHashes ), std::end( m_resourceHashes ), 0 ); } PixelFormat Tr2RenderContextAL::GetBackBufferFormat() const throw() @@ -897,30 +900,9 @@ PixelFormat Tr2RenderContextAL::GetBackBufferFormat() const throw() ALResult Tr2RenderContextAL::BeginScene() throw() { m_shaderProgram = Tr2ShaderProgramAL(); - std::fill( std::begin( m_samplerHashes ), std::end( m_samplerHashes ), 0 ); - - decltype( &ID3D11DeviceContext::VSSetShaderResources ) setResources[] = { - &ID3D11DeviceContext::VSSetShaderResources, - &ID3D11DeviceContext::PSSetShaderResources, - &ID3D11DeviceContext::CSSetShaderResources, - &ID3D11DeviceContext::GSSetShaderResources, - &ID3D11DeviceContext::HSSetShaderResources, - &ID3D11DeviceContext::DSSetShaderResources, - }; - for( uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i ) - { - ID3D11ShaderResourceView* nullSrv[TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES] = {}; - if( m_resourceHashes[i] ) - { - m_resourceHashes[i] = 0; - ( m_context->*( setResources[i] ) )( - 0, - TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES, - nullSrv ); - } - } - m_currentResourceSet = Tr2ResourceSetAL(); + UnbindShaderResources( true ); + memset( m_boundSamplers, 0, sizeof( m_boundSamplers ) ); return S_OK; } @@ -986,6 +968,7 @@ ALResult Tr2RenderContextAL::DrawIndexedPrimitive( } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawIndexed( vc, startIndex, baseVertexLocation ); return S_OK; @@ -1009,6 +992,7 @@ ALResult Tr2RenderContextAL::DrawIndexedInstanced( } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawIndexedInstanced( vc, numInstances, startIndex, 0, 0 ); return S_OK; @@ -1031,6 +1015,7 @@ ALResult Tr2RenderContextAL::DrawIndexedInstanced( } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawIndexedInstanced( indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation ); return S_OK; @@ -1052,6 +1037,7 @@ ALResult Tr2RenderContextAL::DrawInstanced( } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawInstanced( vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation ); return S_OK; @@ -1070,6 +1056,7 @@ ALResult Tr2RenderContextAL::DrawIndexedInstancedIndirect( Tr2BufferAL& params, } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawIndexedInstancedIndirect( params.m_buffer->m_buffer, offset ); return S_OK; @@ -1087,6 +1074,7 @@ ALResult Tr2RenderContextAL::DrawInstancedIndirect( Tr2BufferAL& params, uint32_ } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->DrawInstancedIndirect( params.m_buffer->m_buffer, offset ); return S_OK; @@ -1106,6 +1094,7 @@ ALResult Tr2RenderContextAL::DrawPrimitive( uint32_t startVertex, uint32_t primi } ApplyReadOnlyDepth(); + UseResourceBindings(); m_context->Draw( vc, startVertex ); return S_OK; @@ -1153,6 +1142,7 @@ ALResult Tr2RenderContextAL::RunComputeShader( unsigned groupDimX, unsigned grou { return E_FAIL; } + UseResourceBindings(); m_context->Dispatch( groupDimX, groupDimY, groupDimZ ); return S_OK; } @@ -1164,6 +1154,7 @@ ALResult Tr2RenderContextAL::RunComputeShaderIndirect( Tr2BufferAL& indirectPara return E_FAIL; } + UseResourceBindings(); m_context->DispatchIndirect( indirectParams.m_buffer->m_buffer, offset ); return S_OK; } @@ -1321,24 +1312,8 @@ ALResult Tr2RenderContextAL::Clear( ALResult Tr2RenderContextAL::SetRtDsToDevice( uint32_t changedSlot ) throw() { - m_currentResourceSet = Tr2ResourceSetAL(); - std::fill( std::begin( m_samplerHashes ), std::end( m_samplerHashes ), 0 ); - std::fill( std::begin( m_resourceHashes ), std::end( m_resourceHashes ), 0 ); - decltype( &ID3D11DeviceContext::VSSetShaderResources ) setResources[] = { - &ID3D11DeviceContext::VSSetShaderResources, - &ID3D11DeviceContext::PSSetShaderResources, - &ID3D11DeviceContext::CSSetShaderResources, - &ID3D11DeviceContext::GSSetShaderResources, - &ID3D11DeviceContext::HSSetShaderResources, - &ID3D11DeviceContext::DSSetShaderResources, - }; - - ID3D11ShaderResourceView* nullViews[16] = { nullptr }; - - for( uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i ) - { - ( m_context->*( setResources[i] ) )( 0, 16, nullViews ); - } + // A texture becoming a render target may still be bound as an SRV from an earlier draw. + UnbindShaderResources( false ); ID3D11RenderTargetView* rtViews[MAX_RENDER_TARGET]; // Follow the DX9 behavior: null means 'default backbuffer' for slot 0, and 'nothing' for everything else. @@ -1601,6 +1576,7 @@ ALResult Tr2RenderContextAL::SetShaderProgram( const Tr2ShaderProgramAL& p ) thr } m_shaderProgram = p; + m_bindingsCommitted = false; return S_OK; } @@ -1974,20 +1950,69 @@ bool Tr2RenderContextAL::ApplyRasterizerState() throw() return true; } -ALResult Tr2RenderContextAL::SetResourceSet( const Tr2ResourceSetAL& resourceSet ) throw() +// -------------------------------------------------------------------------------------- +void Tr2RenderContextAL::BeginResourceBindingBatch() throw() { - if( m_currentResourceSet.m_resourceSet == resourceSet.m_resourceSet ) + if( !m_bindingsSealed ) { - return S_OK; + return; } - m_currentResourceSet = resourceSet; + m_bindingsSealed = false; + m_bindingsCommitted = false; + + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); +} + +// -------------------------------------------------------------------------------------- +void Tr2RenderContextAL::DiscardResourceBindings() throw() +{ + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + memset( m_boundSrvs, 0, sizeof( m_boundSrvs ) ); + memset( m_boundSamplers, 0, sizeof( m_boundSamplers ) ); + m_assignedUavOffset = 0; + m_assignedUavCount = 0; + m_assignedPsUavs = false; - auto& rs = *resourceSet.m_resourceSet; + m_bindingsCommitted = false; + m_bindingsSealed = false; + m_committedProgram = nullptr; +} - if( ( rs.m_empty || !rs.m_uavCount ) && m_assignedUavCount ) +// -------------------------------------------------------------------------------------- +void Tr2RenderContextAL::UnbindShaderResources( bool unbindUavs ) throw() +{ + decltype( &ID3D11DeviceContext::VSSetShaderResources ) setResources[] = { + &ID3D11DeviceContext::VSSetShaderResources, + &ID3D11DeviceContext::PSSetShaderResources, + &ID3D11DeviceContext::CSSetShaderResources, + &ID3D11DeviceContext::GSSetShaderResources, + &ID3D11DeviceContext::HSSetShaderResources, + &ID3D11DeviceContext::DSSetShaderResources, + }; + + ID3D11ShaderResourceView* nullSrvs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + for( uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i ) { - ID3D11UnorderedAccessView* nullUAVs[TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES] = {}; + if( memcmp( m_boundSrvs[i], nullSrvs, sizeof( nullSrvs ) ) != 0 ) + { + ( m_context->*( setResources[i] ) )( 0, Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE, nullSrvs ); + memset( m_boundSrvs[i], 0, sizeof( m_boundSrvs[i] ) ); + } + } + + if( unbindUavs && m_assignedUavCount ) + { + ID3D11UnorderedAccessView* nullUavs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; if( m_assignedPsUavs ) { m_context->OMSetRenderTargetsAndUnorderedAccessViews( @@ -1996,144 +2021,427 @@ ALResult Tr2RenderContextAL::SetResourceSet( const Tr2ResourceSetAL& resourceSet nullptr, m_assignedUavOffset, m_assignedUavCount, - nullUAVs, + nullUavs, nullptr ); } else { - m_context->CSSetUnorderedAccessViews( m_assignedUavOffset, m_assignedUavCount, nullUAVs, nullptr ); + m_context->CSSetUnorderedAccessViews( m_assignedUavOffset, m_assignedUavCount, nullUavs, nullptr ); } m_assignedUavCount = 0; + m_assignedPsUavs = false; + } + + m_bindingsCommitted = false; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.colorSpace = colorSpace; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; } + BeginResourceBindingBatch(); - if( rs.m_empty ) + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.mip = mip; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::HEAP_VIEW; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::SAMPLER; + entry.sampler = sampler; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::ResetResourceBindings() throw() +{ + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + m_bindingsCommitted = false; + m_bindingsSealed = false; + m_committedProgram = nullptr; + return S_OK; +} + +// -------------------------------------------------------------------------------------- +ALResult Tr2RenderContextAL::UseResourceBindings() throw() +{ + if( !m_shaderProgram.IsValid() ) + { + return S_OK; + } + const TrinityALImpl::Tr2ShaderProgramAL& program = *m_shaderProgram.m_program; + if( m_bindingsCommitted && m_committedProgram == &program ) { return S_OK; } - decltype( &ID3D11DeviceContext::VSSetShaderResources ) setResources[] = { - &ID3D11DeviceContext::VSSetShaderResources, - &ID3D11DeviceContext::PSSetShaderResources, - &ID3D11DeviceContext::CSSetShaderResources, - &ID3D11DeviceContext::GSSetShaderResources, - &ID3D11DeviceContext::HSSetShaderResources, - &ID3D11DeviceContext::DSSetShaderResources, - }; + const auto& registerMap = program.m_registerMap; - decltype( &ID3D11DeviceContext::VSSetSamplers ) setSamplers[] = { - &ID3D11DeviceContext::VSSetSamplers, - &ID3D11DeviceContext::PSSetSamplers, - &ID3D11DeviceContext::CSSetSamplers, - &ID3D11DeviceContext::GSSetSamplers, - &ID3D11DeviceContext::HSSetSamplers, - &ID3D11DeviceContext::DSSetSamplers, - }; + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + for( const auto& resource : m_pendingSRVs ) + { + uint32_t index = registerMap.srvs[resource.stage][resource.registerIndex]; + if( index < registerMap.srvCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedSRVs[index] = &resource; + } + } + for( const auto& resource : m_pendingUAVs ) + { + uint32_t index = registerMap.uavs[resource.stage][resource.registerIndex]; + if( index < registerMap.uavCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedUAVs[index] = &resource; + } + } + for( const auto& sampler : m_pendingSamplers ) + { + uint32_t index = registerMap.samplers[sampler.stage][sampler.registerIndex]; + if( index < registerMap.samplerCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedSamplers[index] = &sampler; + } + } - if( rs.m_uavCount ) + ID3D11ShaderResourceView* desiredSrvs[SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + ID3D11SamplerState* desiredSamplers[SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + ID3D11UnorderedAccessView* desiredUavs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + uint32_t uavBegin = Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; + uint32_t uavEnd = 0; + bool csUavs = false; + + for( uint32_t stageIndex = 0; stageIndex < SHADER_TYPE_COUNT; ++stageIndex ) { - for( uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i ) + for( uint32_t registerIndex = 0; registerIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; ++registerIndex ) { - ID3D11ShaderResourceView* nullSrv[TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES] = {}; - if( m_resourceHashes[i] ) + uint32_t srvIndex = registerMap.srvs[stageIndex][registerIndex]; + if( srvIndex < registerMap.srvCount ) + { + const Resource* resource = srvIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSRVs[srvIndex] : nullptr; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::TEXTURE: + if( resource->texture.IsValid() ) + { + desiredSrvs[stageIndex][registerIndex] = resource->texture.m_texture->m_view[resource->colorSpace]; + } + break; + case Resource::BUFFER: + if( resource->buffer.IsValid() ) + { + desiredSrvs[stageIndex][registerIndex] = resource->buffer.m_buffer->m_srv; + } + break; + default: + break; + } + } + + uint32_t samplerIndex = registerMap.samplers[stageIndex][registerIndex]; + if( samplerIndex < registerMap.samplerCount ) { - m_resourceHashes[i] = 0; - ( m_context->*( setResources[i] ) )( - 0, - TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES, - nullSrv ); + const Sampler* sampler = samplerIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSamplers[samplerIndex] : nullptr; + if( sampler && sampler->type == Sampler::SAMPLER && sampler->sampler.m_sampler ) + { + desiredSamplers[stageIndex][registerIndex] = sampler->sampler.m_sampler->m_samplerState; + } + } + + uint32_t uavIndex = registerMap.uavs[stageIndex][registerIndex]; + if( uavIndex < registerMap.uavCount && + ( stageIndex == PIXEL_SHADER || stageIndex == COMPUTE_SHADER ) ) + { + const Resource* resource = uavIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedUAVs[uavIndex] : nullptr; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::TEXTURE: + if( resource->texture.IsValid() && resource->mip < resource->texture.m_texture->m_uav.size() ) + { + desiredUavs[registerIndex] = resource->texture.m_texture->m_uav[resource->mip]; + } + break; + case Resource::BUFFER: + if( resource->buffer.IsValid() ) + { + desiredUavs[registerIndex] = resource->buffer.m_buffer->m_uav; + } + break; + default: + CCP_AL_LOGWARN( "Missing UAV resource binding for register %u, stage %u", registerIndex, stageIndex ); + break; + } + uavBegin = std::min( uavBegin, registerIndex ); + uavEnd = std::max( uavEnd, registerIndex + 1 ); + csUavs = stageIndex == COMPUTE_SHADER; } } + } - if( rs.m_csUavs ) + const bool haveUavs = uavEnd > uavBegin; + + if( !haveUavs && m_assignedUavCount ) + { + ID3D11UnorderedAccessView* nullUavs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + if( m_assignedPsUavs ) + { + m_context->OMSetRenderTargetsAndUnorderedAccessViews( + D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, + nullptr, + nullptr, + m_assignedUavOffset, + m_assignedUavCount, + nullUavs, + nullptr ); + } + else + { + m_context->CSSetUnorderedAccessViews( m_assignedUavOffset, m_assignedUavCount, nullUavs, nullptr ); + } + m_assignedUavCount = 0; + m_assignedPsUavs = false; + } + + if( haveUavs ) + { + // The resources entering UAV slots may still be bound as SRVs from an earlier draw; + // release every SRV slot first so the runtime doesn't have to force-unbind them. + UnbindShaderResources( false ); + + if( csUavs ) { if( m_assignedUavCount && m_assignedPsUavs ) { - ID3D11UnorderedAccessView* nullUAVs[TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES] = {}; + ID3D11UnorderedAccessView* nullUavs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; m_context->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, m_assignedUavOffset, m_assignedUavCount, - nullUAVs, + nullUavs, nullptr ); m_assignedUavCount = 0; } - uint32_t begin, end; - if( m_assignedUavCount ) - { - begin = std::min( rs.m_uavOffset, m_assignedUavOffset ); - end = std::max( rs.m_uavOffset + rs.m_uavCount, m_assignedUavOffset + m_assignedUavCount ); - } - else - { - begin = rs.m_uavOffset; - end = rs.m_uavOffset + rs.m_uavCount; - } - m_context->CSSetUnorderedAccessViews( - begin, - end - begin, - reinterpret_cast( rs.m_uavs + begin ), - nullptr ); - m_assignedUavCount = rs.m_uavCount; - m_assignedUavOffset = rs.m_uavOffset; + uint32_t begin = m_assignedUavCount ? std::min( uavBegin, m_assignedUavOffset ) : uavBegin; + uint32_t end = m_assignedUavCount ? std::max( uavEnd, m_assignedUavOffset + m_assignedUavCount ) : uavEnd; + m_context->CSSetUnorderedAccessViews( begin, end - begin, desiredUavs + begin, nullptr ); + m_assignedUavOffset = uavBegin; + m_assignedUavCount = uavEnd - uavBegin; m_assignedPsUavs = false; } else { if( m_assignedUavCount && !m_assignedPsUavs ) { - ID3D11UnorderedAccessView* nullUAVs[TrinityALImpl::Tr2ResourceSetAL::MAX_RESOURCES] = {}; - m_context->CSSetUnorderedAccessViews( m_assignedUavOffset, m_assignedUavCount, nullUAVs, nullptr ); + ID3D11UnorderedAccessView* nullUavs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE] = {}; + m_context->CSSetUnorderedAccessViews( m_assignedUavOffset, m_assignedUavCount, nullUavs, nullptr ); m_assignedUavCount = 0; } - uint32_t begin, end; - if( m_assignedUavCount ) - { - begin = std::min( rs.m_uavOffset, m_assignedUavOffset ); - end = std::max( rs.m_uavOffset + rs.m_uavCount, m_assignedUavOffset + m_assignedUavCount ); - } - else - { - begin = rs.m_uavOffset; - end = rs.m_uavOffset + rs.m_uavCount; - } - + uint32_t begin = m_assignedUavCount ? std::min( uavBegin, m_assignedUavOffset ) : uavBegin; + uint32_t end = m_assignedUavCount ? std::max( uavEnd, m_assignedUavOffset + m_assignedUavCount ) : uavEnd; m_context->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, begin, end - begin, - reinterpret_cast( rs.m_uavs + begin ), + desiredUavs + begin, nullptr ); - m_assignedUavCount = rs.m_uavCount; - m_assignedUavOffset = rs.m_uavOffset; + m_assignedUavOffset = uavBegin; + m_assignedUavCount = uavEnd - uavBegin; m_assignedPsUavs = true; } } - for( uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i ) + decltype( &ID3D11DeviceContext::VSSetShaderResources ) setResources[] = { + &ID3D11DeviceContext::VSSetShaderResources, + &ID3D11DeviceContext::PSSetShaderResources, + &ID3D11DeviceContext::CSSetShaderResources, + &ID3D11DeviceContext::GSSetShaderResources, + &ID3D11DeviceContext::HSSetShaderResources, + &ID3D11DeviceContext::DSSetShaderResources, + }; + + decltype( &ID3D11DeviceContext::VSSetSamplers ) setSamplers[] = { + &ID3D11DeviceContext::VSSetSamplers, + &ID3D11DeviceContext::PSSetSamplers, + &ID3D11DeviceContext::CSSetSamplers, + &ID3D11DeviceContext::GSSetSamplers, + &ID3D11DeviceContext::HSSetSamplers, + &ID3D11DeviceContext::DSSetSamplers, + }; + + for( uint32_t stageIndex = 0; stageIndex < SHADER_TYPE_COUNT; ++stageIndex ) { - auto& stage = rs.m_stages[i]; - if( stage.resourceCount && stage.resourceHash != m_resourceHashes[i] ) + if( memcmp( desiredSrvs[stageIndex], m_boundSrvs[stageIndex], sizeof( desiredSrvs[stageIndex] ) ) != 0 ) { - ( m_context->*( setResources[i] ) )( - stage.resourceOffset, - stage.resourceCount, - reinterpret_cast( stage.resources + stage.resourceOffset ) ); - m_resourceHashes[i] = stage.resourceHash; + ( m_context->*( setResources[stageIndex] ) )( 0, Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE, desiredSrvs[stageIndex] ); + memcpy( m_boundSrvs[stageIndex], desiredSrvs[stageIndex], sizeof( desiredSrvs[stageIndex] ) ); } - if( stage.samplerCount && stage.samplerHash != m_samplerHashes[i] ) + // Sampler slots are capped at 16 in D3D11 (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT); binding more is invalid. + if( memcmp( desiredSamplers[stageIndex], m_boundSamplers[stageIndex], D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * sizeof( desiredSamplers[stageIndex][0] ) ) != 0 ) { - ( m_context->*( setSamplers[i] ) )( - stage.samplerOffset, - stage.samplerCount, - reinterpret_cast( stage.samplers + stage.samplerOffset ) ); - m_samplerHashes[i] = stage.samplerHash; + ( m_context->*( setSamplers[stageIndex] ) )( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, desiredSamplers[stageIndex] ); + memcpy( m_boundSamplers[stageIndex], desiredSamplers[stageIndex], D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * sizeof( desiredSamplers[stageIndex][0] ) ); } } + m_bindingsCommitted = true; + m_bindingsSealed = true; + m_committedProgram = &program; + return S_OK; } diff --git a/trinityal/dx11/Tr2RenderContextDx11.h b/trinityal/dx11/Tr2RenderContextDx11.h index b794d9e65..8d696ec27 100644 --- a/trinityal/dx11/Tr2RenderContextDx11.h +++ b/trinityal/dx11/Tr2RenderContextDx11.h @@ -5,10 +5,13 @@ #define Tr2RenderContextDx11_h_ +#include + #include "../Tr2RenderContextEnum.h" #include "../Tr2DrawUPHelper.h" #include "../include/Tr2ConstantBufferAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2BufferAL.h" +#include "../include/Tr2SamplerStateAL.h" #include "../include/Tr2TextureAL.h" #include "../include/Tr2ShaderAL.h" #include "../include/Tr2ShaderProgramAL.h" @@ -20,8 +23,7 @@ class Tr2ConstantBufferAL; struct ITr2RenderContextEvents; -class Tr2SamplerStateAL; -class Tr2BufferAL; +class Tr2RtPipelineStateAL; class Tr2RtShaderTableAL; struct Tr2Viewport; @@ -99,7 +101,16 @@ class Tr2RenderContextAL ALResult ClearUav( const Tr2TextureAL& rt, uint32_t mipLevel, const float values[4] ) throw(); ALResult ClearUav( const Tr2TextureAL& rt, uint32_t mipLevel, const uint32_t values[4] ) throw(); - ALResult SetResourceSet( const Tr2ResourceSetAL& resourceSet ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip = 0 ) throw(); + ALResult SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw(); + + ALResult ResetResourceBindings() throw(); ALResult DrawIndexedPrimitive( uint32_t numVertices, @@ -256,6 +267,66 @@ class Tr2RenderContextAL // Current shaders Tr2ShaderProgramAL m_shaderProgram; + struct Resource + { + enum Type + { + NONE, + BUFFER, + TEXTURE, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2TextureAL texture; + Tr2BufferAL buffer; + Type type = NONE; + union + { + Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR; + uint32_t mip; + }; + }; + + struct Sampler + { + enum Type + { + NONE, + SAMPLER, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2SamplerStateAL sampler; + Type type = NONE; + }; + + std::vector m_pendingSRVs; + std::vector m_pendingUAVs; + std::vector m_pendingSamplers; + + const Resource* m_sortedSRVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedUAVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Sampler* m_sortedSamplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + + ID3D11ShaderResourceView* m_boundSrvs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + ID3D11SamplerState* m_boundSamplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + uint32_t m_assignedUavOffset; + uint32_t m_assignedUavCount; + bool m_assignedPsUavs; + + bool m_bindingsCommitted; + bool m_bindingsSealed; + const TrinityALImpl::Tr2ShaderProgramAL* m_committedProgram; + + ALResult UseResourceBindings() throw(); + void BeginResourceBindingBatch() throw(); + void DiscardResourceBindings() throw(); + void UnbindShaderResources( bool unbindUavs ) throw(); + Tr2RenderContextEnum::Topology m_topology; Tr2RenderContextEnum::Topology m_lastSetTopology; // If readonly depth buffer was requested @@ -328,19 +399,11 @@ class Tr2RenderContextAL ALResult SetRtDsToDevice( uint32_t changedSlot ) throw(); private: - uint32_t m_resourceHashes[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - uint32_t m_samplerHashes[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - Tr2ResourceSetAL m_currentResourceSet; - friend class Tr2PrimaryRenderContextAL; typedef TrackableStdStack TextureStack; TrackableStdStack m_stackRT[MAX_RENDER_TARGET]; TextureStack m_stackDS; - uint32_t m_assignedUavOffset; - uint32_t m_assignedUavCount; - bool m_assignedPsUavs; - Tr2RenderContextAL( const Tr2RenderContextAL& ) /* = delete */; Tr2RenderContextAL& operator=( const Tr2RenderContextAL& ) /* = delete */; diff --git a/trinityal/dx11/Tr2ResourceSetALDx11.cpp b/trinityal/dx11/Tr2ResourceSetALDx11.cpp deleted file mode 100644 index d335a3584..000000000 --- a/trinityal/dx11/Tr2ResourceSetALDx11.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#include "StdAfx.h" - -#if TRINITY_PLATFORM == TRINITY_DIRECTX11 - -#include "Tr2ResourceSetALDx11.h" -#include "Tr2BufferALDx11.h" -#include "Tr2TextureALDx11.h" -#include "Tr2SamplerStateALDx11.h" -#include "../include/Tr2ShaderProgramAL.h" - -using namespace Tr2RenderContextEnum; - -namespace TrinityALImpl -{ -Tr2ResourceSetAL::Tr2ResourceSetAL() : - m_isValid( false ), - m_empty( true ), - m_uavCount( 0 ), - m_csUavs( false ) -{ -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& /*renderContext*/ ) -{ - Destroy(); - - if( program.GetRegisterMap() != description.m_registerMap ) - { - return E_INVALIDARG; - } - - ON_BLOCK_EXIT_WITH_UNUSED( [&] { if( !IsValid() ) Destroy(); } ); - - for( auto it = std::begin( m_stages ); it != std::end( m_stages ); ++it ) - { - it->resourceOffset = MAX_RESOURCES; - it->samplerOffset = MAX_RESOURCES; - } - bool hasPsUavs = false; - m_uavOffset = MAX_RESOURCES; - for( uint32_t stageIndex = 0; stageIndex < SHADER_TYPE_COUNT; ++stageIndex ) - { - auto& stage = m_stages[stageIndex]; - for( uint32_t registerIndex = 0; registerIndex < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++registerIndex ) - { - if( description.m_registerMap.srvs[stageIndex][registerIndex] >= description.m_registerMap.srvCount ) - { - continue; - } - auto& desc = description.m_srv[description.m_registerMap.srvs[stageIndex][registerIndex]]; - switch( desc.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - stage.resources[registerIndex] = desc.buffer.m_buffer->m_srv; - break; - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - stage.resources[registerIndex] = desc.texture.m_texture->m_view[desc.colorSpace]; - break; - case Tr2ResourceSetDescriptionAL::Resource::NONE: - continue; - default: - return E_INVALIDARG; - } - stage.resourceOffset = std::min( stage.resourceOffset, registerIndex ); - stage.resourceCount = std::max( stage.resourceCount, registerIndex + 1 ); - } - for( uint32_t registerIndex = 0; registerIndex < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++registerIndex ) - { - if( description.m_registerMap.samplers[stageIndex][registerIndex] >= description.m_registerMap.samplerCount ) - { - continue; - } - auto& desc = description.m_samplers[description.m_registerMap.samplers[stageIndex][registerIndex]]; - if( desc.type == Tr2ResourceSetDescriptionAL::Sampler::SAMPLER ) - { - stage.samplers[registerIndex] = desc.sampler.m_sampler->m_samplerState; - stage.samplerOffset = std::min( stage.samplerOffset, registerIndex ); - stage.samplerCount = std::max( stage.samplerCount, registerIndex + 1 ); - } - } - for( uint32_t registerIndex = 0; registerIndex < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++registerIndex ) - { - if( description.m_registerMap.uavs[stageIndex][registerIndex] >= description.m_registerMap.uavCount ) - { - continue; - } - auto& desc = description.m_uav[description.m_registerMap.uavs[stageIndex][registerIndex]]; - if( desc.type == Tr2ResourceSetDescriptionAL::Resource::NONE ) - { - continue; - } - if( stageIndex != PIXEL_SHADER && stageIndex != COMPUTE_SHADER ) - { - return E_INVALIDARG; - } - if( stageIndex == PIXEL_SHADER ) - { - hasPsUavs = true; - } - else if( hasPsUavs ) - { - return E_INVALIDARG; - } - switch( desc.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - m_uavs[registerIndex] = desc.buffer.m_buffer->m_uav; - m_uavCount = registerIndex + 1; - m_uavOffset = std::min( m_uavOffset, registerIndex ); - break; - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - if( desc.mip < desc.texture.m_texture->m_uav.size() ) - { - m_uavs[registerIndex] = desc.texture.m_texture->m_uav[desc.mip]; - } - else - { - m_uavs[registerIndex] = nullptr; - } - m_uavCount = registerIndex + 1; - m_uavOffset = std::min( m_uavOffset, registerIndex ); - break; - default: - return E_INVALIDARG; - } - m_csUavs = stageIndex == COMPUTE_SHADER; - } - } - - if( m_uavCount ) - { - m_empty = false; - m_uavCount -= m_uavOffset; - } - else - { - m_empty = true; - m_uavOffset = 0; - } - - for( auto it = std::begin( m_stages ); it != std::end( m_stages ); ++it ) - { - if( it->resourceCount > it->resourceOffset ) - { - it->resourceHash = 0; - for( uint32_t i = it->resourceOffset; i != it->resourceCount; ++i ) - { - it->resourceHash ^= uint32_t( reinterpret_cast( it->resources[i].p ) & 0xffffffff ) << i; - } - it->resourceCount -= it->resourceOffset; - m_empty = false; - } - else - { - it->resourceCount = 0; - it->resourceHash = 0; - } - if( it->samplerCount > it->samplerOffset ) - { - it->samplerHash = 0; - for( uint32_t i = it->samplerOffset; i != it->samplerCount; ++i ) - { - it->samplerHash ^= uint32_t( reinterpret_cast( it->samplers[i].p ) & 0xffffffff ) << i; - } - it->samplerCount -= it->samplerOffset; - m_empty = false; - } - else - { - it->samplerCount = 0; - it->samplerHash = 0; - } - } - m_isValid = true; - return S_OK; -}; - -bool Tr2ResourceSetAL::IsValid() const -{ - return m_isValid; -} - -void Tr2ResourceSetAL::Destroy() -{ - for( auto it = std::begin( m_stages ); it != std::end( m_stages ); ++it ) - { - it->Destroy(); - } - std::fill_n( m_uavs, MAX_RESOURCES, nullptr ); - m_uavCount = 0; - m_uavOffset = 0; - m_isValid = false; - m_empty = true; - m_csUavs = false; -} - -Tr2ALMemoryType Tr2ResourceSetAL::GetMemoryClass() const -{ - return AL_MEMORY_MANAGED; -} - - -Tr2ResourceSetAL::StageInput::StageInput() : - resourceCount( 0 ), - resourceOffset( 0 ), - samplerCount( 0 ), - samplerOffset( 0 ), - resourceHash( 0 ), - samplerHash( 0 ) -{ -} - -void Tr2ResourceSetAL::StageInput::Destroy() -{ - std::fill_n( resources, MAX_RESOURCES, nullptr ); - std::fill_n( samplers, MAX_RESOURCES, nullptr ); - resourceCount = 0; - samplerCount = 0; - resourceHash = 0; - samplerHash = 0; -} - -void Tr2ResourceSetAL::Describe( Tr2DeviceResourceDescriptionAL& description ) const -{ - description["type"] = "Tr2ResourceSetAL"; - description["name"] = m_name; -} - -ALResult Tr2ResourceSetAL::SetName( const char* name ) -{ - m_name = name; - return S_OK; -} -} - -#endif \ No newline at end of file diff --git a/trinityal/dx11/Tr2ResourceSetALDx11.h b/trinityal/dx11/Tr2ResourceSetALDx11.h deleted file mode 100644 index d6aa4b9e7..000000000 --- a/trinityal/dx11/Tr2ResourceSetALDx11.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#pragma once - -#if TRINITY_PLATFORM == TRINITY_DIRECTX11 - -#include "../include/Tr2ResourceSetAL.h" - -namespace TrinityALImpl -{ -class Tr2ResourceSetAL : public Tr2DeviceResourceAL -{ -public: - Tr2ResourceSetAL(); - - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ); - bool IsValid() const; - - void Destroy(); - Tr2ALMemoryType GetMemoryClass() const; - void Describe( Tr2DeviceResourceDescriptionAL& description ) const; - ALResult SetName( const char* name ); - -private: - static const uint32_t MAX_RESOURCES = 32; - - struct StageInput - { - StageInput(); - void Destroy(); - - CComPtr resources[MAX_RESOURCES]; - CComPtr samplers[MAX_RESOURCES]; - - uint32_t resourceCount; - uint32_t resourceOffset; - uint32_t samplerCount; - uint32_t samplerOffset; - uint32_t resourceHash; - uint32_t samplerHash; - }; - - StageInput m_stages[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - - CComPtr m_uavs[MAX_RESOURCES]; - uint32_t m_uavOffset; - uint32_t m_uavCount; - std::string m_name; - bool m_csUavs; - - bool m_empty; - bool m_isValid; - - friend class Tr2RenderContextAL; -}; -} - -#endif \ No newline at end of file diff --git a/trinityal/dx11/Tr2SamplerStateALDx11.h b/trinityal/dx11/Tr2SamplerStateALDx11.h index 1c7ba9257..ec7a26425 100644 --- a/trinityal/dx11/Tr2SamplerStateALDx11.h +++ b/trinityal/dx11/Tr2SamplerStateALDx11.h @@ -29,7 +29,6 @@ class Tr2SamplerStateAL : public Tr2DeviceResourceAL CComPtr m_samplerState; std::string m_name; friend class Tr2RenderContextAL; - friend class Tr2ResourceSetAL; }; } diff --git a/trinityal/dx11/Tr2ShaderProgramALDx11.h b/trinityal/dx11/Tr2ShaderProgramALDx11.h index 399fbfb8d..7b3a6885f 100644 --- a/trinityal/dx11/Tr2ShaderProgramALDx11.h +++ b/trinityal/dx11/Tr2ShaderProgramALDx11.h @@ -4,7 +4,7 @@ #include "../include/Tr2ShaderProgramAL.h" #include "../include/Tr2ShaderAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2RegisterMapAL.h" #if ( TRINITY_PLATFORM == TRINITY_DIRECTX11 ) diff --git a/trinityal/dx11/Tr2TextureALDx11.h b/trinityal/dx11/Tr2TextureALDx11.h index b655adfcc..a3881a319 100644 --- a/trinityal/dx11/Tr2TextureALDx11.h +++ b/trinityal/dx11/Tr2TextureALDx11.h @@ -14,10 +14,6 @@ #endif -namespace TrinityALImpl -{ -class Tr2ResourceSetAL; -} @@ -108,7 +104,6 @@ class Tr2TextureAL : public Tr2DeviceResourceAL friend class Tr2PrimaryRenderContextAL; friend class Tr2RenderContextAL; - friend class Tr2ResourceSetAL; }; } diff --git a/trinityal/dx12/Tr2BufferALDx12.h b/trinityal/dx12/Tr2BufferALDx12.h index 2e2e5bd51..0893edff7 100644 --- a/trinityal/dx12/Tr2BufferALDx12.h +++ b/trinityal/dx12/Tr2BufferALDx12.h @@ -65,7 +65,6 @@ class Tr2BufferAL : public Tr2DeviceResourceAL std::shared_ptr m_clearUav; friend class Tr2RenderContextAL; - friend class TrinityALImpl::Tr2ResourceSetAL; friend class TrinityALImpl::Tr2RtShaderTableAL; }; } diff --git a/trinityal/dx12/Tr2PrimaryRenderContextDx12.cpp b/trinityal/dx12/Tr2PrimaryRenderContextDx12.cpp index 7cd2567ed..d8cd1d89f 100644 --- a/trinityal/dx12/Tr2PrimaryRenderContextDx12.cpp +++ b/trinityal/dx12/Tr2PrimaryRenderContextDx12.cpp @@ -889,7 +889,7 @@ ALResult Tr2PrimaryRenderContextAL::Present() std::remove_if( begin( m_pendingPresents ), end( m_pendingPresents ), []( const PendingPresent& p ) -> bool { return !p.backBuffer.IsValid(); } ), end( m_pendingPresents ) ); - SetResourceSet( Tr2ResourceSetAL() ); + ResetResourceBindings(); { std::vector barriers; diff --git a/trinityal/dx12/Tr2RenderContextDx12.cpp b/trinityal/dx12/Tr2RenderContextDx12.cpp index dff1c56f9..c203dd2b7 100644 --- a/trinityal/dx12/Tr2RenderContextDx12.cpp +++ b/trinityal/dx12/Tr2RenderContextDx12.cpp @@ -10,11 +10,12 @@ #include "Tr2VertexLayoutALDx12.h" #include "Tr2ShaderProgramALDx12.h" #include "Tr2PrimaryRenderContextDx12.h" -#include "Tr2ResourceSetALDx12.h" +#include "Tr2SamplerStateALDx12.h" #include "Tr2RtPipelineStateALDx12.h" #include "Tr2RtShaderTableALDx12.h" #include "Utilities.h" #include "util/AmdExtDevice.h" +#include "ALLog.h" extern bool g_requestDebugMarkers; extern bool g_dredBreadcrumbsEnabled; @@ -96,9 +97,22 @@ Tr2RenderContextAL::Tr2RenderContextAL() throw() : m_separateAlphaBlendEnabled( false ), m_srgbWriteEnable( false ), m_topology( Tr2RenderContextEnum::TOP_TRIANGLES ), - m_uavBarriersDisabledCounter( 0 ) + m_uavBarriersDisabledCounter( 0 ), + m_bindingsCommitted( false ), + m_bindingsSealed( false ), + m_committedRootSignature( nullptr ) { std::fill( std::begin( m_vertexBuffers ), std::end( m_vertexBuffers ), VB() ); + + m_pendingSRVs.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_pendingUAVs.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_pendingSamplers.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_outTransitions.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + m_usedResources.reserve( Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); } Tr2RenderContextAL::~Tr2RenderContextAL() throw() @@ -114,6 +128,8 @@ void Tr2RenderContextAL::Destroy() throw() m_ownerDevice->UnRegisterFromCrashTracker( m_commandList2 ); } + DiscardResourceBindings(); + ResetDx12(); m_descriptorCache.clear(); @@ -329,6 +345,7 @@ ALResult Tr2RenderContextAL::SetShaderProgram( const Tr2ShaderProgramAL& shader { m_psoDescription.m_shaderProgram = shader; m_dirtyPso = true; + m_bindingsCommitted = false; } return S_OK; } @@ -491,40 +508,217 @@ ALResult Tr2RenderContextAL::SetRenderStates( const uint32_t* stateValuePairs, u return S_OK; } -ALResult Tr2RenderContextAL::SetResourceSet( const Tr2ResourceSetAL& resourceSet ) throw() +void Tr2RenderContextAL::BeginResourceBindingBatch() throw() { - if( m_resourceSet.IsValid() && !m_resourceSet.m_resourceSet->m_outTransitions.empty() ) + if( !m_bindingsSealed ) { - ResourceBarrierDx12( m_resourceSet.m_resourceSet->m_outTransitions.size(), m_resourceSet.m_resourceSet->m_outTransitions.data() ); + return; } - m_resourceSet = resourceSet; - if( !m_resourceSet.IsValid() ) + + m_bindingsSealed = false; + m_bindingsCommitted = false; + + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + if( !m_outTransitions.empty() ) { - return S_OK; + ResourceBarrierDx12( m_outTransitions.size(), m_outTransitions.data() ); + m_outTransitions.clear(); } - auto rs = resourceSet.m_resourceSet.get(); - if( !rs->m_inTransitions.empty() ) + m_usedResources.clear(); +} + +void Tr2RenderContextAL::DiscardResourceBindings() throw() +{ + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + m_outTransitions.clear(); + m_usedResources.clear(); + + m_bindingsCommitted = false; + m_bindingsSealed = false; + m_committedRootSignature = nullptr; +} + +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) { - ResourceBarrierDx12( rs->m_inTransitions.size(), rs->m_inTransitions.data() ); + return E_INVALIDARG; } + BeginResourceBindingBatch(); - uint32_t bufferIndex = GetPrimaryRenderContextPointer()->GetCurrentBackBufferIndex(); - m_descriptorCache[bufferIndex]->SetSamplers( 0, rs->m_samplerCount, rs->m_sampler ); + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} - // Because SRVs and UAVs are stacked in the resource slots, this will filter them out into the correct heap setup calls - // It's not great, but if the system is changed in the future to separate SRVs and UAVs then this is an easy change - for( uint32_t idx = 0; idx < rs->m_resourceCount; ++idx ) +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) { - if( ( rs->m_srvMask & ( 1 << idx ) ) != 0 ) - { - m_descriptorCache[bufferIndex]->SetShaderResources( idx, 1, &rs->m_srv[idx] ); - } - else if( ( rs->m_uavMask & ( 1 << idx ) ) != 0 ) - { - m_descriptorCache[bufferIndex]->SetUnorderedAccessViews( idx, 1, &rs->m_uav[idx] ); - } + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.colorSpace = colorSpace; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.mip = mip; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::SAMPLER; + entry.sampler = sampler; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() +{ + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::HEAP_VIEW; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; + return S_OK; +} + +ALResult Tr2RenderContextAL::ResetResourceBindings() throw() +{ + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + if( !m_outTransitions.empty() ) + { + ResourceBarrierDx12( m_outTransitions.size(), m_outTransitions.data() ); + m_outTransitions.clear(); } + m_usedResources.clear(); + m_bindingsCommitted = false; + m_bindingsSealed = false; + m_committedRootSignature = nullptr; return S_OK; } @@ -747,6 +941,7 @@ ALResult Tr2RenderContextAL::DispatchRays( Tr2RtPipelineStateAL& pipeline, Tr2Rt m_commandList->SetComputeRootSignature( p->GetGlobalRootSignature().m_rootSignature ); uint32_t bufferIndex = m_ownerDevice->GetCurrentBackBufferIndex(); + UseResourceBindings( p->GetGlobalRootSignature() ); m_descriptorCache[bufferIndex]->Commit( m_commandList, GetPrimaryRenderContextPointer()->GetGlobalSrvUavHeap(), GetPrimaryRenderContextPointer()->GetGlobalSamplerHeap(), &pipeline.TrinityALImpl_GetObject()->GetGlobalRootSignature() ); FlushComputeBarriersDx12(); @@ -807,8 +1002,231 @@ ID3D12PipelineState* Tr2RenderContextAL::GetPipelineState() return pipelineState; } +ALResult Tr2RenderContextAL::UseResourceBindings() throw() +{ + if( !m_psoDescription.m_shaderProgram.IsValid() ) + { + return S_OK; + } + return UseResourceBindings( m_psoDescription.m_shaderProgram.m_program->m_rootSignature ); +} + +ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSignatureAL& rootSignature ) throw() +{ + if( m_bindingsCommitted && m_committedRootSignature == &rootSignature ) + { + return S_OK; + } + + Tr2PrimaryRenderContextAL& renderContext = GetPrimaryRenderContext(); + auto& registerMap = rootSignature.m_registerMap; + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + for( const auto& resource : m_pendingSRVs ) + { + uint32_t index = registerMap.srvs[resource.stage][resource.registerIndex]; + if( index < registerMap.srvCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedSRVs[index] = &resource; + } + } + for( const auto& resource : m_pendingUAVs ) + { + uint32_t index = registerMap.uavs[resource.stage][resource.registerIndex]; + if( index < registerMap.uavCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedUAVs[index] = &resource; + } + } + for( const auto& sampler : m_pendingSamplers ) + { + uint32_t index = registerMap.samplers[sampler.stage][sampler.registerIndex]; + if( index < registerMap.samplerCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + m_sortedSamplers[index] = &sampler; + } + } + + if( !m_outTransitions.empty() ) + { + ResourceBarrierDx12( m_outTransitions.size(), m_outTransitions.data() ); + m_outTransitions.clear(); + } + m_usedResources.clear(); + + D3D12_RESOURCE_BARRIER inTransitions[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + ID3D12Resource* transitioned[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + uint32_t inCount = 0; + uint32_t transitionedCount = 0; + + auto AddTransition = [&]( ID3D12Resource* res, D3D12_RESOURCE_STATES defaultState, D3D12_RESOURCE_STATES expectedState ) { + // TODO: verify state + if( ( defaultState & expectedState ) == 0 && defaultState != D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE ) + { + auto found = std::find( transitioned, transitioned + transitionedCount, res ); + if( found == transitioned + transitionedCount && transitionedCount < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + inTransitions[inCount++] = TrinityALImpl::Transition( res, defaultState, expectedState ); + m_outTransitions.push_back( TrinityALImpl::Transition( res, expectedState, defaultState ) ); + transitioned[transitionedCount++] = res; + } + } + m_usedResources.push_back( res ); + }; + + uint32_t bufferIndex = GetPrimaryRenderContextPointer()->GetCurrentBackBufferIndex(); + + for( const auto& reg : rootSignature.m_srvRegisters ) + { + uint32_t mapIndex = registerMap.srvs[reg.stage][reg.index]; + const Resource* resource = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSRVs[mapIndex] : nullptr; + auto stateFlag = reg.stage == Tr2RenderContextEnum::PIXEL_SHADER ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + + std::shared_ptr srv; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::TEXTURE: + if( resource->texture.IsValid() && reg.registerType >= Tr2ShaderRegisterAL::SRV_TEXTURE1D ) + { + srv = resource->texture.m_texture->m_view[resource->colorSpace]; + } + if( !srv ) + { + srv = renderContext.GetNullSrvDx12( reg.registerType ); + } + else + { + AddTransition( resource->texture.m_texture->GetResourceDx12(), resource->texture.m_texture->m_defaultState, stateFlag ); + } + break; + case Resource::BUFFER: + if( resource->buffer.IsValid() && reg.registerType <= Tr2ShaderRegisterAL::SRV_STRUCTURED_BUFFER ) + { + srv = resource->buffer.m_buffer->m_srv; + } + if( !srv ) + { + srv = renderContext.GetNullSrvDx12( reg.registerType ); + } + else + { + AddTransition( resource->buffer.m_buffer->GetGpuResource(), resource->buffer.m_buffer->m_defaultState, stateFlag ); + } + break; + case Resource::HEAP_VIEW: + srv = renderContext.GetSrvHeapView(); + break; + default: + srv = renderContext.GetNullSrvDx12( reg.registerType ); + break; + } + + if( srv ) + { + m_descriptorCache[bufferIndex]->SetShaderResources( reg.parameter, 1, &srv ); + } + } + + for( const auto& reg : rootSignature.m_uavRegisters ) + { + uint32_t mapIndex = registerMap.uavs[reg.stage][reg.index]; + const Resource* resource = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedUAVs[mapIndex] : nullptr; + + std::shared_ptr uav; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::TEXTURE: + if( resource->texture.IsValid() ) + { + if( reg.registerType >= Tr2ShaderRegisterAL::UAV_TEXTURE1D ) + { + uav = resource->texture.m_texture->m_uav[resource->mip]; + } + if( !uav ) + { + uav = renderContext.GetNullUavDx12( reg.registerType ); + } + else + { + AddTransition( resource->texture.m_texture->GetResourceDx12(), resource->texture.m_texture->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); + } + } + break; + case Resource::BUFFER: + if( resource->buffer.IsValid() ) + { + if( reg.registerType <= Tr2ShaderRegisterAL::UAV_STRUCTURED_BUFFER ) + { + uav = resource->buffer.m_buffer->m_uav; + } + if( !uav ) + { + uav = renderContext.GetNullUavDx12( reg.registerType ); + } + else + { + AddTransition( resource->buffer.m_buffer->GetGpuResource(), resource->buffer.m_buffer->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); + } + } + break; + case Resource::HEAP_VIEW: + uav = renderContext.GetUavHeapView(); + break; + default: + CCP_AL_LOGWARN( "Missing UAV resource binding for register %u, stage %u", reg.index, reg.stage ); + uav = renderContext.GetNullUavDx12( reg.registerType ); + break; + } + + if( uav ) + { + m_descriptorCache[bufferIndex]->SetUnorderedAccessViews( reg.parameter, 1, &uav ); + } + } + + std::shared_ptr samplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + uint32_t samplerCount = 0; + + for( const auto& reg : rootSignature.m_samplerRegisters ) + { + uint32_t mapIndex = registerMap.samplers[reg.stage][reg.index]; + const Sampler* sampler = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSamplers[mapIndex] : nullptr; + + switch( sampler ? sampler->type : Sampler::NONE ) + { + case Sampler::SAMPLER: + samplers[reg.parameter] = sampler->sampler.m_sampler->m_samplerState; + break; + case Sampler::HEAP_VIEW: + samplers[reg.parameter] = renderContext.GetSamplerHeapView(); + break; + default: + samplers[reg.parameter] = renderContext.GetNullSamplerDx12(); + break; + } + samplerCount = std::max( reg.parameter + 1, samplerCount ); + } + + m_descriptorCache[bufferIndex]->SetSamplers( 0, samplerCount, samplers ); + + if( inCount ) + { + ResourceBarrierDx12( inCount, inTransitions ); + } + + m_bindingsCommitted = true; + m_bindingsSealed = true; + m_committedRootSignature = &rootSignature; + return S_OK; +} + ALResult Tr2RenderContextAL::SetAllState() { + UseResourceBindings(); + if( ( m_dynamicVBs & m_psoDescription.m_vertexStreamMask ) != 0 ) { D3D12_VERTEX_BUFFER_VIEW vb[4]; @@ -886,8 +1304,8 @@ void Tr2RenderContextAL::FlushGraphicsBarriersDx12( ID3D12Resource* resource ) return; } size_t count = 0; - // resource + m_boundRenderTargets + m_boundDepthStencil + m_vertexBuffers + m_indexBuffer + m_resourceSet - ID3D12Resource* resources[1 + RENDER_TARGET_COUNT + 1 + 4 + 1 + Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; + // resource + m_boundRenderTargets + m_boundDepthStencil + m_vertexBuffers + m_indexBuffer + m_usedResources + ID3D12Resource* resources[1 + RENDER_TARGET_COUNT + 1 + 4 + 1 + 2 * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; if( resource ) { @@ -916,10 +1334,10 @@ void Tr2RenderContextAL::FlushGraphicsBarriersDx12( ID3D12Resource* resource ) resources[count++] = m_indexBuffer.m_buffer->m_buffer.GetResource(); } - if( m_resourceSet.IsValid() ) + if( !m_usedResources.empty() ) { - std::copy( begin( m_resourceSet.m_resourceSet->m_usedResources ), end( m_resourceSet.m_resourceSet->m_usedResources ), resources + count ); - count += m_resourceSet.m_resourceSet->m_usedResources.size(); + std::copy( begin( m_usedResources ), end( m_usedResources ), resources + count ); + count += m_usedResources.size(); } FlushBarriersDx12( count, resources ); @@ -931,25 +1349,22 @@ void Tr2RenderContextAL::FlushComputeBarriersDx12( ID3D12Resource* resource ) { return; } - if( !resource ) - { - if( m_resourceSet.IsValid() && !m_resourceSet.m_resourceSet->m_usedResources.empty() ) - { - FlushBarriersDx12( m_resourceSet.m_resourceSet->m_usedResources.size(), m_resourceSet.m_resourceSet->m_usedResources.data() ); - } - } - else + size_t count = 0; + ID3D12Resource* resources[1 + 2 * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + + if( resource ) { - size_t count = 0; - ID3D12Resource* resources[1 + Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; resources[count++] = resource; + } - if( m_resourceSet.IsValid() && !m_resourceSet.m_resourceSet->m_usedResources.empty() ) - { - std::copy( begin( m_resourceSet.m_resourceSet->m_usedResources ), end( m_resourceSet.m_resourceSet->m_usedResources ), resources + count ); - count += m_resourceSet.m_resourceSet->m_usedResources.size(); - } + if( !m_usedResources.empty() ) + { + std::copy( begin( m_usedResources ), end( m_usedResources ), resources + count ); + count += m_usedResources.size(); + } + if( count ) + { FlushBarriersDx12( count, resources ); } } @@ -1536,10 +1951,7 @@ bool Tr2RenderContextAL::IsBoundDx12( const TrinityALImpl::Tr2TextureAL& texture void Tr2RenderContextAL::ResetDx12() { - if( m_resourceSet.IsValid() && !m_resourceSet.m_resourceSet->m_outTransitions.empty() ) - { - ResourceBarrierDx12( m_resourceSet.m_resourceSet->m_outTransitions.size(), m_resourceSet.m_resourceSet->m_outTransitions.data() ); - } + ResetResourceBindings(); for( uint32_t i = 0; i < 4; ++i ) { @@ -1549,8 +1961,6 @@ void Tr2RenderContextAL::ResetDx12() m_indexBuffer = Tr2BufferAL(); m_dynamicIB = false; - m_resourceSet = Tr2ResourceSetAL(); - m_psoDescription = TrinityALImpl::PSODescription(); m_topology = Tr2RenderContextEnum::TOP_INVALID; m_primitiveToVertexCount = std::make_pair( 0, 0 ); diff --git a/trinityal/dx12/Tr2RenderContextDx12.h b/trinityal/dx12/Tr2RenderContextDx12.h index 00e910a48..e9d639d9a 100644 --- a/trinityal/dx12/Tr2RenderContextDx12.h +++ b/trinityal/dx12/Tr2RenderContextDx12.h @@ -7,7 +7,9 @@ #include "../Tr2RenderContextEnum.h" #include "../Tr2DrawUPHelper.h" #include "../include/Tr2ConstantBufferAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2BufferAL.h" +#include "../include/Tr2RegisterMapAL.h" +#include "../include/Tr2SamplerStateAL.h" #include "../include/Tr2TextureAL.h" #include "../include/Tr2ShaderProgramAL.h" #include "../include/Tr2VertexLayoutAL.h" @@ -23,9 +25,8 @@ class Tr2ConstantBufferAL; struct ITr2RenderContextEvents; class Tr2ShaderAL; -class Tr2SamplerStateAL; -class Tr2BufferAL; class Tr2RtShaderTableAL; +class Tr2RtPipelineStateAL; struct Tr2Viewport; @@ -91,7 +92,16 @@ class Tr2RenderContextAL ALResult SetVertexLayout( const Tr2VertexLayoutAL& layout ) throw(); ALResult SetShaderProgram( const Tr2ShaderProgramAL& shader ) throw(); - ALResult SetResourceSet( const Tr2ResourceSetAL& resourceSet ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip = 0 ) throw(); + ALResult SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw(); + + ALResult ResetResourceBindings() throw(); ALResult DrawIndexedPrimitive( uint32_t numVertices, @@ -235,6 +245,11 @@ class Tr2RenderContextAL ALResult SetAllState(); protected: + ALResult UseResourceBindings() throw(); + ALResult UseResourceBindings( const TrinityALImpl::Tr2RootSignatureAL& rootSignature ) throw(); + void BeginResourceBindingBatch() throw(); + void DiscardResourceBindings() throw(); + ID3D12PipelineState* GetPipelineState(); /** Forcibly reset and dirty all descriptor caches (used for explicit synchronization) */ @@ -261,8 +276,60 @@ class Tr2RenderContextAL std::pair m_primitiveToVertexCount; - Tr2ResourceSetAL m_resourceSet; +private: + struct Resource + { + enum Type + { + NONE, + BUFFER, + TEXTURE, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2TextureAL texture; + Tr2BufferAL buffer; + Type type = NONE; + union + { + Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR; + uint32_t mip; + }; + }; + struct Sampler + { + enum Type + { + NONE, + SAMPLER, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2SamplerStateAL sampler; + Type type = NONE; + }; + + std::vector m_pendingSRVs; + std::vector m_pendingUAVs; + std::vector m_pendingSamplers; + + const Resource* m_sortedSRVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedUAVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Sampler* m_sortedSamplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + + std::vector m_outTransitions; + std::vector m_usedResources; + + bool m_bindingsCommitted; + bool m_bindingsSealed; + const TrinityALImpl::Tr2RootSignatureAL* m_committedRootSignature; + +protected: bool GetRenderTargetHandles( D3D12_CPU_DESCRIPTOR_HANDLE* handles, uint32_t& count ); public: diff --git a/trinityal/dx12/Tr2ResourceSetALDx12.cpp b/trinityal/dx12/Tr2ResourceSetALDx12.cpp deleted file mode 100644 index 08fc52f84..000000000 --- a/trinityal/dx12/Tr2ResourceSetALDx12.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright © 2019 CCP ehf. - -#include "StdAfx.h" - -#if TRINITY_PLATFORM == TRINITY_DIRECTX12 - -#include "Tr2ResourceSetALDx12.h" -#include "Tr2PrimaryRenderContextDx12.h" -#include "Tr2ShaderProgramALDx12.h" -#include "Tr2BufferALDx12.h" -#include "Tr2TextureALDx12.h" -#include "Tr2SamplerStateALDx12.h" -#include "Tr2RtPipelineStateALDx12.h" -#include "Utilities.h" -#include "ALLog.h" - -using namespace Tr2RenderContextEnum; - -namespace -{ -D3D12_CPU_DESCRIPTOR_HANDLE operator+( const D3D12_CPU_DESCRIPTOR_HANDLE& handle, uint32_t offset ) -{ - D3D12_CPU_DESCRIPTOR_HANDLE result = { handle.ptr + offset }; - return result; -} -} - -namespace TrinityALImpl -{ -Tr2ResourceSetAL::Tr2ResourceSetAL() : - m_owner( nullptr ), - m_samplerCount( 0 ), - m_resourceCount( 0 ), - m_srvMask( 0 ), - m_uavMask( 0 ) -{ -} - -Tr2ResourceSetAL::~Tr2ResourceSetAL() -{ - Destroy(); -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ) -{ - Destroy(); - - if( !renderContext.IsValid() ) - { - return E_INVALIDARG; - } - if( !program.IsValid() ) - { - return E_INVALIDARG; - } - - return Create( description, program.m_program->m_rootSignature, renderContext, program.m_program->m_name.c_str() ); -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2RtPipelineStateAL& pipeline, Tr2PrimaryRenderContextAL& renderContext ) -{ - Destroy(); - - if( !renderContext.IsValid() ) - { - return E_INVALIDARG; - } - if( !pipeline.IsValid() ) - { - return E_INVALIDARG; - } - - return Create( description, pipeline.TrinityALImpl_GetObject()->GetGlobalRootSignature(), renderContext, "RtPipeline" ); -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const Tr2RootSignatureAL& rootSignature, Tr2PrimaryRenderContextAL& renderContext, const char* shaderName ) -{ - if( rootSignature.m_registerMap != description.m_registerMap ) - { - return E_INVALIDARG; - } - - std::vector transitioned; - - auto AddTransition = [&]( ID3D12Resource* res, D3D12_RESOURCE_STATES defaultState, D3D12_RESOURCE_STATES expectedState ) { - // TODO: verify state - if( ( defaultState & expectedState ) == 0 && defaultState != D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE ) - { - auto found = std::find( begin( transitioned ), end( transitioned ), res ); - if( found == transitioned.end() ) - { - m_inTransitions.push_back( Transition( res, defaultState, expectedState ) ); - m_outTransitions.push_back( Transition( res, expectedState, defaultState ) ); - transitioned.push_back( res ); - } - } - m_usedResources.push_back( res ); - }; - - for( auto it = begin( rootSignature.m_srvRegisters ); it != end( rootSignature.m_srvRegisters ); ++it ) - { - auto& reg = *it; - auto& resource = description.m_srv[description.m_registerMap.srvs[reg.stage][reg.index]]; - auto stateFlag = reg.stage == PIXEL_SHADER ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; - m_resourceCount = std::max( reg.parameter + 1, m_resourceCount ); - m_srvMask |= 1 << reg.parameter; - switch( resource.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - if( resource.texture.IsValid() && it->registerType >= Tr2ShaderRegisterAL::SRV_TEXTURE1D ) - { - m_srv[reg.parameter] = resource.texture.m_texture->m_view[resource.colorSpace]; - } - else - { - m_srv[reg.parameter] = nullptr; - } - if( !m_srv[reg.parameter] ) - { - m_srv[reg.parameter] = renderContext.GetNullSrvDx12( it->registerType ); - } - else - { - AddTransition( resource.texture.m_texture->GetResourceDx12(), resource.texture.m_texture->m_defaultState, stateFlag ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - if( resource.buffer.IsValid() && it->registerType <= Tr2ShaderRegisterAL::SRV_STRUCTURED_BUFFER ) - { - m_srv[reg.parameter] = resource.buffer.m_buffer->m_srv; - } - else - { - m_srv[reg.parameter] = nullptr; - } - if( !m_srv[reg.parameter] ) - { - m_srv[reg.parameter] = renderContext.GetNullSrvDx12( it->registerType ); - } - else - { - AddTransition( resource.buffer.m_buffer->GetGpuResource(), resource.buffer.m_buffer->m_defaultState, stateFlag ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::HEAP_VIEW: - m_srv[reg.parameter] = renderContext.GetSrvHeapView(); - break; - default: - m_srv[reg.parameter] = renderContext.GetNullSrvDx12( it->registerType ); - break; - } - } - - for( auto it = begin( rootSignature.m_uavRegisters ); it != end( rootSignature.m_uavRegisters ); ++it ) - { - auto& reg = *it; - auto& resource = description.m_uav[description.m_registerMap.uavs[reg.stage][reg.index]]; - m_resourceCount = std::max( reg.parameter + 1, m_resourceCount ); - m_uavMask |= 1 << reg.parameter; - switch( resource.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - if( resource.texture.IsValid() ) - { - if( resource.texture.IsValid() && it->registerType >= Tr2ShaderRegisterAL::UAV_TEXTURE1D ) - { - m_uav[reg.parameter] = resource.texture.m_texture->m_uav[resource.mip]; - } - else - { - m_uav[reg.parameter] = nullptr; - } - if( !m_uav[reg.parameter] ) - { - m_uav[reg.parameter] = renderContext.GetNullUavDx12( it->registerType ); - } - else - { - AddTransition( resource.texture.m_texture->GetResourceDx12(), resource.texture.m_texture->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); - } - } - break; - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - if( resource.buffer.IsValid() ) - { - if( resource.buffer.IsValid() && it->registerType <= Tr2ShaderRegisterAL::UAV_STRUCTURED_BUFFER ) - { - m_uav[reg.parameter] = resource.buffer.m_buffer->m_uav; - } - else - { - m_uav[reg.parameter] = nullptr; - } - if( !m_uav[reg.parameter] ) - { - m_uav[reg.parameter] = renderContext.GetNullUavDx12( it->registerType ); - } - else - { - AddTransition( resource.buffer.m_buffer->GetGpuResource(), resource.buffer.m_buffer->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); - } - } - break; - case Tr2ResourceSetDescriptionAL::Resource::HEAP_VIEW: - m_uav[reg.parameter] = renderContext.GetUavHeapView(); - break; - default: - CCP_AL_LOGWARN( "Missing UAV resource in resource set for register %u, stage %u, shader '%s'", reg.index, reg.stage, shaderName ); - m_uav[reg.parameter] = renderContext.GetNullUavDx12( it->registerType ); - break; - } - } - - for( auto it = begin( rootSignature.m_samplerRegisters ); it != end( rootSignature.m_samplerRegisters ); ++it ) - { - auto& reg = *it; - auto& sampler = description.m_samplers[description.m_registerMap.samplers[reg.stage][reg.index]]; - switch( sampler.type ) - { - case Tr2ResourceSetDescriptionAL::Sampler::SAMPLER: - m_sampler[reg.parameter] = sampler.sampler.m_sampler->m_samplerState; - break; - case Tr2ResourceSetDescriptionAL::Sampler::HEAP_VIEW: - m_sampler[reg.parameter] = renderContext.GetSamplerHeapView(); - break; - default: - m_sampler[reg.parameter] = renderContext.GetNullSamplerDx12(); - break; - } - m_samplerCount = std::max( reg.parameter + 1, m_samplerCount ); - } - - m_owner = &renderContext; - - return S_OK; -} - -void Tr2ResourceSetAL::Destroy() -{ - for( uint32_t idx = 0; idx < m_resourceCount; ++idx ) - { - m_srv[idx] = nullptr; - m_uav[idx] = nullptr; - } - m_resourceCount = 0; - m_srvMask = 0; - m_uavMask = 0; - for( uint32_t idx = 0; idx < m_samplerCount; ++idx ) - { - m_sampler[idx] = nullptr; - } - m_samplerCount = 0; - - m_owner = nullptr; - m_inTransitions.clear(); - m_outTransitions.clear(); - m_usedResources.clear(); -} - -bool Tr2ResourceSetAL::IsValid() const -{ - return m_owner != nullptr; -} - -Tr2ALMemoryType Tr2ResourceSetAL::GetMemoryClass() const -{ - return AL_MEMORY_MANAGED; -} - -void Tr2ResourceSetAL::Describe( Tr2DeviceResourceDescriptionAL& description ) const -{ - description["type"] = "Tr2ResourceSetAL"; - description["name"] = m_name; -} - -ALResult Tr2ResourceSetAL::SetName( const char* name ) -{ - m_name = name; - return S_OK; -} -} - -#endif \ No newline at end of file diff --git a/trinityal/dx12/Tr2ResourceSetALDx12.h b/trinityal/dx12/Tr2ResourceSetALDx12.h deleted file mode 100644 index f20d5d227..000000000 --- a/trinityal/dx12/Tr2ResourceSetALDx12.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright © 2019 CCP ehf. - -#pragma once - -#if TRINITY_PLATFORM == TRINITY_DIRECTX12 - -#include "../include/Tr2ResourceSetAL.h" -#include "util/DescriptorHeapViewDx12.h" - -namespace TrinityALImpl -{ -struct Tr2RootSignatureAL; -class Tr2ResourceSetAL : public Tr2DeviceResourceAL -{ -public: - Tr2ResourceSetAL(); - ~Tr2ResourceSetAL(); - - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ); - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2RtPipelineStateAL& pipeline, Tr2PrimaryRenderContextAL& renderContext ); - void Destroy(); - - bool IsValid() const; - Tr2ALMemoryType GetMemoryClass() const; - - void Describe( Tr2DeviceResourceDescriptionAL& description ) const; - ALResult SetName( const char* name ); - -private: - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const Tr2RootSignatureAL& signature, Tr2PrimaryRenderContextAL& renderContext, const char* shaderName ); - std::shared_ptr m_srv[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - std::shared_ptr m_uav[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - std::shared_ptr m_sampler[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - uint32_t m_samplerCount; - uint32_t m_resourceCount; - uint32_t m_srvMask; - uint32_t m_uavMask; - Tr2PrimaryRenderContextAL* m_owner; - - std::vector m_inTransitions; - std::vector m_outTransitions; - std::vector m_usedResources; - std::string m_name; - - friend class ::Tr2RenderContextAL; -}; -} - -#endif \ No newline at end of file diff --git a/trinityal/dx12/Tr2SamplerStateALDx12.h b/trinityal/dx12/Tr2SamplerStateALDx12.h index a66407662..2c69c279a 100644 --- a/trinityal/dx12/Tr2SamplerStateALDx12.h +++ b/trinityal/dx12/Tr2SamplerStateALDx12.h @@ -36,7 +36,6 @@ class Tr2SamplerStateAL : public Tr2DeviceResourceAL bool m_isValid; friend class Tr2RenderContextAL; - friend class Tr2ResourceSetAL; friend class TrinityALImpl::Tr2RtShaderTableAL; }; diff --git a/trinityal/dx12/Tr2ShaderProgramALDx12.h b/trinityal/dx12/Tr2ShaderProgramALDx12.h index ec664b71c..2ad98bfe4 100644 --- a/trinityal/dx12/Tr2ShaderProgramALDx12.h +++ b/trinityal/dx12/Tr2ShaderProgramALDx12.h @@ -5,7 +5,7 @@ #if TRINITY_PLATFORM == TRINITY_DIRECTX12 #include "../include/Tr2ShaderProgramAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2RegisterMapAL.h" #include "../include/Tr2ShaderAL.h" class DescriptorStateCache; @@ -111,7 +111,6 @@ class Tr2ShaderProgramAL : public Tr2DeviceResourceAL std::string m_name; friend class ::Tr2RenderContextAL; - friend class Tr2ResourceSetAL; friend class ::DescriptorStateCache; friend class PSODescription; }; diff --git a/trinityal/dx12/Tr2StreamlineALDx12.h b/trinityal/dx12/Tr2StreamlineALDx12.h index 84db96dc9..2663a36c7 100644 --- a/trinityal/dx12/Tr2StreamlineALDx12.h +++ b/trinityal/dx12/Tr2StreamlineALDx12.h @@ -13,7 +13,6 @@ #include "../include/Tr2TextureAL.h" #include "Tr2TextureALDx12.h" #include "Tr2RenderContextDx12.h" -#include "Tr2ResourceSetALDx12.h" #include "Tr2GpuTimerALDx12.h" #include "Tr2PrimaryRenderContextDx12.h" #include "Tr2RenderContextDx12.h" diff --git a/trinityal/dx12/Tr2TextureALDx12.cpp b/trinityal/dx12/Tr2TextureALDx12.cpp index ac9dd816a..8641e1c2d 100644 --- a/trinityal/dx12/Tr2TextureALDx12.cpp +++ b/trinityal/dx12/Tr2TextureALDx12.cpp @@ -1193,7 +1193,8 @@ ALResult Tr2TextureAL::GenerateMipMaps( Tr2RenderContextAL& renderContext ) return E_INVALIDCALL; } - renderContext.SetResourceSet( ::Tr2ResourceSetAL() ); + renderContext.ResetResourceBindings(); + renderContext.FlushBarriersDx12(); renderContext.FlushBarriersDx12( m_textures[0] ); renderContext.m_dirtyPso = true; diff --git a/trinityal/dx12/Tr2TextureALDx12.h b/trinityal/dx12/Tr2TextureALDx12.h index 18fcb21bc..a88313b27 100644 --- a/trinityal/dx12/Tr2TextureALDx12.h +++ b/trinityal/dx12/Tr2TextureALDx12.h @@ -17,7 +17,6 @@ namespace TrinityALImpl { -class Tr2ResourceSetAL; class Tr2RtShaderTableAL; } @@ -119,7 +118,6 @@ class Tr2TextureAL : public Tr2DeviceResourceAL struct MipMapGenerator; std::unique_ptr m_mipMapGenerator; - friend class Tr2ResourceSetAL; friend class Tr2RenderContextAL; friend class Tr2RtShaderTableAL; }; diff --git a/trinityal/dx12/upscaling/Tr2XessUpscaling.cpp b/trinityal/dx12/upscaling/Tr2XessUpscaling.cpp index 2a00d6428..a15b0de12 100644 --- a/trinityal/dx12/upscaling/Tr2XessUpscaling.cpp +++ b/trinityal/dx12/upscaling/Tr2XessUpscaling.cpp @@ -320,7 +320,7 @@ Tr2UpscalingAL::Result Tr2XessUpscalingContext::Dispatch( Tr2UpscalingAL::Dispat auto& renderContext = m_params.renderContext; // flush all barriers before changing the state of the textures - renderContext.SetResourceSet( Tr2ResourceSetAL() ); + renderContext.ResetResourceBindings(); renderContext.FlushBarriersDx12(); // transition from common to unordered access view, since the output texture must be in that state diff --git a/trinityal/dx12/util/DescriptorStateCacheDx12.cpp b/trinityal/dx12/util/DescriptorStateCacheDx12.cpp index 4b9de3f0b..a8beb96c4 100644 --- a/trinityal/dx12/util/DescriptorStateCacheDx12.cpp +++ b/trinityal/dx12/util/DescriptorStateCacheDx12.cpp @@ -41,7 +41,7 @@ DescriptorStateCache::DescriptorStateCache( CComPtr device, Tr2Pri /** Dirty all states and reset internal allocators */ void DescriptorStateCache::Reset() { - for( uint32_t slot = 0; slot < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++slot ) + for( uint32_t slot = 0; slot < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; ++slot ) { m_srvUav[slot] = m_nullSrv; m_sampler[slot] = m_nullSampler; @@ -72,7 +72,7 @@ void DescriptorStateCache::Dirty() m_samplerDirty = true; // Pretend that nothing is currently bound forcing the next Commit() to re-assign every parameter - for( uint32_t slot = 0; slot < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++slot ) + for( uint32_t slot = 0; slot < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; ++slot ) { m_parameterSlots[slot].SetNone(); m_parameterSlots[slot].SetNone(); diff --git a/trinityal/dx12/util/DescriptorStateCacheDx12.h b/trinityal/dx12/util/DescriptorStateCacheDx12.h index 238cdbc65..d25883296 100644 --- a/trinityal/dx12/util/DescriptorStateCacheDx12.h +++ b/trinityal/dx12/util/DescriptorStateCacheDx12.h @@ -9,7 +9,7 @@ #include "../Tr2ConstantBufferALDx12.h" #include "../Tr2ShaderProgramAlDx12.h" #include "../../Tr2RenderContextEnum.h" -#include "../../include/Tr2ResourceSetAL.h" +#include "../../include/Tr2RegisterMapAL.h" #include "DescriptorHeapViewDx12.h" #include "FrameLocalDescriptorHeapAllocatorDx12.h" @@ -129,9 +129,9 @@ class DescriptorStateCache CComPtr m_rootSignature; - std::shared_ptr m_srvUav[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - std::shared_ptr m_sampler[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - D3D12_GPU_VIRTUAL_ADDRESS m_cbv[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; + std::shared_ptr m_srvUav[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + std::shared_ptr m_sampler[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + D3D12_GPU_VIRTUAL_ADDRESS m_cbv[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; CComPtr m_globalSrvUavHeap; CComPtr m_globalSamplerHeap; @@ -139,7 +139,7 @@ class DescriptorStateCache bool m_srvUavDirty; bool m_samplerDirty; - RootParameterSlot m_parameterSlots[Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; + RootParameterSlot m_parameterSlots[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; }; #endif diff --git a/trinityal/include/Tr2BufferAL.h b/trinityal/include/Tr2BufferAL.h index 588251b81..1c0b00cff 100644 --- a/trinityal/include/Tr2BufferAL.h +++ b/trinityal/include/Tr2BufferAL.h @@ -12,7 +12,6 @@ class Tr2RenderContextAL; namespace TrinityALImpl { class Tr2BufferAL; -class Tr2ResourceSetAL; } @@ -98,7 +97,6 @@ class Tr2BufferAL friend class Tr2RenderContextAL; friend class Tr2PrimaryRenderContextAL; - friend class TrinityALImpl::Tr2ResourceSetAL; }; diff --git a/trinityal/include/Tr2RegisterMapAL.h b/trinityal/include/Tr2RegisterMapAL.h new file mode 100644 index 000000000..27c726ec4 --- /dev/null +++ b/trinityal/include/Tr2RegisterMapAL.h @@ -0,0 +1,28 @@ +// Copyright © 2023 CCP ehf. + +#pragma once + +#include "../Tr2RenderContextEnum.h" + +class Tr2ShaderAL; +struct Tr2ShaderSignatureAL; + +struct Tr2RegisterMapAL +{ + Tr2RegisterMapAL(); + Tr2RegisterMapAL( Tr2RenderContextEnum::ShaderType stage, const Tr2ShaderSignatureAL& signature ); + Tr2RegisterMapAL( const Tr2ShaderAL* shaders, size_t shaderCount ); + Tr2RegisterMapAL( const Tr2RenderContextEnum::ShaderType* shaders, const Tr2ShaderSignatureAL* signatures, size_t signatureCount ); + + bool operator==( const Tr2RegisterMapAL& other ) const; + bool operator!=( const Tr2RegisterMapAL& other ) const; + + static const uint32_t MAX_RESOURCES_IN_STAGE = 32; + + uint32_t srvCount; + uint32_t uavCount; + uint32_t samplerCount; + uint8_t srvs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; + uint8_t uavs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; + uint8_t samplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; +}; diff --git a/trinityal/include/Tr2ResourceSetAL.h b/trinityal/include/Tr2ResourceSetAL.h deleted file mode 100644 index 261f9c02c..000000000 --- a/trinityal/include/Tr2ResourceSetAL.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#pragma once - -#include "../ALResult.h" -#include "../Tr2DeviceResourceAL.h" -#include "Tr2BufferAL.h" -#include "Tr2TextureAL.h" -#include "Tr2SamplerStateAL.h" - -class Tr2ShaderAL; -class Tr2ShaderProgramAL; -class Tr2PrimaryRenderContextAL; -class Tr2RtPipelineStateAL; -struct Tr2ShaderSignatureAL; - -namespace TrinityALImpl -{ -class Tr2ResourceSetAL; -class Tr2RtShaderTableAL; -} - -struct Tr2RegisterMapAL -{ - Tr2RegisterMapAL(); - Tr2RegisterMapAL( Tr2RenderContextEnum::ShaderType stage, const Tr2ShaderSignatureAL& signature ); - Tr2RegisterMapAL( const Tr2ShaderAL* shaders, size_t shaderCount ); - Tr2RegisterMapAL( const Tr2RenderContextEnum::ShaderType* shaders, const Tr2ShaderSignatureAL* signatures, size_t signatureCount ); - - bool operator==( const Tr2RegisterMapAL& other ) const; - bool operator!=( const Tr2RegisterMapAL& other ) const; - - static const uint32_t MAX_RESOURCES_IN_STAGE = 32; - - uint32_t srvCount; - uint32_t uavCount; - uint32_t samplerCount; - uint8_t srvs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; - uint8_t uavs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; - uint8_t samplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT][MAX_RESOURCES_IN_STAGE]; -}; - - -class Tr2ResourceSetDescriptionAL -{ -public: - static const uint32_t MAX_RESOURCES_IN_STAGE = 32; - - Tr2ResourceSetDescriptionAL(); - Tr2ResourceSetDescriptionAL( const Tr2ResourceSetDescriptionAL& ); - Tr2ResourceSetDescriptionAL( Tr2ResourceSetDescriptionAL&& ); - explicit Tr2ResourceSetDescriptionAL( const Tr2ShaderProgramAL& program ); - explicit Tr2ResourceSetDescriptionAL( const Tr2RegisterMapAL& registers ); - Tr2ResourceSetDescriptionAL& operator=( const Tr2ResourceSetDescriptionAL& other ); - Tr2ResourceSetDescriptionAL& operator=( Tr2ResourceSetDescriptionAL&& other ); - - bool SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ); - bool SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR ); - bool SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ); - bool SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip = 0 ); - bool SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); - bool SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); - bool SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); - bool SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ); - void ClearResources(); - - uint32_t ComputeHash() const; - - bool operator==( const Tr2ResourceSetDescriptionAL& other ) const; - -private: - struct Resource - { - enum Type - { - NONE, - BUFFER, - TEXTURE, - HEAP_VIEW, - }; - - Resource(); - - bool operator==( const Resource& other ) const; - bool Is( const Tr2BufferAL& other ) const; - bool Is( const Tr2TextureAL& other, Tr2RenderContextEnum::ColorSpace otherColorSpace ) const; - bool Is( const Tr2TextureAL& other, uint32_t otherMip ) const; - void UpdateHash( uint32_t& hash ) const; - - Tr2TextureAL texture; - Tr2BufferAL buffer; - Type type; - union - { - Tr2RenderContextEnum::ColorSpace colorSpace; - uint32_t mip; - }; - }; - - struct Sampler - { - enum Type - { - NONE, - SAMPLER, - HEAP_VIEW, - }; - - Sampler(); - - bool operator==( const Sampler& other ) const; - bool operator==( const Tr2SamplerStateAL& other ) const; - - void UpdateHash( uint32_t& hash ) const; - - Tr2SamplerStateAL sampler; - Type type; - }; - - Tr2RegisterMapAL m_registerMap; - std::unique_ptr m_srv; - std::unique_ptr m_uav; - std::unique_ptr m_samplers; - - friend class TrinityALImpl::Tr2ResourceSetAL; - friend class TrinityALImpl::Tr2RtShaderTableAL; -}; - -class Tr2ResourceSetAL -{ -public: - Tr2ResourceSetAL(); - - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ); - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const Tr2RtPipelineStateAL& pipeline, Tr2PrimaryRenderContextAL& renderContext ); - bool IsValid() const; - - Tr2ALMemoryType GetMemoryClass() const; - - ALResult SetName( const char* name ); - -private: - std::shared_ptr m_resourceSet; - - friend class Tr2RenderContextAL; -}; diff --git a/trinityal/include/Tr2RtPipelineStateAL.h b/trinityal/include/Tr2RtPipelineStateAL.h index 8e2433b76..32a38e415 100644 --- a/trinityal/include/Tr2RtPipelineStateAL.h +++ b/trinityal/include/Tr2RtPipelineStateAL.h @@ -71,6 +71,4 @@ class Tr2RtPipelineStateAL private: std::shared_ptr m_pipeline; - - friend class TrinityALImpl::Tr2ResourceSetAL; }; diff --git a/trinityal/include/Tr2RtShaderTableAL.h b/trinityal/include/Tr2RtShaderTableAL.h index ba91f784b..d29e6f119 100644 --- a/trinityal/include/Tr2RtShaderTableAL.h +++ b/trinityal/include/Tr2RtShaderTableAL.h @@ -6,7 +6,6 @@ #include "../ALResult.h" #include "../Tr2DeviceResourceAL.h" #include "Tr2ConstantBufferAL.h" -#include "Tr2ResourceSetAL.h" namespace TrinityALImpl { diff --git a/trinityal/include/Tr2SamplerStateAL.h b/trinityal/include/Tr2SamplerStateAL.h index 583ee5506..008c8e498 100644 --- a/trinityal/include/Tr2SamplerStateAL.h +++ b/trinityal/include/Tr2SamplerStateAL.h @@ -11,7 +11,6 @@ struct Tr2SamplerDescription; namespace TrinityALImpl { class Tr2SamplerStateAL; -class Tr2ResourceSetAL; } class Tr2SamplerStateAL @@ -35,7 +34,6 @@ class Tr2SamplerStateAL private: std::shared_ptr m_sampler; friend class Tr2RenderContextAL; - friend class TrinityALImpl::Tr2ResourceSetAL; }; namespace TrinityALImpl diff --git a/trinityal/include/Tr2ShaderProgramAL.h b/trinityal/include/Tr2ShaderProgramAL.h index a65fd9410..5ebcff7e7 100644 --- a/trinityal/include/Tr2ShaderProgramAL.h +++ b/trinityal/include/Tr2ShaderProgramAL.h @@ -12,7 +12,6 @@ struct Tr2RegisterMapAL; namespace TrinityALImpl { class Tr2ShaderProgramAL; -class Tr2ResourceSetAL; class PSODescription; } @@ -54,6 +53,5 @@ class Tr2ShaderProgramAL friend class Tr2RenderContextAL; friend class Tr2PrimaryRenderContextAL; - friend class TrinityALImpl::Tr2ResourceSetAL; friend class TrinityALImpl::PSODescription; }; diff --git a/trinityal/include/Tr2StaticResourceBindingsAL.h b/trinityal/include/Tr2StaticResourceBindingsAL.h new file mode 100644 index 000000000..1f50dd51f --- /dev/null +++ b/trinityal/include/Tr2StaticResourceBindingsAL.h @@ -0,0 +1,49 @@ +// Copyright © 2023 CCP ehf. + +#pragma once + +#include + +#include "../ALResult.h" +#include "../Tr2RenderContextEnum.h" +#include "Tr2SamplerStateAL.h" + +class Tr2RenderContextAL; + +class Tr2StaticResourceBindingsAL +{ +public: + bool SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ); + bool SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); + bool SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); + bool SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ); + void Clear(); + bool IsEmpty() const; + + bool operator==( const Tr2StaticResourceBindingsAL& other ) const; + + ALResult Apply( Tr2RenderContextAL& renderContext ) const; + +private: + enum Kind : uint8_t + { + KIND_SAMPLER, + KIND_SRV_HEAP_VIEW, + KIND_UAV_HEAP_VIEW, + KIND_SAMPLER_HEAP_VIEW, + }; + + struct Entry + { + Tr2SamplerStateAL sampler; + uint8_t stage; + uint8_t registerIndex; + Kind kind; + }; + + static bool SharesRegisterSpace( Kind a, Kind b ); + + bool Set( Kind kind, Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ); + + std::vector m_entries; +}; diff --git a/trinityal/include/Tr2TextureAL.h b/trinityal/include/Tr2TextureAL.h index 67071be97..dd27bec4c 100644 --- a/trinityal/include/Tr2TextureAL.h +++ b/trinityal/include/Tr2TextureAL.h @@ -9,7 +9,6 @@ namespace TrinityALImpl { class Tr2TextureAL; -class Tr2ResourceSetAL; class Tr2SwapChainAL; } @@ -79,6 +78,5 @@ class Tr2TextureAL friend class Tr2PrimaryRenderContextAL; friend class Tr2RenderContextAL; friend class TrinityALImpl::Tr2SwapChainAL; - friend class TrinityALImpl::Tr2ResourceSetAL; friend class TrinityALImpl::Tr2TextureAL; }; diff --git a/trinityal/include/TrinityAL.h b/trinityal/include/TrinityAL.h index e9d4621c1..4a053243d 100644 --- a/trinityal/include/TrinityAL.h +++ b/trinityal/include/TrinityAL.h @@ -24,7 +24,8 @@ #include "Tr2FenceAL.h" #include "Tr2GpuTimerAL.h" #include "Tr2ShaderProgramAL.h" -#include "Tr2ResourceSetAL.h" +#include "Tr2RegisterMapAL.h" +#include "Tr2StaticResourceBindingsAL.h" #include "Tr2BufferAL.h" #include "Tr2PipelineStatsQueryAL.h" #include "Tr2RtBottomLevelAccelerationStructureAL.h" diff --git a/trinityal/include/upscaling/Tr2Fsr1Upscaling.h b/trinityal/include/upscaling/Tr2Fsr1Upscaling.h index f9bd0eed4..1943a4e0a 100644 --- a/trinityal/include/upscaling/Tr2Fsr1Upscaling.h +++ b/trinityal/include/upscaling/Tr2Fsr1Upscaling.h @@ -7,7 +7,7 @@ #include "Tr2UpscalingAL.h" #include "Tr2RenderContextAL.h" #include "Tr2ShaderAL.h" -#include "Tr2ResourceSetAL.h" +#include "Tr2SamplerStateAL.h" #include "Tr2ShaderProgramAL.h" #if TRINITY_PLATFORM == TRINITY_DIRECTX12 diff --git a/trinityal/metal/Tr2RenderContextMetal.h b/trinityal/metal/Tr2RenderContextMetal.h index 37a6ad952..12863a688 100644 --- a/trinityal/metal/Tr2RenderContextMetal.h +++ b/trinityal/metal/Tr2RenderContextMetal.h @@ -9,8 +9,8 @@ #include "../include/Tr2TextureAL.h" #include "../include/Tr2SwapChainAL.h" #include "../include/Tr2CapsAL.h" -#include "../include/Tr2ResourceSetAL.h" #include "../include/Tr2SamplerStateAL.h" +#include "../include/Tr2BufferAL.h" #include "../include/Tr2ShaderProgramAL.h" #include "../include/Tr2VertexLayoutAL.h" #include "../include/Tr2ConstantBufferAL.h" @@ -25,10 +25,6 @@ class Tr2ConstantBufferAL; class Tr2ShaderAL; -class Tr2SamplerStateAL; -class Tr2TextureAL; -class Tr2ResourceSetAL; -class Tr2BufferAL; class Tr2RtShaderTableAL; class Tr2RtPipelineStateAL; struct ITr2RenderContextEvents; @@ -94,7 +90,22 @@ class Tr2RenderContextAL ALResult SetTopology( Tr2RenderContextEnum::Topology topology ); ALResult SetShaderProgram( const Tr2ShaderProgramAL& shaderProgram ); - ALResult SetResourceSet( const Tr2ResourceSetAL& resourceSet ); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2TextureAL& texture, + Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2TextureAL& texture, + uint32_t mip = 0 ) throw(); + ALResult SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw(); + + ALResult ResetResourceBindings() throw(); ALResult DrawIndexedPrimitive( uint32_t numVertices, uint32_t startIndex, @@ -301,7 +312,6 @@ class Tr2RenderContextAL Tr2PresentParametersAL m_presentParameters; Tr2ShaderProgramAL m_shaderProgram; - Tr2ResourceSetAL m_resourceSet; Tr2VertexLayoutAL m_vertexLayout; bool m_needsDrawResourceCheck; diff --git a/trinityal/metal/Tr2RenderContextMetal.mm b/trinityal/metal/Tr2RenderContextMetal.mm index 349292d96..f1e962fb6 100644 --- a/trinityal/metal/Tr2RenderContextMetal.mm +++ b/trinityal/metal/Tr2RenderContextMetal.mm @@ -12,7 +12,6 @@ #include "Tr2ConstantBufferALMetal.h" #include "Tr2RenderContextMetal.h" #include "Tr2VertexLayoutALMetal.h" -#include "Tr2ResourceSetALMetal.h" #include "Tr2ShaderProgramALMetal.h" #include "Tr2TextureALMetal.h" #include "Tr2SwapChainALMetal.h" @@ -93,7 +92,6 @@ MTLClearColor MakeClearColor( uint32_t color ) } m_vertexLayout = Tr2VertexLayoutAL(); - m_resourceSet = Tr2ResourceSetAL(); m_shaderProgram = Tr2ShaderProgramAL(); std::fill( std::begin( m_boundRenderTargets ), std::end( m_boundRenderTargets ), BoundRT{} ); @@ -523,8 +521,8 @@ MTLClearColor MakeClearColor( uint32_t color ) void Tr2RenderContextAL::CheckDrawResources() { - // Only need to check resources if we don't have a resource set and the shader has changed since the last draw. - if( m_needsDrawResourceCheck && !m_resourceSet.IsValid() ) + // Only need to check resources if the shader has changed since the last draw. + if( m_needsDrawResourceCheck ) { m_shaderProgram.m_program->SetDummyResources( *m_workQueue ); m_needsDrawResourceCheck = false; @@ -869,7 +867,6 @@ MTLClearColor MakeClearColor( uint32_t color ) m_workQueue->EndFrame(); m_vertexLayout = Tr2VertexLayoutAL(); - m_resourceSet = Tr2ResourceSetAL(); m_shaderProgram = Tr2ShaderProgramAL(); m_needsDrawResourceCheck = true; @@ -1134,46 +1131,51 @@ MTLClearColor MakeClearColor( uint32_t color ) return S_OK; } -ALResult Tr2RenderContextAL::SetResourceSet( const Tr2ResourceSetAL& resourceSet ) +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() { -#if 0 - if( m_resourceSet.m_resourceSet == resourceSet.m_resourceSet ) - { - return S_OK; - } -#endif + return S_OK; +} - TrinityALImpl::MetalContext* metalContext = GetMetalContext(); +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, + uint32_t, + const Tr2TextureAL&, + Tr2RenderContextEnum::ColorSpace ) throw() +{ + return S_OK; +} - m_resourceSet = resourceSet; - auto& rs = *resourceSet.m_resourceSet; +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() +{ + return S_OK; +} - if( rs.IsValid() ) - { - const ShaderType stages[] = { VERTEX_SHADER, PIXEL_SHADER, COMPUTE_SHADER }; - for( auto stage : stages ) - { - m_workQueue->SetBuffers( stage, - rs.m_buffers[stage], - rs.m_buffersMask[stage], - GetMetalContext()->GetHeapViewBuffer(), - rs.m_heapViewMask[stage] ); - m_workQueue->SetTextures( stage, rs.m_textures[stage], rs.m_texturesRange[stage] ); - m_workQueue->SetSamplers( stage, rs.m_samplers[stage], rs.m_samplersRange[stage] ); - } - } - else - { - const ShaderType stages[] = { VERTEX_SHADER, PIXEL_SHADER, COMPUTE_SHADER }; - for( auto stage : stages ) - { - m_workQueue->ResetBuffers( stage ); - m_workQueue->ResetTextures( stage ); - m_workQueue->ResetSamplers( stage ); - } - } +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2TextureAL&, uint32_t ) throw() +{ + return S_OK; +} - m_needsDrawResourceCheck = true; +ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2SamplerStateAL& ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::ResetResourceBindings() throw() +{ return S_OK; } @@ -1399,7 +1401,6 @@ MTLClearColor MakeClearColor( uint32_t color ) context->m_depthCompareFunction = m_depthCompareFunction; context->m_vertexLayout = Tr2VertexLayoutAL(); - context->m_resourceSet = Tr2ResourceSetAL(); context->m_shaderProgram = Tr2ShaderProgramAL(); context->m_needsDrawResourceCheck = true; diff --git a/trinityal/metal/Tr2ResourceSetALMetal.h b/trinityal/metal/Tr2ResourceSetALMetal.h deleted file mode 100644 index 95c64d45d..000000000 --- a/trinityal/metal/Tr2ResourceSetALMetal.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#pragma once - -#if TRINITY_PLATFORM == TRINITY_METAL - -#include "../include/Tr2ResourceSetAL.h" -#include "MetalContext.h" -#include "../include/Tr2RtPipelineStateAL.h" -#include "../include/Tr2ShaderProgramAL.h" - - -namespace TrinityALImpl -{ - -class Tr2ResourceSetAL : public Tr2DeviceResourceAL -{ -public: - Tr2ResourceSetAL(); - ~Tr2ResourceSetAL(); - - ALResult Create( const Tr2ResourceSetDescriptionAL& description, - const ::Tr2ShaderProgramAL& program, - Tr2PrimaryRenderContextAL& renderContext ); - ALResult Create( const Tr2ResourceSetDescriptionAL& description, - const ::Tr2RtPipelineStateAL& pipeline, - Tr2PrimaryRenderContextAL& renderContext ); - bool IsValid() const; - - void Destroy(); - Tr2ALMemoryType GetMemoryClass() const; - void Describe( Tr2DeviceResourceDescriptionAL& description ) const; - ALResult SetName( const char* name ); - -private: - id m_buffers[Tr2RenderContextEnum::SHADER_TYPE_COUNT] - [Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - id m_textures[Tr2RenderContextEnum::SHADER_TYPE_COUNT] - [Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - id m_samplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT] - [Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE]; - - uint32_t m_buffersMask[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - uint32_t m_heapViewMask[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - NSRange m_texturesRange[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - NSRange m_samplersRange[Tr2RenderContextEnum::SHADER_TYPE_COUNT]; - std::string m_name; - - bool m_isValid; - - friend class ::Tr2RenderContextAL; - friend class ::Tr2RtPipelineStateAL; -}; -} - -#endif diff --git a/trinityal/metal/Tr2ResourceSetALMetal.mm b/trinityal/metal/Tr2ResourceSetALMetal.mm deleted file mode 100644 index cf09886cf..000000000 --- a/trinityal/metal/Tr2ResourceSetALMetal.mm +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#include "StdAfx.h" - -#if TRINITY_PLATFORM == TRINITY_METAL - -#include "Tr2ResourceSetALMetal.h" -#include "Tr2BufferALMetal.h" -#include "Tr2RenderContextMetal.h" -#include "Tr2SamplerStateALMetal.h" -#include "Tr2TextureALMetal.h" -#include "Tr2ShaderProgramALMetal.h" -#include "Tr2RtPipelineStateALMetal.h" -#include "ALLog.h" - -static_assert( sizeof( TrinityALImpl::ShaderResourceMask::constantBufferMask ) * 8 >= METAL_MAX_BOUND_BUFFERS, - "Please use a type with more bits for ShaderResourceMask::constantBufferMask." ); -static_assert( sizeof( TrinityALImpl::ShaderResourceMask::bufferMask ) * 8 >= METAL_MAX_BOUND_BUFFERS, - "Please use a type with more bits for ShaderResourceMask::bufferMask." ); -static_assert( sizeof( TrinityALImpl::ShaderResourceMask::textureMask ) * 8 >= METAL_MAX_BOUND_TEXTURES, - "Please use a type with more bits for ShaderResourceMask::textureMask." ); -static_assert( sizeof( TrinityALImpl::ShaderResourceMask::samplerMask ) * 8 >= METAL_MAX_BOUND_SAMPLERS, - "Please use a type with more bits for ShaderResourceMask::samplerMask." ); - - -namespace TrinityALImpl -{ -Tr2ResourceSetAL::Tr2ResourceSetAL() : m_isValid( false ) -{ - static_assert( sizeof( m_buffersMask ) * 8 >= METAL_MAX_BOUND_BUFFERS, - "Please use a type with more bits for m_buffersMask." ); - - Destroy(); -} - -Tr2ResourceSetAL::~Tr2ResourceSetAL() -{ - Destroy(); -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, - const ::Tr2RtPipelineStateAL& pipeline, - Tr2PrimaryRenderContextAL& renderContext ) -{ - Destroy(); - - if( !renderContext.IsValid() || !pipeline.IsValid() ) - { - return E_INVALIDARG; - } - - const ::Tr2ShaderProgramAL program = pipeline.m_pipeline->GetShaderProgram( 0 ); - - return Create( description, program, renderContext ); -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, - const ::Tr2ShaderProgramAL& program, - Tr2PrimaryRenderContextAL& renderContext ) -{ - Destroy(); - - if( !renderContext.IsValid() || !program.IsValid() ) - { - return E_INVALIDARG; - } - - using namespace Tr2RenderContextEnum; - const ShaderType stages[] = { VERTEX_SHADER, PIXEL_SHADER, COMPUTE_SHADER }; - for( auto stage : stages ) - { - uint32_t buffersMask = 0; - uint32_t heapViewMask = 0; - NSUInteger texturesMin = NSUIntegerMax; - NSUInteger texturesMax = 0; - - // Init required resource mask to that required by the shader. - // uint32_t bufferMask = program.m_program->m_resourceMask[stage].bufferMask; - uint32_t textureMask = program.m_program->m_resourceMask[stage].textureMask; - uint32_t samplerMask = program.m_program->m_resourceMask[stage].samplerMask; - - for( int i = 0; i < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++i ) - { - if( description.m_registerMap.srvs[stage][i] >= description.m_registerMap.srvCount ) - { - continue; - } - const Tr2ResourceSetDescriptionAL::Resource& resource = - description.m_srv[description.m_registerMap.srvs[stage][i]]; - - switch( resource.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - if( resource.buffer.IsValid() ) - { - CCP_ASSERT( i < METAL_SRV_BUFFER_COUNT ); - - const NSUInteger bufferIndex = METAL_SRV_BUFFER_OFFSET + i; - m_buffers[stage][bufferIndex] = resource.buffer.m_buffer->GetMetalBuffer(); - buffersMask |= ( 1 << bufferIndex ); - - // Remove this resource from mask. - // bufferMask &= ~(1 << bufferIndex); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::HEAP_VIEW: { - CCP_ASSERT( i < METAL_SRV_BUFFER_COUNT ); - - const NSUInteger bufferIndex = METAL_SRV_BUFFER_OFFSET + i; - heapViewMask |= ( 1 << bufferIndex ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - if( resource.texture.IsValid() ) - { - CCP_ASSERT( i < METAL_SRV_TEXTURE_COUNT ); - - const NSUInteger texIndex = METAL_SRV_TEXTURE_OFFSET + i; - - if( resource.colorSpace == COLOR_SPACE_SRGB ) - { - m_textures[stage][texIndex] = resource.texture.m_texture->GetSRGBViewMetalTexture(); - } - else - { - m_textures[stage][texIndex] = resource.texture.m_texture->GetMetalTexture(); - } - - texturesMin = std::min( texturesMin, texIndex ); - texturesMax = std::max( texturesMax, texIndex ); - // Remove this resource from mask. - textureMask &= ~( 1 << texIndex ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::NONE: - continue; - default: - CCP_AL_LOGWARN( "Unknown SRV resource type in resource set for register %d, stage %d", i, stage ); - return E_INVALIDARG; - } - } - - for( int i = 0; i < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++i ) - { - if( description.m_registerMap.uavs[stage][i] >= description.m_registerMap.uavCount ) - { - continue; - } - const Tr2ResourceSetDescriptionAL::Resource& resource = - description.m_uav[description.m_registerMap.uavs[stage][i]]; - - switch( resource.type ) - { - case Tr2ResourceSetDescriptionAL::Resource::BUFFER: - if( resource.buffer.IsValid() ) - { - CCP_ASSERT( i < METAL_UAV_BUFFER_COUNT ); - - const NSUInteger bufferIndex = METAL_UAV_BUFFER_OFFSET + i; - m_buffers[stage][bufferIndex] = resource.buffer.m_buffer->GetMetalBuffer(); - buffersMask |= ( 1 << bufferIndex ); - - // Remove this resource from mask. - // bufferMask &= ~(1 << bufferIndex); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::HEAP_VIEW: { - CCP_ASSERT( i < METAL_UAV_BUFFER_COUNT ); - - const NSUInteger bufferIndex = METAL_UAV_BUFFER_OFFSET + i; - heapViewMask |= ( 1 << bufferIndex ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::TEXTURE: - if( resource.texture.IsValid() ) - { - CCP_ASSERT( i < METAL_UAV_TEXTURE_COUNT ); - - const NSUInteger texIndex = METAL_UAV_TEXTURE_OFFSET + i; - m_textures[stage][texIndex] = resource.texture.m_texture->GetUAVMetalTexture( resource.mip ); - texturesMin = std::min( texturesMin, texIndex ); - texturesMax = std::max( texturesMax, texIndex ); - // Remove this resource from mask. - textureMask &= ~( 1 << texIndex ); - } - break; - case Tr2ResourceSetDescriptionAL::Resource::NONE: - continue; - default: - CCP_AL_LOGWARN( "Unknown UAV resource type in resource set for register %d, stage %d", i, stage ); - return E_INVALIDARG; - } - } - - NSUInteger samplersMin = NSUIntegerMax; - NSUInteger samplersMax = 0; - - for( int i = 0; i < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++i ) - { - if( description.m_registerMap.samplers[stage][i] >= description.m_registerMap.samplerCount ) - { - continue; - } - const Tr2ResourceSetDescriptionAL::Sampler& sampler = - description.m_samplers[description.m_registerMap.samplers[stage][i]]; - - if( sampler.type == Tr2ResourceSetDescriptionAL::Sampler::SAMPLER ) - { - m_samplers[stage][i] = sampler.sampler.m_sampler->GetMetalSamplerState(); - samplersMin = std::min( samplersMin, i ); - samplersMax = std::max( samplersMax, i ); - // Remove this resource from mask. - samplerMask &= ~( 1 << i ); - } - else if( sampler.type == Tr2ResourceSetDescriptionAL::Sampler::HEAP_VIEW ) - { - CCP_ASSERT( i < METAL_SRV_BUFFER_COUNT ); - const NSUInteger bufferIndex = METAL_SRV_BUFFER_OFFSET + i; - heapViewMask |= ( 1 << bufferIndex ); - } - } - - // Replace any missing resources with dummy ones. - - MetalContext* metalContext = renderContext.GetMetalContext(); - unsigned int index = 0; - // Buffers not supported yet. -#if 0 - while( bufferMask ) - { - if( bufferMask & 0x1 ) - { - // Note - Buffers for vertex shaders are NOT set via a resource set, so you if you re-set them here trouble will ensue. - } - bufferMask >>= 1; - ++index; - } -#endif - - index = 0; - while( textureMask ) - { - if( textureMask & 0x1 ) - { - m_textures[stage][index] = metalContext->GetDummyTexture( - MTLTextureType( program.m_program->m_resourceMask[stage].textureTypes[index] ) ); - texturesMin = std::min( texturesMin, index ); - texturesMax = std::max( texturesMax, index ); - } - textureMask >>= 1; - ++index; - } - - index = 0; - while( samplerMask ) - { - if( samplerMask & 0x1 ) - { - m_samplers[stage][index] = metalContext->GetDummySampler(); - samplersMin = std::min( samplersMin, index ); - samplersMax = std::max( samplersMax, index ); - } - samplerMask >>= 1; - ++index; - } - - m_buffersMask[stage] = buffersMask; - m_heapViewMask[stage] = heapViewMask; - m_texturesRange[stage] = ( texturesMin != NSUIntegerMax ) ? - NSMakeRange( texturesMin, texturesMax - texturesMin + 1 ) : - NSMakeRange( 0, 0 ); - m_samplersRange[stage] = ( samplersMin != NSUIntegerMax ) ? - NSMakeRange( samplersMin, samplersMax - samplersMin + 1 ) : - NSMakeRange( 0, 0 ); - } - - m_isValid = true; - return S_OK; -} - -bool Tr2ResourceSetAL::IsValid() const -{ - return m_isValid; -} - -void Tr2ResourceSetAL::Destroy() -{ - m_isValid = false; - - using namespace Tr2RenderContextEnum; - const ShaderType stages[] = { VERTEX_SHADER, PIXEL_SHADER, COMPUTE_SHADER }; - for( auto stage : stages ) - { - for( int i = 0; i < Tr2ResourceSetDescriptionAL::MAX_RESOURCES_IN_STAGE; ++i ) - { - m_buffers[stage][i] = nil; - m_textures[stage][i] = nil; - m_samplers[stage][i] = nil; - } - - m_buffersMask[stage] = 0; - m_heapViewMask[stage] = 0; - m_texturesRange[stage] = NSMakeRange( 0, 0 ); - m_samplersRange[stage] = NSMakeRange( 0, 0 ); - } -} - -Tr2ALMemoryType Tr2ResourceSetAL::GetMemoryClass() const -{ - return AL_MEMORY_MANAGED; -} - -void Tr2ResourceSetAL::Describe( Tr2DeviceResourceDescriptionAL& description ) const -{ - description["type"] = "Tr2ResourceSetAL"; - description["name"] = m_name; -} - -ALResult Tr2ResourceSetAL::SetName( const char* name ) -{ - m_name = name; - return S_OK; -} -} - -#endif diff --git a/trinityal/metal/Tr2RtPipelineStateALMetal.h b/trinityal/metal/Tr2RtPipelineStateALMetal.h index 680f2510a..c8e191c08 100644 --- a/trinityal/metal/Tr2RtPipelineStateALMetal.h +++ b/trinityal/metal/Tr2RtPipelineStateALMetal.h @@ -14,7 +14,6 @@ //#include "StdAfx.h" #include "Tr2ShaderProgramALMetal.h" #include "../include/Tr2RtPipelineStateAL.h" -#include "../include/Tr2ResourceSetAL.h" #include "Tr2ShaderAL.h" #include diff --git a/trinityal/metal/Tr2ShaderALMetal.h b/trinityal/metal/Tr2ShaderALMetal.h index 8bf29c80b..267242d3c 100644 --- a/trinityal/metal/Tr2ShaderALMetal.h +++ b/trinityal/metal/Tr2ShaderALMetal.h @@ -5,7 +5,6 @@ #if TRINITY_PLATFORM == TRINITY_METAL #include "../include/Tr2ShaderAL.h" -#include "Tr2ResourceSetALMetal.h" namespace TrinityALImpl diff --git a/trinityal/metal/Tr2ShaderProgramALMetal.h b/trinityal/metal/Tr2ShaderProgramALMetal.h index cb01c9748..23bb01931 100644 --- a/trinityal/metal/Tr2ShaderProgramALMetal.h +++ b/trinityal/metal/Tr2ShaderProgramALMetal.h @@ -5,9 +5,8 @@ #if TRINITY_PLATFORM == TRINITY_METAL #include "../include/Tr2ShaderProgramAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2RegisterMapAL.h" #include "Tr2ShaderALMetal.h" -#include "Tr2ResourceSetALMetal.h" #include "MetalContext.h" namespace TrinityALImpl @@ -59,7 +58,6 @@ class Tr2ShaderProgramAL : public Tr2DeviceResourceAL bool m_isValid; friend class Tr2RenderContextAL; - friend class Tr2ResourceSetAL; }; } diff --git a/trinityal/src/Tr2RegisterMapAL.cpp b/trinityal/src/Tr2RegisterMapAL.cpp new file mode 100644 index 000000000..757697f0b --- /dev/null +++ b/trinityal/src/Tr2RegisterMapAL.cpp @@ -0,0 +1,125 @@ +// Copyright © 2023 CCP ehf. + +#include "StdAfx.h" +#include "../include/Tr2RegisterMapAL.h" +#include "../include/Tr2ShaderAL.h" + + +Tr2RegisterMapAL::Tr2RegisterMapAL() : // cppcheck-suppress uninitMemberVar + srvCount( 0 ), + uavCount( 0 ), + samplerCount( 0 ) +{ +} + +Tr2RegisterMapAL::Tr2RegisterMapAL( Tr2RenderContextEnum::ShaderType stage, const Tr2ShaderSignatureAL& signature ) : + srvCount( 0 ), + uavCount( 0 ), + samplerCount( 0 ) +{ + memset( srvs, -1, sizeof( srvs ) ); + memset( uavs, -1, sizeof( uavs ) ); + memset( samplers, -1, sizeof( samplers ) ); + + for( auto it = begin( signature.registers ); it != end( signature.registers ); ++it ) + { + if( it->IsSrv() ) + { + srvs[stage][it->registerIndex] = uint8_t( srvCount++ ); + } + else if( it->IsUav() ) + { + uavs[stage][it->registerIndex] = uint8_t( uavCount++ ); + } + else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) + { + samplers[stage][it->registerIndex] = uint8_t( samplerCount++ ); + } + } +} + +Tr2RegisterMapAL::Tr2RegisterMapAL( const Tr2ShaderAL* shaders, size_t shaderCount ) : + srvCount( 0 ), + uavCount( 0 ), + samplerCount( 0 ) +{ + memset( srvs, -1, sizeof( srvs ) ); + memset( uavs, -1, sizeof( uavs ) ); + memset( samplers, -1, sizeof( samplers ) ); + + for( size_t i = 0; i < shaderCount; ++i ) + { + auto shaderType = shaders[i].GetType(); + auto& signature = shaders[i].GetSignature(); + for( auto it = begin( signature.registers ); it != end( signature.registers ); ++it ) + { + if( it->IsSrv() ) + { + srvs[shaderType][it->registerIndex] = uint8_t( srvCount++ ); + } + else if( it->IsUav() ) + { + uavs[shaderType][it->registerIndex] = uint8_t( uavCount++ ); + } + else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) + { + samplers[shaderType][it->registerIndex] = uint8_t( samplerCount++ ); + } + } + } +} + +Tr2RegisterMapAL::Tr2RegisterMapAL( const Tr2RenderContextEnum::ShaderType* shaders, const Tr2ShaderSignatureAL* signatures, size_t signatureCount ) : + srvCount( 0 ), + uavCount( 0 ), + samplerCount( 0 ) +{ + memset( srvs, -1, sizeof( srvs ) ); + memset( uavs, -1, sizeof( uavs ) ); + memset( samplers, -1, sizeof( samplers ) ); + + for( size_t i = 0; i < signatureCount; ++i ) + { + for( auto it = begin( signatures[i].registers ); it != end( signatures[i].registers ); ++it ) + { + if( it->IsSrv() ) + { + srvs[shaders[i]][it->registerIndex] = uint8_t( srvCount++ ); + } + else if( it->IsUav() ) + { + uavs[shaders[i]][it->registerIndex] = uint8_t( uavCount++ ); + } + else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) + { + samplers[shaders[i]][it->registerIndex] = uint8_t( samplerCount++ ); + } + } + } +} + +bool Tr2RegisterMapAL::operator==( const Tr2RegisterMapAL& other ) const +{ + if( srvCount != other.srvCount || uavCount != other.uavCount || samplerCount != other.samplerCount ) + { + return false; + } + if( srvCount > 0 && memcmp( srvs, other.srvs, sizeof( srvs ) ) ) + { + return false; + } + if( uavCount > 0 && memcmp( uavs, other.uavs, sizeof( uavs ) ) ) + { + return false; + } + if( samplerCount > 0 && memcmp( samplers, other.samplers, sizeof( samplers ) ) ) + { + return false; + } + return true; +} + +bool Tr2RegisterMapAL::operator!=( const Tr2RegisterMapAL& other ) const +{ + return !( *this == other ); +} diff --git a/trinityal/src/Tr2ResourceSetAL.cpp b/trinityal/src/Tr2ResourceSetAL.cpp deleted file mode 100644 index da64763b6..000000000 --- a/trinityal/src/Tr2ResourceSetAL.cpp +++ /dev/null @@ -1,605 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#include "StdAfx.h" -#include "../include/Tr2ResourceSetAL.h" -#include "../include/Tr2TextureAL.h" -#include "../include/Tr2ShaderAL.h" -#include "../include/Tr2ShaderProgramAL.h" -#include "../include/Tr2CapsAL.h" - - -#include TRINITY_AL_PLATFORM_INCLUDE( Tr2ResourceSetAL ) - - -namespace -{ - -template -void HashResourcePtr( const T& resource, uint32_t& hash ) -{ - auto p = resource.TrinityALImpl_GetObject(); - hash = CcpHashFNV1( &p, sizeof( p ), hash ); -} - -} - - -Tr2RegisterMapAL::Tr2RegisterMapAL() : // cppcheck-suppress uninitMemberVar - srvCount( 0 ), - uavCount( 0 ), - samplerCount( 0 ) -{ -} - -Tr2RegisterMapAL::Tr2RegisterMapAL( Tr2RenderContextEnum::ShaderType stage, const Tr2ShaderSignatureAL& signature ) : - srvCount( 0 ), - uavCount( 0 ), - samplerCount( 0 ) -{ - memset( srvs, -1, sizeof( srvs ) ); - memset( uavs, -1, sizeof( uavs ) ); - memset( samplers, -1, sizeof( samplers ) ); - - for( auto it = begin( signature.registers ); it != end( signature.registers ); ++it ) - { - if( it->IsSrv() ) - { - srvs[stage][it->registerIndex] = uint8_t( srvCount++ ); - } - else if( it->IsUav() ) - { - uavs[stage][it->registerIndex] = uint8_t( uavCount++ ); - } - else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) - { - samplers[stage][it->registerIndex] = uint8_t( samplerCount++ ); - } - } -} - -Tr2RegisterMapAL::Tr2RegisterMapAL( const Tr2ShaderAL* shaders, size_t shaderCount ) : - srvCount( 0 ), - uavCount( 0 ), - samplerCount( 0 ) -{ - memset( srvs, -1, sizeof( srvs ) ); - memset( uavs, -1, sizeof( uavs ) ); - memset( samplers, -1, sizeof( samplers ) ); - - for( size_t i = 0; i < shaderCount; ++i ) - { - auto shaderType = shaders[i].GetType(); - auto& signature = shaders[i].GetSignature(); - for( auto it = begin( signature.registers ); it != end( signature.registers ); ++it ) - { - if( it->IsSrv() ) - { - srvs[shaderType][it->registerIndex] = uint8_t( srvCount++ ); - } - else if( it->IsUav() ) - { - uavs[shaderType][it->registerIndex] = uint8_t( uavCount++ ); - } - else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) - { - samplers[shaderType][it->registerIndex] = uint8_t( samplerCount++ ); - } - } - } -} - -Tr2RegisterMapAL::Tr2RegisterMapAL( const Tr2RenderContextEnum::ShaderType* shaders, const Tr2ShaderSignatureAL* signatures, size_t signatureCount ) : - srvCount( 0 ), - uavCount( 0 ), - samplerCount( 0 ) -{ - memset( srvs, -1, sizeof( srvs ) ); - memset( uavs, -1, sizeof( uavs ) ); - memset( samplers, -1, sizeof( samplers ) ); - - for( size_t i = 0; i < signatureCount; ++i ) - { - for( auto it = begin( signatures[i].registers ); it != end( signatures[i].registers ); ++it ) - { - if( it->IsSrv() ) - { - srvs[shaders[i]][it->registerIndex] = uint8_t( srvCount++ ); - } - else if( it->IsUav() ) - { - uavs[shaders[i]][it->registerIndex] = uint8_t( uavCount++ ); - } - else if( it->registerType == Tr2ShaderRegisterAL::SAMPLER ) - { - samplers[shaders[i]][it->registerIndex] = uint8_t( samplerCount++ ); - } - } - } -} - -bool Tr2RegisterMapAL::operator==( const Tr2RegisterMapAL& other ) const -{ - if( srvCount != other.srvCount || uavCount != other.uavCount || samplerCount != other.samplerCount ) - { - return false; - } - if( srvCount > 0 && memcmp( srvs, other.srvs, sizeof( srvs ) ) ) - { - return false; - } - if( uavCount > 0 && memcmp( uavs, other.uavs, sizeof( uavs ) ) ) - { - return false; - } - if( samplerCount > 0 && memcmp( samplers, other.samplers, sizeof( samplers ) ) ) - { - return false; - } - return true; -} - -bool Tr2RegisterMapAL::operator!=( const Tr2RegisterMapAL& other ) const -{ - return !( *this == other ); -} - - -Tr2ResourceSetDescriptionAL::Tr2ResourceSetDescriptionAL() -{ -} - -Tr2ResourceSetDescriptionAL::Tr2ResourceSetDescriptionAL( const Tr2ResourceSetDescriptionAL& other ) : - m_registerMap( other.m_registerMap ) -{ - if( m_registerMap.srvCount > 0 ) - { - m_srv.reset( new Resource[m_registerMap.srvCount] ); - std::copy_n( other.m_srv.get(), m_registerMap.srvCount, m_srv.get() ); - } - if( m_registerMap.uavCount > 0 ) - { - m_uav.reset( new Resource[m_registerMap.uavCount] ); - std::copy_n( other.m_uav.get(), m_registerMap.uavCount, m_uav.get() ); - } - if( m_registerMap.samplerCount > 0 ) - { - m_samplers.reset( new Sampler[m_registerMap.samplerCount] ); - std::copy_n( other.m_samplers.get(), m_registerMap.samplerCount, m_samplers.get() ); - } -} - -Tr2ResourceSetDescriptionAL::Tr2ResourceSetDescriptionAL( Tr2ResourceSetDescriptionAL&& other ) : - m_registerMap( other.m_registerMap ) -{ - std::swap( m_srv, other.m_srv ); - std::swap( m_uav, other.m_uav ); - std::swap( m_samplers, other.m_samplers ); -} - -Tr2ResourceSetDescriptionAL::Tr2ResourceSetDescriptionAL( const Tr2ShaderProgramAL& program ) : - m_registerMap( program.GetRegisterMap() ) -{ - if( m_registerMap.srvCount > 0 ) - { - m_srv.reset( new Resource[m_registerMap.srvCount] ); - } - if( m_registerMap.uavCount > 0 ) - { - m_uav.reset( new Resource[m_registerMap.uavCount] ); - } - if( m_registerMap.samplerCount > 0 ) - { - m_samplers.reset( new Sampler[m_registerMap.samplerCount] ); - } -} - -Tr2ResourceSetDescriptionAL::Tr2ResourceSetDescriptionAL( const Tr2RegisterMapAL& registers ) : - m_registerMap( registers ) -{ - if( m_registerMap.srvCount > 0 ) - { - m_srv.reset( new Resource[m_registerMap.srvCount] ); - } - if( m_registerMap.uavCount > 0 ) - { - m_uav.reset( new Resource[m_registerMap.uavCount] ); - } - if( m_registerMap.samplerCount > 0 ) - { - m_samplers.reset( new Sampler[m_registerMap.samplerCount] ); - } -} - -Tr2ResourceSetDescriptionAL& Tr2ResourceSetDescriptionAL::operator=( const Tr2ResourceSetDescriptionAL& other ) -{ - if( &other == this ) - { - return *this; - } - m_registerMap = other.m_registerMap; - if( m_registerMap.srvCount > 0 ) - { - m_srv.reset( new Resource[m_registerMap.srvCount] ); - std::copy_n( other.m_srv.get(), m_registerMap.srvCount, m_srv.get() ); - } - else - { - m_srv.reset(); - } - if( m_registerMap.uavCount > 0 ) - { - m_uav.reset( new Resource[m_registerMap.uavCount] ); - std::copy_n( other.m_uav.get(), m_registerMap.uavCount, m_uav.get() ); - } - else - { - m_uav.reset(); - } - if( m_registerMap.samplerCount > 0 ) - { - m_samplers.reset( new Sampler[m_registerMap.samplerCount] ); - std::copy_n( other.m_samplers.get(), m_registerMap.samplerCount, m_samplers.get() ); - } - else - { - m_samplers.reset(); - } - return *this; -} - -Tr2ResourceSetDescriptionAL& Tr2ResourceSetDescriptionAL::operator=( Tr2ResourceSetDescriptionAL&& other ) -{ - if( &other == this ) - { - return *this; - } - m_registerMap = other.m_registerMap; - std::swap( m_srv, other.m_srv ); - other.m_srv.reset(); - std::swap( m_uav, other.m_uav ); - other.m_uav.reset(); - std::swap( m_samplers, other.m_samplers ); - other.m_samplers.reset(); - return *this; -} - - -bool Tr2ResourceSetDescriptionAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) -{ - if( m_registerMap.srvCount == 0 ) - { - return false; - } - auto index = m_registerMap.srvs[stage][registerIndex]; - if( index >= m_registerMap.srvCount ) - { - return false; - } - auto& resource = m_srv[index]; - if( resource.Is( buffer ) ) - { - return false; - } - resource.type = Resource::BUFFER; - resource.buffer = buffer; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace ) -{ - if( m_registerMap.srvCount == 0 ) - { - return false; - } - auto index = m_registerMap.srvs[stage][registerIndex]; - if( index >= m_registerMap.srvCount ) - { - return false; - } - auto& resource = m_srv[index]; - if( resource.Is( texture, colorSpace ) ) - { - return false; - } - resource.type = Resource::TEXTURE; - resource.texture = texture; - resource.colorSpace = colorSpace; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) -{ - if( m_registerMap.uavCount == 0 ) - { - return false; - } - auto index = m_registerMap.uavs[stage][registerIndex]; - if( index >= m_registerMap.uavCount ) - { - return false; - } - auto& resource = m_uav[index]; - if( resource.Is( buffer ) ) - { - return false; - } - resource.type = Resource::BUFFER; - resource.buffer = buffer; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip ) -{ - if( m_registerMap.uavCount == 0 ) - { - return false; - } - auto index = m_registerMap.uavs[stage][registerIndex]; - if( index >= m_registerMap.uavCount ) - { - return false; - } - auto& resource = m_uav[index]; - if( resource.Is( texture, mip ) ) - { - return false; - } - resource.type = Resource::TEXTURE; - resource.texture = texture; - resource.mip = mip; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) -{ - if( m_registerMap.srvCount == 0 ) - { - return false; - } - auto index = m_registerMap.srvs[stage][registerIndex]; - if( index >= m_registerMap.srvCount ) - { - return false; - } - auto& resource = m_srv[index]; - if( resource.type == Resource::HEAP_VIEW ) - { - return false; - } - resource.type = Resource::HEAP_VIEW; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) -{ - if( m_registerMap.uavCount == 0 ) - { - return false; - } - auto index = m_registerMap.uavs[stage][registerIndex]; - if( index >= m_registerMap.uavCount ) - { - return false; - } - auto& resource = m_uav[index]; - if( resource.type == Resource::HEAP_VIEW ) - { - return false; - } - resource.type = Resource::HEAP_VIEW; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) -{ - if( m_registerMap.samplerCount == 0 ) - { - return false; - } - auto index = m_registerMap.samplers[stage][registerIndex]; - if( index >= m_registerMap.samplerCount ) - { - return false; - } - auto& resource = m_samplers[index]; - if( resource.type == Sampler::HEAP_VIEW ) - { - return false; - } - resource.type = Sampler::HEAP_VIEW; - return true; -} - -bool Tr2ResourceSetDescriptionAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) -{ - if( m_registerMap.samplerCount == 0 ) - { - return false; - } - auto index = m_registerMap.samplers[stage][registerIndex]; - if( index >= m_registerMap.samplerCount ) - { - return false; - } - auto& resource = m_samplers[index]; - if( resource.type == Sampler::SAMPLER && resource.sampler == sampler ) - { - return false; - } - resource.sampler = sampler; - resource.type = Sampler::SAMPLER; - return true; -} - -bool Tr2ResourceSetDescriptionAL::operator==( const Tr2ResourceSetDescriptionAL& other ) const -{ - return m_srv == other.m_srv && m_uav == other.m_uav && m_samplers == other.m_samplers; -} - -void Tr2ResourceSetDescriptionAL::ClearResources() -{ - for( uint32_t i = 0; i < m_registerMap.srvCount; ++i ) - { - auto& srv = m_srv[i]; - srv.type = Resource::NONE; - srv.texture = Tr2TextureAL(); - srv.buffer = Tr2BufferAL(); - } - for( uint32_t i = 0; i < m_registerMap.uavCount; ++i ) - { - auto& uav = m_uav[i]; - uav.type = Resource::NONE; - uav.texture = Tr2TextureAL(); - uav.buffer = Tr2BufferAL(); - } -} - -uint32_t Tr2ResourceSetDescriptionAL::ComputeHash() const -{ - uint32_t hash = 0; - for( uint32_t i = 0; i < m_registerMap.srvCount; ++i ) - { - m_srv[i].UpdateHash( hash ); - } - for( uint32_t i = 0; i < m_registerMap.uavCount; ++i ) - { - m_uav[i].UpdateHash( hash ); - } - for( uint32_t i = 0; i < m_registerMap.samplerCount; ++i ) - { - m_samplers[i].UpdateHash( hash ); - } - return hash; -} - - -Tr2ResourceSetDescriptionAL::Resource::Resource() : - type( NONE ), - colorSpace( Tr2RenderContextEnum::COLOR_SPACE_LINEAR ) -{ -} - -bool Tr2ResourceSetDescriptionAL::Resource::operator==( const Resource& other ) const -{ - return type == other.type && buffer == other.buffer && texture == other.texture; -} - -bool Tr2ResourceSetDescriptionAL::Resource::Is( const Tr2BufferAL& other ) const -{ - return type == BUFFER && buffer == other; -} - -bool Tr2ResourceSetDescriptionAL::Resource::Is( const Tr2TextureAL& other, Tr2RenderContextEnum::ColorSpace otherColorSpace ) const -{ - return type == TEXTURE && texture == other && colorSpace == otherColorSpace; -} - -bool Tr2ResourceSetDescriptionAL::Resource::Is( const Tr2TextureAL& other, uint32_t otherMip ) const -{ - return type == TEXTURE && texture == other && mip == otherMip; -} - -void Tr2ResourceSetDescriptionAL::Resource::UpdateHash( uint32_t& hash ) const -{ - if( type == BUFFER ) - { - HashResourcePtr( buffer, hash ); - } - else if( type == TEXTURE ) - { - HashResourcePtr( texture, hash ); - } - else if( type == HEAP_VIEW ) - { - hash = CcpHashFNV1( &type, sizeof( type ), hash ); - } -} - -Tr2ResourceSetDescriptionAL::Sampler::Sampler() : - type( NONE ) -{ -} - -bool Tr2ResourceSetDescriptionAL::Sampler::operator==( const Sampler& other ) const -{ - return sampler == other.sampler && type == other.type; -} - -bool Tr2ResourceSetDescriptionAL::Sampler::operator==( const Tr2SamplerStateAL& other ) const -{ - return sampler == other && type == SAMPLER; -} - -void Tr2ResourceSetDescriptionAL::Sampler::UpdateHash( uint32_t& hash ) const -{ - if( type == SAMPLER ) - { - HashResourcePtr( sampler, hash ); - } - else if( type == HEAP_VIEW ) - { - hash = CcpHashFNV1( &type, sizeof( type ), hash ); - } -} - - -namespace -{ -std::shared_ptr nullRS = std::make_shared(); -} - - -Tr2ResourceSetAL::Tr2ResourceSetAL() : - m_resourceSet( nullRS ) -{ -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ) -{ - m_resourceSet = std::make_shared(); - auto result = m_resourceSet->Create( description, program, renderContext ); - if( FAILED( result ) ) - { - m_resourceSet = nullRS; - } - return result; -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL& description, const Tr2RtPipelineStateAL& pipeline, Tr2PrimaryRenderContextAL& renderContext ) -{ -#if TRINITY_PLATFORM_SUPPORTS_RAY_TRACING - m_resourceSet = std::make_shared(); - auto result = m_resourceSet->Create( description, pipeline, renderContext ); - if( FAILED( result ) ) - { - m_resourceSet = nullRS; - } - return result; -#else - m_resourceSet = nullRS; - return E_FAIL; -#endif -} - -bool Tr2ResourceSetAL::IsValid() const -{ - return m_resourceSet->IsValid(); -} - -Tr2ALMemoryType Tr2ResourceSetAL::GetMemoryClass() const -{ - return m_resourceSet->GetMemoryClass(); -} - -ALResult Tr2ResourceSetAL::SetName( const char* name ) -{ - if( !IsValid() ) - { - return E_INVALIDCALL; - } - if( !name ) - { - return E_INVALIDARG; - } - return m_resourceSet->SetName( name ); -} diff --git a/trinityal/src/Tr2StaticResourceBindingsAL.cpp b/trinityal/src/Tr2StaticResourceBindingsAL.cpp new file mode 100644 index 000000000..c441518f2 --- /dev/null +++ b/trinityal/src/Tr2StaticResourceBindingsAL.cpp @@ -0,0 +1,117 @@ +// Copyright © 2023 CCP ehf. + +#include "StdAfx.h" +#include "../include/Tr2StaticResourceBindingsAL.h" +#include "../include/Tr2RenderContextAL.h" + + +bool Tr2StaticResourceBindingsAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) +{ + return Set( KIND_SAMPLER, stage, registerIndex, sampler ); +} + +bool Tr2StaticResourceBindingsAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) +{ + return Set( KIND_SRV_HEAP_VIEW, stage, registerIndex, Tr2SamplerStateAL() ); +} + +bool Tr2StaticResourceBindingsAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) +{ + return Set( KIND_UAV_HEAP_VIEW, stage, registerIndex, Tr2SamplerStateAL() ); +} + +bool Tr2StaticResourceBindingsAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) +{ + return Set( KIND_SAMPLER_HEAP_VIEW, stage, registerIndex, Tr2SamplerStateAL() ); +} + +void Tr2StaticResourceBindingsAL::Clear() +{ + m_entries.clear(); +} + +bool Tr2StaticResourceBindingsAL::IsEmpty() const +{ + return m_entries.empty(); +} + +bool Tr2StaticResourceBindingsAL::operator==( const Tr2StaticResourceBindingsAL& other ) const +{ + if( m_entries.size() != other.m_entries.size() ) + { + return false; + } + for( size_t i = 0; i < m_entries.size(); ++i ) + { + auto& entry = m_entries[i]; + auto& otherEntry = other.m_entries[i]; + if( entry.kind != otherEntry.kind || entry.stage != otherEntry.stage || entry.registerIndex != otherEntry.registerIndex ) + { + return false; + } + if( !( entry.sampler == otherEntry.sampler ) ) + { + return false; + } + } + return true; +} + +ALResult Tr2StaticResourceBindingsAL::Apply( Tr2RenderContextAL& renderContext ) const +{ + for( const auto& entry : m_entries ) + { + auto stage = Tr2RenderContextEnum::ShaderType( entry.stage ); + switch( entry.kind ) + { + case KIND_SAMPLER: + CR_RETURN_HR( renderContext.SetSampler( stage, entry.registerIndex, entry.sampler ) ); + break; + case KIND_SRV_HEAP_VIEW: + CR_RETURN_HR( renderContext.SetSrvHeapView( stage, entry.registerIndex ) ); + break; + case KIND_UAV_HEAP_VIEW: + CR_RETURN_HR( renderContext.SetUavHeapView( stage, entry.registerIndex ) ); + break; + case KIND_SAMPLER_HEAP_VIEW: + CR_RETURN_HR( renderContext.SetSamplerHeapView( stage, entry.registerIndex ) ); + break; + } + } + return S_OK; +} + +bool Tr2StaticResourceBindingsAL::SharesRegisterSpace( Kind a, Kind b ) +{ + if( a == b ) + { + return true; + } + return ( a == KIND_SAMPLER || a == KIND_SAMPLER_HEAP_VIEW ) && ( b == KIND_SAMPLER || b == KIND_SAMPLER_HEAP_VIEW ); +} + +bool Tr2StaticResourceBindingsAL::Set( Kind kind, Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) +{ + for( auto& entry : m_entries ) + { + if( entry.stage != uint8_t( stage ) || entry.registerIndex != uint8_t( registerIndex ) || !SharesRegisterSpace( entry.kind, kind ) ) + { + continue; + } + if( entry.kind == kind && entry.sampler == sampler ) + { + return false; + } + entry.kind = kind; + entry.sampler = sampler; + return true; + } + + Entry entry; + entry.sampler = sampler; + entry.stage = uint8_t( stage ); + entry.registerIndex = uint8_t( registerIndex ); + entry.kind = kind; + m_entries.push_back( entry ); + return true; +} diff --git a/trinityal/src/upscaling/Tr2Fsr1Upscaling.cpp b/trinityal/src/upscaling/Tr2Fsr1Upscaling.cpp index 8611290af..42a4a266d 100644 --- a/trinityal/src/upscaling/Tr2Fsr1Upscaling.cpp +++ b/trinityal/src/upscaling/Tr2Fsr1Upscaling.cpp @@ -182,15 +182,9 @@ Tr2UpscalingAL::Result Tr2Fsr1UpscalingContext::Dispatch( Tr2UpscalingAL::Dispat renderContext.SetShaderProgram( m_easuProgram ); - Tr2ResourceSetDescriptionAL desc( m_easuProgram ); - desc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, FSR1::SRV_REGISTER_INDEX, *dispatchParameters.input ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, FSR1::UAV_REGISTER_INDEX, *dispatchParameters.output ); - desc.SetSampler( Tr2RenderContextEnum::COMPUTE_SHADER, 0, m_sampler ); - - Tr2ResourceSetAL resourceSet; - resourceSet.Create( desc, m_easuProgram, m_params.renderContext.GetPrimaryRenderContext() ); - - renderContext.SetResourceSet( resourceSet ); + renderContext.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, FSR1::SRV_REGISTER_INDEX, *dispatchParameters.input ); + renderContext.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, FSR1::UAV_REGISTER_INDEX, *dispatchParameters.output ); + renderContext.SetSampler( Tr2RenderContextEnum::COMPUTE_SHADER, 0, m_sampler ); renderContext.SetConstants( m_constantBuffer, Tr2RenderContextEnum::COMPUTE_SHADER, 0 ); diff --git a/trinityal/stub/Tr2RenderContextStub.cpp b/trinityal/stub/Tr2RenderContextStub.cpp index 797c1a342..eaff70566 100644 --- a/trinityal/stub/Tr2RenderContextStub.cpp +++ b/trinityal/stub/Tr2RenderContextStub.cpp @@ -305,7 +305,47 @@ ALResult Tr2RenderContextAL::SetRenderStates( const uint32_t*, uint32_t ) return S_OK; } -ALResult Tr2RenderContextAL::SetResourceSet( const Tr2ResourceSetAL& ) +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2TextureAL&, Tr2RenderContextEnum::ColorSpace ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2TextureAL&, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2SamplerStateAL& ) throw() +{ + return S_OK; +} + +ALResult Tr2RenderContextAL::ResetResourceBindings() throw() { return S_OK; } diff --git a/trinityal/stub/Tr2RenderContextStub.h b/trinityal/stub/Tr2RenderContextStub.h index 2d781346b..c702b4997 100644 --- a/trinityal/stub/Tr2RenderContextStub.h +++ b/trinityal/stub/Tr2RenderContextStub.h @@ -20,7 +20,6 @@ class Tr2VertexLayoutAL; class Tr2ShaderAL; class Tr2SamplerStateAL; class Tr2TextureAL; -class Tr2ResourceSetAL; class Tr2BufferAL; class Tr2RtShaderTableAL; class Tr2RtPipelineStateAL; @@ -111,7 +110,16 @@ class Tr2RenderContextAL return E_FAIL; } - ALResult SetResourceSet( const Tr2ResourceSetAL& resourceSet ); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetSrv( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2BufferAL& buffer ) throw(); + ALResult SetUav( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2TextureAL& texture, uint32_t mip = 0 ) throw(); + ALResult SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw(); + ALResult SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) throw(); + + ALResult ResetResourceBindings() throw(); ALResult DrawIndexedPrimitive( uint32_t numVertices, diff --git a/trinityal/stub/Tr2ResourceSetALStub.cpp b/trinityal/stub/Tr2ResourceSetALStub.cpp deleted file mode 100644 index 91c54f6ef..000000000 --- a/trinityal/stub/Tr2ResourceSetALStub.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#include "StdAfx.h" - -#if TRINITY_PLATFORM == TRINITY_STUB - -#include "Tr2ResourceSetALStub.h" - -namespace TrinityALImpl -{ -Tr2ResourceSetAL::Tr2ResourceSetAL() : - m_isValid( false ) -{ -} - -ALResult Tr2ResourceSetAL::Create( const Tr2ResourceSetDescriptionAL&, const ::Tr2ShaderProgramAL&, Tr2PrimaryRenderContextAL& ) -{ - m_isValid = true; - return S_OK; -} - -bool Tr2ResourceSetAL::IsValid() const -{ - return m_isValid; -} - -void Tr2ResourceSetAL::Destroy() -{ - m_isValid = false; -} - -Tr2ALMemoryType Tr2ResourceSetAL::GetMemoryClass() const -{ - return AL_MEMORY_MANAGED; -} - -void Tr2ResourceSetAL::Describe( Tr2DeviceResourceDescriptionAL& ) const -{ -} - -ALResult Tr2ResourceSetAL::SetName( const char* ) -{ - return S_OK; -} -} - -#endif \ No newline at end of file diff --git a/trinityal/stub/Tr2ResourceSetALStub.h b/trinityal/stub/Tr2ResourceSetALStub.h deleted file mode 100644 index 19198aca9..000000000 --- a/trinityal/stub/Tr2ResourceSetALStub.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2023 CCP ehf. - -#pragma once - -#if TRINITY_PLATFORM == TRINITY_STUB - -#include "../include/Tr2ResourceSetAL.h" - -namespace TrinityALImpl -{ -class Tr2ResourceSetAL : public Tr2DeviceResourceAL -{ -public: - Tr2ResourceSetAL(); - - ALResult Create( const Tr2ResourceSetDescriptionAL& description, const ::Tr2ShaderProgramAL& program, Tr2PrimaryRenderContextAL& renderContext ); - bool IsValid() const; - - void Destroy(); - Tr2ALMemoryType GetMemoryClass() const; - void Describe( Tr2DeviceResourceDescriptionAL& description ) const; - ALResult SetName( const char* name ); - -private: - bool m_isValid; -}; -} - -#endif \ No newline at end of file diff --git a/trinityal/stub/Tr2ShaderProgramALStub.h b/trinityal/stub/Tr2ShaderProgramALStub.h index a40bb55ec..8135bdc7f 100644 --- a/trinityal/stub/Tr2ShaderProgramALStub.h +++ b/trinityal/stub/Tr2ShaderProgramALStub.h @@ -5,7 +5,7 @@ #if TRINITY_PLATFORM == TRINITY_STUB #include "../include/Tr2ShaderProgramAL.h" -#include "../include/Tr2ResourceSetAL.h" +#include "../include/Tr2RegisterMapAL.h" namespace TrinityALImpl { diff --git a/trinityal/tests/Compute.cpp b/trinityal/tests/Compute.cpp index bfa33a5da..4a9320bad 100644 --- a/trinityal/tests/Compute.cpp +++ b/trinityal/tests/Compute.cpp @@ -31,17 +31,12 @@ TEST_F( Compute, CanReadCSResult ) Tr2BufferAL output; ASSERT_HRESULT_SUCCEEDED( output.Create( PIXEL_FORMAT_R32G32B32A32_FLOAT, 1, Tr2GpuUsage::UNORDERED_ACCESS, Tr2CpuUsage::READ, nullptr, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ); - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->RunComputeShader( 1, 1, 1 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( Tr2ResourceSetAL() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->ResetResourceBindings() ); const float* data; ASSERT_HRESULT_SUCCEEDED( output.MapForReading( data, *renderContext ) ); @@ -84,21 +79,14 @@ TEST_F( Compute, DISABLED_CanAddInCS ) Tr2BufferAL output; ASSERT_HRESULT_SUCCEEDED( output.Create( PIXEL_FORMAT_R32G32B32A32_FLOAT, 1, Tr2GpuUsage::UNORDERED_ACCESS, Tr2CpuUsage::READ, nullptr, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, arg1 ); - desc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, arg2 ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, arg1 ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, arg2 ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->RunComputeShader( 1, 1, 1 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( Tr2ResourceSetAL() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->ResetResourceBindings() ); const float* data; ASSERT_HRESULT_SUCCEEDED( output.MapForReading( data, *renderContext ) ); @@ -146,23 +134,15 @@ TEST_F( Compute, CanAddConstantInCS ) Tr2BufferAL output; ASSERT_HRESULT_SUCCEEDED( output.Create( PIXEL_FORMAT_R32G32B32A32_FLOAT, 1, Tr2GpuUsage::UNORDERED_ACCESS, Tr2CpuUsage::READ, nullptr, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, arg1 ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); - + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, arg1 ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( arg2, COMPUTE_SHADER, 1 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->RunComputeShader( 1, 1, 1 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( Tr2ResourceSetAL() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->ResetResourceBindings() ); const float* readData = nullptr; ASSERT_HRESULT_SUCCEEDED( output.MapForReading( readData, *renderContext ) ); @@ -222,21 +202,14 @@ TEST_F( Compute, DISABLED_CanRead2DTextureInCS ) Tr2BufferAL output; ASSERT_HRESULT_SUCCEEDED( output.Create( PIXEL_FORMAT_R32G32B32A32_FLOAT, 1, Tr2GpuUsage::UNORDERED_ACCESS, Tr2CpuUsage::READ, nullptr, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, input ); - desc.SetSampler( Tr2RenderContextEnum::COMPUTE_SHADER, 0, sampl ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 0, input ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::COMPUTE_SHADER, 0, sampl ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->RunComputeShader( 1, 1, 1 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( Tr2ResourceSetAL() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->ResetResourceBindings() ); const float* data; ASSERT_HRESULT_SUCCEEDED( output.MapForReading( data, *renderContext ) ); @@ -267,19 +240,12 @@ TEST_F( Compute, CanDispatchCSGroups ) Tr2BufferAL output; ASSERT_HRESULT_SUCCEEDED( output.Create( PIXEL_FORMAT_R32_UINT, 1, Tr2GpuUsage::UNORDERED_ACCESS, Tr2CpuUsage::READ, nullptr, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, output ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->RunComputeShader( 2, 2, 2 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( Tr2ResourceSetAL() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->ResetResourceBindings() ); const uint32_t* data; ASSERT_HRESULT_SUCCEEDED( output.MapForReading( data, *renderContext ) ); diff --git a/trinityal/tests/Raytracing.cpp b/trinityal/tests/Raytracing.cpp index 5ac5c879f..cef48ebb6 100644 --- a/trinityal/tests/Raytracing.cpp +++ b/trinityal/tests/Raytracing.cpp @@ -337,8 +337,7 @@ struct QuadRenderer }; CR_RETURN_HR( m_quadVb.Create( VB_STRIDE, sizeof( quad ) / VB_STRIDE, Tr2GpuUsage::VERTEX_BUFFER, Tr2CpuUsage::NONE, quad, *renderContext ) ); - Tr2SamplerStateAL sampl; - CR_RETURN_HR( sampl.Create( + CR_RETURN_HR( m_sampler.Create( Tr2SamplerDescription( Tr2RenderContextEnum::TF_POINT, Tr2RenderContextEnum::TA_WRAP, @@ -347,11 +346,7 @@ struct QuadRenderer 0.0f ), *renderContext ) ); - Tr2ResourceSetDescriptionAL resourceSetDescription( m_shaderProgram ); - resourceSetDescription.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, texture ); - resourceSetDescription.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - CR_RETURN_HR( m_resourceSet.Create( resourceSetDescription, m_shaderProgram, *renderContext ) ); + m_texture = texture; return S_OK; } @@ -364,7 +359,8 @@ struct QuadRenderer CR_RETURN_HR( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); CR_RETURN_HR( renderContext->SetStreamSource( 0, m_quadVb, 0, VB_STRIDE ) ); CR_RETURN_HR( renderContext->SetShaderProgram( m_shaderProgram ) ); - CR_RETURN_HR( renderContext->SetResourceSet( m_resourceSet ) ); + CR_RETURN_HR( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, m_texture ) ); + CR_RETURN_HR( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, m_sampler ) ); CR_RETURN_HR( renderContext->DrawPrimitive( 0, 2 ) ); return S_OK; } @@ -396,7 +392,8 @@ struct QuadRenderer } Tr2ShaderProgramAL m_shaderProgram; - Tr2ResourceSetAL m_resourceSet; + Tr2TextureAL m_texture; + Tr2SamplerStateAL m_sampler; Tr2BufferAL m_quadVb; Tr2VertexLayoutAL m_vertexLayout; static const uint32_t VB_STRIDE = 5 * sizeof( float ); @@ -503,17 +500,6 @@ TEST_F( Raytracing, TraceRays ) Tr2RtTopLevelAccelerationStructureAL tlas; ASSERT_HRESULT_SUCCEEDED( tlas.Create( 1, &instance, Tr2RtBuildFlags::PREFER_FAST_TRACE, *renderContext ) ); - auto shaderType = Tr2RenderContextEnum::COMPUTE_SHADER; - Tr2RegisterMapAL registerMap = Tr2RegisterMapAL( &shaderType, &signature, 1 ); - - // We need to insert a UAV barrier before using the acceleration structures in a raytracing - Tr2ResourceSetDescriptionAL rsDesc( registerMap ); - rsDesc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ); // accelerationStructure - rsDesc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, resultTex ); // RTOutput - - Tr2ResourceSetAL rs; - rs.Create( rsDesc, state, *renderContext ); - QuadRenderer quadRenderer; ASSERT_HRESULT_SUCCEEDED( quadRenderer.Create( resultTex, renderContext ) ); @@ -546,7 +532,9 @@ TEST_F( Raytracing, TraceRays ) ASSERT_HRESULT_SUCCEEDED( renderContext->ClearUav( resultTex, 0, clearColor ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::COMPUTE_SHADER, 0 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( rs ) ); + // We need to insert a UAV barrier before using the acceleration structures in a raytracing + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ) ); // accelerationStructure + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, resultTex ) ); // RTOutput // mac specific renderContext->UseAccelerationStructure( tlas ); @@ -629,17 +617,6 @@ TEST_F( Raytracing, CanUpdateBlas ) Tr2RtTopLevelAccelerationStructureAL tlas; ASSERT_HRESULT_SUCCEEDED( tlas.Create( 1, &instance, Tr2RtBuildFlags::PREFER_FAST_TRACE, *renderContext ) ); - auto shaderType = Tr2RenderContextEnum::COMPUTE_SHADER; - Tr2RegisterMapAL registerMap = Tr2RegisterMapAL( &shaderType, &signature, 1 ); - - // We need to insert a UAV barrier before using the acceleration structures in a raytracing - Tr2ResourceSetDescriptionAL rsDesc( registerMap ); - rsDesc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ); // accelerationStructure - rsDesc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, resultTex ); // RTOutput - - Tr2ResourceSetAL rs; - rs.Create( rsDesc, state, *renderContext ); - QuadRenderer quadRenderer; ASSERT_HRESULT_SUCCEEDED( quadRenderer.Create( resultTex, renderContext ) ); @@ -689,7 +666,9 @@ TEST_F( Raytracing, CanUpdateBlas ) ASSERT_HRESULT_SUCCEEDED( renderContext->ClearUav( resultTex, 0, clearColor ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::COMPUTE_SHADER, 0 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( rs ) ); + // We need to insert a UAV barrier before using the acceleration structures in a raytracing + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ) ); // accelerationStructure + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, resultTex ) ); // RTOutput // mac specific renderContext->UseAccelerationStructure( tlas ); @@ -805,16 +784,6 @@ TEST_F( Raytracing, CanUseLocalConstants ) Tr2RtTopLevelAccelerationStructureAL tlas; ASSERT_HRESULT_SUCCEEDED( tlas.Create( 2, instances, Tr2RtBuildFlags::PREFER_FAST_TRACE, *renderContext ) ); - auto shaderType = Tr2RenderContextEnum::COMPUTE_SHADER; - Tr2RegisterMapAL registerMap = Tr2RegisterMapAL( &shaderType, &globalSignature, 1 ); - - Tr2ResourceSetDescriptionAL rsDesc( registerMap ); - rsDesc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ); - rsDesc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, result ); - - Tr2ResourceSetAL rs; - rs.Create( rsDesc, state, *renderContext ); - QuadRenderer quadRenderer; ASSERT_HRESULT_SUCCEEDED( quadRenderer.Create( result, renderContext ) ); @@ -850,7 +819,8 @@ TEST_F( Raytracing, CanUseLocalConstants ) ASSERT_HRESULT_SUCCEEDED( renderContext->ClearUav( result, 0, clearColor ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::COMPUTE_SHADER, 0 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( rs ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, result ) ); renderContext->UseAccelerationStructure( tlas ); @@ -990,16 +960,6 @@ TEST_F( Raytracing, CanUsePerObjectData ) Tr2RtTopLevelAccelerationStructureAL tlas; ASSERT_HRESULT_SUCCEEDED( tlas.Create( 2, instances, Tr2RtBuildFlags::PREFER_FAST_TRACE, *renderContext ) ); - auto shaderType = Tr2RenderContextEnum::COMPUTE_SHADER; - Tr2RegisterMapAL registerMap = Tr2RegisterMapAL( &shaderType, &globalSignature, 1 ); - - Tr2ResourceSetDescriptionAL rsDesc( registerMap ); - rsDesc.SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ); - rsDesc.SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, result ); - - Tr2ResourceSetAL rs; - rs.Create( rsDesc, state, *renderContext ); - QuadRenderer quadRenderer; ASSERT_HRESULT_SUCCEEDED( quadRenderer.Create( result, renderContext ) ); @@ -1035,7 +995,8 @@ TEST_F( Raytracing, CanUsePerObjectData ) ASSERT_HRESULT_SUCCEEDED( renderContext->ClearUav( result, 0, clearColor ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::COMPUTE_SHADER, 0 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( rs ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::COMPUTE_SHADER, 1, tlas.GetBuffer() ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::COMPUTE_SHADER, 0, result ) ); renderContext->UseAccelerationStructure( tlas ); diff --git a/trinityal/tests/Rendering.cpp b/trinityal/tests/Rendering.cpp index 0d520b75e..8a2211438 100644 --- a/trinityal/tests/Rendering.cpp +++ b/trinityal/tests/Rendering.cpp @@ -521,13 +521,6 @@ TEST_F( Rendering, CanSampleTexture ) uint32_t g = 127; - Tr2ResourceSetDescriptionAL resourceSetDescription( sp ); - resourceSetDescription.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - resourceSetDescription.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( resourceSetDescription, sp, *renderContext ) ); - auto frame = [&] { ASSERT_HRESULT_SUCCEEDED( renderContext->BeginScene() ); ASSERT_HRESULT_SUCCEEDED( renderContext->Clear( Tr2RenderContextEnum::CLEARFLAGS_TARGET, 0xff000000 | ( g & 0xff ), 1.0f ) ); @@ -538,7 +531,8 @@ TEST_F( Rendering, CanSampleTexture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 1 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -648,14 +642,6 @@ TEST_F( Rendering, CanSampleMipMappedTexture ) std::numeric_limits::max() ), *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - ASSERT_HRESULT_SUCCEEDED( renderContext->BeginScene() ); ASSERT_HRESULT_SUCCEEDED( renderContext->Clear( Tr2RenderContextEnum::CLEARFLAGS_TARGET, 0xff000000 | ( g & 0xff ), 1.0f ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetStreamSource( 0, vb, 0, vbStride ) ); @@ -665,7 +651,8 @@ TEST_F( Rendering, CanSampleMipMappedTexture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 1 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -898,14 +885,6 @@ TEST_F( Rendering, CanClearRenderTarget ) Tr2TextureAL rt; ASSERT_HRESULT_SUCCEEDED( rt.Create( Tr2BitmapDimensions( 128, 64, 1, Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2GpuUsage::RENDER_TARGET | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - - uint32_t g = 127; auto frame = [&] { @@ -926,7 +905,8 @@ TEST_F( Rendering, CanClearRenderTarget ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -1017,14 +997,6 @@ TEST_F( Rendering, CanRenderToRenderTarget ) Tr2TextureAL rt; ASSERT_HRESULT_SUCCEEDED( rt.Create( Tr2BitmapDimensions( 128, 64, 1, Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2GpuUsage::RENDER_TARGET | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -1055,7 +1027,8 @@ TEST_F( Rendering, CanRenderToRenderTarget ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -1149,14 +1122,6 @@ TEST_F( Rendering, CanRenderToMsaaRenderTarget ) Tr2TextureAL readableRt; ASSERT_HRESULT_SUCCEEDED( readableRt.Create( Tr2BitmapDimensions( 128, 64, 1, Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2GpuUsage::RENDER_TARGET | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, readableRt ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -1189,7 +1154,8 @@ TEST_F( Rendering, CanRenderToMsaaRenderTarget ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, readableRt ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -1481,14 +1447,6 @@ TEST_F( Rendering, CanSampleDepthBuffer ) Tr2GpuUsage::DEPTH_STENCIL | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - Tr2ResourceSetDescriptionAL resourceSetDescription( sp2 ); - resourceSetDescription.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, depthBuffer ); - resourceSetDescription.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( resourceSetDescription, sp2, *renderContext ) ); - - uint32_t g = 127; auto frame = [&] { @@ -1514,7 +1472,8 @@ TEST_F( Rendering, CanSampleDepthBuffer ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetStreamSource( 0, quadVb, 0, vbStride ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp2 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, depthBuffer ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); renderContext->SetReadOnlyDepth( false ); @@ -2002,14 +1961,6 @@ TEST_F( Rendering, CanPerformAlphaBlend ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2024,7 +1975,8 @@ TEST_F( Rendering, CanPerformAlphaBlend ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_SRCBLEND, Tr2RenderContextEnum::BM_SRCALPHA ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_DESTBLEND, Tr2RenderContextEnum::BM_INVSRCALPHA ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -2160,14 +2112,6 @@ TEST_F( Rendering, CanGenerateRenderTargetMips ) std::numeric_limits::max() ); ASSERT_HRESULT_SUCCEEDED( sampler.Create( samplerDesc, *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampler ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2199,7 +2143,8 @@ TEST_F( Rendering, CanGenerateRenderTargetMips ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampler ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); for( uint32_t i = 0; i < 8; ++i ) @@ -2304,14 +2249,6 @@ TEST_F( Rendering, CanCopyRenderTargetRegion ) Tr2TextureAL rt2; ASSERT_HRESULT_SUCCEEDED( rt2.Create( Tr2BitmapDimensions( 256, 256, 1, Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2GpuUsage::RENDER_TARGET | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt2 ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2351,7 +2288,8 @@ TEST_F( Rendering, CanCopyRenderTargetRegion ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt2 ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -2436,14 +2374,6 @@ TEST_F( Rendering, CanSampleBc1Texture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2456,7 +2386,8 @@ TEST_F( Rendering, CanSampleBc1Texture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); @@ -2612,14 +2543,6 @@ TEST_F( Rendering, CanSampleBc2Texture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2632,7 +2555,8 @@ TEST_F( Rendering, CanSampleBc2Texture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); @@ -2719,14 +2643,6 @@ TEST_F( Rendering, CanSampleBc3Texture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -2739,7 +2655,8 @@ TEST_F( Rendering, CanSampleBc3Texture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); @@ -2827,14 +2744,6 @@ TEST_F( Rendering, CanSampleVolumeTexture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; @@ -2857,7 +2766,8 @@ TEST_F( Rendering, CanSampleVolumeTexture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::PIXEL_SHADER, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); @@ -2946,14 +2856,6 @@ TEST_F( Rendering, CanSampleBc3VolumeTexture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; @@ -2976,7 +2878,8 @@ TEST_F( Rendering, CanSampleBc3VolumeTexture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetConstants( cb, Tr2RenderContextEnum::PIXEL_SHADER, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLE_STRIP ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); @@ -3161,14 +3064,6 @@ TEST_F( Rendering, CanLockTextureTwice ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -3187,7 +3082,8 @@ TEST_F( Rendering, CanLockTextureTwice ) *reinterpret_cast( data ) = 0xffff0000; tex.UnmapForWriting( *renderContext ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetStreamSource( 0, vb1, 0, vbStride ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); @@ -3294,14 +3190,6 @@ TEST_F( Rendering, CanSampleSrgbTexture ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex, Tr2RenderContextEnum::COLOR_SPACE_SRGB ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -3314,7 +3202,8 @@ TEST_F( Rendering, CanSampleSrgbTexture ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex, Tr2RenderContextEnum::COLOR_SPACE_SRGB ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -3410,14 +3299,6 @@ TEST_F( Rendering, CanOutputToSrgbTarget ) 0.0f ), *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex, Tr2RenderContextEnum::COLOR_SPACE_SRGB ); - desc.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -3431,7 +3312,8 @@ TEST_F( Rendering, CanOutputToSrgbTarget ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, tex, Tr2RenderContextEnum::COLOR_SPACE_SRGB ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); @@ -3493,14 +3375,6 @@ TEST_F( Rendering, CanUsePsUavs ) Tr2TextureAL rwTexture; ASSERT_HRESULT_SUCCEEDED( rwTexture.Create( Tr2BitmapDimensions( 64, 64, 1, PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2GpuUsage::SHADER_RESOURCE | Tr2GpuUsage::UNORDERED_ACCESS, *renderContext ) ); - Tr2ResourceSetAL uavResourceSet; - { - Tr2ResourceSetDescriptionAL resourceSetDescription( sp ); - resourceSetDescription.SetUav( Tr2RenderContextEnum::PIXEL_SHADER, 1, rwTexture ); - ASSERT_HRESULT_SUCCEEDED( uavResourceSet.Create( resourceSetDescription, sp, *renderContext ) ); - } - - float quad[] = { 0, 0, @@ -3555,15 +3429,6 @@ TEST_F( Rendering, CanUsePsUavs ) Tr2ShaderProgramAL sp2; ASSERT_HRESULT_SUCCEEDED( sp2.Create( shaders2, 2, *renderContext ) ); - - Tr2ResourceSetDescriptionAL resourceSetDescription( sp2 ); - resourceSetDescription.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rwTexture ); - resourceSetDescription.SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( resourceSetDescription, sp2, *renderContext ) ); - - uint32_t g = 127; auto frame = [&] { @@ -3576,7 +3441,7 @@ TEST_F( Rendering, CanUsePsUavs ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetStreamSource( 0, vb, 0, vbStride ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetVertexLayout( vertexLayout ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( uavResourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetUav( Tr2RenderContextEnum::PIXEL_SHADER, 1, rwTexture ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetTopology( Tr2RenderContextEnum::TOP_TRIANGLES ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); @@ -3584,7 +3449,8 @@ TEST_F( Rendering, CanUsePsUavs ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetStreamSource( 0, quadVb, 0, vbStride ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetShaderProgram( sp2 ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rwTexture ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSampler( Tr2RenderContextEnum::PIXEL_SHADER, 0, sampl ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); @@ -4017,13 +3883,6 @@ TEST_F( Rendering, CanLoadMsaaRenderTarget ) Tr2TextureAL rt; ASSERT_HRESULT_SUCCEEDED( rt.Create( Tr2BitmapDimensions( 128, 64, 1, Tr2RenderContextEnum::PIXEL_FORMAT_B8G8R8A8_UNORM ), Tr2MsaaDesc( 4 ), Tr2GpuUsage::RENDER_TARGET | Tr2GpuUsage::SHADER_RESOURCE, *renderContext ) ); - - Tr2ResourceSetDescriptionAL desc( sp ); - desc.SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ); - - Tr2ResourceSetAL resourceSet; - ASSERT_HRESULT_SUCCEEDED( resourceSet.Create( desc, sp, *renderContext ) ); - uint32_t g = 127; auto frame = [&] { @@ -4054,7 +3913,7 @@ TEST_F( Rendering, CanLoadMsaaRenderTarget ) ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ZENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_ALPHABLENDENABLE, 0 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->SetRenderState( Tr2RenderContextEnum::RS_CULLMODE, Tr2RenderContextEnum::CULLMODE_NONE ) ); - ASSERT_HRESULT_SUCCEEDED( renderContext->SetResourceSet( resourceSet ) ); + ASSERT_HRESULT_SUCCEEDED( renderContext->SetSrv( Tr2RenderContextEnum::PIXEL_SHADER, 0, rt ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->DrawPrimitive( 0, 2 ) ); ASSERT_HRESULT_SUCCEEDED( renderContext->EndScene() ); MakeTestScreenShot(); From bedc3415066841275a9413c59d6e731eb4db2e23 Mon Sep 17 00:00:00 2001 From: JohnGreenCCP Date: Wed, 9 Sep 2026 12:29:39 +0100 Subject: [PATCH 2/5] PLAT-9853: Metal direct resource bindings replace resource sets --- .../Eve/SpaceObject/Children/EveChildMesh.cpp | 2 +- trinityal/metal/Tr2RenderContextMetal.h | 56 ++- trinityal/metal/Tr2RenderContextMetal.mm | 406 +++++++++++++++++- trinityal/metal/Tr2ShaderALMetal.h | 1 + trinityal/metal/Tr2ShaderProgramALMetal.h | 2 - trinityal/metal/Tr2ShaderProgramALMetal.mm | 39 -- 6 files changed, 441 insertions(+), 65 deletions(-) diff --git a/trinity/Eve/SpaceObject/Children/EveChildMesh.cpp b/trinity/Eve/SpaceObject/Children/EveChildMesh.cpp index a8d8aa20f..7eed6cfa1 100644 --- a/trinity/Eve/SpaceObject/Children/EveChildMesh.cpp +++ b/trinity/Eve/SpaceObject/Children/EveChildMesh.cpp @@ -883,7 +883,7 @@ Tr2PerObjectData* EveChildMesh::GetPerObjectData( ITriRenderBatchAccumulator* ac if( m_animationUpdater && m_animationUpdater->IsInitialized() ) { auto meshIndex = m_mesh->GetMeshIndex(); - if( auto mesh = m_mesh->GetGeometryResource()->GetMeshData( meshIndex ) ) + if( m_mesh->GetGeometryResource()->GetMeshData( meshIndex ) ) { auto lod = m_mesh->GetGeometryResource()->GetMeshLod( meshIndex, m_currentScreenSize ); if( lod->m_morphTargetAllocation.IsValid() ) diff --git a/trinityal/metal/Tr2RenderContextMetal.h b/trinityal/metal/Tr2RenderContextMetal.h index 12863a688..d880fb3c3 100644 --- a/trinityal/metal/Tr2RenderContextMetal.h +++ b/trinityal/metal/Tr2RenderContextMetal.h @@ -12,6 +12,7 @@ #include "../include/Tr2SamplerStateAL.h" #include "../include/Tr2BufferAL.h" #include "../include/Tr2ShaderProgramAL.h" +#include "../include/Tr2RegisterMapAL.h" #include "../include/Tr2VertexLayoutAL.h" #include "../include/Tr2ConstantBufferAL.h" #include "../include/Tr2RenderPassAL.h" @@ -314,8 +315,61 @@ class Tr2RenderContextAL Tr2ShaderProgramAL m_shaderProgram; Tr2VertexLayoutAL m_vertexLayout; - bool m_needsDrawResourceCheck; +private: + struct Resource + { + enum Type + { + NONE, + BUFFER, + TEXTURE, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2TextureAL texture; + Tr2BufferAL buffer; + Type type = NONE; + union + { + Tr2RenderContextEnum::ColorSpace colorSpace = Tr2RenderContextEnum::COLOR_SPACE_LINEAR; + uint32_t mip; + }; + }; + + struct Sampler + { + enum Type + { + NONE, + SAMPLER, + HEAP_VIEW, + }; + + Tr2RenderContextEnum::ShaderType stage = Tr2RenderContextEnum::INVALID_SHADER; + uint32_t registerIndex = 0; + Tr2SamplerStateAL sampler; + Type type = NONE; + }; + + std::vector m_pendingSRVs; + std::vector m_pendingUAVs; + std::vector m_pendingSamplers; + + const Resource* m_sortedSRVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedUAVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Sampler* m_sortedSamplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + bool m_bindingsCommitted; + bool m_bindingsSealed; + const TrinityALImpl::Tr2ShaderProgramAL* m_committedProgram; + + ALResult UseResourceBindings() throw(); + void BeginResourceBindingBatch() throw(); + void DiscardResourceBindings() throw(); + +protected: struct MetalPrimitiveInfo { MTLPrimitiveType metalPrimitiveType; diff --git a/trinityal/metal/Tr2RenderContextMetal.mm b/trinityal/metal/Tr2RenderContextMetal.mm index f1e962fb6..aa525010b 100644 --- a/trinityal/metal/Tr2RenderContextMetal.mm +++ b/trinityal/metal/Tr2RenderContextMetal.mm @@ -14,6 +14,7 @@ #include "Tr2VertexLayoutALMetal.h" #include "Tr2ShaderProgramALMetal.h" #include "Tr2TextureALMetal.h" +#include "Tr2SamplerStateALMetal.h" #include "Tr2SwapChainALMetal.h" #include "Tr2RtPipelineStateALMetal.h" #include "Tr2RtShaderTableALMetal.h" @@ -77,7 +78,10 @@ MTLClearColor MakeClearColor( uint32_t color ) m_srgbWriteEnable( false ), m_isPrimary( false ), m_caps(), - m_upscalingTechnique( nullptr ) + m_upscalingTechnique( nullptr ), + m_bindingsCommitted( false ), + m_bindingsSealed( false ), + m_committedProgram( nullptr ) { } @@ -119,7 +123,6 @@ MTLClearColor MakeClearColor( uint32_t color ) m_caMetalLayer = nil; m_defaultBackBuffer.m_texture = std::make_shared(); m_boundDepthStencil.m_texture = nullptr; - m_needsDrawResourceCheck = true; m_swapChain.m_swapChain = std::make_shared(); } @@ -151,6 +154,7 @@ MTLClearColor MakeClearColor( uint32_t color ) m_boundRenderTargets[i] = {}; } m_boundDepthStencil = Tr2TextureAL(); + DiscardResourceBindings(); m_isValid = false; } @@ -521,12 +525,7 @@ MTLClearColor MakeClearColor( uint32_t color ) void Tr2RenderContextAL::CheckDrawResources() { - // Only need to check resources if the shader has changed since the last draw. - if( m_needsDrawResourceCheck ) - { - m_shaderProgram.m_program->SetDummyResources( *m_workQueue ); - m_needsDrawResourceCheck = false; - } + UseResourceBindings(); if( m_vertexLayout.IsValid() ) { @@ -615,6 +614,8 @@ MTLClearColor MakeClearColor( uint32_t color ) ALResult Tr2RenderContextAL::RunComputeShader( unsigned groupDimX, unsigned groupDimY, unsigned groupDimZ ) { + UseResourceBindings(); + m_workQueue->Dispatch( groupDimX, groupDimY, groupDimZ ); return S_OK; @@ -627,6 +628,8 @@ MTLClearColor MakeClearColor( uint32_t color ) return E_FAIL; } + UseResourceBindings(); + m_workQueue->Dispatch( indirectParams.m_buffer->GetMetalBuffer(), offset ); return S_OK; @@ -652,6 +655,7 @@ MTLClearColor MakeClearColor( uint32_t color ) { // pass on shaderTable to bind it to the RayGen shader SetShaderProgram( pipeline.TrinityALImpl_GetObject()->GetShaderProgram( *rayGen ) ); + UseResourceBindings(); m_workQueue->DispatchRays( pipeline.TrinityALImpl_GetObject(), shaderTable.TrinityALImpl_GetObject(), *rayGen, width, height, depth ); } @@ -868,7 +872,6 @@ MTLClearColor MakeClearColor( uint32_t color ) m_vertexLayout = Tr2VertexLayoutAL(); m_shaderProgram = Tr2ShaderProgramAL(); - m_needsDrawResourceCheck = true; return S_OK; } @@ -911,7 +914,7 @@ MTLClearColor MakeClearColor( uint32_t color ) shaderProgram.m_program->GetThreadGroupSize(), shaderProgram.m_program->GetResourceMasks() ); - m_needsDrawResourceCheck = true; + m_bindingsCommitted = false; return S_OK; } @@ -1131,51 +1134,411 @@ MTLClearColor MakeClearColor( uint32_t color ) return S_OK; } -ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2BufferAL& buffer ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType, - uint32_t, - const Tr2TextureAL&, - Tr2RenderContextEnum::ColorSpace ) throw() +ALResult Tr2RenderContextAL::SetSrv( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2TextureAL& texture, + Tr2RenderContextEnum::ColorSpace colorSpace ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.colorSpace = colorSpace; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2BufferAL& ) throw() +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2BufferAL& buffer ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::BUFFER; + resource.buffer = buffer; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2TextureAL&, uint32_t ) throw() +ALResult Tr2RenderContextAL::SetUav( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2TextureAL& texture, + uint32_t mip ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::TEXTURE; + resource.texture = texture; + resource.mip = mip; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +ALResult Tr2RenderContextAL::SetSrvHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingSRVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +ALResult Tr2RenderContextAL::SetUavHeapView( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Resource resource; + resource.stage = stage; + resource.registerIndex = registerIndex; + resource.type = Resource::HEAP_VIEW; + m_pendingUAVs.push_back( resource ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType, uint32_t ) throw() +ALResult Tr2RenderContextAL::SetSamplerHeapView( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::HEAP_VIEW; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; return S_OK; } -ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType, uint32_t, const Tr2SamplerStateAL& ) throw() +ALResult Tr2RenderContextAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, + uint32_t registerIndex, + const Tr2SamplerStateAL& sampler ) throw() { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return E_INVALIDARG; + } + BeginResourceBindingBatch(); + + Sampler entry; + entry.stage = stage; + entry.registerIndex = registerIndex; + entry.type = Sampler::SAMPLER; + entry.sampler = sampler; + m_pendingSamplers.push_back( entry ); + + m_bindingsCommitted = false; return S_OK; } ALResult Tr2RenderContextAL::ResetResourceBindings() throw() { + DiscardResourceBindings(); + return S_OK; +} + +void Tr2RenderContextAL::BeginResourceBindingBatch() throw() +{ + if( !m_bindingsSealed ) + { + return; + } + + m_bindingsSealed = false; + m_bindingsCommitted = false; + + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); +} + +void Tr2RenderContextAL::DiscardResourceBindings() throw() +{ + m_pendingSRVs.clear(); + m_pendingUAVs.clear(); + m_pendingSamplers.clear(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + m_bindingsCommitted = false; + m_bindingsSealed = false; + m_committedProgram = nullptr; +} + +ALResult Tr2RenderContextAL::UseResourceBindings() throw() +{ + if( !m_shaderProgram.IsValid() ) + { + return S_OK; + } + + const TrinityALImpl::Tr2ShaderProgramAL& program = *m_shaderProgram.m_program; + if( m_bindingsCommitted && m_committedProgram == &program ) + { + return S_OK; + } + + const Tr2RegisterMapAL& registerMap = program.GetRegisterMap(); + const TrinityALImpl::ShaderResourceMask* resourceMasks = program.GetResourceMasks(); + + std::fill( std::begin( m_sortedSRVs ), std::end( m_sortedSRVs ), nullptr ); + std::fill( std::begin( m_sortedUAVs ), std::end( m_sortedUAVs ), nullptr ); + std::fill( std::begin( m_sortedSamplers ), std::end( m_sortedSamplers ), nullptr ); + + for( const auto& resource : m_pendingSRVs ) + { + uint32_t index = registerMap.srvs[resource.stage][resource.registerIndex]; + if( index < registerMap.srvCount ) + { + m_sortedSRVs[index] = &resource; + } + } + for( const auto& resource : m_pendingUAVs ) + { + uint32_t index = registerMap.uavs[resource.stage][resource.registerIndex]; + if( index < registerMap.uavCount ) + { + m_sortedUAVs[index] = &resource; + } + } + for( const auto& sampler : m_pendingSamplers ) + { + uint32_t index = registerMap.samplers[sampler.stage][sampler.registerIndex]; + if( index < registerMap.samplerCount ) + { + m_sortedSamplers[index] = &sampler; + } + } + + TrinityALImpl::MetalContext* metalContext = GetMetalContext(); + id heapView = metalContext->GetHeapViewBuffer(); + + const ShaderType stages[] = { VERTEX_SHADER, PIXEL_SHADER, COMPUTE_SHADER }; + for( auto stage : stages ) + { + id buffers[METAL_MAX_BOUND_BUFFERS] = {}; + id textures[METAL_MAX_BOUND_TEXTURES] = {}; + id samplers[METAL_MAX_BOUND_SAMPLERS] = {}; + + uint32_t buffersMask = 0; + uint32_t heapViewMask = 0; + NSUInteger texturesMin = NSUIntegerMax; + NSUInteger texturesMax = 0; + NSUInteger samplersMin = NSUIntegerMax; + NSUInteger samplersMax = 0; + + // Resources the shader declares but nothing bound; filled with dummies below. + uint32_t missingTextureMask = resourceMasks[stage].textureMask; + uint32_t missingSamplerMask = resourceMasks[stage].samplerMask; + + for( uint32_t reg = 0; reg < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; ++reg ) + { + const uint32_t srvIndex = registerMap.srvs[stage][reg]; + if( srvIndex < registerMap.srvCount ) + { + const Resource* resource = m_sortedSRVs[srvIndex]; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::BUFFER: + if( resource->buffer.IsValid() && reg < METAL_SRV_BUFFER_COUNT ) + { + const NSUInteger bufferIndex = METAL_SRV_BUFFER_OFFSET + reg; + buffers[bufferIndex] = resource->buffer.m_buffer->GetMetalBuffer(); + buffersMask |= ( 1u << bufferIndex ); + } + break; + case Resource::TEXTURE: + if( resource->texture.IsValid() && reg < METAL_SRV_TEXTURE_COUNT ) + { + const NSUInteger texIndex = METAL_SRV_TEXTURE_OFFSET + reg; + textures[texIndex] = ( resource->colorSpace == COLOR_SPACE_SRGB ) ? + resource->texture.m_texture->GetSRGBViewMetalTexture() : + resource->texture.m_texture->GetMetalTexture(); + texturesMin = std::min( texturesMin, texIndex ); + texturesMax = std::max( texturesMax, texIndex ); + missingTextureMask &= ~( 1u << texIndex ); + } + break; + case Resource::HEAP_VIEW: + if( reg < METAL_SRV_BUFFER_COUNT ) + { + heapViewMask |= ( 1u << ( METAL_SRV_BUFFER_OFFSET + reg ) ); + } + break; + default: + break; + } + } + + const uint32_t uavIndex = registerMap.uavs[stage][reg]; + if( uavIndex < registerMap.uavCount ) + { + const Resource* resource = m_sortedUAVs[uavIndex]; + switch( resource ? resource->type : Resource::NONE ) + { + case Resource::BUFFER: + if( resource->buffer.IsValid() && reg < METAL_UAV_BUFFER_COUNT ) + { + const NSUInteger bufferIndex = METAL_UAV_BUFFER_OFFSET + reg; + buffers[bufferIndex] = resource->buffer.m_buffer->GetMetalBuffer(); + buffersMask |= ( 1u << bufferIndex ); + } + break; + case Resource::TEXTURE: + if( resource->texture.IsValid() && reg < METAL_UAV_TEXTURE_COUNT ) + { + const NSUInteger texIndex = METAL_UAV_TEXTURE_OFFSET + reg; + textures[texIndex] = resource->texture.m_texture->GetUAVMetalTexture( resource->mip ); + texturesMin = std::min( texturesMin, texIndex ); + texturesMax = std::max( texturesMax, texIndex ); + missingTextureMask &= ~( 1u << texIndex ); + } + break; + case Resource::HEAP_VIEW: + if( reg < METAL_UAV_BUFFER_COUNT ) + { + heapViewMask |= ( 1u << ( METAL_UAV_BUFFER_OFFSET + reg ) ); + } + break; + default: + break; + } + } + + const uint32_t samplerIndex = registerMap.samplers[stage][reg]; + if( samplerIndex < registerMap.samplerCount ) + { + const Sampler* sampler = m_sortedSamplers[samplerIndex]; + switch( sampler ? sampler->type : Sampler::NONE ) + { + case Sampler::SAMPLER: + if( sampler->sampler.IsValid() && reg < METAL_MAX_BOUND_SAMPLERS ) + { + samplers[reg] = sampler->sampler.m_sampler->GetMetalSamplerState(); + samplersMin = std::min( samplersMin, reg ); + samplersMax = std::max( samplersMax, reg ); + missingSamplerMask &= ~( 1u << reg ); + } + break; + case Sampler::HEAP_VIEW: + if( reg < METAL_SRV_BUFFER_COUNT ) + { + heapViewMask |= ( 1u << ( METAL_SRV_BUFFER_OFFSET + reg ) ); + } + break; + default: + break; + } + } + } + + for( uint32_t index = 0; missingTextureMask && index < METAL_MAX_BOUND_TEXTURES; + missingTextureMask >>= 1, ++index ) + { + if( missingTextureMask & 0x1 ) + { + textures[index] = metalContext->GetDummyTexture( MTLTextureType( resourceMasks[stage].textureTypes[index] ) ); + texturesMin = std::min( texturesMin, index ); + texturesMax = std::max( texturesMax, index ); + } + } + + for( uint32_t index = 0; missingSamplerMask && index < METAL_MAX_BOUND_SAMPLERS; + missingSamplerMask >>= 1, ++index ) + { + if( missingSamplerMask & 0x1 ) + { + samplers[index] = metalContext->GetDummySampler(); + samplersMin = std::min( samplersMin, index ); + samplersMax = std::max( samplersMax, index ); + } + } + + m_workQueue->SetBuffers( stage, buffers, buffersMask, heapView, heapViewMask ); + m_workQueue->SetTextures( stage, + textures, + ( texturesMin != NSUIntegerMax ) ? + NSMakeRange( texturesMin, texturesMax - texturesMin + 1 ) : + NSMakeRange( 0, 0 ) ); + m_workQueue->SetSamplers( stage, + samplers, + ( samplersMin != NSUIntegerMax ) ? + NSMakeRange( samplersMin, samplersMax - samplersMin + 1 ) : + NSMakeRange( 0, 0 ) ); + } + + m_bindingsCommitted = true; + m_bindingsSealed = true; + m_committedProgram = &program; return S_OK; } @@ -1402,7 +1765,6 @@ MTLClearColor MakeClearColor( uint32_t color ) context->m_vertexLayout = Tr2VertexLayoutAL(); context->m_shaderProgram = Tr2ShaderProgramAL(); - context->m_needsDrawResourceCheck = true; return S_OK; } diff --git a/trinityal/metal/Tr2ShaderALMetal.h b/trinityal/metal/Tr2ShaderALMetal.h index 267242d3c..11a1f6219 100644 --- a/trinityal/metal/Tr2ShaderALMetal.h +++ b/trinityal/metal/Tr2ShaderALMetal.h @@ -5,6 +5,7 @@ #if TRINITY_PLATFORM == TRINITY_METAL #include "../include/Tr2ShaderAL.h" +#include "MetalWorkQueue.h" namespace TrinityALImpl diff --git a/trinityal/metal/Tr2ShaderProgramALMetal.h b/trinityal/metal/Tr2ShaderProgramALMetal.h index 23bb01931..a525160b6 100644 --- a/trinityal/metal/Tr2ShaderProgramALMetal.h +++ b/trinityal/metal/Tr2ShaderProgramALMetal.h @@ -37,8 +37,6 @@ class Tr2ShaderProgramAL : public Tr2DeviceResourceAL const std::vector& GetInputs() const; size_t GetInputsHash() const; - void SetDummyResources( TrinityALImpl::MetalWorkQueue& workQueue ); - private: id CompileShader( const ::Tr2ShaderAL& shader, NSString* entryFunction, Tr2PrimaryRenderContextAL& renderContext ); diff --git a/trinityal/metal/Tr2ShaderProgramALMetal.mm b/trinityal/metal/Tr2ShaderProgramALMetal.mm index f61fc9981..3629caf19 100644 --- a/trinityal/metal/Tr2ShaderProgramALMetal.mm +++ b/trinityal/metal/Tr2ShaderProgramALMetal.mm @@ -262,44 +262,5 @@ } return S_OK; } - -void Tr2ShaderProgramAL::SetDummyResources( TrinityALImpl::MetalWorkQueue& workQueue ) -{ - for( uint32_t i = 0; i < Tr2RenderContextEnum::SHADER_TYPE_COUNT; ++i ) - { - Tr2RenderContextEnum::ShaderType shaderType = (Tr2RenderContextEnum::ShaderType)i; - - // If there's not resource set then we need to set dummies for all textures and samplers. - uint32_t missingTextureMask = m_resourceMask[i].textureMask; - uint32_t missingSamplerMask = m_resourceMask[i].samplerMask; - - if( !missingTextureMask && !missingSamplerMask ) - { - continue; - } - - // Set any missing textures and samplers to the dummy object. - uint32_t index = 0; - while( missingTextureMask && missingSamplerMask ) - { - if( missingTextureMask & 0x1 ) - { - auto dummyTexture = - m_metalContext->GetDummyTexture( MTLTextureType( m_resourceMask[i].textureTypes[index] ) ); - workQueue.SetTextures( shaderType, &dummyTexture, NSMakeRange( index, 1 ) ); - } - missingTextureMask >>= 1; - - if( missingSamplerMask & 0x1 ) - { - auto dummySampler = m_metalContext->GetDummySampler(); - workQueue.SetSamplers( shaderType, &dummySampler, NSMakeRange( index, 1 ) ); - } - missingSamplerMask >>= 1; - - ++index; - } - } -} } #endif From f09a2a9cc9e2009d090d80d8e5718a9b3765aecb Mon Sep 17 00:00:00 2001 From: JohnGreenCCP Date: Thu, 27 Aug 2026 10:56:10 +0100 Subject: [PATCH 3/5] Skip invalid sampler registers in static resource bindings Bindless sampler handles appear as fake sampler registers (100+) in the effect description. Binding them failed and stopped the remaining static bindings, including the bindless texture heap view, from being applied, so shaders like specialfx/ubershader read the wrong textures. --- trinityal/src/Tr2StaticResourceBindingsAL.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/trinityal/src/Tr2StaticResourceBindingsAL.cpp b/trinityal/src/Tr2StaticResourceBindingsAL.cpp index c441518f2..2f6622b68 100644 --- a/trinityal/src/Tr2StaticResourceBindingsAL.cpp +++ b/trinityal/src/Tr2StaticResourceBindingsAL.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "../include/Tr2StaticResourceBindingsAL.h" #include "../include/Tr2RenderContextAL.h" +#include "../include/Tr2RegisterMapAL.h" bool Tr2StaticResourceBindingsAL::SetSampler( Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) @@ -92,6 +93,10 @@ bool Tr2StaticResourceBindingsAL::SharesRegisterSpace( Kind a, Kind b ) bool Tr2StaticResourceBindingsAL::Set( Kind kind, Tr2RenderContextEnum::ShaderType stage, uint32_t registerIndex, const Tr2SamplerStateAL& sampler ) { + if( stage >= Tr2RenderContextEnum::SHADER_TYPE_COUNT || registerIndex >= Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + { + return false; + } for( auto& entry : m_entries ) { if( entry.stage != uint8_t( stage ) || entry.registerIndex != uint8_t( registerIndex ) || !SharesRegisterSpace( entry.kind, kind ) ) From c3b3c31bbe932af213f4596a3df55f44850c60d5 Mon Sep 17 00:00:00 2001 From: JohnGreenCCP Date: Fri, 11 Sep 2026 14:52:59 +0100 Subject: [PATCH 4/5] Size sorted resource bindings for all shader stages on dx11 and dx12 Tr2RegisterMapAL indexes SRVs, UAVs and samplers globally across stages, so the per-stage cap on the sorted arrays dropped any binding with a global index above 31. Size the arrays for SHADER_TYPE_COUNT stages as Metal does and guard on the global counts. Also size the dx12 per-draw transition arrays for the full resource count. --- trinityal/dx11/Tr2RenderContextDx11.cpp | 12 ++++++------ trinityal/dx11/Tr2RenderContextDx11.h | 6 +++--- trinityal/dx12/Tr2RenderContextDx12.cpp | 19 ++++++++++--------- trinityal/dx12/Tr2RenderContextDx12.h | 6 +++--- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/trinityal/dx11/Tr2RenderContextDx11.cpp b/trinityal/dx11/Tr2RenderContextDx11.cpp index d894e5c96..612de7ddb 100644 --- a/trinityal/dx11/Tr2RenderContextDx11.cpp +++ b/trinityal/dx11/Tr2RenderContextDx11.cpp @@ -2233,7 +2233,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() for( const auto& resource : m_pendingSRVs ) { uint32_t index = registerMap.srvs[resource.stage][resource.registerIndex]; - if( index < registerMap.srvCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.srvCount ) { m_sortedSRVs[index] = &resource; } @@ -2241,7 +2241,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() for( const auto& resource : m_pendingUAVs ) { uint32_t index = registerMap.uavs[resource.stage][resource.registerIndex]; - if( index < registerMap.uavCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.uavCount ) { m_sortedUAVs[index] = &resource; } @@ -2249,7 +2249,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() for( const auto& sampler : m_pendingSamplers ) { uint32_t index = registerMap.samplers[sampler.stage][sampler.registerIndex]; - if( index < registerMap.samplerCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.samplerCount ) { m_sortedSamplers[index] = &sampler; } @@ -2269,7 +2269,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() uint32_t srvIndex = registerMap.srvs[stageIndex][registerIndex]; if( srvIndex < registerMap.srvCount ) { - const Resource* resource = srvIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSRVs[srvIndex] : nullptr; + const Resource* resource = m_sortedSRVs[srvIndex]; switch( resource ? resource->type : Resource::NONE ) { case Resource::TEXTURE: @@ -2292,7 +2292,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() uint32_t samplerIndex = registerMap.samplers[stageIndex][registerIndex]; if( samplerIndex < registerMap.samplerCount ) { - const Sampler* sampler = samplerIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSamplers[samplerIndex] : nullptr; + const Sampler* sampler = m_sortedSamplers[samplerIndex]; if( sampler && sampler->type == Sampler::SAMPLER && sampler->sampler.m_sampler ) { desiredSamplers[stageIndex][registerIndex] = sampler->sampler.m_sampler->m_samplerState; @@ -2303,7 +2303,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings() throw() if( uavIndex < registerMap.uavCount && ( stageIndex == PIXEL_SHADER || stageIndex == COMPUTE_SHADER ) ) { - const Resource* resource = uavIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedUAVs[uavIndex] : nullptr; + const Resource* resource = m_sortedUAVs[uavIndex]; switch( resource ? resource->type : Resource::NONE ) { case Resource::TEXTURE: diff --git a/trinityal/dx11/Tr2RenderContextDx11.h b/trinityal/dx11/Tr2RenderContextDx11.h index 8d696ec27..1163b8536 100644 --- a/trinityal/dx11/Tr2RenderContextDx11.h +++ b/trinityal/dx11/Tr2RenderContextDx11.h @@ -308,9 +308,9 @@ class Tr2RenderContextAL std::vector m_pendingUAVs; std::vector m_pendingSamplers; - const Resource* m_sortedSRVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; - const Resource* m_sortedUAVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; - const Sampler* m_sortedSamplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedSRVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedUAVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Sampler* m_sortedSamplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; ID3D11ShaderResourceView* m_boundSrvs[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; ID3D11SamplerState* m_boundSamplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT][Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; diff --git a/trinityal/dx12/Tr2RenderContextDx12.cpp b/trinityal/dx12/Tr2RenderContextDx12.cpp index c203dd2b7..79ce201d5 100644 --- a/trinityal/dx12/Tr2RenderContextDx12.cpp +++ b/trinityal/dx12/Tr2RenderContextDx12.cpp @@ -1028,7 +1028,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& resource : m_pendingSRVs ) { uint32_t index = registerMap.srvs[resource.stage][resource.registerIndex]; - if( index < registerMap.srvCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.srvCount ) { m_sortedSRVs[index] = &resource; } @@ -1036,7 +1036,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& resource : m_pendingUAVs ) { uint32_t index = registerMap.uavs[resource.stage][resource.registerIndex]; - if( index < registerMap.uavCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.uavCount ) { m_sortedUAVs[index] = &resource; } @@ -1044,7 +1044,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& sampler : m_pendingSamplers ) { uint32_t index = registerMap.samplers[sampler.stage][sampler.registerIndex]; - if( index < registerMap.samplerCount && index < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( index < registerMap.samplerCount ) { m_sortedSamplers[index] = &sampler; } @@ -1057,8 +1057,9 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi } m_usedResources.clear(); - D3D12_RESOURCE_BARRIER inTransitions[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; - ID3D12Resource* transitioned[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + constexpr uint32_t maxTransitions = 2 * Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE; + D3D12_RESOURCE_BARRIER inTransitions[maxTransitions]; + ID3D12Resource* transitioned[maxTransitions]; uint32_t inCount = 0; uint32_t transitionedCount = 0; @@ -1067,7 +1068,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi if( ( defaultState & expectedState ) == 0 && defaultState != D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE ) { auto found = std::find( transitioned, transitioned + transitionedCount, res ); - if( found == transitioned + transitionedCount && transitionedCount < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ) + if( found == transitioned + transitionedCount && transitionedCount < maxTransitions ) { inTransitions[inCount++] = TrinityALImpl::Transition( res, defaultState, expectedState ); m_outTransitions.push_back( TrinityALImpl::Transition( res, expectedState, defaultState ) ); @@ -1082,7 +1083,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& reg : rootSignature.m_srvRegisters ) { uint32_t mapIndex = registerMap.srvs[reg.stage][reg.index]; - const Resource* resource = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSRVs[mapIndex] : nullptr; + const Resource* resource = mapIndex < registerMap.srvCount ? m_sortedSRVs[mapIndex] : nullptr; auto stateFlag = reg.stage == Tr2RenderContextEnum::PIXEL_SHADER ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; std::shared_ptr srv; @@ -1133,7 +1134,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& reg : rootSignature.m_uavRegisters ) { uint32_t mapIndex = registerMap.uavs[reg.stage][reg.index]; - const Resource* resource = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedUAVs[mapIndex] : nullptr; + const Resource* resource = mapIndex < registerMap.uavCount ? m_sortedUAVs[mapIndex] : nullptr; std::shared_ptr uav; switch( resource ? resource->type : Resource::NONE ) @@ -1193,7 +1194,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi for( const auto& reg : rootSignature.m_samplerRegisters ) { uint32_t mapIndex = registerMap.samplers[reg.stage][reg.index]; - const Sampler* sampler = mapIndex < Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE ? m_sortedSamplers[mapIndex] : nullptr; + const Sampler* sampler = mapIndex < registerMap.samplerCount ? m_sortedSamplers[mapIndex] : nullptr; switch( sampler ? sampler->type : Sampler::NONE ) { diff --git a/trinityal/dx12/Tr2RenderContextDx12.h b/trinityal/dx12/Tr2RenderContextDx12.h index e9d639d9a..00aa10333 100644 --- a/trinityal/dx12/Tr2RenderContextDx12.h +++ b/trinityal/dx12/Tr2RenderContextDx12.h @@ -318,9 +318,9 @@ class Tr2RenderContextAL std::vector m_pendingUAVs; std::vector m_pendingSamplers; - const Resource* m_sortedSRVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; - const Resource* m_sortedUAVs[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; - const Sampler* m_sortedSamplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedSRVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Resource* m_sortedUAVs[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; + const Sampler* m_sortedSamplers[Tr2RenderContextEnum::SHADER_TYPE_COUNT * Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; std::vector m_outTransitions; std::vector m_usedResources; From c1a4ce1d9a5c6713fa6a2ae6c8c0e5d9468e6407 Mon Sep 17 00:00:00 2001 From: JohnGreenCCP Date: Mon, 14 Sep 2026 12:25:14 +0100 Subject: [PATCH 5/5] Fixed AI suggestions --- trinity/Shader/Tr2EffectDescription.h | 2 -- trinity/Shader/Tr2Material.cpp | 1 + trinity/TriVariable.cpp | 2 +- trinityal/dx11/Tr2RenderContextDx11.cpp | 5 ++- trinityal/dx11/Tr2TextureALDx11.h | 1 - trinityal/dx12/Tr2RenderContextDx12.cpp | 46 +++++++++--------------- trinityal/metal/Tr2RenderContextMetal.mm | 15 +++++--- 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/trinity/Shader/Tr2EffectDescription.h b/trinity/Shader/Tr2EffectDescription.h index 532c415c0..ecfbe52ed 100644 --- a/trinity/Shader/Tr2EffectDescription.h +++ b/trinity/Shader/Tr2EffectDescription.h @@ -7,8 +7,6 @@ #include "../Tr2IndirectDrawBuffer.h" -#include <../trinityal/include/Tr2StaticResourceBindingsAL.h> - extern const BlueSharedString DEFAULT_TECHNIQUE; extern const BlueSharedString ANY_TECHNIQUE; diff --git a/trinity/Shader/Tr2Material.cpp b/trinity/Shader/Tr2Material.cpp index 7af042e37..5e961ea91 100644 --- a/trinity/Shader/Tr2Material.cpp +++ b/trinity/Shader/Tr2Material.cpp @@ -243,6 +243,7 @@ void Tr2Material::ApplyMaterialDataForPassWithOverride( uint32_t techniqueIndex, auto& pp = *m_parametersForPasses[techniqueIndex].passes[passIndex]; renderContext.ResetResourceBindings(); + pp.m_staticBindings.Apply( renderContext ); for( unsigned i = 0; i != Tr2RenderContextEnum::SHADER_TYPE_COUNT && mask; ++i ) { diff --git a/trinity/TriVariable.cpp b/trinity/TriVariable.cpp index 7870e5ace..071488ca7 100644 --- a/trinity/TriVariable.cpp +++ b/trinity/TriVariable.cpp @@ -87,7 +87,7 @@ void TriVariable::UseUav( } else { - renderContext.SetUav( stage, registerIndex, Tr2BufferAL() ); + renderContext.SetUav( stage, registerIndex, Tr2TextureAL() ); } return; } diff --git a/trinityal/dx11/Tr2RenderContextDx11.cpp b/trinityal/dx11/Tr2RenderContextDx11.cpp index 612de7ddb..f96d09dbf 100644 --- a/trinityal/dx11/Tr2RenderContextDx11.cpp +++ b/trinityal/dx11/Tr2RenderContextDx11.cpp @@ -89,7 +89,7 @@ struct NullContext : ID3D11DeviceContext { virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, - __RPC__deref_out void __RPC_FAR* __RPC_FAR* ppvObject ) + __RPC__deref_out void __RPC_FAR * __RPC_FAR * ppvObject ) { return E_FAIL; } @@ -762,8 +762,7 @@ struct NullContext : ID3D11DeviceContext #pragma warning( default : 4100 ) Tr2RenderContextAL::Tr2RenderContextAL() throw() : - m_topology( TOP_INVALID ), m_lastSetTopology( TOP_INVALID ), m_renderTargetHighWaterMark( 1 ), m_lastSetVertexLayoutVSHash( 0 ), m_stackDS( "Tr2RenderContextAL::m_stackDS" ), m_useReadOnlyDepthView( false ), m_isDepthReadOnly( false ), m_isSrgbRenderTarget( false ), m_previouslyHadHullShader( false ), m_events( nullptr ), m_aftermathContext( nullptr ), - m_assignedUavOffset( 0 ), m_assignedUavCount( 0 ), m_assignedPsUavs( false ), m_bindingsCommitted( false ), m_bindingsSealed( false ), m_committedProgram( nullptr ) + m_topology( TOP_INVALID ), m_lastSetTopology( TOP_INVALID ), m_renderTargetHighWaterMark( 1 ), m_lastSetVertexLayoutVSHash( 0 ), m_stackDS( "Tr2RenderContextAL::m_stackDS" ), m_useReadOnlyDepthView( false ), m_isDepthReadOnly( false ), m_isSrgbRenderTarget( false ), m_previouslyHadHullShader( false ), m_events( nullptr ), m_aftermathContext( nullptr ), m_assignedUavOffset( 0 ), m_assignedUavCount( 0 ), m_assignedPsUavs( false ), m_bindingsCommitted( false ), m_bindingsSealed( false ), m_committedProgram( nullptr ) { m_dirtyFlag.mask = 0; diff --git a/trinityal/dx11/Tr2TextureALDx11.h b/trinityal/dx11/Tr2TextureALDx11.h index a3881a319..d5b7fb956 100644 --- a/trinityal/dx11/Tr2TextureALDx11.h +++ b/trinityal/dx11/Tr2TextureALDx11.h @@ -16,7 +16,6 @@ - namespace TrinityALImpl { class Tr2TextureAL : public Tr2DeviceResourceAL diff --git a/trinityal/dx12/Tr2RenderContextDx12.cpp b/trinityal/dx12/Tr2RenderContextDx12.cpp index 79ce201d5..ad212ae4f 100644 --- a/trinityal/dx12/Tr2RenderContextDx12.cpp +++ b/trinityal/dx12/Tr2RenderContextDx12.cpp @@ -1140,37 +1140,23 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi switch( resource ? resource->type : Resource::NONE ) { case Resource::TEXTURE: - if( resource->texture.IsValid() ) + if( resource->texture.IsValid() && reg.registerType >= Tr2ShaderRegisterAL::UAV_TEXTURE1D && resource->mip < resource->texture.m_texture->m_uav.size() ) { - if( reg.registerType >= Tr2ShaderRegisterAL::UAV_TEXTURE1D ) - { - uav = resource->texture.m_texture->m_uav[resource->mip]; - } - if( !uav ) - { - uav = renderContext.GetNullUavDx12( reg.registerType ); - } - else - { - AddTransition( resource->texture.m_texture->GetResourceDx12(), resource->texture.m_texture->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); - } + uav = resource->texture.m_texture->m_uav[resource->mip]; + } + if( uav ) + { + AddTransition( resource->texture.m_texture->GetResourceDx12(), resource->texture.m_texture->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); } break; case Resource::BUFFER: - if( resource->buffer.IsValid() ) + if( resource->buffer.IsValid() && reg.registerType <= Tr2ShaderRegisterAL::UAV_STRUCTURED_BUFFER ) { - if( reg.registerType <= Tr2ShaderRegisterAL::UAV_STRUCTURED_BUFFER ) - { - uav = resource->buffer.m_buffer->m_uav; - } - if( !uav ) - { - uav = renderContext.GetNullUavDx12( reg.registerType ); - } - else - { - AddTransition( resource->buffer.m_buffer->GetGpuResource(), resource->buffer.m_buffer->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); - } + uav = resource->buffer.m_buffer->m_uav; + } + if( uav ) + { + AddTransition( resource->buffer.m_buffer->GetGpuResource(), resource->buffer.m_buffer->m_defaultState, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); } break; case Resource::HEAP_VIEW: @@ -1178,14 +1164,14 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi break; default: CCP_AL_LOGWARN( "Missing UAV resource binding for register %u, stage %u", reg.index, reg.stage ); - uav = renderContext.GetNullUavDx12( reg.registerType ); break; } - if( uav ) + if( !uav ) { - m_descriptorCache[bufferIndex]->SetUnorderedAccessViews( reg.parameter, 1, &uav ); + uav = renderContext.GetNullUavDx12( reg.registerType ); } + m_descriptorCache[bufferIndex]->SetUnorderedAccessViews( reg.parameter, 1, &uav ); } std::shared_ptr samplers[Tr2RegisterMapAL::MAX_RESOURCES_IN_STAGE]; @@ -1199,7 +1185,7 @@ ALResult Tr2RenderContextAL::UseResourceBindings( const TrinityALImpl::Tr2RootSi switch( sampler ? sampler->type : Sampler::NONE ) { case Sampler::SAMPLER: - samplers[reg.parameter] = sampler->sampler.m_sampler->m_samplerState; + samplers[reg.parameter] = sampler->sampler.IsValid() ? sampler->sampler.m_sampler->m_samplerState : renderContext.GetNullSamplerDx12(); break; case Sampler::HEAP_VIEW: samplers[reg.parameter] = renderContext.GetSamplerHeapView(); diff --git a/trinityal/metal/Tr2RenderContextMetal.mm b/trinityal/metal/Tr2RenderContextMetal.mm index aa525010b..3795d0f2a 100644 --- a/trinityal/metal/Tr2RenderContextMetal.mm +++ b/trinityal/metal/Tr2RenderContextMetal.mm @@ -872,6 +872,7 @@ MTLClearColor MakeClearColor( uint32_t color ) m_vertexLayout = Tr2VertexLayoutAL(); m_shaderProgram = Tr2ShaderProgramAL(); + DiscardResourceBindings(); return S_OK; } @@ -1456,11 +1457,15 @@ MTLClearColor MakeClearColor( uint32_t color ) case Resource::TEXTURE: if( resource->texture.IsValid() && reg < METAL_UAV_TEXTURE_COUNT ) { - const NSUInteger texIndex = METAL_UAV_TEXTURE_OFFSET + reg; - textures[texIndex] = resource->texture.m_texture->GetUAVMetalTexture( resource->mip ); - texturesMin = std::min( texturesMin, texIndex ); - texturesMax = std::max( texturesMax, texIndex ); - missingTextureMask &= ~( 1u << texIndex ); + id uavTexture = resource->texture.m_texture->GetUAVMetalTexture( resource->mip ); + if( uavTexture ) + { + const NSUInteger texIndex = METAL_UAV_TEXTURE_OFFSET + reg; + textures[texIndex] = uavTexture; + texturesMin = std::min( texturesMin, texIndex ); + texturesMax = std::max( texturesMax, texIndex ); + missingTextureMask &= ~( 1u << texIndex ); + } } break; case Resource::HEAP_VIEW: