Added nearest filtering for PSX render mode. Closes #613

This commit is contained in:
Robert Beckebans 2023-12-30 15:01:31 +01:00
parent 567b95a642
commit fd5b25dc59
5 changed files with 316 additions and 132 deletions

View file

@ -459,15 +459,7 @@ public:
return ( void* )texture.Get();
}
void* GetSampler( SamplerCache& samplerCache )
{
if( !sampler )
{
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
}
return ( void* )sampler.Get();
}
void* GetSampler( SamplerCache& samplerCache );
void* GetSampler( nvrhi::IDevice* device )
{

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2022 Robert Beckebans
Copyright (C) 2013-2023 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -296,6 +296,36 @@ void idImage::SetTexParameters()
{
}
/*
========================
idImage::GetSampler
========================
*/
void* idImage::GetSampler( SamplerCache& samplerCache )
{
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
if( !sampler )
{
nvrhi::SamplerDesc sampDesc = samplerDesc;
// turn off linear filtering
sampDesc.setAllFilters( false );
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
}
}
else
{
if( !sampler )
{
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
}
}
return ( void* )sampler.Get();
}
/*
========================
idImage::AllocImage

View file

@ -733,18 +733,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
desc[2].bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 10 )->GetTextureID();
}
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[3].bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
}
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
if( desc[3].bindings.empty() )
{
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
}
}
}
else if( type == BINDING_LAYOUT_AMBIENT_LIGHTING_IBL_SKINNED )
@ -804,18 +823,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
desc[2].bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 10 )->GetTextureID();
}
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[3].bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
}
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
if( desc[3].bindings.empty() )
{
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
}
}
}
else if( type == BINDING_LAYOUT_DRAW_AO )
@ -900,18 +938,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
}
// samplers: 3
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[3].bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
if( desc[3].bindings.empty() )
{
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
}
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SKINNED )
@ -967,18 +1024,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
}
// samplers: 3
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[3].bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
if( desc[3].bindings.empty() )
{
desc[3].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
}
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SM )
@ -1037,24 +1113,49 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
}
// samplers: 3
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
auto& bindings = desc[3].bindings;
bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
auto& bindings = desc[3].bindings;
bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
if( desc[3].bindings.empty() )
{
auto& bindings = desc[3].bindings;
bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
}
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SM_SKINNED )
@ -1117,24 +1218,49 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
}
// samplers: 3
if( desc[3].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
auto& bindings = desc[3].bindings;
bindings =
if( desc[3].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
auto& bindings = desc[3].bindings;
bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
if( desc[3].bindings.empty() )
{
auto& bindings = desc[3].bindings;
bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
};
}
else
{
auto& bindings = desc[3].bindings;
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
}
else if( type == BINDING_LAYOUT_FOG )
@ -1340,16 +1466,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
desc[0].bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
}
if( desc[1].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[1].bindings =
if( desc[1].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearClampSampler )
};
desc[1].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointClampSampler )
};
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_PointClampSampler;
}
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearClampSampler;
if( desc[1].bindings.empty() )
{
desc[1].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearClampSampler )
};
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearClampSampler;
}
}
}
else if( type == BINDING_LAYOUT_POST_PROCESS_FINAL )
@ -1415,16 +1558,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
}
if( desc[2].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[2].bindings =
if( desc[2].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
if( desc[2].bindings.empty() )
{
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
}
}
}
else if( type == BINDING_LAYOUT_NORMAL_CUBE_SKINNED )
@ -1462,16 +1622,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
}
if( desc[2].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[2].bindings =
if( desc[2].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
if( desc[2].bindings.empty() )
{
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
}
}
}
else if( type == BINDING_LAYOUT_BINK_VIDEO )
@ -1495,16 +1672,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
desc[0].bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
}
if( desc[1].bindings.empty() )
if( r_renderMode.GetInteger() == RENDERMODE_PSX )
{
desc[1].bindings =
if( desc[1].bindings.empty() )
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
desc[1].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
};
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
}
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
if( desc[1].bindings.empty() )
{
desc[1].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
};
}
else
{
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
}
}
}
else if( type == BINDING_LAYOUT_TAA_MOTION_VECTORS )
@ -1830,7 +2024,7 @@ See if some cvars that we watch have changed
*/
void idRenderBackend::CheckCVars()
{
// gamma stuff
// TODO remove, gamma stuff doesn't work and isn't used using the latest Nvidia drivers
if( r_gamma.IsModified() || r_brightness.IsModified() )
{
r_gamma.ClearModified();
@ -1845,56 +2039,14 @@ void idRenderBackend::CheckCVars()
deviceManager->SetVsyncEnabled( r_swapInterval.GetInteger() );
}
// filtering
/*if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() )
// retro rendering
if( r_renderMode.IsModified() )
{
idLib::Printf( "Updating texture filter parameters.\n" );
r_maxAnisotropicFiltering.ClearModified();
r_useTrilinearFiltering.ClearModified();
r_lodBias.ClearModified();
r_renderMode.ClearModified();
for( int i = 0; i < globalImages->images.Num(); i++ )
{
if( globalImages->images[i] )
{
globalImages->images[i]->Bind();
globalImages->images[i]->SetTexParameters();
}
}
}*/
#if 0
if( r_antiAliasing.IsModified() )
{
switch( r_antiAliasing.GetInteger() )
{
case ANTI_ALIASING_MSAA_2X:
case ANTI_ALIASING_MSAA_4X:
if( r_antiAliasing.GetInteger() > 0 )
{
//glEnable( GL_MULTISAMPLE );
}
break;
default:
//glDisable( GL_MULTISAMPLE );
break;
}
if( tr.IsInitialized() )
{
Framebuffer::ResizeFramebuffers();
}
if( taaPass )
{
delete taaPass;
taaPass = NULL;
}
r_antiAliasing.ClearModified();
// clear caches because PSX rendering will use nearest texture filtering instead of linear
ClearCaches();
}
#endif
}
/*

View file

@ -1297,6 +1297,14 @@ extern idCVar r_useCRTPostFX;
extern idCVar r_crtCurvature;
extern idCVar r_crtVignette;
enum RenderMode
{
RENDERMODE_DOOM,
RENDERMODE_C64,
RENDERMODE_MEGADRIVE,
RENDERMODE_PSX,
};
extern idCVar r_renderMode;
// RB end

View file

@ -84,5 +84,7 @@ void main( PS_IN fragment, out PS_OUT result )
Quantize( color.b, quantizationPeriod.b )
);
//color = t_BaseColor.Sample( samp0, uv ).rgb;
result.color = float4( color, 1.0 );
}