Skip to content

Commit

Permalink
nvapi-d3d: Drop repeated frame IDs
Browse files Browse the repository at this point in the history
Frame IDs must be monotonic per marker type and
device/command queue.
  • Loading branch information
jp7677 committed Jan 20, 2025
1 parent 8bdf43e commit a112a9b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/nvapi/nvapi_d3d_low_latency_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ namespace dxvk {
if (d3dLowLatencyDevice == nullptr)
return false;

if (IsRepeatedFrame(device, frameID, markerType))
return true;

return SUCCEEDED(d3dLowLatencyDevice->SetLatencyMarker(
GetFrameIdGenerator(d3dLowLatencyDevice.ptr())->GetLowLatencyDeviceFrameId(frameID), markerType));
}
Expand All @@ -108,6 +111,9 @@ namespace dxvk {
if (d3dLowLatencyDevice == nullptr)
return false;

if (IsRepeatedFrame(commandQueue, frameID, markerType))
return true;

return SUCCEEDED(d3dLowLatencyDevice->SetLatencyMarker(
GetFrameIdGenerator(d3dLowLatencyDevice.ptr())->GetLowLatencyDeviceFrameId(frameID), markerType));
}
Expand Down Expand Up @@ -151,11 +157,22 @@ namespace dxvk {
return {};
}

bool NvapiD3dLowLatencyDevice::IsRepeatedFrame(IUnknown* commandQueue, uint64_t frameID, uint32_t markerType) {
auto key = std::make_pair(commandQueue, markerType);
if (m_lastFrameIdMap.contains(key) && m_lastFrameIdMap[key] == frameID) {
return true;
}

m_lastFrameIdMap[key] = frameID;
return false;
}

void NvapiD3dLowLatencyDevice::ClearCacheMaps() {
std::scoped_lock lock(m_lowLatencyDeviceMutex, m_lowLatencyFrameIdGeneratorMutex);

m_lowLatencyDeviceMap.clear();
m_frameIdGeneratorMap.clear();
m_lastFrameIdMap.clear();
}

Com<ID3DLowLatencyDevice> NvapiD3dLowLatencyDevice::GetLowLatencyDevice(IUnknown* device) {
Expand Down
2 changes: 2 additions & 0 deletions src/nvapi/nvapi_d3d_low_latency_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ namespace dxvk {
private:
inline static std::unordered_map<IUnknown*, ID3DLowLatencyDevice*> m_lowLatencyDeviceMap;
inline static std::unordered_map<ID3DLowLatencyDevice*, std::unique_ptr<LowLatencyFrameIdGenerator>> m_frameIdGeneratorMap;
inline static std::map<std::pair<IUnknown*, uint64_t>, uint64_t> m_lastFrameIdMap;

inline static std::mutex m_lowLatencyDeviceMutex;
inline static std::mutex m_lowLatencyFrameIdGeneratorMutex;

[[nodiscard]] static Com<ID3DLowLatencyDevice> GetLowLatencyDevice(IUnknown* device);
[[nodiscard]] static Com<ID3DLowLatencyDevice> GetLowLatencyDevice(ID3D12CommandQueue* commandQueue);
[[nodiscard]] static LowLatencyFrameIdGenerator* GetFrameIdGenerator(ID3DLowLatencyDevice* device);
[[nodiscard]] static bool IsRepeatedFrame(IUnknown* commandQueue, uint64_t frameID, uint32_t markerType);
};
}
18 changes: 18 additions & 0 deletions tests/nvapi_d3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,24 @@ TEST_CASE("D3D Reflex/LatencyFleX depending methods succeed", "[.d3d]") {
REQUIRE(NvAPI_D3D_SetLatencyMarker(&unknown, &latencyMarkerParams) == NVAPI_OK);
}

SECTION("SetLatencyMarker drops repeated frame IDs and returns OK") {
uint64_t lowLatencyDeviceFrameId = 163ULL;
REQUIRE_CALL(lowLatencyDevice, SetLatencyMarker(lowLatencyDeviceFrameId, PRESENT_START))
.TIMES(1)
.RETURN(S_OK);

SetupResourceFactory(std::move(dxgiFactory), std::move(vk), std::move(nvml), std::move(lfx));
REQUIRE(NvAPI_Initialize() == NVAPI_OK);

NV_LATENCY_MARKER_PARAMS latencyMarkerParams{};
latencyMarkerParams.version = NV_LATENCY_MARKER_PARAMS_VER1;
latencyMarkerParams.frameID = lowLatencyDeviceFrameId;
latencyMarkerParams.markerType = PRESENT_START;
REQUIRE(NvAPI_D3D_SetLatencyMarker(&unknown, &latencyMarkerParams) == NVAPI_OK);
REQUIRE(NvAPI_D3D_SetLatencyMarker(&unknown, &latencyMarkerParams) == NVAPI_OK);
REQUIRE(NvAPI_D3D_SetLatencyMarker(&unknown, &latencyMarkerParams) == NVAPI_OK);
}

SECTION("SetLatencyMarker correctly produces monotonic frame ids for a sequence of unique application frame ids") {
REQUIRE_CALL(lowLatencyDevice, SetLatencySleepMode(true, false, 750U))
.RETURN(S_OK);
Expand Down

0 comments on commit a112a9b

Please sign in to comment.