RendererD3D.h (23226B)
1 // Copyright 2014 The ANGLE Project Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 6 // RendererD3D.h: Defines a back-end specific class for the DirectX renderer. 7 8 #ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ 9 #define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ 10 11 #include <array> 12 13 #include "common/Color.h" 14 #include "common/MemoryBuffer.h" 15 #include "common/debug.h" 16 #include "libANGLE/Device.h" 17 #include "libANGLE/State.h" 18 #include "libANGLE/Version.h" 19 #include "libANGLE/angletypes.h" 20 #include "libANGLE/formatutils.h" 21 #include "libANGLE/renderer/d3d/ShaderD3D.h" 22 #include "libANGLE/renderer/d3d/VertexDataManager.h" 23 #include "libANGLE/renderer/d3d/formatutilsD3D.h" 24 #include "libANGLE/renderer/renderer_utils.h" 25 #include "libANGLE/renderer/serial_utils.h" 26 #include "platform/FeaturesD3D_autogen.h" 27 28 namespace egl 29 { 30 class ConfigSet; 31 } 32 33 namespace gl 34 { 35 class ErrorSet; 36 class FramebufferState; 37 class InfoLog; 38 class Texture; 39 struct LinkedVarying; 40 } // namespace gl 41 42 namespace rx 43 { 44 class ContextImpl; 45 struct D3DUniform; 46 struct D3DVarying; 47 class DeviceD3D; 48 class EGLImageD3D; 49 class FramebufferImpl; 50 class ImageD3D; 51 class IndexBuffer; 52 class NativeWindowD3D; 53 class ProgramD3D; 54 class RenderTargetD3D; 55 class ShaderExecutableD3D; 56 class SwapChainD3D; 57 class TextureStorage; 58 struct TranslatedIndexData; 59 class UniformStorageD3D; 60 class VertexBuffer; 61 62 struct DeviceIdentifier 63 { 64 UINT VendorId; 65 UINT DeviceId; 66 UINT SubSysId; 67 UINT Revision; 68 UINT FeatureLevel; 69 }; 70 71 enum RendererClass 72 { 73 RENDERER_D3D11, 74 RENDERER_D3D9 75 }; 76 77 struct BindFlags 78 { 79 bool renderTarget = false; 80 bool unorderedAccess = false; 81 static BindFlags RenderTarget() 82 { 83 BindFlags flags; 84 flags.renderTarget = true; 85 return flags; 86 } 87 static BindFlags UnorderedAccess() 88 { 89 BindFlags flags; 90 flags.unorderedAccess = true; 91 return flags; 92 } 93 }; 94 95 // A d3d::Context wraps error handling. 96 namespace d3d 97 { 98 class Context : angle::NonCopyable 99 { 100 public: 101 Context() {} 102 virtual ~Context() {} 103 104 virtual void handleResult(HRESULT hr, 105 const char *message, 106 const char *file, 107 const char *function, 108 unsigned int line) = 0; 109 }; 110 } // namespace d3d 111 112 // ANGLE_TRY for HRESULT errors. 113 #define ANGLE_TRY_HR(CONTEXT, EXPR, MESSAGE) \ 114 do \ 115 { \ 116 auto ANGLE_LOCAL_VAR = (EXPR); \ 117 if (ANGLE_UNLIKELY(FAILED(ANGLE_LOCAL_VAR))) \ 118 { \ 119 CONTEXT->handleResult(ANGLE_LOCAL_VAR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \ 120 return angle::Result::Stop; \ 121 } \ 122 } while (0) 123 124 #define ANGLE_CHECK_HR(CONTEXT, EXPR, MESSAGE, ERROR) \ 125 do \ 126 { \ 127 if (ANGLE_UNLIKELY(!(EXPR))) \ 128 { \ 129 CONTEXT->handleResult(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \ 130 return angle::Result::Stop; \ 131 } \ 132 } while (0) 133 134 #define ANGLE_HR_UNREACHABLE(context) \ 135 UNREACHABLE(); \ 136 ANGLE_CHECK_HR(context, false, "Unreachble code reached.", E_FAIL) 137 138 // Check if the device is lost every 10 failures to get the query data 139 constexpr unsigned int kPollingD3DDeviceLostCheckFrequency = 10; 140 141 // Useful for unit testing 142 class BufferFactoryD3D : angle::NonCopyable 143 { 144 public: 145 BufferFactoryD3D() {} 146 virtual ~BufferFactoryD3D() {} 147 148 virtual VertexBuffer *createVertexBuffer() = 0; 149 virtual IndexBuffer *createIndexBuffer() = 0; 150 151 // TODO(jmadill): add VertexFormatCaps 152 virtual VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const = 0; 153 virtual GLenum getVertexComponentType(angle::FormatID vertexFormatID) const = 0; 154 155 // Warning: you should ensure binding really matches attrib.bindingIndex before using this 156 // function. 157 virtual angle::Result getVertexSpaceRequired(const gl::Context *context, 158 const gl::VertexAttribute &attrib, 159 const gl::VertexBinding &binding, 160 size_t count, 161 GLsizei instances, 162 GLuint baseInstance, 163 unsigned int *bytesRequiredOut) const = 0; 164 }; 165 166 using AttribIndexArray = gl::AttribArray<int>; 167 168 class RendererD3D : public BufferFactoryD3D 169 { 170 public: 171 explicit RendererD3D(egl::Display *display); 172 ~RendererD3D() override; 173 174 virtual egl::Error initialize() = 0; 175 176 virtual egl::ConfigSet generateConfigs() = 0; 177 virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0; 178 179 virtual ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) = 0; 180 181 virtual std::string getRendererDescription() const = 0; 182 virtual std::string getVendorString() const = 0; 183 virtual std::string getVersionString(bool includeFullVersion) const = 0; 184 185 virtual int getMinorShaderModel() const = 0; 186 virtual std::string getShaderModelSuffix() const = 0; 187 188 // Direct3D Specific methods 189 virtual DeviceIdentifier getAdapterIdentifier() const = 0; 190 191 virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; 192 virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, 193 const egl::Config *config, 194 const egl::AttributeMap &attribs) const = 0; 195 196 virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, 197 HANDLE shareHandle, 198 IUnknown *d3dTexture, 199 GLenum backBufferFormat, 200 GLenum depthBufferFormat, 201 EGLint orientation, 202 EGLint samples) = 0; 203 virtual egl::Error getD3DTextureInfo(const egl::Config *configuration, 204 IUnknown *d3dTexture, 205 const egl::AttributeMap &attribs, 206 EGLint *width, 207 EGLint *height, 208 GLsizei *samples, 209 gl::Format *glFormat, 210 const angle::Format **angleFormat, 211 UINT *arraySlice) const = 0; 212 virtual egl::Error validateShareHandle(const egl::Config *config, 213 HANDLE shareHandle, 214 const egl::AttributeMap &attribs) const = 0; 215 216 virtual int getMajorShaderModel() const = 0; 217 218 virtual void setGlobalDebugAnnotator() = 0; 219 220 const angle::FeaturesD3D &getFeatures() const; 221 222 // Pixel operations 223 virtual angle::Result copyImage2D(const gl::Context *context, 224 const gl::Framebuffer *framebuffer, 225 const gl::Rectangle &sourceRect, 226 GLenum destFormat, 227 const gl::Offset &destOffset, 228 TextureStorage *storage, 229 GLint level) = 0; 230 virtual angle::Result copyImageCube(const gl::Context *context, 231 const gl::Framebuffer *framebuffer, 232 const gl::Rectangle &sourceRect, 233 GLenum destFormat, 234 const gl::Offset &destOffset, 235 TextureStorage *storage, 236 gl::TextureTarget target, 237 GLint level) = 0; 238 virtual angle::Result copyImage3D(const gl::Context *context, 239 const gl::Framebuffer *framebuffer, 240 const gl::Rectangle &sourceRect, 241 GLenum destFormat, 242 const gl::Offset &destOffset, 243 TextureStorage *storage, 244 GLint level) = 0; 245 virtual angle::Result copyImage2DArray(const gl::Context *context, 246 const gl::Framebuffer *framebuffer, 247 const gl::Rectangle &sourceRect, 248 GLenum destFormat, 249 const gl::Offset &destOffset, 250 TextureStorage *storage, 251 GLint level) = 0; 252 253 virtual angle::Result copyTexture(const gl::Context *context, 254 const gl::Texture *source, 255 GLint sourceLevel, 256 gl::TextureTarget srcTarget, 257 const gl::Box &sourceBox, 258 GLenum destFormat, 259 GLenum destType, 260 const gl::Offset &destOffset, 261 TextureStorage *storage, 262 gl::TextureTarget destTarget, 263 GLint destLevel, 264 bool unpackFlipY, 265 bool unpackPremultiplyAlpha, 266 bool unpackUnmultiplyAlpha) = 0; 267 virtual angle::Result copyCompressedTexture(const gl::Context *context, 268 const gl::Texture *source, 269 GLint sourceLevel, 270 TextureStorage *storage, 271 GLint destLevel) = 0; 272 273 // RenderTarget creation 274 virtual angle::Result createRenderTarget(const gl::Context *context, 275 int width, 276 int height, 277 GLenum format, 278 GLsizei samples, 279 RenderTargetD3D **outRT) = 0; 280 virtual angle::Result createRenderTargetCopy(const gl::Context *context, 281 RenderTargetD3D *source, 282 RenderTargetD3D **outRT) = 0; 283 284 // Shader operations 285 virtual angle::Result loadExecutable(d3d::Context *context, 286 const uint8_t *function, 287 size_t length, 288 gl::ShaderType type, 289 const std::vector<D3DVarying> &streamOutVaryings, 290 bool separatedOutputBuffers, 291 ShaderExecutableD3D **outExecutable) = 0; 292 virtual angle::Result compileToExecutable(d3d::Context *context, 293 gl::InfoLog &infoLog, 294 const std::string &shaderHLSL, 295 gl::ShaderType type, 296 const std::vector<D3DVarying> &streamOutVaryings, 297 bool separatedOutputBuffers, 298 const CompilerWorkaroundsD3D &workarounds, 299 ShaderExecutableD3D **outExectuable) = 0; 300 virtual angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) = 0; 301 302 virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0; 303 304 // Image operations 305 virtual ImageD3D *createImage() = 0; 306 virtual ExternalImageSiblingImpl *createExternalImageSibling( 307 const gl::Context *context, 308 EGLenum target, 309 EGLClientBuffer buffer, 310 const egl::AttributeMap &attribs) = 0; 311 virtual angle::Result generateMipmap(const gl::Context *context, 312 ImageD3D *dest, 313 ImageD3D *source) = 0; 314 virtual angle::Result generateMipmapUsingD3D(const gl::Context *context, 315 TextureStorage *storage, 316 const gl::TextureState &textureState) = 0; 317 virtual angle::Result copyImage(const gl::Context *context, 318 ImageD3D *dest, 319 ImageD3D *source, 320 const gl::Box &sourceBox, 321 const gl::Offset &destOffset, 322 bool unpackFlipY, 323 bool unpackPremultiplyAlpha, 324 bool unpackUnmultiplyAlpha) = 0; 325 virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain, 326 const std::string &label) = 0; 327 virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, 328 RenderTargetD3D *renderTargetD3D, 329 const std::string &label) = 0; 330 virtual TextureStorage *createTextureStorageBuffer( 331 const gl::OffsetBindingPointer<gl::Buffer> &buffer, 332 GLenum internalFormat, 333 const std::string &label) = 0; 334 virtual TextureStorage *createTextureStorageExternal( 335 egl::Stream *stream, 336 const egl::Stream::GLTextureDescription &desc, 337 const std::string &label) = 0; 338 virtual TextureStorage *createTextureStorage2D(GLenum internalformat, 339 BindFlags bindFlags, 340 GLsizei width, 341 GLsizei height, 342 int levels, 343 const std::string &label, 344 bool hintLevelZeroOnly) = 0; 345 virtual TextureStorage *createTextureStorageCube(GLenum internalformat, 346 BindFlags bindFlags, 347 int size, 348 int levels, 349 bool hintLevelZeroOnly, 350 const std::string &label) = 0; 351 virtual TextureStorage *createTextureStorage3D(GLenum internalformat, 352 BindFlags bindFlags, 353 GLsizei width, 354 GLsizei height, 355 GLsizei depth, 356 int levels, 357 const std::string &label) = 0; 358 virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, 359 BindFlags bindFlags, 360 GLsizei width, 361 GLsizei height, 362 GLsizei depth, 363 int levels, 364 const std::string &label) = 0; 365 virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, 366 GLsizei width, 367 GLsizei height, 368 int levels, 369 int samples, 370 bool fixedSampleLocations, 371 const std::string &label) = 0; 372 virtual TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat, 373 GLsizei width, 374 GLsizei height, 375 GLsizei depth, 376 int levels, 377 int samples, 378 bool fixedSampleLocations, 379 const std::string &label) = 0; 380 381 // Buffer-to-texture and Texture-to-buffer copies 382 virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; 383 virtual angle::Result fastCopyBufferToTexture(const gl::Context *context, 384 const gl::PixelUnpackState &unpack, 385 gl::Buffer *unpackBuffer, 386 unsigned int offset, 387 RenderTargetD3D *destRenderTarget, 388 GLenum destinationFormat, 389 GLenum sourcePixelsType, 390 const gl::Box &destArea) = 0; 391 392 // Device lost 393 gl::GraphicsResetStatus getResetStatus(); 394 void notifyDeviceLost(); 395 virtual bool resetDevice() = 0; 396 virtual bool testDeviceLost() = 0; 397 virtual bool testDeviceResettable() = 0; 398 399 virtual RendererClass getRendererClass() const = 0; 400 virtual void *getD3DDevice() = 0; 401 402 void setGPUDisjoint(); 403 404 GLint getGPUDisjoint(); 405 GLint64 getTimestamp(); 406 407 virtual angle::Result clearRenderTarget(const gl::Context *context, 408 RenderTargetD3D *renderTarget, 409 const gl::ColorF &clearColorValue, 410 const float clearDepthValue, 411 const unsigned int clearStencilValue) = 0; 412 413 virtual DeviceImpl *createEGLDevice() = 0; 414 415 bool presentPathFastEnabled() const { return mPresentPathFastEnabled; } 416 417 // Stream creation 418 virtual StreamProducerImpl *createStreamProducerD3DTexture( 419 egl::Stream::ConsumerType consumerType, 420 const egl::AttributeMap &attribs) = 0; 421 422 const gl::Caps &getNativeCaps() const; 423 const gl::TextureCapsMap &getNativeTextureCaps() const; 424 const gl::Extensions &getNativeExtensions() const; 425 const gl::Limitations &getNativeLimitations() const; 426 ShPixelLocalStorageType getNativePixelLocalStorageType() const; 427 virtual void initializeFrontendFeatures(angle::FrontendFeatures *features) const = 0; 428 429 // Necessary hack for default framebuffers in D3D. 430 virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; 431 432 virtual gl::Version getMaxSupportedESVersion() const = 0; 433 virtual gl::Version getMaxConformantESVersion() const = 0; 434 435 angle::Result initRenderTarget(const gl::Context *context, RenderTargetD3D *renderTarget); 436 437 virtual angle::Result getIncompleteTexture(const gl::Context *context, 438 gl::TextureType type, 439 gl::Texture **textureOut) = 0; 440 441 Serial generateSerial(); 442 443 virtual bool canSelectViewInVertexShader() const = 0; 444 445 protected: 446 virtual bool getLUID(LUID *adapterLuid) const = 0; 447 virtual void generateCaps(gl::Caps *outCaps, 448 gl::TextureCapsMap *outTextureCaps, 449 gl::Extensions *outExtensions, 450 gl::Limitations *outLimitations) const = 0; 451 452 bool skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode); 453 454 egl::Display *mDisplay; 455 456 bool mPresentPathFastEnabled; 457 458 private: 459 void ensureCapsInitialized() const; 460 461 virtual void initializeFeatures(angle::FeaturesD3D *features) const = 0; 462 463 mutable bool mCapsInitialized; 464 mutable gl::Caps mNativeCaps; 465 mutable gl::TextureCapsMap mNativeTextureCaps; 466 mutable gl::Extensions mNativeExtensions; 467 mutable gl::Limitations mNativeLimitations; 468 469 mutable bool mFeaturesInitialized; 470 mutable angle::FeaturesD3D mFeatures; 471 472 bool mDisjoint; 473 bool mDeviceLost; 474 475 SerialFactory mSerialFactory; 476 }; 477 478 unsigned int GetBlendSampleMask(const gl::State &glState, int samples); 479 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode); 480 GLenum DefaultGLErrorCode(HRESULT hr); 481 482 // Define stubs so we don't need to include D3D9/D3D11 headers directly. 483 RendererD3D *CreateRenderer11(egl::Display *display); 484 RendererD3D *CreateRenderer9(egl::Display *display); 485 486 } // namespace rx 487 488 #endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_