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