• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2012 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 // Renderer9.h: Defines a back-end specific class for the D3D9 renderer.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
10 #define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
11 
12 #include "common/angleutils.h"
13 #include "common/mathutil.h"
14 #include "libANGLE/renderer/d3d/HLSLCompiler.h"
15 #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
16 #include "libANGLE/renderer/d3d/RendererD3D.h"
17 #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
18 #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h"
19 #include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
20 #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
21 #include "libANGLE/renderer/driver_utils.h"
22 
23 namespace gl
24 {
25 class FramebufferAttachment;
26 }
27 
28 namespace egl
29 {
30 class AttributeMap;
31 }
32 
33 namespace rx
34 {
35 class Blit9;
36 class Context9;
37 class IndexDataManager;
38 class ProgramD3D;
39 class RenderTarget9;
40 class StreamingIndexBufferInterface;
41 class StaticIndexBufferInterface;
42 class VertexDataManager;
43 struct ClearParameters;
44 struct D3DUniform;
45 struct TranslatedAttribute;
46 
47 enum D3D9InitError
48 {
49     D3D9_INIT_SUCCESS = 0,
50     // Failed to load the D3D or ANGLE compiler
51     D3D9_INIT_COMPILER_ERROR,
52     // Failed to load a necessary DLL
53     D3D9_INIT_MISSING_DEP,
54     // Device creation error
55     D3D9_INIT_CREATE_DEVICE_ERROR,
56     // System does not meet minimum shader spec
57     D3D9_INIT_UNSUPPORTED_VERSION,
58     // System does not support stretchrect from textures
59     D3D9_INIT_UNSUPPORTED_STRETCHRECT,
60     // A call returned out of memory or device lost
61     D3D9_INIT_OUT_OF_MEMORY,
62     // Other unspecified error
63     D3D9_INIT_OTHER_ERROR,
64     NUM_D3D9_INIT_ERRORS
65 };
66 
67 class Renderer9 : public RendererD3D
68 {
69   public:
70     explicit Renderer9(egl::Display *display);
71     ~Renderer9() override;
72 
73     egl::Error initialize() override;
74     bool resetDevice() override;
75 
76     egl::ConfigSet generateConfigs() override;
77     void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
78 
79     void startScene();
80     void endScene();
81 
82     angle::Result flush(const gl::Context *context);
83     angle::Result finish(const gl::Context *context);
84 
85     bool isValidNativeWindow(EGLNativeWindowType window) const override;
86     NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
87                                         const egl::Config *config,
88                                         const egl::AttributeMap &attribs) const override;
89 
90     SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
91                                   HANDLE shareHandle,
92                                   IUnknown *d3dTexture,
93                                   GLenum backBufferFormat,
94                                   GLenum depthBufferFormat,
95                                   EGLint orientation,
96                                   EGLint samples) override;
97     egl::Error getD3DTextureInfo(const egl::Config *configuration,
98                                  IUnknown *d3dTexture,
99                                  const egl::AttributeMap &attribs,
100                                  EGLint *width,
101                                  EGLint *height,
102                                  GLsizei *samples,
103                                  gl::Format *glFormat,
104                                  const angle::Format **angleFormat) const override;
105     egl::Error validateShareHandle(const egl::Config *config,
106                                    HANDLE shareHandle,
107                                    const egl::AttributeMap &attribs) const override;
108 
109     ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) override;
110 
111     angle::Result allocateEventQuery(const gl::Context *context, IDirect3DQuery9 **outQuery);
112     void freeEventQuery(IDirect3DQuery9 *query);
113 
114     // resource creation
115     angle::Result createVertexShader(d3d::Context *context,
116                                      const DWORD *function,
117                                      size_t length,
118                                      IDirect3DVertexShader9 **outShader);
119     angle::Result createPixelShader(d3d::Context *context,
120                                     const DWORD *function,
121                                     size_t length,
122                                     IDirect3DPixelShader9 **outShader);
123     HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
124     HRESULT createIndexBuffer(UINT Length,
125                               DWORD Usage,
126                               D3DFORMAT Format,
127                               IDirect3DIndexBuffer9 **ppIndexBuffer);
128     angle::Result setSamplerState(const gl::Context *context,
129                                   gl::ShaderType type,
130                                   int index,
131                                   gl::Texture *texture,
132                                   const gl::SamplerState &sampler);
133     angle::Result setTexture(const gl::Context *context,
134                              gl::ShaderType type,
135                              int index,
136                              gl::Texture *texture);
137 
138     angle::Result updateState(const gl::Context *context, gl::PrimitiveMode drawMode);
139 
140     void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
141     void setViewport(const gl::Rectangle &viewport,
142                      float zNear,
143                      float zFar,
144                      gl::PrimitiveMode drawMode,
145                      GLenum frontFace,
146                      bool ignoreViewport);
147 
148     angle::Result applyRenderTarget(const gl::Context *context,
149                                     const RenderTarget9 *colorRenderTarget,
150                                     const RenderTarget9 *depthStencilRenderTarget);
151     void applyUniforms(ProgramD3D *programD3D);
152     bool applyPrimitiveType(gl::PrimitiveMode primitiveType,
153                             GLsizei elementCount,
154                             bool usesPointSize);
155     angle::Result applyVertexBuffer(const gl::Context *context,
156                                     gl::PrimitiveMode mode,
157                                     GLint first,
158                                     GLsizei count,
159                                     GLsizei instances,
160                                     TranslatedIndexData *indexInfo);
161     angle::Result applyIndexBuffer(const gl::Context *context,
162                                    const void *indices,
163                                    GLsizei count,
164                                    gl::PrimitiveMode mode,
165                                    gl::DrawElementsType type,
166                                    TranslatedIndexData *indexInfo);
167 
168     void clear(const ClearParameters &clearParams,
169                const RenderTarget9 *colorRenderTarget,
170                const RenderTarget9 *depthStencilRenderTarget);
171 
172     void markAllStateDirty();
173 
174     // lost device
175     bool testDeviceLost() override;
176     bool testDeviceResettable() override;
177 
178     VendorID getVendorId() const;
179     std::string getRendererDescription() const;
180     DeviceIdentifier getAdapterIdentifier() const override;
181 
getDevice()182     IDirect3DDevice9 *getDevice() { return mDevice; }
183     void *getD3DDevice() override;
184 
185     unsigned int getReservedVertexUniformVectors() const;
186     unsigned int getReservedFragmentUniformVectors() const;
187 
188     bool getShareHandleSupport() const;
189 
190     int getMajorShaderModel() const override;
191     int getMinorShaderModel() const override;
192     std::string getShaderModelSuffix() const override;
193 
194     DWORD getCapsDeclTypes() const;
195 
196     // Pixel operations
197     angle::Result copyImage2D(const gl::Context *context,
198                               const gl::Framebuffer *framebuffer,
199                               const gl::Rectangle &sourceRect,
200                               GLenum destFormat,
201                               const gl::Offset &destOffset,
202                               TextureStorage *storage,
203                               GLint level) override;
204     angle::Result copyImageCube(const gl::Context *context,
205                                 const gl::Framebuffer *framebuffer,
206                                 const gl::Rectangle &sourceRect,
207                                 GLenum destFormat,
208                                 const gl::Offset &destOffset,
209                                 TextureStorage *storage,
210                                 gl::TextureTarget target,
211                                 GLint level) override;
212     angle::Result copyImage3D(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                               GLint level) override;
219     angle::Result copyImage2DArray(const gl::Context *context,
220                                    const gl::Framebuffer *framebuffer,
221                                    const gl::Rectangle &sourceRect,
222                                    GLenum destFormat,
223                                    const gl::Offset &destOffset,
224                                    TextureStorage *storage,
225                                    GLint level) override;
226 
227     angle::Result copyTexture(const gl::Context *context,
228                               const gl::Texture *source,
229                               GLint sourceLevel,
230                               gl::TextureTarget srcTarget,
231                               const gl::Box &sourceBox,
232                               GLenum destFormat,
233                               GLenum destType,
234                               const gl::Offset &destOffset,
235                               TextureStorage *storage,
236                               gl::TextureTarget destTarget,
237                               GLint destLevel,
238                               bool unpackFlipY,
239                               bool unpackPremultiplyAlpha,
240                               bool unpackUnmultiplyAlpha) override;
241     angle::Result copyCompressedTexture(const gl::Context *context,
242                                         const gl::Texture *source,
243                                         GLint sourceLevel,
244                                         TextureStorage *storage,
245                                         GLint destLevel) override;
246 
247     // RenderTarget creation
248     angle::Result createRenderTarget(const gl::Context *context,
249                                      int width,
250                                      int height,
251                                      GLenum format,
252                                      GLsizei samples,
253                                      RenderTargetD3D **outRT) override;
254     angle::Result createRenderTargetCopy(const gl::Context *context,
255                                          RenderTargetD3D *source,
256                                          RenderTargetD3D **outRT) override;
257 
258     // Shader operations
259     angle::Result loadExecutable(d3d::Context *context,
260                                  const uint8_t *function,
261                                  size_t length,
262                                  gl::ShaderType type,
263                                  const std::vector<D3DVarying> &streamOutVaryings,
264                                  bool separatedOutputBuffers,
265                                  ShaderExecutableD3D **outExecutable) override;
266     angle::Result compileToExecutable(d3d::Context *context,
267                                       gl::InfoLog &infoLog,
268                                       const std::string &shaderHLSL,
269                                       gl::ShaderType type,
270                                       const std::vector<D3DVarying> &streamOutVaryings,
271                                       bool separatedOutputBuffers,
272                                       const angle::CompilerWorkaroundsD3D &workarounds,
273                                       ShaderExecutableD3D **outExectuable) override;
274     angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) override;
275 
276     UniformStorageD3D *createUniformStorage(size_t storageSize) override;
277 
278     // Image operations
279     ImageD3D *createImage() override;
280     ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
281                                                          EGLenum target,
282                                                          EGLClientBuffer buffer,
283                                                          const egl::AttributeMap &attribs) override;
284     angle::Result generateMipmap(const gl::Context *context,
285                                  ImageD3D *dest,
286                                  ImageD3D *source) override;
287     angle::Result generateMipmapUsingD3D(const gl::Context *context,
288                                          TextureStorage *storage,
289                                          const gl::TextureState &textureState) override;
290     angle::Result copyImage(const gl::Context *context,
291                             ImageD3D *dest,
292                             ImageD3D *source,
293                             const gl::Box &sourceBox,
294                             const gl::Offset &destOffset,
295                             bool unpackFlipY,
296                             bool unpackPremultiplyAlpha,
297                             bool unpackUnmultiplyAlpha) override;
298     TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override;
299     TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
300                                                  RenderTargetD3D *renderTargetD3D) override;
301     TextureStorage *createTextureStorageExternal(
302         egl::Stream *stream,
303         const egl::Stream::GLTextureDescription &desc) override;
304     TextureStorage *createTextureStorage2D(GLenum internalformat,
305                                            bool renderTarget,
306                                            GLsizei width,
307                                            GLsizei height,
308                                            int levels,
309                                            bool hintLevelZeroOnly) override;
310     TextureStorage *createTextureStorageCube(GLenum internalformat,
311                                              bool renderTarget,
312                                              int size,
313                                              int levels,
314                                              bool hintLevelZeroOnly) override;
315     TextureStorage *createTextureStorage3D(GLenum internalformat,
316                                            bool renderTarget,
317                                            GLsizei width,
318                                            GLsizei height,
319                                            GLsizei depth,
320                                            int levels) override;
321     TextureStorage *createTextureStorage2DArray(GLenum internalformat,
322                                                 bool renderTarget,
323                                                 GLsizei width,
324                                                 GLsizei height,
325                                                 GLsizei depth,
326                                                 int levels) override;
327 
328     TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
329                                                       GLsizei width,
330                                                       GLsizei height,
331                                                       int levels,
332                                                       int samples,
333                                                       bool fixedSampleLocations) override;
334     TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
335                                                            GLsizei width,
336                                                            GLsizei height,
337                                                            GLsizei depth,
338                                                            int levels,
339                                                            int samples,
340                                                            bool fixedSampleLocations) override;
341 
342     // Buffer creation
343     VertexBuffer *createVertexBuffer() override;
344     IndexBuffer *createIndexBuffer() override;
345 
346     // Stream Creation
347     StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
348                                                        const egl::AttributeMap &attribs) override;
349 
350     // Buffer-to-texture and Texture-to-buffer copies
351     bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override;
352     angle::Result fastCopyBufferToTexture(const gl::Context *context,
353                                           const gl::PixelUnpackState &unpack,
354                                           gl::Buffer *unpackBuffer,
355                                           unsigned int offset,
356                                           RenderTargetD3D *destRenderTarget,
357                                           GLenum destinationFormat,
358                                           GLenum sourcePixelsType,
359                                           const gl::Box &destArea) override;
360 
361     // D3D9-renderer specific methods
362     angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
363 
364     D3DPOOL getTexturePool(DWORD usage) const;
365 
366     bool getLUID(LUID *adapterLuid) const override;
367     VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const override;
368     GLenum getVertexComponentType(angle::FormatID vertexFormatID) const override;
369 
370     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
371     // function.
372     angle::Result getVertexSpaceRequired(const gl::Context *context,
373                                          const gl::VertexAttribute &attrib,
374                                          const gl::VertexBinding &binding,
375                                          size_t count,
376                                          GLsizei instances,
377                                          unsigned int *bytesRequiredOut) const override;
378 
379     angle::Result copyToRenderTarget(const gl::Context *context,
380                                      IDirect3DSurface9 *dest,
381                                      IDirect3DSurface9 *source,
382                                      bool fromManaged);
383 
384     RendererClass getRendererClass() const override;
385 
getD3D9DeviceType()386     D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; }
387 
388     DeviceImpl *createEGLDevice() override;
389 
getStateManager()390     StateManager9 *getStateManager() { return &mStateManager; }
391 
392     angle::Result genericDrawArrays(const gl::Context *context,
393                                     gl::PrimitiveMode mode,
394                                     GLint first,
395                                     GLsizei count,
396                                     GLsizei instances);
397 
398     angle::Result genericDrawElements(const gl::Context *context,
399                                       gl::PrimitiveMode mode,
400                                       GLsizei count,
401                                       gl::DrawElementsType type,
402                                       const void *indices,
403                                       GLsizei instances);
404 
405     // Necessary hack for default framebuffers in D3D.
406     FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
407 
getAnnotator()408     DebugAnnotator9 *getAnnotator() { return &mAnnotator; }
409 
410     gl::Version getMaxSupportedESVersion() const override;
411     gl::Version getMaxConformantESVersion() const override;
412 
413     angle::Result clearRenderTarget(const gl::Context *context,
414                                     RenderTargetD3D *renderTarget,
415                                     const gl::ColorF &clearColorValue,
416                                     const float clearDepthValue,
417                                     const unsigned int clearStencilValue) override;
418 
419     bool canSelectViewInVertexShader() const override;
420 
421     angle::Result getIncompleteTexture(const gl::Context *context,
422                                        gl::TextureType type,
423                                        gl::Texture **textureOut) override;
424 
425     angle::Result ensureVertexDataManagerInitialized(const gl::Context *context);
426 
427   private:
428     angle::Result drawArraysImpl(const gl::Context *context,
429                                  gl::PrimitiveMode mode,
430                                  GLint startVertex,
431                                  GLsizei count,
432                                  GLsizei instances);
433     angle::Result drawElementsImpl(const gl::Context *context,
434                                    gl::PrimitiveMode mode,
435                                    GLsizei count,
436                                    gl::DrawElementsType type,
437                                    const void *indices,
438                                    GLsizei instances);
439 
440     angle::Result applyShaders(const gl::Context *context, gl::PrimitiveMode drawMode);
441 
442     angle::Result applyTextures(const gl::Context *context);
443     angle::Result applyTextures(const gl::Context *context, gl::ShaderType shaderType);
444 
445     void generateCaps(gl::Caps *outCaps,
446                       gl::TextureCapsMap *outTextureCaps,
447                       gl::Extensions *outExtensions,
448                       gl::Limitations *outLimitations) const override;
449 
450     void initializeFeatures(angle::FeaturesD3D *features) const override;
451 
452     angle::Result setBlendDepthRasterStates(const gl::Context *context, gl::PrimitiveMode drawMode);
453 
454     void release();
455 
456     void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v);
457     void applyUniformniv(const D3DUniform *targetUniform, const GLint *v);
458     void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v);
459 
460     angle::Result drawLineLoop(const gl::Context *context,
461                                GLsizei count,
462                                gl::DrawElementsType type,
463                                const void *indices,
464                                int minIndex,
465                                gl::Buffer *elementArrayBuffer);
466     angle::Result drawIndexedPoints(const gl::Context *context,
467                                     GLsizei count,
468                                     gl::DrawElementsType type,
469                                     const void *indices,
470                                     int minIndex,
471                                     gl::Buffer *elementArrayBuffer);
472 
473     angle::Result getCountingIB(const gl::Context *context,
474                                 size_t count,
475                                 StaticIndexBufferInterface **outIB);
476 
477     angle::Result getNullColorRenderTarget(const gl::Context *context,
478                                            const RenderTarget9 *depthRenderTarget,
479                                            const RenderTarget9 **outColorRenderTarget);
480 
481     D3DPOOL getBufferPool(DWORD usage) const;
482 
483     HMODULE mD3d9Module;
484 
485     egl::Error initializeDevice();
486     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
487     void releaseDeviceResources();
488 
489     HRESULT getDeviceStatusCode();
490     bool isRemovedDeviceResettable() const;
491     bool resetRemovedDevice();
492 
493     UINT mAdapter;
494     D3DDEVTYPE mDeviceType;
495     IDirect3D9 *mD3d9;      // Always valid after successful initialization.
496     IDirect3D9Ex *mD3d9Ex;  // Might be null if D3D9Ex is not supported.
497     IDirect3DDevice9 *mDevice;
498     IDirect3DDevice9Ex *mDeviceEx;  // Might be null if D3D9Ex is not supported.
499 
500     HLSLCompiler mCompiler;
501 
502     Blit9 *mBlit;
503 
504     HWND mDeviceWindow;
505 
506     D3DCAPS9 mDeviceCaps;
507     D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
508 
509     D3DPRIMITIVETYPE mPrimitiveType;
510     int mPrimitiveCount;
511     GLsizei mRepeatDraw;
512 
513     bool mSceneStarted;
514 
515     bool mVertexTextureSupport;
516 
517     // current render target states
518     unsigned int mAppliedRenderTargetSerial;
519     unsigned int mAppliedDepthStencilSerial;
520     bool mDepthStencilInitialized;
521     bool mRenderTargetDescInitialized;
522 
523     IDirect3DStateBlock9 *mMaskedClearSavedState;
524 
525     StateManager9 mStateManager;
526 
527     // Currently applied sampler states
528     struct CurSamplerState
529     {
530         CurSamplerState();
531 
532         bool forceSet;
533         size_t baseLevel;
534         gl::SamplerState samplerState;
535     };
536     std::vector<CurSamplerState> mCurVertexSamplerStates;
537     std::vector<CurSamplerState> mCurPixelSamplerStates;
538 
539     // Currently applied textures
540     std::vector<uintptr_t> mCurVertexTextures;
541     std::vector<uintptr_t> mCurPixelTextures;
542 
543     unsigned int mAppliedIBSerial;
544     IDirect3DVertexShader9 *mAppliedVertexShader;
545     IDirect3DPixelShader9 *mAppliedPixelShader;
546     unsigned int mAppliedProgramSerial;
547 
548     // A pool of event queries that are currently unused.
549     std::vector<IDirect3DQuery9 *> mEventQueryPool;
550     VertexShaderCache mVertexShaderCache;
551     PixelShaderCache mPixelShaderCache;
552 
553     VertexDataManager *mVertexDataManager;
554     VertexDeclarationCache mVertexDeclarationCache;
555 
556     IndexDataManager *mIndexDataManager;
557     StreamingIndexBufferInterface *mLineLoopIB;
558     StaticIndexBufferInterface *mCountingIB;
559 
560     enum
561     {
562         NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12
563     };
564     struct NullRenderTargetCacheEntry
565     {
566         UINT lruCount;
567         int width;
568         int height;
569         RenderTarget9 *renderTarget;
570     };
571 
572     std::array<NullRenderTargetCacheEntry, NUM_NULL_COLORBUFFER_CACHE_ENTRIES>
573         mNullRenderTargetCache;
574     UINT mMaxNullColorbufferLRU;
575 
576     std::vector<TranslatedAttribute> mTranslatedAttribCache;
577 
578     DebugAnnotator9 mAnnotator;
579 };
580 
581 }  // namespace rx
582 
583 #endif  // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
584