RendererD3D.cpp (6237B)
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.cpp: Implementation of the base D3D Renderer. 8 9 #include "libANGLE/renderer/d3d/RendererD3D.h" 10 11 #include "common/MemoryBuffer.h" 12 #include "common/debug.h" 13 #include "common/utilities.h" 14 #include "libANGLE/Context.h" 15 #include "libANGLE/Display.h" 16 #include "libANGLE/Framebuffer.h" 17 #include "libANGLE/FramebufferAttachment.h" 18 #include "libANGLE/ImageIndex.h" 19 #include "libANGLE/ResourceManager.h" 20 #include "libANGLE/State.h" 21 #include "libANGLE/VertexArray.h" 22 #include "libANGLE/formatutils.h" 23 #include "libANGLE/renderer/ContextImpl.h" 24 #include "libANGLE/renderer/TextureImpl.h" 25 #include "libANGLE/renderer/d3d/BufferD3D.h" 26 #include "libANGLE/renderer/d3d/DeviceD3D.h" 27 #include "libANGLE/renderer/d3d/DisplayD3D.h" 28 #include "libANGLE/renderer/d3d/IndexDataManager.h" 29 #include "libANGLE/renderer/d3d/ProgramD3D.h" 30 #include "libANGLE/renderer/d3d/SamplerD3D.h" 31 #include "libANGLE/renderer/d3d/TextureD3D.h" 32 33 namespace rx 34 { 35 36 RendererD3D::RendererD3D(egl::Display *display) 37 : mDisplay(display), 38 mPresentPathFastEnabled(false), 39 mCapsInitialized(false), 40 mFeaturesInitialized(false), 41 mDisjoint(false), 42 mDeviceLost(false) 43 {} 44 45 RendererD3D::~RendererD3D() {} 46 47 bool RendererD3D::skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode) 48 { 49 if (drawMode == gl::PrimitiveMode::Points) 50 { 51 bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize(); 52 53 // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, 54 // which affects varying interpolation. Since the value of gl_PointSize is 55 // undefined when not written, just skip drawing to avoid unexpected results. 56 if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) 57 { 58 // Notify developers of risking undefined behavior. 59 WARN() << "Point rendering without writing to gl_PointSize."; 60 return true; 61 } 62 } 63 else if (gl::IsTriangleMode(drawMode)) 64 { 65 if (glState.getRasterizerState().cullFace && 66 glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack) 67 { 68 return true; 69 } 70 } 71 72 return false; 73 } 74 75 gl::GraphicsResetStatus RendererD3D::getResetStatus() 76 { 77 if (!mDeviceLost) 78 { 79 if (testDeviceLost()) 80 { 81 mDeviceLost = true; 82 notifyDeviceLost(); 83 return gl::GraphicsResetStatus::UnknownContextReset; 84 } 85 return gl::GraphicsResetStatus::NoError; 86 } 87 88 if (testDeviceResettable()) 89 { 90 return gl::GraphicsResetStatus::NoError; 91 } 92 93 return gl::GraphicsResetStatus::UnknownContextReset; 94 } 95 96 void RendererD3D::notifyDeviceLost() 97 { 98 mDisplay->notifyDeviceLost(); 99 } 100 101 void RendererD3D::setGPUDisjoint() 102 { 103 mDisjoint = true; 104 } 105 106 GLint RendererD3D::getGPUDisjoint() 107 { 108 bool disjoint = mDisjoint; 109 110 // Disjoint flag is cleared when read 111 mDisjoint = false; 112 113 return disjoint; 114 } 115 116 GLint64 RendererD3D::getTimestamp() 117 { 118 // D3D has no way to get an actual timestamp reliably so 0 is returned 119 return 0; 120 } 121 122 void RendererD3D::ensureCapsInitialized() const 123 { 124 if (!mCapsInitialized) 125 { 126 generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations); 127 mCapsInitialized = true; 128 } 129 } 130 131 const gl::Caps &RendererD3D::getNativeCaps() const 132 { 133 ensureCapsInitialized(); 134 return mNativeCaps; 135 } 136 137 const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const 138 { 139 ensureCapsInitialized(); 140 return mNativeTextureCaps; 141 } 142 143 const gl::Extensions &RendererD3D::getNativeExtensions() const 144 { 145 ensureCapsInitialized(); 146 return mNativeExtensions; 147 } 148 149 const gl::Limitations &RendererD3D::getNativeLimitations() const 150 { 151 ensureCapsInitialized(); 152 return mNativeLimitations; 153 } 154 155 ShPixelLocalStorageType RendererD3D::getNativePixelLocalStorageType() const 156 { 157 if (!getNativeExtensions().shaderPixelLocalStorageANGLE) 158 { 159 return ShPixelLocalStorageType::NotSupported; 160 } 161 // Read/write UAVs only support "r32*" images. 162 return ShPixelLocalStorageType::ImageStoreR32PackedFormats; 163 } 164 165 Serial RendererD3D::generateSerial() 166 { 167 return mSerialFactory.generate(); 168 } 169 170 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode) 171 { 172 return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() && 173 mode == gl::PrimitiveMode::Points; 174 } 175 176 angle::Result RendererD3D::initRenderTarget(const gl::Context *context, 177 RenderTargetD3D *renderTarget) 178 { 179 return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0); 180 } 181 182 const angle::FeaturesD3D &RendererD3D::getFeatures() const 183 { 184 if (!mFeaturesInitialized) 185 { 186 initializeFeatures(&mFeatures); 187 mFeaturesInitialized = true; 188 } 189 190 return mFeatures; 191 } 192 193 unsigned int GetBlendSampleMask(const gl::State &glState, int samples) 194 { 195 unsigned int mask = 0; 196 if (glState.isSampleCoverageEnabled()) 197 { 198 GLfloat coverageValue = glState.getSampleCoverageValue(); 199 if (coverageValue != 0) 200 { 201 float threshold = 0.5f; 202 203 for (int i = 0; i < samples; ++i) 204 { 205 mask <<= 1; 206 207 if ((i + 1) * coverageValue >= threshold) 208 { 209 threshold += 1.0f; 210 mask |= 1; 211 } 212 } 213 } 214 215 bool coverageInvert = glState.getSampleCoverageInvert(); 216 if (coverageInvert) 217 { 218 mask = ~mask; 219 } 220 } 221 else 222 { 223 mask = 0xFFFFFFFF; 224 } 225 226 if (glState.isSampleMaskEnabled()) 227 { 228 mask &= glState.getSampleMaskWord(0); 229 } 230 231 return mask; 232 } 233 234 GLenum DefaultGLErrorCode(HRESULT hr) 235 { 236 switch (hr) 237 { 238 #ifdef ANGLE_ENABLE_D3D9 239 case D3DERR_OUTOFVIDEOMEMORY: 240 #endif 241 case E_OUTOFMEMORY: 242 return GL_OUT_OF_MEMORY; 243 default: 244 return GL_INVALID_OPERATION; 245 } 246 } 247 } // namespace rx