mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Fixed dlss issues.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user