xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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