Skip to content

Commit

Permalink
nvapi-d3d11: Fix struct version handling
Browse files Browse the repository at this point in the history
  • Loading branch information
jp7677 committed Aug 28, 2024
1 parent 3a4a4cd commit be0c8c6
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 27 deletions.
29 changes: 15 additions & 14 deletions src/nvapi_d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,26 @@ extern "C" {
if (pMultiGPUCaps == nullptr)
return InvalidArgument(n);

switch (pMultiGPUCaps->version) {
case 0: // NV_MULTIGPU_CAPS_V1 has no version field
case NV_MULTIGPU_CAPS_VER1: {
auto version = pMultiGPUCaps->version;
switch (version) { // NOLINT(*-multiway-paths-covered)
case NV_MULTIGPU_CAPS_VER2:
*pMultiGPUCaps = {};
pMultiGPUCaps->version = version;
pMultiGPUCaps->multiGPUVersion = 3; // Observed on Windows
pMultiGPUCaps->nTotalGPUs = nvapiAdapterRegistry->GetAdapterCount();
// Report on purpose that no SLI GPUs are available by
// keeping pMultiGPUCaps->nSLIGPUs at zero
break;
default: {
// NV_MULTIGPU_CAPS_V1 has no version field
auto pMultiGPUCapsV1 = reinterpret_cast<NV_MULTIGPU_CAPS_V1*>(pMultiGPUCaps);
*pMultiGPUCapsV1 = {};
// Report that SLI is not available
pMultiGPUCapsV1->reserved = version; // This is a union field with version in V2
pMultiGPUCapsV1->multiGPUVersion = 3; // Observed on Windows
pMultiGPUCapsV1->nTotalGPUs = nvapiAdapterRegistry->GetAdapterCount();
pMultiGPUCapsV1->nSLIGPUs = 0;
break;
}
case NV_MULTIGPU_CAPS_VER2: {
*pMultiGPUCaps = {};
// Report that SLI is not available
pMultiGPUCaps->nTotalGPUs = nvapiAdapterRegistry->GetAdapterCount();
pMultiGPUCaps->nSLIGPUs = 0;
// See above about reporting no SLI
break;
}
default:
return IncompatibleStructVersion(n, pMultiGPUCaps->version);
}

return Ok(n);
Expand Down
15 changes: 2 additions & 13 deletions tests/nvapi_d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ TEST_CASE("D3D11 MultiGPU methods succeed", "[.d3d11]") {
NV_MULTIGPU_CAPS_V1 multiGPUCaps{};

REQUIRE(NvAPI_D3D11_MultiGPU_GetCaps(reinterpret_cast<PNV_MULTIGPU_CAPS>(&multiGPUCaps)) == NVAPI_OK);
REQUIRE(multiGPUCaps.multiGPUVersion == 3);
REQUIRE(multiGPUCaps.nTotalGPUs == 1);
REQUIRE(multiGPUCaps.nSLIGPUs == 0);
}
Expand All @@ -462,23 +463,11 @@ TEST_CASE("D3D11 MultiGPU methods succeed", "[.d3d11]") {
multiGPUCaps.version = NV_MULTIGPU_CAPS_VER2;

REQUIRE(NvAPI_D3D11_MultiGPU_GetCaps(&multiGPUCaps) == NVAPI_OK);
REQUIRE(multiGPUCaps.multiGPUVersion == 3);
REQUIRE(multiGPUCaps.nTotalGPUs == 1);
REQUIRE(multiGPUCaps.nSLIGPUs == 0);
}

SECTION("MultiGPU_GetCaps with unknown struct version returns incompatible-struct-version") {
NV_MULTIGPU_CAPS multiGPUCaps{};
multiGPUCaps.version = NV_MULTIGPU_CAPS_VER2 + 1;
REQUIRE(NvAPI_D3D11_MultiGPU_GetCaps(&multiGPUCaps) == NVAPI_INCOMPATIBLE_STRUCT_VERSION);
}

SECTION("MultiGPU_GetCaps with current struct version returns not incompatible-struct-version") {
// This test fails when a header update provides a newer not yet implemented struct version
NV_MULTIGPU_CAPS multiGPUCaps{};
multiGPUCaps.version = NV_MULTIGPU_CAPS_VER;
REQUIRE(NvAPI_D3D11_MultiGPU_GetCaps(&multiGPUCaps) != NVAPI_INCOMPATIBLE_STRUCT_VERSION);
}

SECTION("MultiGPU_Init returns OK") {
REQUIRE(NvAPI_D3D11_MultiGPU_Init(true) == NVAPI_OK);
}
Expand Down

0 comments on commit be0c8c6

Please sign in to comment.