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