• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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