mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
added r_shadingRate
This commit is contained in:
parent
d841f13fb0
commit
fd035c0f70
7 changed files with 155 additions and 4 deletions
|
@ -360,6 +360,8 @@ struct World
|
|||
int psoChangeCount;
|
||||
bool batchDepthHack;
|
||||
bool batchOldDepthHack;
|
||||
ShadingRate::Id batchShadingRate;
|
||||
ShadingRate::Id batchOldShadingRate;
|
||||
|
||||
// dynamic
|
||||
GeometryBuffers dynBuffers[FrameCount];
|
||||
|
|
|
@ -399,6 +399,8 @@ void World::Begin()
|
|||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
batchOldShadingRate = ShadingRate::SR_1x1;
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
|
||||
TextureBarrier tb(depthTexture, ResourceStates::DepthWriteBit);
|
||||
CmdBarrier(1, &tb);
|
||||
|
@ -562,6 +564,12 @@ void World::EndBatch()
|
|||
batchOldDepthHack = batchDepthHack;
|
||||
}
|
||||
|
||||
if(batchShadingRate != batchOldShadingRate)
|
||||
{
|
||||
CmdSetShadingRate(batchShadingRate);
|
||||
batchOldShadingRate = batchShadingRate;
|
||||
}
|
||||
|
||||
for(int p = 0; p < shader->numPipelines; ++p)
|
||||
{
|
||||
const pipeline_t& pipeline = shader->pipelines[p];
|
||||
|
@ -631,6 +639,8 @@ void World::EndSkyBatch()
|
|||
|
||||
SCOPED_RENDER_PASS("Sky", 0.0, 0.5f, 1.0f);
|
||||
|
||||
CmdSetShadingRate(ShadingRate::SR_1x1);
|
||||
|
||||
const viewParms_t& vp = backEnd.viewParms;
|
||||
CmdSetViewport(vp.viewportX, vp.viewportY, vp.viewportWidth, vp.viewportHeight, 0.0f, 0.0f);
|
||||
RB_DrawSky();
|
||||
|
@ -640,6 +650,8 @@ void World::EndSkyBatch()
|
|||
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
batchOldShadingRate = ShadingRate::SR_1x1;
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
}
|
||||
|
||||
void World::RestartBatch()
|
||||
|
@ -920,6 +932,10 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
bool oldHasStaticGeo = false;
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
|
||||
ShadingRate::Id lowShadingRate = (ShadingRate::Id)r_shadingRate->integer;
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
batchOldShadingRate = ShadingRate::SR_1x1;
|
||||
|
||||
int ds;
|
||||
const drawSurf_t* drawSurf;
|
||||
for(ds = 0, drawSurf = drawSurfs; ds < surfCount; ++ds, ++drawSurf)
|
||||
|
@ -929,6 +945,8 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
EndSkyBatch();
|
||||
EndBatch();
|
||||
|
||||
CmdSetShadingRate(lowShadingRate);
|
||||
batchOldShadingRate = lowShadingRate;
|
||||
DrawFog();
|
||||
|
||||
if(transpCount > 0)
|
||||
|
@ -982,6 +1000,7 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
EndBatch();
|
||||
BeginBatch(shader, hasStaticGeo);
|
||||
tess.greyscale = drawSurf->greyscale;
|
||||
batchShadingRate = lowShadingRate;
|
||||
}
|
||||
|
||||
if(entityChanged)
|
||||
|
@ -996,6 +1015,7 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
{
|
||||
EndBatch();
|
||||
BeginBatch(tess.shader, batchHasStaticGeo);
|
||||
batchShadingRate = lowShadingRate;
|
||||
}
|
||||
|
||||
memcpy(tess.indexes + tess.numIndexes, statIndices + chunk.firstCPUIndex, chunk.indexCount * sizeof(uint32_t));
|
||||
|
@ -1005,6 +1025,19 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
{
|
||||
R_TessellateSurface(drawSurf->surface);
|
||||
}
|
||||
|
||||
// we want full rate for nopicmipped sprites and nopicmipped alpha tests
|
||||
if((shader->imgflags & IMG_NOPICMIP) != 0)
|
||||
{
|
||||
if(entityNum != ENTITYNUM_WORLD && tr.refdef.entities[entityNum].e.reType == RT_SPRITE)
|
||||
{
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
}
|
||||
else if(shader->isAlphaTestedOpaque)
|
||||
{
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
backEnd.refdef.floatTime = originalTime;
|
||||
|
@ -1012,6 +1045,8 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
EndSkyBatch();
|
||||
EndBatch();
|
||||
|
||||
CmdSetShadingRate(ShadingRate::SR_1x1);
|
||||
|
||||
if(transpCount <= 0)
|
||||
{
|
||||
DrawFog();
|
||||
|
@ -1024,6 +1059,10 @@ void World::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
|
||||
CmdSetShadingRate(ShadingRate::SR_1x1);
|
||||
batchOldShadingRate = ShadingRate::SR_1x1;
|
||||
batchShadingRate = ShadingRate::SR_1x1;
|
||||
}
|
||||
|
||||
void World::BindVertexBuffers(bool staticGeo, uint32_t firstStage, uint32_t stageCount)
|
||||
|
|
|
@ -533,11 +533,11 @@ namespace RHI
|
|||
IDXGISwapChain3* swapChain;
|
||||
HTexture renderTargets[FrameCount];
|
||||
ID3D12CommandAllocator* mainCommandAllocators[FrameCount];
|
||||
ID3D12GraphicsCommandList* mainCommandList;
|
||||
ID3D12GraphicsCommandList6* mainCommandList;
|
||||
ID3D12CommandAllocator* tempCommandAllocator;
|
||||
ID3D12GraphicsCommandList* tempCommandList;
|
||||
ID3D12GraphicsCommandList6* tempCommandList;
|
||||
bool tempCommandListOpen;
|
||||
ID3D12GraphicsCommandList* commandList; // not owned, don't release it!
|
||||
ID3D12GraphicsCommandList6* commandList; // not owned, don't release it!
|
||||
uint32_t swapChainBufferCount;
|
||||
uint32_t renderFrameCount;
|
||||
HANDLE frameLatencyWaitableObject;
|
||||
|
@ -555,6 +555,8 @@ namespace RHI
|
|||
bool isTearingSupported;
|
||||
bool vsync;
|
||||
bool frameBegun;
|
||||
bool baseVRSSupport;
|
||||
bool extendedVRSSupport;
|
||||
|
||||
HMODULE dxcModule;
|
||||
HMODULE dxilModule;
|
||||
|
@ -1646,6 +1648,21 @@ namespace RHI
|
|||
}
|
||||
}
|
||||
|
||||
D3D12_SHADING_RATE GetD3DShadingRate(ShadingRate::Id shadingRate)
|
||||
{
|
||||
switch(shadingRate)
|
||||
{
|
||||
case ShadingRate::SR_1x1: return D3D12_SHADING_RATE_1X1;
|
||||
case ShadingRate::SR_1x2: return D3D12_SHADING_RATE_1X2;
|
||||
case ShadingRate::SR_2x1: return D3D12_SHADING_RATE_2X1;
|
||||
case ShadingRate::SR_2x2: return D3D12_SHADING_RATE_2X2;
|
||||
case ShadingRate::SR_2x4: return D3D12_SHADING_RATE_2X4;
|
||||
case ShadingRate::SR_4x2: return D3D12_SHADING_RATE_4X2;
|
||||
case ShadingRate::SR_4x4: return D3D12_SHADING_RATE_4X4;
|
||||
default: Q_assert(!"Unsupported shading rate"); return D3D12_SHADING_RATE_1X1;
|
||||
}
|
||||
}
|
||||
|
||||
static D3D12_BLEND GetAlphaBlendFromColorBlend(D3D12_BLEND colorBlend)
|
||||
{
|
||||
switch(colorBlend)
|
||||
|
@ -2178,7 +2195,23 @@ namespace RHI
|
|||
case D3D12_RAYTRACING_TIER_1_1: tier = "1.1";
|
||||
default: break;
|
||||
}
|
||||
TableRow(2, "Raytracing tier (DXR)", tier);
|
||||
TableRow(2, "Raytracing (DXR) tier", tier);
|
||||
}
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS6 options6 = { 0 };
|
||||
if(SUCCEEDED(rhi.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6))))
|
||||
{
|
||||
const char* tier = "Unknown";
|
||||
switch(options6.VariableShadingRateTier)
|
||||
{
|
||||
case D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED: tier = "N/A";
|
||||
case D3D12_VARIABLE_SHADING_RATE_TIER_1: tier = "1";
|
||||
case D3D12_VARIABLE_SHADING_RATE_TIER_2: tier = "2";
|
||||
default: break;
|
||||
}
|
||||
TableRow(2, "Variable shading rate (VRS) tier", tier);
|
||||
|
||||
TableRow(2, "VRS: 2x4, 4x2, 4x4 support", options6.AdditionalShadingRatesSupported ? "YES" : "NO");
|
||||
}
|
||||
|
||||
NvU64 cvvTotal, cvvFree;
|
||||
|
@ -2710,6 +2743,19 @@ namespace RHI
|
|||
D3D(dxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&rhi.dxcUtils)));
|
||||
D3D(dxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&rhi.dxcCompiler)));
|
||||
|
||||
{
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS6 options6 = {};
|
||||
if(SUCCEEDED(rhi.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6))))
|
||||
{
|
||||
rhi.baseVRSSupport = options6.VariableShadingRateTier != D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED;
|
||||
rhi.extendedVRSSupport = rhi.baseVRSSupport && options6.AdditionalShadingRatesSupported;
|
||||
}
|
||||
|
||||
const char* modeLists[] = { "1x1", "1x1 2x1 1x2 2x2", "1x1 2x1 1x2 2x2 4x2 2x4 4x4" };
|
||||
const int listIndex = rhi.extendedVRSSupport ? 2 : (rhi.baseVRSSupport ? 1 : 0);
|
||||
ri.Printf(PRINT_ALL, "Supported VRS modes: %s\n", modeLists[listIndex]);
|
||||
}
|
||||
|
||||
glInfo.maxTextureSize = MAX_TEXTURE_SIZE;
|
||||
glInfo.maxAnisotropy = 16;
|
||||
glInfo.depthFadeSupport = qfalse;
|
||||
|
@ -4273,6 +4319,32 @@ namespace RHI
|
|||
rhi.commandList->CopyBufferRegion(dst.buffer, 0, src.buffer, 0, byteCount);
|
||||
}
|
||||
|
||||
void CmdSetShadingRate(ShadingRate::Id shadingRate)
|
||||
{
|
||||
Q_assert(CanWriteCommands());
|
||||
|
||||
if(!rhi.baseVRSSupport)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!rhi.extendedVRSSupport)
|
||||
{
|
||||
switch(shadingRate)
|
||||
{
|
||||
case ShadingRate::SR_2x4:
|
||||
case ShadingRate::SR_4x2:
|
||||
case ShadingRate::SR_4x4:
|
||||
shadingRate = ShadingRate::SR_2x2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rhi.commandList->RSSetShadingRate(GetD3DShadingRate(shadingRate), NULL);
|
||||
}
|
||||
|
||||
uint32_t GetDurationCount()
|
||||
{
|
||||
return rhi.resolvedQueries.durationQueryCount;
|
||||
|
|
|
@ -234,6 +234,23 @@ namespace RHI
|
|||
};
|
||||
};
|
||||
|
||||
struct ShadingRate
|
||||
{
|
||||
enum Id
|
||||
{
|
||||
// Guaranteed modes:
|
||||
SR_1x1,
|
||||
SR_2x1,
|
||||
SR_1x2,
|
||||
SR_2x2,
|
||||
// Additional modes:
|
||||
SR_4x2,
|
||||
SR_2x4,
|
||||
SR_4x4,
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct RootSignatureDesc
|
||||
{
|
||||
RootSignatureDesc() = default;
|
||||
|
@ -716,6 +733,7 @@ namespace RHI
|
|||
void CmdEndDebugLabel();
|
||||
void CmdSetStencilReference(uint8_t stencilRef);
|
||||
void CmdCopyBuffer(HBuffer dest, HBuffer source);
|
||||
void CmdSetShadingRate(ShadingRate::Id shadingRate);
|
||||
|
||||
#if 0
|
||||
void CmdClearUAV(HTexture htexture, uint32_t mip);
|
||||
|
|
|
@ -142,6 +142,23 @@ S_COLOR_VAL " 2 " S_COLOR_HELP "= None"
|
|||
S_COLOR_VAL "2500 " S_COLOR_HELP "should be enough to deal with delayed thread wake-ups.\n" \
|
||||
"Use the frame graph to confirm that higher values help on your system."
|
||||
|
||||
#define help_r_shadingRate \
|
||||
"variable-rate shading (VRS) mode\n" \
|
||||
S_COLOR_VAL " 0 " S_COLOR_HELP "= 1x1 (VRS off)\n" \
|
||||
S_COLOR_VAL " 1 " S_COLOR_HELP "= 2x1 (base mode)\n" \
|
||||
S_COLOR_VAL " 2 " S_COLOR_HELP "= 1x2 (base mode)\n" \
|
||||
S_COLOR_VAL " 3 " S_COLOR_HELP "= 2x2 (base mode)\n" \
|
||||
S_COLOR_VAL " 4 " S_COLOR_HELP "= 4x2 (extended mode)\n" \
|
||||
S_COLOR_VAL " 5 " S_COLOR_HELP "= 2x4 (extended mode)\n" \
|
||||
S_COLOR_VAL " 6 " S_COLOR_HELP "= 4x4 (extended mode)\n" \
|
||||
"The numbers are the horizontal and vertical subsampling factors.\n" \
|
||||
"1x1 is forced for the sky, nopicmipped sprites (e.g. simple items)\n" \
|
||||
"and nopicmipped alpha tested surfaces (e.g. grates).\n" \
|
||||
"If extended modes are not supported, 2x2 is used instead.\n" \
|
||||
"Prefer horizontal subsampling as many maps have textures\n" \
|
||||
"with thin horizontal lines, which become an aliased mess when\n" \
|
||||
"vertically subsampled."
|
||||
|
||||
#define help_r_ignoreShaderSortKey \
|
||||
"ignores the shader sort key of transparent surfaces\n" \
|
||||
"Instead, it sorts by depth and original registration order only.\n" \
|
||||
|
|
|
@ -60,6 +60,7 @@ cvar_t *r_mapGreyscale;
|
|||
cvar_t *r_mapGreyscaleCTF;
|
||||
cvar_t *r_teleporterFlash;
|
||||
cvar_t *r_sleepThreshold;
|
||||
cvar_t *r_shadingRate;
|
||||
cvar_t *r_novis;
|
||||
cvar_t *r_nocull;
|
||||
cvar_t *r_nocurves;
|
||||
|
@ -392,6 +393,7 @@ static const cvarTableItem_t r_cvars[] =
|
|||
{ &r_mapGreyscaleCTF, "r_mapGreyscaleCTF", "0", CVAR_ARCHIVE, CVART_FLOAT, "0", "1", help_r_mapGreyscaleCTF },
|
||||
{ &r_teleporterFlash, "r_teleporterFlash", "1", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, "draws bright colors when being teleported" },
|
||||
{ &r_sleepThreshold, "r_sleepThreshold", "2500", CVAR_ARCHIVE, CVART_INTEGER, "2000", "4000", help_r_sleepThreshold },
|
||||
{ &r_shadingRate, "r_shadingRate", "0", CVAR_ARCHIVE, CVART_INTEGER, "0", "6", help_r_shadingRate },
|
||||
|
||||
//
|
||||
// temporary variables that can change at any time
|
||||
|
|
|
@ -1061,6 +1061,7 @@ extern cvar_t *r_mapGreyscale; // how monochrome the map looks
|
|||
extern cvar_t *r_mapGreyscaleCTF; // how monochrome CTF map surfaces look
|
||||
extern cvar_t *r_teleporterFlash; // 1 is default Q3 behavior, 0 is pure black
|
||||
extern cvar_t *r_sleepThreshold; // time cushion in us for a call to Sleep(1+)
|
||||
extern cvar_t *r_shadingRate; // variable-rate shading (VRS) mode
|
||||
extern cvar_t *r_fullbright; // avoid lightmap pass
|
||||
extern cvar_t *r_depthFade; // fades marked shaders based on depth
|
||||
extern cvar_t *r_dither; // enables dithering
|
||||
|
|
Loading…
Reference in a new issue