[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / rendering / dx / DirectXHelper.h
blob779b8751d571377e83f55f23dea26ca05aa38d51
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #pragma once
11 #include "commons/Exception.h"
12 #include "dxerr.h"
14 #include "platform/win32/CharsetConverter.h"
16 #include <d3d11_4.h>
17 #include <ppltasks.h> // For create_task
19 enum PCI_Vendors
21 PCIV_AMD = 0x1002,
22 PCIV_NVIDIA = 0x10DE,
23 PCIV_Intel = 0x8086,
24 PCIV_MICROSOFT = 0x1414,
27 namespace DX
29 #define RATIONAL_TO_FLOAT(rational) ((rational.Denominator != 0) ? \
30 static_cast<float>(rational.Numerator) / static_cast<float>(rational.Denominator) : 0.0f)
32 namespace DisplayMetrics
34 // High resolution displays can require a lot of GPU and battery power to render.
35 // High resolution phones, for example, may suffer from poor battery life if
36 // games attempt to render at 60 frames per second at full fidelity.
37 // The decision to render at full fidelity across all platforms and form factors
38 // should be deliberate.
39 static const bool SupportHighResolutions = true;
41 // The default thresholds that define a "high resolution" display. If the thresholds
42 // are exceeded and SupportHighResolutions is false, the dimensions will be scaled
43 // by 50%.
44 static const float Dpi100 = 96.0f; // 100% of standard desktop display.
45 static const float DpiThreshold = 192.0f; // 200% of standard desktop display.
46 static const float WidthThreshold = 1920.0f; // 1080p width.
47 static const float HeightThreshold = 1080.0f; // 1080p height.
50 inline void BreakIfFailed(HRESULT hr)
52 if (FAILED(hr))
54 // Set a breakpoint on this line to catch Win32 API errors.
55 #if _DEBUG && !defined(TARGET_WINDOWS_STORE)
56 DebugBreak();
57 #endif
58 throw new XbmcCommons::UncheckedException(__FUNCTION__, "Unhandled error");
62 // Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
63 inline float ConvertDipsToPixels(float dips, float dpi)
65 static const float dipsPerInch = DisplayMetrics::Dpi100;
66 return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
69 inline float ConvertPixelsToDips(float pixels, float dpi)
71 static const float dipsPerInch = DisplayMetrics::Dpi100;
72 return floorf(pixels / (dpi / dipsPerInch) + 0.5f); // Round to nearest integer.
75 inline float RationalToFloat(DXGI_RATIONAL rational)
77 return RATIONAL_TO_FLOAT(rational);
80 inline void GetRefreshRatio(uint32_t refresh, uint32_t *num, uint32_t *den)
82 int i = (((refresh + 1) % 24) == 0 || ((refresh + 1) % 30) == 0) ? 1 : 0;
83 *num = (refresh + i) * 1000;
84 *den = 1000 + i;
87 inline std::string GetErrorDescription(HRESULT hr)
89 using namespace KODI::PLATFORM::WINDOWS;
91 WCHAR buff[2048];
92 DXGetErrorDescriptionW(hr, buff, 2048);
94 return FromW(StringUtils::Format(L"{:X} - {} ({})", hr, DXGetErrorStringW(hr), buff));
97 inline std::string GetFeatureLevelDescription(D3D_FEATURE_LEVEL featureLevel)
99 uint32_t fl_major = (featureLevel & 0xF000u) >> 12;
100 uint32_t fl_minor = (featureLevel & 0x0F00u) >> 8;
102 return StringUtils::Format("D3D_FEATURE_LEVEL_{}_{}", fl_major, fl_minor);
105 constexpr std::string_view GetGFXProviderName(UINT vendorId)
107 switch (vendorId)
109 case PCIV_AMD:
110 return "AMD";
111 case PCIV_Intel:
112 return "Intel";
113 case PCIV_NVIDIA:
114 return "NVIDIA";
115 case PCIV_MICROSOFT:
116 return "Microsoft";
117 default:
118 return "unknown";
122 constexpr std::string_view DXGIFormatToShortString(const DXGI_FORMAT format)
124 switch (format)
126 case DXGI_FORMAT_B8G8R8A8_UNORM:
127 return "BGRA8";
128 case DXGI_FORMAT_R10G10B10A2_UNORM:
129 return "RGBA10";
130 case DXGI_FORMAT_R16G16B16A16_FLOAT:
131 return "FP16";
132 case DXGI_FORMAT_R32G32B32A32_FLOAT:
133 return "FP32";
134 default:
135 return "unknown";
139 template <typename T> struct SizeGen
141 SizeGen<T>() { Width = Height = 0; }
142 SizeGen<T>(T width, T height) { Width = width; Height = height; }
144 bool operator !=(const SizeGen<T> &size) const
146 return Width != size.Width || Height != size.Height;
149 const SizeGen<T> &operator -=(const SizeGen<T> &size)
151 Width -= size.Width;
152 Height -= size.Height;
153 return *this;
156 const SizeGen<T> &operator +=(const SizeGen<T> &size)
158 Width += size.Width;
159 Height += size.Height;
160 return *this;
163 const SizeGen<T> &operator -=(const T &size)
165 Width -= size;
166 Height -= size;
167 return *this;
170 const SizeGen<T> &operator +=(const T &size)
172 Width += size;
173 Height += size;
174 return *this;
177 T Width, Height;
180 #if defined(_DEBUG)
181 // Check for SDK Layer support.
182 inline bool SdkLayersAvailable()
184 HRESULT hr = D3D11CreateDevice(
185 nullptr,
186 D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
187 nullptr,
188 D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
189 nullptr, // Any feature level will do.
191 D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
192 nullptr, // No need to keep the D3D device reference.
193 nullptr, // No need to know the feature level.
194 nullptr // No need to keep the D3D device context reference.
197 return SUCCEEDED(hr);
199 #endif
201 const std::string DXGIFormatToString(const DXGI_FORMAT format);
202 const std::string DXGIColorSpaceTypeToString(DXGI_COLOR_SPACE_TYPE type);
203 const std::string D3D11VideoProcessorFormatSupportToString(
204 D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT value);
207 #ifdef TARGET_WINDOWS_DESKTOP
208 namespace winrt
210 namespace Windows
212 namespace Foundation
214 typedef DX::SizeGen<float> Size;
215 typedef DX::SizeGen<int> SizeInt;
219 #endif