mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-05-14 05:30:52 +00:00
Add LFX to Vulkan
This commit is contained in:
@@ -327,8 +327,7 @@ namespace nvd {
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_D3D_GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams) {
|
||||
lowlatency_ctx.GetSleepStatus(pDevice, pGetSleepStatusParams);
|
||||
return OK();
|
||||
return lowlatency_ctx.GetSleepStatus(pDevice, pGetSleepStatusParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_D3D_GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
@@ -339,9 +338,7 @@ namespace nvd {
|
||||
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
|
||||
|
||||
// xellGetFramesReports() currently doesn't give any extra data that we can't already get
|
||||
lowlatency_ctx.get_latency_result(pGetLatencyParams);
|
||||
|
||||
return OK();
|
||||
return lowlatency_ctx.GetLatency(pDev, pGetLatencyParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_D3D_SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams) {
|
||||
@@ -546,37 +543,58 @@ namespace nvd {
|
||||
if (pSetAsyncFrameMarkerParams == nullptr)
|
||||
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
|
||||
|
||||
lowlatency_ctx.SetAsyncFrameMarker(pCommandQueue, pSetAsyncFrameMarkerParams);
|
||||
|
||||
return OK();
|
||||
return lowlatency_ctx.SetAsyncFrameMarker(pCommandQueue, pSetAsyncFrameMarkerParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_InitLowLatencyDevice(__in HANDLE vkDevice, __out HANDLE *signalSemaphoreHandle) {
|
||||
// It happens automatically on every reflex call
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_DestroyLowLatencyDevice(__in HANDLE vkDevice) {
|
||||
lowlatency_ctx.deinit_current_tech();
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_GetSleepStatus(__in HANDLE vkDevice, __inout NV_VULKAN_GET_SLEEP_STATUS_PARAMS *pGetSleepStatusParams) {
|
||||
return OK();
|
||||
return lowlatency_ctx.GetSleepStatus(vkDevice, pGetSleepStatusParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_SetSleepMode(__in HANDLE vkDevice, __in NV_VULKAN_SET_SLEEP_MODE_PARAMS *pSetSleepModeParams) {
|
||||
return OK();
|
||||
if (!Init())
|
||||
return ERROR();
|
||||
|
||||
return lowlatency_ctx.SetSleepMode(vkDevice, pSetSleepModeParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_Sleep(__in HANDLE vkDevice, __in NvU64 signalValue) {
|
||||
return OK();
|
||||
if (!Init())
|
||||
return ERROR();
|
||||
|
||||
if (!vkDevice)
|
||||
return ERROR();
|
||||
|
||||
return lowlatency_ctx.Sleep(vkDevice);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_GetLatency(__in HANDLE vkDevice, __inout NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
return OK();
|
||||
if (!Init())
|
||||
return ERROR();
|
||||
|
||||
if (pGetLatencyParams == nullptr)
|
||||
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
|
||||
|
||||
return lowlatency_ctx.GetLatency(vkDevice, pGetLatencyParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_SetLatencyMarker(__in HANDLE vkDevice, __in NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) {
|
||||
return OK();
|
||||
if (!Init())
|
||||
return ERROR();
|
||||
|
||||
if (!vkDevice)
|
||||
return ERROR();
|
||||
|
||||
return lowlatency_ctx.SetLatencyMarker(vkDevice, pSetLatencyMarkerParams);
|
||||
}
|
||||
|
||||
NvAPI_Status __cdecl NvAPI_Vulkan_NotifyOutOfBandVkQueue(__in HANDLE vkDevice, __in HANDLE queueHandle, __in NV_VULKAN_OUT_OF_BAND_QUEUE_TYPE queueType) {
|
||||
|
||||
@@ -63,6 +63,32 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowLatency::update_low_latency_tech(HANDLE vkDevice) {
|
||||
if (!currently_active_tech) {
|
||||
currently_active_tech = new LatencyFlex();
|
||||
if (currently_active_tech->init(nullptr)) {
|
||||
spdlog::debug("LowLatency algo: LatencyFlex");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool last_force_latencyflex = Config::get().get_force_latencyflex();
|
||||
bool force_latencyflex = Config::get().get_force_latencyflex();
|
||||
bool change_detected = last_force_latencyflex != force_latencyflex;
|
||||
last_force_latencyflex = force_latencyflex;
|
||||
|
||||
if (change_detected) {
|
||||
if (deinit_current_tech()) {
|
||||
return update_low_latency_tech((HANDLE) nullptr); // call back to reinit
|
||||
} else {
|
||||
spdlog::error("Couldn't deinitialize low latency tech");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LowLatency::update_effective_fg_state() {
|
||||
if (!currently_active_tech)
|
||||
return;
|
||||
@@ -123,12 +149,62 @@ void LowLatency::add_marker_to_report(NV_LATENCY_MARKER_PARAMS* pSetLatencyMarke
|
||||
}
|
||||
}
|
||||
|
||||
void LowLatency::add_marker_to_report(NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) {
|
||||
auto current_timestamp = get_timestamp() / 1000;
|
||||
static auto last_sim_start = current_timestamp;
|
||||
static auto _2nd_last_sim_start = current_timestamp;
|
||||
auto current_report = &frame_reports[pSetLatencyMarkerParams->frameID % 64];
|
||||
current_report->frameID = pSetLatencyMarkerParams->frameID;
|
||||
current_report->gpuFrameTimeUs = (uint32_t)(last_sim_start - _2nd_last_sim_start);
|
||||
current_report->gpuActiveRenderTimeUs = 100;
|
||||
current_report->driverStartTime = current_timestamp;
|
||||
current_report->driverEndTime = current_timestamp + 100;
|
||||
current_report->gpuRenderStartTime = current_timestamp;
|
||||
current_report->gpuRenderEndTime = current_timestamp + 100;
|
||||
current_report->osRenderQueueStartTime = current_timestamp;
|
||||
current_report->osRenderQueueEndTime = current_timestamp + 100;
|
||||
switch (pSetLatencyMarkerParams->markerType) {
|
||||
case VULKAN_SIMULATION_START:
|
||||
_2nd_last_sim_start = last_sim_start;
|
||||
last_sim_start = get_timestamp() / 1000;
|
||||
current_report->simStartTime = last_sim_start;
|
||||
break;
|
||||
case VULKAN_SIMULATION_END:
|
||||
current_report->simEndTime = get_timestamp() / 1000;
|
||||
break;
|
||||
case VULKAN_RENDERSUBMIT_START:
|
||||
current_report->renderSubmitStartTime = get_timestamp() / 1000;
|
||||
break;
|
||||
case VULKAN_RENDERSUBMIT_END:
|
||||
current_report->renderSubmitEndTime = get_timestamp() / 1000;
|
||||
break;
|
||||
case VULKAN_PRESENT_START:
|
||||
current_report->presentStartTime = get_timestamp() / 1000;
|
||||
break;
|
||||
case VULKAN_PRESENT_END:
|
||||
current_report->presentEndTime = get_timestamp() / 1000;
|
||||
break;
|
||||
case VULKAN_INPUT_SAMPLE:
|
||||
current_report->inputSampleTime = get_timestamp() / 1000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LowLatency::get_latency_result(NV_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
for (auto i = 0; i < 64; i++) {
|
||||
memcpy(&pGetLatencyParams->frameReport[i], &frame_reports[i], sizeof(frame_reports[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void LowLatency::get_latency_result(NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
for (auto i = 0; i < 64; i++) {
|
||||
// some data is sent into rsvd
|
||||
memcpy(&pGetLatencyParams->frameReport[i], &frame_reports[i], sizeof(frame_reports[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void LowLatency::get_low_latency_context(void** low_latency_context, Mode* low_latency_tech) {
|
||||
if (!currently_active_tech || !low_latency_context)
|
||||
return;
|
||||
@@ -137,6 +213,52 @@ void LowLatency::get_low_latency_context(void** low_latency_context, Mode* low_l
|
||||
*low_latency_tech = currently_active_tech->get_mode();
|
||||
}
|
||||
|
||||
std::string LowLatency::marker_to_name(uint32_t marker) {
|
||||
switch (marker) {
|
||||
case SIMULATION_START:
|
||||
return "SIMULATION_START";
|
||||
break;
|
||||
case SIMULATION_END:
|
||||
return "SIMULATION_END";
|
||||
break;
|
||||
case RENDERSUBMIT_START:
|
||||
return "RENDERSUBMIT_START";
|
||||
break;
|
||||
case RENDERSUBMIT_END:
|
||||
return "RENDERSUBMIT_END";
|
||||
break;
|
||||
case PRESENT_START:
|
||||
return "PRESENT_START";
|
||||
break;
|
||||
case PRESENT_END:
|
||||
return "PRESENT_END";
|
||||
break;
|
||||
case INPUT_SAMPLE:
|
||||
return "INPUT_SAMPLE";
|
||||
break;
|
||||
case TRIGGER_FLASH:
|
||||
return "TRIGGER_FLASH";
|
||||
break;
|
||||
case PC_LATENCY_PING:
|
||||
return "PC_LATENCY_PING";
|
||||
break;
|
||||
case OUT_OF_BAND_RENDERSUBMIT_START:
|
||||
return "OUT_OF_BAND_RENDERSUBMIT_START";
|
||||
break;
|
||||
case OUT_OF_BAND_RENDERSUBMIT_END:
|
||||
return "OUT_OF_BAND_RENDERSUBMIT_END";
|
||||
break;
|
||||
case OUT_OF_BAND_PRESENT_START:
|
||||
return "OUT_OF_BAND_PRESENT_START";
|
||||
break;
|
||||
case OUT_OF_BAND_PRESENT_END:
|
||||
return "OUT_OF_BAND_PRESENT_END";
|
||||
break;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::GetSleepStatus(IUnknown *pDevice, NV_GET_SLEEP_STATUS_PARAMS *pGetSleepStatusParams)
|
||||
{
|
||||
if (!update_low_latency_tech(pDevice))
|
||||
@@ -153,6 +275,20 @@ NvAPI_Status LowLatency::GetSleepStatus(IUnknown *pDevice, NV_GET_SLEEP_STATUS_P
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::GetSleepStatus(HANDLE vkDevice, NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams)
|
||||
{
|
||||
if (!update_low_latency_tech(vkDevice))
|
||||
return ERROR();
|
||||
|
||||
SleepParams sleep_params{};
|
||||
|
||||
currently_active_tech->get_sleep_status(&sleep_params);
|
||||
|
||||
pGetSleepStatusParams->bLowLatencyMode = sleep_params.low_latency_enabled;
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams) {
|
||||
if (!update_low_latency_tech(pDevice))
|
||||
return ERROR();
|
||||
@@ -169,6 +305,22 @@ NvAPI_Status LowLatency::SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAM
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams) {
|
||||
if (!update_low_latency_tech(vkDevice))
|
||||
return ERROR();
|
||||
|
||||
SleepMode sleep_mode{};
|
||||
|
||||
sleep_mode.low_latency_enabled = pSetSleepModeParams->bLowLatencyMode;
|
||||
sleep_mode.low_latency_boost = pSetSleepModeParams->bLowLatencyBoost;
|
||||
sleep_mode.minimum_interval_us = pSetSleepModeParams->minimumIntervalUs;
|
||||
sleep_mode.use_markers_to_optimize = true;
|
||||
|
||||
currently_active_tech->set_sleep_mode(&sleep_mode);
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::Sleep(IUnknown* pDevice) {
|
||||
if (!update_low_latency_tech(pDevice))
|
||||
return ERROR();
|
||||
@@ -178,6 +330,15 @@ NvAPI_Status LowLatency::Sleep(IUnknown* pDevice) {
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::Sleep(HANDLE vkDevice) {
|
||||
if (!update_low_latency_tech(vkDevice))
|
||||
return ERROR();
|
||||
|
||||
currently_active_tech->sleep();
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) {
|
||||
if (!update_low_latency_tech(pDev))
|
||||
return ERROR();
|
||||
@@ -195,7 +356,31 @@ NvAPI_Status LowLatency::SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARA
|
||||
|
||||
currently_active_tech->set_marker(&marker_params);
|
||||
|
||||
return OK();
|
||||
spdlog::trace("{}: {}", marker_to_name(pSetLatencyMarkerParams->markerType), pSetLatencyMarkerParams->frameID);
|
||||
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::SetLatencyMarker(HANDLE vkDevice, NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) {
|
||||
if (!update_low_latency_tech(vkDevice))
|
||||
return ERROR();
|
||||
|
||||
update_effective_fg_state();
|
||||
|
||||
update_enabled_override();
|
||||
|
||||
add_marker_to_report(pSetLatencyMarkerParams);
|
||||
|
||||
MarkerParams marker_params{};
|
||||
|
||||
marker_params.frame_id = pSetLatencyMarkerParams->frameID;
|
||||
marker_params.marker_type = (MarkerType) pSetLatencyMarkerParams->markerType; // requires enums to match
|
||||
|
||||
currently_active_tech->set_marker(&marker_params);
|
||||
|
||||
spdlog::trace("{}: {}", marker_to_name(pSetLatencyMarkerParams->markerType), pSetLatencyMarkerParams->frameID);
|
||||
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue, NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams) {
|
||||
@@ -233,4 +418,22 @@ NvAPI_Status LowLatency::SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue,
|
||||
currently_active_tech->set_async_marker(&marker_params);
|
||||
|
||||
return OK();
|
||||
}
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
if (!update_low_latency_tech(pDev))
|
||||
return ERROR();
|
||||
|
||||
get_latency_result(pGetLatencyParams);
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
NvAPI_Status LowLatency::GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams) {
|
||||
if (!update_low_latency_tech(vkDevice))
|
||||
return ERROR();
|
||||
|
||||
get_latency_result(pGetLatencyParams);
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,10 @@ private:
|
||||
bool update_low_latency_tech(IUnknown* pDevice);
|
||||
void update_effective_fg_state();
|
||||
void update_enabled_override();
|
||||
void get_latency_result(NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
|
||||
void add_marker_to_report(NV_LATENCY_MARKER_PARAMS *pSetLatencyMarkerParams);
|
||||
void add_marker_to_report(NV_VULKAN_LATENCY_MARKER_PARAMS *pSetLatencyMarkerParams);
|
||||
inline std::string marker_to_name(uint32_t marker);
|
||||
void update_config();
|
||||
|
||||
public:
|
||||
@@ -50,7 +53,6 @@ public:
|
||||
~LowLatency() { deinit_current_tech(); };
|
||||
|
||||
bool deinit_current_tech();
|
||||
void get_latency_result(NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
|
||||
void set_forced_fg(std::optional<bool> forced_fg) { this->forced_fg = forced_fg; };
|
||||
void set_fg_type(bool interpolated, uint64_t frame_id) { currently_active_tech->set_fg_type(interpolated, frame_id); }
|
||||
void get_low_latency_context(void** low_latency_context, Mode* low_latency_tech);
|
||||
@@ -58,7 +60,16 @@ public:
|
||||
NvAPI_Status GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
|
||||
NvAPI_Status SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
|
||||
NvAPI_Status Sleep(IUnknown* pDevice);
|
||||
NvAPI_Status SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
|
||||
NvAPI_Status SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue, NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams);
|
||||
NvAPI_Status SetLatencyMarker(IUnknown *pDev, NV_LATENCY_MARKER_PARAMS *pSetLatencyMarkerParams);
|
||||
NvAPI_Status SetAsyncFrameMarker(ID3D12CommandQueue *pCommandQueue, NV_ASYNC_FRAME_MARKER_PARAMS *pSetAsyncFrameMarkerParams);
|
||||
NvAPI_Status GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
|
||||
|
||||
// Vulkan
|
||||
bool update_low_latency_tech(HANDLE vkDevice);
|
||||
void get_latency_result(NV_VULKAN_LATENCY_RESULT_PARAMS *pGetLatencyParams);
|
||||
NvAPI_Status SetLatencyMarker(HANDLE vkDevice, NV_VULKAN_LATENCY_MARKER_PARAMS *pSetLatencyMarkerParams);
|
||||
NvAPI_Status Sleep(HANDLE vkDevice);
|
||||
NvAPI_Status SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
|
||||
NvAPI_Status GetSleepStatus(HANDLE vkDevice, NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
|
||||
NvAPI_Status GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams);
|
||||
};
|
||||
Reference in New Issue
Block a user