1 2 // Copyright (c) 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/ContextState.h" 18 #include "libANGLE/Device.h" 19 #include "libANGLE/Version.h" 20 #include "libANGLE/WorkerThread.h" 21 #include "libANGLE/angletypes.h" 22 #include "libANGLE/formatutils.h" 23 #include "libANGLE/renderer/d3d/VertexDataManager.h" 24 #include "libANGLE/renderer/d3d/formatutilsD3D.h" 25 #include "libANGLE/renderer/renderer_utils.h" 26 #include "platform/WorkaroundsD3D.h" 27 28 namespace egl 29 { 30 class ConfigSet; 31 } 32 33 namespace gl 34 { 35 class FramebufferState; 36 class InfoLog; 37 class Texture; 38 struct LinkedVarying; 39 } 40 41 namespace rx 42 { 43 class ContextImpl; 44 struct D3DUniform; 45 struct D3DVarying; 46 class DeviceD3D; 47 class EGLImageD3D; 48 class FramebufferImpl; 49 class ImageD3D; 50 class IndexBuffer; 51 class NativeWindowD3D; 52 class ProgramD3D; 53 class RenderTargetD3D; 54 class ShaderExecutableD3D; 55 class SwapChainD3D; 56 class TextureStorage; 57 struct TranslatedIndexData; 58 class UniformStorageD3D; 59 class VertexBuffer; 60 61 struct DeviceIdentifier 62 { 63 UINT VendorId; 64 UINT DeviceId; 65 UINT SubSysId; 66 UINT Revision; 67 UINT FeatureLevel; 68 }; 69 70 enum RendererClass 71 { 72 RENDERER_D3D11, 73 RENDERER_D3D9 74 }; 75 76 // Useful for unit testing 77 class BufferFactoryD3D : angle::NonCopyable 78 { 79 public: BufferFactoryD3D()80 BufferFactoryD3D() {} ~BufferFactoryD3D()81 virtual ~BufferFactoryD3D() {} 82 83 virtual VertexBuffer *createVertexBuffer() = 0; 84 virtual IndexBuffer *createIndexBuffer() = 0; 85 86 // TODO(jmadill): add VertexFormatCaps 87 virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0; 88 virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0; 89 90 // Warning: you should ensure binding really matches attrib.bindingIndex before using this 91 // function. 92 virtual gl::ErrorOrResult<unsigned int> getVertexSpaceRequired( 93 const gl::VertexAttribute &attrib, 94 const gl::VertexBinding &binding, 95 GLsizei count, 96 GLsizei instances) const = 0; 97 }; 98 99 using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>; 100 101 class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitializer 102 { 103 public: 104 explicit RendererD3D(egl::Display *display); 105 ~RendererD3D() override; 106 107 virtual egl::Error initialize() = 0; 108 109 virtual egl::ConfigSet generateConfigs() = 0; 110 virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0; 111 112 virtual ContextImpl *createContext(const gl::ContextState &state) = 0; 113 114 std::string getVendorString() const; 115 116 virtual int getMinorShaderModel() const = 0; 117 virtual std::string getShaderModelSuffix() const = 0; 118 119 // Direct3D Specific methods 120 virtual DeviceIdentifier getAdapterIdentifier() const = 0; 121 122 virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; 123 virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, 124 const egl::Config *config, 125 const egl::AttributeMap &attribs) const = 0; 126 127 virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, 128 HANDLE shareHandle, 129 IUnknown *d3dTexture, 130 GLenum backBufferFormat, 131 GLenum depthBufferFormat, 132 EGLint orientation, 133 EGLint samples) = 0; 134 virtual egl::Error getD3DTextureInfo(const egl::Config *configuration, 135 IUnknown *d3dTexture, 136 EGLint *width, 137 EGLint *height, 138 GLenum *fboFormat) const = 0; 139 virtual egl::Error validateShareHandle(const egl::Config *config, 140 HANDLE shareHandle, 141 const egl::AttributeMap &attribs) const = 0; 142 143 virtual int getMajorShaderModel() const = 0; 144 145 const angle::WorkaroundsD3D &getWorkarounds() const; 146 147 // Pixel operations 148 virtual gl::Error copyImage2D(const gl::Context *context, 149 const gl::Framebuffer *framebuffer, 150 const gl::Rectangle &sourceRect, 151 GLenum destFormat, 152 const gl::Offset &destOffset, 153 TextureStorage *storage, 154 GLint level) = 0; 155 virtual gl::Error copyImageCube(const gl::Context *context, 156 const gl::Framebuffer *framebuffer, 157 const gl::Rectangle &sourceRect, 158 GLenum destFormat, 159 const gl::Offset &destOffset, 160 TextureStorage *storage, 161 GLenum target, 162 GLint level) = 0; 163 virtual gl::Error copyImage3D(const gl::Context *context, 164 const gl::Framebuffer *framebuffer, 165 const gl::Rectangle &sourceRect, 166 GLenum destFormat, 167 const gl::Offset &destOffset, 168 TextureStorage *storage, 169 GLint level) = 0; 170 virtual gl::Error copyImage2DArray(const gl::Context *context, 171 const gl::Framebuffer *framebuffer, 172 const gl::Rectangle &sourceRect, 173 GLenum destFormat, 174 const gl::Offset &destOffset, 175 TextureStorage *storage, 176 GLint level) = 0; 177 178 virtual gl::Error copyTexture(const gl::Context *context, 179 const gl::Texture *source, 180 GLint sourceLevel, 181 const gl::Rectangle &sourceRect, 182 GLenum destFormat, 183 const gl::Offset &destOffset, 184 TextureStorage *storage, 185 GLenum destTarget, 186 GLint destLevel, 187 bool unpackFlipY, 188 bool unpackPremultiplyAlpha, 189 bool unpackUnmultiplyAlpha) = 0; 190 virtual gl::Error copyCompressedTexture(const gl::Context *context, 191 const gl::Texture *source, 192 GLint sourceLevel, 193 TextureStorage *storage, 194 GLint destLevel) = 0; 195 196 // RenderTarget creation 197 virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0; 198 virtual gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) = 0; 199 200 // Shader operations 201 virtual gl::Error loadExecutable(const uint8_t *function, 202 size_t length, 203 gl::ShaderType type, 204 const std::vector<D3DVarying> &streamOutVaryings, 205 bool separatedOutputBuffers, 206 ShaderExecutableD3D **outExecutable) = 0; 207 virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, 208 const std::string &shaderHLSL, 209 gl::ShaderType type, 210 const std::vector<D3DVarying> &streamOutVaryings, 211 bool separatedOutputBuffers, 212 const angle::CompilerWorkaroundsD3D &workarounds, 213 ShaderExecutableD3D **outExectuable) = 0; 214 virtual gl::Error ensureHLSLCompilerInitialized() = 0; 215 216 virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0; 217 218 // Image operations 219 virtual ImageD3D *createImage() = 0; 220 virtual gl::Error generateMipmap(const gl::Context *context, 221 ImageD3D *dest, 222 ImageD3D *source) = 0; 223 virtual gl::Error generateMipmapUsingD3D(const gl::Context *context, 224 TextureStorage *storage, 225 const gl::TextureState &textureState) = 0; 226 virtual gl::Error copyImage(const gl::Context *context, 227 ImageD3D *dest, 228 ImageD3D *source, 229 const gl::Rectangle &sourceRect, 230 const gl::Offset &destOffset, 231 bool unpackFlipY, 232 bool unpackPremultiplyAlpha, 233 bool unpackUnmultiplyAlpha) = 0; 234 virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0; 235 virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, 236 RenderTargetD3D *renderTargetD3D) = 0; 237 virtual TextureStorage *createTextureStorageExternal( 238 egl::Stream *stream, 239 const egl::Stream::GLTextureDescription &desc) = 0; 240 virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 0; 241 virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0; 242 virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; 243 virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; 244 virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, 245 GLsizei width, 246 GLsizei height, 247 int levels, 248 int samples, 249 bool fixedSampleLocations) = 0; 250 251 // Buffer-to-texture and Texture-to-buffer copies 252 virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; 253 virtual gl::Error fastCopyBufferToTexture(const gl::Context *context, 254 const gl::PixelUnpackState &unpack, 255 unsigned int offset, 256 RenderTargetD3D *destRenderTarget, 257 GLenum destinationFormat, 258 GLenum sourcePixelsType, 259 const gl::Box &destArea) = 0; 260 261 // Device lost 262 GLenum getResetStatus(); 263 void notifyDeviceLost(); 264 virtual bool resetDevice() = 0; 265 virtual bool testDeviceLost() = 0; 266 virtual bool testDeviceResettable() = 0; 267 268 virtual RendererClass getRendererClass() const = 0; 269 virtual void *getD3DDevice() = 0; 270 271 void setGPUDisjoint(); 272 273 GLint getGPUDisjoint(); 274 GLint64 getTimestamp(); 275 276 virtual gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, 277 const gl::ColorF &clearColorValue, 278 const float clearDepthValue, 279 const unsigned int clearStencilValue) = 0; 280 281 virtual egl::Error getEGLDevice(DeviceImpl **device) = 0; 282 presentPathFastEnabled()283 bool presentPathFastEnabled() const { return mPresentPathFastEnabled; } 284 285 // Stream creation 286 virtual StreamProducerImpl *createStreamProducerD3DTextureNV12( 287 egl::Stream::ConsumerType consumerType, 288 const egl::AttributeMap &attribs) = 0; 289 290 const gl::Caps &getNativeCaps() const; 291 const gl::TextureCapsMap &getNativeTextureCaps() const; 292 const gl::Extensions &getNativeExtensions() const; 293 const gl::Limitations &getNativeLimitations() const; 294 295 // Necessary hack for default framebuffers in D3D. 296 virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; 297 298 virtual gl::Version getMaxSupportedESVersion() const = 0; 299 300 gl::Error initRenderTarget(RenderTargetD3D *renderTarget); 301 302 angle::WorkerThreadPool *getWorkerThreadPool(); 303 304 gl::Error getIncompleteTexture(const gl::Context *context, 305 GLenum type, 306 gl::Texture **textureOut); 307 308 Serial generateSerial(); 309 310 virtual bool canSelectViewInVertexShader() const = 0; 311 312 gl::Error initializeMultisampleTextureToBlack(const gl::Context *context, 313 gl::Texture *glTexture) override; 314 315 protected: 316 virtual bool getLUID(LUID *adapterLuid) const = 0; 317 virtual void generateCaps(gl::Caps *outCaps, 318 gl::TextureCapsMap *outTextureCaps, 319 gl::Extensions *outExtensions, 320 gl::Limitations *outLimitations) const = 0; 321 322 void cleanup(); 323 324 bool skipDraw(const gl::State &glState, GLenum drawMode); 325 326 egl::Display *mDisplay; 327 328 bool mPresentPathFastEnabled; 329 330 private: 331 void ensureCapsInitialized() const; 332 333 virtual angle::WorkaroundsD3D generateWorkarounds() const = 0; 334 335 mutable bool mCapsInitialized; 336 mutable gl::Caps mNativeCaps; 337 mutable gl::TextureCapsMap mNativeTextureCaps; 338 mutable gl::Extensions mNativeExtensions; 339 mutable gl::Limitations mNativeLimitations; 340 341 IncompleteTextureSet mIncompleteTextures; 342 343 mutable bool mWorkaroundsInitialized; 344 mutable angle::WorkaroundsD3D mWorkarounds; 345 346 bool mDisjoint; 347 bool mDeviceLost; 348 349 angle::WorkerThreadPool mWorkerThreadPool; 350 351 SerialFactory mSerialFactory; 352 }; 353 354 unsigned int GetBlendSampleMask(const gl::State &glState, int samples); 355 bool InstancedPointSpritesActive(ProgramD3D *programD3D, GLenum mode); 356 357 } // namespace rx 358 359 #endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ 360