recreate samplers on video restart so max anisotropy takes effect

This commit is contained in:
myT 2023-07-20 00:14:29 +02:00
parent e2f6e05ebe
commit d841f13fb0
3 changed files with 55 additions and 37 deletions

View file

@ -197,20 +197,6 @@ void GRP::Init()
if(firstInit) if(firstInit)
{ {
for(uint32_t w = 0; w < TW_COUNT; ++w)
{
for(uint32_t f = 0; f < TextureFilter::Count; ++f)
{
for(uint32_t m = 0; m < MaxTextureMips; ++m)
{
const textureWrap_t wrap = (textureWrap_t)w;
const TextureFilter::Id filter = (TextureFilter::Id)f;
const uint32_t s = GetSamplerIndex(wrap, filter, m);
samplers[s] = CreateSampler(SamplerDesc(wrap, filter, (float)m));
}
}
}
RootSignatureDesc desc("main"); RootSignatureDesc desc("main");
desc.usingVertexBuffers = true; desc.usingVertexBuffers = true;
desc.samplerCount = ARRAY_LEN(samplers); desc.samplerCount = ARRAY_LEN(samplers);
@ -223,10 +209,6 @@ void GRP::Init()
descriptorTable = CreateDescriptorTable(DescriptorTableDesc("game textures", rootSignature)); descriptorTable = CreateDescriptorTable(DescriptorTableDesc("game textures", rootSignature));
DescriptorTableUpdate update;
update.SetSamplers(ARRAY_LEN(samplers), samplers);
UpdateDescriptorTable(descriptorTable, update);
desc.name = "world"; desc.name = "world";
desc.usingVertexBuffers = true; desc.usingVertexBuffers = true;
desc.constants[ShaderStage::Vertex].byteCount = sizeof(WorldVertexRC); desc.constants[ShaderStage::Vertex].byteCount = sizeof(WorldVertexRC);
@ -244,6 +226,31 @@ void GRP::Init()
} }
} }
// we recreate the samplers on every vid_restart to create the right level
// of anisotropy based on the latched CVar
for(uint32_t w = 0; w < TW_COUNT; ++w)
{
for(uint32_t f = 0; f < TextureFilter::Count; ++f)
{
for(uint32_t m = 0; m < MaxTextureMips; ++m)
{
const textureWrap_t wrap = (textureWrap_t)w;
const TextureFilter::Id filter = (TextureFilter::Id)f;
const uint32_t s = GetSamplerIndex(wrap, filter, m);
SamplerDesc desc(wrap, filter, (float)m);
desc.shortLifeTime = true;
samplers[s] = CreateSampler(desc);
}
}
}
// update our descriptor table with the new sampler descriptors
{
DescriptorTableUpdate update;
update.SetSamplers(ARRAY_LEN(samplers), samplers);
UpdateDescriptorTable(descriptorTable, update);
}
textureIndex = 0; textureIndex = 0;
psoCount = 1; // we treat index 0 as invalid psoCount = 1; // we treat index 0 as invalid

View file

@ -282,7 +282,8 @@ namespace RHI
R(Heap, "heap") \ R(Heap, "heap") \
R(QueryHeap, "query heap") \ R(QueryHeap, "query heap") \
R(Texture, "texture") \ R(Texture, "texture") \
R(Buffer, "buffer") R(Buffer, "buffer") \
R(Sampler, "samplers")
#define R(Enum, Name) Enum, #define R(Enum, Name) Enum,
struct D3DResourceType struct D3DResourceType
@ -378,6 +379,13 @@ namespace RHI
bool shortLifeTime = false; bool shortLifeTime = false;
}; };
struct Sampler
{
SamplerDesc desc;
uint32_t heapIndex = UINT32_MAX;
bool shortLifeTime = true;
};
struct QueryState struct QueryState
{ {
enum Id enum Id
@ -566,6 +574,7 @@ namespace RHI
POOL(DescriptorTable, 64) descriptorTables; POOL(DescriptorTable, 64) descriptorTables;
POOL(Pipeline, 256) pipelines; POOL(Pipeline, 256) pipelines;
POOL(Shader, 16) shaders; POOL(Shader, 16) shaders;
POOL(Sampler, 128) samplers;
#undef POOL #undef POOL
#define DESTROY_POOL_LIST(POOL) \ #define DESTROY_POOL_LIST(POOL) \
@ -574,7 +583,8 @@ namespace RHI
POOL(rootSignatures, DestroyRootSignature) \ POOL(rootSignatures, DestroyRootSignature) \
POOL(descriptorTables, DestroyDescriptorTable) \ POOL(descriptorTables, DestroyDescriptorTable) \
POOL(pipelines, DestroyPipeline) \ POOL(pipelines, DestroyPipeline) \
POOL(shaders, DestroyShader) POOL(shaders, DestroyShader) \
POOL(samplers, DestroySampler)
// null resources, no manual clean-up needed // null resources, no manual clean-up needed
HTexture nullTexture; // SRV HTexture nullTexture; // SRV
@ -2059,6 +2069,7 @@ namespace RHI
ITEM("Descriptor Tables", rhi.descriptorTables); ITEM("Descriptor Tables", rhi.descriptorTables);
ITEM("Pipelines", rhi.pipelines); ITEM("Pipelines", rhi.pipelines);
ITEM("Shaders", rhi.shaders); ITEM("Shaders", rhi.shaders);
ITEM("Samplers", rhi.samplers);
#undef ITEM #undef ITEM
TableRow(3, "Duration Queries", TableRow(3, "Duration Queries",
va("%d", rhi.frameQueries[rhi.frameIndex].durationQueryCount), va("%d", rhi.frameQueries[rhi.frameIndex].durationQueryCount),
@ -3294,10 +3305,10 @@ namespace RHI
rhi.textures.Remove(handle); rhi.textures.Remove(handle);
} }
HSampler CreateSampler(const SamplerDesc& sampler) HSampler CreateSampler(const SamplerDesc& rhiDesc)
{ {
const D3D12_TEXTURE_ADDRESS_MODE addressMode = GetD3DTextureAddressMode(sampler.wrapMode); const D3D12_TEXTURE_ADDRESS_MODE addressMode = GetD3DTextureAddressMode(rhiDesc.wrapMode);
D3D12_FILTER filter = GetD3DFilter(sampler.filterMode); D3D12_FILTER filter = GetD3DFilter(rhiDesc.filterMode);
UINT maxAnisotropy = r_ext_max_anisotropy->integer; UINT maxAnisotropy = r_ext_max_anisotropy->integer;
if(filter == D3D12_FILTER_ANISOTROPIC && maxAnisotropy <= 1) if(filter == D3D12_FILTER_ANISOTROPIC && maxAnisotropy <= 1)
{ {
@ -3316,26 +3327,25 @@ namespace RHI
desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NONE; desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NONE;
desc.MaxAnisotropy = maxAnisotropy; desc.MaxAnisotropy = maxAnisotropy;
desc.MaxLOD = 666.0f; desc.MaxLOD = 666.0f;
desc.MinLOD = sampler.minLOD; desc.MinLOD = rhiDesc.minLOD;
desc.MipLODBias = sampler.mipLODBias; desc.MipLODBias = rhiDesc.mipLODBias;
desc.Filter = filter; desc.Filter = filter;
const uint32_t index = rhi.descHeapSamplers.CreateSampler(desc); const uint32_t index = rhi.descHeapSamplers.CreateSampler(desc);
return RHI_MAKE_HANDLE(CreateHandle(ResourceType::Sampler, index, 0)); Sampler sampler;
sampler.desc = rhiDesc;
sampler.shortLifeTime = rhiDesc.shortLifeTime;
sampler.heapIndex = index;
const HSampler handle = rhi.samplers.Add(sampler);
return handle;
} }
void DestroySampler(HSampler sampler) void DestroySampler(HSampler hsampler)
{ {
Handle type, index, gen; const Sampler& sampler = rhi.samplers.Get(hsampler);
DecomposeHandle(&type, &index, &gen, sampler.v); rhi.descHeapSamplers.Free(sampler.heapIndex);
Q_assert(type == ResourceType::Sampler); rhi.samplers.Remove(hsampler);
if(type != ResourceType::Sampler)
{
ri.Error(ERR_FATAL, "DestroySampler handle is not a sampler!\n");
return;
}
rhi.descHeapSamplers.Free(index);
} }
static void AddShaderVisibility(bool outVis[ShaderStage::Count], D3D12_SHADER_VISIBILITY inVis) static void AddShaderVisibility(bool outVis[ShaderStage::Count], D3D12_SHADER_VISIBILITY inVis)

View file

@ -506,6 +506,7 @@ namespace RHI
TextureFilter::Id filterMode = TextureFilter::Linear; TextureFilter::Id filterMode = TextureFilter::Linear;
float minLOD = 0.0f; float minLOD = 0.0f;
float mipLODBias = 0.0f; float mipLODBias = 0.0f;
bool shortLifeTime = false;
}; };
struct DescriptorTableDesc struct DescriptorTableDesc