Fixed dlss issues.

This commit is contained in:
Justin Marshall
2026-05-21 08:19:03 -07:00
parent ce78a355f5
commit 2e4265f5a1
17 changed files with 97617 additions and 92471 deletions
+40703 -34673
View File
File diff suppressed because it is too large Load Diff
+42236 -42316
View File
File diff suppressed because it is too large Load Diff
+248 -240
View File
File diff suppressed because it is too large Load Diff
+13860 -15228
View File
File diff suppressed because it is too large Load Diff
+557 -11
View File
@@ -73,6 +73,8 @@ using Microsoft::WRL::ComPtr;
#include <sl_consts.h>
#include <sl_dlss.h>
#include <sl_dlss_d.h>
#include <sl_dlss_g.h>
#include <sl_reflex.h>
#endif
#if defined(QD3D12_ENABLE_FFX)
@@ -197,6 +199,9 @@ using Microsoft::WRL::ComPtr;
#ifndef GL_QD3D12_NEURAL_POM_BINDING
#define GL_QD3D12_NEURAL_POM_BINDING 0x600D
#endif
#ifndef GL_QD3D12_FRAME_GENERATION
#define GL_QD3D12_FRAME_GENERATION 0x600E
#endif
#ifndef GL_QD3D12_TAA
#define GL_QD3D12_TAA GL_QD3D12_TAA_ENABLED
#endif
@@ -327,6 +332,8 @@ void QD3D12_SetUpscalerQuality(int quality);
void QD3D12_SetUpscalerSharpness(float sharpness);
void QD3D12_SetToneMapBrightness(float brightness);
float QD3D12_GetToneMapBrightness(void);
void QD3D12_SetFrameGenerationMultiplier(int multiplier);
int QD3D12_GetFrameGenerationMultiplier(void);
void APIENTRY glToneMapBrightnessQD3D12(GLfloat brightness);
void APIENTRY glToneMapBrightnessfQD3D12(GLfloat brightness);
void APIENTRY glTonemapBrightnessQD3D12(GLfloat brightness);
@@ -1295,14 +1302,20 @@ struct GLState
std::unordered_map<GLuint, Mat4> prevObjectMVPs;
std::unordered_map<GLuint, Mat4> currObjectMVPs;
uint64_t frameSerial = 0;
#if defined(QD3D12_ENABLE_STREAMLINE)
sl::FrameToken* streamlineFrameToken = nullptr;
uint64_t streamlineFrameTokenSerial = UINT64_MAX;
uint64_t streamlineConstantsSerial = UINT64_MAX;
#endif
bool motionHistoryReset = true;
QD3D12UpscalerBackend upscalerBackend = QD3D12_UPSCALER_DLSS;
QD3D12UpscalerQuality upscalerQuality = QD3D12_QUALITY_DLAA;
QD3D12UpscalerQuality upscalerQuality = QD3D12_QUALITY_PERFORMANCE;
bool enableInternalTAA = true;
bool enableRayAIDenoise = false;
bool enableDLSSRayReconstruction = true;
bool enableFSRRayRegeneration = false;
uint32_t frameGenerationMultiplier = 2;
uint32_t pathTracingSamplesPerPixel = 1;
uint32_t pathTracingFallbackSamplesPerPixel = 2;
uint32_t pathTracingMaxBounces = 2;
@@ -6095,6 +6108,14 @@ struct QD3D12StreamlineState
bool deviceBound = false;
bool dlssSupported = false;
bool dlssRrSupported = false;
bool dlssGSupported = false;
bool dlssGFeatureLoaded = false;
bool reflexSupported = false;
bool dlssGActive = false;
uint32_t lastDlssGStatusLogged = 0;
uint32_t lastDlssGEligibilityMaskLogged = 0xffffffffu;
uint32_t lastDlssGFramesToGenerateLogged = 0xffffffffu;
uint32_t lastDlssGPresentedFramesLogged = 0xffffffffu;
sl::ViewportHandle viewport = { 1 };
};
static QD3D12StreamlineState g_qd3d12Sl;
@@ -6110,6 +6131,106 @@ struct QD3D12StreamlineInterposerState
};
static QD3D12StreamlineInterposerState g_qd3d12SlInterposer;
static bool QD3D12_GetExecutableDirectoryA(char* outPath, size_t outPathSize)
{
if (!outPath || outPathSize == 0)
return false;
DWORD len = GetModuleFileNameA(nullptr, outPath, (DWORD)outPathSize);
if (len == 0 || len >= outPathSize)
return false;
for (char* p = outPath + len; p > outPath; --p)
{
if (p[-1] == '\\' || p[-1] == '/')
{
p[-1] = '\0';
return true;
}
}
return false;
}
static bool QD3D12_GetExecutableDirectoryW(wchar_t* outPath, size_t outPathSize)
{
if (!outPath || outPathSize == 0)
return false;
DWORD len = GetModuleFileNameW(nullptr, outPath, (DWORD)outPathSize);
if (len == 0 || len >= outPathSize)
return false;
for (wchar_t* p = outPath + len; p > outPath; --p)
{
if (p[-1] == L'\\' || p[-1] == L'/')
{
p[-1] = L'\0';
return true;
}
}
return false;
}
static bool QD3D12_ExecutableDirectoryHasFile(const char* dir, const char* name)
{
if (!dir || !name)
return false;
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s\\%s", dir, name);
return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES;
}
static bool QD3D12_CheckStreamlineFrameGenerationRuntimeFiles()
{
char exeDir[MAX_PATH] = {};
if (!QD3D12_GetExecutableDirectoryA(exeDir, sizeof(exeDir)))
{
QD3D12_Log("DLSS_G runtime check failed: could not resolve executable directory.");
return false;
}
struct RequiredFile
{
const char* name;
bool requiredForFrameGeneration;
};
const RequiredFile files[] =
{
{ "sl.interposer.dll", true },
{ "sl.common.dll", true },
{ "sl.dlss.dll", true },
{ "sl.dlss_d.dll", true },
{ "sl.dlss_g.dll", true },
{ "sl.reflex.dll", true },
{ "sl.pcl.dll", false },
{ "nvngx_dlss.dll", true },
{ "nvngx_dlssd.dll", true },
{ "nvngx_dlssg.dll", true }
};
bool ok = true;
for (const RequiredFile& file : files)
{
const bool present = QD3D12_ExecutableDirectoryHasFile(exeDir, file.name);
if (!present && file.requiredForFrameGeneration)
{
QD3D12_Log("DLSS_G runtime missing %s beside the executable in %s.", file.name, exeDir);
ok = false;
}
}
if (!ok)
{
QD3D12_Log("DLSS_G cannot generate frames until the Streamline DLSS-G runtime DLLs are copied beside the game executable.");
}
return ok;
}
static void QD3D12_LoadStreamlineInterposer()
{
if (g_qd3d12SlInterposer.module)
@@ -6188,11 +6309,27 @@ static void QD3D12_InitStreamlineEarly()
pref.engine = sl::EngineType::eCustom;
pref.engineVersion = "IceBridge 1.0";
pref.flags |= sl::PreferenceFlags::eUseFrameBasedResourceTagging;
pref.flags |= sl::PreferenceFlags::eUseDXGIFactoryProxy;
pref.flags &= ~sl::PreferenceFlags::eAllowOTA;
pref.flags &= ~sl::PreferenceFlags::eLoadDownloadedPlugins;
static wchar_t pluginPath[MAX_PATH] = {};
static const wchar_t* pluginPaths[] = { pluginPath };
if (QD3D12_GetExecutableDirectoryW(pluginPath, _countof(pluginPath)))
{
pref.pathsToPlugins = pluginPaths;
pref.numPathsToPlugins = _countof(pluginPaths);
pref.pathToLogsAndData = pluginPath;
}
QD3D12_CheckStreamlineFrameGenerationRuntimeFiles();
sl::Feature features[] =
{
sl::kFeatureDLSS,
sl::kFeatureDLSS_RR
sl::kFeatureDLSS_RR,
sl::kFeatureDLSS_G,
sl::kFeatureReflex
};
pref.featuresToLoad = features;
@@ -6206,12 +6343,16 @@ static void QD3D12_InitStreamlineEarly()
}
g_qd3d12Sl.initialized = true;
g_qd3d12Sl.dlssGFeatureLoaded = true;
}
static void QD3D12_CheckStreamlineFeatureSupport()
{
g_qd3d12Sl.dlssSupported = false;
g_qd3d12Sl.dlssRrSupported = false;
g_qd3d12Sl.dlssGSupported = false;
g_qd3d12Sl.dlssGFeatureLoaded = false;
g_qd3d12Sl.reflexSupported = false;
if (!g_qd3d12Sl.initialized || !g_gl.device)
return;
@@ -6233,6 +6374,28 @@ static void QD3D12_CheckStreamlineFeatureSupport()
QD3D12_Log("slIsFeatureSupported(DLSS_RR) failed (%d); disabling Ray Reconstruction.", int(rrSupport));
g_gl.enableDLSSRayReconstruction = false;
}
const sl::Result fgSupport = slIsFeatureSupported(sl::kFeatureDLSS_G, adapterInfo);
g_qd3d12Sl.dlssGSupported = (fgSupport == sl::Result::eOk);
if (!g_qd3d12Sl.dlssGSupported)
{
QD3D12_Log("slIsFeatureSupported(DLSS_G) failed (%d); frame generation will stay off.", int(fgSupport));
}
bool dlssGLoaded = false;
const sl::Result fgLoadedResult = slIsFeatureLoaded(sl::kFeatureDLSS_G, dlssGLoaded);
g_qd3d12Sl.dlssGFeatureLoaded = (fgLoadedResult == sl::Result::eOk && dlssGLoaded);
if (!g_qd3d12Sl.dlssGFeatureLoaded)
{
QD3D12_Log("slIsFeatureLoaded(DLSS_G) failed or returned unloaded (result=%d loaded=%d).", int(fgLoadedResult), dlssGLoaded ? 1 : 0);
}
const sl::Result reflexSupport = slIsFeatureSupported(sl::kFeatureReflex, adapterInfo);
g_qd3d12Sl.reflexSupported = (reflexSupport == sl::Result::eOk);
if (!g_qd3d12Sl.reflexSupported)
{
QD3D12_Log("slIsFeatureSupported(Reflex) failed (%d); frame generation will stay off.", int(reflexSupport));
}
}
static void QD3D12_StreamlineOnDeviceCreated()
@@ -6276,6 +6439,9 @@ static bool QD3D12_UseLightingTextureAsUpscaleInput(const QD3D12Window& w)
static sl::Result QD3D12_SetStreamlineCommonConstants(sl::FrameToken& frameToken)
{
if (g_gl.streamlineConstantsSerial == g_gl.frameSerial)
return sl::Result::eOk;
sl::Constants consts{};
memcpy(&consts.cameraViewToClip, g_gl.cameraState.viewToClip.m, sizeof(float) * 16);
memcpy(&consts.clipToCameraView, g_gl.cameraState.clipToView.m, sizeof(float) * 16);
@@ -6283,6 +6449,7 @@ static sl::Result QD3D12_SetStreamlineCommonConstants(sl::FrameToken& frameToken
memcpy(&consts.prevClipToClip, g_gl.cameraState.prevClipToClip.m, sizeof(float) * 16);
consts.jitterOffset = { g_gl.jitterX, g_gl.jitterY };
consts.mvecScale = { 1.0f, 1.0f }; // motion vectors are written in PreviousUV - CurrentUV
consts.cameraPinholeOffset = { 0.0f, 0.0f };
memcpy(&consts.cameraPos, g_gl.cameraState.cameraPos, sizeof(float) * 3);
memcpy(&consts.cameraRight, g_gl.cameraState.cameraRight, sizeof(float) * 3);
memcpy(&consts.cameraUp, g_gl.cameraState.cameraUp, sizeof(float) * 3);
@@ -6297,7 +6464,295 @@ static sl::Result QD3D12_SetStreamlineCommonConstants(sl::FrameToken& frameToken
consts.motionVectors3D = sl::Boolean::eFalse;
consts.motionVectorsDilated = sl::Boolean::eFalse;
consts.motionVectorsJittered = sl::Boolean::eFalse;
return slSetConstants(consts, frameToken, g_qd3d12Sl.viewport);
const sl::Result result = slSetConstants(consts, frameToken, g_qd3d12Sl.viewport);
if (result == sl::Result::eOk)
g_gl.streamlineConstantsSerial = g_gl.frameSerial;
return result;
}
static sl::Result QD3D12_GetStreamlineFrameToken(sl::FrameToken*& frameToken)
{
if (g_gl.streamlineFrameToken &&
g_gl.streamlineFrameTokenSerial == g_gl.frameSerial)
{
frameToken = g_gl.streamlineFrameToken;
return sl::Result::eOk;
}
frameToken = nullptr;
uint32_t frameIndex = (uint32_t)g_gl.frameSerial;
const sl::Result result = slGetNewFrameToken(frameToken, &frameIndex);
if (result == sl::Result::eOk && frameToken)
{
g_gl.streamlineFrameToken = frameToken;
g_gl.streamlineFrameTokenSerial = g_gl.frameSerial;
g_gl.streamlineConstantsSerial = UINT64_MAX;
}
return result;
}
static bool QD3D12_WantsDLSSFrameGeneration(const QD3D12Window& w)
{
return
!w.isPbuffer &&
g_gl.cameraState.valid &&
g_qd3d12Sl.deviceBound &&
g_qd3d12Sl.dlssGSupported &&
g_qd3d12Sl.dlssGFeatureLoaded &&
g_qd3d12Sl.reflexSupported &&
g_gl.frameGenerationMultiplier >= 2 &&
w.backBuffers[w.frameIndex] &&
w.depthBuffer &&
w.velocityBuffers[w.frameIndex];
}
static uint32_t QD3D12_GetDLSSFrameGenerationEligibilityMask(const QD3D12Window& w)
{
uint32_t mask = 0;
if (w.isPbuffer)
mask |= 1u << 0;
if (!g_gl.cameraState.valid)
mask |= 1u << 1;
if (!g_qd3d12Sl.deviceBound)
mask |= 1u << 2;
if (!g_qd3d12Sl.dlssGSupported)
mask |= 1u << 3;
if (!g_qd3d12Sl.dlssGFeatureLoaded)
mask |= 1u << 4;
if (!g_qd3d12Sl.reflexSupported)
mask |= 1u << 5;
if (g_gl.frameGenerationMultiplier < 2)
mask |= 1u << 6;
if (!w.backBuffers[w.frameIndex] || !w.depthBuffer || !w.velocityBuffers[w.frameIndex])
mask |= 1u << 7;
return mask;
}
static void QD3D12_LogDLSSFrameGenerationEligibility(const QD3D12Window& w, uint32_t mask)
{
if (g_qd3d12Sl.lastDlssGEligibilityMaskLogged == mask)
return;
g_qd3d12Sl.lastDlssGEligibilityMaskLogged = mask;
if (mask == 0)
{
QD3D12_Log("DLSS_G eligible: requested %ux frame generation.", g_gl.frameGenerationMultiplier);
return;
}
QD3D12_Log(
"DLSS_G inactive: r_frameGen=%u, pbuffer=%d, camera=%d, deviceBound=%d, dlssG=%d, reflex=%d, resources=%d.",
g_gl.frameGenerationMultiplier,
w.isPbuffer ? 1 : 0,
g_gl.cameraState.valid ? 1 : 0,
g_qd3d12Sl.deviceBound ? 1 : 0,
(g_qd3d12Sl.dlssGSupported && g_qd3d12Sl.dlssGFeatureLoaded) ? 1 : 0,
g_qd3d12Sl.reflexSupported ? 1 : 0,
(w.backBuffers[w.frameIndex] && w.depthBuffer && w.velocityBuffers[w.frameIndex]) ? 1 : 0);
}
static void QD3D12_SetDLSSFrameGenerationOff()
{
if (!g_qd3d12Sl.deviceBound || !g_qd3d12Sl.dlssGSupported || !g_qd3d12Sl.dlssGActive)
return;
sl::DLSSGOptions options{};
options.mode = sl::DLSSGMode::eOff;
options.flags = sl::DLSSGFlags::eRetainResourcesWhenOff;
const sl::Result result = slDLSSGSetOptions(g_qd3d12Sl.viewport, options);
if (result != sl::Result::eOk)
QD3D12_Log("slDLSSGSetOptions(off) failed (%d).", int(result));
if (g_qd3d12Sl.reflexSupported)
{
sl::ReflexOptions reflexOptions{};
reflexOptions.mode = sl::ReflexMode::eOff;
slReflexSetOptions(reflexOptions);
}
g_qd3d12Sl.dlssGActive = false;
}
static void QD3D12_SetDLSSGFeatureLoaded(bool loaded)
{
if (!g_qd3d12Sl.initialized || g_qd3d12Sl.dlssGFeatureLoaded == loaded)
return;
const sl::Result result = slSetFeatureLoaded(sl::kFeatureDLSS_G, loaded);
if (result != sl::Result::eOk)
{
QD3D12_Log("slSetFeatureLoaded(DLSS_G, %d) failed (%d).", loaded ? 1 : 0, int(result));
return;
}
g_qd3d12Sl.dlssGFeatureLoaded = loaded;
QD3D12_Log("DLSS_G feature %s for swap-chain recreation.", loaded ? "loaded" : "unloaded");
}
static void QD3D12_TagDLSSFrameGenerationInputs(
QD3D12Window& w,
sl::FrameToken& frameToken,
const sl::Extent& renderExtent,
const sl::Extent& outputExtent)
{
ID3D12GraphicsCommandList* cl = g_gl.cmdList.Get();
if (!cl)
return;
sl::Resource hudless = { sl::ResourceType::eTex2d, w.backBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.backBufferState[w.frameIndex]) };
sl::Resource depth = { sl::ResourceType::eTex2d, w.depthBuffer.Get(), nullptr, nullptr, uint32_t(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) };
sl::Resource mvec = { sl::ResourceType::eTex2d, w.velocityBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) };
sl::ResourceTag tags[] =
{
sl::ResourceTag{ &hudless, sl::kBufferTypeHUDLessColor, sl::ResourceLifecycle::eValidUntilPresent, &outputExtent },
sl::ResourceTag{ &depth, sl::kBufferTypeDepth, sl::ResourceLifecycle::eValidUntilPresent, &renderExtent },
sl::ResourceTag{ &mvec, sl::kBufferTypeMotionVectors, sl::ResourceLifecycle::eValidUntilPresent, &renderExtent }
};
slSetTagForFrame(frameToken, g_qd3d12Sl.viewport, tags, _countof(tags), cl);
}
static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window& w, sl::FrameToken* existingFrameToken)
{
const uint32_t eligibilityMask = QD3D12_GetDLSSFrameGenerationEligibilityMask(w);
if (g_gl.frameGenerationMultiplier >= 2 && !w.isPbuffer)
QD3D12_LogDLSSFrameGenerationEligibility(w, eligibilityMask);
if (eligibilityMask != 0 || !QD3D12_WantsDLSSFrameGeneration(w))
{
QD3D12_SetDLSSFrameGenerationOff();
return;
}
sl::FrameToken* frameToken = existingFrameToken;
if (!frameToken)
{
const sl::Result frameResult = QD3D12_GetStreamlineFrameToken(frameToken);
if (frameResult != sl::Result::eOk || !frameToken)
{
QD3D12_Log("slGetNewFrameToken for DLSS_G failed (%d), disabling frame generation for this frame.", int(frameResult));
QD3D12_SetDLSSFrameGenerationOff();
return;
}
}
const sl::Result constResult = QD3D12_SetStreamlineCommonConstants(*frameToken);
if (constResult != sl::Result::eOk)
{
QD3D12_Log("slSetConstants for DLSS_G failed (%d), disabling frame generation for this frame.", int(constResult));
QD3D12_SetDLSSFrameGenerationOff();
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;
renderExtent.width = w.renderWidth;
renderExtent.height = w.renderHeight;
sl::Extent outputExtent{};
outputExtent.left = 0;
outputExtent.top = 0;
outputExtent.width = w.width;
outputExtent.height = w.height;
sl::DLSSGOptions options{};
options.mode = sl::DLSSGMode::eOn;
options.numFramesToGenerate = ClampValue<uint32_t>(g_gl.frameGenerationMultiplier - 1, 1, 3);
options.flags = sl::DLSSGFlags::eRetainResourcesWhenOff;
options.numBackBuffers = QD3D12_FrameCount;
options.mvecDepthWidth = w.renderWidth;
options.mvecDepthHeight = w.renderHeight;
options.colorWidth = w.width;
options.colorHeight = w.height;
options.colorBufferFormat = uint32_t(DXGI_FORMAT_R8G8B8A8_UNORM);
options.mvecBufferFormat = uint32_t(QD3D12_VelocityFormat);
options.depthBufferFormat = uint32_t(QD3D12_DepthSrvFormat);
options.hudLessBufferFormat = uint32_t(DXGI_FORMAT_R8G8B8A8_UNORM);
options.uiBufferFormat = uint32_t(DXGI_FORMAT_R8G8B8A8_UNORM);
sl::DLSSGState state{};
const sl::Result stateResult = slDLSSGGetState(g_qd3d12Sl.viewport, state, &options);
if (stateResult == sl::Result::eOk)
{
if (state.numFramesToGenerateMax > 0)
options.numFramesToGenerate = min(options.numFramesToGenerate, state.numFramesToGenerateMax);
if (state.status != sl::DLSSGStatus::eOk)
{
const uint32_t statusBits = uint32_t(state.status);
if (g_qd3d12Sl.lastDlssGStatusLogged != statusBits)
{
QD3D12_Log("DLSS_G reported status 0x%08x; leaving frame generation off for this frame.", statusBits);
g_qd3d12Sl.lastDlssGStatusLogged = statusBits;
}
QD3D12_SetDLSSFrameGenerationOff();
return;
}
g_qd3d12Sl.lastDlssGStatusLogged = 0;
}
else
{
QD3D12_Log("slDLSSGGetState failed (%d), trying DLSS_G set-options path anyway.", int(stateResult));
}
QD3D12_TagDLSSFrameGenerationInputs(w, *frameToken, renderExtent, outputExtent);
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;
}
if (!g_qd3d12Sl.dlssGActive || g_qd3d12Sl.lastDlssGFramesToGenerateLogged != options.numFramesToGenerate)
{
QD3D12_Log(
"DLSS_G active: requested %ux, generating %u frame(s) between rendered frames.",
g_gl.frameGenerationMultiplier,
options.numFramesToGenerate);
g_qd3d12Sl.lastDlssGFramesToGenerateLogged = options.numFramesToGenerate;
}
g_qd3d12Sl.dlssGActive = true;
}
static void QD3D12_LogDLSSFrameGenerationPresentResult()
{
if (!g_qd3d12Sl.deviceBound || !g_qd3d12Sl.dlssGSupported || !g_qd3d12Sl.dlssGActive)
return;
sl::DLSSGState state{};
const sl::Result stateResult = slDLSSGGetState(g_qd3d12Sl.viewport, state, nullptr);
if (stateResult != sl::Result::eOk)
return;
if (state.numFramesActuallyPresented != g_qd3d12Sl.lastDlssGPresentedFramesLogged)
{
QD3D12_Log(
"DLSS_G present: Streamline presented %u frame(s) since last check.",
state.numFramesActuallyPresented);
g_qd3d12Sl.lastDlssGPresentedFramesLogged = state.numFramesActuallyPresented;
}
}
#else
static HRESULT QD3D12_CreateDXGIFactory1ForStreamline(REFIID riid, void** ppFactory)
@@ -6315,6 +6770,8 @@ static void QD3D12_StreamlineOnDeviceCreated() {}
static bool QD3D12_WantsDLSSRayReconstruction() { return false; }
static bool QD3D12_CanUseDLSSRayReconstructionForLighting(const QD3D12Window&) { return false; }
static bool QD3D12_UseLightingTextureAsUpscaleInput(const QD3D12Window&) { return false; }
static void QD3D12_ConfigureDLSSFrameGeneration(QD3D12Window&, void*) {}
static void QD3D12_LogDLSSFrameGenerationPresentResult() {}
#endif
#if defined(QD3D12_ENABLE_FFX)
@@ -6948,8 +7405,7 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w)
if (haveTemporalCameraInputs && useLightingUpscaleInput && g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS && g_qd3d12Sl.deviceBound && w.slOutputBuffers[w.frameIndex])
{
sl::FrameToken* frameToken = nullptr;
uint32_t frameIndex = (uint32_t)g_gl.frameSerial;
const sl::Result frameResult = slGetNewFrameToken(frameToken, &frameIndex);
const sl::Result frameResult = QD3D12_GetStreamlineFrameToken(frameToken);
if (frameResult == sl::Result::eOk && frameToken)
{
sl::Extent renderExtent{};
@@ -7060,8 +7516,7 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w)
if (haveTemporalCameraInputs && g_gl.upscalerBackend == QD3D12_UPSCALER_DLSS && g_qd3d12Sl.deviceBound && w.slOutputBuffers[w.frameIndex])
{
sl::FrameToken* frameToken = nullptr;
uint32_t frameIndex = (uint32_t)g_gl.frameSerial;
const sl::Result frameResult = slGetNewFrameToken(frameToken, &frameIndex);
const sl::Result frameResult = QD3D12_GetStreamlineFrameToken(frameToken);
if (frameResult == sl::Result::eOk && frameToken)
{
sl::Extent renderExtent{};
@@ -7252,13 +7707,12 @@ static void QD3D12_CreateDevice()
QD3D12_CHECK(QD3D12_CreateDXGIFactory1ForStreamline(IID_PPV_ARGS(&g_gl.factory)));
QD3D12_CHECK(QD3D12_D3D12CreateDeviceForStreamline(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&g_gl.device)));
QD3D12_StreamlineOnDeviceCreated();
QD3D12_SelectGBufferSampleCount();
D3D12_COMMAND_QUEUE_DESC qd{};
qd.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
QD3D12_CHECK(g_gl.device->CreateCommandQueue(&qd, IID_PPV_ARGS(&g_gl.queue)));
QD3D12_StreamlineOnDeviceCreated();
}
static void QD3D12_CreateSwapChainForWindow(QD3D12Window& w)
@@ -7273,15 +7727,17 @@ static void QD3D12_CreateSwapChainForWindow(QD3D12Window& w)
sd.SampleDesc.Count = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
ComPtr<IDXGISwapChain1> sc1;
IDXGISwapChain1* rawSwapChain = nullptr;
QD3D12_CHECK(g_gl.factory->CreateSwapChainForHwnd(
g_gl.queue.Get(),
w.hwnd,
&sd,
nullptr,
nullptr,
&sc1));
&rawSwapChain));
ComPtr<IDXGISwapChain1> sc1;
sc1.Attach(rawSwapChain);
QD3D12_CHECK(sc1.As(&w.swapChain));
w.frameIndex = w.swapChain->GetCurrentBackBufferIndex();
}
@@ -8970,6 +9426,9 @@ void QD3D12_EndFrame()
QD3D12_ProcessCompletedTextureMipJobs(2);
QD3D12_TransitionResource(g_gl.cmdList.Get(), w.backBuffers[w.frameIndex].Get(), w.backBufferState[w.frameIndex], D3D12_RESOURCE_STATE_PRESENT);
#if defined(QD3D12_ENABLE_STREAMLINE)
QD3D12_ConfigureDLSSFrameGeneration(w, nullptr);
#endif
QD3D12_CHECK(g_gl.cmdList->Close());
ID3D12CommandList* lists[] = { g_gl.cmdList.Get() };
@@ -8993,7 +9452,12 @@ void QD3D12_Present()
QD3D12Window& w = *g_currentWindow;
if (w.swapChain)
{
QD3D12_CHECK(w.swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING));
#if defined(QD3D12_ENABLE_STREAMLINE)
QD3D12_LogDLSSFrameGenerationPresentResult();
#endif
}
FrameResources& fr = w.frames[w.frameIndex];
const UINT64 signalValue = g_gl.nextFenceValue++;
@@ -13298,6 +13762,66 @@ static void QD3D12_ReconfigureCurrentWindowForUpscalerChange()
QD3D12_UpdateViewportState();
}
static void QD3D12_RecreateCurrentWindowSwapChainForFrameGenerationChange(bool enableFrameGeneration)
{
if (!g_currentWindow || !g_currentWindow->swapChain || !g_gl.device)
return;
const UINT width = g_currentWindow->width;
const UINT height = g_currentWindow->height;
if (width == 0 || height == 0)
return;
if (g_gl.frameOpen || !g_gl.queuedBatches.empty())
QD3D12_SubmitOpenFrameNoPresentAndWait();
QD3D12_WaitForGPU();
g_gl.queuedBatches.clear();
#if defined(QD3D12_ENABLE_STREAMLINE)
if (!enableFrameGeneration)
QD3D12_SetDLSSFrameGenerationOff();
#endif
#if defined(QD3D12_ENABLE_FFX)
QD3D12_DestroyFfxUpscaleContext();
#endif
QD3D12_ReleaseWindowSizeResources(*g_currentWindow);
g_currentWindow->swapChain.Reset();
#if defined(QD3D12_ENABLE_STREAMLINE)
QD3D12_SetDLSSGFeatureLoaded(enableFrameGeneration);
#endif
QD3D12_CreateSwapChainForWindow(*g_currentWindow);
QD3D12_SelectRenderResolution(*g_currentWindow, width, height);
g_currentWindow->frameIndex = g_currentWindow->swapChain->GetCurrentBackBufferIndex();
g_gl.viewportW = (GLsizei)width;
g_gl.viewportH = (GLsizei)height;
g_gl.motionHistoryReset = true;
QD3D12_CreateRTVsForWindow(*g_currentWindow);
QD3D12_CreateDSVForWindow(*g_currentWindow);
g_psoCache.clear();
g_arbPsoCache.clear();
g_gl.framePhase = QD3D12_FRAME_LOW_RES;
g_gl.sceneResolvedThisFrame = false;
g_gl.gbufferResolvedThisFrame = false;
g_gl.raytracedLightingReadyThisFrame = false;
g_gl.sceneFogValidThisFrame = false;
#if defined(QD3D12_ENABLE_STREAMLINE)
g_gl.streamlineFrameToken = nullptr;
g_gl.streamlineFrameTokenSerial = UINT64_MAX;
g_gl.streamlineConstantsSerial = UINT64_MAX;
#endif
QD3D12_UpdateViewportState();
QD3D12_Log("DLSS_G swap-chain recreated with frame generation %s.", enableFrameGeneration ? "enabled" : "disabled");
}
GLenum APIENTRY glGetError(void) {
GLenum e = g_gl.lastError;
if (e != GL_NO_ERROR)
@@ -14745,6 +15269,8 @@ PROC WINAPI qd3d12_wglGetProcAddress(LPCSTR name) {
{ "QD3D12_SetUpscalerSharpness", (PROC)QD3D12_SetUpscalerSharpness },
{ "QD3D12_SetToneMapBrightness", (PROC)QD3D12_SetToneMapBrightness },
{ "QD3D12_GetToneMapBrightness", (PROC)QD3D12_GetToneMapBrightness },
{ "QD3D12_SetFrameGenerationMultiplier", (PROC)QD3D12_SetFrameGenerationMultiplier },
{ "QD3D12_GetFrameGenerationMultiplier", (PROC)QD3D12_GetFrameGenerationMultiplier },
{ "glToneMapBrightnessQD3D12", (PROC)glToneMapBrightnessQD3D12 },
{ "glToneMapBrightnessfQD3D12", (PROC)glToneMapBrightnessfQD3D12 },
{ "glTonemapBrightnessQD3D12", (PROC)glTonemapBrightnessQD3D12 },
@@ -15665,6 +16191,26 @@ void QD3D12_SetUpscalerQuality(int quality)
QD3D12_ReconfigureCurrentWindowForUpscalerChange();
}
void QD3D12_SetFrameGenerationMultiplier(int multiplier)
{
const uint32_t clamped = (uint32_t)ClampValue<int>(multiplier, 0, 4);
const bool wasEnabled = g_gl.frameGenerationMultiplier >= 2;
const bool willBeEnabled = clamped >= 2;
if (g_gl.frameGenerationMultiplier == clamped)
return;
g_gl.frameGenerationMultiplier = clamped;
g_gl.motionHistoryReset = true;
if (wasEnabled != willBeEnabled)
QD3D12_RecreateCurrentWindowSwapChainForFrameGenerationChange(willBeEnabled);
}
int QD3D12_GetFrameGenerationMultiplier(void)
{
return (int)g_gl.frameGenerationMultiplier;
}
void QD3D12_EnableDLAA(int enabled)
{
const QD3D12UpscalerBackend oldBackend = g_gl.upscalerBackend;
+3 -1
View File
@@ -2326,7 +2326,9 @@ void APIENTRY glShowAllTopLevelAccelStructures(
void QD3D12_SetUpscalerSharpness(float sharpness);
void QD3D12_SetToneMapBrightness(float brightness);
void QD3D12_SetFrameGenerationMultiplier(int multiplier);
int QD3D12_GetFrameGenerationMultiplier(void);
void QD3D12_EnableTAA(int enabled);
#include "opengl_nn.h"
#include "opengl_nn.h"
+6 -1
View File
@@ -281,6 +281,11 @@ static void R_CheckCvars( void ) {
R_SetColorMappings();
}
if ( r_frameGen.IsModified() ) {
r_frameGen.ClearModified();
QD3D12_SetFrameGenerationMultiplier( r_frameGen.GetInteger() );
}
// check for changes to logging state
// GLimp_EnableLogging( r_logFile.GetInteger() != 0 );
}
@@ -1050,4 +1055,4 @@ idRenderSystemLocal::LoadImage
*/
void idRenderSystemLocal::LoadImage(const char* cname, byte** pic, int* width, int* height, ID_TIME_T* timestamp, bool makePowerOf2) {
R_LoadImage(cname, pic, width, height, timestamp, makePowerOf2);
}
}
@@ -81,6 +81,7 @@ idCVar r_znear( "r_znear", "3", CVAR_RENDERER | CVAR_FLOAT, "near Z clip plane d
idCVar r_ignoreGLErrors( "r_ignoreGLErrors", "1", CVAR_RENDERER | CVAR_BOOL, "ignore GL errors" );
idCVar r_finish( "r_finish", "0", CVAR_RENDERER | CVAR_BOOL, "force a call to glFinish() every frame" );
idCVar r_swapInterval( "r_swapInterval", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "changes wglSwapIntarval" );
idCVar r_frameGen( "r_frameGen", "2", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "DLSS frame generation multiplier: 0/1 = off, 2 = 2x, 3 = 3x, 4 = 4x", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> );
idCVar r_gamma( "r_gamma", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 3.0f );
idCVar r_brightness( "r_brightnesspt", "1.5", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 2.0f );
+2 -1
View File
@@ -159,6 +159,7 @@ void RB_DXDrawInteractions(void)
bool hasLight = false;
QD3D12_SetToneMapBrightness(r_brightness.GetFloat());
QD3D12_SetFrameGenerationMultiplier(r_frameGen.GetInteger());
for (vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next)
{
@@ -228,4 +229,4 @@ void RB_DXDrawInteractions(void)
glFinish();
glLightScene(backEnd.viewDef->renderWorld->dxrWorldId);
glRaytracingLightingClearLights(false);
}
}
+1
View File
@@ -829,6 +829,7 @@ extern idCVar r_znear; // near Z clip plane
extern idCVar r_finish; // force a call to glFinish() every frame
extern idCVar r_frontBuffer; // draw to front buffer for debugging
extern idCVar r_swapInterval; // changes wglSwapIntarval
extern idCVar r_frameGen; // DLSS frame generation multiplier
extern idCVar r_offsetFactor; // polygon offset parameter
extern idCVar r_offsetUnits; // polygon offset parameter
extern idCVar r_singleTriangle; // only draw a single triangle per primitive
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.