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