• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RendererD3D(egl::Display * display)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 
~RendererD3D()45 RendererD3D::~RendererD3D() {}
46 
skipDraw(const gl::State & glState,gl::PrimitiveMode drawMode)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 
getResetStatus()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 
notifyDeviceLost()96 void RendererD3D::notifyDeviceLost()
97 {
98     mDisplay->notifyDeviceLost();
99 }
100 
setGPUDisjoint()101 void RendererD3D::setGPUDisjoint()
102 {
103     mDisjoint = true;
104 }
105 
getGPUDisjoint()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 
getTimestamp()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 
ensureCapsInitialized() const122 void RendererD3D::ensureCapsInitialized() const
123 {
124     if (!mCapsInitialized)
125     {
126         generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
127         mCapsInitialized = true;
128     }
129 }
130 
getNativeCaps() const131 const gl::Caps &RendererD3D::getNativeCaps() const
132 {
133     ensureCapsInitialized();
134     return mNativeCaps;
135 }
136 
getNativeTextureCaps() const137 const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const
138 {
139     ensureCapsInitialized();
140     return mNativeTextureCaps;
141 }
142 
getNativeExtensions() const143 const gl::Extensions &RendererD3D::getNativeExtensions() const
144 {
145     ensureCapsInitialized();
146     return mNativeExtensions;
147 }
148 
getNativeLimitations() const149 const gl::Limitations &RendererD3D::getNativeLimitations() const
150 {
151     ensureCapsInitialized();
152     return mNativeLimitations;
153 }
154 
generateSerial()155 Serial RendererD3D::generateSerial()
156 {
157     return mSerialFactory.generate();
158 }
159 
InstancedPointSpritesActive(ProgramD3D * programD3D,gl::PrimitiveMode mode)160 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode)
161 {
162     return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() &&
163            mode == gl::PrimitiveMode::Points;
164 }
165 
initRenderTarget(const gl::Context * context,RenderTargetD3D * renderTarget)166 angle::Result RendererD3D::initRenderTarget(const gl::Context *context,
167                                             RenderTargetD3D *renderTarget)
168 {
169     return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0);
170 }
171 
getFeatures() const172 const angle::FeaturesD3D &RendererD3D::getFeatures() const
173 {
174     if (!mFeaturesInitialized)
175     {
176         initializeFeatures(&mFeatures);
177         mFeaturesInitialized = true;
178     }
179 
180     return mFeatures;
181 }
182 
GetBlendSampleMask(const gl::State & glState,int samples)183 unsigned int GetBlendSampleMask(const gl::State &glState, int samples)
184 {
185     unsigned int mask = 0;
186     if (glState.isSampleCoverageEnabled())
187     {
188         GLfloat coverageValue = glState.getSampleCoverageValue();
189         if (coverageValue != 0)
190         {
191             float threshold = 0.5f;
192 
193             for (int i = 0; i < samples; ++i)
194             {
195                 mask <<= 1;
196 
197                 if ((i + 1) * coverageValue >= threshold)
198                 {
199                     threshold += 1.0f;
200                     mask |= 1;
201                 }
202             }
203         }
204 
205         bool coverageInvert = glState.getSampleCoverageInvert();
206         if (coverageInvert)
207         {
208             mask = ~mask;
209         }
210     }
211     else
212     {
213         mask = 0xFFFFFFFF;
214     }
215 
216     if (glState.isSampleMaskEnabled())
217     {
218         mask &= glState.getSampleMaskWord(0);
219     }
220 
221     return mask;
222 }
223 
DefaultGLErrorCode(HRESULT hr)224 GLenum DefaultGLErrorCode(HRESULT hr)
225 {
226     switch (hr)
227     {
228 #ifdef ANGLE_ENABLE_D3D9
229         case D3DERR_OUTOFVIDEOMEMORY:
230 #endif
231         case E_OUTOFMEMORY:
232             return GL_OUT_OF_MEMORY;
233         default:
234             return GL_INVALID_OPERATION;
235     }
236 }
237 }  // namespace rx
238