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