diff options
author | Jens Peters <jp7677@gmail.com> | 2022-02-06 21:38:02 +0300 |
---|---|---|
committer | Jens Peters <jp7677@gmail.com> | 2022-02-06 21:38:02 +0300 |
commit | d1a1c5c6857ad626e9ba66706944eb10e228cd1b (patch) | |
tree | 38c513ce68369b13e96ce16f29991097a0455482 | |
parent | bef3c94f46fec7da2058e13ef35aef600359d827 (diff) |
nvapi-d3d: Handle different struct versions explicitely
This is somewhat verbose, but ensures that we don't accidentally mix fields from different struct versions. Add tests for different struct versions.
-rw-r--r-- | src/nvapi_d3d.cpp | 70 | ||||
-rw-r--r-- | tests/nvapi_d3d.cpp | 89 |
2 files changed, 98 insertions, 61 deletions
diff --git a/src/nvapi_d3d.cpp b/src/nvapi_d3d.cpp index 11b453c..3994b3d 100644 --- a/src/nvapi_d3d.cpp +++ b/src/nvapi_d3d.cpp @@ -35,19 +35,31 @@ extern "C" { if (pDevice == nullptr || pSliState == nullptr) return InvalidArgument(n); - if (pSliState->version != NV_GET_CURRENT_SLI_STATE_VER1 && pSliState->version != NV_GET_CURRENT_SLI_STATE_VER2) - return IncompatibleStructVersion(n); - - // Report that SLI is not available - pSliState->maxNumAFRGroups = 1; - pSliState->numAFRGroups = 1; - pSliState->currentAFRIndex = 0; - pSliState->nextFrameAFRIndex = 0; - pSliState->previousFrameAFRIndex = 0; - pSliState->bIsCurAFRGroupNew = false; - - if (pSliState->version == NV_GET_CURRENT_SLI_STATE_VER2) - pSliState->numVRSLIGpus = 0; + switch (pSliState->version) { + case NV_GET_CURRENT_SLI_STATE_VER1: { + auto pSliStateV1 = reinterpret_cast<NV_GET_CURRENT_SLI_STATE_V1*>(pSliState); + // Report that SLI is not available + pSliStateV1->maxNumAFRGroups = 1; + pSliStateV1->numAFRGroups = 1; + pSliStateV1->currentAFRIndex = 0; + pSliStateV1->nextFrameAFRIndex = 0; + pSliStateV1->previousFrameAFRIndex = 0; + pSliStateV1->bIsCurAFRGroupNew = false; + break; + } + case NV_GET_CURRENT_SLI_STATE_VER2: + // Report that SLI is not available + pSliState->maxNumAFRGroups = 1; + pSliState->numAFRGroups = 1; + pSliState->currentAFRIndex = 0; + pSliState->nextFrameAFRIndex = 0; + pSliState->previousFrameAFRIndex = 0; + pSliState->bIsCurAFRGroupNew = false; + pSliState->numVRSLIGpus = 0; + break; + default: + return IncompatibleStructVersion(n); + } return Ok(n, alreadyLoggedOk); } @@ -65,31 +77,27 @@ extern "C" { constexpr auto n = __func__; static bool alreadyLoggedOk = false; - switch(structVersion) { - case NV_D3D1x_GRAPHICS_CAPS_VER1: + switch (structVersion) { + case NV_D3D1x_GRAPHICS_CAPS_VER1: { memset(pGraphicsCaps, 0, sizeof(NV_D3D1x_GRAPHICS_CAPS_V1)); + auto pGraphicsCapsV1 = reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V1*>(pGraphicsCaps); + pGraphicsCapsV1->bExclusiveScissorRectsSupported = 0; + pGraphicsCapsV1->bVariablePixelRateShadingSupported = 0; break; + } case NV_D3D1x_GRAPHICS_CAPS_VER2: memset(pGraphicsCaps, 0, sizeof(NV_D3D1x_GRAPHICS_CAPS_V2)); - break; - default: - return IncompatibleStructVersion(n); - } - - switch(structVersion) { - case NV_D3D1x_GRAPHICS_CAPS_VER2: // bFastUAVClearSupported is reported mostly for the sake of DLSS. // All NVIDIA Vulkan drivers support this. - (*reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V2*>(pGraphicsCaps)).bFastUAVClearSupported = 1; + pGraphicsCaps->bFastUAVClearSupported = 1; // dummy SM version number (unused by DLSS): - (*reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V2*>(pGraphicsCaps)).majorSMVersion = 0; - (*reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V2*>(pGraphicsCaps)).minorSMVersion = 0; - - [[fallthrough]]; - - case NV_D3D1x_GRAPHICS_CAPS_VER1: - (*reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V1*>(pGraphicsCaps)).bExclusiveScissorRectsSupported = 0; - (*reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS_V1*>(pGraphicsCaps)).bVariablePixelRateShadingSupported = 0; + pGraphicsCaps->majorSMVersion = 0; + pGraphicsCaps->minorSMVersion = 0; + pGraphicsCaps->bExclusiveScissorRectsSupported = 0; + pGraphicsCaps->bVariablePixelRateShadingSupported = 0; + break; + default: + return IncompatibleStructVersion(n); } return Ok(n, alreadyLoggedOk); diff --git a/tests/nvapi_d3d.cpp b/tests/nvapi_d3d.cpp index 9d61c72..ce43863 100644 --- a/tests/nvapi_d3d.cpp +++ b/tests/nvapi_d3d.cpp @@ -25,42 +25,71 @@ TEST_CASE("D3D methods succeed", "[.d3d]") { REQUIRE(NvAPI_D3D_EndResourceRendering(&unknown, NVDX_ObjectHandle(), 0) == NVAPI_OK); } - SECTION("GetCurrentSLIState returns OK") { - NV_GET_CURRENT_SLI_STATE state; - state.version = NV_GET_CURRENT_SLI_STATE_VER2; - REQUIRE(NvAPI_D3D_GetCurrentSLIState(&unknown, &state) == NVAPI_OK); - REQUIRE(state.maxNumAFRGroups == 1); - REQUIRE(state.numAFRGroups == 1); - REQUIRE(state.currentAFRIndex == 0); - REQUIRE(state.nextFrameAFRIndex == 0); - REQUIRE(state.previousFrameAFRIndex == 0); - REQUIRE(state.bIsCurAFRGroupNew == false); - REQUIRE(state.numVRSLIGpus == 0); - } + SECTION("GetCurrentSLIState succeeds") { + SECTION("GetCurrentSLIState (V1) returns OK") { + NV_GET_CURRENT_SLI_STATE_V1 state; + state.version = NV_GET_CURRENT_SLI_STATE_VER1; + REQUIRE(NvAPI_D3D_GetCurrentSLIState(&unknown, reinterpret_cast<NV_GET_CURRENT_SLI_STATE*>(&state)) == + NVAPI_OK); + REQUIRE(state.maxNumAFRGroups == 1); + REQUIRE(state.numAFRGroups == 1); + REQUIRE(state.currentAFRIndex == 0); + REQUIRE(state.nextFrameAFRIndex == 0); + REQUIRE(state.previousFrameAFRIndex == 0); + REQUIRE(state.bIsCurAFRGroupNew == false); + } - SECTION("ImplicitSLIControl returns OK") { - REQUIRE(NvAPI_D3D_ImplicitSLIControl(DISABLE_IMPLICIT_SLI) == NVAPI_OK); - } + SECTION("GetCurrentSLIState (V2) returns OK") { + NV_GET_CURRENT_SLI_STATE_V2 state; + state.version = NV_GET_CURRENT_SLI_STATE_VER1; + REQUIRE(NvAPI_D3D_GetCurrentSLIState(&unknown, &state) == NVAPI_OK); + REQUIRE(state.maxNumAFRGroups == 1); + REQUIRE(state.numAFRGroups == 1); + REQUIRE(state.currentAFRIndex == 0); + REQUIRE(state.nextFrameAFRIndex == 0); + REQUIRE(state.previousFrameAFRIndex == 0); + REQUIRE(state.bIsCurAFRGroupNew == false); + REQUIRE(state.numVRSLIGpus == 0); + } - SECTION("ImplicitSLIControl returns error when enabling SLI") { - REQUIRE(NvAPI_D3D_ImplicitSLIControl(ENABLE_IMPLICIT_SLI) == NVAPI_ERROR); + SECTION("GetCurrentSLIState with future struct version returns incompatible-struct-version") { + NV_GET_CURRENT_SLI_STATE state; + state.version = NV_GET_CURRENT_SLI_STATE_VER2 + 1; + REQUIRE(NvAPI_D3D_GetCurrentSLIState(&unknown, &state) == NVAPI_INCOMPATIBLE_STRUCT_VERSION); + } } - SECTION("GetGraphicsCapabilities (V1) returns OK") { - NV_D3D1x_GRAPHICS_CAPS_V1 caps; - REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER1, reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS*>(&caps)) == NVAPI_OK); - // returned bExclusiveScissorRectsSupported/bVariablePixelRateShadingSupported values not enforced by testing - } + SECTION("ImplicitSLIControl succeeds") { + SECTION("ImplicitSLIControl returns OK") { + REQUIRE(NvAPI_D3D_ImplicitSLIControl(DISABLE_IMPLICIT_SLI) == NVAPI_OK); + } - SECTION("GetGraphicsCapabilities (V2) returns OK") { - NV_D3D1x_GRAPHICS_CAPS_V2 caps; - REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER2, reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS*>(&caps)) == NVAPI_OK); - REQUIRE(caps.bFastUAVClearSupported == 1); - // returned minorSMVersion/majorSMVersion not enforced by testing since current returns are dummy values anyway + SECTION("ImplicitSLIControl returns error when enabling SLI") { + REQUIRE(NvAPI_D3D_ImplicitSLIControl(ENABLE_IMPLICIT_SLI) == NVAPI_ERROR); + } } - SECTION("GetGraphicsCapabilities (FUTURE VERSION) returns IncompatibleStructVersion") { - NV_D3D1x_GRAPHICS_CAPS caps; - REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER+1, reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS*>(&caps)) == NVAPI_INCOMPATIBLE_STRUCT_VERSION); + SECTION("GetGraphicsCapabilities succeeds") { + SECTION("GetGraphicsCapabilities (V1) returns OK") { + NV_D3D1x_GRAPHICS_CAPS_V1 caps; + REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER1, reinterpret_cast<NV_D3D1x_GRAPHICS_CAPS*>(&caps)) == NVAPI_OK); + REQUIRE(caps.bExclusiveScissorRectsSupported == 0); + REQUIRE(caps.bVariablePixelRateShadingSupported == 0); + } + + SECTION("GetGraphicsCapabilities (V2) returns OK") { + NV_D3D1x_GRAPHICS_CAPS_V2 caps; + REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER2, &caps) == NVAPI_OK); + REQUIRE(caps.bFastUAVClearSupported == 1); + REQUIRE(caps.majorSMVersion == 0); + REQUIRE(caps.minorSMVersion == 0); + REQUIRE(caps.bExclusiveScissorRectsSupported == 0); + REQUIRE(caps.bVariablePixelRateShadingSupported == 0); + } + + SECTION("GetGraphicsCapabilities with future struct version returns incompatible-struct-version") { + NV_D3D1x_GRAPHICS_CAPS caps; + REQUIRE(NvAPI_D3D1x_GetGraphicsCapabilities(&unknown, NV_D3D1x_GRAPHICS_CAPS_VER2 + 1, &caps) == NVAPI_INCOMPATIBLE_STRUCT_VERSION); + } } } |