mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-01-22 16:31:13 +00:00
DXR 1.1 and SV_Barycentrics support are now optional
This commit is contained in:
parent
62f3a17e55
commit
b5b16e6033
11 changed files with 126 additions and 38 deletions
|
@ -45,6 +45,11 @@ struct DenoiseRC
|
|||
|
||||
void DynamicLights::Init()
|
||||
{
|
||||
if(!rhiInfo.hasInlineRaytracing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
GraphicsPipelineDesc desc("Dynamic Lights");
|
||||
desc.shortLifeTime = true;
|
||||
|
@ -77,8 +82,7 @@ void DynamicLights::Draw()
|
|||
return;
|
||||
}
|
||||
|
||||
const HBuffer tlasBuffer = crp.raytracing.GetTLAS();
|
||||
if(IsNullHandle(tlasBuffer) ||
|
||||
if(!crp.raytracing.CanRaytrace() ||
|
||||
backEnd.refdef.num_dlights <= 0)
|
||||
{
|
||||
CmdBeginBarrier();
|
||||
|
|
|
@ -335,8 +335,9 @@ struct Raytracing
|
|||
void Init();
|
||||
void ProcessWorld(world_t& world);
|
||||
void BeginFrame(bool wantUpdate);
|
||||
HBuffer GetTLAS() { return tlasBuffer; }
|
||||
HBuffer GetInstanceBuffer() { return tlasInstanceBuffer; }
|
||||
uint32_t GetTLASBufferIndex();
|
||||
uint32_t GetInstanceBufferIndex();
|
||||
bool CanRaytrace();
|
||||
|
||||
private:
|
||||
void TagMapSurfacesRecursively(mnode_t* node);
|
||||
|
|
|
@ -287,7 +287,6 @@ void CRP::Init()
|
|||
|
||||
InitDesc initDesc;
|
||||
initDesc.directDescriptorHeapIndexing = true;
|
||||
initDesc.inlineRaytracing = true;
|
||||
srp.firstInit = RHI::Init(initDesc);
|
||||
srp.psoStatsValid = false;
|
||||
|
||||
|
@ -916,8 +915,6 @@ void CRP::UploadSceneViewData()
|
|||
const viewParms_t& vp = backEnd.viewParms;
|
||||
const HBuffer uploadBuffer = sceneViewUploadBuffers[GetFrameIndex()];
|
||||
const uint32_t uploadByteOffset = sceneViewIndex * SceneViewConst::StructBytes;
|
||||
const HBuffer tlasBuffer = raytracing.GetTLAS();
|
||||
const HBuffer tlasInstanceBuffer = raytracing.GetInstanceBuffer();
|
||||
|
||||
SceneView& dest = *(SceneView*)(MapBuffer(uploadBuffer) + uploadByteOffset);
|
||||
|
||||
|
@ -953,8 +950,8 @@ void CRP::UploadSceneViewData()
|
|||
dest.motionVectorTextureIndex = GetTextureIndexSRV(motionVectorTexture);
|
||||
dest.motionVectorMBTextureIndex = GetTextureIndexSRV(motionVectorMBTexture);
|
||||
dest.lightTextureIndex = GetTextureIndexSRV(lightTexture);
|
||||
dest.tlasBufferIndex = IsNullHandle(tlasBuffer) ? 0 : GetBufferIndexSRV(tlasBuffer);
|
||||
dest.tlasInstanceBufferIndex = IsNullHandle(tlasInstanceBuffer) ? 0 : GetBufferIndexSRV(tlasInstanceBuffer);
|
||||
dest.tlasBufferIndex = raytracing.GetTLASBufferIndex();
|
||||
dest.tlasInstanceBufferIndex = raytracing.GetInstanceBufferIndex();
|
||||
dest.lightCount = refdef.num_dlights;
|
||||
RB_LinearDepthConstants(&dest.linearDepthA, &dest.linearDepthB);
|
||||
dest.zNear = vp.zNear;
|
||||
|
|
|
@ -23,6 +23,7 @@ along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
#include "crp_local.h"
|
||||
#include "compshaders/crp/prepass.h"
|
||||
#include "compshaders/crp/prepass_bary.h"
|
||||
#include "compshaders/crp/fullscreen.h"
|
||||
#include "compshaders/crp/skybox_motion.h"
|
||||
|
||||
|
@ -315,8 +316,16 @@ void Prepass::ProcessShader(shader_t& shader)
|
|||
desc.name = "pre-pass";
|
||||
desc.rootSignature = RHI_MAKE_NULL_HANDLE();
|
||||
desc.shortLifeTime = true; // the PSO cache is only valid for this map!
|
||||
if(rhiInfo.hasBarycentrics)
|
||||
{
|
||||
desc.vertexShader.Set(g_prepass_bary_vs);
|
||||
desc.pixelShader.Set(g_prepass_bary_ps);
|
||||
}
|
||||
else
|
||||
{
|
||||
desc.vertexShader.Set(g_prepass_vs);
|
||||
desc.pixelShader.Set(g_prepass_ps);
|
||||
}
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Position, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::TexCoord, DataType::Float32, 2, 0);
|
||||
|
|
|
@ -166,12 +166,6 @@ static void CreateOrGrowBuffer(HBuffer& buffer, uint32_t& curByteCount, const Bu
|
|||
|
||||
void Raytracing::Init()
|
||||
{
|
||||
const uint32_t structByteCount = sizeof(TLASInstance);
|
||||
BufferDesc desc("BLAS support instance", 2 * BLASBucket::Count * structByteCount, ResourceStates::ShaderAccessBits);
|
||||
desc.shortLifeTime = true;
|
||||
desc.structureByteCount = structByteCount;
|
||||
tlasInstanceBuffer = CreateBuffer(desc);
|
||||
|
||||
// make sure we're not trying to use deleted buffers after a video restart
|
||||
for(uint32_t i = 0; i < BLASBucket::Count; i++)
|
||||
{
|
||||
|
@ -180,10 +174,27 @@ void Raytracing::Init()
|
|||
dynamicBLASBuffers[i] = {};
|
||||
}
|
||||
tlasBuffer = RHI_MAKE_NULL_HANDLE();
|
||||
|
||||
if(!rhiInfo.hasInlineRaytracing)
|
||||
{
|
||||
tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t structByteCount = sizeof(TLASInstance);
|
||||
BufferDesc desc("BLAS support instance", 2 * BLASBucket::Count * structByteCount, ResourceStates::ShaderAccessBits);
|
||||
desc.shortLifeTime = true;
|
||||
desc.structureByteCount = structByteCount;
|
||||
tlasInstanceBuffer = CreateBuffer(desc);
|
||||
}
|
||||
|
||||
void Raytracing::ProcessWorld(world_t& world)
|
||||
{
|
||||
if(!rhiInfo.hasInlineRaytracing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TagMapSurfacesRecursively(world.nodes);
|
||||
|
||||
BLASBuilder staticBLASes[BLASBucket::Count];
|
||||
|
@ -248,6 +259,11 @@ void Raytracing::ProcessWorld(world_t& world)
|
|||
|
||||
void Raytracing::BeginFrame(bool wantUpdate)
|
||||
{
|
||||
if(!rhiInfo.hasInlineRaytracing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(tr.world == NULL || tr.sceneCounterRT == 0)
|
||||
{
|
||||
return;
|
||||
|
@ -651,3 +667,31 @@ bool Raytracing::DynamicSurfaceList::GetSurface(Surface& surface, uint32_t index
|
|||
|
||||
return skip;
|
||||
}
|
||||
|
||||
uint32_t Raytracing::GetTLASBufferIndex()
|
||||
{
|
||||
if(IsNullHandle(tlasBuffer))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetBufferIndexSRV(tlasBuffer);
|
||||
}
|
||||
|
||||
uint32_t Raytracing::GetInstanceBufferIndex()
|
||||
{
|
||||
if(IsNullHandle(tlasInstanceBuffer))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetBufferIndexSRV(tlasInstanceBuffer);
|
||||
}
|
||||
|
||||
bool Raytracing::CanRaytrace()
|
||||
{
|
||||
return
|
||||
rhiInfo.hasInlineRaytracing &&
|
||||
GetTLASBufferIndex() != 0 &&
|
||||
GetInstanceBufferIndex() != 0;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,6 @@ void GRP::Init()
|
|||
{
|
||||
InitDesc initDesc;
|
||||
initDesc.directDescriptorHeapIndexing = false;
|
||||
initDesc.inlineRaytracing = false;
|
||||
srp.firstInit = RHI::Init(initDesc);
|
||||
|
||||
if(srp.firstInit)
|
||||
|
|
|
@ -3351,18 +3351,6 @@ namespace RHI
|
|||
}
|
||||
}
|
||||
|
||||
if(initDesc.inlineRaytracing)
|
||||
{
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5 = {};
|
||||
if(SUCCEEDED(rhi.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5))))
|
||||
{
|
||||
if(options5.RaytracingTier < D3D12_RAYTRACING_TIER_1_1)
|
||||
{
|
||||
ri.Error(ERR_FATAL, "The CRP requires DXR 1.1 capable hardware\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
D3D12MA::ALLOCATOR_DESC desc = {};
|
||||
desc.pDevice = rhi.device;
|
||||
|
@ -3624,6 +3612,16 @@ namespace RHI
|
|||
ri.Printf(PRINT_ALL, "Supported VRS modes: %s\n", modeLists[listIndex]);
|
||||
}
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5 = {};
|
||||
const bool hasInlineRaytracing =
|
||||
SUCCEEDED(rhi.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5))) &&
|
||||
options5.RaytracingTier >= D3D12_RAYTRACING_TIER_1_1;
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS3 options3 = {};
|
||||
const bool hasBarycentrics =
|
||||
SUCCEEDED(rhi.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &options3, sizeof(options3))) &&
|
||||
options3.BarycentricsSupported;
|
||||
|
||||
glInfo.maxTextureSize = MAX_TEXTURE_SIZE;
|
||||
glInfo.maxAnisotropy = 16;
|
||||
glInfo.depthFadeSupport = qtrue;
|
||||
|
@ -3638,6 +3636,8 @@ namespace RHI
|
|||
rhiInfo.hasExtendedVRS = rhi.extendedVRSSupport;
|
||||
rhiInfo.isUMA = rhi.allocator->IsUMA();
|
||||
rhiInfo.isCacheCoherentUMA = rhi.allocator->IsCacheCoherentUMA();
|
||||
rhiInfo.hasInlineRaytracing = hasInlineRaytracing;
|
||||
rhiInfo.hasBarycentrics = hasBarycentrics;
|
||||
|
||||
rhi.initialized = true;
|
||||
|
||||
|
|
|
@ -720,9 +720,6 @@ namespace RHI
|
|||
// - all shader resources are exclusively used through ResourceDescriptorHeap and SamplerDescriptorHeap
|
||||
// - all root signature and descriptor table functions are disabled
|
||||
bool directDescriptorHeapIndexing = false;
|
||||
|
||||
// shut down if DXR 1.1 isn't available
|
||||
bool inlineRaytracing = false;
|
||||
};
|
||||
|
||||
bool Init(const InitDesc& desc); // true when a full init happened (the device was created)
|
||||
|
|
|
@ -61,8 +61,13 @@ struct VOut
|
|||
float4 currPosition : CURRPOSITION;
|
||||
float4 prevPosition : PREVPOSITION;
|
||||
float4 prevPositionMB : PREVPOSITIONMB;
|
||||
#if BARYCENTRICS
|
||||
nointerpolation float3 normalWS : NORMALWS;
|
||||
nointerpolation float3 positionWS : POSITIONWS;
|
||||
#else
|
||||
float3 normalWS : NORMALWS;
|
||||
float3 positionWS : POSITIONWS;
|
||||
#endif
|
||||
float2 texCoords : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float clipDist : SV_ClipDistance0;
|
||||
|
@ -120,7 +125,11 @@ struct POut
|
|||
float4 shadingPosition : SV_Target3;
|
||||
};
|
||||
|
||||
#if BARYCENTRICS
|
||||
POut ps(VOut input, float3 barycentrics : SV_Barycentrics)
|
||||
#else
|
||||
POut ps(VOut input)
|
||||
#endif
|
||||
{
|
||||
if(alphaTest != ATEST_NONE)
|
||||
{
|
||||
|
@ -133,6 +142,7 @@ POut ps(VOut input, float3 barycentrics : SV_Barycentrics)
|
|||
}
|
||||
}
|
||||
|
||||
#if BARYCENTRICS
|
||||
float3 p0 = GetAttributeAtVertex(input.positionWS, 0);
|
||||
float3 p1 = GetAttributeAtVertex(input.positionWS, 1);
|
||||
float3 p2 = GetAttributeAtVertex(input.positionWS, 2);
|
||||
|
@ -151,6 +161,11 @@ POut ps(VOut input, float3 barycentrics : SV_Barycentrics)
|
|||
float3 dist3 = saturate(abs(shadingPosition - position));
|
||||
float dist = saturate(distance(shadingPosition, position));
|
||||
float positionDelta = asfloat(PackColor(float4(dist3, dist)));
|
||||
#else
|
||||
float3 normal = input.normalWS;
|
||||
float3 shadingPosition = input.positionWS + 0.01 * normal;
|
||||
float positionDelta = asfloat(0);
|
||||
#endif
|
||||
|
||||
float2 currPosTC = NDCToTC(input.currPosition.xy / input.currPosition.w);
|
||||
float2 prevPosTC = NDCToTC(input.prevPosition.xy / input.prevPosition.w);
|
||||
|
|
|
@ -1755,6 +1755,8 @@ struct RHIInfo
|
|||
qbool hasExtendedVRS;
|
||||
qbool isUMA;
|
||||
qbool isCacheCoherentUMA;
|
||||
qbool hasInlineRaytracing;
|
||||
qbool hasBarycentrics;
|
||||
};
|
||||
|
||||
extern RHIInfo rhiInfo;
|
||||
|
|
|
@ -170,35 +170,54 @@ void CompileSMAAShaders()
|
|||
ProcessSMAAShadersForPreset("ultra", "-D SMAA_PRESET_ULTRA=1");
|
||||
}
|
||||
|
||||
void CompileGraphics(const char* headerPath, const char* shaderPath, const char* varName)
|
||||
void CompileGraphics(const char* headerPath, const char* shaderPath, const char* varName,
|
||||
int vsOptionCount = 0, int psOptionCount = 0, ...)
|
||||
{
|
||||
const char* vsHeaderRelPath = va("%s.vs.h", shaderPath);
|
||||
const char* psHeaderRelPath = va("%s.ps.h", shaderPath);
|
||||
const char* vsHeaderPath = OutputPath(vsHeaderRelPath);
|
||||
const char* psHeaderPath = OutputPath(psHeaderRelPath);
|
||||
const char* vsExtras[] =
|
||||
|
||||
int vsExtraCount = 4;
|
||||
int psExtraCount = 4;
|
||||
const char* vsExtras[64] =
|
||||
{
|
||||
"-D", "VERTEX_SHADER=1",
|
||||
"-Vn", HeaderVariable(va("g_%s_vs", varName))
|
||||
};
|
||||
const char* psExtras[] =
|
||||
const char* psExtras[64] =
|
||||
{
|
||||
"-D", "PIXEL_SHADER=1",
|
||||
"-Vn", HeaderVariable(va("g_%s_ps", varName))
|
||||
};
|
||||
|
||||
assert(vsExtraCount + vsOptionCount <= _countof(vsExtras));
|
||||
assert(psExtraCount + psOptionCount <= _countof(psExtras));
|
||||
|
||||
va_list argPtr;
|
||||
va_start(argPtr, psOptionCount);
|
||||
for(int i = 0; i < vsOptionCount; i++)
|
||||
{
|
||||
vsExtras[vsExtraCount++] = va_arg(argPtr, const char*);
|
||||
}
|
||||
for(int i = 0; i < psOptionCount; i++)
|
||||
{
|
||||
psExtras[psExtraCount++] = va_arg(argPtr, const char*);
|
||||
}
|
||||
va_end(argPtr);
|
||||
|
||||
ShaderArgs args;
|
||||
args.entryPoint = "vs";
|
||||
args.headerPath = vsHeaderRelPath;
|
||||
args.shaderPath = shaderPath;
|
||||
args.targetProfile = targetVS;
|
||||
CompileShader(args, _countof(vsExtras), vsExtras);
|
||||
CompileShader(args, vsExtraCount, vsExtras);
|
||||
|
||||
args.entryPoint = "ps";
|
||||
args.headerPath = psHeaderRelPath;
|
||||
args.shaderPath = shaderPath;
|
||||
args.targetProfile = targetPS;
|
||||
CompileShader(args, _countof(psExtras), psExtras);
|
||||
CompileShader(args, psExtraCount, psExtras);
|
||||
|
||||
const char* outHeaderPath = OutputPath(headerPath);
|
||||
system(va("type %s %s > %s", vsHeaderPath, psHeaderPath, outHeaderPath));
|
||||
|
@ -389,6 +408,7 @@ void ProcessCRP()
|
|||
CompileCompute("mip_2.h", "mip_2.hlsl", "mip_2");
|
||||
CompileCompute("mip_3.h", "mip_3.hlsl", "mip_3");
|
||||
CompileGraphics("prepass.h", "prepass.hlsl", "prepass");
|
||||
CompileGraphics("prepass_bary.h", "prepass.hlsl", "prepass_bary", 1, 1, "-D BARYCENTRICS=1", "-D BARYCENTRICS=1");
|
||||
CompileGraphics("opaque.h", "opaque.hlsl", "opaque");
|
||||
CompileGraphics("transp_draw.h", "transp_draw.hlsl", "transp_draw");
|
||||
CompilePixelShader("transp_resolve.h", "transp_resolve.hlsl", "transp_resolve");
|
||||
|
|
Loading…
Reference in a new issue