• 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 
getVendorString() const101 std::string RendererD3D::getVendorString() const
102 {
103     LUID adapterLuid = {};
104 
105     if (getLUID(&adapterLuid))
106     {
107         char adapterLuidString[64];
108         sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)",
109                   adapterLuid.HighPart, adapterLuid.LowPart);
110         return std::string(adapterLuidString);
111     }
112 
113     return std::string("");
114 }
115 
setGPUDisjoint()116 void RendererD3D::setGPUDisjoint()
117 {
118     mDisjoint = true;
119 }
120 
getGPUDisjoint()121 GLint RendererD3D::getGPUDisjoint()
122 {
123     bool disjoint = mDisjoint;
124 
125     // Disjoint flag is cleared when read
126     mDisjoint = false;
127 
128     return disjoint;
129 }
130 
getTimestamp()131 GLint64 RendererD3D::getTimestamp()
132 {
133     // D3D has no way to get an actual timestamp reliably so 0 is returned
134     return 0;
135 }
136 
ensureCapsInitialized() const137 void RendererD3D::ensureCapsInitialized() const
138 {
139     if (!mCapsInitialized)
140     {
141         generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
142         mCapsInitialized = true;
143     }
144 }
145 
getNativeCaps() const146 const gl::Caps &RendererD3D::getNativeCaps() const
147 {
148     ensureCapsInitialized();
149     return mNativeCaps;
150 }
151 
getNativeTextureCaps() const152 const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const
153 {
154     ensureCapsInitialized();
155     return mNativeTextureCaps;
156 }
157 
getNativeExtensions() const158 const gl::Extensions &RendererD3D::getNativeExtensions() const
159 {
160     ensureCapsInitialized();
161     return mNativeExtensions;
162 }
163 
getNativeLimitations() const164 const gl::Limitations &RendererD3D::getNativeLimitations() const
165 {
166     ensureCapsInitialized();
167     return mNativeLimitations;
168 }
169 
generateSerial()170 Serial RendererD3D::generateSerial()
171 {
172     return mSerialFactory.generate();
173 }
174 
InstancedPointSpritesActive(ProgramD3D * programD3D,gl::PrimitiveMode mode)175 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode)
176 {
177     return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() &&
178            mode == gl::PrimitiveMode::Points;
179 }
180 
initRenderTarget(const gl::Context * context,RenderTargetD3D * renderTarget)181 angle::Result RendererD3D::initRenderTarget(const gl::Context *context,
182                                             RenderTargetD3D *renderTarget)
183 {
184     return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0);
185 }
186 
getFeatures() const187 const angle::FeaturesD3D &RendererD3D::getFeatures() const
188 {
189     if (!mFeaturesInitialized)
190     {
191         initializeFeatures(&mFeatures);
192         mFeaturesInitialized = true;
193     }
194 
195     return mFeatures;
196 }
197 
GetBlendSampleMask(const gl::State & glState,int samples)198 unsigned int GetBlendSampleMask(const gl::State &glState, int samples)
199 {
200     unsigned int mask = 0;
201     if (glState.isSampleCoverageEnabled())
202     {
203         GLfloat coverageValue = glState.getSampleCoverageValue();
204         if (coverageValue != 0)
205         {
206             float threshold = 0.5f;
207 
208             for (int i = 0; i < samples; ++i)
209             {
210                 mask <<= 1;
211 
212                 if ((i + 1) * coverageValue >= threshold)
213                 {
214                     threshold += 1.0f;
215                     mask |= 1;
216                 }
217             }
218         }
219 
220         bool coverageInvert = glState.getSampleCoverageInvert();
221         if (coverageInvert)
222         {
223             mask = ~mask;
224         }
225     }
226     else
227     {
228         mask = 0xFFFFFFFF;
229     }
230 
231     if (glState.isSampleMaskEnabled())
232     {
233         mask &= glState.getSampleMaskWord(0);
234     }
235 
236     return mask;
237 }
238 
DefaultGLErrorCode(HRESULT hr)239 GLenum DefaultGLErrorCode(HRESULT hr)
240 {
241     switch (hr)
242     {
243 #ifdef ANGLE_ENABLE_D3D9
244         case D3DERR_OUTOFVIDEOMEMORY:
245 #endif
246         case E_OUTOFMEMORY:
247             return GL_OUT_OF_MEMORY;
248         default:
249             return GL_INVALID_OPERATION;
250     }
251 }
252 }  // namespace rx
253