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