-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
platform/windows: implement IDXGIOutput5 / Per Monitor v2 #522
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
Changes from all commits
5b7c400
7bad3bf
62f98b8
d247122
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 |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
|
|
||
| #include <cmath> | ||
| #include <codecvt> | ||
| #include <initguid.h> | ||
|
|
||
| #include "display.h" | ||
| #include "misc.h" | ||
|
|
@@ -79,22 +80,21 @@ duplication_t::~duplication_t() { | |
| } | ||
|
|
||
| int display_base_t::init(int framerate, const std::string &display_name) { | ||
| /* Uncomment when use of IDXGIOutput5 is implemented | ||
| std::once_flag windows_cpp_once_flag; | ||
|
|
||
| std::call_once(windows_cpp_once_flag, []() { | ||
| DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); | ||
| const auto DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = ((DPI_AWARENESS_CONTEXT)-4); | ||
|
|
||
| typedef BOOL (*User32_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value); | ||
|
|
||
| auto user32 = LoadLibraryA("user32.dll"); | ||
| auto f = (User32_SetProcessDpiAwarenessContext)GetProcAddress(user32, "SetProcessDpiAwarenessContext"); | ||
| auto f = (User32_SetProcessDpiAwarenessContext)GetProcAddress(user32, "SetProcessDpiAwarenessContext"); | ||
| if(f) { | ||
| f(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); | ||
| } | ||
|
|
||
| FreeLibrary(user32); | ||
| }); | ||
| */ | ||
|
|
||
| // Ensure we can duplicate the current display | ||
| syncThreadDesktop(); | ||
|
|
@@ -291,27 +291,51 @@ int display_base_t::init(int framerate, const std::string &display_name) { | |
| } | ||
|
|
||
| //FIXME: Duplicate output on RX580 in combination with DOOM (2016) --> BSOD | ||
| //TODO: Use IDXGIOutput5 for improved performance | ||
| { | ||
| const DXGI_FORMAT DesktopFormats[] = { | ||
| DXGI_FORMAT_R8G8B8A8_UNORM, | ||
| DXGI_FORMAT_B8G8R8A8_UNORM, | ||
| DXGI_FORMAT_R16G16B16A16_FLOAT, | ||
| DXGI_FORMAT_R10G10B10A2_UNORM, | ||
|
Collaborator
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. I wonder if we can fix #376 here by specifying the appropriate formats (DXGI_FORMAT_B8G8R8A8_UNORM for SDR and DXGI_FORMAT_R10G10B10A2_UNORM for HDR, when that is implemented). As I understand the docs, DWM should convert the format to match what we've asked for (for example, doing HDR -> SDR conversion if requested).
Contributor
Author
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. Unfortunately I don't have any HDR capable monitors to test HDR or HDR -> SDR conversion; I even tried a virtual monitor driver for Windows, but it refuses to enable HDR in the virtual monitor. Specifying the expanded list of formats doesn't seem to automatically convert formats, but it has allowed me to fix some other issues (added as separate commits). Since my hands are tied in diagnosing/fixing HDR support due to lack of hardware, I would be more than happy to let you take over this PR (doesn't matter if you recommend this to be merged and then you continue, you cherry-pick some changes, or start over entirely, I don't mind). In its present form, this PR will at minimum fix: #553
Collaborator
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.
It actually does, but we just made an mistake in our interpretation of the MSDN docs on it. For |
||
| }; | ||
| const unsigned DesktopFormatsCounts = sizeof(DesktopFormats) / sizeof(DesktopFormats[0]); | ||
| dxgi::output1_t output1 {}; | ||
| status = output->QueryInterface(IID_IDXGIOutput1, (void **)&output1); | ||
| dxgi::output5_t output5 {}; | ||
|
|
||
| status = output->QueryInterface(IID_IDXGIOutput5, (void **)&output5); | ||
| if(FAILED(status)) { | ||
| BOOST_LOG(error) << "Failed to query IDXGIOutput1 from the output"sv; | ||
| return -1; | ||
| BOOST_LOG(warning) << "Failed to query IDXGIOutput5 from the output"sv; | ||
|
|
||
| status = output->QueryInterface(IID_IDXGIOutput1, (void **)&output1); | ||
| if(FAILED(status)) { | ||
| BOOST_LOG(error) << "Failed to query IDXGIOutput1 from the output"sv; | ||
| return -1; | ||
| } | ||
| } | ||
|
|
||
| // We try this twice, in case we still get an error on reinitialization | ||
| for(int x = 0; x < 2; ++x) { | ||
| status = output1->DuplicateOutput((IUnknown *)device.get(), &dup.dup); | ||
| status = output5->DuplicateOutput1((IUnknown *)device.get(), 0, DesktopFormatsCounts, DesktopFormats, &dup.dup); | ||
| if(SUCCEEDED(status)) { | ||
| break; | ||
| } | ||
| std::this_thread::sleep_for(200ms); | ||
| } | ||
|
|
||
| if(FAILED(status)) { | ||
| BOOST_LOG(error) << "DuplicateOutput Failed [0x"sv << util::hex(status).to_string_view() << ']'; | ||
| return -1; | ||
| BOOST_LOG(warning) << "DuplicateOutput1 Failed [0x"sv << util::hex(status).to_string_view() << ']'; | ||
| for(int x = 0; x < 2; ++x) { | ||
| status = output1->DuplicateOutput((IUnknown *)device.get(), &dup.dup); | ||
| if(SUCCEEDED(status)) { | ||
| break; | ||
| } | ||
| std::this_thread::sleep_for(200ms); | ||
| } | ||
|
|
||
| if(FAILED(status)) { | ||
| BOOST_LOG(error) << "DuplicateOutput Failed [0x"sv << util::hex(status).to_string_view() << ']'; | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -434,6 +434,7 @@ class hwdevice_t : public platf::hwdevice_t { | |||
|
|
||||
| this->device_ctx_p = device_ctx_p; | ||||
|
|
||||
| DXGI_FORMAT src_format = format; | ||||
|
Contributor
Author
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. Related to #609: I actually made an additional mistake here: I assumed that Sunshine/src/platform/windows/display_ram.cpp Line 288 in 62f98b8
However, looking at #609, instead of fixing this, it looks like I should just remove both the
Collaborator
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. I think The base |
||||
| format = (pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010); | ||||
| status = device_p->CreateVertexShader(scene_vs_hlsl->GetBufferPointer(), scene_vs_hlsl->GetBufferSize(), nullptr, &scene_vs); | ||||
| if(status) { | ||||
|
|
@@ -490,7 +491,7 @@ class hwdevice_t : public platf::hwdevice_t { | |||
| } | ||||
|
|
||||
| D3D11_SHADER_RESOURCE_VIEW_DESC desc { | ||||
| DXGI_FORMAT_B8G8R8A8_UNORM, | ||||
| src_format, | ||||
| D3D11_SRV_DIMENSION_TEXTURE2D | ||||
| }; | ||||
| desc.Texture2D.MipLevels = 1; | ||||
|
|
@@ -885,4 +886,4 @@ int init() { | |||
|
|
||||
| return 0; | ||||
| } | ||||
| } // namespace platf::dxgi | ||||
| } // namespace platf::dxgi | ||||
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.
I noticed this comment from loki. My host GPU is a newer AMD GPU (RX 6600), but perhaps this is related to my problem; DOOM 2016 runs in Vulkan, so it could be using
DXGI_FORMAT_R8G8B8A8_UNORMjust like DX11 titles in true fullscreen exclusive mode.I've been testing a game (Dying Light) with "disable fullscreen optimizations" checked. Before this PR, it wasn't possible to run in true exclusive fullscreen; now it works. However, if you toggle between resolutions in the settings menu, eventually it will either cause a driver timeout or complete BSOD. I was able to reproduce the crash on both
libx264andamdvce, and it looks like #605 doesn't solve my issue (but I realize that it wasn't the focus).