• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // RendererD3D.h: Defines a back-end specific class for the DirectX renderer.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
10 #define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
11 
12 #include <array>
13 
14 #include "common/Color.h"
15 #include "common/MemoryBuffer.h"
16 #include "common/debug.h"
17 #include "libANGLE/Device.h"
18 #include "libANGLE/State.h"
19 #include "libANGLE/Version.h"
20 #include "libANGLE/angletypes.h"
21 #include "libANGLE/formatutils.h"
22 #include "libANGLE/renderer/d3d/VertexDataManager.h"
23 #include "libANGLE/renderer/d3d/formatutilsD3D.h"
24 #include "libANGLE/renderer/renderer_utils.h"
25 #include "libANGLE/renderer/serial_utils.h"
26 #include "platform/FeaturesD3D.h"
27 
28 namespace egl
29 {
30 class ConfigSet;
31 }
32 
33 namespace gl
34 {
35 class ErrorSet;
36 class FramebufferState;
37 class InfoLog;
38 class Texture;
39 struct LinkedVarying;
40 }  // namespace gl
41 
42 namespace rx
43 {
44 class ContextImpl;
45 struct D3DUniform;
46 struct D3DVarying;
47 class DeviceD3D;
48 class EGLImageD3D;
49 class FramebufferImpl;
50 class ImageD3D;
51 class IndexBuffer;
52 class NativeWindowD3D;
53 class ProgramD3D;
54 class RenderTargetD3D;
55 class ShaderExecutableD3D;
56 class SwapChainD3D;
57 class TextureStorage;
58 struct TranslatedIndexData;
59 class UniformStorageD3D;
60 class VertexBuffer;
61 
62 struct DeviceIdentifier
63 {
64     UINT VendorId;
65     UINT DeviceId;
66     UINT SubSysId;
67     UINT Revision;
68     UINT FeatureLevel;
69 };
70 
71 enum RendererClass
72 {
73     RENDERER_D3D11,
74     RENDERER_D3D9
75 };
76 
77 // A d3d::Context wraps error handling.
78 namespace d3d
79 {
80 class Context : angle::NonCopyable
81 {
82   public:
Context()83     Context() {}
~Context()84     virtual ~Context() {}
85 
86     virtual void handleResult(HRESULT hr,
87                               const char *message,
88                               const char *file,
89                               const char *function,
90                               unsigned int line) = 0;
91 };
92 }  // namespace d3d
93 
94 // ANGLE_TRY for HRESULT errors.
95 #define ANGLE_TRY_HR(CONTEXT, EXPR, MESSAGE)                                                     \
96     do                                                                                           \
97     {                                                                                            \
98         auto ANGLE_LOCAL_VAR = (EXPR);                                                           \
99         if (ANGLE_UNLIKELY(FAILED(ANGLE_LOCAL_VAR)))                                             \
100         {                                                                                        \
101             CONTEXT->handleResult(ANGLE_LOCAL_VAR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
102             return angle::Result::Stop;                                                          \
103         }                                                                                        \
104     } while (0)
105 
106 #define ANGLE_CHECK_HR(CONTEXT, EXPR, MESSAGE, ERROR)                                  \
107     do                                                                                 \
108     {                                                                                  \
109         if (ANGLE_UNLIKELY(!(EXPR)))                                                   \
110         {                                                                              \
111             CONTEXT->handleResult(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
112             return angle::Result::Stop;                                                \
113         }                                                                              \
114     } while (0)
115 
116 #define ANGLE_HR_UNREACHABLE(context) \
117     UNREACHABLE();                    \
118     ANGLE_CHECK_HR(context, false, "Unreachble code reached.", E_FAIL)
119 
120 // Check if the device is lost every 10 failures to get the query data
121 constexpr unsigned int kPollingD3DDeviceLostCheckFrequency = 10;
122 
123 // Useful for unit testing
124 class BufferFactoryD3D : angle::NonCopyable
125 {
126   public:
BufferFactoryD3D()127     BufferFactoryD3D() {}
~BufferFactoryD3D()128     virtual ~BufferFactoryD3D() {}
129 
130     virtual VertexBuffer *createVertexBuffer() = 0;
131     virtual IndexBuffer *createIndexBuffer()   = 0;
132 
133     // TODO(jmadill): add VertexFormatCaps
134     virtual VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const = 0;
135     virtual GLenum getVertexComponentType(angle::FormatID vertexFormatID) const                = 0;
136 
137     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
138     // function.
139     virtual angle::Result getVertexSpaceRequired(const gl::Context *context,
140                                                  const gl::VertexAttribute &attrib,
141                                                  const gl::VertexBinding &binding,
142                                                  size_t count,
143                                                  GLsizei instances,
144                                                  unsigned int *bytesRequiredOut) const = 0;
145 };
146 
147 using AttribIndexArray = gl::AttribArray<int>;
148 
149 class RendererD3D : public BufferFactoryD3D
150 {
151   public:
152     explicit RendererD3D(egl::Display *display);
153     ~RendererD3D() override;
154 
155     virtual egl::Error initialize() = 0;
156 
157     virtual egl::ConfigSet generateConfigs()                                            = 0;
158     virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0;
159 
160     virtual ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) = 0;
161 
162     std::string getVendorString() const;
163 
164     virtual int getMinorShaderModel() const          = 0;
165     virtual std::string getShaderModelSuffix() const = 0;
166 
167     // Direct3D Specific methods
168     virtual DeviceIdentifier getAdapterIdentifier() const = 0;
169 
170     virtual bool isValidNativeWindow(EGLNativeWindowType window) const                  = 0;
171     virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
172                                                 const egl::Config *config,
173                                                 const egl::AttributeMap &attribs) const = 0;
174 
175     virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
176                                           HANDLE shareHandle,
177                                           IUnknown *d3dTexture,
178                                           GLenum backBufferFormat,
179                                           GLenum depthBufferFormat,
180                                           EGLint orientation,
181                                           EGLint samples)                          = 0;
182     virtual egl::Error getD3DTextureInfo(const egl::Config *configuration,
183                                          IUnknown *d3dTexture,
184                                          const egl::AttributeMap &attribs,
185                                          EGLint *width,
186                                          EGLint *height,
187                                          GLsizei *samples,
188                                          gl::Format *glFormat,
189                                          const angle::Format **angleFormat) const  = 0;
190     virtual egl::Error validateShareHandle(const egl::Config *config,
191                                            HANDLE shareHandle,
192                                            const egl::AttributeMap &attribs) const = 0;
193 
194     virtual int getMajorShaderModel() const = 0;
195 
196     const angle::FeaturesD3D &getFeatures() const;
197 
198     // Pixel operations
199     virtual angle::Result copyImage2D(const gl::Context *context,
200                                       const gl::Framebuffer *framebuffer,
201                                       const gl::Rectangle &sourceRect,
202                                       GLenum destFormat,
203                                       const gl::Offset &destOffset,
204                                       TextureStorage *storage,
205                                       GLint level)      = 0;
206     virtual angle::Result copyImageCube(const gl::Context *context,
207                                         const gl::Framebuffer *framebuffer,
208                                         const gl::Rectangle &sourceRect,
209                                         GLenum destFormat,
210                                         const gl::Offset &destOffset,
211                                         TextureStorage *storage,
212                                         gl::TextureTarget target,
213                                         GLint level)    = 0;
214     virtual angle::Result copyImage3D(const gl::Context *context,
215                                       const gl::Framebuffer *framebuffer,
216                                       const gl::Rectangle &sourceRect,
217                                       GLenum destFormat,
218                                       const gl::Offset &destOffset,
219                                       TextureStorage *storage,
220                                       GLint level)      = 0;
221     virtual angle::Result copyImage2DArray(const gl::Context *context,
222                                            const gl::Framebuffer *framebuffer,
223                                            const gl::Rectangle &sourceRect,
224                                            GLenum destFormat,
225                                            const gl::Offset &destOffset,
226                                            TextureStorage *storage,
227                                            GLint level) = 0;
228 
229     virtual angle::Result copyTexture(const gl::Context *context,
230                                       const gl::Texture *source,
231                                       GLint sourceLevel,
232                                       gl::TextureTarget srcTarget,
233                                       const gl::Box &sourceBox,
234                                       GLenum destFormat,
235                                       GLenum destType,
236                                       const gl::Offset &destOffset,
237                                       TextureStorage *storage,
238                                       gl::TextureTarget destTarget,
239                                       GLint destLevel,
240                                       bool unpackFlipY,
241                                       bool unpackPremultiplyAlpha,
242                                       bool unpackUnmultiplyAlpha) = 0;
243     virtual angle::Result copyCompressedTexture(const gl::Context *context,
244                                                 const gl::Texture *source,
245                                                 GLint sourceLevel,
246                                                 TextureStorage *storage,
247                                                 GLint destLevel)  = 0;
248 
249     // RenderTarget creation
250     virtual angle::Result createRenderTarget(const gl::Context *context,
251                                              int width,
252                                              int height,
253                                              GLenum format,
254                                              GLsizei samples,
255                                              RenderTargetD3D **outRT)     = 0;
256     virtual angle::Result createRenderTargetCopy(const gl::Context *context,
257                                                  RenderTargetD3D *source,
258                                                  RenderTargetD3D **outRT) = 0;
259 
260     // Shader operations
261     virtual angle::Result loadExecutable(d3d::Context *context,
262                                          const uint8_t *function,
263                                          size_t length,
264                                          gl::ShaderType type,
265                                          const std::vector<D3DVarying> &streamOutVaryings,
266                                          bool separatedOutputBuffers,
267                                          ShaderExecutableD3D **outExecutable)      = 0;
268     virtual angle::Result compileToExecutable(d3d::Context *context,
269                                               gl::InfoLog &infoLog,
270                                               const std::string &shaderHLSL,
271                                               gl::ShaderType type,
272                                               const std::vector<D3DVarying> &streamOutVaryings,
273                                               bool separatedOutputBuffers,
274                                               const angle::CompilerWorkaroundsD3D &workarounds,
275                                               ShaderExecutableD3D **outExectuable) = 0;
276     virtual angle::Result ensureHLSLCompilerInitialized(d3d::Context *context)     = 0;
277 
278     virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0;
279 
280     // Image operations
281     virtual ImageD3D *createImage() = 0;
282     virtual ExternalImageSiblingImpl *createExternalImageSibling(
283         const gl::Context *context,
284         EGLenum target,
285         EGLClientBuffer buffer,
286         const egl::AttributeMap &attribs)                                                  = 0;
287     virtual angle::Result generateMipmap(const gl::Context *context,
288                                          ImageD3D *dest,
289                                          ImageD3D *source)                                 = 0;
290     virtual angle::Result generateMipmapUsingD3D(const gl::Context *context,
291                                                  TextureStorage *storage,
292                                                  const gl::TextureState &textureState)     = 0;
293     virtual angle::Result copyImage(const gl::Context *context,
294                                     ImageD3D *dest,
295                                     ImageD3D *source,
296                                     const gl::Box &sourceBox,
297                                     const gl::Offset &destOffset,
298                                     bool unpackFlipY,
299                                     bool unpackPremultiplyAlpha,
300                                     bool unpackUnmultiplyAlpha)                            = 0;
301     virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain)                = 0;
302     virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
303                                                          RenderTargetD3D *renderTargetD3D) = 0;
304     virtual TextureStorage *createTextureStorageExternal(
305         egl::Stream *stream,
306         const egl::Stream::GLTextureDescription &desc)                                        = 0;
307     virtual TextureStorage *createTextureStorage2D(GLenum internalformat,
308                                                    bool renderTarget,
309                                                    GLsizei width,
310                                                    GLsizei height,
311                                                    int levels,
312                                                    bool hintLevelZeroOnly)                    = 0;
313     virtual TextureStorage *createTextureStorageCube(GLenum internalformat,
314                                                      bool renderTarget,
315                                                      int size,
316                                                      int levels,
317                                                      bool hintLevelZeroOnly)                  = 0;
318     virtual TextureStorage *createTextureStorage3D(GLenum internalformat,
319                                                    bool renderTarget,
320                                                    GLsizei width,
321                                                    GLsizei height,
322                                                    GLsizei depth,
323                                                    int levels)                                = 0;
324     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat,
325                                                         bool renderTarget,
326                                                         GLsizei width,
327                                                         GLsizei height,
328                                                         GLsizei depth,
329                                                         int levels)                           = 0;
330     virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
331                                                               GLsizei width,
332                                                               GLsizei height,
333                                                               int levels,
334                                                               int samples,
335                                                               bool fixedSampleLocations)      = 0;
336     virtual TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
337                                                                    GLsizei width,
338                                                                    GLsizei height,
339                                                                    GLsizei depth,
340                                                                    int levels,
341                                                                    int samples,
342                                                                    bool fixedSampleLocations) = 0;
343 
344     // Buffer-to-texture and Texture-to-buffer copies
345     virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
346     virtual angle::Result fastCopyBufferToTexture(const gl::Context *context,
347                                                   const gl::PixelUnpackState &unpack,
348                                                   gl::Buffer *unpackBuffer,
349                                                   unsigned int offset,
350                                                   RenderTargetD3D *destRenderTarget,
351                                                   GLenum destinationFormat,
352                                                   GLenum sourcePixelsType,
353                                                   const gl::Box &destArea)    = 0;
354 
355     // Device lost
356     gl::GraphicsResetStatus getResetStatus();
357     void notifyDeviceLost();
358     virtual bool resetDevice()          = 0;
359     virtual bool testDeviceLost()       = 0;
360     virtual bool testDeviceResettable() = 0;
361 
362     virtual RendererClass getRendererClass() const = 0;
363     virtual void *getD3DDevice()                   = 0;
364 
365     void setGPUDisjoint();
366 
367     GLint getGPUDisjoint();
368     GLint64 getTimestamp();
369 
370     virtual angle::Result clearRenderTarget(const gl::Context *context,
371                                             RenderTargetD3D *renderTarget,
372                                             const gl::ColorF &clearColorValue,
373                                             const float clearDepthValue,
374                                             const unsigned int clearStencilValue) = 0;
375 
376     virtual DeviceImpl *createEGLDevice() = 0;
377 
presentPathFastEnabled()378     bool presentPathFastEnabled() const { return mPresentPathFastEnabled; }
379 
380     // Stream creation
381     virtual StreamProducerImpl *createStreamProducerD3DTexture(
382         egl::Stream::ConsumerType consumerType,
383         const egl::AttributeMap &attribs) = 0;
384 
385     const gl::Caps &getNativeCaps() const;
386     const gl::TextureCapsMap &getNativeTextureCaps() const;
387     const gl::Extensions &getNativeExtensions() const;
388     const gl::Limitations &getNativeLimitations() const;
389 
390     // Necessary hack for default framebuffers in D3D.
391     virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
392 
393     virtual gl::Version getMaxSupportedESVersion() const  = 0;
394     virtual gl::Version getMaxConformantESVersion() const = 0;
395 
396     angle::Result initRenderTarget(const gl::Context *context, RenderTargetD3D *renderTarget);
397 
398     virtual angle::Result getIncompleteTexture(const gl::Context *context,
399                                                gl::TextureType type,
400                                                gl::Texture **textureOut) = 0;
401 
402     Serial generateSerial();
403 
404     virtual bool canSelectViewInVertexShader() const = 0;
405 
406   protected:
407     virtual bool getLUID(LUID *adapterLuid) const                    = 0;
408     virtual void generateCaps(gl::Caps *outCaps,
409                               gl::TextureCapsMap *outTextureCaps,
410                               gl::Extensions *outExtensions,
411                               gl::Limitations *outLimitations) const = 0;
412 
413     bool skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode);
414 
415     egl::Display *mDisplay;
416 
417     bool mPresentPathFastEnabled;
418 
419   private:
420     void ensureCapsInitialized() const;
421 
422     virtual void initializeFeatures(angle::FeaturesD3D *features) const = 0;
423 
424     mutable bool mCapsInitialized;
425     mutable gl::Caps mNativeCaps;
426     mutable gl::TextureCapsMap mNativeTextureCaps;
427     mutable gl::Extensions mNativeExtensions;
428     mutable gl::Limitations mNativeLimitations;
429 
430     mutable bool mFeaturesInitialized;
431     mutable angle::FeaturesD3D mFeatures;
432 
433     bool mDisjoint;
434     bool mDeviceLost;
435 
436     SerialFactory mSerialFactory;
437 };
438 
439 unsigned int GetBlendSampleMask(const gl::State &glState, int samples);
440 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode);
441 GLenum DefaultGLErrorCode(HRESULT hr);
442 }  // namespace rx
443 
444 #endif  // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
445