summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d11/MLGDeviceD3D11.h
blob: 2a6aa8ffc7c22a386949a308f93a98ff3b51295b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h
#define mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h

#include <d3d11_1.h>

#include "mozilla/layers/MLGDevice.h"
#include "mozilla/layers/SyncObject.h"
#include "mozilla/EnumeratedArray.h"
#include "nsTHashtable.h"
#include "nsPrintfCString.h"

namespace mozilla {
namespace layers {

struct GPUStats;
struct ShaderBytes;
class DiagnosticsD3D11;

class MLGRenderTargetD3D11 final : public MLGRenderTarget {
 public:
  MLGRenderTargetD3D11(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags);

  // Create with a new texture.
  bool Initialize(ID3D11Device* aDevice);

  // Do not create a texture - use the given one provided, which may be null.
  // The depth buffer is still initialized.
  bool Initialize(ID3D11Device* aDevice, ID3D11Texture2D* aTexture);

  gfx::IntSize GetSize() const override;
  MLGRenderTargetD3D11* AsD3D11() override { return this; }
  MLGTexture* GetTexture() override;

  // This is exposed only for MLGSwapChainD3D11.
  bool UpdateTexture(ID3D11Texture2D* aTexture);

  ID3D11DepthStencilView* GetDSV();
  ID3D11RenderTargetView* GetRenderTargetView();

 private:
  bool CreateDepthBuffer(ID3D11Device* aDevice);
  void ForgetTexture();

 private:
  virtual ~MLGRenderTargetD3D11();

 private:
  RefPtr<ID3D11Texture2D> mTexture;
  RefPtr<ID3D11RenderTargetView> mRTView;
  RefPtr<ID3D11Texture2D> mDepthBuffer;
  RefPtr<ID3D11DepthStencilView> mDepthStencilView;
  RefPtr<MLGTexture> mTextureSource;
  gfx::IntSize mSize;
};

class MLGSwapChainD3D11 final : public MLGSwapChain {
 public:
  static RefPtr<MLGSwapChainD3D11> Create(MLGDeviceD3D11* aParent,
                                          ID3D11Device* aDevice,
                                          widget::CompositorWidget* aWidget);

  RefPtr<MLGRenderTarget> AcquireBackBuffer() override;
  gfx::IntSize GetSize() const override;
  bool ResizeBuffers(const gfx::IntSize& aSize) override;
  void CopyBackbuffer(gfx::DrawTarget* aTarget,
                      const gfx::IntRect& aBounds) override;
  void Present() override;
  void ForcePresent() override;
  void Destroy() override;

 private:
  MLGSwapChainD3D11(MLGDeviceD3D11* aParent, ID3D11Device* aDevice);
  virtual ~MLGSwapChainD3D11();

  bool Initialize(widget::CompositorWidget* aWidget);
  void UpdateBackBufferContents(ID3D11Texture2D* aBack);

 private:
  RefPtr<MLGDeviceD3D11> mParent;
  RefPtr<ID3D11Device> mDevice;
  RefPtr<IDXGISwapChain> mSwapChain;
  RefPtr<IDXGISwapChain1> mSwapChain1;
  RefPtr<MLGRenderTargetD3D11> mRT;
  widget::CompositorWidget* mWidget;
  gfx::IntSize mSize;
  bool mCanUsePartialPresents;
};

class MLGResourceD3D11 {
 public:
  virtual ID3D11Resource* GetResource() const = 0;
};

class MLGBufferD3D11 final : public MLGBuffer, public MLGResourceD3D11 {
 public:
  static RefPtr<MLGBufferD3D11> Create(ID3D11Device* aDevice,
                                       MLGBufferType aType, uint32_t aSize,
                                       MLGUsage aUsage,
                                       const void* aInitialData);

  MLGBufferD3D11* AsD3D11() override { return this; }
  ID3D11Resource* GetResource() const override { return mBuffer; }
  ID3D11Buffer* GetBuffer() const { return mBuffer; }
  MLGResourceD3D11* AsResourceD3D11() override { return this; }
  size_t GetSize() const override { return mSize; }

 protected:
  MLGBufferD3D11(ID3D11Buffer* aBuffer, MLGBufferType aType, size_t aSize);
  virtual ~MLGBufferD3D11();

 private:
  RefPtr<ID3D11Buffer> mBuffer;
  MLGBufferType mType;
  size_t mSize;
};

class MLGTextureD3D11 final : public MLGTexture, public MLGResourceD3D11 {
 public:
  explicit MLGTextureD3D11(ID3D11Texture2D* aTexture);

  static RefPtr<MLGTextureD3D11> Create(ID3D11Device* aDevice,
                                        const gfx::IntSize& aSize,
                                        gfx::SurfaceFormat aFormat,
                                        MLGUsage aUsage,
                                        MLGTextureFlags aFlags);

  MLGTextureD3D11* AsD3D11() override { return this; }
  MLGResourceD3D11* AsResourceD3D11() override { return this; }
  ID3D11Texture2D* GetTexture() const { return mTexture; }
  ID3D11Resource* GetResource() const override { return mTexture; }
  ID3D11ShaderResourceView* GetShaderResourceView();

 private:
  RefPtr<ID3D11Texture2D> mTexture;
  RefPtr<ID3D11ShaderResourceView> mView;
};

class MLGDeviceD3D11 final : public MLGDevice {
 public:
  explicit MLGDeviceD3D11(ID3D11Device* aDevice);
  virtual ~MLGDeviceD3D11();

  bool Initialize() override;

  void StartDiagnostics(uint32_t aInvalidPixels) override;
  void EndDiagnostics() override;
  void GetDiagnostics(GPUStats* aStats) override;

  MLGDeviceD3D11* AsD3D11() override { return this; }
  TextureFactoryIdentifier GetTextureFactoryIdentifier(
      widget::CompositorWidget* aWidget) const override;

  RefPtr<MLGSwapChain> CreateSwapChainForWidget(
      widget::CompositorWidget* aWidget) override;

  int32_t GetMaxTextureSize() const override;
  LayersBackend GetLayersBackend() const override;

  void EndFrame() override;

  bool Map(MLGResource* aResource, MLGMapType aType,
           MLGMappedResource* aMap) override;
  void Unmap(MLGResource* aResource) override;
  void UpdatePartialResource(MLGResource* aResource, const gfx::IntRect* aRect,
                             void* aData, uint32_t aStride) override;
  void CopyTexture(MLGTexture* aDest, const gfx::IntPoint& aTarget,
                   MLGTexture* aSource, const gfx::IntRect& aRect) override;

  RefPtr<DataTextureSource> CreateDataTextureSource(
      TextureFlags aFlags) override;

  void SetRenderTarget(MLGRenderTarget* aRT) override;
  MLGRenderTarget* GetRenderTarget() override;
  void SetViewport(const gfx::IntRect& aViewport) override;
  void SetScissorRect(const Maybe<gfx::IntRect>& aScissorRect) override;
  void SetVertexShader(VertexShaderID aVertexShader) override;
  void SetPixelShader(PixelShaderID aPixelShader) override;
  void SetSamplerMode(uint32_t aIndex, SamplerMode aSamplerMode) override;
  void SetBlendState(MLGBlendState aBlendState) override;
  void SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride,
                       uint32_t aOffset) override;
  void SetPSTextures(uint32_t aSlot, uint32_t aNumTextures,
                     TextureSource* const* aTextures) override;
  void SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) override;
  void SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) override;
  void SetPrimitiveTopology(MLGPrimitiveTopology aTopology) override;
  void SetDepthTestMode(MLGDepthTestMode aMode) override;

  void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override;
  void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override;
  void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer,
                           uint32_t aFirstConstant,
                           uint32_t aNumConstants) override;
  void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer,
                           uint32_t aFirstConstant,
                           uint32_t aNumConstants) override;

  RefPtr<MLGBuffer> CreateBuffer(MLGBufferType aType, uint32_t aSize,
                                 MLGUsage aUsage,
                                 const void* aInitialData) override;

  RefPtr<MLGRenderTarget> CreateRenderTarget(
      const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) override;

  RefPtr<MLGTexture> CreateTexture(const gfx::IntSize& aSize,
                                   gfx::SurfaceFormat aFormat, MLGUsage aUsage,
                                   MLGTextureFlags aFlags) override;

  RefPtr<MLGTexture> CreateTexture(TextureSource* aSource) override;

  void Clear(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor) override;
  void ClearDepthBuffer(MLGRenderTarget* aRT) override;
  void ClearView(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor,
                 const gfx::IntRect* aRects, size_t aNumRects) override;
  void Draw(uint32_t aVertexCount, uint32_t aOffset) override;
  void DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount,
                     uint32_t aVertexOffset, uint32_t aInstanceOffset) override;
  void Flush() override;

  // This is exposed for TextureSourceProvider.
  ID3D11Device* GetD3D11Device() const { return mDevice; }

  bool Synchronize() override;
  void UnlockAllTextures() override;

  void InsertPresentWaitQuery();
  void WaitForPreviousPresentQuery();
  void HandleDeviceReset(const char* aWhere);

 private:
  bool InitSyncObject();

  void MaybeLockTexture(ID3D11Texture2D* aTexture);

  bool InitPixelShader(PixelShaderID aShaderID);
  bool InitVertexShader(VertexShaderID aShaderID);
  bool InitInputLayout(D3D11_INPUT_ELEMENT_DESC* aDesc, size_t aNumElements,
                       const ShaderBytes& aCode, VertexShaderID aShaderID);
  bool InitRasterizerStates();
  bool InitSamplerStates();
  bool InitBlendStates();
  bool InitDepthStencilState();
  bool VerifyConstantBufferOffsetting() override;

  void SetInputLayout(ID3D11InputLayout* aLayout);
  void SetVertexShader(ID3D11VertexShader* aShader);

  // Resolve a TextureSource to an ID3D11ShaderResourceView, locking the
  // texture if needed. The lock is released at the end of the frame.
  ID3D11ShaderResourceView* ResolveTextureSourceForShader(
      TextureSource* aSource);

 private:
  RefPtr<ID3D11Device> mDevice;
  RefPtr<ID3D11DeviceContext> mCtx;
  RefPtr<ID3D11DeviceContext1> mCtx1;
  UniquePtr<DiagnosticsD3D11> mDiagnostics;

  typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders,
                          RefPtr<ID3D11PixelShader>>
      PixelShaderArray;
  typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
                          RefPtr<ID3D11VertexShader>>
      VertexShaderArray;
  typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
                          RefPtr<ID3D11InputLayout>>
      InputLayoutArray;
  typedef EnumeratedArray<SamplerMode, SamplerMode::MaxModes,
                          RefPtr<ID3D11SamplerState>>
      SamplerStateArray;
  typedef EnumeratedArray<MLGBlendState, MLGBlendState::MaxStates,
                          RefPtr<ID3D11BlendState>>
      BlendStateArray;
  typedef EnumeratedArray<MLGDepthTestMode, MLGDepthTestMode::MaxModes,
                          RefPtr<ID3D11DepthStencilState>>
      DepthStencilStateArray;

  PixelShaderArray mPixelShaders;
  VertexShaderArray mVertexShaders;
  InputLayoutArray mInputLayouts;
  SamplerStateArray mSamplerStates;
  BlendStateArray mBlendStates;
  DepthStencilStateArray mDepthStencilStates;
  RefPtr<ID3D11RasterizerState> mRasterizerStateNoScissor;
  RefPtr<ID3D11RasterizerState> mRasterizerStateScissor;

  RefPtr<SyncObjectHost> mSyncObject;

  RefPtr<MLGBuffer> mUnitQuadVB;
  RefPtr<MLGBuffer> mUnitTriangleVB;
  RefPtr<ID3D11VertexShader> mCurrentVertexShader;
  RefPtr<ID3D11InputLayout> mCurrentInputLayout;
  RefPtr<ID3D11PixelShader> mCurrentPixelShader;
  RefPtr<ID3D11BlendState> mCurrentBlendState;

  RefPtr<ID3D11Query> mWaitForPresentQuery;
  RefPtr<ID3D11Query> mNextWaitForPresentQuery;

  nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockedTextures;
  nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockAttemptedTextures;

  typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders,
                          const ShaderBytes*>
      LazyPixelShaderArray;
  LazyPixelShaderArray mLazyPixelShaders;

  typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
                          const ShaderBytes*>
      LazyVertexShaderArray;
  LazyVertexShaderArray mLazyVertexShaders;

  bool mScissored;
};

}  // namespace layers
}  // namespace mozilla

struct ShaderBytes;

#endif  // mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h