2024-12-12 17:41:33 +08:00
|
|
|
#include "xess1/xess.h"
|
|
|
|
|
|
|
|
|
|
#include "xess/xess_d3d12_debug.h"
|
|
|
|
|
|
|
|
|
|
static std::function<void(const char*)>log_func = {};
|
|
|
|
|
|
|
|
|
|
const char *ResultToString(xess_result_t result)
|
|
|
|
|
{
|
|
|
|
|
switch (result)
|
|
|
|
|
{
|
|
|
|
|
case XESS_RESULT_WARNING_NONEXISTING_FOLDER:
|
|
|
|
|
return "Warning Nonexistent Folder";
|
|
|
|
|
case XESS_RESULT_WARNING_OLD_DRIVER:
|
|
|
|
|
return "Warning Old Driver";
|
|
|
|
|
case XESS_RESULT_SUCCESS:
|
|
|
|
|
return "Success";
|
|
|
|
|
case XESS_RESULT_ERROR_UNSUPPORTED_DEVICE:
|
|
|
|
|
return "Unsupported Device";
|
|
|
|
|
case XESS_RESULT_ERROR_UNSUPPORTED_DRIVER:
|
|
|
|
|
return "Unsupported Driver";
|
|
|
|
|
case XESS_RESULT_ERROR_UNINITIALIZED:
|
|
|
|
|
return "Uninitialized";
|
|
|
|
|
case XESS_RESULT_ERROR_INVALID_ARGUMENT:
|
|
|
|
|
return "Invalid Argument";
|
|
|
|
|
case XESS_RESULT_ERROR_DEVICE_OUT_OF_MEMORY:
|
|
|
|
|
return "Device Out of Memory";
|
|
|
|
|
case XESS_RESULT_ERROR_DEVICE:
|
|
|
|
|
return "Device Error";
|
|
|
|
|
case XESS_RESULT_ERROR_NOT_IMPLEMENTED:
|
|
|
|
|
return "Not Implemented";
|
|
|
|
|
case XESS_RESULT_ERROR_INVALID_CONTEXT:
|
|
|
|
|
return "Invalid Context";
|
|
|
|
|
case XESS_RESULT_ERROR_OPERATION_IN_PROGRESS:
|
|
|
|
|
return "Operation in Progress";
|
|
|
|
|
case XESS_RESULT_ERROR_UNSUPPORTED:
|
|
|
|
|
return "Unsupported";
|
|
|
|
|
case XESS_RESULT_ERROR_CANT_LOAD_LIBRARY:
|
|
|
|
|
return "Cannot Load Library";
|
|
|
|
|
case XESS_RESULT_ERROR_UNKNOWN:
|
|
|
|
|
default:
|
|
|
|
|
return "Unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void LogCallback(const char* msg, xess_logging_level_t level)
|
|
|
|
|
{
|
|
|
|
|
if (level >= xess_logging_level_t::XESS_LOGGING_LEVEL_WARNING)
|
|
|
|
|
{
|
|
|
|
|
log_func(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool XessV13::enable(std::function<void(const char*)> log_cb)
|
|
|
|
|
{
|
|
|
|
|
if (inited)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
log_func = log_cb;
|
|
|
|
|
xess_version_t ver;
|
|
|
|
|
xess_result_t ret = xessGetVersion(&ver);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char buf[128];
|
|
|
|
|
sprintf_s(buf, "XeSS: Version -%u.%u.%u", ver.major, ver.minor, ver.patch);
|
|
|
|
|
log_func(buf);
|
|
|
|
|
ret = xessD3D12CreateContext(device, &xess_context);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS || !xess_context)
|
|
|
|
|
{
|
|
|
|
|
xess_context = nullptr;
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (XESS_RESULT_WARNING_OLD_DRIVER == xessIsOptimalDriver(xess_context))
|
|
|
|
|
{
|
|
|
|
|
log_func("Important notice: Please install the latest graphics driver from your vendor for optimal Intel(R) XeSS performance and visual quality.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = xessSetLoggingCallback(xess_context, XESS_LOGGING_LEVEL_DEBUG, LogCallback);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
log_func("xessD3D12CreateContext done");
|
|
|
|
|
xessForceLegacyScaleFactors(xess_context, false);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XessV13::disable()
|
|
|
|
|
{
|
|
|
|
|
if (!inited)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xessDestroyContext(xess_context);
|
|
|
|
|
log_func("xessDestroyContext done");
|
|
|
|
|
xess_context = nullptr;
|
|
|
|
|
inited = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct Xess1ConfigParam
|
|
|
|
|
{
|
|
|
|
|
uint32_t OutputWidth;
|
|
|
|
|
/// Output buffer height.
|
|
|
|
|
uint32_t OutputHeight;
|
|
|
|
|
/// Quality level of XeSS.
|
|
|
|
|
int Quality;
|
|
|
|
|
/// If we are in High-Res motion vectors mode.
|
|
|
|
|
bool UseHiResMotionVectors;
|
|
|
|
|
/// If motion vectors are jittered.
|
|
|
|
|
bool UseJitteredMotionVectors;
|
|
|
|
|
/// If motion vectors are in Normalized Device Coordinate (NDC).
|
|
|
|
|
bool UseMotionVectorsInNDC;
|
|
|
|
|
/// If use exposure texture.
|
|
|
|
|
bool UseExposureTexture;
|
|
|
|
|
/// If use responsive mask.
|
|
|
|
|
bool UseResponsiveMask;
|
|
|
|
|
/// If use auto exposure.
|
|
|
|
|
bool UseAutoExposure;
|
|
|
|
|
/// If enable GPU profiling.
|
|
|
|
|
bool EnableProfiling;
|
|
|
|
|
|
2024-12-12 20:32:36 +08:00
|
|
|
bool InvertedDepth;
|
|
|
|
|
|
2024-12-12 17:41:33 +08:00
|
|
|
float VelocityScaleX;
|
|
|
|
|
float VelocityScaleY;
|
|
|
|
|
|
|
|
|
|
float JitterScaleX;
|
|
|
|
|
float JitterScaleY;
|
|
|
|
|
|
|
|
|
|
float ExposureScale;
|
|
|
|
|
};
|
|
|
|
|
struct Xess1ExecParam
|
|
|
|
|
{
|
|
|
|
|
float Jitterx;
|
|
|
|
|
float Jittery;
|
|
|
|
|
int InputWidth;
|
|
|
|
|
int InputHeight;
|
|
|
|
|
bool ResetHistory;
|
|
|
|
|
float ExposureScale;
|
|
|
|
|
void* ColorTexture;
|
|
|
|
|
void* VelocityTexture;
|
|
|
|
|
void* OutputTexture;
|
2024-12-12 20:32:36 +08:00
|
|
|
void* DepthTexture;
|
2024-12-12 17:41:33 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool XessV13::configxess(void* data)
|
|
|
|
|
{
|
|
|
|
|
xess_d3d12_init_params_t params{};
|
|
|
|
|
Xess1ConfigParam* config = (Xess1ConfigParam*)data;
|
|
|
|
|
|
|
|
|
|
params.outputResolution.x = config->OutputWidth;
|
|
|
|
|
params.outputResolution.y = config->OutputHeight;
|
|
|
|
|
params.qualitySetting = (xess_quality_settings_t)config->Quality;
|
|
|
|
|
|
|
|
|
|
params.initFlags = config->UseHiResMotionVectors ? XESS_INIT_FLAG_HIGH_RES_MV : 0;
|
|
|
|
|
if (config->UseJitteredMotionVectors)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_JITTERED_MV;
|
|
|
|
|
}
|
|
|
|
|
if (config->UseMotionVectorsInNDC)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_USE_NDC_VELOCITY;
|
|
|
|
|
}
|
|
|
|
|
if (config->UseExposureTexture)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE;
|
|
|
|
|
}
|
|
|
|
|
if (config->UseResponsiveMask)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK;
|
|
|
|
|
}
|
|
|
|
|
if (config->UseAutoExposure)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE;
|
|
|
|
|
}
|
|
|
|
|
if (config->EnableProfiling)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_D3D12_DEBUG_ENABLE_PROFILING;
|
|
|
|
|
}
|
2024-12-12 20:32:36 +08:00
|
|
|
if (config->InvertedDepth)
|
|
|
|
|
{
|
|
|
|
|
params.initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH;
|
|
|
|
|
}
|
2024-12-12 17:41:33 +08:00
|
|
|
|
|
|
|
|
params.pPipelineLibrary = nullptr;
|
|
|
|
|
|
|
|
|
|
log_func("xessD3D12Init");
|
|
|
|
|
xess_result_t ret = xessD3D12Init(xess_context, ¶ms);
|
|
|
|
|
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
log_func("xessD3D12Init done");
|
|
|
|
|
ret = xessSetVelocityScale(xess_context, config->VelocityScaleX, config->VelocityScaleY);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = xessSetJitterScale(xess_context, config->JitterScaleX, config->JitterScaleY);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = xessSetExposureMultiplier(xess_context, config->ExposureScale);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inited = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XessV13::execute(void* data, ID3D12GraphicsCommandList* cmd_list)
|
|
|
|
|
{
|
|
|
|
|
Xess1ExecParam* param = (Xess1ExecParam*)data;
|
|
|
|
|
xess_d3d12_execute_params_t params{};
|
|
|
|
|
|
|
|
|
|
params.jitterOffsetX = param->Jitterx;
|
|
|
|
|
params.jitterOffsetY = param->Jittery;
|
|
|
|
|
params.inputWidth = param->InputWidth;
|
|
|
|
|
params.inputHeight = param->InputHeight;
|
|
|
|
|
params.ResetHistory = param->ResetHistory ? 1 : 0;
|
|
|
|
|
params.ExposureScale = param->ExposureScale;
|
|
|
|
|
params.pColorTexture = (ID3D12Resource*)param->ColorTexture;
|
|
|
|
|
params.pVelocityTexture = (ID3D12Resource*)param->VelocityTexture;
|
|
|
|
|
params.pOutputTexture = (ID3D12Resource*)param->OutputTexture;
|
2024-12-12 20:32:36 +08:00
|
|
|
params.pDepthTexture = (ID3D12Resource*)param->DepthTexture;
|
2024-12-12 17:41:33 +08:00
|
|
|
params.pExposureScaleTexture = nullptr;
|
|
|
|
|
params.pResponsivePixelMaskTexture = nullptr;
|
|
|
|
|
|
|
|
|
|
//params.pDepthTexture = m_InitArguments.UseHiResMotionVectors ? nullptr : Execonfig->DepthTexture->GetResource();
|
|
|
|
|
//params.pExposureScaleTexture = !m_InitArguments.UseExposureTexture ? nullptr : Execonfig->ExposureTexture->GetResource();
|
|
|
|
|
//params.pResponsivePixelMaskTexture = !m_InitArguments.UseResponsiveMask ? nullptr : Execonfig->ResponsiveMask->GetResource();
|
|
|
|
|
xess_result_t ret = xessD3D12Execute(xess_context, cmd_list, ¶ms);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
static bool s_Reported = false;
|
|
|
|
|
if (!s_Reported)
|
|
|
|
|
{
|
|
|
|
|
s_Reported = true;
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-16 20:33:34 +08:00
|
|
|
bool XessV13::get_input_resolution(uint32_t outw, uint32_t outh, int quality,uint32_t& width, uint32_t& height)
|
2024-12-12 17:41:33 +08:00
|
|
|
{
|
|
|
|
|
xess_2d_t inputRes = { 1, 1 };
|
|
|
|
|
xess_2d_t outputRes = { outw, outh };
|
|
|
|
|
|
|
|
|
|
xess_result_t ret = xessGetInputResolution(xess_context, &outputRes, (xess_quality_settings_t) quality, &inputRes);
|
|
|
|
|
if (ret != XESS_RESULT_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
log_func(ResultToString(ret));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-16 20:33:34 +08:00
|
|
|
width = inputRes.x;
|
|
|
|
|
height = inputRes.y;
|
2024-12-12 17:41:33 +08:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|