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