kodi
DirectXHelper.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "commons/Exception.h"
12 #include "dxerr.h"
13 
14 #include "platform/win32/CharsetConverter.h"
15 
16 #include <d3d11_4.h>
17 #include <ppltasks.h> // For create_task
18 
19 enum PCI_Vendors
20 {
21  PCIV_AMD = 0x1002,
22  PCIV_NVIDIA = 0x10DE,
23  PCIV_Intel = 0x8086,
24  PCIV_MICROSOFT = 0x1414,
25 };
26 
27 namespace DX
28 {
29 #define RATIONAL_TO_FLOAT(rational) ((rational.Denominator != 0) ? \
30  static_cast<float>(rational.Numerator) / static_cast<float>(rational.Denominator) : 0.0f)
31 
32  namespace DisplayMetrics
33  {
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;
40 
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.
48  };
49 
50  inline void BreakIfFailed(HRESULT hr)
51  {
52  if (FAILED(hr))
53  {
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");
59  }
60  }
61 
62  // Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
63  inline float ConvertDipsToPixels(float dips, float dpi)
64  {
65  static const float dipsPerInch = DisplayMetrics::Dpi100;
66  return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
67  }
68 
69  inline float ConvertPixelsToDips(float pixels, float dpi)
70  {
71  static const float dipsPerInch = DisplayMetrics::Dpi100;
72  return floorf(pixels / (dpi / dipsPerInch) + 0.5f); // Round to nearest integer.
73  }
74 
75  inline float RationalToFloat(DXGI_RATIONAL rational)
76  {
77  return RATIONAL_TO_FLOAT(rational);
78  }
79 
80  inline void GetRefreshRatio(uint32_t refresh, uint32_t *num, uint32_t *den)
81  {
82  int i = (((refresh + 1) % 24) == 0 || ((refresh + 1) % 30) == 0) ? 1 : 0;
83  *num = (refresh + i) * 1000;
84  *den = 1000 + i;
85  }
86 
87  inline std::string GetErrorDescription(HRESULT hr)
88  {
89  using namespace KODI::PLATFORM::WINDOWS;
90 
91  WCHAR buff[2048];
92  DXGetErrorDescriptionW(hr, buff, 2048);
93 
94  return FromW(StringUtils::Format(L"{:X} - {} ({})", hr, DXGetErrorStringW(hr), buff));
95  }
96 
97  inline std::string GetFeatureLevelDescription(D3D_FEATURE_LEVEL featureLevel)
98  {
99  uint32_t fl_major = (featureLevel & 0xF000u) >> 12;
100  uint32_t fl_minor = (featureLevel & 0x0F00u) >> 8;
101 
102  return StringUtils::Format("D3D_FEATURE_LEVEL_{}_{}", fl_major, fl_minor);
103  }
104 
105  constexpr std::string_view GetGFXProviderName(UINT vendorId)
106  {
107  switch (vendorId)
108  {
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";
119  }
120  }
121 
122  constexpr std::string_view DXGIFormatToShortString(const DXGI_FORMAT format)
123  {
124  switch (format)
125  {
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";
136  }
137  }
138 
139  template <typename T> struct SizeGen
140  {
141  SizeGen<T>() { Width = Height = 0; }
142  SizeGen<T>(T width, T height) { Width = width; Height = height; }
143 
144  bool operator !=(const SizeGen<T> &size) const
145  {
146  return Width != size.Width || Height != size.Height;
147  }
148 
149  const SizeGen<T> &operator -=(const SizeGen<T> &size)
150  {
151  Width -= size.Width;
152  Height -= size.Height;
153  return *this;
154  };
155 
156  const SizeGen<T> &operator +=(const SizeGen<T> &size)
157  {
158  Width += size.Width;
159  Height += size.Height;
160  return *this;
161  };
162 
163  const SizeGen<T> &operator -=(const T &size)
164  {
165  Width -= size;
166  Height -= size;
167  return *this;
168  };
169 
170  const SizeGen<T> &operator +=(const T &size)
171  {
172  Width += size;
173  Height += size;
174  return *this;
175  };
176 
177  T Width, Height;
178  };
179 
180 #if defined(_DEBUG)
181  // Check for SDK Layer support.
182  inline bool SdkLayersAvailable()
183  {
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.
190  0,
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.
195  );
196 
197  return SUCCEEDED(hr);
198  }
199 #endif
200 
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);
205 }
206 
207 #ifdef TARGET_WINDOWS_DESKTOP
208 namespace winrt
209 {
210  namespace Windows
211  {
212  namespace Foundation
213  {
214  typedef DX::SizeGen<float> Size;
215  typedef DX::SizeGen<int> SizeInt;
216  }
217  }
218 }
219 #endif
Definition: AsyncHelpers.h:15
Definition: DeviceResources.h:27
static std::string Format(const std::string &fmt, Args &&... args)
Get a formatted string similar to sprintf.
Definition: StringUtils.h:79
Definition: CharsetConverter.cpp:16
Definition: DirectXHelper.h:139