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 GLenum *fboFormat) 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::SamplerType type, 124 int index, 125 gl::Texture *texture, 126 const gl::SamplerState &sampler); 127 gl::Error setTexture(const gl::Context *context, 128 gl::SamplerType 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 const gl::Offset &destOffset, 227 TextureStorage *storage, 228 GLenum destTarget, 229 GLint destLevel, 230 bool unpackFlipY, 231 bool unpackPremultiplyAlpha, 232 bool unpackUnmultiplyAlpha) override; 233 gl::Error copyCompressedTexture(const gl::Context *context, 234 const gl::Texture *source, 235 GLint sourceLevel, 236 TextureStorage *storage, 237 GLint destLevel) override; 238 239 // RenderTarget creation 240 gl::Error createRenderTarget(int width, 241 int height, 242 GLenum format, 243 GLsizei samples, 244 RenderTargetD3D **outRT) override; 245 gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; 246 247 // Shader operations 248 gl::Error loadExecutable(const uint8_t *function, 249 size_t length, 250 gl::ShaderType type, 251 const std::vector<D3DVarying> &streamOutVaryings, 252 bool separatedOutputBuffers, 253 ShaderExecutableD3D **outExecutable) override; 254 gl::Error compileToExecutable(gl::InfoLog &infoLog, 255 const std::string &shaderHLSL, 256 gl::ShaderType type, 257 const std::vector<D3DVarying> &streamOutVaryings, 258 bool separatedOutputBuffers, 259 const angle::CompilerWorkaroundsD3D &workarounds, 260 ShaderExecutableD3D **outExectuable) override; 261 gl::Error ensureHLSLCompilerInitialized() override; 262 263 UniformStorageD3D *createUniformStorage(size_t storageSize) override; 264 265 // Image operations 266 ImageD3D *createImage() override; 267 gl::Error generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *source) override; 268 gl::Error generateMipmapUsingD3D(const gl::Context *context, 269 TextureStorage *storage, 270 const gl::TextureState &textureState) override; 271 gl::Error copyImage(const gl::Context *context, 272 ImageD3D *dest, 273 ImageD3D *source, 274 const gl::Rectangle &sourceRect, 275 const gl::Offset &destOffset, 276 bool unpackFlipY, 277 bool unpackPremultiplyAlpha, 278 bool unpackUnmultiplyAlpha) override; 279 TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; 280 TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, 281 RenderTargetD3D *renderTargetD3D) override; 282 TextureStorage *createTextureStorageExternal( 283 egl::Stream *stream, 284 const egl::Stream::GLTextureDescription &desc) override; 285 TextureStorage *createTextureStorage2D(GLenum internalformat, 286 bool renderTarget, 287 GLsizei width, 288 GLsizei height, 289 int levels, 290 bool hintLevelZeroOnly) override; 291 TextureStorage *createTextureStorageCube(GLenum internalformat, 292 bool renderTarget, 293 int size, 294 int levels, 295 bool hintLevelZeroOnly) override; 296 TextureStorage *createTextureStorage3D(GLenum internalformat, 297 bool renderTarget, 298 GLsizei width, 299 GLsizei height, 300 GLsizei depth, 301 int levels) override; 302 TextureStorage *createTextureStorage2DArray(GLenum internalformat, 303 bool renderTarget, 304 GLsizei width, 305 GLsizei height, 306 GLsizei depth, 307 int levels) override; 308 309 TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, 310 GLsizei width, 311 GLsizei height, 312 int levels, 313 int samples, 314 bool fixedSampleLocations) override; 315 316 // Buffer creation 317 VertexBuffer *createVertexBuffer() override; 318 IndexBuffer *createIndexBuffer() override; 319 320 // Stream Creation 321 StreamProducerImpl *createStreamProducerD3DTextureNV12( 322 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 egl::Error getEGLDevice(DeviceImpl **device) 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::SamplerType 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 DeviceD3D *mEGLDevice; 536 std::vector<TranslatedAttribute> mTranslatedAttribCache; 537 538 DebugAnnotator9 mAnnotator; 539 }; 540 541 } // namespace rx 542 543 #endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ 544