• 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       mDeviceLost(false)
42 {}
43 
~RendererD3D()44 RendererD3D::~RendererD3D() {}
45 
skipDraw(const gl::State & glState,gl::PrimitiveMode drawMode)46 bool RendererD3D::skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode)
47 {
48     if (drawMode == gl::PrimitiveMode::Points)
49     {
50         bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize();
51 
52         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
53         // which affects varying interpolation. Since the value of gl_PointSize is
54         // undefined when not written, just skip drawing to avoid unexpected results.
55         if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
56         {
57             // Notify developers of risking undefined behavior.
58             WARN() << "Point rendering without writing to gl_PointSize.";
59             return true;
60         }
61     }
62     else if (gl::IsTriangleMode(drawMode))
63     {
64         if (glState.getRasterizerState().cullFace &&
65             glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack)
66         {
67             return true;
68         }
69     }
70 
71     return false;
72 }
73 
getResetStatus()74 gl::GraphicsResetStatus RendererD3D::getResetStatus()
75 {
76     if (!mDeviceLost)
77     {
78         if (testDeviceLost())
79         {
80             mDeviceLost = true;
81             notifyDeviceLost();
82             return gl::GraphicsResetStatus::UnknownContextReset;
83         }
84         return gl::GraphicsResetStatus::NoError;
85     }
86 
87     if (testDeviceResettable())
88     {
89         return gl::GraphicsResetStatus::NoError;
90     }
91 
92     return gl::GraphicsResetStatus::UnknownContextReset;
93 }
94 
notifyDeviceLost()95 void RendererD3D::notifyDeviceLost()
96 {
97     mDisplay->notifyDeviceLost();
98 }
99 
getTimestamp()100 GLint64 RendererD3D::getTimestamp()
101 {
102     // D3D has no way to get an actual timestamp reliably so 0 is returned
103     return 0;
104 }
105 
ensureCapsInitialized() const106 void RendererD3D::ensureCapsInitialized() const
107 {
108     if (!mCapsInitialized)
109     {
110         generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations,
111                      &mNativePLSOptions);
112         mCapsInitialized = true;
113     }
114 }
115 
getNativeCaps() const116 const gl::Caps &RendererD3D::getNativeCaps() const
117 {
118     ensureCapsInitialized();
119     return mNativeCaps;
120 }
121 
getNativeTextureCaps() const122 const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const
123 {
124     ensureCapsInitialized();
125     return mNativeTextureCaps;
126 }
127 
getNativeExtensions() const128 const gl::Extensions &RendererD3D::getNativeExtensions() const
129 {
130     ensureCapsInitialized();
131     return mNativeExtensions;
132 }
133 
getNativeLimitations() const134 const gl::Limitations &RendererD3D::getNativeLimitations() const
135 {
136     ensureCapsInitialized();
137     return mNativeLimitations;
138 }
139 
getNativePixelLocalStorageOptions() const140 const ShPixelLocalStorageOptions &RendererD3D::getNativePixelLocalStorageOptions() const
141 {
142     return mNativePLSOptions;
143 }
144 
generateSerial()145 UniqueSerial RendererD3D::generateSerial()
146 {
147     return mSerialFactory.generate();
148 }
149 
InstancedPointSpritesActive(ProgramD3D * programD3D,gl::PrimitiveMode mode)150 bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode)
151 {
152     return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() &&
153            mode == gl::PrimitiveMode::Points;
154 }
155 
initRenderTarget(const gl::Context * context,RenderTargetD3D * renderTarget)156 angle::Result RendererD3D::initRenderTarget(const gl::Context *context,
157                                             RenderTargetD3D *renderTarget)
158 {
159     return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0);
160 }
161 
getFeatures() const162 const angle::FeaturesD3D &RendererD3D::getFeatures() const
163 {
164     if (!mFeaturesInitialized)
165     {
166         initializeFeatures(&mFeatures);
167         mFeaturesInitialized = true;
168     }
169 
170     return mFeatures;
171 }
172 
GetBlendSampleMask(const gl::State & glState,int samples)173 unsigned int GetBlendSampleMask(const gl::State &glState, int samples)
174 {
175     unsigned int mask = 0;
176     if (glState.isSampleCoverageEnabled())
177     {
178         GLfloat coverageValue = glState.getSampleCoverageValue();
179         if (coverageValue != 0)
180         {
181             float threshold = 0.5f;
182 
183             for (int i = 0; i < samples; ++i)
184             {
185                 mask <<= 1;
186 
187                 if ((i + 1) * coverageValue >= threshold)
188                 {
189                     threshold += 1.0f;
190                     mask |= 1;
191                 }
192             }
193         }
194 
195         bool coverageInvert = glState.getSampleCoverageInvert();
196         if (coverageInvert)
197         {
198             mask = ~mask;
199         }
200     }
201     else
202     {
203         mask = 0xFFFFFFFF;
204     }
205 
206     if (glState.isSampleMaskEnabled())
207     {
208         mask &= glState.getSampleMaskWord(0);
209     }
210 
211     return mask;
212 }
213 
DefaultGLErrorCode(HRESULT hr)214 GLenum DefaultGLErrorCode(HRESULT hr)
215 {
216     switch (hr)
217     {
218 #ifdef ANGLE_ENABLE_D3D9
219         case D3DERR_OUTOFVIDEOMEMORY:
220 #endif
221         case E_OUTOFMEMORY:
222             return GL_OUT_OF_MEMORY;
223         default:
224             return GL_INVALID_OPERATION;
225     }
226 }
227 }  // namespace rx
228