2024-12-12 17:41:33 +08:00

271 lines
7.7 KiB
C++

#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;
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;
};
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;
}
params.pPipelineLibrary = nullptr;
log_func("xessD3D12Init");
xess_result_t ret = xessD3D12Init(xess_context, &params);
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;
params.pDepthTexture = nullptr;
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, &params);
if (ret != XESS_RESULT_SUCCESS)
{
static bool s_Reported = false;
if (!s_Reported)
{
s_Reported = true;
log_func(ResultToString(ret));
}
}
}
bool XessV13::get_input_resolution(uint32_t outw, uint32_t outh, int quality,uint32_t& Width, uint32_t& Height)
{
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;
}
Width = inputRes.x;
Height = inputRes.y;
return true;
}