1 //
2 // Copyright 2016 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 // Context9:
7 // D3D9-specific functionality associated with a GL Context.
8 //
9
10 #include "libANGLE/renderer/d3d/d3d9/Context9.h"
11
12 #include "common/string_utils.h"
13 #include "libANGLE/renderer/OverlayImpl.h"
14 #include "libANGLE/renderer/d3d/CompilerD3D.h"
15 #include "libANGLE/renderer/d3d/ProgramD3D.h"
16 #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
17 #include "libANGLE/renderer/d3d/SamplerD3D.h"
18 #include "libANGLE/renderer/d3d/ShaderD3D.h"
19 #include "libANGLE/renderer/d3d/TextureD3D.h"
20 #include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
21 #include "libANGLE/renderer/d3d/d3d9/Fence9.h"
22 #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
23 #include "libANGLE/renderer/d3d/d3d9/Query9.h"
24 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
25 #include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
26 #include "libANGLE/renderer/d3d/d3d9/VertexArray9.h"
27
28 namespace rx
29 {
30
Context9(const gl::State & state,gl::ErrorSet * errorSet,Renderer9 * renderer)31 Context9::Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer)
32 : ContextD3D(state, errorSet), mRenderer(renderer)
33 {}
34
~Context9()35 Context9::~Context9() {}
36
initialize()37 angle::Result Context9::initialize()
38 {
39 return angle::Result::Continue;
40 }
41
onDestroy(const gl::Context * context)42 void Context9::onDestroy(const gl::Context *context)
43 {
44 mIncompleteTextures.onDestroy(context);
45 }
46
createCompiler()47 CompilerImpl *Context9::createCompiler()
48 {
49 return new CompilerD3D(SH_HLSL_3_0_OUTPUT);
50 }
51
createShader(const gl::ShaderState & data)52 ShaderImpl *Context9::createShader(const gl::ShaderState &data)
53 {
54 return new ShaderD3D(data, mRenderer->getFeatures(), mRenderer->getNativeExtensions());
55 }
56
createProgram(const gl::ProgramState & data)57 ProgramImpl *Context9::createProgram(const gl::ProgramState &data)
58 {
59 return new ProgramD3D(data, mRenderer);
60 }
61
createFramebuffer(const gl::FramebufferState & data)62 FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data)
63 {
64 return new Framebuffer9(data, mRenderer);
65 }
66
createTexture(const gl::TextureState & state)67 TextureImpl *Context9::createTexture(const gl::TextureState &state)
68 {
69 switch (state.getType())
70 {
71 case gl::TextureType::_2D:
72 // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to 2D texture on Windows platform.
73 case gl::TextureType::VideoImage:
74 return new TextureD3D_2D(state, mRenderer);
75 case gl::TextureType::CubeMap:
76 return new TextureD3D_Cube(state, mRenderer);
77 case gl::TextureType::External:
78 return new TextureD3D_External(state, mRenderer);
79 default:
80 UNREACHABLE();
81 }
82 return nullptr;
83 }
84
createRenderbuffer(const gl::RenderbufferState & state)85 RenderbufferImpl *Context9::createRenderbuffer(const gl::RenderbufferState &state)
86 {
87 return new RenderbufferD3D(state, mRenderer);
88 }
89
createBuffer(const gl::BufferState & state)90 BufferImpl *Context9::createBuffer(const gl::BufferState &state)
91 {
92 return new Buffer9(state, mRenderer);
93 }
94
createVertexArray(const gl::VertexArrayState & data)95 VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data)
96 {
97 return new VertexArray9(data);
98 }
99
createQuery(gl::QueryType type)100 QueryImpl *Context9::createQuery(gl::QueryType type)
101 {
102 return new Query9(mRenderer, type);
103 }
104
createFenceNV()105 FenceNVImpl *Context9::createFenceNV()
106 {
107 return new FenceNV9(mRenderer);
108 }
109
createSync()110 SyncImpl *Context9::createSync()
111 {
112 // D3D9 doesn't support ES 3.0 and its sync objects.
113 UNREACHABLE();
114 return nullptr;
115 }
116
createTransformFeedback(const gl::TransformFeedbackState & state)117 TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state)
118 {
119 UNREACHABLE();
120 return nullptr;
121 }
122
createSampler(const gl::SamplerState & state)123 SamplerImpl *Context9::createSampler(const gl::SamplerState &state)
124 {
125 return new SamplerD3D(state);
126 }
127
createProgramPipeline(const gl::ProgramPipelineState & data)128 ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data)
129 {
130 UNREACHABLE();
131 return nullptr;
132 }
133
createMemoryObject()134 MemoryObjectImpl *Context9::createMemoryObject()
135 {
136 UNREACHABLE();
137 return nullptr;
138 }
139
createSemaphore()140 SemaphoreImpl *Context9::createSemaphore()
141 {
142 UNREACHABLE();
143 return nullptr;
144 }
145
createOverlay(const gl::OverlayState & state)146 OverlayImpl *Context9::createOverlay(const gl::OverlayState &state)
147 {
148 // Not implemented.
149 return new OverlayImpl(state);
150 }
151
flush(const gl::Context * context)152 angle::Result Context9::flush(const gl::Context *context)
153 {
154 return mRenderer->flush(context);
155 }
156
finish(const gl::Context * context)157 angle::Result Context9::finish(const gl::Context *context)
158 {
159 return mRenderer->finish(context);
160 }
161
drawArrays(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count)162 angle::Result Context9::drawArrays(const gl::Context *context,
163 gl::PrimitiveMode mode,
164 GLint first,
165 GLsizei count)
166 {
167 return mRenderer->genericDrawArrays(context, mode, first, count, 0);
168 }
169
drawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)170 angle::Result Context9::drawArraysInstanced(const gl::Context *context,
171 gl::PrimitiveMode mode,
172 GLint first,
173 GLsizei count,
174 GLsizei instanceCount)
175 {
176 return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount);
177 }
178
drawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)179 angle::Result Context9::drawArraysInstancedBaseInstance(const gl::Context *context,
180 gl::PrimitiveMode mode,
181 GLint first,
182 GLsizei count,
183 GLsizei instanceCount,
184 GLuint baseInstance)
185 {
186 ANGLE_HR_UNREACHABLE(this);
187 return angle::Result::Continue;
188 }
189
drawElements(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices)190 angle::Result Context9::drawElements(const gl::Context *context,
191 gl::PrimitiveMode mode,
192 GLsizei count,
193 gl::DrawElementsType type,
194 const void *indices)
195 {
196 return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
197 }
198
drawElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)199 angle::Result Context9::drawElementsBaseVertex(const gl::Context *context,
200 gl::PrimitiveMode mode,
201 GLsizei count,
202 gl::DrawElementsType type,
203 const void *indices,
204 GLint baseVertex)
205 {
206 ANGLE_HR_UNREACHABLE(this);
207 return angle::Result::Continue;
208 }
209
drawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances)210 angle::Result Context9::drawElementsInstanced(const gl::Context *context,
211 gl::PrimitiveMode mode,
212 GLsizei count,
213 gl::DrawElementsType type,
214 const void *indices,
215 GLsizei instances)
216 {
217 return mRenderer->genericDrawElements(context, mode, count, type, indices, instances);
218 }
219
drawElementsInstancedBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex)220 angle::Result Context9::drawElementsInstancedBaseVertex(const gl::Context *context,
221 gl::PrimitiveMode mode,
222 GLsizei count,
223 gl::DrawElementsType type,
224 const void *indices,
225 GLsizei instances,
226 GLint baseVertex)
227 {
228 ANGLE_HR_UNREACHABLE(this);
229 return angle::Result::Continue;
230 }
231
drawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex,GLuint baseInstance)232 angle::Result Context9::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
233 gl::PrimitiveMode mode,
234 GLsizei count,
235 gl::DrawElementsType type,
236 const void *indices,
237 GLsizei instances,
238 GLint baseVertex,
239 GLuint baseInstance)
240 {
241 ANGLE_HR_UNREACHABLE(this);
242 return angle::Result::Continue;
243 }
244
drawRangeElements(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices)245 angle::Result Context9::drawRangeElements(const gl::Context *context,
246 gl::PrimitiveMode mode,
247 GLuint start,
248 GLuint end,
249 GLsizei count,
250 gl::DrawElementsType type,
251 const void *indices)
252 {
253 return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
254 }
255
drawRangeElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)256 angle::Result Context9::drawRangeElementsBaseVertex(const gl::Context *context,
257 gl::PrimitiveMode mode,
258 GLuint start,
259 GLuint end,
260 GLsizei count,
261 gl::DrawElementsType type,
262 const void *indices,
263 GLint baseVertex)
264 {
265 ANGLE_HR_UNREACHABLE(this);
266 return angle::Result::Continue;
267 }
268
drawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect)269 angle::Result Context9::drawArraysIndirect(const gl::Context *context,
270 gl::PrimitiveMode mode,
271 const void *indirect)
272 {
273 ANGLE_HR_UNREACHABLE(this);
274 return angle::Result::Stop;
275 }
276
drawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect)277 angle::Result Context9::drawElementsIndirect(const gl::Context *context,
278 gl::PrimitiveMode mode,
279 gl::DrawElementsType type,
280 const void *indirect)
281 {
282 ANGLE_HR_UNREACHABLE(this);
283 return angle::Result::Stop;
284 }
285
getResetStatus()286 gl::GraphicsResetStatus Context9::getResetStatus()
287 {
288 return mRenderer->getResetStatus();
289 }
290
getVendorString() const291 std::string Context9::getVendorString() const
292 {
293 return mRenderer->getVendorString();
294 }
295
getRendererDescription() const296 std::string Context9::getRendererDescription() const
297 {
298 return mRenderer->getRendererDescription();
299 }
300
insertEventMarker(GLsizei length,const char * marker)301 angle::Result Context9::insertEventMarker(GLsizei length, const char *marker)
302 {
303 mRenderer->getAnnotator()->setMarker(marker);
304 return angle::Result::Continue;
305 }
306
pushGroupMarker(GLsizei length,const char * marker)307 angle::Result Context9::pushGroupMarker(GLsizei length, const char *marker)
308 {
309 mRenderer->getAnnotator()->beginEvent(marker, marker);
310 mMarkerStack.push(std::string(marker));
311 return angle::Result::Continue;
312 }
313
popGroupMarker()314 angle::Result Context9::popGroupMarker()
315 {
316 const char *marker = nullptr;
317 if (!mMarkerStack.empty())
318 {
319 marker = mMarkerStack.top().c_str();
320 mMarkerStack.pop();
321 mRenderer->getAnnotator()->endEvent(marker);
322 }
323 return angle::Result::Continue;
324 }
325
pushDebugGroup(const gl::Context * context,GLenum source,GLuint id,const std::string & message)326 angle::Result Context9::pushDebugGroup(const gl::Context *context,
327 GLenum source,
328 GLuint id,
329 const std::string &message)
330 {
331 // Fall through to the EXT_debug_marker functions
332 return pushGroupMarker(static_cast<GLsizei>(message.size()), message.c_str());
333 }
334
popDebugGroup(const gl::Context * context)335 angle::Result Context9::popDebugGroup(const gl::Context *context)
336 {
337 // Fall through to the EXT_debug_marker functions
338 return popGroupMarker();
339 }
340
syncState(const gl::Context * context,const gl::State::DirtyBits & dirtyBits,const gl::State::DirtyBits & bitMask)341 angle::Result Context9::syncState(const gl::Context *context,
342 const gl::State::DirtyBits &dirtyBits,
343 const gl::State::DirtyBits &bitMask)
344 {
345 mRenderer->getStateManager()->syncState(mState, dirtyBits);
346 return angle::Result::Continue;
347 }
348
getGPUDisjoint()349 GLint Context9::getGPUDisjoint()
350 {
351 return mRenderer->getGPUDisjoint();
352 }
353
getTimestamp()354 GLint64 Context9::getTimestamp()
355 {
356 return mRenderer->getTimestamp();
357 }
358
onMakeCurrent(const gl::Context * context)359 angle::Result Context9::onMakeCurrent(const gl::Context *context)
360 {
361 mRenderer->getStateManager()->setAllDirtyBits();
362 return mRenderer->ensureVertexDataManagerInitialized(context);
363 }
364
getNativeCaps() const365 gl::Caps Context9::getNativeCaps() const
366 {
367 return mRenderer->getNativeCaps();
368 }
369
getNativeTextureCaps() const370 const gl::TextureCapsMap &Context9::getNativeTextureCaps() const
371 {
372 return mRenderer->getNativeTextureCaps();
373 }
374
getNativeExtensions() const375 const gl::Extensions &Context9::getNativeExtensions() const
376 {
377 return mRenderer->getNativeExtensions();
378 }
379
getNativeLimitations() const380 const gl::Limitations &Context9::getNativeLimitations() const
381 {
382 return mRenderer->getNativeLimitations();
383 }
384
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)385 angle::Result Context9::dispatchCompute(const gl::Context *context,
386 GLuint numGroupsX,
387 GLuint numGroupsY,
388 GLuint numGroupsZ)
389 {
390 ANGLE_HR_UNREACHABLE(this);
391 return angle::Result::Stop;
392 }
393
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)394 angle::Result Context9::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
395 {
396 ANGLE_HR_UNREACHABLE(this);
397 return angle::Result::Stop;
398 }
399
memoryBarrier(const gl::Context * context,GLbitfield barriers)400 angle::Result Context9::memoryBarrier(const gl::Context *context, GLbitfield barriers)
401 {
402 ANGLE_HR_UNREACHABLE(this);
403 return angle::Result::Stop;
404 }
405
memoryBarrierByRegion(const gl::Context * context,GLbitfield barriers)406 angle::Result Context9::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
407 {
408 ANGLE_HR_UNREACHABLE(this);
409 return angle::Result::Stop;
410 }
411
getIncompleteTexture(const gl::Context * context,gl::TextureType type,gl::Texture ** textureOut)412 angle::Result Context9::getIncompleteTexture(const gl::Context *context,
413 gl::TextureType type,
414 gl::Texture **textureOut)
415 {
416 return mIncompleteTextures.getIncompleteTexture(context, type, nullptr, textureOut);
417 }
418
handleResult(HRESULT hr,const char * message,const char * file,const char * function,unsigned int line)419 void Context9::handleResult(HRESULT hr,
420 const char *message,
421 const char *file,
422 const char *function,
423 unsigned int line)
424 {
425 ASSERT(FAILED(hr));
426
427 if (d3d9::isDeviceLostError(hr))
428 {
429 mRenderer->notifyDeviceLost();
430 }
431
432 GLenum glErrorCode = DefaultGLErrorCode(hr);
433
434 std::stringstream errorStream;
435 errorStream << "Internal D3D9 error: " << gl::FmtHR(hr) << ": " << message;
436
437 mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line);
438 }
439 } // namespace rx
440