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