diff --git a/e3/maps/e3/e3_1.map b/e3/maps/e3/e3_1.map
index 6239f657..2bdb88fc 100644
--- a/e3/maps/e3/e3_1.map
+++ b/e3/maps/e3/e3_1.map
@@ -17771,6 +17771,7 @@ Version 2
"light_target" "0 0 -434"
"light_up" "8 -348 0"
"light_right" "-272 6 0"
+"vls" "1"
}
// entity 89
{
diff --git a/neo/engine/doomdll.vcxproj.user b/neo/engine/doomdll.vcxproj.user
index e4f905db..b9fcfa12 100644
--- a/neo/engine/doomdll.vcxproj.user
+++ b/neo/engine/doomdll.vcxproj.user
@@ -15,9 +15,9 @@
D:\projects\Doom3\Doom3.exe
WindowsLocalDebugger
- +set r_fullscreen 0 +set r_mode 9 +set sv_pure 0 +set fs_game e3
+ +set r_fullscreen 0 +set r_mode 9 +set sv_pure 0
D:\projects\Doom3
- +set r_fullscreen 0 +set r_mode 9|+set r_fullscreen 1 +set r_mode 9 +set sv_pure 0 +set fs_game e3|+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0 |+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0|+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0 +set fs_game e3|
+ +set r_fullscreen 0 +set r_mode 9|+set r_fullscreen 1 +set r_mode 9 +set sv_pure 0 +set fs_game e3|+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0|+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0 +set fs_game e3|+set r_fullscreen 0 +set r_mode 9 +set sv_pure 0 |
D:\projects\Doom3\Quake4.exe
diff --git a/neo/engine/framework/Console.cpp b/neo/engine/framework/Console.cpp
index c20805a7..2e698299 100644
--- a/neo/engine/framework/Console.cpp
+++ b/neo/engine/framework/Console.cpp
@@ -178,6 +178,16 @@ SCR_DrawFPS
==================
*/
#define FPS_FRAMES 4
+static const idVec4 &SCR_FrameTimeColor( int msec ) {
+ if ( msec < 16 ) {
+ return colorGreen;
+ }
+ if ( msec < 30 ) {
+ return colorYellow;
+ }
+ return colorRed;
+}
+
float SCR_DrawFPS( float y ) {
char *s;
int w;
@@ -208,15 +218,25 @@ float SCR_DrawFPS( float y ) {
fps = 10000 * FPS_FRAMES / total;
fps = (fps + 5)/10;
- s = va( "%ifps", fps );
+ const int averageFrameTime = ( total + ( FPS_FRAMES / 2 ) ) / FPS_FRAMES;
+ const int frameGenMultiplier = idMath::ClampInt( 1, 4, cvarSystem->GetCVarInteger( "r_frameGen" ) );
+ const int displayFps = fps * frameGenMultiplier;
+ const int displayFrameTime = ( averageFrameTime + ( frameGenMultiplier / 2 ) ) / frameGenMultiplier;
+ const idVec4 &frameColor = SCR_FrameTimeColor( displayFrameTime );
+
+ if ( frameGenMultiplier >= 2 ) {
+ s = va( "%ifps %dms est (%ir %dms)", displayFps, displayFrameTime, fps, averageFrameTime );
+ } else {
+ s = va( "%ifps %dms", fps, averageFrameTime );
+ }
w = strlen( s ) * BIGCHAR_WIDTH;
- renderSystem->DrawBigStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, colorWhite, true, localConsole.charSetShader);
+ renderSystem->DrawBigStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, frameColor, true, localConsole.charSetShader);
y += BIGCHAR_HEIGHT + 4;
s = va( "game cpu:%4.1fms render cpu:%4.1fms pt gpu:%4.1fms", com_lastGameFrameMsec, com_lastRenderFrameMsec, com_pathTracingGpuMsec );
w = strlen( s ) * SMALLCHAR_WIDTH;
- renderSystem->DrawSmallStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, colorWhite, true, localConsole.charSetShader);
+ renderSystem->DrawSmallStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, frameColor, true, localConsole.charSetShader);
return y + SMALLCHAR_HEIGHT + 4;
}
diff --git a/neo/engine/opengl/gl_d3d12raylight.cpp b/neo/engine/opengl/gl_d3d12raylight.cpp
index 5b629e1e..703ac935 100644
--- a/neo/engine/opengl/gl_d3d12raylight.cpp
+++ b/neo/engine/opengl/gl_d3d12raylight.cpp
@@ -2434,11 +2434,12 @@ struct glRaytracingLightingState_t
ComPtr denoisePSO;
ComPtr temporalPSO;
- glRaytracingTexture_t pathTraceTexture;
+ glRaytracingTexture_t pathTraceTexture[2];
glRaytracingTexture_t temporalTexture;
glRaytracingTexture_t historyTexture[2];
glRaytracingTexture_t denoiseTemp[2];
uint32_t currentHistoryIndex;
+ uint32_t currentPathTraceIndex;
glRaytracingBuffer_t denoiseConstantBuffer[3];
glRaytracingBuffer_t denoiseConstantBufferRing[GL_RAYTRACING_CMD_RING_SIZE][3];
void* denoiseConstantBufferMapped[3];
@@ -2474,6 +2475,7 @@ struct glRaytracingLightingState_t
denoiseHeight = 0;
denoiseFormat = DXGI_FORMAT_UNKNOWN;
currentHistoryIndex = 0;
+ currentPathTraceIndex = 0;
frameCounter = 0;
externalDenoiser = false;
emissiveTexture = nullptr;
@@ -4707,7 +4709,7 @@ float3 PathTraceDeterministicLighting(
float3 skyColorRGB = float3(0.98, 0.55, 0.35);
float3 skyColor = skyColorRGB * (0.35 + 0.65 * upness);
- float3 lightingAccum = gAmbientColor.rgb * (gAmbientColor.a * 0.04);
+ float3 lightingAccum = float3(0, 0, 0); // gAmbientColor.rgb * (gAmbientColor.a * 0.04);
lightingAccum += skyColor * (0.42 * skyVis);
lightingAccum += ambientSkyVis * (skyColorRGB * 0.12);
@@ -6243,7 +6245,8 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
if (width == 0 || height == 0)
return 0;
- if (g_glRaytracingLighting.pathTraceTexture.resource &&
+ if (g_glRaytracingLighting.pathTraceTexture[0].resource &&
+ g_glRaytracingLighting.pathTraceTexture[1].resource &&
g_glRaytracingLighting.temporalTexture.resource &&
g_glRaytracingLighting.historyTexture[0].resource &&
g_glRaytracingLighting.historyTexture[1].resource &&
@@ -6256,7 +6259,8 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
return 1;
}
- if (g_glRaytracingLighting.pathTraceTexture.resource ||
+ if (g_glRaytracingLighting.pathTraceTexture[0].resource ||
+ g_glRaytracingLighting.pathTraceTexture[1].resource ||
g_glRaytracingLighting.temporalTexture.resource ||
g_glRaytracingLighting.historyTexture[0].resource ||
g_glRaytracingLighting.historyTexture[1].resource ||
@@ -6266,20 +6270,24 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
glRaytracingWaitIdle();
}
- g_glRaytracingLighting.pathTraceTexture = glRaytracingTexture_t();
+ g_glRaytracingLighting.pathTraceTexture[0] = glRaytracingTexture_t();
+ g_glRaytracingLighting.pathTraceTexture[1] = glRaytracingTexture_t();
g_glRaytracingLighting.temporalTexture = glRaytracingTexture_t();
g_glRaytracingLighting.historyTexture[0] = glRaytracingTexture_t();
g_glRaytracingLighting.historyTexture[1] = glRaytracingTexture_t();
g_glRaytracingLighting.denoiseTemp[0] = glRaytracingTexture_t();
g_glRaytracingLighting.denoiseTemp[1] = glRaytracingTexture_t();
- g_glRaytracingLighting.pathTraceTexture = glRaytracingCreateTexture2D(
- g_glRaytracingCmd.device.Get(),
- width,
- height,
- GL_RAYTRACING_DENOISE_FORMAT,
- D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
- D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+ for (int i = 0; i < 2; ++i)
+ {
+ g_glRaytracingLighting.pathTraceTexture[i] = glRaytracingCreateTexture2D(
+ g_glRaytracingCmd.device.Get(),
+ width,
+ height,
+ GL_RAYTRACING_DENOISE_FORMAT,
+ D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
+ D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+ }
g_glRaytracingLighting.temporalTexture = glRaytracingCreateTexture2D(
g_glRaytracingCmd.device.Get(),
@@ -6311,7 +6319,8 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
}
- if (!g_glRaytracingLighting.pathTraceTexture.resource ||
+ if (!g_glRaytracingLighting.pathTraceTexture[0].resource ||
+ !g_glRaytracingLighting.pathTraceTexture[1].resource ||
!g_glRaytracingLighting.temporalTexture.resource ||
!g_glRaytracingLighting.historyTexture[0].resource ||
!g_glRaytracingLighting.historyTexture[1].resource ||
@@ -6322,6 +6331,7 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
}
g_glRaytracingLighting.currentHistoryIndex = 0;
+ g_glRaytracingLighting.currentPathTraceIndex = 0;
g_glRaytracingLighting.denoiseWidth = width;
g_glRaytracingLighting.denoiseHeight = height;
g_glRaytracingLighting.denoiseFormat = GL_RAYTRACING_DENOISE_FORMAT;
@@ -6486,7 +6496,7 @@ static bool glRaytracingLightingExecuteInternal(
!g_glRaytracingLighting.externalDenoiser;
ID3D12Resource* rayOutputTexture = useInternalDenoiser
- ? g_glRaytracingLighting.pathTraceTexture.resource.Get()
+ ? g_glRaytracingLighting.pathTraceTexture[g_glRaytracingLighting.currentPathTraceIndex & 1u].resource.Get()
: pass->outputTexture;
if (!glRaytracingBeginCmd())
@@ -6517,12 +6527,14 @@ static bool glRaytracingLightingExecuteInternal(
const uint32_t historyReadIndex = g_glRaytracingLighting.currentHistoryIndex & 1u;
const uint32_t historyWriteIndex = (g_glRaytracingLighting.currentHistoryIndex ^ 1u) & 1u;
+ const uint32_t pathTraceIndex = g_glRaytracingLighting.currentPathTraceIndex & 1u;
+ glRaytracingTexture_t& pathTraceTexture = g_glRaytracingLighting.pathTraceTexture[pathTraceIndex];
glRaytracingLightingCreatePerPassDescriptors(
pass,
topLevelAS,
rayOutputTexture,
- g_glRaytracingLighting.pathTraceTexture.resource.Get(),
+ pathTraceTexture.resource.Get(),
g_glRaytracingLighting.denoiseTemp[0].resource.Get(),
g_glRaytracingLighting.denoiseTemp[1].resource.Get(),
g_glRaytracingLighting.historyTexture[historyReadIndex].resource.Get(),
@@ -6532,10 +6544,10 @@ static bool glRaytracingLightingExecuteInternal(
if (useInternalDenoiser)
{
glRaytracingTransition(g_glRaytracingCmd.cmdList.Get(),
- g_glRaytracingLighting.pathTraceTexture.resource.Get(),
- g_glRaytracingLighting.pathTraceTexture.state,
+ pathTraceTexture.resource.Get(),
+ pathTraceTexture.state,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- g_glRaytracingLighting.pathTraceTexture.state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
+ pathTraceTexture.state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
}
else
{
@@ -6598,10 +6610,10 @@ static bool glRaytracingLightingExecuteInternal(
const UINT groupsY = (pass->height + 7u) / 8u;
glRaytracingTransition(g_glRaytracingCmd.cmdList.Get(),
- g_glRaytracingLighting.pathTraceTexture.resource.Get(),
- g_glRaytracingLighting.pathTraceTexture.state,
+ pathTraceTexture.resource.Get(),
+ pathTraceTexture.state,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- g_glRaytracingLighting.pathTraceTexture.state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+ pathTraceTexture.state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
glRaytracingTransition(g_glRaytracingCmd.cmdList.Get(),
g_glRaytracingLighting.temporalTexture.resource.Get(),
@@ -6737,7 +6749,10 @@ static bool glRaytracingLightingExecuteInternal(
g_glRaytracingCmd.pathTracingTimestampFenceRing[g_glRaytracingCmd.cmdCurrentSlot] = g_glRaytracingCmd.cmdLastFenceValue;
if (useInternalDenoiser)
+ {
g_glRaytracingLighting.currentHistoryIndex = historyWriteIndex;
+ g_glRaytracingLighting.currentPathTraceIndex = (pathTraceIndex ^ 1u);
+ }
++g_glRaytracingLighting.frameCounter;
return true;
@@ -6795,6 +6810,7 @@ bool glRaytracingLightingInit(void)
return false;
memset(&g_glRaytracingLighting.constants, 0, sizeof(g_glRaytracingLighting.constants));
+ g_glRaytracingLighting.cpuLights.reserve(GL_RAYTRACING_MAX_LIGHTS);
glRaytracingSetIdentity4x4(g_glRaytracingLighting.constants.invViewProj);
glRaytracingSetIdentity4x4(g_glRaytracingLighting.constants.invViewMatrix);
glRaytracingSetIdentity4x4(g_glRaytracingLighting.constants.viewProj);
diff --git a/neo/engine/opengl/gl_d3d12shim.cpp b/neo/engine/opengl/gl_d3d12shim.cpp
index b3669ece..a3fd56f9 100644
--- a/neo/engine/opengl/gl_d3d12shim.cpp
+++ b/neo/engine/opengl/gl_d3d12shim.cpp
@@ -373,6 +373,7 @@ static void QD3D12_SubmitOpenFrameNoPresentAndWait();
static void QD3D12_EnsureFrameOpen();
static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w);
static void QD3D12_ExecuteMainCommandListAndWait(QD3D12Window& w);
+static void QD3D12_ExecuteMainCommandListForRaytracingHandoff(QD3D12Window& w);
static bool QD3D12_RunInternalTAA(QD3D12Window& w, D3D12_GPU_DESCRIPTOR_HANDLE inputSrv, D3D12_GPU_DESCRIPTOR_HANDLE& outputSrv);
static bool QD3D12_FinalBlitToBackBuffer(QD3D12Window& w, D3D12_GPU_DESCRIPTOR_HANDLE inputSrv, const D3D12_VIEWPORT& outputViewport, const D3D12_RECT& outputScissor, bool toneMapInput = false);
static void QD3D12_RunRayAIDenoiseIfEnabled(ID3D12GraphicsCommandList* cl, QD3D12Window& w, ID3D12Resource* lightingResource);
@@ -1483,6 +1484,10 @@ struct GLState
GLenum depthFunc = GL_LEQUAL;
UINT64 nextFenceValue = 1;
+ ComPtr raytraceContinuationAlloc[QD3D12_FrameCount];
+ UINT64 raytraceContinuationFence[QD3D12_FrameCount] = {};
+ UINT raytraceContinuationIndex = 0;
+ int activeRaytraceContinuationSlot = -1;
GLuint currentMotionObjectId = 0;
float currentSurfaceRoughness = 0.5f;
@@ -1500,14 +1505,14 @@ struct GLState
QD3D12UpscalerBackend upscalerBackend = QD3D12_UPSCALER_DLSS;
QD3D12UpscalerQuality upscalerQuality = QD3D12_QUALITY_DLAA;
- bool enableInternalTAA = true;
+ bool enableInternalTAA = false;
bool enableRayAIDenoise = false;
- bool enableDLSSRayReconstruction = true;
+ bool enableDLSSRayReconstruction = false;
bool enableFSRRayRegeneration = false;
uint32_t frameGenerationMultiplier = 2;
uint32_t pathTracingSamplesPerPixel = 1;
uint32_t pathTracingFallbackSamplesPerPixel = 2;
- uint32_t pathTracingMaxBounces = 2;
+ uint32_t pathTracingMaxBounces = 3;
float jitterX = 0.0f;
float jitterY = 0.0f;
@@ -2250,9 +2255,17 @@ void QD3D12_SetCurrentWindow(struct QD3D12Window* window) {
g_qd3d12CurrentDC = window->hdc;
}
-static GLuint g_lightingTextureId = 0;
-static TextureResource* g_lightingTexture = nullptr;
-static D3D12_RESOURCE_STATES g_lightingTextureState = D3D12_RESOURCE_STATE_COMMON;
+static constexpr UINT QD3D12_LightingTextureCount = 2;
+static GLuint g_lightingTextureId[QD3D12_LightingTextureCount] = {};
+static TextureResource* g_lightingTexture[QD3D12_LightingTextureCount] = {};
+static D3D12_RESOURCE_STATES g_lightingTextureState[QD3D12_LightingTextureCount] =
+{
+ D3D12_RESOURCE_STATE_COMMON,
+ D3D12_RESOURCE_STATE_COMMON
+};
+static bool g_lightingTextureValid[QD3D12_LightingTextureCount] = {};
+static UINT g_lightingReadIndex = 0;
+static UINT g_lightingWriteIndex = 0;
static ComPtr g_qd3d12NeuralPOMZeroBuffer;
static UINT g_qd3d12NeuralPOMZeroSrvIndex = UINT_MAX;
@@ -6751,7 +6764,12 @@ struct QD3D12StreamlineState
uint32_t lastDlssGEligibilityMaskLogged = 0xffffffffu;
uint32_t lastDlssGFramesToGenerateLogged = 0xffffffffu;
uint32_t lastDlssGPresentedFramesLogged = 0xffffffffu;
- sl::ViewportHandle viewport = { 1 };
+ uint32_t dlssGConfiguredFramesToGenerate = 0xffffffffu;
+ uint32_t dlssGConfiguredRenderWidth = 0xffffffffu;
+ uint32_t dlssGConfiguredRenderHeight = 0xffffffffu;
+ uint32_t dlssGConfiguredColorWidth = 0xffffffffu;
+ uint32_t dlssGConfiguredColorHeight = 0xffffffffu;
+ sl::ViewportHandle viewport = { 0 };
};
static QD3D12StreamlineState g_qd3d12Sl;
@@ -7051,10 +7069,7 @@ static void QD3D12_StreamlineOnDeviceCreated()
static bool QD3D12_WantsDLSSRayReconstruction()
{
- return g_gl.enableDLSSRayReconstruction &&
- g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS &&
- g_gl.upscalerQuality != QD3D12_QUALITY_NATIVE &&
- g_qd3d12Sl.deviceBound;
+ return false;
}
static bool QD3D12_CanUseDLSSRayReconstructionForLighting(const QD3D12Window& w)
@@ -7068,8 +7083,8 @@ static bool QD3D12_UseLightingTextureAsUpscaleInput(const QD3D12Window& w)
{
return QD3D12_CanUseDLSSRayReconstructionForLighting(w) &&
g_gl.raytracedLightingReadyThisFrame &&
- g_lightingTexture &&
- g_lightingTexture->texture;
+ g_lightingTexture[g_lightingReadIndex] &&
+ g_lightingTexture[g_lightingReadIndex]->texture;
}
static sl::Result QD3D12_SetStreamlineCommonConstants(sl::FrameToken& frameToken)
@@ -7127,6 +7142,21 @@ static sl::Result QD3D12_GetStreamlineFrameToken(sl::FrameToken*& frameToken)
return result;
}
+static sl::Result QD3D12_EnableReflexForFrame(sl::FrameToken& frameToken)
+{
+ sl::ReflexOptions reflexOptions{};
+ reflexOptions.mode = sl::ReflexMode::eLowLatencyWithBoost;
+ sl::Result result = slReflexSetOptions(reflexOptions);
+ if (result != sl::Result::eOk)
+ return result;
+
+ result = slReflexSleep(frameToken);
+ if (result != sl::Result::eOk)
+ QD3D12_Log("slReflexSleep failed (%d), continuing with frame generation setup.", int(result));
+
+ return sl::Result::eOk;
+}
+
static bool QD3D12_WantsDLSSFrameGeneration(const QD3D12Window& w)
{
return
@@ -7207,6 +7237,11 @@ static void QD3D12_SetDLSSFrameGenerationOff()
}
g_qd3d12Sl.dlssGActive = false;
+ g_qd3d12Sl.dlssGConfiguredFramesToGenerate = 0xffffffffu;
+ g_qd3d12Sl.dlssGConfiguredRenderWidth = 0xffffffffu;
+ g_qd3d12Sl.dlssGConfiguredRenderHeight = 0xffffffffu;
+ g_qd3d12Sl.dlssGConfiguredColorWidth = 0xffffffffu;
+ g_qd3d12Sl.dlssGConfiguredColorHeight = 0xffffffffu;
}
static void QD3D12_SetDLSSGFeatureLoaded(bool loaded)
@@ -7273,6 +7308,14 @@ static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window& w, sl::FrameToken*
}
}
+ const sl::Result reflexResult = QD3D12_EnableReflexForFrame(*frameToken);
+ if (reflexResult != sl::Result::eOk)
+ {
+ QD3D12_Log("slReflexSetOptions failed (%d), disabling frame generation for this frame.", int(reflexResult));
+ QD3D12_SetDLSSFrameGenerationOff();
+ return;
+ }
+
const sl::Result constResult = QD3D12_SetStreamlineCommonConstants(*frameToken);
if (constResult != sl::Result::eOk)
{
@@ -7281,22 +7324,6 @@ static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window& w, sl::FrameToken*
return;
}
- sl::ReflexOptions reflexOptions{};
- reflexOptions.mode = sl::ReflexMode::eLowLatencyWithBoost;
- const sl::Result reflexOptionsResult = slReflexSetOptions(reflexOptions);
- if (reflexOptionsResult != sl::Result::eOk)
- {
- QD3D12_Log("slReflexSetOptions failed (%d), disabling frame generation for this frame.", int(reflexOptionsResult));
- QD3D12_SetDLSSFrameGenerationOff();
- return;
- }
-
- const sl::Result reflexSleepResult = slReflexSleep(*frameToken);
- if (reflexSleepResult != sl::Result::eOk)
- {
- QD3D12_Log("slReflexSleep failed (%d), continuing with frame generation setup.", int(reflexSleepResult));
- }
-
sl::Extent renderExtent{};
renderExtent.left = 0;
renderExtent.top = 0;
@@ -7324,8 +7351,16 @@ static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window& w, sl::FrameToken*
options.hudLessBufferFormat = uint32_t(DXGI_FORMAT_R8G8B8A8_UNORM);
options.uiBufferFormat = uint32_t(DXGI_FORMAT_R8G8B8A8_UNORM);
+ const bool configMayNeedUpdate =
+ !g_qd3d12Sl.dlssGActive ||
+ g_qd3d12Sl.dlssGConfiguredFramesToGenerate != options.numFramesToGenerate ||
+ g_qd3d12Sl.dlssGConfiguredRenderWidth != w.renderWidth ||
+ g_qd3d12Sl.dlssGConfiguredRenderHeight != w.renderHeight ||
+ g_qd3d12Sl.dlssGConfiguredColorWidth != w.width ||
+ g_qd3d12Sl.dlssGConfiguredColorHeight != w.height;
+
sl::DLSSGState state{};
- const sl::Result stateResult = slDLSSGGetState(g_qd3d12Sl.viewport, state, &options);
+ const sl::Result stateResult = slDLSSGGetState(g_qd3d12Sl.viewport, state, configMayNeedUpdate ? &options : nullptr);
if (stateResult == sl::Result::eOk)
{
if (state.numFramesToGenerateMax > 0)
@@ -7351,12 +7386,29 @@ static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window& w, sl::FrameToken*
QD3D12_TagDLSSFrameGenerationInputs(w, *frameToken, renderExtent, outputExtent);
- const sl::Result setResult = slDLSSGSetOptions(g_qd3d12Sl.viewport, options);
- if (setResult != sl::Result::eOk)
+ const bool needsSetOptions =
+ !g_qd3d12Sl.dlssGActive ||
+ g_qd3d12Sl.dlssGConfiguredFramesToGenerate != options.numFramesToGenerate ||
+ g_qd3d12Sl.dlssGConfiguredRenderWidth != w.renderWidth ||
+ g_qd3d12Sl.dlssGConfiguredRenderHeight != w.renderHeight ||
+ g_qd3d12Sl.dlssGConfiguredColorWidth != w.width ||
+ g_qd3d12Sl.dlssGConfiguredColorHeight != w.height;
+
+ if (needsSetOptions)
{
- QD3D12_Log("slDLSSGSetOptions(on) failed (%d).", int(setResult));
- QD3D12_SetDLSSFrameGenerationOff();
- return;
+ const sl::Result setResult = slDLSSGSetOptions(g_qd3d12Sl.viewport, options);
+ if (setResult != sl::Result::eOk)
+ {
+ QD3D12_Log("slDLSSGSetOptions(on) failed (%d).", int(setResult));
+ QD3D12_SetDLSSFrameGenerationOff();
+ return;
+ }
+
+ g_qd3d12Sl.dlssGConfiguredFramesToGenerate = options.numFramesToGenerate;
+ g_qd3d12Sl.dlssGConfiguredRenderWidth = w.renderWidth;
+ g_qd3d12Sl.dlssGConfiguredRenderHeight = w.renderHeight;
+ g_qd3d12Sl.dlssGConfiguredColorWidth = w.width;
+ g_qd3d12Sl.dlssGConfiguredColorHeight = w.height;
}
if (!g_qd3d12Sl.dlssGActive || g_qd3d12Sl.lastDlssGFramesToGenerateLogged != options.numFramesToGenerate)
@@ -7847,11 +7899,8 @@ static bool QD3D12_ExternalTemporalUpscalerActive(const QD3D12Window& w)
static bool QD3D12_ShouldRunInternalTAA(const QD3D12Window& w)
{
- // DLSS/DLSS-RR/FSR are already temporal. The internal TAA pass replaces MSAA
- // for the native/no-upscaler path and runs after lighting but before 2D.
- return g_gl.enableInternalTAA &&
- !w.isPbuffer &&
- !QD3D12_ExternalTemporalUpscalerActive(w);
+ (void)w;
+ return false;
}
static bool QD3D12_FinalBlitToBackBuffer(
@@ -7985,6 +8034,40 @@ static void QD3D12_ExecuteMainCommandListAndWait(QD3D12Window& w)
g_gl.frameOwner = &w;
}
+static void QD3D12_ExecuteMainCommandListForRaytracingHandoff(QD3D12Window& w)
+{
+ QD3D12_CHECK(g_gl.cmdList->Close());
+
+ ID3D12CommandList* lists[] = { g_gl.cmdList.Get() };
+ g_gl.queue->ExecuteCommandLists(1, lists);
+
+ const UINT64 signalValue = g_gl.nextFenceValue++;
+ QD3D12_CHECK(g_gl.queue->Signal(g_gl.fence.Get(), signalValue));
+ w.frames[w.frameIndex].fenceValue = signalValue;
+
+ const UINT slot = g_gl.raytraceContinuationIndex++ % QD3D12_FrameCount;
+ const UINT64 continuationFence = g_gl.raytraceContinuationFence[slot];
+ if (continuationFence != 0 && g_gl.fence->GetCompletedValue() < continuationFence)
+ {
+ QD3D12_CHECK(g_gl.fence->SetEventOnCompletion(continuationFence, g_gl.fenceEvent));
+ WaitForSingleObject(g_gl.fenceEvent, INFINITE);
+ }
+
+ if (!g_gl.raytraceContinuationAlloc[slot])
+ {
+ QD3D12_CHECK(g_gl.device->CreateCommandAllocator(
+ D3D12_COMMAND_LIST_TYPE_DIRECT,
+ IID_PPV_ARGS(&g_gl.raytraceContinuationAlloc[slot])));
+ }
+
+ QD3D12_CHECK(g_gl.raytraceContinuationAlloc[slot]->Reset());
+ QD3D12_CHECK(g_gl.cmdList->Reset(g_gl.raytraceContinuationAlloc[slot].Get(), nullptr));
+
+ g_gl.activeRaytraceContinuationSlot = (int)slot;
+ g_gl.frameOpen = true;
+ g_gl.frameOwner = &w;
+}
+
static void QD3D12_RunRayAIDenoiseIfEnabled(ID3D12GraphicsCommandList* cl, QD3D12Window& w, ID3D12Resource* lightingResource)
{
(void)cl;
@@ -8016,10 +8099,11 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w)
ID3D12Resource* upscaleInputResource = w.sceneColorBuffers[w.frameIndex].Get();
D3D12_GPU_DESCRIPTOR_HANDLE upscaleInputSrv = w.sceneColorSrvGpu[w.frameIndex];
- if (useLightingUpscaleInput && g_lightingTexture && g_lightingTexture->texture)
+ TextureResource* readLightingTex = g_lightingTexture[g_lightingReadIndex];
+ if (useLightingUpscaleInput && readLightingTex && readLightingTex->texture)
{
- upscaleInputResource = g_lightingTexture->texture.Get();
- upscaleInputSrv = g_lightingTexture->srvGpu;
+ upscaleInputResource = readLightingTex->texture.Get();
+ upscaleInputSrv = readLightingTex->srvGpu;
}
D3D12_VIEWPORT outputViewport{};
@@ -10069,6 +10153,15 @@ void QD3D12_EndFrame()
ID3D12CommandList* lists[] = { g_gl.cmdList.Get() };
g_gl.queue->ExecuteCommandLists(1, lists);
+ if (g_gl.activeRaytraceContinuationSlot >= 0)
+ {
+ const UINT slot = (UINT)g_gl.activeRaytraceContinuationSlot;
+ const UINT64 signalValue = g_gl.nextFenceValue++;
+ QD3D12_CHECK(g_gl.queue->Signal(g_gl.fence.Get(), signalValue));
+ g_gl.raytraceContinuationFence[slot] = signalValue;
+ g_gl.activeRaytraceContinuationSlot = -1;
+ }
+
g_gl.frameOpen = false;
g_gl.frameOwner = nullptr;
if (!w.isPbuffer)
@@ -10300,16 +10393,17 @@ static void EnsureTextureResource(TextureResource& tex)
tex.gpuValid = false;
}
-static TextureResource* QD3D12_EnsureLightingTexture(int width, int height)
+static TextureResource* QD3D12_EnsureLightingTexture(int width, int height, UINT slot)
{
const DXGI_FORMAT desiredFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
+ slot %= QD3D12_LightingTextureCount;
- if (g_lightingTextureId == 0)
+ if (g_lightingTextureId[slot] == 0)
{
- g_lightingTextureId = g_gl.nextTextureId++;
+ g_lightingTextureId[slot] = g_gl.nextTextureId++;
TextureResource tex{};
- tex.glId = g_lightingTextureId;
+ tex.glId = g_lightingTextureId[slot];
tex.width = (int)width;
tex.height = (int)height;
tex.format = GL_RGBA;
@@ -10329,44 +10423,45 @@ static TextureResource* QD3D12_EnsureLightingTexture(int width, int height)
tex.srvCpu = QD3D12_SrvCpu(tex.srvIndex);
tex.srvGpu = QD3D12_SrvGpu(tex.srvIndex);
- auto it = g_gl.textures.emplace(g_lightingTextureId, std::move(tex)).first;
- g_lightingTexture = &it->second;
+ auto it = g_gl.textures.emplace(g_lightingTextureId[slot], std::move(tex)).first;
+ g_lightingTexture[slot] = &it->second;
}
- if (!g_lightingTexture)
+ if (!g_lightingTexture[slot])
{
- auto it = g_gl.textures.find(g_lightingTextureId);
+ auto it = g_gl.textures.find(g_lightingTextureId[slot]);
if (it == g_gl.textures.end())
return nullptr;
- g_lightingTexture = &it->second;
+ g_lightingTexture[slot] = &it->second;
}
- g_lightingTexture->dxgiFormat = desiredFormat;
- g_lightingTexture->mipLevels = 1;
+ TextureResource* lightingTex = g_lightingTexture[slot];
+ lightingTex->dxgiFormat = desiredFormat;
+ lightingTex->mipLevels = 1;
const bool needsCreate =
- !g_lightingTexture->texture ||
- g_lightingTexture->width != (int)width ||
- g_lightingTexture->height != (int)height ||
- g_lightingTexture->texture->GetDesc().Format != desiredFormat ||
- ((g_lightingTexture->texture->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) == 0);
+ !lightingTex->texture ||
+ lightingTex->width != (int)width ||
+ lightingTex->height != (int)height ||
+ lightingTex->texture->GetDesc().Format != desiredFormat ||
+ ((lightingTex->texture->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) == 0);
if (!needsCreate)
- return g_lightingTexture;
+ return lightingTex;
- if (g_lightingTexture->texture)
+ if (lightingTex->texture)
{
- QD3D12_RetireResource(g_lightingTexture->texture);
+ QD3D12_RetireResource(lightingTex->texture);
}
- g_lightingTexture->width = (int)width;
- g_lightingTexture->height = (int)height;
- g_lightingTexture->compressed = false;
- g_lightingTexture->compressedInternalFormat = 0;
- g_lightingTexture->compressedBlockBytes = 0;
- g_lightingTexture->compressedImageSize = 0;
- g_lightingTexture->forceOpaqueAlpha = false;
- g_lightingTexture->sysmem.clear();
+ lightingTex->width = (int)width;
+ lightingTex->height = (int)height;
+ lightingTex->compressed = false;
+ lightingTex->compressedInternalFormat = 0;
+ lightingTex->compressedBlockBytes = 0;
+ lightingTex->compressedImageSize = 0;
+ lightingTex->forceOpaqueAlpha = false;
+ lightingTex->sysmem.clear();
D3D12_RESOURCE_DESC rd{};
rd.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
@@ -10390,7 +10485,7 @@ static TextureResource* QD3D12_EnsureLightingTexture(int width, int height)
&rd,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
nullptr,
- IID_PPV_ARGS(&g_lightingTexture->texture)));
+ IID_PPV_ARGS(&lightingTex->texture)));
D3D12_SHADER_RESOURCE_VIEW_DESC srv{};
srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
@@ -10399,15 +10494,16 @@ static TextureResource* QD3D12_EnsureLightingTexture(int width, int height)
srv.Texture2D.MipLevels = 1;
g_gl.device->CreateShaderResourceView(
- g_lightingTexture->texture.Get(),
+ lightingTex->texture.Get(),
&srv,
- g_lightingTexture->srvCpu);
+ lightingTex->srvCpu);
- g_lightingTexture->gpuValid = true;
- g_lightingTexture->state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
- g_lightingTextureState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ lightingTex->gpuValid = true;
+ lightingTex->state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureState[slot] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureValid[slot] = false;
- return g_lightingTexture;
+ return lightingTex;
}
static void ConvertToRGBA8(const TextureResource& tex, std::vector& outRGBA)
@@ -16733,9 +16829,15 @@ static void QD3D12_ResolveSceneToOutputAndEnterNativePhase(QD3D12Window& w)
{
QD3D12_TransitionResource(cl, w.normalBuffers[w.frameIndex].Get(), w.normalBufferState[w.frameIndex], D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- if (g_lightingTexture && g_lightingTexture->texture)
+ TextureResource* readLightingTex = g_lightingTexture[g_lightingReadIndex];
+ if (readLightingTex && readLightingTex->texture)
{
- QD3D12_TransitionResource(cl, g_lightingTexture->texture.Get(), g_lightingTextureState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ QD3D12_TransitionResource(
+ cl,
+ readLightingTex->texture.Get(),
+ g_lightingTextureState[g_lightingReadIndex],
+ D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ g_lightingTextureState[g_lightingReadIndex] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
}
}
@@ -16771,8 +16873,14 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
QD3D12_EnsureFrameOpen();
- TextureResource* lightingTex = QD3D12_EnsureLightingTexture(width, height);
- if (!lightingTex || !lightingTex->texture)
+ const UINT writeLightingIndex = g_lightingWriteIndex % QD3D12_LightingTextureCount;
+ const UINT previousLightingIndex = writeLightingIndex ^ 1u;
+
+ TextureResource* writeLightingTex = QD3D12_EnsureLightingTexture(width, height, writeLightingIndex);
+ (void)QD3D12_EnsureLightingTexture(width, height, previousLightingIndex);
+ const UINT readLightingIndex = writeLightingIndex;
+ TextureResource* readLightingTex = g_lightingTexture[readLightingIndex];
+ if (!writeLightingTex || !writeLightingTex->texture || !readLightingTex || !readLightingTex->texture)
return;
// Scene/TLAS ownership is now per render world. Querying the scene TLAS here
@@ -16835,18 +16943,18 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
// The external DXR module records and executes its own command list. Because
// of that, the scene input transitions must be submitted on the main command
// list before we call into glRaytracingLightingExecuteForScene.
- if (g_lightingTextureState != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
+ if (g_lightingTextureState[writeLightingIndex] != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
{
QD3D12_TransitionResource(
cl,
- lightingTex->texture.Get(),
- g_lightingTextureState,
+ writeLightingTex->texture.Get(),
+ g_lightingTextureState[writeLightingIndex],
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- g_lightingTextureState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureState[writeLightingIndex] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
}
- QD3D12_ExecuteMainCommandListAndWait(*window);
+ QD3D12_ExecuteMainCommandListForRaytracingHandoff(*window);
cl = g_gl.cmdList.Get();
QD3D12_UpdateCameraInfoFromCurrentMatrices();
@@ -16883,8 +16991,8 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
pass.depthTexture = sceneDepth;
pass.depthFormat = QD3D12_DepthSrvFormat;
- pass.outputTexture = lightingTex->texture.Get();
- pass.outputFormat = lightingTex->dxgiFormat;
+ pass.outputTexture = writeLightingTex->texture.Get();
+ pass.outputFormat = writeLightingTex->dxgiFormat;
pass.width = (uint32_t)width;
pass.height = (uint32_t)height;
@@ -16945,21 +17053,25 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
}
// The scene-handle DXR path leaves outputTexture in PIXEL_SHADER_RESOURCE.
- g_lightingTextureState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureState[writeLightingIndex] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureValid[writeLightingIndex] = true;
+ g_lightingReadIndex = readLightingIndex;
+ g_lightingWriteIndex = previousLightingIndex;
- QD3D12_RunRayAIDenoiseIfEnabled(cl, *window, lightingTex->texture.Get());
+ QD3D12_RunRayAIDenoiseIfEnabled(cl, *window, writeLightingTex->texture.Get());
- // If the denoiser changes the texture state and updates g_lightingTextureState,
+ // If the denoiser changes the written texture state, restore it to a
+ // shader-readable state before this slot becomes the next read target.
// restore the texture to a shader-readable state for the post/upscale pass.
- if (g_lightingTextureState != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
+ if (g_lightingTextureState[writeLightingIndex] != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
{
QD3D12_TransitionResource(
cl,
- lightingTex->texture.Get(),
- g_lightingTextureState,
+ writeLightingTex->texture.Get(),
+ g_lightingTextureState[writeLightingIndex],
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- g_lightingTextureState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ g_lightingTextureState[writeLightingIndex] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
}
g_gl.raytracedLightingReadyThisFrame = true;
@@ -16992,7 +17104,7 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
// in QD3D12_FinalBlitToBackBuffer().
if (!QD3D12_ToneMapFullscreenPass(
*window,
- lightingTex->srvGpu,
+ readLightingTex->srvGpu,
CurrentResolvedSceneColorRTV(),
viewport,
scissor,
@@ -17002,7 +17114,7 @@ void glLightScene(glRaytracingSceneHandle_t sceneHandle)
QD3D12_PostFullscreenPass(
cl,
g_gl.postCopyPSO.Get(),
- lightingTex->srvGpu,
+ readLightingTex->srvGpu,
CurrentResolvedSceneColorRTV(),
viewport,
scissor,
@@ -17177,7 +17289,8 @@ static void QD3D12_ResetInternalTAAHistoryForWindow(QD3D12Window* window)
void QD3D12_EnableTAA(int enabled)
{
- const bool newValue = enabled ? true : false;
+ (void)enabled;
+ const bool newValue = false;
if (g_gl.enableInternalTAA == newValue)
return;
@@ -17193,7 +17306,7 @@ void QD3D12_EnableTAA(int enabled)
int QD3D12_IsTAAEnabled(void)
{
- return g_gl.enableInternalTAA ? 1 : 0;
+ return 0;
}
void APIENTRY glTAAQD3D12(GLboolean enable)
@@ -17270,7 +17383,8 @@ void QD3D12_EnableRayAIDenoise(int enabled)
void QD3D12_EnableDLSSRayReconstruction(int enabled)
{
- const bool newValue = enabled ? true : false;
+ (void)enabled;
+ const bool newValue = false;
if (g_gl.enableDLSSRayReconstruction == newValue)
return;