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 // Context11:
7 // D3D11-specific functionality associated with a GL Context.
8 //
9
10 #include "libANGLE/renderer/d3d/d3d11/Context11.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/Context.h"
16 #include "libANGLE/Context.inl.h"
17 #include "libANGLE/MemoryProgramCache.h"
18 #include "libANGLE/renderer/OverlayImpl.h"
19 #include "libANGLE/renderer/d3d/CompilerD3D.h"
20 #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
21 #include "libANGLE/renderer/d3d/SamplerD3D.h"
22 #include "libANGLE/renderer/d3d/ShaderD3D.h"
23 #include "libANGLE/renderer/d3d/TextureD3D.h"
24 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
25 #include "libANGLE/renderer/d3d/d3d11/Fence11.h"
26 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
27 #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
28 #include "libANGLE/renderer/d3d/d3d11/Program11.h"
29 #include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h"
30 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
31 #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
32 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
33 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
34 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
35
36 namespace rx
37 {
38
39 namespace
40 {
DrawCallHasDynamicAttribs(const gl::Context * context)41 ANGLE_INLINE bool DrawCallHasDynamicAttribs(const gl::Context *context)
42 {
43 VertexArray11 *vertexArray11 = GetImplAs<VertexArray11>(context->getState().getVertexArray());
44 return vertexArray11->hasActiveDynamicAttrib(context);
45 }
46
DrawCallHasStreamingVertexArrays(const gl::Context * context,gl::PrimitiveMode mode)47 bool DrawCallHasStreamingVertexArrays(const gl::Context *context, gl::PrimitiveMode mode)
48 {
49 // Direct drawing doesn't support dynamic attribute storage since it needs the first and count
50 // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported
51 // either since we need to simulate them in D3D.
52 if (DrawCallHasDynamicAttribs(context) || mode == gl::PrimitiveMode::LineLoop ||
53 mode == gl::PrimitiveMode::TriangleFan)
54 {
55 return true;
56 }
57
58 ProgramD3D *programD3D = GetImplAs<ProgramD3D>(context->getState().getProgram());
59 if (InstancedPointSpritesActive(programD3D, mode))
60 {
61 return true;
62 }
63
64 return false;
65 }
66
DrawCallHasStreamingElementArray(const gl::Context * context,gl::DrawElementsType srcType)67 bool DrawCallHasStreamingElementArray(const gl::Context *context, gl::DrawElementsType srcType)
68 {
69 const gl::State &glState = context->getState();
70 gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer();
71
72 bool primitiveRestartWorkaround =
73 UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType);
74 const gl::DrawElementsType dstType =
75 (srcType == gl::DrawElementsType::UnsignedInt || primitiveRestartWorkaround)
76 ? gl::DrawElementsType::UnsignedInt
77 : gl::DrawElementsType::UnsignedShort;
78
79 // Not clear where the offset comes from here.
80 switch (ClassifyIndexStorage(glState, elementArrayBuffer, srcType, dstType, 0))
81 {
82 case IndexStorageType::Dynamic:
83 return true;
84 case IndexStorageType::Direct:
85 return false;
86 case IndexStorageType::Static:
87 {
88 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
89 StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
90 return (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != dstType);
91 }
92 default:
93 UNREACHABLE();
94 return true;
95 }
96 }
97
98 template <typename IndirectBufferT>
ReadbackIndirectBuffer(const gl::Context * context,const void * indirect,const IndirectBufferT ** bufferPtrOut)99 angle::Result ReadbackIndirectBuffer(const gl::Context *context,
100 const void *indirect,
101 const IndirectBufferT **bufferPtrOut)
102 {
103 const gl::State &glState = context->getState();
104 gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
105 ASSERT(drawIndirectBuffer);
106 Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
107 uintptr_t offset = reinterpret_cast<uintptr_t>(indirect);
108
109 const uint8_t *bufferData = nullptr;
110 ANGLE_TRY(storage->getData(context, &bufferData));
111 ASSERT(bufferData);
112
113 *bufferPtrOut = reinterpret_cast<const IndirectBufferT *>(bufferData + offset);
114 return angle::Result::Continue;
115 }
116 } // anonymous namespace
117
Context11(const gl::State & state,gl::ErrorSet * errorSet,Renderer11 * renderer)118 Context11::Context11(const gl::State &state, gl::ErrorSet *errorSet, Renderer11 *renderer)
119 : ContextD3D(state, errorSet),
120 mRenderer(renderer),
121 mDisjointQueryStarted(false),
122 mDisjoint(false),
123 mFrequency(0)
124 {}
125
~Context11()126 Context11::~Context11() {}
127
initialize()128 angle::Result Context11::initialize()
129 {
130 return angle::Result::Continue;
131 }
132
onDestroy(const gl::Context * context)133 void Context11::onDestroy(const gl::Context *context)
134 {
135 mIncompleteTextures.onDestroy(context);
136 }
137
createCompiler()138 CompilerImpl *Context11::createCompiler()
139 {
140 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
141 {
142 return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT);
143 }
144 else
145 {
146 return new CompilerD3D(SH_HLSL_4_1_OUTPUT);
147 }
148 }
149
createShader(const gl::ShaderState & data)150 ShaderImpl *Context11::createShader(const gl::ShaderState &data)
151 {
152 return new ShaderD3D(data, mRenderer);
153 }
154
createProgram(const gl::ProgramState & data)155 ProgramImpl *Context11::createProgram(const gl::ProgramState &data)
156 {
157 return new Program11(data, mRenderer);
158 }
159
createFramebuffer(const gl::FramebufferState & data)160 FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data)
161 {
162 return new Framebuffer11(data, mRenderer);
163 }
164
createTexture(const gl::TextureState & state)165 TextureImpl *Context11::createTexture(const gl::TextureState &state)
166 {
167 switch (state.getType())
168 {
169 case gl::TextureType::_2D:
170 // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to native 2D texture on Windows platform
171 case gl::TextureType::VideoImage:
172 return new TextureD3D_2D(state, mRenderer);
173 case gl::TextureType::CubeMap:
174 return new TextureD3D_Cube(state, mRenderer);
175 case gl::TextureType::_3D:
176 return new TextureD3D_3D(state, mRenderer);
177 case gl::TextureType::_2DArray:
178 return new TextureD3D_2DArray(state, mRenderer);
179 case gl::TextureType::External:
180 return new TextureD3D_External(state, mRenderer);
181 case gl::TextureType::_2DMultisample:
182 return new TextureD3D_2DMultisample(state, mRenderer);
183 case gl::TextureType::_2DMultisampleArray:
184 return new TextureD3D_2DMultisampleArray(state, mRenderer);
185 case gl::TextureType::Buffer:
186 return new TextureD3D_Buffer(state, mRenderer);
187 default:
188 UNREACHABLE();
189 }
190
191 return nullptr;
192 }
193
createRenderbuffer(const gl::RenderbufferState & state)194 RenderbufferImpl *Context11::createRenderbuffer(const gl::RenderbufferState &state)
195 {
196 return new RenderbufferD3D(state, mRenderer);
197 }
198
createBuffer(const gl::BufferState & state)199 BufferImpl *Context11::createBuffer(const gl::BufferState &state)
200 {
201 Buffer11 *buffer = new Buffer11(state, mRenderer);
202 mRenderer->onBufferCreate(buffer);
203 return buffer;
204 }
205
createVertexArray(const gl::VertexArrayState & data)206 VertexArrayImpl *Context11::createVertexArray(const gl::VertexArrayState &data)
207 {
208 return new VertexArray11(data);
209 }
210
createQuery(gl::QueryType type)211 QueryImpl *Context11::createQuery(gl::QueryType type)
212 {
213 return new Query11(mRenderer, type);
214 }
215
createFenceNV()216 FenceNVImpl *Context11::createFenceNV()
217 {
218 return new FenceNV11(mRenderer);
219 }
220
createSync()221 SyncImpl *Context11::createSync()
222 {
223 return new Sync11(mRenderer);
224 }
225
createTransformFeedback(const gl::TransformFeedbackState & state)226 TransformFeedbackImpl *Context11::createTransformFeedback(const gl::TransformFeedbackState &state)
227 {
228 return new TransformFeedback11(state, mRenderer);
229 }
230
createSampler(const gl::SamplerState & state)231 SamplerImpl *Context11::createSampler(const gl::SamplerState &state)
232 {
233 return new SamplerD3D(state);
234 }
235
createProgramPipeline(const gl::ProgramPipelineState & data)236 ProgramPipelineImpl *Context11::createProgramPipeline(const gl::ProgramPipelineState &data)
237 {
238 return new ProgramPipeline11(data);
239 }
240
createMemoryObject()241 MemoryObjectImpl *Context11::createMemoryObject()
242 {
243 UNREACHABLE();
244 return nullptr;
245 }
246
createSemaphore()247 SemaphoreImpl *Context11::createSemaphore()
248 {
249 UNREACHABLE();
250 return nullptr;
251 }
252
createOverlay(const gl::OverlayState & state)253 OverlayImpl *Context11::createOverlay(const gl::OverlayState &state)
254 {
255 // Not implemented.
256 return new OverlayImpl(state);
257 }
258
flush(const gl::Context * context)259 angle::Result Context11::flush(const gl::Context *context)
260 {
261 return mRenderer->flush(this);
262 }
263
finish(const gl::Context * context)264 angle::Result Context11::finish(const gl::Context *context)
265 {
266 return mRenderer->finish(this);
267 }
268
drawArrays(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count)269 angle::Result Context11::drawArrays(const gl::Context *context,
270 gl::PrimitiveMode mode,
271 GLint first,
272 GLsizei count)
273 {
274 ASSERT(count > 0);
275 ANGLE_TRY(mRenderer->getStateManager()->updateState(
276 context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true));
277 return mRenderer->drawArrays(context, mode, first, count, 0, 0, false);
278 }
279
drawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)280 angle::Result Context11::drawArraysInstanced(const gl::Context *context,
281 gl::PrimitiveMode mode,
282 GLint first,
283 GLsizei count,
284 GLsizei instanceCount)
285 {
286 ASSERT(count > 0);
287 ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
288 gl::DrawElementsType::InvalidEnum, nullptr,
289 instanceCount, 0, 0, true));
290 return mRenderer->drawArrays(context, mode, first, count, instanceCount, 0, true);
291 }
292
drawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)293 angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *context,
294 gl::PrimitiveMode mode,
295 GLint first,
296 GLsizei count,
297 GLsizei instanceCount,
298 GLuint baseInstance)
299 {
300 ASSERT(count > 0);
301 ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
302 gl::DrawElementsType::InvalidEnum, nullptr,
303 instanceCount, 0, baseInstance, true));
304 return mRenderer->drawArrays(context, mode, first, count, instanceCount, baseInstance, true);
305 }
306
drawElementsImpl(const gl::Context * context,gl::PrimitiveMode mode,GLsizei indexCount,gl::DrawElementsType indexType,const void * indices,GLsizei instanceCount,GLint baseVertex,GLuint baseInstance,bool promoteDynamic,bool isInstancedDraw)307 ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *context,
308 gl::PrimitiveMode mode,
309 GLsizei indexCount,
310 gl::DrawElementsType indexType,
311 const void *indices,
312 GLsizei instanceCount,
313 GLint baseVertex,
314 GLuint baseInstance,
315 bool promoteDynamic,
316 bool isInstancedDraw)
317 {
318 ASSERT(indexCount > 0);
319
320 if (DrawCallHasDynamicAttribs(context))
321 {
322 gl::IndexRange indexRange;
323 ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(
324 context, indexType, indexCount, indices, &indexRange));
325 GLint startVertex;
326 ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, baseVertex,
327 &startVertex));
328 ANGLE_TRY(mRenderer->getStateManager()->updateState(
329 context, mode, startVertex, indexCount, indexType, indices, instanceCount, baseVertex,
330 baseInstance, promoteDynamic));
331 return mRenderer->drawElements(context, mode, startVertex, indexCount, indexType, indices,
332 instanceCount, baseVertex, baseInstance, isInstancedDraw);
333 }
334 else
335 {
336 ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, indexCount, indexType,
337 indices, instanceCount, baseVertex,
338 baseInstance, promoteDynamic));
339 return mRenderer->drawElements(context, mode, 0, indexCount, indexType, indices,
340 instanceCount, baseVertex, baseInstance, isInstancedDraw);
341 }
342 }
343
drawElements(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices)344 angle::Result Context11::drawElements(const gl::Context *context,
345 gl::PrimitiveMode mode,
346 GLsizei count,
347 gl::DrawElementsType type,
348 const void *indices)
349 {
350 return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false);
351 }
352
drawElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)353 angle::Result Context11::drawElementsBaseVertex(const gl::Context *context,
354 gl::PrimitiveMode mode,
355 GLsizei count,
356 gl::DrawElementsType type,
357 const void *indices,
358 GLint baseVertex)
359 {
360 return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false);
361 }
362
drawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances)363 angle::Result Context11::drawElementsInstanced(const gl::Context *context,
364 gl::PrimitiveMode mode,
365 GLsizei count,
366 gl::DrawElementsType type,
367 const void *indices,
368 GLsizei instances)
369 {
370 return drawElementsImpl(context, mode, count, type, indices, instances, 0, 0, true, true);
371 }
372
drawElementsInstancedBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex)373 angle::Result Context11::drawElementsInstancedBaseVertex(const gl::Context *context,
374 gl::PrimitiveMode mode,
375 GLsizei count,
376 gl::DrawElementsType type,
377 const void *indices,
378 GLsizei instances,
379 GLint baseVertex)
380 {
381 return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex, 0, true,
382 true);
383 }
384
drawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex,GLuint baseInstance)385 angle::Result Context11::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
386 gl::PrimitiveMode mode,
387 GLsizei count,
388 gl::DrawElementsType type,
389 const void *indices,
390 GLsizei instances,
391 GLint baseVertex,
392 GLuint baseInstance)
393 {
394 return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex,
395 baseInstance, true, true);
396 }
397
drawRangeElements(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices)398 angle::Result Context11::drawRangeElements(const gl::Context *context,
399 gl::PrimitiveMode mode,
400 GLuint start,
401 GLuint end,
402 GLsizei count,
403 gl::DrawElementsType type,
404 const void *indices)
405 {
406 return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false);
407 }
408
drawRangeElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)409 angle::Result Context11::drawRangeElementsBaseVertex(const gl::Context *context,
410 gl::PrimitiveMode mode,
411 GLuint start,
412 GLuint end,
413 GLsizei count,
414 gl::DrawElementsType type,
415 const void *indices,
416 GLint baseVertex)
417 {
418 return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false);
419 }
420
drawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect)421 angle::Result Context11::drawArraysIndirect(const gl::Context *context,
422 gl::PrimitiveMode mode,
423 const void *indirect)
424 {
425 if (DrawCallHasStreamingVertexArrays(context, mode))
426 {
427 const gl::DrawArraysIndirectCommand *cmd = nullptr;
428 ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
429
430 ANGLE_TRY(mRenderer->getStateManager()->updateState(
431 context, mode, cmd->first, cmd->count, gl::DrawElementsType::InvalidEnum, nullptr,
432 cmd->instanceCount, 0, 0, true));
433 return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount,
434 cmd->baseInstance, true);
435 }
436 else
437 {
438 ANGLE_TRY(mRenderer->getStateManager()->updateState(
439 context, mode, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true));
440 return mRenderer->drawArraysIndirect(context, indirect);
441 }
442 }
443
drawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect)444 angle::Result Context11::drawElementsIndirect(const gl::Context *context,
445 gl::PrimitiveMode mode,
446 gl::DrawElementsType type,
447 const void *indirect)
448 {
449 if (DrawCallHasStreamingVertexArrays(context, mode) ||
450 DrawCallHasStreamingElementArray(context, type))
451 {
452 const gl::DrawElementsIndirectCommand *cmd = nullptr;
453 ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
454
455 const GLuint typeBytes = gl::GetDrawElementsTypeSize(type);
456 const void *indices =
457 reinterpret_cast<const void *>(static_cast<uintptr_t>(cmd->firstIndex * typeBytes));
458
459 // We must explicitly resolve the index range for the slow-path indirect drawElements to
460 // make sure we are using the correct 'baseVertex'. This parameter does not exist for the
461 // direct drawElements.
462 gl::IndexRange indexRange;
463 ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(context, type, cmd->count,
464 indices, &indexRange));
465
466 GLint startVertex;
467 ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, cmd->baseVertex,
468 &startVertex));
469
470 ANGLE_TRY(mRenderer->getStateManager()->updateState(
471 context, mode, startVertex, cmd->count, type, indices, cmd->primCount, cmd->baseVertex,
472 cmd->baseInstance, true));
473 return mRenderer->drawElements(context, mode, static_cast<GLint>(indexRange.start),
474 cmd->count, type, indices, cmd->primCount, 0,
475 cmd->baseInstance, true);
476 }
477 else
478 {
479 ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0,
480 0, 0, true));
481 return mRenderer->drawElementsIndirect(context, indirect);
482 }
483 }
484
485 #define DRAW_ARRAYS__ \
486 do \
487 { \
488 ANGLE_TRY(mRenderer->getStateManager()->updateState( \
489 context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
490 nullptr, 0, 0, 0, false)); \
491 ANGLE_TRY( \
492 mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], 0, 0, false)); \
493 } while (0)
494 #define DRAW_ARRAYS_INSTANCED_ \
495 do \
496 { \
497 ANGLE_TRY(mRenderer->getStateManager()->updateState( \
498 context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
499 nullptr, instanceCounts[drawID], 0, 0, false)); \
500 ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \
501 instanceCounts[drawID], 0, true)); \
502 } while (0)
503 #define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \
504 do \
505 { \
506 ANGLE_TRY(mRenderer->getStateManager()->updateState( \
507 context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
508 nullptr, instanceCounts[drawID], 0, baseInstances[drawID], false)); \
509 ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \
510 instanceCounts[drawID], baseInstances[drawID], true)); \
511 } while (0)
512 #define DRAW_ELEMENTS__ \
513 ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], 0, 0, 0, \
514 false, false))
515 #define DRAW_ELEMENTS_INSTANCED_ \
516 ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \
517 instanceCounts[drawID], 0, 0, false, true))
518 #define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \
519 ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \
520 instanceCounts[drawID], baseVertices[drawID], \
521 baseInstances[drawID], false, true))
522
523 #define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi
524
525 #define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \
526 do \
527 { \
528 for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
529 { \
530 if (ANGLE_NOOP_DRAW(instanced)) \
531 { \
532 continue; \
533 } \
534 ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
535 ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
536 ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
537 ASSERT(counts[drawID] > 0); \
538 DRAW_CALL(drawType, instanced, bvbi); \
539 ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \
540 gl::MarkShaderStorageUsage(context); \
541 } \
542 /* reset the uniform to zero for non-multi-draw uses of the program */ \
543 ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(0); \
544 } while (0)
545
multiDrawArrays(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)546 angle::Result Context11::multiDrawArrays(const gl::Context *context,
547 gl::PrimitiveMode mode,
548 const GLint *firsts,
549 const GLsizei *counts,
550 GLsizei drawcount)
551 {
552 gl::Program *programObject = context->getState().getLinkedProgram(context);
553 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
554 if (hasDrawID)
555 {
556 MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0);
557 }
558 else
559 {
560 MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0);
561 }
562
563 return angle::Result::Continue;
564 }
565
multiDrawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)566 angle::Result Context11::multiDrawArraysInstanced(const gl::Context *context,
567 gl::PrimitiveMode mode,
568 const GLint *firsts,
569 const GLsizei *counts,
570 const GLsizei *instanceCounts,
571 GLsizei drawcount)
572 {
573 gl::Program *programObject = context->getState().getLinkedProgram(context);
574 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
575 if (hasDrawID)
576 {
577 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0);
578 }
579 else
580 {
581 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0);
582 }
583
584 return angle::Result::Continue;
585 }
586
multiDrawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect,GLsizei drawcount,GLsizei stride)587 angle::Result Context11::multiDrawArraysIndirect(const gl::Context *context,
588 gl::PrimitiveMode mode,
589 const void *indirect,
590 GLsizei drawcount,
591 GLsizei stride)
592 {
593 return rx::MultiDrawArraysIndirectGeneral(this, context, mode, indirect, drawcount, stride);
594 }
595
multiDrawElements(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)596 angle::Result Context11::multiDrawElements(const gl::Context *context,
597 gl::PrimitiveMode mode,
598 const GLsizei *counts,
599 gl::DrawElementsType type,
600 const GLvoid *const *indices,
601 GLsizei drawcount)
602 {
603 gl::Program *programObject = context->getState().getLinkedProgram(context);
604 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
605 if (hasDrawID)
606 {
607 MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0);
608 }
609 else
610 {
611 MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0);
612 }
613
614 return angle::Result::Continue;
615 }
616
multiDrawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)617 angle::Result Context11::multiDrawElementsInstanced(const gl::Context *context,
618 gl::PrimitiveMode mode,
619 const GLsizei *counts,
620 gl::DrawElementsType type,
621 const GLvoid *const *indices,
622 const GLsizei *instanceCounts,
623 GLsizei drawcount)
624 {
625 gl::Program *programObject = context->getState().getLinkedProgram(context);
626 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
627 if (hasDrawID)
628 {
629 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0);
630 }
631 else
632 {
633 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0);
634 }
635
636 return angle::Result::Continue;
637 }
638
multiDrawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect,GLsizei drawcount,GLsizei stride)639 angle::Result Context11::multiDrawElementsIndirect(const gl::Context *context,
640 gl::PrimitiveMode mode,
641 gl::DrawElementsType type,
642 const void *indirect,
643 GLsizei drawcount,
644 GLsizei stride)
645 {
646 return rx::MultiDrawElementsIndirectGeneral(this, context, mode, type, indirect, drawcount,
647 stride);
648 }
649
multiDrawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)650 angle::Result Context11::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
651 gl::PrimitiveMode mode,
652 const GLint *firsts,
653 const GLsizei *counts,
654 const GLsizei *instanceCounts,
655 const GLuint *baseInstances,
656 GLsizei drawcount)
657 {
658 gl::Program *programObject = context->getState().getLinkedProgram(context);
659 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
660 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
661 ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
662
663 if (hasDrawID && hasBaseInstance)
664 {
665 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1);
666 }
667 else if (hasDrawID)
668 {
669 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0);
670 }
671 else if (hasBaseInstance)
672 {
673 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1);
674 }
675 else
676 {
677 MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0);
678 }
679
680 return angle::Result::Continue;
681 }
682
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)683 angle::Result Context11::multiDrawElementsInstancedBaseVertexBaseInstance(
684 const gl::Context *context,
685 gl::PrimitiveMode mode,
686 const GLsizei *counts,
687 gl::DrawElementsType type,
688 const GLvoid *const *indices,
689 const GLsizei *instanceCounts,
690 const GLint *baseVertices,
691 const GLuint *baseInstances,
692 GLsizei drawcount)
693 {
694 gl::Program *programObject = context->getState().getLinkedProgram(context);
695 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
696 const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
697 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
698 ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
699
700 if (hasDrawID)
701 {
702 if (hasBaseVertex)
703 {
704 if (hasBaseInstance)
705 {
706 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1);
707 }
708 else
709 {
710 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0);
711 }
712 }
713 else
714 {
715 if (hasBaseInstance)
716 {
717 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1);
718 }
719 else
720 {
721 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0);
722 }
723 }
724 }
725 else
726 {
727 if (hasBaseVertex)
728 {
729 if (hasBaseInstance)
730 {
731 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1);
732 }
733 else
734 {
735 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0);
736 }
737 }
738 else
739 {
740 if (hasBaseInstance)
741 {
742 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1);
743 }
744 else
745 {
746 MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0);
747 }
748 }
749 }
750
751 return angle::Result::Continue;
752 }
753
getResetStatus()754 gl::GraphicsResetStatus Context11::getResetStatus()
755 {
756 return mRenderer->getResetStatus();
757 }
758
insertEventMarker(GLsizei length,const char * marker)759 angle::Result Context11::insertEventMarker(GLsizei length, const char *marker)
760 {
761 mRenderer->getDebugAnnotatorContext()->setMarker(marker);
762 return angle::Result::Continue;
763 }
764
pushGroupMarker(GLsizei length,const char * marker)765 angle::Result Context11::pushGroupMarker(GLsizei length, const char *marker)
766 {
767 mRenderer->getDebugAnnotatorContext()->beginEvent(angle::EntryPoint::GLPushGroupMarkerEXT,
768 marker, marker);
769 mMarkerStack.push(std::string(marker));
770 return angle::Result::Continue;
771 }
772
popGroupMarker()773 angle::Result Context11::popGroupMarker()
774 {
775 const char *marker = nullptr;
776 if (!mMarkerStack.empty())
777 {
778 marker = mMarkerStack.top().c_str();
779 mMarkerStack.pop();
780 mRenderer->getDebugAnnotatorContext()->endEvent(marker,
781 angle::EntryPoint::GLPopGroupMarkerEXT);
782 }
783 return angle::Result::Continue;
784 }
785
pushDebugGroup(const gl::Context * context,GLenum source,GLuint id,const std::string & message)786 angle::Result Context11::pushDebugGroup(const gl::Context *context,
787 GLenum source,
788 GLuint id,
789 const std::string &message)
790 {
791 // Fall through to the EXT_debug_marker functions
792 return pushGroupMarker(static_cast<GLsizei>(message.size()), message.c_str());
793 }
794
popDebugGroup(const gl::Context * context)795 angle::Result Context11::popDebugGroup(const gl::Context *context)
796 {
797 // Fall through to the EXT_debug_marker functions
798 return popGroupMarker();
799 }
800
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)801 angle::Result Context11::syncState(const gl::Context *context,
802 const gl::state::DirtyBits dirtyBits,
803 const gl::state::DirtyBits bitMask,
804 const gl::state::ExtendedDirtyBits extendedDirtyBits,
805 const gl::state::ExtendedDirtyBits extendedBitMask,
806 gl::Command command)
807 {
808 mRenderer->getStateManager()->syncState(context, dirtyBits, extendedDirtyBits, command);
809 return angle::Result::Continue;
810 }
811
checkDisjointQuery()812 angle::Result Context11::checkDisjointQuery()
813 {
814 if (!mDisjointQuery.valid())
815 {
816 D3D11_QUERY_DESC queryDesc;
817 queryDesc.Query = gl_d3d11::ConvertQueryType(gl::QueryType::Timestamp);
818 queryDesc.MiscFlags = 0;
819
820 ANGLE_TRY(mRenderer->allocateResource(this, queryDesc, &mDisjointQuery));
821 mRenderer->getDeviceContext()->Begin(mDisjointQuery.get());
822 mDisjointQueryStarted = true;
823 }
824 return angle::Result::Continue;
825 }
826
checkDisjointQueryStatus()827 HRESULT Context11::checkDisjointQueryStatus()
828 {
829 HRESULT result = S_OK;
830 if (mDisjointQuery.valid())
831 {
832 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
833 if (mDisjointQueryStarted)
834 {
835 context->End(mDisjointQuery.get());
836 mDisjointQueryStarted = false;
837 }
838 D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {};
839 result = context->GetData(mDisjointQuery.get(), &timeStats, sizeof(timeStats), 0);
840 if (result == S_OK)
841 {
842 mFrequency = timeStats.Frequency;
843 mDisjoint = timeStats.Disjoint;
844 mDisjointQuery.reset();
845 }
846 }
847 return result;
848 }
849
getDisjointFrequency()850 UINT64 Context11::getDisjointFrequency()
851 {
852 return mFrequency;
853 }
854
setDisjointFrequency(UINT64 frequency)855 void Context11::setDisjointFrequency(UINT64 frequency)
856 {
857 mFrequency = frequency;
858 }
859
setGPUDisjoint()860 void Context11::setGPUDisjoint()
861 {
862 mDisjoint = true;
863 }
864
getGPUDisjoint()865 GLint Context11::getGPUDisjoint()
866 {
867 if (mRenderer->getFeatures().enableTimestampQueries.enabled)
868 {
869 checkDisjointQueryStatus();
870 }
871 bool disjoint = mDisjoint;
872
873 // Disjoint flag is cleared when read
874 mDisjoint = false;
875
876 return disjoint;
877 }
878
getTimestamp()879 GLint64 Context11::getTimestamp()
880 {
881 return mRenderer->getTimestamp();
882 }
883
onMakeCurrent(const gl::Context * context)884 angle::Result Context11::onMakeCurrent(const gl::Context *context)
885 {
886 // Immediately return if the device has been lost.
887 if (!mRenderer->getDevice())
888 {
889 return angle::Result::Continue;
890 }
891
892 return mRenderer->getStateManager()->onMakeCurrent(context);
893 }
894
getNativeCaps() const895 gl::Caps Context11::getNativeCaps() const
896 {
897 gl::Caps caps = mRenderer->getNativeCaps();
898
899 // For pixel shaders, the render targets and unordered access views share the same resource
900 // slots, so the maximum number of fragment shader outputs depends on the current context
901 // version:
902 // - If current context is ES 3.0 and below, we use D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8)
903 // as the value of max draw buffers because UAVs are not used.
904 // - If current context is ES 3.1 and the feature level is 11_0, the RTVs and UAVs share 8
905 // slots. As ES 3.1 requires at least 1 atomic counter buffer in compute shaders, the value
906 // of max combined shader output resources is limited to 7, thus only 7 RTV slots can be
907 // used simultaneously.
908 // - If current context is ES 3.1 and the feature level is 11_1, the RTVs and UAVs share 64
909 // slots. Currently we allocate 60 slots for combined shader output resources, so we can use
910 // at most D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8) RTVs simultaneously.
911 if (mState.getClientVersion() >= gl::ES_3_1 &&
912 mRenderer->getRenderer11DeviceCaps().featureLevel == D3D_FEATURE_LEVEL_11_0)
913 {
914 caps.maxDrawBuffers = caps.maxCombinedShaderOutputResources;
915 caps.maxColorAttachments = caps.maxCombinedShaderOutputResources;
916 }
917
918 return caps;
919 }
920
getNativeTextureCaps() const921 const gl::TextureCapsMap &Context11::getNativeTextureCaps() const
922 {
923 return mRenderer->getNativeTextureCaps();
924 }
925
getNativeExtensions() const926 const gl::Extensions &Context11::getNativeExtensions() const
927 {
928 return mRenderer->getNativeExtensions();
929 }
930
getNativeLimitations() const931 const gl::Limitations &Context11::getNativeLimitations() const
932 {
933 return mRenderer->getNativeLimitations();
934 }
935
getNativePixelLocalStorageOptions() const936 const ShPixelLocalStorageOptions &Context11::getNativePixelLocalStorageOptions() const
937 {
938 return mRenderer->getNativePixelLocalStorageOptions();
939 }
940
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)941 angle::Result Context11::dispatchCompute(const gl::Context *context,
942 GLuint numGroupsX,
943 GLuint numGroupsY,
944 GLuint numGroupsZ)
945 {
946 return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
947 }
948
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)949 angle::Result Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
950 {
951 return mRenderer->dispatchComputeIndirect(context, indirect);
952 }
953
triggerDrawCallProgramRecompilation(const gl::Context * context,gl::PrimitiveMode drawMode)954 angle::Result Context11::triggerDrawCallProgramRecompilation(const gl::Context *context,
955 gl::PrimitiveMode drawMode)
956 {
957 const auto &glState = context->getState();
958 const auto *va11 = GetImplAs<VertexArray11>(glState.getVertexArray());
959 const auto *drawFBO = glState.getDrawFramebuffer();
960 gl::Program *program = glState.getProgram();
961 ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
962
963 programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState);
964 programD3D->updateCachedOutputLayout(context, drawFBO);
965
966 bool recompileVS = !programD3D->hasVertexExecutableForCachedInputLayout();
967 bool recompileGS = !programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode);
968 bool recompilePS = !programD3D->hasPixelExecutableForCachedOutputLayout();
969
970 if (!recompileVS && !recompileGS && !recompilePS)
971 {
972 return angle::Result::Continue;
973 }
974
975 // Load the compiler if necessary and recompile the programs.
976 ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this));
977
978 gl::InfoLog infoLog;
979
980 if (recompileVS)
981 {
982 ShaderExecutableD3D *vertexExe = nullptr;
983 ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(this, &vertexExe, &infoLog));
984 if (!programD3D->hasVertexExecutableForCachedInputLayout())
985 {
986 ASSERT(infoLog.getLength() > 0);
987 ERR() << "Error compiling dynamic vertex executable: " << infoLog.str();
988 ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic vertex executable");
989 }
990 }
991
992 if (recompileGS)
993 {
994 ShaderExecutableD3D *geometryExe = nullptr;
995 ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(this, glState, drawMode,
996 &geometryExe, &infoLog));
997 if (!programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode))
998 {
999 ASSERT(infoLog.getLength() > 0);
1000 ERR() << "Error compiling dynamic geometry executable: " << infoLog.str();
1001 ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic geometry executable");
1002 }
1003 }
1004
1005 if (recompilePS)
1006 {
1007 ShaderExecutableD3D *pixelExe = nullptr;
1008 ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(this, &pixelExe, &infoLog));
1009 if (!programD3D->hasPixelExecutableForCachedOutputLayout())
1010 {
1011 ASSERT(infoLog.getLength() > 0);
1012 ERR() << "Error compiling dynamic pixel executable: " << infoLog.str();
1013 ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic pixel executable");
1014 }
1015 }
1016
1017 // Refresh the program cache entry.
1018 if (mMemoryProgramCache)
1019 {
1020 ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program));
1021 }
1022
1023 return angle::Result::Continue;
1024 }
1025
triggerDispatchCallProgramRecompilation(const gl::Context * context)1026 angle::Result Context11::triggerDispatchCallProgramRecompilation(const gl::Context *context)
1027 {
1028 const auto &glState = context->getState();
1029 gl::Program *program = glState.getProgram();
1030 ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
1031
1032 programD3D->updateCachedComputeImage2DBindLayout(context);
1033
1034 bool recompileCS = !programD3D->hasComputeExecutableForCachedImage2DBindLayout();
1035
1036 if (!recompileCS)
1037 {
1038 return angle::Result::Continue;
1039 }
1040
1041 // Load the compiler if necessary and recompile the programs.
1042 ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this));
1043
1044 gl::InfoLog infoLog;
1045
1046 ShaderExecutableD3D *computeExe = nullptr;
1047 ANGLE_TRY(
1048 programD3D->getComputeExecutableForImage2DBindLayout(context, this, &computeExe, &infoLog));
1049 if (!programD3D->hasComputeExecutableForCachedImage2DBindLayout())
1050 {
1051 ASSERT(infoLog.getLength() > 0);
1052 ERR() << "Dynamic recompilation error log: " << infoLog.str();
1053 ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic compute executable");
1054 }
1055
1056 // Refresh the program cache entry.
1057 if (mMemoryProgramCache)
1058 {
1059 ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program));
1060 }
1061
1062 return angle::Result::Continue;
1063 }
1064
memoryBarrier(const gl::Context * context,GLbitfield barriers)1065 angle::Result Context11::memoryBarrier(const gl::Context *context, GLbitfield barriers)
1066 {
1067 return angle::Result::Continue;
1068 }
1069
memoryBarrierByRegion(const gl::Context * context,GLbitfield barriers)1070 angle::Result Context11::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
1071 {
1072 return angle::Result::Continue;
1073 }
1074
getIncompleteTexture(const gl::Context * context,gl::TextureType type,gl::Texture ** textureOut)1075 angle::Result Context11::getIncompleteTexture(const gl::Context *context,
1076 gl::TextureType type,
1077 gl::Texture **textureOut)
1078 {
1079 return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float, this,
1080 textureOut);
1081 }
1082
initializeMultisampleTextureToBlack(const gl::Context * context,gl::Texture * glTexture)1083 angle::Result Context11::initializeMultisampleTextureToBlack(const gl::Context *context,
1084 gl::Texture *glTexture)
1085 {
1086 ASSERT(glTexture->getType() == gl::TextureType::_2DMultisample);
1087 TextureD3D *textureD3D = GetImplAs<TextureD3D>(glTexture);
1088 gl::ImageIndex index = gl::ImageIndex::Make2DMultisample();
1089 RenderTargetD3D *renderTarget = nullptr;
1090 GLsizei texSamples = textureD3D->getRenderToTextureSamples();
1091 ANGLE_TRY(textureD3D->getRenderTarget(context, index, texSamples, &renderTarget));
1092 return mRenderer->clearRenderTarget(context, renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f),
1093 1.0f, 0);
1094 }
1095
handleResult(HRESULT hr,const char * message,const char * file,const char * function,unsigned int line)1096 void Context11::handleResult(HRESULT hr,
1097 const char *message,
1098 const char *file,
1099 const char *function,
1100 unsigned int line)
1101 {
1102 ASSERT(FAILED(hr));
1103
1104 GLenum glErrorCode = DefaultGLErrorCode(hr);
1105
1106 std::stringstream errorStream;
1107 errorStream << "Internal D3D11 error: " << gl::FmtHR(hr);
1108
1109 if (d3d11::isDeviceLostError(hr))
1110 {
1111 HRESULT removalReason = mRenderer->getDevice()->GetDeviceRemovedReason();
1112 errorStream << " (removal reason: " << gl::FmtHR(removalReason) << ")";
1113 mRenderer->notifyDeviceLost();
1114 }
1115
1116 errorStream << ": " << message;
1117
1118 mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line);
1119 }
1120
getImageLoadContext() const1121 angle::ImageLoadContext Context11::getImageLoadContext() const
1122 {
1123 return getRenderer()->getDisplay()->getImageLoadContext();
1124 }
1125 } // namespace rx
1126