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