Skip to content

Commit 73a77c4

Browse files
committed
Refactor framebuffer handling to use dedicated cache system with RenderTarget structures
1 parent 7d1630f commit 73a77c4

5 files changed

Lines changed: 92 additions & 43 deletions

File tree

src/vrhi_backend.cpp

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -319,50 +319,41 @@ void vhCmdBackendState::BE_UpdateBuffer( vhBackendBuffer& bbuf, uint64_t offset,
319319
}
320320
}
321321

322-
nvrhi::FramebufferHandle vhCmdBackendState::BE_GetFrameBuffer( const std::vector< vhTexture >& colours, vhTexture depth, int mip, int layer )
322+
nvrhi::FramebufferHandle vhCmdBackendState::BE_GetFrameBuffer( const std::vector< vhState::RenderTarget >& colourAttachment, const vhState::RenderTarget& depthAttachment )
323323
{
324-
// TODO: ################ Finish implementation ################
325-
// TODO: THIS IS UNTESTED!! Use this at graphics render time in future.
326-
327-
// Combine all inputs into a hash key
328-
uint64_t hashInput[32]; // Enough for color attachments + depth + mip/layer
329-
int i = 0;
330-
for ( auto c : colours ) hashInput[i++] = ( uint64_t ) c;
331-
hashInput[i++] = ( uint64_t ) depth;
332-
hashInput[i++] = ( uint32_t ) mip | ( ( uint32_t ) layer << 16 );
333-
334-
uint64_t key = komihash( hashInput, i * sizeof( uint64_t ), 0 );
335-
336-
if ( backendFramebuffers.find( key ) == backendFramebuffers.end() )
324+
nvrhi::FramebufferDesc desc;
325+
for ( const auto& rt : colourAttachment )
337326
{
338-
nvrhi::FramebufferDesc desc;
339-
for ( auto texture : colours )
327+
if ( rt.texture == VRHI_INVALID_HANDLE ) continue;
328+
auto it = backendTextures.find( rt.texture );
329+
if ( it != backendTextures.end() && it->second->handle )
340330
{
341-
auto it = backendTextures.find( texture );
342-
if ( it != backendTextures.end() && it->second->handle )
343-
{
344-
desc.addColorAttachment( nvrhi::FramebufferAttachment( it->second->handle )
345-
.setArraySlice( layer )
346-
.setMipLevel( mip ) );
347-
}
331+
nvrhi::FramebufferAttachment att;
332+
att.setTexture( it->second->handle );
333+
att.setArraySlice( rt.arrayLayer );
334+
att.setMipLevel( rt.mipLevel );
335+
att.setFormat( rt.formatOverride );
336+
att.setReadOnly( rt.readOnly );
337+
desc.addColorAttachment( att );
348338
}
339+
}
349340

350-
if ( depth != VRHI_INVALID_HANDLE )
341+
if ( depthAttachment.texture != VRHI_INVALID_HANDLE )
342+
{
343+
auto it = backendTextures.find( depthAttachment.texture );
344+
if ( it != backendTextures.end() && it->second->handle )
351345
{
352-
auto it = backendTextures.find( depth );
353-
if ( it != backendTextures.end() && it->second->handle )
354-
{
355-
desc.setDepthAttachment( nvrhi::FramebufferAttachment( it->second->handle )
356-
.setArraySlice( layer )
357-
.setMipLevel( mip ) );
358-
}
346+
nvrhi::FramebufferAttachment att;
347+
att.setTexture( it->second->handle );
348+
att.setArraySlice( depthAttachment.arrayLayer );
349+
att.setMipLevel( depthAttachment.mipLevel );
350+
att.setFormat( depthAttachment.formatOverride );
351+
att.setReadOnly( depthAttachment.readOnly );
352+
desc.setDepthAttachment( att );
359353
}
360-
361-
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
362-
backendFramebuffers[key] = g_vhDevice->createFramebuffer( desc );
363354
}
364355

365-
return backendFramebuffers[key];
356+
return vhFBOCacheGet( desc );
366357
}
367358

368359
bool vhCmdBackendState::BE_PresubmitCommon_PipelineDesc(
@@ -1172,7 +1163,6 @@ void vhCmdBackendState::shutdown()
11721163
backendTextures.clear();
11731164
backendBuffers.clear();
11741165
backendShaders.clear();
1175-
backendFramebuffers.clear();
11761166

11771167
// Clear static caches
11781168
s_layoutToShader.clear();
@@ -1209,8 +1199,7 @@ void vhCmdBackendState::Handle_vhResetTexture( VIDL_vhResetTexture* cmd )
12091199
void vhCmdBackendState::Handle_vhResizeCleanup( VIDL_vhResizeCleanup* cmd )
12101200
{
12111201
BE_CmdRAII cmdRAII( cmd );
1212-
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
1213-
backendFramebuffers.clear();
1202+
vhFBOCacheReset();
12141203
}
12151204

12161205
void vhCmdBackendState::Handle_vhDestroyTexture( VIDL_vhDestroyTexture* cmd )

src/vrhi_backend.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ class vhCmdBackendState : public VIDLHandler
130130
std::map< vhBuffer, std::unique_ptr< vhBackendBuffer > > backendBuffers;
131131
std::map< vhShader, std::unique_ptr< vhBackendShader > > backendShaders;
132132
std::map< vhStateId, vhState > backendStates;
133-
std::unordered_map< uint64_t, nvrhi::FramebufferHandle > backendFramebuffers;
134133
vhTransientBuffer m_globalUniformBuffer;
135134
uint64_t m_globalUniformBufferLastHash = 0;
136135
vhTransientBuffer m_worldUniformBuffer;
@@ -196,7 +195,7 @@ class vhCmdBackendState : public VIDLHandler
196195

197196
void BE_UpdateBuffer( vhBackendBuffer& bbuf, uint64_t offset, const vhMem* data );
198197

199-
nvrhi::FramebufferHandle BE_GetFrameBuffer( const std::vector< vhTexture >& colours, vhTexture depth, int mip = 0, int layer = 0 );
198+
nvrhi::FramebufferHandle BE_GetFrameBuffer( const std::vector< vhState::RenderTarget >& colourAttachment, const vhState::RenderTarget& depthAttachment );
200199

201200
int64_t BE_Util_WriteGlobalUniform( const vhState& state, vhTransientBuffer& tbuf, uint64_t& lastHash );
202201
int64_t BE_Util_WriteWorldUniform( const vhState& state, vhTransientBuffer& tbuf, uint64_t& lastHash );

src/vrhi_device.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ void vhShutdown( bool quiet )
355355
vhPSOCacheShutdown();
356356
vhSamplerCacheShutdown();
357357
vhBindingSetCacheClear();
358+
vhFBOCacheReset();
358359

359360
if ( !quiet ) VRHI_LOG( " Destroying NVRHI Device...\n" );
360361
g_vhDevice = nullptr; // RefCountPtr handles the release()
@@ -1002,4 +1003,48 @@ uint64_t vhHashGlobalUniform( const vhGlobalUniform& u )
10021003
uint64_t vhHashWorldUniform( const vhWorldUniform& u )
10031004
{
10041005
return komihash( &u, sizeof( u ), 0 );
1005-
}
1006+
}
1007+
1008+
uint64_t vhHashFrameBuffer( const nvrhi::FramebufferDesc& desc )
1009+
{
1010+
uint64_t h = 0;
1011+
for ( const auto& at : desc.colorAttachments )
1012+
{
1013+
h = komihash( &at.texture, sizeof( at.texture ), h );
1014+
h = komihash( &at.subresources, sizeof( at.subresources ), h );
1015+
h = komihash( &at.format, sizeof( at.format ), h );
1016+
h = komihash( &at.isReadOnly, sizeof( at.isReadOnly ), h );
1017+
}
1018+
h = komihash( &desc.depthAttachment.texture, sizeof( desc.depthAttachment.texture ), h );
1019+
h = komihash( &desc.depthAttachment.subresources, sizeof( desc.depthAttachment.subresources ), h );
1020+
h = komihash( &desc.depthAttachment.format, sizeof( desc.depthAttachment.format ), h );
1021+
h = komihash( &desc.depthAttachment.isReadOnly, sizeof( desc.depthAttachment.isReadOnly ), h );
1022+
1023+
// Also hash shading rate if needed, though not explicitly requested, good practice to match struct
1024+
h = komihash( &desc.shadingRateAttachment.texture, sizeof( desc.shadingRateAttachment.texture ), h );
1025+
1026+
return h;
1027+
}
1028+
1029+
static std::unordered_map< uint64_t, nvrhi::FramebufferHandle > s_FBOCache;
1030+
1031+
void vhFBOCacheReset()
1032+
{
1033+
std::lock_guard<std::mutex> lock( g_nvRHIStateMutex );
1034+
s_FBOCache.clear();
1035+
}
1036+
1037+
nvrhi::FramebufferHandle vhFBOCacheGet( const nvrhi::FramebufferDesc& desc )
1038+
{
1039+
uint64_t hash = vhHashFrameBuffer( desc );
1040+
1041+
std::lock_guard<std::mutex> lock( g_nvRHIStateMutex );
1042+
auto it = s_FBOCache.find( hash );
1043+
if ( it != s_FBOCache.end() )
1044+
return it->second;
1045+
1046+
nvrhi::FramebufferHandle fb = g_vhDevice->createFramebuffer( desc );
1047+
if ( fb ) s_FBOCache[hash] = fb;
1048+
return fb;
1049+
}
1050+

src/vrhi_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ nvrhi::ComputePipelineHandle vhPSOCacheGet( const nvrhi::ComputePipelineDesc& de
201201
nvrhi::GraphicsPipelineHandle vhPSOCacheGet( const nvrhi::GraphicsPipelineDesc& desc, const nvrhi::FramebufferInfo& fbInfo );
202202
void vhBindingSetCacheClear();
203203
nvrhi::BindingSetHandle vhGetBindingSet( const nvrhi::BindingSetDesc& desc, nvrhi::BindingLayoutHandle layout );
204+
nvrhi::FramebufferHandle vhFBOCacheGet( const nvrhi::FramebufferDesc& desc );
205+
void vhFBOCacheReset();
204206

205207
struct vhTransientBuffer
206208
{
@@ -267,10 +269,13 @@ uint64_t vhHashInputLayout( nvrhi::InputLayoutHandle layout );
267269
uint64_t vhHashSamplerDesc( const nvrhi::SamplerDesc& desc );
268270
uint64_t vhHashGlobalUniform( const vhGlobalUniform& u );
269271
uint64_t vhHashWorldUniform( const vhWorldUniform& u );
272+
uint64_t vhHashFrameBuffer( const nvrhi::FramebufferDesc& desc );
270273
void vhWriteStateToGlobalUniform( const vhState& state, vhGlobalUniform& out );
271274
void vhWriteStateToWorldUniform( const vhState& state, vhWorldUniform& out );
272275
nvrhi::PrimitiveType vhTranslatePrimitiveType( uint64_t stateFlags );
273276
nvrhi::BlendState vhTranslateBlendState( uint64_t stateFlags );
274277
nvrhi::DepthStencilState vhTranslateDepthStencilState( uint64_t stateFlags, uint32_t frontStencil, uint32_t backStencil );
275278
nvrhi::RasterState vhTranslateRasterState( uint64_t stateFlags );
276279

280+
281+

test/test_backend.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,19 @@ class vhCmdBackendStateTest
9292

9393
static bool GetFrameBuffer( const std::vector< vhTexture >& colors, vhTexture depth )
9494
{
95-
auto fb1 = Get().BE_GetFrameBuffer( colors, depth, 0, 0 );
96-
auto fb2 = Get().BE_GetFrameBuffer( colors, depth, 0, 0 );
95+
std::vector< vhState::RenderTarget > rtColors;
96+
for ( auto c : colors )
97+
{
98+
vhState::RenderTarget rt;
99+
rt.texture = c;
100+
rtColors.push_back( rt );
101+
}
102+
103+
vhState::RenderTarget rtDepth;
104+
rtDepth.texture = depth;
105+
106+
auto fb1 = Get().BE_GetFrameBuffer( rtColors, rtDepth );
107+
auto fb2 = Get().BE_GetFrameBuffer( rtColors, rtDepth );
97108

98109
if ( !fb1 || !fb2 ) return false;
99110
return fb1.Get() == fb2.Get();

0 commit comments

Comments
 (0)