• 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                                                  GLuint baseInstance,
145                                                  unsigned int *bytesRequiredOut) const = 0;
146 };
147 
148 using AttribIndexArray = gl::AttribArray<int>;
149 
150 class RendererD3D : public BufferFactoryD3D
151 {
152   public:
153     explicit RendererD3D(egl::Display *display);
154     ~RendererD3D() override;
155 
156     virtual egl::Error initialize() = 0;
157 
158     virtual egl::ConfigSet generateConfigs()                                            = 0;
159     virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0;
160 
161     virtual ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) = 0;
162 
163     virtual std::string getRendererDescription() const = 0;
164     virtual std::string getVendorString() const        = 0;
165     virtual std::string getVersionString() const       = 0;
166 
167     virtual int getMinorShaderModel() const          = 0;
168     virtual std::string getShaderModelSuffix() const = 0;
169 
170     // Direct3D Specific methods
171     virtual DeviceIdentifier getAdapterIdentifier() const = 0;
172 
173     virtual bool isValidNativeWindow(EGLNativeWindowType window) const                  = 0;
174     virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
175                                                 const egl::Config *config,
176                                                 const egl::AttributeMap &attribs) const = 0;
177 
178     virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
179                                           HANDLE shareHandle,
180                                           IUnknown *d3dTexture,
181                                           GLenum backBufferFormat,
182                                           GLenum depthBufferFormat,
183                                           EGLint orientation,
184                                           EGLint samples)                          = 0;
185     virtual egl::Error getD3DTextureInfo(const egl::Config *configuration,
186                                          IUnknown *d3dTexture,
187                                          const egl::AttributeMap &attribs,
188                                          EGLint *width,
189                                          EGLint *height,
190                                          GLsizei *samples,
191                                          gl::Format *glFormat,
192                                          const angle::Format **angleFormat,
193                                          UINT *arraySlice) const                   = 0;
194     virtual egl::Error validateShareHandle(const egl::Config *config,
195                                            HANDLE shareHandle,
196                                            const egl::AttributeMap &attribs) const = 0;
197 
198     virtual int getMajorShaderModel() const = 0;
199 
200     virtual void setGlobalDebugAnnotator() = 0;
201 
202     const angle::FeaturesD3D &getFeatures() const;
203 
204     // Pixel operations
205     virtual angle::Result copyImage2D(const gl::Context *context,
206                                       const gl::Framebuffer *framebuffer,
207                                       const gl::Rectangle &sourceRect,
208                                       GLenum destFormat,
209                                       const gl::Offset &destOffset,
210                                       TextureStorage *storage,
211                                       GLint level)      = 0;
212     virtual angle::Result copyImageCube(const gl::Context *context,
213                                         const gl::Framebuffer *framebuffer,
214                                         const gl::Rectangle &sourceRect,
215                                         GLenum destFormat,
216                                         const gl::Offset &destOffset,
217                                         TextureStorage *storage,
218                                         gl::TextureTarget target,
219                                         GLint level)    = 0;
220     virtual angle::Result copyImage3D(const gl::Context *context,
221                                       const gl::Framebuffer *framebuffer,
222                                       const gl::Rectangle &sourceRect,
223                                       GLenum destFormat,
224                                       const gl::Offset &destOffset,
225                                       TextureStorage *storage,
226                                       GLint level)      = 0;
227     virtual angle::Result copyImage2DArray(const gl::Context *context,
228                                            const gl::Framebuffer *framebuffer,
229                                            const gl::Rectangle &sourceRect,
230                                            GLenum destFormat,
231                                            const gl::Offset &destOffset,
232                                            TextureStorage *storage,
233                                            GLint level) = 0;
234 
235     virtual angle::Result copyTexture(const gl::Context *context,
236                                       const gl::Texture *source,
237                                       GLint sourceLevel,
238                                       gl::TextureTarget srcTarget,
239                                       const gl::Box &sourceBox,
240                                       GLenum destFormat,
241                                       GLenum destType,
242                                       const gl::Offset &destOffset,
243                                       TextureStorage *storage,
244                                       gl::TextureTarget destTarget,
245                                       GLint destLevel,
246                                       bool unpackFlipY,
247                                       bool unpackPremultiplyAlpha,
248                                       bool unpackUnmultiplyAlpha) = 0;
249     virtual angle::Result copyCompressedTexture(const gl::Context *context,
250                                                 const gl::Texture *source,
251                                                 GLint sourceLevel,
252                                                 TextureStorage *storage,
253                                                 GLint destLevel)  = 0;
254 
255     // RenderTarget creation
256     virtual angle::Result createRenderTarget(const gl::Context *context,
257                                              int width,
258                                              int height,
259                                              GLenum format,
260                                              GLsizei samples,
261                                              RenderTargetD3D **outRT)     = 0;
262     virtual angle::Result createRenderTargetCopy(const gl::Context *context,
263                                                  RenderTargetD3D *source,
264                                                  RenderTargetD3D **outRT) = 0;
265 
266     // Shader operations
267     virtual angle::Result loadExecutable(d3d::Context *context,
268                                          const uint8_t *function,
269                                          size_t length,
270                                          gl::ShaderType type,
271                                          const std::vector<D3DVarying> &streamOutVaryings,
272                                          bool separatedOutputBuffers,
273                                          ShaderExecutableD3D **outExecutable)      = 0;
274     virtual angle::Result compileToExecutable(d3d::Context *context,
275                                               gl::InfoLog &infoLog,
276                                               const std::string &shaderHLSL,
277                                               gl::ShaderType type,
278                                               const std::vector<D3DVarying> &streamOutVaryings,
279                                               bool separatedOutputBuffers,
280                                               const angle::CompilerWorkaroundsD3D &workarounds,
281                                               ShaderExecutableD3D **outExectuable) = 0;
282     virtual angle::Result ensureHLSLCompilerInitialized(d3d::Context *context)     = 0;
283 
284     virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0;
285 
286     // Image operations
287     virtual ImageD3D *createImage() = 0;
288     virtual ExternalImageSiblingImpl *createExternalImageSibling(
289         const gl::Context *context,
290         EGLenum target,
291         EGLClientBuffer buffer,
292         const egl::AttributeMap &attribs)                                              = 0;
293     virtual angle::Result generateMipmap(const gl::Context *context,
294                                          ImageD3D *dest,
295                                          ImageD3D *source)                             = 0;
296     virtual angle::Result generateMipmapUsingD3D(const gl::Context *context,
297                                                  TextureStorage *storage,
298                                                  const gl::TextureState &textureState) = 0;
299     virtual angle::Result copyImage(const gl::Context *context,
300                                     ImageD3D *dest,
301                                     ImageD3D *source,
302                                     const gl::Box &sourceBox,
303                                     const gl::Offset &destOffset,
304                                     bool unpackFlipY,
305                                     bool unpackPremultiplyAlpha,
306                                     bool unpackUnmultiplyAlpha)                        = 0;
307     virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain,
308                                                    const std::string &label)           = 0;
309     virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
310                                                          RenderTargetD3D *renderTargetD3D,
311                                                          const std::string &label)     = 0;
312     virtual TextureStorage *createTextureStorageExternal(
313         egl::Stream *stream,
314         const egl::Stream::GLTextureDescription &desc,
315         const std::string &label)                                                            = 0;
316     virtual TextureStorage *createTextureStorage2D(GLenum internalformat,
317                                                    bool renderTarget,
318                                                    GLsizei width,
319                                                    GLsizei height,
320                                                    int levels,
321                                                    const std::string &label,
322                                                    bool hintLevelZeroOnly)                   = 0;
323     virtual TextureStorage *createTextureStorageCube(GLenum internalformat,
324                                                      bool renderTarget,
325                                                      int size,
326                                                      int levels,
327                                                      bool hintLevelZeroOnly,
328                                                      const std::string &label)               = 0;
329     virtual TextureStorage *createTextureStorage3D(GLenum internalformat,
330                                                    bool renderTarget,
331                                                    GLsizei width,
332                                                    GLsizei height,
333                                                    GLsizei depth,
334                                                    int levels,
335                                                    const std::string &label)                 = 0;
336     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat,
337                                                         bool renderTarget,
338                                                         GLsizei width,
339                                                         GLsizei height,
340                                                         GLsizei depth,
341                                                         int levels,
342                                                         const std::string &label)            = 0;
343     virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
344                                                               GLsizei width,
345                                                               GLsizei height,
346                                                               int levels,
347                                                               int samples,
348                                                               bool fixedSampleLocations,
349                                                               const std::string &label)      = 0;
350     virtual TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
351                                                                    GLsizei width,
352                                                                    GLsizei height,
353                                                                    GLsizei depth,
354                                                                    int levels,
355                                                                    int samples,
356                                                                    bool fixedSampleLocations,
357                                                                    const std::string &label) = 0;
358 
359     // Buffer-to-texture and Texture-to-buffer copies
360     virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
361     virtual angle::Result fastCopyBufferToTexture(const gl::Context *context,
362                                                   const gl::PixelUnpackState &unpack,
363                                                   gl::Buffer *unpackBuffer,
364                                                   unsigned int offset,
365                                                   RenderTargetD3D *destRenderTarget,
366                                                   GLenum destinationFormat,
367                                                   GLenum sourcePixelsType,
368                                                   const gl::Box &destArea)    = 0;
369 
370     // Device lost
371     gl::GraphicsResetStatus getResetStatus();
372     void notifyDeviceLost();
373     virtual bool resetDevice()          = 0;
374     virtual bool testDeviceLost()       = 0;
375     virtual bool testDeviceResettable() = 0;
376 
377     virtual RendererClass getRendererClass() const = 0;
378     virtual void *getD3DDevice()                   = 0;
379 
380     void setGPUDisjoint();
381 
382     GLint getGPUDisjoint();
383     GLint64 getTimestamp();
384 
385     virtual angle::Result clearRenderTarget(const gl::Context *context,
386                                             RenderTargetD3D *renderTarget,
387                                             const gl::ColorF &clearColorValue,
388                                             const float clearDepthValue,
389                                             const unsigned int clearStencilValue) = 0;
390 
391     virtual DeviceImpl *createEGLDevice() = 0;
392 
presentPathFastEnabled()393     bool presentPathFastEnabled() const { return mPresentPathFastEnabled; }
394 
395     // Stream creation
396     virtual StreamProducerImpl *createStreamProducerD3DTexture(
397         egl::Stream::ConsumerType consumerType,
398         const egl::AttributeMap &attribs) = 0;
399 
400     const gl::Caps &getNativeCaps() const;
401     const gl::TextureCapsMap &getNativeTextureCaps() const;
402     const gl::Extensions &getNativeExtensions() const;
403     const gl::Limitations &getNativeLimitations() const;
404 
405     // Necessary hack for default framebuffers in D3D.
406     virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
407 
408     virtual gl::Version getMaxSupportedESVersion() const  = 0;
409     virtual gl::Version getMaxConformantESVersion() const = 0;
410 
411     angle::Result initRenderTarget(const gl::Context *context, RenderTargetD3D *renderTarget);
412 
413     virtual angle::Result getIncompleteTexture(const gl::Context *context,
414                                                gl::TextureType type,
415                                                gl::Texture **textureOut) = 0;
416 
417     Serial generateSerial();
418 
419     virtual bool canSelectViewInVertexShader() const = 0;
420 
421   protected:
422     virtual bool getLUID(LUID *adapterLuid) const                    = 0;
423     virtual void generateCaps(gl::Caps *outCaps,
424                               gl::TextureCapsMap *outTextureCaps,
425                               gl::Extensions *outExtensions,
426                               gl::Limitations *outLimitations) const = 0;
427 
428     bool skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode);
429 
430     egl::Display *mDisplay;
431 
432     bool mPresentPathFastEnabled;
433 
434   private:
435     void ensureCapsInitialized() const;
436 
437     virtual void initializeFeatures(angle::FeaturesD3D *features) const = 0;
438 
439     mutable bool mCapsInitialized;
440     mutable gl::Caps mNativeCaps;
441     mutable gl::TextureCapsMap mNativeTextureCaps;
442     mutable gl::Extensions mNativeExtensions;
443     mutable gl::Limitations mNativeLimitations;
444 
445     mutable bool mFeaturesInitialized;
446     mutable angle::FeaturesD3D mFeatures;
447 
448     bool mDisjoint;
449     bool mDeviceLost;
450 
451     SerialFactory mSerialFactory;
452 };
453 
454 unsigned int GetBlendSampleMask(const gl::State &glState, int samples);
455 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode);
456 GLenum DefaultGLErrorCode(HRESULT hr);
457 
458 // Define stubs so we don't need to include D3D9/D3D11 headers directly.
459 RendererD3D *CreateRenderer11(egl::Display *display);
460 RendererD3D *CreateRenderer9(egl::Display *display);
461 
462 }  // namespace rx
463 
464 #endif  // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
465