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/entry_points_enum_autogen.h"
13 #include "common/string_utils.h"
14 #include "image_util/loadimage.h"
15 #include "libANGLE/renderer/OverlayImpl.h"
16 #include "libANGLE/renderer/d3d/CompilerD3D.h"
17 #include "libANGLE/renderer/d3d/ProgramD3D.h"
18 #include "libANGLE/renderer/d3d/ProgramExecutableD3D.h"
19 #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
20 #include "libANGLE/renderer/d3d/SamplerD3D.h"
21 #include "libANGLE/renderer/d3d/ShaderD3D.h"
22 #include "libANGLE/renderer/d3d/TextureD3D.h"
23 #include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
24 #include "libANGLE/renderer/d3d/d3d9/Fence9.h"
25 #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
26 #include "libANGLE/renderer/d3d/d3d9/Query9.h"
27 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
28 #include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
29 #include "libANGLE/renderer/d3d/d3d9/VertexArray9.h"
30
31 namespace rx
32 {
33
Context9(const gl::State & state,gl::ErrorSet * errorSet,Renderer9 * renderer)34 Context9::Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer)
35 : ContextD3D(state, errorSet), mRenderer(renderer)
36 {}
37
~Context9()38 Context9::~Context9() {}
39
initialize(const angle::ImageLoadContext & imageLoadContext)40 angle::Result Context9::initialize(const angle::ImageLoadContext &imageLoadContext)
41 {
42 mImageLoadContext = imageLoadContext;
43 return angle::Result::Continue;
44 }
45
onDestroy(const gl::Context * context)46 void Context9::onDestroy(const gl::Context *context)
47 {
48 mIncompleteTextures.onDestroy(context);
49
50 mImageLoadContext = {};
51 }
52
createCompiler()53 CompilerImpl *Context9::createCompiler()
54 {
55 return new CompilerD3D(SH_HLSL_3_0_OUTPUT);
56 }
57
createShader(const gl::ShaderState & data)58 ShaderImpl *Context9::createShader(const gl::ShaderState &data)
59 {
60 return new ShaderD3D(data, mRenderer);
61 }
62
createProgram(const gl::ProgramState & data)63 ProgramImpl *Context9::createProgram(const gl::ProgramState &data)
64 {
65 return new ProgramD3D(data, mRenderer);
66 }
67
createProgramExecutable(const gl::ProgramExecutable * executable)68 ProgramExecutableImpl *Context9::createProgramExecutable(const gl::ProgramExecutable *executable)
69 {
70 return new ProgramExecutableD3D(executable);
71 }
72
createFramebuffer(const gl::FramebufferState & data)73 FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data)
74 {
75 return new Framebuffer9(data, mRenderer);
76 }
77
createTexture(const gl::TextureState & state)78 TextureImpl *Context9::createTexture(const gl::TextureState &state)
79 {
80 switch (state.getType())
81 {
82 case gl::TextureType::_2D:
83 // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to 2D texture on Windows platform.
84 case gl::TextureType::VideoImage:
85 return new TextureD3D_2D(state, mRenderer);
86 case gl::TextureType::CubeMap:
87 return new TextureD3D_Cube(state, mRenderer);
88 case gl::TextureType::External:
89 return new TextureD3D_External(state, mRenderer);
90 default:
91 UNREACHABLE();
92 }
93 return nullptr;
94 }
95
createRenderbuffer(const gl::RenderbufferState & state)96 RenderbufferImpl *Context9::createRenderbuffer(const gl::RenderbufferState &state)
97 {
98 return new RenderbufferD3D(state, mRenderer);
99 }
100
createBuffer(const gl::BufferState & state)101 BufferImpl *Context9::createBuffer(const gl::BufferState &state)
102 {
103 return new Buffer9(state, mRenderer);
104 }
105
createVertexArray(const gl::VertexArrayState & data)106 VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data)
107 {
108 return new VertexArray9(data);
109 }
110
createQuery(gl::QueryType type)111 QueryImpl *Context9::createQuery(gl::QueryType type)
112 {
113 return new Query9(mRenderer, type);
114 }
115
createFenceNV()116 FenceNVImpl *Context9::createFenceNV()
117 {
118 return new FenceNV9(mRenderer);
119 }
120
createSync()121 SyncImpl *Context9::createSync()
122 {
123 // D3D9 doesn't support ES 3.0 and its sync objects.
124 UNREACHABLE();
125 return nullptr;
126 }
127
createTransformFeedback(const gl::TransformFeedbackState & state)128 TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state)
129 {
130 UNREACHABLE();
131 return nullptr;
132 }
133
createSampler(const gl::SamplerState & state)134 SamplerImpl *Context9::createSampler(const gl::SamplerState &state)
135 {
136 return new SamplerD3D(state);
137 }
138
createProgramPipeline(const gl::ProgramPipelineState & data)139 ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data)
140 {
141 UNREACHABLE();
142 return nullptr;
143 }
144
createMemoryObject()145 MemoryObjectImpl *Context9::createMemoryObject()
146 {
147 UNREACHABLE();
148 return nullptr;
149 }
150
createSemaphore()151 SemaphoreImpl *Context9::createSemaphore()
152 {
153 UNREACHABLE();
154 return nullptr;
155 }
156
createOverlay(const gl::OverlayState & state)157 OverlayImpl *Context9::createOverlay(const gl::OverlayState &state)
158 {
159 // Not implemented.
160 return new OverlayImpl(state);
161 }
162
flush(const gl::Context * context)163 angle::Result Context9::flush(const gl::Context *context)
164 {
165 return mRenderer->flush(context);
166 }
167
finish(const gl::Context * context)168 angle::Result Context9::finish(const gl::Context *context)
169 {
170 return mRenderer->finish(context);
171 }
172
drawArrays(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count)173 angle::Result Context9::drawArrays(const gl::Context *context,
174 gl::PrimitiveMode mode,
175 GLint first,
176 GLsizei count)
177 {
178 return mRenderer->genericDrawArrays(context, mode, first, count, 0);
179 }
180
drawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)181 angle::Result Context9::drawArraysInstanced(const gl::Context *context,
182 gl::PrimitiveMode mode,
183 GLint first,
184 GLsizei count,
185 GLsizei instanceCount)
186 {
187 return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount);
188 }
189
drawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)190 angle::Result Context9::drawArraysInstancedBaseInstance(const gl::Context *context,
191 gl::PrimitiveMode mode,
192 GLint first,
193 GLsizei count,
194 GLsizei instanceCount,
195 GLuint baseInstance)
196 {
197 ANGLE_HR_UNREACHABLE(this);
198 return angle::Result::Continue;
199 }
200
drawElements(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices)201 angle::Result Context9::drawElements(const gl::Context *context,
202 gl::PrimitiveMode mode,
203 GLsizei count,
204 gl::DrawElementsType type,
205 const void *indices)
206 {
207 return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
208 }
209
drawElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)210 angle::Result Context9::drawElementsBaseVertex(const gl::Context *context,
211 gl::PrimitiveMode mode,
212 GLsizei count,
213 gl::DrawElementsType type,
214 const void *indices,
215 GLint baseVertex)
216 {
217 ANGLE_HR_UNREACHABLE(this);
218 return angle::Result::Continue;
219 }
220
drawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances)221 angle::Result Context9::drawElementsInstanced(const gl::Context *context,
222 gl::PrimitiveMode mode,
223 GLsizei count,
224 gl::DrawElementsType type,
225 const void *indices,
226 GLsizei instances)
227 {
228 return mRenderer->genericDrawElements(context, mode, count, type, indices, instances);
229 }
230
drawElementsInstancedBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex)231 angle::Result Context9::drawElementsInstancedBaseVertex(const gl::Context *context,
232 gl::PrimitiveMode mode,
233 GLsizei count,
234 gl::DrawElementsType type,
235 const void *indices,
236 GLsizei instances,
237 GLint baseVertex)
238 {
239 ANGLE_HR_UNREACHABLE(this);
240 return angle::Result::Continue;
241 }
242
drawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex,GLuint baseInstance)243 angle::Result Context9::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
244 gl::PrimitiveMode mode,
245 GLsizei count,
246 gl::DrawElementsType type,
247 const void *indices,
248 GLsizei instances,
249 GLint baseVertex,
250 GLuint baseInstance)
251 {
252 ANGLE_HR_UNREACHABLE(this);
253 return angle::Result::Continue;
254 }
255
drawRangeElements(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices)256 angle::Result Context9::drawRangeElements(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 {
264 return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
265 }
266
drawRangeElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)267 angle::Result Context9::drawRangeElementsBaseVertex(const gl::Context *context,
268 gl::PrimitiveMode mode,
269 GLuint start,
270 GLuint end,
271 GLsizei count,
272 gl::DrawElementsType type,
273 const void *indices,
274 GLint baseVertex)
275 {
276 ANGLE_HR_UNREACHABLE(this);
277 return angle::Result::Continue;
278 }
279
drawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect)280 angle::Result Context9::drawArraysIndirect(const gl::Context *context,
281 gl::PrimitiveMode mode,
282 const void *indirect)
283 {
284 ANGLE_HR_UNREACHABLE(this);
285 return angle::Result::Stop;
286 }
287
drawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect)288 angle::Result Context9::drawElementsIndirect(const gl::Context *context,
289 gl::PrimitiveMode mode,
290 gl::DrawElementsType type,
291 const void *indirect)
292 {
293 ANGLE_HR_UNREACHABLE(this);
294 return angle::Result::Stop;
295 }
296
multiDrawArrays(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)297 angle::Result Context9::multiDrawArrays(const gl::Context *context,
298 gl::PrimitiveMode mode,
299 const GLint *firsts,
300 const GLsizei *counts,
301 GLsizei drawcount)
302 {
303 return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
304 }
305
multiDrawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)306 angle::Result Context9::multiDrawArraysInstanced(const gl::Context *context,
307 gl::PrimitiveMode mode,
308 const GLint *firsts,
309 const GLsizei *counts,
310 const GLsizei *instanceCounts,
311 GLsizei drawcount)
312 {
313 return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
314 drawcount);
315 }
316
multiDrawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect,GLsizei drawcount,GLsizei stride)317 angle::Result Context9::multiDrawArraysIndirect(const gl::Context *context,
318 gl::PrimitiveMode mode,
319 const void *indirect,
320 GLsizei drawcount,
321 GLsizei stride)
322 {
323 UNREACHABLE();
324 return angle::Result::Stop;
325 }
326
multiDrawElements(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)327 angle::Result Context9::multiDrawElements(const gl::Context *context,
328 gl::PrimitiveMode mode,
329 const GLsizei *counts,
330 gl::DrawElementsType type,
331 const GLvoid *const *indices,
332 GLsizei drawcount)
333 {
334 return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
335 }
336
multiDrawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)337 angle::Result Context9::multiDrawElementsInstanced(const gl::Context *context,
338 gl::PrimitiveMode mode,
339 const GLsizei *counts,
340 gl::DrawElementsType type,
341 const GLvoid *const *indices,
342 const GLsizei *instanceCounts,
343 GLsizei drawcount)
344 {
345 return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
346 instanceCounts, drawcount);
347 }
348
multiDrawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect,GLsizei drawcount,GLsizei stride)349 angle::Result Context9::multiDrawElementsIndirect(const gl::Context *context,
350 gl::PrimitiveMode mode,
351 gl::DrawElementsType type,
352 const void *indirect,
353 GLsizei drawcount,
354 GLsizei stride)
355 {
356 UNREACHABLE();
357 return angle::Result::Stop;
358 }
359
multiDrawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)360 angle::Result Context9::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
361 gl::PrimitiveMode mode,
362 const GLint *firsts,
363 const GLsizei *counts,
364 const GLsizei *instanceCounts,
365 const GLuint *baseInstances,
366 GLsizei drawcount)
367 {
368 ANGLE_HR_UNREACHABLE(this);
369 return angle::Result::Stop;
370 }
371
multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)372 angle::Result Context9::multiDrawElementsInstancedBaseVertexBaseInstance(
373 const gl::Context *context,
374 gl::PrimitiveMode mode,
375 const GLsizei *counts,
376 gl::DrawElementsType type,
377 const GLvoid *const *indices,
378 const GLsizei *instanceCounts,
379 const GLint *baseVertices,
380 const GLuint *baseInstances,
381 GLsizei drawcount)
382 {
383 ANGLE_HR_UNREACHABLE(this);
384 return angle::Result::Stop;
385 }
386
getResetStatus()387 gl::GraphicsResetStatus Context9::getResetStatus()
388 {
389 return mRenderer->getResetStatus();
390 }
391
insertEventMarker(GLsizei length,const char * marker)392 angle::Result Context9::insertEventMarker(GLsizei length, const char *marker)
393 {
394 mRenderer->getAnnotator()->setMarker(/*context=*/nullptr, marker);
395 return angle::Result::Continue;
396 }
397
pushGroupMarker(GLsizei length,const char * marker)398 angle::Result Context9::pushGroupMarker(GLsizei length, const char *marker)
399 {
400 mRenderer->getAnnotator()->beginEvent(nullptr, angle::EntryPoint::GLPushGroupMarkerEXT, marker,
401 marker);
402 mMarkerStack.push(std::string(marker));
403 return angle::Result::Continue;
404 }
405
popGroupMarker()406 angle::Result Context9::popGroupMarker()
407 {
408 const char *marker = nullptr;
409 if (!mMarkerStack.empty())
410 {
411 marker = mMarkerStack.top().c_str();
412 mMarkerStack.pop();
413 mRenderer->getAnnotator()->endEvent(nullptr, marker,
414 angle::EntryPoint::GLPopGroupMarkerEXT);
415 }
416 return angle::Result::Continue;
417 }
418
pushDebugGroup(const gl::Context * context,GLenum source,GLuint id,const std::string & message)419 angle::Result Context9::pushDebugGroup(const gl::Context *context,
420 GLenum source,
421 GLuint id,
422 const std::string &message)
423 {
424 // Fall through to the EXT_debug_marker functions
425 return pushGroupMarker(static_cast<GLsizei>(message.size()), message.c_str());
426 }
427
popDebugGroup(const gl::Context * context)428 angle::Result Context9::popDebugGroup(const gl::Context *context)
429 {
430 // Fall through to the EXT_debug_marker functions
431 return popGroupMarker();
432 }
433
syncState(const gl::Context * context,const gl::state::DirtyBits dirtyBits,const gl::state::DirtyBits bitMask,const gl::state::ExtendedDirtyBits extendedDirtyBits,const gl::state::ExtendedDirtyBits extendedBitMask,gl::Command command)434 angle::Result Context9::syncState(const gl::Context *context,
435 const gl::state::DirtyBits dirtyBits,
436 const gl::state::DirtyBits bitMask,
437 const gl::state::ExtendedDirtyBits extendedDirtyBits,
438 const gl::state::ExtendedDirtyBits extendedBitMask,
439 gl::Command command)
440 {
441 mRenderer->getStateManager()->syncState(mState, dirtyBits, extendedDirtyBits);
442 return angle::Result::Continue;
443 }
444
getGPUDisjoint()445 GLint Context9::getGPUDisjoint()
446 {
447 // Disjoint timer queries are not supported.
448 return false;
449 }
450
getTimestamp()451 GLint64 Context9::getTimestamp()
452 {
453 return mRenderer->getTimestamp();
454 }
455
onMakeCurrent(const gl::Context * context)456 angle::Result Context9::onMakeCurrent(const gl::Context *context)
457 {
458 mRenderer->getStateManager()->setAllDirtyBits();
459 return mRenderer->ensureVertexDataManagerInitialized(context);
460 }
461
getNativeCaps() const462 gl::Caps Context9::getNativeCaps() const
463 {
464 return mRenderer->getNativeCaps();
465 }
466
getNativeTextureCaps() const467 const gl::TextureCapsMap &Context9::getNativeTextureCaps() const
468 {
469 return mRenderer->getNativeTextureCaps();
470 }
471
getNativeExtensions() const472 const gl::Extensions &Context9::getNativeExtensions() const
473 {
474 return mRenderer->getNativeExtensions();
475 }
476
getNativeLimitations() const477 const gl::Limitations &Context9::getNativeLimitations() const
478 {
479 return mRenderer->getNativeLimitations();
480 }
481
getNativePixelLocalStorageOptions() const482 const ShPixelLocalStorageOptions &Context9::getNativePixelLocalStorageOptions() const
483 {
484 return mRenderer->getNativePixelLocalStorageOptions();
485 }
486
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)487 angle::Result Context9::dispatchCompute(const gl::Context *context,
488 GLuint numGroupsX,
489 GLuint numGroupsY,
490 GLuint numGroupsZ)
491 {
492 ANGLE_HR_UNREACHABLE(this);
493 return angle::Result::Stop;
494 }
495
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)496 angle::Result Context9::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
497 {
498 ANGLE_HR_UNREACHABLE(this);
499 return angle::Result::Stop;
500 }
501
memoryBarrier(const gl::Context * context,GLbitfield barriers)502 angle::Result Context9::memoryBarrier(const gl::Context *context, GLbitfield barriers)
503 {
504 ANGLE_HR_UNREACHABLE(this);
505 return angle::Result::Stop;
506 }
507
memoryBarrierByRegion(const gl::Context * context,GLbitfield barriers)508 angle::Result Context9::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
509 {
510 ANGLE_HR_UNREACHABLE(this);
511 return angle::Result::Stop;
512 }
513
getIncompleteTexture(const gl::Context * context,gl::TextureType type,gl::Texture ** textureOut)514 angle::Result Context9::getIncompleteTexture(const gl::Context *context,
515 gl::TextureType type,
516 gl::Texture **textureOut)
517 {
518 return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float,
519 nullptr, textureOut);
520 }
521
handleResult(HRESULT hr,const char * message,const char * file,const char * function,unsigned int line)522 void Context9::handleResult(HRESULT hr,
523 const char *message,
524 const char *file,
525 const char *function,
526 unsigned int line)
527 {
528 ASSERT(FAILED(hr));
529
530 if (d3d9::isDeviceLostError(hr))
531 {
532 mRenderer->notifyDeviceLost();
533 }
534
535 GLenum glErrorCode = DefaultGLErrorCode(hr);
536
537 std::stringstream errorStream;
538 errorStream << "Internal D3D9 error: " << gl::FmtHR(hr) << ": " << message;
539
540 mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line);
541 }
542 } // namespace rx
543