Repository navigation
fix(windows): stop DXGI enumeration on any failure #5893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -503,7 +503,8 @@ namespace platf::dxgi { | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| adapter_t::pointer adapter_p; | ||||||||||||||||||||||||||||||||||
| for (int tries = 0; tries < 2; ++tries) { | ||||||||||||||||||||||||||||||||||
| for (int x = 0; factory->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) { | ||||||||||||||||||||||||||||||||||
| int x = 0; | ||||||||||||||||||||||||||||||||||
| while (SUCCEEDED(status = factory->EnumAdapters1(x++, &adapter_p))) { | ||||||||||||||||||||||||||||||||||
| dxgi::adapter_t adapter_tmp {adapter_p}; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| DXGI_ADAPTER_DESC1 adapter_desc; | ||||||||||||||||||||||||||||||||||
|
|
@@ -514,7 +515,8 @@ namespace platf::dxgi { | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| dxgi::output_t::pointer output_p; | ||||||||||||||||||||||||||||||||||
| for (int y = 0; adapter_tmp->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) { | ||||||||||||||||||||||||||||||||||
| int y = 0; | ||||||||||||||||||||||||||||||||||
| while (SUCCEEDED(status = adapter_tmp->EnumOutputs(y++, &output_p))) { | ||||||||||||||||||||||||||||||||||
| dxgi::output_t output_tmp {output_p}; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| DXGI_OUTPUT_DESC desc; | ||||||||||||||||||||||||||||||||||
|
|
@@ -549,12 +551,18 @@ namespace platf::dxgi { | |||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (FAILED(status) && status != DXGI_ERROR_NOT_FOUND) { | ||||||||||||||||||||||||||||||||||
| BOOST_LOG(error) << "Failed to enumerate DXGI outputs [0x"sv << util::hex(status).to_string_view() << ']'; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (output) { | ||||||||||||||||||||||||||||||||||
| adapter = std::move(adapter_tmp); | ||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (FAILED(status) && status != DXGI_ERROR_NOT_FOUND) { | ||||||||||||||||||||||||||||||||||
| BOOST_LOG(error) << "Failed to enumerate DXGI adapters [0x"sv << util::hex(status).to_string_view() << ']'; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (output) { | ||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
|
|
@@ -1085,7 +1093,8 @@ namespace platf { | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| dxgi::adapter_t::pointer adapter_p; | ||||||||||||||||||||||||||||||||||
| for (int x = 0; factory->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) { | ||||||||||||||||||||||||||||||||||
| int x = 0; | ||||||||||||||||||||||||||||||||||
| while (SUCCEEDED(status = factory->EnumAdapters1(x++, &adapter_p))) { | ||||||||||||||||||||||||||||||||||
| dxgi::adapter_t adapter {adapter_p}; | ||||||||||||||||||||||||||||||||||
| DXGI_ADAPTER_DESC1 adapter_desc; | ||||||||||||||||||||||||||||||||||
| adapter->GetDesc1(&adapter_desc); | ||||||||||||||||||||||||||||||||||
|
|
@@ -1103,7 +1112,8 @@ namespace platf { | |||||||||||||||||||||||||||||||||
| << " ====== OUTPUT ======"sv << std::endl; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| dxgi::output_t::pointer output_p {}; | ||||||||||||||||||||||||||||||||||
| for (int y = 0; adapter->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) { | ||||||||||||||||||||||||||||||||||
| int y = 0; | ||||||||||||||||||||||||||||||||||
| while (SUCCEEDED(status = adapter->EnumOutputs(y++, &output_p))) { | ||||||||||||||||||||||||||||||||||
| dxgi::output_t output {output_p}; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| DXGI_OUTPUT_DESC desc; | ||||||||||||||||||||||||||||||||||
|
|
@@ -1125,6 +1135,12 @@ namespace platf { | |||||||||||||||||||||||||||||||||
| display_names.emplace_back(std::move(device_name)); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (FAILED(status) && status != DXGI_ERROR_NOT_FOUND) { | ||||||||||||||||||||||||||||||||||
| BOOST_LOG(error) << "Failed to enumerate DXGI outputs [0x"sv << util::hex(status).to_string_view() << ']'; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (FAILED(status) && status != DXGI_ERROR_NOT_FOUND) { | ||||||||||||||||||||||||||||||||||
| BOOST_LOG(error) << "Failed to enumerate DXGI adapters [0x"sv << util::hex(status).to_string_view() << ']'; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+1138
to
1144
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] Discard the display list when enumeration fails If one display has already been appended and a later Return immediately from both unexpected-error handlers:
Suggested change
I reproduced this using the exact function from this head with fake DXGI objects: failure after an output, failure after an adapter, and output failure on a later adapter all returned [PRIMARY]. With these two returns, all seven harness scenarios passed. This was an extracted-function harness, not a hardware or full Sunshine test run. Review completed by Codex | Model: gpt-6.1-sol | Thinking: xhigh |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return display_names; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2] Add regression coverage for the failed-enumeration paths
The PR changes six production enumeration loops but adds no automated tests. The manual SSH check does not exercise a failure after a successful result, which is the partial-list defect above. Regression tests are required for changed source behavior.
Add
tests/unit/platform/windows/test_dxgi_enumeration.cpp, using../../../tests_common.hin the test include group and the existing GoogleTest framework. Introduce an injectable factory/adapter seam or a shared production helper so these tests exercise the actual enumeration code without requiring SSH or a particular GPU. There is currently no enumeration injection seam, so a test that merely copies the loops would not protect the fix.Concrete cases for
DxgiEnumerationTest:E_FAIL, and the first output call fail withDXGI_ERROR_NOT_CURRENTLY_AVAILABLE; assert no descriptor/pointer access occurs after failure and the call terminates.DXGI_ERROR_NOT_FOUND; assert both names remain and normal exhaustion produces no error log.Document the failure contract in Doxygen alongside the changed methods/helper. A focused test command after building the test target is:
These are proposed repository tests; they have not been added or run. The separate review harness covered the seven display-list scenarios described above.
Review completed by Codex | Model: gpt-6.1-sol | Thinking: xhigh