From 772f7f7fd246118f491400975ed6729de0e86076 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 6 Mar 2025 09:00:33 +0100 Subject: [PATCH] Move `GPUDeviceDX::UpdateOutputs` to cpp file --- .../GraphicsDevice/DirectX/GPUDeviceDX.h | 161 +----------------- .../GraphicsDevice/DirectX/RenderToolsDX.cpp | 155 +++++++++++++++++ 2 files changed, 157 insertions(+), 159 deletions(-) diff --git a/Source/Engine/GraphicsDevice/DirectX/GPUDeviceDX.h b/Source/Engine/GraphicsDevice/DirectX/GPUDeviceDX.h index cc6d123d1..61b61847e 100644 --- a/Source/Engine/GraphicsDevice/DirectX/GPUDeviceDX.h +++ b/Source/Engine/GraphicsDevice/DirectX/GPUDeviceDX.h @@ -23,83 +23,15 @@ public: Array VideoModes; }; -namespace Windows -{ - typedef struct _devicemodeW - { - WCHAR dmDeviceName[32]; - WORD dmSpecVersion; - WORD dmDriverVersion; - WORD dmSize; - WORD dmDriverExtra; - DWORD dmFields; - - union - { - struct - { - short dmOrientation; - short dmPaperSize; - short dmPaperLength; - short dmPaperWidth; - short dmScale; - short dmCopies; - short dmDefaultSource; - short dmPrintQuality; - } DUMMYSTRUCTNAME; - - POINTL dmPosition; - - struct - { - POINTL dmPosition; - DWORD dmDisplayOrientation; - DWORD dmDisplayFixedOutput; - } DUMMYSTRUCTNAME2; - } DUMMYUNIONNAME; - - short dmColor; - short dmDuplex; - short dmYResolution; - short dmTTOption; - short dmCollate; - WCHAR dmFormName[32]; - WORD dmLogPixels; - DWORD dmBitsPerPel; - DWORD dmPelsWidth; - DWORD dmPelsHeight; - - union - { - DWORD dmDisplayFlags; - DWORD dmNup; - } DUMMYUNIONNAME2; - - DWORD dmDisplayFrequency; - DWORD dmICMMethod; - DWORD dmICMIntent; - DWORD dmMediaType; - DWORD dmDitherType; - DWORD dmReserved1; - DWORD dmReserved2; - DWORD dmPanningWidth; - DWORD dmPanningHeight; - } DEVMODEW, *PDEVMODEW, *NPDEVMODEW, *LPDEVMODEW; - - WIN_API BOOL WIN_API_CALLCONV EnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode); -} - /// /// Base for all DirectX graphics devices. /// class GPUDeviceDX : public GPUDevice { protected: - GPUAdapterDX* _adapter; protected: - GPUDeviceDX(RendererType type, ShaderProfile profile, GPUAdapterDX* adapter) : GPUDevice(type, profile) , _adapter(adapter) @@ -107,11 +39,9 @@ protected: } public: - /// - /// Gets DirectX device feature level + /// Gets DirectX device feature level. /// - /// D3D feature level FORCE_INLINE D3D_FEATURE_LEVEL GetD3DFeatureLevel() const { return _adapter->MaxFeatureLevel; @@ -124,94 +54,7 @@ public: protected: - void UpdateOutputs(IDXGIAdapter* adapter) - { -#if PLATFORM_WINDOWS - // Collect output devices - uint32 outputIdx = 0; - ComPtr output; - DXGI_FORMAT defaultBackbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT); - Array modeDesc; - while (adapter->EnumOutputs(outputIdx, &output) != DXGI_ERROR_NOT_FOUND) - { - auto& outputDX11 = Outputs.AddOne(); - - outputDX11.Output = output; - output->GetDesc(&outputDX11.Desc); - - uint32 numModes = 0; - HRESULT hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, nullptr); - if (FAILED(hr)) - { - LOG(Warning, "Error while enumerating adapter output video modes."); - continue; - } - - modeDesc.Resize(numModes, false); - hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, modeDesc.Get()); - if (FAILED(hr)) - { - LOG(Warning, "Error while enumerating adapter output video modes."); - continue; - } - - for (auto& mode : modeDesc) - { - bool foundVideoMode = false; - for (auto& videoMode : outputDX11.VideoModes) - { - if (videoMode.Width == mode.Width && - videoMode.Height == mode.Height && - videoMode.RefreshRate.Numerator == mode.RefreshRate.Numerator && - videoMode.RefreshRate.Denominator == mode.RefreshRate.Denominator) - { - foundVideoMode = true; - break; - } - } - - if (!foundVideoMode) - { - outputDX11.VideoModes.Add(mode); - - // Collect only from the main monitor - if (Outputs.Count() == 1) - { - VideoOutputModes.Add({ mode.Width, mode.Height, (uint32)(mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator) }); - } - } - } - - // Get desktop display mode - HMONITOR hMonitor = outputDX11.Desc.Monitor; - MONITORINFOEX monitorInfo; - monitorInfo.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &monitorInfo); - - Windows::DEVMODEW devMode; - devMode.dmSize = sizeof(Windows::DEVMODEW); - devMode.dmDriverExtra = 0; - Windows::EnumDisplaySettingsW(monitorInfo.szDevice, ((DWORD)-1), &devMode); - - DXGI_MODE_DESC currentMode; - currentMode.Width = devMode.dmPelsWidth; - currentMode.Height = devMode.dmPelsHeight; - bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency; - currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency; - currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1; - currentMode.Format = defaultBackbufferFormat; - currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - - if (output->FindClosestMatchingMode(¤tMode, &outputDX11.DesktopViewMode, nullptr) != S_OK) - outputDX11.DesktopViewMode = currentMode; - - float refreshRate = outputDX11.DesktopViewMode.RefreshRate.Numerator / (float)outputDX11.DesktopViewMode.RefreshRate.Denominator; - LOG(Info, "Video output '{0}' {1}x{2} {3} Hz", outputDX11.Desc.DeviceName, devMode.dmPelsWidth, devMode.dmPelsHeight, refreshRate); - outputIdx++; - } -#endif - } + void UpdateOutputs(IDXGIAdapter* adapter); static RendererType getRendererType(GPUAdapterDX* adapter) { diff --git a/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp b/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp index 90c7e6a74..39a975b74 100644 --- a/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp @@ -3,10 +3,77 @@ #if GRAPHICS_API_DIRECTX11 || GRAPHICS_API_DIRECTX12 #include "RenderToolsDX.h" +#include "GPUDeviceDX.h" #include "Engine/Core/Types/StringBuilder.h" #include "Engine/Graphics/GPUDevice.h" #include +namespace Windows +{ + typedef struct _devicemodeW + { + WCHAR dmDeviceName[32]; + WORD dmSpecVersion; + WORD dmDriverVersion; + WORD dmSize; + WORD dmDriverExtra; + DWORD dmFields; + + union + { + struct + { + short dmOrientation; + short dmPaperSize; + short dmPaperLength; + short dmPaperWidth; + short dmScale; + short dmCopies; + short dmDefaultSource; + short dmPrintQuality; + } DUMMYSTRUCTNAME; + + POINTL dmPosition; + + struct + { + POINTL dmPosition; + DWORD dmDisplayOrientation; + DWORD dmDisplayFixedOutput; + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME; + + short dmColor; + short dmDuplex; + short dmYResolution; + short dmTTOption; + short dmCollate; + WCHAR dmFormName[32]; + WORD dmLogPixels; + DWORD dmBitsPerPel; + DWORD dmPelsWidth; + DWORD dmPelsHeight; + + union + { + DWORD dmDisplayFlags; + DWORD dmNup; + } DUMMYUNIONNAME2; + + DWORD dmDisplayFrequency; + DWORD dmICMMethod; + DWORD dmICMIntent; + DWORD dmMediaType; + DWORD dmDitherType; + DWORD dmReserved1; + DWORD dmReserved2; + DWORD dmPanningWidth; + DWORD dmPanningHeight; + } DEVMODEW, *PDEVMODEW, *NPDEVMODEW, *LPDEVMODEW; + + WIN_API BOOL WIN_API_CALLCONV EnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode); +} + // @formatter:off DXGI_FORMAT PixelFormatToDXGIFormat[110] = @@ -372,5 +439,93 @@ LPCSTR RenderToolsDX::GetVertexInputSemantic(VertexElement::Types type, UINT& se return ""; } } +void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter) +{ +#if PLATFORM_WINDOWS + // Collect output devices + uint32 outputIdx = 0; + ComPtr output; + DXGI_FORMAT defaultBackbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT); + Array modeDesc; + while (adapter->EnumOutputs(outputIdx, &output) != DXGI_ERROR_NOT_FOUND) + { + auto& outputDX11 = Outputs.AddOne(); + + outputDX11.Output = output; + output->GetDesc(&outputDX11.Desc); + + uint32 numModes = 0; + HRESULT hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, nullptr); + if (FAILED(hr)) + { + LOG(Warning, "Error while enumerating adapter output video modes."); + continue; + } + + modeDesc.Resize(numModes, false); + hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, modeDesc.Get()); + if (FAILED(hr)) + { + LOG(Warning, "Error while enumerating adapter output video modes."); + continue; + } + + for (auto& mode : modeDesc) + { + bool foundVideoMode = false; + for (auto& videoMode : outputDX11.VideoModes) + { + if (videoMode.Width == mode.Width && + videoMode.Height == mode.Height && + videoMode.RefreshRate.Numerator == mode.RefreshRate.Numerator && + videoMode.RefreshRate.Denominator == mode.RefreshRate.Denominator) + { + foundVideoMode = true; + break; + } + } + + if (!foundVideoMode) + { + outputDX11.VideoModes.Add(mode); + + // Collect only from the main monitor + if (Outputs.Count() == 1) + { + VideoOutputModes.Add({ mode.Width, mode.Height, (uint32)(mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator) }); + } + } + } + + // Get desktop display mode + HMONITOR hMonitor = outputDX11.Desc.Monitor; + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfo); + + Windows::DEVMODEW devMode; + devMode.dmSize = sizeof(Windows::DEVMODEW); + devMode.dmDriverExtra = 0; + Windows::EnumDisplaySettingsW(monitorInfo.szDevice, ((DWORD)-1), &devMode); + + DXGI_MODE_DESC currentMode; + currentMode.Width = devMode.dmPelsWidth; + currentMode.Height = devMode.dmPelsHeight; + bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency; + currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency; + currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1; + currentMode.Format = defaultBackbufferFormat; + currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + if (output->FindClosestMatchingMode(¤tMode, &outputDX11.DesktopViewMode, nullptr) != S_OK) + outputDX11.DesktopViewMode = currentMode; + + float refreshRate = outputDX11.DesktopViewMode.RefreshRate.Numerator / (float)outputDX11.DesktopViewMode.RefreshRate.Denominator; + LOG(Info, "Video output '{0}' {1}x{2} {3} Hz", outputDX11.Desc.DeviceName, devMode.dmPelsWidth, devMode.dmPelsHeight, refreshRate); + outputIdx++; + } +#endif +} #endif