From e7ff9997ce62d03ada69bf0e689e6d7eb823fad7 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Sun, 10 May 2026 23:19:23 -0700 Subject: [PATCH] Added DLAA support. --- neo/engine/opengl/gl_d3d12shim.cpp | 118 ++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/neo/engine/opengl/gl_d3d12shim.cpp b/neo/engine/opengl/gl_d3d12shim.cpp index 54bf9db8..05a2ae2a 100644 --- a/neo/engine/opengl/gl_d3d12shim.cpp +++ b/neo/engine/opengl/gl_d3d12shim.cpp @@ -161,6 +161,15 @@ using Microsoft::WRL::ComPtr; #ifndef GL_SPECULAR_MAP_BINDING_QD3D12 #define GL_SPECULAR_MAP_BINDING_QD3D12 0x6006 #endif +#ifndef GL_QD3D12_UPSCALER_BACKEND +#define GL_QD3D12_UPSCALER_BACKEND 0x6007 +#endif +#ifndef GL_QD3D12_UPSCALER_QUALITY +#define GL_QD3D12_UPSCALER_QUALITY 0x6008 +#endif +#ifndef GL_QD3D12_DLAA_ENABLED +#define GL_QD3D12_DLAA_ENABLED 0x6009 +#endif // Optional material/ray-visibility tags for the DXR path. These are private // shim enums; they deliberately live next to the normal-map compatibility enums. @@ -268,6 +277,16 @@ void glShowTopLevelAceelStructure(glRaytracingSceneHandle_t scene, uint32_t topL int glIsTopLevelAceelStructureVisible(glRaytracingSceneHandle_t scene, uint32_t topLevelHandle); void glHideAllTopLevelAceelStructures(glRaytracingSceneHandle_t scene); void glShowAllTopLevelAceelStructures(glRaytracingSceneHandle_t scene); +void QD3D12_SetUpscalerBackend(int backend); +void QD3D12_SetUpscalerQuality(int quality); +void QD3D12_SetUpscalerSharpness(float sharpness); +void QD3D12_EnableRayAIDenoise(int enabled); +void QD3D12_EnableDLSSRayReconstruction(int enabled); +void QD3D12_EnableFSRRayRegeneration(int enabled); +void QD3D12_EnableDLAA(int enabled); +int QD3D12_IsDLAAEnabled(void); +void APIENTRY glDLAAQD3D12(GLboolean enable); +void APIENTRY glEnableDLAAQD3D12(GLboolean enable); void QD3D12_SetPathTracingQuality(uint32_t samplesPerPixel, uint32_t maxBounces); void QD3D12_SetPathTracingFallbackSamples(uint32_t samplesPerPixel); void QD3D12_SetCameraInfo( @@ -417,7 +436,8 @@ enum QD3D12UpscalerQuality QD3D12_QUALITY_QUALITY, QD3D12_QUALITY_BALANCED, QD3D12_QUALITY_PERFORMANCE, - QD3D12_QUALITY_ULTRA_PERFORMANCE + QD3D12_QUALITY_ULTRA_PERFORMANCE, + QD3D12_QUALITY_DLAA }; enum QD3D12FramePhase @@ -602,7 +622,7 @@ struct GLBufferObject const char* vendor = "Justin Marshall"; const char* renderer = "Quake D3D12 Wrapper"; const char* version = "1.1-quake-d3d12"; -const char* extensions = "GL_SGIS_multitexture GL_ARB_multitexture GL_EXT_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_compression GL_EXT_texture_compression_s3tc GL_ARB_vertex_program GL_ARB_fragment_program GL_EXT_texture_cube_map GL_EXT_depth_bounds_test GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_QD3D12_normal_map GL_QD3D12_glow_map GL_QD3D12_specular_map GL_QD3D12_glass_material GL_QD3D12_volumetric_light"; +const char* extensions = "GL_SGIS_multitexture GL_ARB_multitexture GL_EXT_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_compression GL_EXT_texture_compression_s3tc GL_ARB_vertex_program GL_ARB_fragment_program GL_EXT_texture_cube_map GL_EXT_depth_bounds_test GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_QD3D12_normal_map GL_QD3D12_glow_map GL_QD3D12_specular_map GL_QD3D12_glass_material GL_QD3D12_volumetric_light GL_QD3D12_dlaa"; enum TexEnvModeShader { @@ -1108,7 +1128,7 @@ struct GLState bool motionHistoryReset = true; QD3D12UpscalerBackend upscalerBackend = QD3D12_UPSCALER_DLSS; - QD3D12UpscalerQuality upscalerQuality = QD3D12_QUALITY_QUALITY; + QD3D12UpscalerQuality upscalerQuality = QD3D12_QUALITY_DLAA; bool enableRayAIDenoise = false; bool enableDLSSRayReconstruction = true; bool enableFSRRayRegeneration = false; @@ -4163,10 +4183,16 @@ static void QD3D12_CreateOcclusionQueryObjects() // SECTION 6.5: temporal upscalers / AI denoise helpers // ============================================================ +static bool QD3D12_IsDLAAQuality(QD3D12UpscalerQuality quality) +{ + return quality == QD3D12_QUALITY_DLAA; +} + static float QD3D12_QualityRatio(QD3D12UpscalerQuality quality) { switch (quality) { + case QD3D12_QUALITY_DLAA: return 1.0f; case QD3D12_QUALITY_QUALITY: return 0.6666667f; case QD3D12_QUALITY_BALANCED: return 0.58f; case QD3D12_QUALITY_PERFORMANCE: return 0.5f; @@ -4259,6 +4285,7 @@ static sl::DLSSMode QD3D12_MapDLSSMode(QD3D12UpscalerQuality quality) case QD3D12_QUALITY_BALANCED: return sl::DLSSMode::eBalanced; case QD3D12_QUALITY_PERFORMANCE: return sl::DLSSMode::eMaxPerformance; case QD3D12_QUALITY_ULTRA_PERFORMANCE: return sl::DLSSMode::eUltraPerformance; + case QD3D12_QUALITY_DLAA: return sl::DLSSMode::eDLAA; case QD3D12_QUALITY_NATIVE: default: return sl::DLSSMode::eOff; } @@ -4483,6 +4510,12 @@ static void QD3D12_SelectRenderResolution(QD3D12Window& w, UINT outputWidth, UIN if (g_gl.upscalerBackend == QD3D12_UPSCALER_NONE || g_gl.upscalerQuality == QD3D12_QUALITY_NATIVE) return; + // DLAA is DLSS at native resolution: keep the internal render target at the + // output size, but do not treat it like QD3D12_QUALITY_NATIVE because the + // Streamline DLSS evaluation still needs to run later in QD3D12_RunUpscalerOrBlit(). + if (QD3D12_IsDLAAQuality(g_gl.upscalerQuality)) + return; + #if defined(QD3D12_ENABLE_STREAMLINE) if (g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS && g_qd3d12Sl.deviceBound) { @@ -4903,7 +4936,9 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w) #endif #if defined(QD3D12_ENABLE_FFX) - if (haveTemporalCameraInputs && g_gl.upscalerBackend == QD3D12_UPSCALER_FSR) + if (haveTemporalCameraInputs && + g_gl.upscalerBackend == QD3D12_UPSCALER_FSR && + !QD3D12_IsDLAAQuality(g_gl.upscalerQuality)) { QD3D12_EnsureFfxUpscaleContext(w); @@ -9467,6 +9502,18 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint* params) *params = (GLint)QD3D12_CurrentRayMaterialFlags(); break; + case GL_QD3D12_UPSCALER_BACKEND: + *params = (GLint)g_gl.upscalerBackend; + break; + + case GL_QD3D12_UPSCALER_QUALITY: + *params = (GLint)g_gl.upscalerQuality; + break; + + case GL_QD3D12_DLAA_ENABLED: + *params = (GLint)QD3D12_IsDLAAEnabled(); + break; + #ifdef GL_ACTIVE_STENCIL_FACE_EXT case GL_ACTIVE_STENCIL_FACE_EXT: *params = (GLint)g_gl.activeStencilFace; @@ -12046,6 +12093,16 @@ PROC WINAPI qd3d12_wglGetProcAddress(LPCSTR name) { { "glRaytracingMaterialFlagQD3D12", (PROC)glRaytracingMaterialFlagQD3D12 }, { "glResolveGBufferQD3D12", (PROC)glResolveGBufferQD3D12 }, { "QD3D12_ResolveGBufferNow", (PROC)QD3D12_ResolveGBufferNow }, + { "QD3D12_SetUpscalerBackend", (PROC)QD3D12_SetUpscalerBackend }, + { "QD3D12_SetUpscalerQuality", (PROC)QD3D12_SetUpscalerQuality }, + { "QD3D12_SetUpscalerSharpness", (PROC)QD3D12_SetUpscalerSharpness }, + { "QD3D12_EnableRayAIDenoise", (PROC)QD3D12_EnableRayAIDenoise }, + { "QD3D12_EnableDLSSRayReconstruction", (PROC)QD3D12_EnableDLSSRayReconstruction }, + { "QD3D12_EnableFSRRayRegeneration", (PROC)QD3D12_EnableFSRRayRegeneration }, + { "QD3D12_EnableDLAA", (PROC)QD3D12_EnableDLAA }, + { "QD3D12_IsDLAAEnabled", (PROC)QD3D12_IsDLAAEnabled }, + { "glDLAAQD3D12", (PROC)glDLAAQD3D12 }, + { "glEnableDLAAQD3D12", (PROC)glEnableDLAAQD3D12 }, { "QD3D12_SetPathTracingQuality", (PROC)QD3D12_SetPathTracingQuality }, { "QD3D12_SetPathTracingFallbackSamples", (PROC)QD3D12_SetPathTracingFallbackSamples }, { "glSetTopLevelAccelStructureVisible", (PROC)glSetTopLevelAccelStructureVisible }, @@ -12896,6 +12953,14 @@ void QD3D12_SetUpscalerBackend(int backend) break; } + // DLAA is not a generic native-quality mode; it is a DLSS mode. If the + // backend is changed away from DLSS, fall back to ordinary native rendering. + if (g_gl.upscalerBackend != QD3D12_UPSCALER_DLSS && + QD3D12_IsDLAAQuality(g_gl.upscalerQuality)) + { + g_gl.upscalerQuality = QD3D12_QUALITY_NATIVE; + } + g_gl.motionHistoryReset = true; QD3D12_ReconfigureCurrentWindowForUpscalerChange(); } @@ -12911,6 +12976,10 @@ void QD3D12_SetUpscalerQuality(int quality) case QD3D12_QUALITY_ULTRA_PERFORMANCE: g_gl.upscalerQuality = (QD3D12UpscalerQuality)quality; break; + case QD3D12_QUALITY_DLAA: + g_gl.upscalerBackend = QD3D12_UPSCALER_DLSS; + g_gl.upscalerQuality = QD3D12_QUALITY_DLAA; + break; default: g_gl.upscalerQuality = QD3D12_QUALITY_QUALITY; break; @@ -12920,6 +12989,47 @@ void QD3D12_SetUpscalerQuality(int quality) QD3D12_ReconfigureCurrentWindowForUpscalerChange(); } +void QD3D12_EnableDLAA(int enabled) +{ + const QD3D12UpscalerBackend oldBackend = g_gl.upscalerBackend; + const QD3D12UpscalerQuality oldQuality = g_gl.upscalerQuality; + + if (enabled) + { + // DLAA is DLSS-only. Force the DLSS backend so callers can enable it with + // one function call even if a previous menu selection left FSR or no + // upscaler active. + g_gl.upscalerBackend = QD3D12_UPSCALER_DLSS; + g_gl.upscalerQuality = QD3D12_QUALITY_DLAA; + } + else if (g_gl.upscalerQuality == QD3D12_QUALITY_DLAA) + { + g_gl.upscalerQuality = QD3D12_QUALITY_NATIVE; + } + + if (oldBackend != g_gl.upscalerBackend || oldQuality != g_gl.upscalerQuality) + { + g_gl.motionHistoryReset = true; + QD3D12_ReconfigureCurrentWindowForUpscalerChange(); + } +} + +int QD3D12_IsDLAAEnabled(void) +{ + return (g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS && + g_gl.upscalerQuality == QD3D12_QUALITY_DLAA) ? 1 : 0; +} + +void APIENTRY glDLAAQD3D12(GLboolean enable) +{ + QD3D12_EnableDLAA(enable != GL_FALSE ? 1 : 0); +} + +void APIENTRY glEnableDLAAQD3D12(GLboolean enable) +{ + glDLAAQD3D12(enable); +} + void QD3D12_SetUpscalerSharpness(float sharpness) { g_gl.upscalerSharpness = ClampValue(sharpness, 0.0f, 1.0f);