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