xbmc
D3DResource.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 "GUIColorManager.h"
12 #include "utils/ColorUtils.h"
13 #include "utils/Geometry.h"
14 
15 #include <map>
16 
17 #include <DirectXMath.h>
18 #include <d3dx11effect.h>
19 #include <wrl/client.h>
20 
21 #define KODI_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT 4
22 
23 typedef enum SHADER_METHOD {
24  SHADER_METHOD_RENDER_DEFAULT,
25  SHADER_METHOD_RENDER_TEXTURE_NOBLEND,
26  SHADER_METHOD_RENDER_FONT,
27  SHADER_METHOD_RENDER_TEXTURE_BLEND,
28  SHADER_METHOD_RENDER_MULTI_TEXTURE_BLEND,
29  SHADER_METHOD_RENDER_STEREO_INTERLACED_LEFT,
30  SHADER_METHOD_RENDER_STEREO_INTERLACED_RIGHT,
31  SHADER_METHOD_RENDER_STEREO_CHECKERBOARD_LEFT,
32  SHADER_METHOD_RENDER_STEREO_CHECKERBOARD_RIGHT,
33  SHADER_METHOD_RENDER_COUNT
34 } _SHADER_METHOD;
35 
37 {
38 public:
39  virtual ~ID3DResource() {}
40 
41  virtual void OnDestroyDevice(bool fatal)=0;
42  virtual void OnCreateDevice()=0;
43 
44 protected:
45  void Register();
46  void Unregister();
47 
48  bool m_bRegistered = false;
49 };
50 
52 {
53 public:
54  static inline void XMStoreColor(float* floats, DWORD dword)
55  {
56  floats[0] = float((dword >> 16) & 0xFF) * (1.0f / 255.0f); // r
57  floats[1] = float((dword >> 8) & 0xFF) * (1.0f / 255.0f); // g
58  floats[2] = float((dword >> 0) & 0xFF) * (1.0f / 255.0f); // b
59  floats[3] = float((dword >> 24) & 0xFF) * (1.0f / 255.0f); // a
60  }
61 
62  static inline void XMStoreColor(DirectX::XMFLOAT4* floats, DWORD dword)
63  {
64  XMStoreColor(reinterpret_cast<float*>(floats), dword);
65  }
66 
67  static inline void XMStoreColor(float* floats, unsigned char a, unsigned char r, unsigned char g, unsigned char b)
68  {
69  floats[0] = r * (1.0f / 255.0f);
70  floats[1] = g * (1.0f / 255.0f);
71  floats[2] = b * (1.0f / 255.0f);
72  floats[3] = a * (1.0f / 255.0f);
73  }
74 
75  static inline void XMStoreColor(DirectX::XMFLOAT4* floats, unsigned char a, unsigned char r, unsigned char g, unsigned char b)
76  {
77  XMStoreColor(reinterpret_cast<float*>(floats), a, r, g, b);
78  }
79 
80  // helper function to properly "clear" shader resources
81  static inline void PSClearShaderResources(ID3D11DeviceContext* pContext)
82  {
83  ID3D11ShaderResourceView* shader_resource_views[KODI_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
84  pContext->PSSetShaderResources(0, ARRAYSIZE(shader_resource_views), shader_resource_views);
85  }
86 
87  static size_t BitsPerPixel(DXGI_FORMAT fmt);
88 };
89 
90 class CD3DTexture : public ID3DResource
91 {
92 public:
93  CD3DTexture();
94  virtual ~CD3DTexture();
95 
96  bool Create(UINT width, UINT height, UINT mipLevels, D3D11_USAGE usage, DXGI_FORMAT format, const void* pInitData = nullptr, unsigned int srcPitch = 0);
97 
98  void Release();
99  bool GetDesc(D3D11_TEXTURE2D_DESC *desc) const;
100  bool LockRect(UINT subresource, D3D11_MAPPED_SUBRESOURCE *res, D3D11_MAP mapType) const;
101  bool UnlockRect(UINT subresource) const;
102 
103  // Accessors
104  ID3D11Texture2D* Get() const { return m_texture.Get(); }
105  ID3D11ShaderResourceView* GetShaderResource(DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN);
106  ID3D11ShaderResourceView** GetAddressOfSRV(DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN);
107  ID3D11RenderTargetView* GetRenderTarget();
108  ID3D11RenderTargetView** GetAddressOfRTV();
109  UINT GetWidth() const { return m_width; }
110  UINT GetHeight() const { return m_height; }
111  DXGI_FORMAT GetFormat() const { return m_format; }
112  void GenerateMipmaps();
113 
114  // static methods
115  static void DrawQuad(const CPoint points[4],
116  UTILS::COLOR::Color color,
117  CD3DTexture* texture,
118  const CRect* texCoords,
119  SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
120 
121  static void DrawQuad(const CPoint points[4],
122  UTILS::COLOR::Color color,
123  unsigned numViews,
124  ID3D11ShaderResourceView** view,
125  const CRect* texCoords,
126  SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
127 
128  static void DrawQuad(const CRect& coords,
129  UTILS::COLOR::Color color,
130  CD3DTexture* texture,
131  const CRect* texCoords,
132  SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
133 
134  static void DrawQuad(const CRect& coords,
135  UTILS::COLOR::Color color,
136  unsigned numViews,
137  ID3D11ShaderResourceView** view,
138  const CRect* texCoords,
139  SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
140 
141  void OnDestroyDevice(bool fatal) override;
142  void OnCreateDevice() override;
143 
144 protected:
145  ID3D11RenderTargetView* GetRenderTargetInternal(unsigned idx = 0);
146  unsigned int GetMemoryUsage(unsigned int pitch) const;
147  bool CreateInternal(const void* pInitData = nullptr, unsigned int srcPitch = 0);
148 
149  void SaveTexture();
150  void RestoreTexture();
151 
152  // saved data
153  BYTE* m_data;
154  // creation parameters
155  UINT m_width;
156  UINT m_height;
157  UINT m_mipLevels;
158  UINT m_pitch;
159  UINT m_bindFlags;
160  UINT m_cpuFlags;
161  UINT m_viewIdx;
162  D3D11_USAGE m_usage;
163  DXGI_FORMAT m_format;
164 
165  // created texture
166  Microsoft::WRL::ComPtr<ID3D11Texture2D> m_texture;
167  Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargets[2];
168  // store views in different formats
169  std::map<DXGI_FORMAT, Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>> m_views;
170 };
171 
172 typedef std::map<std::string, std::string> DefinesMap;
173 
174 class CD3DEffect : public ID3DResource, public ID3DInclude
175 {
176 public:
177  CD3DEffect();
178  virtual ~CD3DEffect();
179  bool Create(const std::string &effectString, DefinesMap* defines);
180  void Release();
181  bool SetFloatArray(LPCSTR handle, const float* val, unsigned int count);
182  bool SetMatrix(LPCSTR handle, const float* mat);
183  bool SetTechnique(LPCSTR handle);
184  bool SetTexture(LPCSTR handle, CD3DTexture &texture);
185  bool SetResources(LPCSTR handle, ID3D11ShaderResourceView** ppSRViews, size_t count);
186  bool SetConstantBuffer(LPCSTR handle, ID3D11Buffer *buffer);
187  bool SetScalar(LPCSTR handle, float value);
188  bool Begin(UINT *passes, DWORD flags);
189  bool BeginPass(UINT pass);
190  bool EndPass();
191  bool End();
192 
193  ID3DX11Effect* Get() const { return m_effect.Get(); }
194 
195  void OnDestroyDevice(bool fatal) override;
196  void OnCreateDevice() override;
197 
198  // ID3DInclude interface
199  __declspec(nothrow) HRESULT __stdcall Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override;
200  __declspec(nothrow) HRESULT __stdcall Close(LPCVOID pData) override;
201 
202 private:
203  bool CreateEffect();
204 
205  std::string m_effectString;
206  DefinesMap m_defines;
207  Microsoft::WRL::ComPtr<ID3DX11Effect> m_effect;
208  Microsoft::WRL::ComPtr<ID3DX11EffectTechnique> m_techniquie;
209  Microsoft::WRL::ComPtr<ID3DX11EffectPass> m_currentPass;
210 };
211 
212 class CD3DBuffer : public ID3DResource
213 {
214 public:
215  CD3DBuffer();
216  virtual ~CD3DBuffer();
217  bool Create(D3D11_BIND_FLAG type, UINT count, UINT stride, DXGI_FORMAT format, D3D11_USAGE usage, const void* initData = nullptr);
218  bool Map(void** resource);
219  bool Unmap();
220  void Release();
221  unsigned int GetStride() { return m_stride; }
222  DXGI_FORMAT GetFormat() { return m_format; }
223  ID3D11Buffer* Get() const { return m_buffer.Get(); }
224 
225  void OnDestroyDevice(bool fatal) override;
226  void OnCreateDevice() override;
227 
228 private:
229  bool CreateBuffer(const void *pData);
230 
231  // saved data
232  BYTE* m_data;
233  UINT m_length;
234  UINT m_stride;
235  UINT m_cpuFlags;
236  DXGI_FORMAT m_format;
237  D3D11_USAGE m_usage;
238  D3D11_BIND_FLAG m_type;
239  Microsoft::WRL::ComPtr<ID3D11Buffer> m_buffer;
240 };
241 
243 {
244 public:
246  ~CD3DVertexShader();
247 
248  bool Create(const std::wstring& vertexFile, D3D11_INPUT_ELEMENT_DESC* vertexLayout, unsigned int vertexLayoutSize);
249  bool Create(const void* code, size_t codeLength, D3D11_INPUT_ELEMENT_DESC* vertexLayout, unsigned int vertexLayoutSize);
250  void ReleaseShader();
251  void BindShader();
252  void UnbindShader();
253  void Release();
254  bool IsInited() { return m_inited; }
255 
256  void OnDestroyDevice(bool fatal) override;
257  void OnCreateDevice() override;
258 
259 private:
260  bool CreateInternal();
261 
262  bool m_inited;
263  unsigned int m_vertexLayoutSize;
264  D3D11_INPUT_ELEMENT_DESC* m_vertexLayout;
265  Microsoft::WRL::ComPtr<ID3DBlob> m_VSBuffer;
266  Microsoft::WRL::ComPtr<ID3D11VertexShader> m_VS;
267  Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
268 };
269 
271 {
272 public:
273  CD3DPixelShader();
274  ~CD3DPixelShader();
275 
276  bool Create(const std::wstring& wstrFile);
277  bool Create(const void* code, size_t codeLength);
278  void ReleaseShader();
279  void BindShader();
280  void UnbindShader();
281  void Release();
282  bool IsInited() { return m_inited; }
283 
284  void OnDestroyDevice(bool fatal) override;
285  void OnCreateDevice() override;
286 
287 private:
288  bool CreateInternal();
289 
290  bool m_inited;
291  Microsoft::WRL::ComPtr<ID3DBlob> m_PSBuffer;
292  Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PS;
293 };
Definition: D3DResource.h:90
Definition: D3DResource.h:174
Definition: D3DResource.h:270
Definition: D3DResource.h:36
Definition: inftrees.h:24
Definition: D3DResource.h:51
Definition: D3DResource.h:242
Definition: D3DResource.h:212