1 //
2 // Copyright (c) 2015 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 
7 // StateManager11.cpp: Defines a class for caching D3D11 state
8 
9 #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
10 
11 #include "common/bitset_utils.h"
12 #include "common/utilities.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/Query.h"
15 #include "libANGLE/VertexArray.h"
16 #include "libANGLE/renderer/d3d/TextureD3D.h"
17 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
18 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
19 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
20 #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
21 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
22 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
23 #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
24 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
25 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
26 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
27 
28 namespace rx
29 {
30 
31 namespace
32 {
ImageIndexConflictsWithSRV(const gl::ImageIndex & index,D3D11_SHADER_RESOURCE_VIEW_DESC desc)33 bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
34 {
35     unsigned mipLevel   = index.mipIndex;
36     GLint layerIndex    = index.layerIndex;
37     GLenum type         = index.type;
38 
39     switch (desc.ViewDimension)
40     {
41         case D3D11_SRV_DIMENSION_TEXTURE2D:
42         {
43             bool allLevels         = (desc.Texture2D.MipLevels == std::numeric_limits<UINT>::max());
44             unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
45             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
46 
47             unsigned mipMin = index.mipIndex;
48             unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
49 
50             return type == GL_TEXTURE_2D &&
51                    gl::RangeUI(mipMin, mipMax)
52                        .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
53         }
54 
55         case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
56         {
57             bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits<UINT>::max());
58             unsigned int maxSrvMip =
59                 desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
60             maxSrvMip = allLevels ? INT_MAX : maxSrvMip;
61 
62             unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
63 
64             // Cube maps can be mapped to Texture2DArray SRVs
65             return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) &&
66                    desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
67                    desc.Texture2DArray.FirstArraySlice <= static_cast<UINT>(layerIndex) &&
68                    static_cast<UINT>(layerIndex) < maxSlice;
69         }
70 
71         case D3D11_SRV_DIMENSION_TEXTURECUBE:
72         {
73             bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits<UINT>::max());
74             unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
75             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
76 
77             return gl::IsCubeMapTextureTarget(type) &&
78                    desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
79         }
80 
81         case D3D11_SRV_DIMENSION_TEXTURE3D:
82         {
83             bool allLevels         = (desc.Texture3D.MipLevels == std::numeric_limits<UINT>::max());
84             unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
85             maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
86 
87             return type == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel &&
88                    mipLevel < maxSrvMip;
89         }
90         default:
91             // We only handle the cases corresponding to valid image indexes
92             UNIMPLEMENTED();
93     }
94 
95     return false;
96 }
97 
98 // Does *not* increment the resource ref count!!
GetViewResource(ID3D11View * view)99 ID3D11Resource *GetViewResource(ID3D11View *view)
100 {
101     ID3D11Resource *resource = nullptr;
102     ASSERT(view);
103     view->GetResource(&resource);
104     resource->Release();
105     return resource;
106 }
107 
GetWrapBits(GLenum wrap)108 int GetWrapBits(GLenum wrap)
109 {
110     switch (wrap)
111     {
112         case GL_CLAMP_TO_EDGE:
113             return 0x1;
114         case GL_REPEAT:
115             return 0x2;
116         case GL_MIRRORED_REPEAT:
117             return 0x3;
118         default:
119             UNREACHABLE();
120             return 0;
121     }
122 }
123 
FindFirstNonInstanced(const std::vector<const TranslatedAttribute * > & currentAttributes)124 Optional<size_t> FindFirstNonInstanced(
125     const std::vector<const TranslatedAttribute *> &currentAttributes)
126 {
127     for (size_t index = 0; index < currentAttributes.size(); ++index)
128     {
129         if (currentAttributes[index]->divisor == 0)
130         {
131             return Optional<size_t>(index);
132         }
133     }
134 
135     return Optional<size_t>::Invalid();
136 }
137 
SortAttributesByLayout(const gl::Program * program,const std::vector<TranslatedAttribute> & vertexArrayAttribs,const std::vector<TranslatedAttribute> & currentValueAttribs,AttribIndexArray * sortedD3DSemanticsOut,std::vector<const TranslatedAttribute * > * sortedAttributesOut)138 void SortAttributesByLayout(const gl::Program *program,
139                             const std::vector<TranslatedAttribute> &vertexArrayAttribs,
140                             const std::vector<TranslatedAttribute> &currentValueAttribs,
141                             AttribIndexArray *sortedD3DSemanticsOut,
142                             std::vector<const TranslatedAttribute *> *sortedAttributesOut)
143 {
144     sortedAttributesOut->clear();
145 
146     const auto &locationToSemantic =
147         GetImplAs<ProgramD3D>(program)->getAttribLocationToD3DSemantics();
148 
149     for (auto locationIndex : program->getActiveAttribLocationsMask())
150     {
151         int d3dSemantic = locationToSemantic[locationIndex];
152         if (sortedAttributesOut->size() <= static_cast<size_t>(d3dSemantic))
153         {
154             sortedAttributesOut->resize(d3dSemantic + 1);
155         }
156 
157         (*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic;
158 
159         const auto *arrayAttrib = &vertexArrayAttribs[locationIndex];
160         if (arrayAttrib->attribute && arrayAttrib->attribute->enabled)
161         {
162             (*sortedAttributesOut)[d3dSemantic] = arrayAttrib;
163         }
164         else
165         {
166             ASSERT(currentValueAttribs[locationIndex].attribute);
167             (*sortedAttributesOut)[d3dSemantic] = &currentValueAttribs[locationIndex];
168         }
169     }
170 }
171 
UpdateUniformBuffer(ID3D11DeviceContext * deviceContext,UniformStorage11 * storage,const d3d11::Buffer * buffer)172 void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext,
173                          UniformStorage11 *storage,
174                          const d3d11::Buffer *buffer)
175 {
176     deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
177                                      0);
178 }
179 
180 }  // anonymous namespace
181 
182 // StateManager11::SRVCache Implementation.
183 
SRVCache()184 StateManager11::SRVCache::SRVCache() : mHighestUsedSRV(0)
185 {
186 }
187 
~SRVCache()188 StateManager11::SRVCache::~SRVCache()
189 {
190 }
191 
update(size_t resourceIndex,ID3D11ShaderResourceView * srv)192 void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
193 {
194     ASSERT(resourceIndex < mCurrentSRVs.size());
195     SRVRecord *record = &mCurrentSRVs[resourceIndex];
196 
197     record->srv = reinterpret_cast<uintptr_t>(srv);
198     if (srv)
199     {
200         record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
201         srv->GetDesc(&record->desc);
202         mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
203     }
204     else
205     {
206         record->resource = 0;
207 
208         if (resourceIndex + 1 == mHighestUsedSRV)
209         {
210             do
211             {
212                 --mHighestUsedSRV;
213             } while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0);
214         }
215     }
216 }
217 
clear()218 void StateManager11::SRVCache::clear()
219 {
220     if (mCurrentSRVs.empty())
221     {
222         return;
223     }
224 
225     memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size());
226     mHighestUsedSRV = 0;
227 }
228 
229 // ShaderConstants11 implementation
230 
ShaderConstants11()231 ShaderConstants11::ShaderConstants11()
232     : mVertexDirty(true),
233       mPixelDirty(true),
234       mComputeDirty(true),
235       mSamplerMetadataVSDirty(true),
236       mSamplerMetadataPSDirty(true),
237       mSamplerMetadataCSDirty(true)
238 {
239 }
240 
~ShaderConstants11()241 ShaderConstants11::~ShaderConstants11()
242 {
243 }
244 
init(const gl::Caps & caps)245 void ShaderConstants11::init(const gl::Caps &caps)
246 {
247     mSamplerMetadataVS.resize(caps.maxVertexTextureImageUnits);
248     mSamplerMetadataPS.resize(caps.maxTextureImageUnits);
249     mSamplerMetadataCS.resize(caps.maxComputeTextureImageUnits);
250 }
251 
getRequiredBufferSize(gl::SamplerType samplerType) const252 size_t ShaderConstants11::getRequiredBufferSize(gl::SamplerType samplerType) const
253 {
254     switch (samplerType)
255     {
256         case gl::SAMPLER_VERTEX:
257             return sizeof(Vertex) + mSamplerMetadataVS.size() * sizeof(SamplerMetadata);
258         case gl::SAMPLER_PIXEL:
259             return sizeof(Pixel) + mSamplerMetadataPS.size() * sizeof(SamplerMetadata);
260         case gl::SAMPLER_COMPUTE:
261             return sizeof(Compute) + mSamplerMetadataCS.size() * sizeof(SamplerMetadata);
262         default:
263             UNREACHABLE();
264             return 0;
265     }
266 }
267 
markDirty()268 void ShaderConstants11::markDirty()
269 {
270     mVertexDirty            = true;
271     mPixelDirty             = true;
272     mComputeDirty           = true;
273     mSamplerMetadataVSDirty = true;
274     mSamplerMetadataPSDirty = true;
275     mSamplerMetadataCSDirty = true;
276 }
277 
updateSamplerMetadata(SamplerMetadata * data,const gl::Texture & texture)278 bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture)
279 {
280     bool dirty             = false;
281     unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
282     GLenum sizedFormat =
283         texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat;
284     if (data->baseLevel != static_cast<int>(baseLevel))
285     {
286         data->baseLevel = static_cast<int>(baseLevel);
287         dirty           = true;
288     }
289 
290     // Some metadata is needed only for integer textures. We avoid updating the constant buffer
291     // unnecessarily by changing the data only in case the texture is an integer texture and
292     // the values have changed.
293     bool needIntegerTextureMetadata = false;
294     // internalFormatBits == 0 means a 32-bit texture in the case of integer textures.
295     int internalFormatBits = 0;
296     switch (sizedFormat)
297     {
298         case GL_RGBA32I:
299         case GL_RGBA32UI:
300         case GL_RGB32I:
301         case GL_RGB32UI:
302         case GL_RG32I:
303         case GL_RG32UI:
304         case GL_R32I:
305         case GL_R32UI:
306             needIntegerTextureMetadata = true;
307             break;
308         case GL_RGBA16I:
309         case GL_RGBA16UI:
310         case GL_RGB16I:
311         case GL_RGB16UI:
312         case GL_RG16I:
313         case GL_RG16UI:
314         case GL_R16I:
315         case GL_R16UI:
316             needIntegerTextureMetadata = true;
317             internalFormatBits         = 16;
318             break;
319         case GL_RGBA8I:
320         case GL_RGBA8UI:
321         case GL_RGB8I:
322         case GL_RGB8UI:
323         case GL_RG8I:
324         case GL_RG8UI:
325         case GL_R8I:
326         case GL_R8UI:
327             needIntegerTextureMetadata = true;
328             internalFormatBits         = 8;
329             break;
330         case GL_RGB10_A2UI:
331             needIntegerTextureMetadata = true;
332             internalFormatBits         = 10;
333             break;
334         default:
335             break;
336     }
337     if (needIntegerTextureMetadata)
338     {
339         if (data->internalFormatBits != internalFormatBits)
340         {
341             data->internalFormatBits = internalFormatBits;
342             dirty                    = true;
343         }
344         // Pack the wrap values into one integer so we can fit all the metadata in one 4-integer
345         // vector.
346         GLenum wrapS  = texture.getWrapS();
347         GLenum wrapT  = texture.getWrapT();
348         GLenum wrapR  = texture.getWrapR();
349         int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
350         if (data->wrapModes != wrapModes)
351         {
352             data->wrapModes = wrapModes;
353             dirty           = true;
354         }
355     }
356 
357     return dirty;
358 }
359 
setComputeWorkGroups(GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)360 void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX,
361                                              GLuint numGroupsY,
362                                              GLuint numGroupsZ)
363 {
364     mCompute.numWorkGroups[0] = numGroupsX;
365     mCompute.numWorkGroups[1] = numGroupsY;
366     mCompute.numWorkGroups[2] = numGroupsZ;
367     mComputeDirty             = true;
368 }
369 
setMultiviewWriteToViewportIndex(GLfloat index)370 void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index)
371 {
372     mVertex.multiviewWriteToViewportIndex = index;
373     mVertexDirty                          = true;
374     mPixel.multiviewWriteToViewportIndex  = index;
375     mPixelDirty                           = true;
376 }
377 
onViewportChange(const gl::Rectangle & glViewport,const D3D11_VIEWPORT & dxViewport,bool is9_3,bool presentPathFast)378 void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
379                                          const D3D11_VIEWPORT &dxViewport,
380                                          bool is9_3,
381                                          bool presentPathFast)
382 {
383     mVertexDirty = true;
384     mPixelDirty  = true;
385 
386     // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
387     // using viewAdjust (like the D3D9 renderer).
388     if (is9_3)
389     {
390         mVertex.viewAdjust[0] = static_cast<float>((glViewport.width - dxViewport.Width) +
391                                                    2 * (glViewport.x - dxViewport.TopLeftX)) /
392                                 dxViewport.Width;
393         mVertex.viewAdjust[1] = static_cast<float>((glViewport.height - dxViewport.Height) +
394                                                    2 * (glViewport.y - dxViewport.TopLeftY)) /
395                                 dxViewport.Height;
396         mVertex.viewAdjust[2] = static_cast<float>(glViewport.width) / dxViewport.Width;
397         mVertex.viewAdjust[3] = static_cast<float>(glViewport.height) / dxViewport.Height;
398     }
399 
400     mPixel.viewCoords[0] = glViewport.width * 0.5f;
401     mPixel.viewCoords[1] = glViewport.height * 0.5f;
402     mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f);
403     mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f);
404 
405     // Instanced pointsprite emulation requires ViewCoords to be defined in the
406     // the vertex shader.
407     mVertex.viewCoords[0] = mPixel.viewCoords[0];
408     mVertex.viewCoords[1] = mPixel.viewCoords[1];
409     mVertex.viewCoords[2] = mPixel.viewCoords[2];
410     mVertex.viewCoords[3] = mPixel.viewCoords[3];
411 
412     const float zNear = dxViewport.MinDepth;
413     const float zFar  = dxViewport.MaxDepth;
414 
415     mPixel.depthFront[0] = (zFar - zNear) * 0.5f;
416     mPixel.depthFront[1] = (zNear + zFar) * 0.5f;
417 
418     mVertex.depthRange[0] = zNear;
419     mVertex.depthRange[1] = zFar;
420     mVertex.depthRange[2] = zFar - zNear;
421 
422     mPixel.depthRange[0] = zNear;
423     mPixel.depthRange[1] = zFar;
424     mPixel.depthRange[2] = zFar - zNear;
425 
426     mPixel.viewScale[0] = 1.0f;
427     mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f;
428     // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
429     // framebuffer's layout is changed.
430 
431     mVertex.viewScale[0] = mPixel.viewScale[0];
432     mVertex.viewScale[1] = mPixel.viewScale[1];
433 }
434 
onSamplerChange(gl::SamplerType samplerType,unsigned int samplerIndex,const gl::Texture & texture)435 void ShaderConstants11::onSamplerChange(gl::SamplerType samplerType,
436                                         unsigned int samplerIndex,
437                                         const gl::Texture &texture)
438 {
439     switch (samplerType)
440     {
441         case gl::SAMPLER_VERTEX:
442             if (updateSamplerMetadata(&mSamplerMetadataVS[samplerIndex], texture))
443             {
444                 mSamplerMetadataVSDirty = true;
445             }
446             break;
447         case gl::SAMPLER_PIXEL:
448             if (updateSamplerMetadata(&mSamplerMetadataPS[samplerIndex], texture))
449             {
450                 mSamplerMetadataPSDirty = true;
451             }
452             break;
453         case gl::SAMPLER_COMPUTE:
454             if (updateSamplerMetadata(&mSamplerMetadataCS[samplerIndex], texture))
455             {
456                 mSamplerMetadataCSDirty = true;
457             }
458             break;
459         default:
460             UNREACHABLE();
461             break;
462     }
463 }
464 
updateBuffer(ID3D11DeviceContext * deviceContext,gl::SamplerType samplerType,const ProgramD3D & programD3D,const d3d11::Buffer & driverConstantBuffer)465 gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext,
466                                           gl::SamplerType samplerType,
467                                           const ProgramD3D &programD3D,
468                                           const d3d11::Buffer &driverConstantBuffer)
469 {
470     bool dirty                 = false;
471     size_t dataSize            = 0;
472     const uint8_t *data        = nullptr;
473     const uint8_t *samplerData = nullptr;
474 
475     switch (samplerType)
476     {
477         case gl::SAMPLER_VERTEX:
478             dirty                   = mVertexDirty || mSamplerMetadataVSDirty;
479             dataSize                = sizeof(Vertex);
480             data                    = reinterpret_cast<const uint8_t *>(&mVertex);
481             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataVS.data());
482             mVertexDirty            = false;
483             mSamplerMetadataVSDirty = false;
484             break;
485         case gl::SAMPLER_PIXEL:
486             dirty                   = mPixelDirty || mSamplerMetadataPSDirty;
487             dataSize                = sizeof(Pixel);
488             data                    = reinterpret_cast<const uint8_t *>(&mPixel);
489             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataPS.data());
490             mPixelDirty             = false;
491             mSamplerMetadataPSDirty = false;
492             break;
493         case gl::SAMPLER_COMPUTE:
494             dirty                   = mComputeDirty || mSamplerMetadataCSDirty;
495             dataSize                = sizeof(Compute);
496             data                    = reinterpret_cast<const uint8_t *>(&mCompute);
497             samplerData             = reinterpret_cast<const uint8_t *>(mSamplerMetadataCS.data());
498             mComputeDirty           = false;
499             mSamplerMetadataCSDirty = false;
500             break;
501         default:
502             UNREACHABLE();
503             break;
504     }
505 
506     ASSERT(driverConstantBuffer.valid());
507 
508     if (!dirty)
509     {
510         return gl::NoError();
511     }
512 
513     // Previous buffer contents are discarded, so we need to refresh the whole buffer.
514     D3D11_MAPPED_SUBRESOURCE mapping = {0};
515     HRESULT result =
516         deviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping);
517 
518     if (FAILED(result))
519     {
520         return gl::OutOfMemory() << "Internal error mapping constant buffer: " << gl::FmtHR(result);
521     }
522 
523     size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(samplerType);
524 
525     memcpy(mapping.pData, data, dataSize);
526     memcpy(reinterpret_cast<uint8_t *>(mapping.pData) + dataSize, samplerData, samplerDataBytes);
527 
528     deviceContext->Unmap(driverConstantBuffer.get(), 0);
529 
530     return gl::NoError();
531 }
532 
533 static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
534                                     GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT,
535                                     GL_COMMANDS_COMPLETED_CHROMIUM};
536 
StateManager11(Renderer11 * renderer)537 StateManager11::StateManager11(Renderer11 *renderer)
538     : mRenderer(renderer),
539       mInternalDirtyBits(),
540       mCurBlendColor(0, 0, 0, 0),
541       mCurSampleMask(0),
542       mCurStencilRef(0),
543       mCurStencilBackRef(0),
544       mCurStencilSize(0),
545       mCurScissorEnabled(false),
546       mCurScissorRect(),
547       mCurViewport(),
548       mCurNear(0.0f),
549       mCurFar(0.0f),
550       mViewportBounds(),
551       mRenderTargetIsDirty(true),
552       mCurPresentPathFastEnabled(false),
553       mCurPresentPathFastColorBufferHeight(0),
554       mDirtyCurrentValueAttribs(),
555       mCurrentValueAttribs(),
556       mCurrentInputLayout(),
557       mInputLayoutIsDirty(false),
558       mVertexAttribsNeedTranslation(false),
559       mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
560       mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
561       mDirtySwizzles(false),
562       mAppliedIB(nullptr),
563       mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
564       mAppliedIBOffset(0),
565       mIndexBufferIsDirty(false),
566       mVertexDataManager(renderer),
567       mIndexDataManager(renderer),
568       mIsMultiviewEnabled(false),
569       mEmptySerial(mRenderer->generateSerial()),
570       mIsTransformFeedbackCurrentlyActiveUnpaused(false)
571 {
572     mCurBlendState.blend                 = false;
573     mCurBlendState.sourceBlendRGB        = GL_ONE;
574     mCurBlendState.destBlendRGB          = GL_ZERO;
575     mCurBlendState.sourceBlendAlpha      = GL_ONE;
576     mCurBlendState.destBlendAlpha        = GL_ZERO;
577     mCurBlendState.blendEquationRGB      = GL_FUNC_ADD;
578     mCurBlendState.blendEquationAlpha    = GL_FUNC_ADD;
579     mCurBlendState.colorMaskRed          = true;
580     mCurBlendState.colorMaskBlue         = true;
581     mCurBlendState.colorMaskGreen        = true;
582     mCurBlendState.colorMaskAlpha        = true;
583     mCurBlendState.sampleAlphaToCoverage = false;
584     mCurBlendState.dither                = false;
585 
586     mCurDepthStencilState.depthTest                = false;
587     mCurDepthStencilState.depthFunc                = GL_LESS;
588     mCurDepthStencilState.depthMask                = true;
589     mCurDepthStencilState.stencilTest              = false;
590     mCurDepthStencilState.stencilMask              = true;
591     mCurDepthStencilState.stencilFail              = GL_KEEP;
592     mCurDepthStencilState.stencilPassDepthFail     = GL_KEEP;
593     mCurDepthStencilState.stencilPassDepthPass     = GL_KEEP;
594     mCurDepthStencilState.stencilWritemask         = static_cast<GLuint>(-1);
595     mCurDepthStencilState.stencilBackFunc          = GL_ALWAYS;
596     mCurDepthStencilState.stencilBackMask          = static_cast<GLuint>(-1);
597     mCurDepthStencilState.stencilBackFail          = GL_KEEP;
598     mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
599     mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
600     mCurDepthStencilState.stencilBackWritemask     = static_cast<GLuint>(-1);
601 
602     mCurRasterState.rasterizerDiscard   = false;
603     mCurRasterState.cullFace            = false;
604     mCurRasterState.cullMode            = gl::CullFaceMode::Back;
605     mCurRasterState.frontFace           = GL_CCW;
606     mCurRasterState.polygonOffsetFill   = false;
607     mCurRasterState.polygonOffsetFactor = 0.0f;
608     mCurRasterState.polygonOffsetUnits  = 0.0f;
609     mCurRasterState.pointDrawMode       = false;
610     mCurRasterState.multiSample         = false;
611 
612     // Start with all internal dirty bits set.
613     mInternalDirtyBits.set();
614 
615     // Initially all current value attributes must be updated on first use.
616     mDirtyCurrentValueAttribs.set();
617 
618     mCurrentVertexBuffers.fill(nullptr);
619     mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
620     mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
621 }
622 
~StateManager11()623 StateManager11::~StateManager11()
624 {
625 }
626 
627 template <typename SRVType>
setShaderResourceInternal(gl::SamplerType shaderType,UINT resourceSlot,const SRVType * srv)628 void StateManager11::setShaderResourceInternal(gl::SamplerType shaderType,
629                                                UINT resourceSlot,
630                                                const SRVType *srv)
631 {
632     auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
633 
634     ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
635     const SRVRecord &record = currentSRVs[resourceSlot];
636 
637     if (record.srv != reinterpret_cast<uintptr_t>(srv))
638     {
639         ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
640         ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr;
641         if (shaderType == gl::SAMPLER_VERTEX)
642         {
643             deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
644         }
645         else
646         {
647             deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
648         }
649 
650         currentSRVs.update(resourceSlot, srvPtr);
651     }
652 }
653 
updateStencilSizeIfChanged(bool depthStencilInitialized,unsigned int stencilSize)654 void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
655                                                 unsigned int stencilSize)
656 {
657     if (!depthStencilInitialized || stencilSize != mCurStencilSize)
658     {
659         mCurStencilSize = stencilSize;
660         mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
661     }
662 }
663 
checkPresentPath(const gl::Context * context)664 void StateManager11::checkPresentPath(const gl::Context *context)
665 {
666     if (!mRenderer->presentPathFastEnabled())
667         return;
668 
669     const auto *framebuffer          = context->getGLState().getDrawFramebuffer();
670     const auto *firstColorAttachment = framebuffer->getFirstColorbuffer();
671     const bool presentPathFastActive = UsePresentPathFast(mRenderer, firstColorAttachment);
672 
673     const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0;
674 
675     if ((mCurPresentPathFastEnabled != presentPathFastActive) ||
676         (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight)))
677     {
678         mCurPresentPathFastEnabled           = presentPathFastActive;
679         mCurPresentPathFastColorBufferHeight = colorBufferHeight;
680 
681         // Scissor rect may need to be vertically inverted
682         mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
683 
684         // Cull Mode may need to be inverted
685         mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
686 
687         // Viewport may need to be vertically inverted
688         invalidateViewport(context);
689     }
690 }
691 
updateStateForCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)692 gl::Error StateManager11::updateStateForCompute(const gl::Context *context,
693                                                 GLuint numGroupsX,
694                                                 GLuint numGroupsY,
695                                                 GLuint numGroupsZ)
696 {
697     mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ);
698 
699     // TODO(jmadill): Use dirty bits.
700     const auto &glState = context->getGLState();
701     auto *programD3D    = GetImplAs<ProgramD3D>(glState.getProgram());
702     programD3D->updateSamplerMapping();
703 
704     // TODO(jmadill): Use dirty bits.
705     ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_COMPUTE));
706 
707     // TODO(jmadill): More complete implementation.
708     ANGLE_TRY(syncTextures(context));
709 
710     // TODO(Xinghua): applyUniformBuffers for compute shader.
711 
712     return gl::NoError();
713 }
714 
syncState(const gl::Context * context,const gl::State::DirtyBits & dirtyBits)715 void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
716 {
717     if (!dirtyBits.any())
718     {
719         return;
720     }
721 
722     const auto &state = context->getGLState();
723 
724     for (auto dirtyBit : dirtyBits)
725     {
726         switch (dirtyBit)
727         {
728             case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
729             {
730                 const gl::BlendState &blendState = state.getBlendState();
731                 if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB ||
732                     blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha)
733                 {
734                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
735                 }
736                 break;
737             }
738             case gl::State::DIRTY_BIT_BLEND_FUNCS:
739             {
740                 const gl::BlendState &blendState = state.getBlendState();
741                 if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB ||
742                     blendState.destBlendRGB != mCurBlendState.destBlendRGB ||
743                     blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha ||
744                     blendState.destBlendAlpha != mCurBlendState.destBlendAlpha)
745                 {
746                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
747                 }
748                 break;
749             }
750             case gl::State::DIRTY_BIT_BLEND_ENABLED:
751                 if (state.getBlendState().blend != mCurBlendState.blend)
752                 {
753                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
754                 }
755                 break;
756             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
757                 if (state.getBlendState().sampleAlphaToCoverage !=
758                     mCurBlendState.sampleAlphaToCoverage)
759                 {
760                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
761                 }
762                 break;
763             case gl::State::DIRTY_BIT_DITHER_ENABLED:
764                 if (state.getBlendState().dither != mCurBlendState.dither)
765                 {
766                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
767                 }
768                 break;
769             case gl::State::DIRTY_BIT_COLOR_MASK:
770             {
771                 const gl::BlendState &blendState = state.getBlendState();
772                 if (blendState.colorMaskRed != mCurBlendState.colorMaskRed ||
773                     blendState.colorMaskGreen != mCurBlendState.colorMaskGreen ||
774                     blendState.colorMaskBlue != mCurBlendState.colorMaskBlue ||
775                     blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha)
776                 {
777                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
778                 }
779                 break;
780             }
781             case gl::State::DIRTY_BIT_BLEND_COLOR:
782                 if (state.getBlendColor() != mCurBlendColor)
783                 {
784                     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
785                 }
786                 break;
787             case gl::State::DIRTY_BIT_DEPTH_MASK:
788                 if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask)
789                 {
790                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
791                 }
792                 break;
793             case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
794                 if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest)
795                 {
796                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
797                 }
798                 break;
799             case gl::State::DIRTY_BIT_DEPTH_FUNC:
800                 if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc)
801                 {
802                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
803                 }
804                 break;
805             case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
806                 if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest)
807                 {
808                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
809                 }
810                 break;
811             case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
812             {
813                 const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
814                 if (depthStencil.stencilFunc != mCurDepthStencilState.stencilFunc ||
815                     depthStencil.stencilMask != mCurDepthStencilState.stencilMask ||
816                     state.getStencilRef() != mCurStencilRef)
817                 {
818                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
819                 }
820                 break;
821             }
822             case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
823             {
824                 const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
825                 if (depthStencil.stencilBackFunc != mCurDepthStencilState.stencilBackFunc ||
826                     depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask ||
827                     state.getStencilBackRef() != mCurStencilBackRef)
828                 {
829                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
830                 }
831                 break;
832             }
833             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
834                 if (state.getDepthStencilState().stencilWritemask !=
835                     mCurDepthStencilState.stencilWritemask)
836                 {
837                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
838                 }
839                 break;
840             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
841                 if (state.getDepthStencilState().stencilBackWritemask !=
842                     mCurDepthStencilState.stencilBackWritemask)
843                 {
844                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
845                 }
846                 break;
847             case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
848             {
849                 const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
850                 if (depthStencil.stencilFail != mCurDepthStencilState.stencilFail ||
851                     depthStencil.stencilPassDepthFail !=
852                         mCurDepthStencilState.stencilPassDepthFail ||
853                     depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass)
854                 {
855                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
856                 }
857                 break;
858             }
859             case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
860             {
861                 const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
862                 if (depthStencil.stencilBackFail != mCurDepthStencilState.stencilBackFail ||
863                     depthStencil.stencilBackPassDepthFail !=
864                         mCurDepthStencilState.stencilBackPassDepthFail ||
865                     depthStencil.stencilBackPassDepthPass !=
866                         mCurDepthStencilState.stencilBackPassDepthPass)
867                 {
868                     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
869                 }
870                 break;
871             }
872             case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
873                 if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
874                 {
875                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
876                 }
877                 break;
878             case gl::State::DIRTY_BIT_CULL_FACE:
879                 if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
880                 {
881                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
882                 }
883                 break;
884             case gl::State::DIRTY_BIT_FRONT_FACE:
885                 if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
886                 {
887                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
888                 }
889                 break;
890             case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
891                 if (state.getRasterizerState().polygonOffsetFill !=
892                     mCurRasterState.polygonOffsetFill)
893                 {
894                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
895                 }
896                 break;
897             case gl::State::DIRTY_BIT_POLYGON_OFFSET:
898             {
899                 const gl::RasterizerState &rasterState = state.getRasterizerState();
900                 if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
901                     rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
902                 {
903                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
904                 }
905                 break;
906             }
907             case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
908                 if (state.getRasterizerState().rasterizerDiscard !=
909                     mCurRasterState.rasterizerDiscard)
910                 {
911                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
912 
913                     // Enabling/disabling rasterizer discard affects the pixel shader.
914                     invalidateShaders();
915                 }
916                 break;
917             case gl::State::DIRTY_BIT_SCISSOR:
918                 if (state.getScissor() != mCurScissorRect)
919                 {
920                     mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
921                 }
922                 break;
923             case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
924                 if (state.isScissorTestEnabled() != mCurScissorEnabled)
925                 {
926                     mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
927                     // Rasterizer state update needs mCurScissorsEnabled and updates when it changes
928                     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
929                 }
930                 break;
931             case gl::State::DIRTY_BIT_DEPTH_RANGE:
932                 if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar)
933                 {
934                     invalidateViewport(context);
935                 }
936                 break;
937             case gl::State::DIRTY_BIT_VIEWPORT:
938                 if (state.getViewport() != mCurViewport)
939                 {
940                     invalidateViewport(context);
941                 }
942                 break;
943             case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
944                 invalidateRenderTarget();
945                 if (mIsMultiviewEnabled)
946                 {
947                     handleMultiviewDrawFramebufferChange(context);
948                 }
949                 break;
950             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
951                 invalidateVertexBuffer();
952                 // Force invalidate the current value attributes, since the VertexArray11 keeps an
953                 // internal cache of TranslatedAttributes, and they CurrentValue attributes are
954                 // owned by the StateManager11/Context.
955                 mDirtyCurrentValueAttribs.set();
956                 // Invalidate the cached index buffer.
957                 mIndexBufferIsDirty = true;
958                 break;
959             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
960                 invalidateTexturesAndSamplers();
961                 break;
962             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
963                 invalidateTexturesAndSamplers();
964                 break;
965             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
966             {
967                 mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
968                 invalidateVertexBuffer();
969                 invalidateRenderTarget();
970                 invalidateTexturesAndSamplers();
971                 invalidateProgramUniforms();
972                 invalidateProgramUniformBuffers();
973                 gl::VertexArray *vao = state.getVertexArray();
974                 if (mIsMultiviewEnabled && vao != nullptr)
975                 {
976                     // If ANGLE_multiview is enabled, the attribute divisor has to be updated for
977                     // each binding.
978                     VertexArray11 *vao11       = GetImplAs<VertexArray11>(vao);
979                     const gl::Program *program = state.getProgram();
980                     int numViews               = 1;
981                     if (program != nullptr && program->usesMultiview())
982                     {
983                         numViews = program->getNumViews();
984                     }
985                     vao11->markAllAttributeDivisorsForAdjustment(numViews);
986                 }
987                 break;
988             }
989             case gl::State::DIRTY_BIT_CURRENT_VALUES:
990             {
991                 for (auto attribIndex : state.getAndResetDirtyCurrentValues())
992                 {
993                     invalidateCurrentValueAttrib(attribIndex);
994                 }
995             }
996             default:
997                 break;
998         }
999     }
1000 
1001     // TODO(jmadill): Input layout and vertex buffer state.
1002 }
1003 
handleMultiviewDrawFramebufferChange(const gl::Context * context)1004 void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context)
1005 {
1006     const auto &glState                    = context->getGLState();
1007     const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
1008     ASSERT(drawFramebuffer != nullptr);
1009 
1010     // Update viewport offsets.
1011     const std::vector<gl::Offset> *attachmentViewportOffsets =
1012         drawFramebuffer->getViewportOffsets();
1013     const std::vector<gl::Offset> &viewportOffsets =
1014         attachmentViewportOffsets != nullptr
1015             ? *attachmentViewportOffsets
1016             : gl::FramebufferAttachment::GetDefaultViewportOffsetVector();
1017     if (mViewportOffsets != viewportOffsets)
1018     {
1019         mViewportOffsets = viewportOffsets;
1020 
1021         // Because new viewport offsets are to be applied, we have to mark the internal viewport and
1022         // scissor state as dirty.
1023         invalidateViewport(context);
1024         mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
1025     }
1026     switch (drawFramebuffer->getMultiviewLayout())
1027     {
1028         case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
1029             mShaderConstants.setMultiviewWriteToViewportIndex(1.0f);
1030             break;
1031         case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
1032             // Because the base view index is applied as an offset to the 2D texture array when the
1033             // RTV is created, we just have to pass a boolean to select which code path is to be
1034             // used.
1035             mShaderConstants.setMultiviewWriteToViewportIndex(0.0f);
1036             break;
1037         default:
1038             // There is no need to update the value in the constant buffer if the active framebuffer
1039             // object does not have a multiview layout.
1040             break;
1041     }
1042 }
1043 
syncBlendState(const gl::Context * context,const gl::Framebuffer * framebuffer,const gl::BlendState & blendState,const gl::ColorF & blendColor,unsigned int sampleMask)1044 gl::Error StateManager11::syncBlendState(const gl::Context *context,
1045                                          const gl::Framebuffer *framebuffer,
1046                                          const gl::BlendState &blendState,
1047                                          const gl::ColorF &blendColor,
1048                                          unsigned int sampleMask)
1049 {
1050     const d3d11::BlendState *dxBlendState = nullptr;
1051     const d3d11::BlendStateKey &key =
1052         RenderStateCache::GetBlendStateKey(context, framebuffer, blendState);
1053 
1054     ANGLE_TRY(mRenderer->getBlendState(key, &dxBlendState));
1055 
1056     ASSERT(dxBlendState != nullptr);
1057 
1058     float blendColors[4] = {0.0f};
1059     if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
1060         blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
1061         blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
1062         blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
1063     {
1064         blendColors[0] = blendColor.red;
1065         blendColors[1] = blendColor.green;
1066         blendColors[2] = blendColor.blue;
1067         blendColors[3] = blendColor.alpha;
1068     }
1069     else
1070     {
1071         blendColors[0] = blendColor.alpha;
1072         blendColors[1] = blendColor.alpha;
1073         blendColors[2] = blendColor.alpha;
1074         blendColors[3] = blendColor.alpha;
1075     }
1076 
1077     mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask);
1078 
1079     mCurBlendState = blendState;
1080     mCurBlendColor = blendColor;
1081     mCurSampleMask = sampleMask;
1082 
1083     return gl::NoError();
1084 }
1085 
syncDepthStencilState(const gl::State & glState)1086 gl::Error StateManager11::syncDepthStencilState(const gl::State &glState)
1087 {
1088     mCurDepthStencilState = glState.getDepthStencilState();
1089     mCurStencilRef        = glState.getStencilRef();
1090     mCurStencilBackRef    = glState.getStencilBackRef();
1091 
1092     // get the maximum size of the stencil ref
1093     unsigned int maxStencil = 0;
1094     if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
1095     {
1096         maxStencil = (1 << mCurStencilSize) - 1;
1097     }
1098     ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
1099            (mCurDepthStencilState.stencilBackWritemask & maxStencil));
1100     ASSERT(mCurStencilRef == mCurStencilBackRef);
1101     ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
1102            (mCurDepthStencilState.stencilBackMask & maxStencil));
1103 
1104     gl::DepthStencilState modifiedGLState = glState.getDepthStencilState();
1105 
1106     ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid());
1107 
1108     if (mCurDisableDepth.value())
1109     {
1110         modifiedGLState.depthTest = false;
1111         modifiedGLState.depthMask = false;
1112     }
1113 
1114     if (mCurDisableStencil.value())
1115     {
1116         modifiedGLState.stencilWritemask     = 0;
1117         modifiedGLState.stencilBackWritemask = 0;
1118         modifiedGLState.stencilTest          = false;
1119     }
1120 
1121     const d3d11::DepthStencilState *d3dState = nullptr;
1122     ANGLE_TRY(mRenderer->getDepthStencilState(modifiedGLState, &d3dState));
1123     ASSERT(d3dState);
1124 
1125     // Max D3D11 stencil reference value is 0xFF,
1126     // corresponding to the max 8 bits in a stencil buffer
1127     // GL specifies we should clamp the ref value to the
1128     // nearest bit depth when doing stencil ops
1129     static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
1130                   "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
1131     static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
1132                   "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
1133     UINT dxStencilRef = std::min<UINT>(mCurStencilRef, 0xFFu);
1134 
1135     mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef);
1136 
1137     return gl::NoError();
1138 }
1139 
syncRasterizerState(const gl::Context * context,bool pointDrawMode)1140 gl::Error StateManager11::syncRasterizerState(const gl::Context *context, bool pointDrawMode)
1141 {
1142     // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
1143     gl::RasterizerState rasterState = context->getGLState().getRasterizerState();
1144     rasterState.pointDrawMode       = pointDrawMode;
1145     rasterState.multiSample         = mCurRasterState.multiSample;
1146 
1147     ID3D11RasterizerState *dxRasterState = nullptr;
1148 
1149     if (mCurPresentPathFastEnabled)
1150     {
1151         gl::RasterizerState modifiedRasterState = rasterState;
1152 
1153         // If prseent path fast is active then we need invert the front face state.
1154         // This ensures that both gl_FrontFacing is correct, and front/back culling
1155         // is performed correctly.
1156         if (modifiedRasterState.frontFace == GL_CCW)
1157         {
1158             modifiedRasterState.frontFace = GL_CW;
1159         }
1160         else
1161         {
1162             ASSERT(modifiedRasterState.frontFace == GL_CW);
1163             modifiedRasterState.frontFace = GL_CCW;
1164         }
1165 
1166         ANGLE_TRY(
1167             mRenderer->getRasterizerState(modifiedRasterState, mCurScissorEnabled, &dxRasterState));
1168     }
1169     else
1170     {
1171         ANGLE_TRY(mRenderer->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState));
1172     }
1173 
1174     mRenderer->getDeviceContext()->RSSetState(dxRasterState);
1175 
1176     mCurRasterState = rasterState;
1177 
1178     return gl::NoError();
1179 }
1180 
syncScissorRectangle(const gl::Rectangle & scissor,bool enabled)1181 void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool enabled)
1182 {
1183     int modifiedScissorY = scissor.y;
1184     if (mCurPresentPathFastEnabled)
1185     {
1186         modifiedScissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y;
1187     }
1188 
1189     if (enabled)
1190     {
1191         std::array<D3D11_RECT, gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS> rectangles;
1192         const UINT numRectangles = static_cast<UINT>(mViewportOffsets.size());
1193         for (UINT i = 0u; i < numRectangles; ++i)
1194         {
1195             D3D11_RECT &rect = rectangles[i];
1196             int x            = scissor.x + mViewportOffsets[i].x;
1197             int y            = modifiedScissorY + mViewportOffsets[i].y;
1198             rect.left        = std::max(0, x);
1199             rect.top         = std::max(0, y);
1200             rect.right       = x + std::max(0, scissor.width);
1201             rect.bottom      = y + std::max(0, scissor.height);
1202         }
1203         mRenderer->getDeviceContext()->RSSetScissorRects(numRectangles, rectangles.data());
1204     }
1205 
1206     mCurScissorRect      = scissor;
1207     mCurScissorEnabled   = enabled;
1208 }
1209 
syncViewport(const gl::Context * context)1210 void StateManager11::syncViewport(const gl::Context *context)
1211 {
1212     const auto &glState          = context->getGLState();
1213     gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
1214     float actualZNear            = gl::clamp01(glState.getNearPlane());
1215     float actualZFar             = gl::clamp01(glState.getFarPlane());
1216 
1217     const auto &caps         = context->getCaps();
1218     int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
1219     int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
1220     int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
1221     int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
1222 
1223     bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3;
1224 
1225     if (is9_3)
1226     {
1227         // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
1228         dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
1229         dxMaxViewportBoundsY = static_cast<int>(mViewportBounds.height);
1230         dxMinViewportBoundsX = 0;
1231         dxMinViewportBoundsY = 0;
1232     }
1233 
1234     const auto &viewport = glState.getViewport();
1235     std::array<D3D11_VIEWPORT, gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS> dxViewports;
1236     const UINT numRectangles = static_cast<UINT>(mViewportOffsets.size());
1237 
1238     int dxViewportTopLeftX = 0;
1239     int dxViewportTopLeftY = 0;
1240     int dxViewportWidth    = 0;
1241     int dxViewportHeight   = 0;
1242 
1243     for (UINT i = 0u; i < numRectangles; ++i)
1244     {
1245         dxViewportTopLeftX = gl::clamp(viewport.x + mViewportOffsets[i].x, dxMinViewportBoundsX,
1246                                        dxMaxViewportBoundsX);
1247         dxViewportTopLeftY = gl::clamp(viewport.y + mViewportOffsets[i].y, dxMinViewportBoundsY,
1248                                        dxMaxViewportBoundsY);
1249         dxViewportWidth  = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
1250         dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
1251 
1252         D3D11_VIEWPORT &dxViewport = dxViewports[i];
1253         dxViewport.TopLeftX        = static_cast<float>(dxViewportTopLeftX);
1254         if (mCurPresentPathFastEnabled)
1255         {
1256             // When present path fast is active and we're rendering to framebuffer 0, we must invert
1257             // the viewport in Y-axis.
1258             // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave
1259             // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the
1260             // unaltered dxViewportTopLeftY value.
1261             dxViewport.TopLeftY = static_cast<float>(mCurPresentPathFastColorBufferHeight -
1262                                                      dxViewportTopLeftY - dxViewportHeight);
1263         }
1264         else
1265         {
1266             dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
1267         }
1268 
1269         // The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering
1270         // will be limited to a rectangle having a lower left of (0, 0) and an upper right of
1271         // (width, height), where width and height are the framebuffer object's default width
1272         // and height." See http://anglebug.com/1594
1273         // If the Framebuffer has no color attachment and the default width or height is smaller
1274         // than the current viewport, use the smaller of the two sizes.
1275         // If framebuffer default width or height is 0, the params should not set.
1276         if (!framebuffer->getFirstNonNullAttachment() &&
1277             (framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight()))
1278         {
1279             dxViewport.Width =
1280                 static_cast<GLfloat>(std::min(viewport.width, framebuffer->getDefaultWidth()));
1281             dxViewport.Height =
1282                 static_cast<GLfloat>(std::min(viewport.height, framebuffer->getDefaultHeight()));
1283         }
1284         else
1285         {
1286             dxViewport.Width  = static_cast<float>(dxViewportWidth);
1287             dxViewport.Height = static_cast<float>(dxViewportHeight);
1288         }
1289         dxViewport.MinDepth = actualZNear;
1290         dxViewport.MaxDepth = actualZFar;
1291     }
1292 
1293     mRenderer->getDeviceContext()->RSSetViewports(numRectangles, dxViewports.data());
1294 
1295     mCurViewport = viewport;
1296     mCurNear     = actualZNear;
1297     mCurFar      = actualZFar;
1298 
1299     const D3D11_VIEWPORT adjustViewport = {static_cast<FLOAT>(dxViewportTopLeftX),
1300                                            static_cast<FLOAT>(dxViewportTopLeftY),
1301                                            static_cast<FLOAT>(dxViewportWidth),
1302                                            static_cast<FLOAT>(dxViewportHeight),
1303                                            actualZNear,
1304                                            actualZFar};
1305     mShaderConstants.onViewportChange(viewport, adjustViewport, is9_3, mCurPresentPathFastEnabled);
1306 }
1307 
invalidateRenderTarget()1308 void StateManager11::invalidateRenderTarget()
1309 {
1310     mRenderTargetIsDirty = true;
1311 }
1312 
processFramebufferInvalidation(const gl::Context * context)1313 void StateManager11::processFramebufferInvalidation(const gl::Context *context)
1314 {
1315     if (!mRenderTargetIsDirty)
1316     {
1317         return;
1318     }
1319 
1320     ASSERT(context);
1321 
1322     mRenderTargetIsDirty = false;
1323     mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
1324 
1325     // The pixel shader is dependent on the output layout.
1326     invalidateShaders();
1327 
1328     // The D3D11 blend state is heavily dependent on the current render target.
1329     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
1330 
1331     gl::Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
1332     ASSERT(fbo);
1333 
1334     // Disable the depth test/depth write if we are using a stencil-only attachment.
1335     // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read
1336     // nor write to the unused depth part of this emulated texture.
1337     bool disableDepth = (!fbo->hasDepth() && fbo->hasStencil());
1338 
1339     // Similarly we disable the stencil portion of the DS attachment if the app only binds depth.
1340     bool disableStencil = (fbo->hasDepth() && !fbo->hasStencil());
1341 
1342     if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() ||
1343         !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value())
1344     {
1345         mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
1346         mCurDisableDepth   = disableDepth;
1347         mCurDisableStencil = disableStencil;
1348     }
1349 
1350     bool multiSample = (fbo->getCachedSamples(context) != 0);
1351     if (multiSample != mCurRasterState.multiSample)
1352     {
1353         mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
1354         mCurRasterState.multiSample = multiSample;
1355     }
1356 
1357     checkPresentPath(context);
1358 
1359     if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
1360     {
1361         const auto *firstAttachment = fbo->getFirstNonNullAttachment();
1362         if (firstAttachment)
1363         {
1364             const auto &size = firstAttachment->getSize();
1365             if (mViewportBounds.width != size.width || mViewportBounds.height != size.height)
1366             {
1367                 mViewportBounds = gl::Extents(size.width, size.height, 1);
1368                 invalidateViewport(context);
1369             }
1370         }
1371     }
1372 }
1373 
invalidateBoundViews()1374 void StateManager11::invalidateBoundViews()
1375 {
1376     mCurVertexSRVs.clear();
1377     mCurPixelSRVs.clear();
1378 
1379     invalidateRenderTarget();
1380 }
1381 
invalidateVertexBuffer()1382 void StateManager11::invalidateVertexBuffer()
1383 {
1384     unsigned int limit = std::min<unsigned int>(mRenderer->getNativeCaps().maxVertexAttributes,
1385                                                 gl::MAX_VERTEX_ATTRIBS);
1386     mDirtyVertexBufferRange = gl::RangeUI(0, limit);
1387     mInputLayoutIsDirty     = true;
1388     mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
1389     invalidateVertexAttributeTranslation();
1390 }
1391 
invalidateViewport(const gl::Context * context)1392 void StateManager11::invalidateViewport(const gl::Context *context)
1393 {
1394     mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
1395 
1396     // Viewport affects the driver constants.
1397     invalidateDriverUniforms();
1398 }
1399 
invalidateTexturesAndSamplers()1400 void StateManager11::invalidateTexturesAndSamplers()
1401 {
1402     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
1403     invalidateSwizzles();
1404 
1405     // Texture state affects the driver uniforms (base level, etc).
1406     invalidateDriverUniforms();
1407 }
1408 
invalidateSwizzles()1409 void StateManager11::invalidateSwizzles()
1410 {
1411     mDirtySwizzles = true;
1412 }
1413 
invalidateProgramUniforms()1414 void StateManager11::invalidateProgramUniforms()
1415 {
1416     mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
1417 }
1418 
invalidateDriverUniforms()1419 void StateManager11::invalidateDriverUniforms()
1420 {
1421     mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
1422 }
1423 
invalidateProgramUniformBuffers()1424 void StateManager11::invalidateProgramUniformBuffers()
1425 {
1426     mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS);
1427 }
1428 
invalidateConstantBuffer(unsigned int slot)1429 void StateManager11::invalidateConstantBuffer(unsigned int slot)
1430 {
1431     if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER)
1432     {
1433         invalidateDriverUniforms();
1434     }
1435     else if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK)
1436     {
1437         invalidateProgramUniforms();
1438     }
1439     else
1440     {
1441         invalidateProgramUniformBuffers();
1442     }
1443 }
1444 
invalidateShaders()1445 void StateManager11::invalidateShaders()
1446 {
1447     mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
1448 }
1449 
setRenderTarget(ID3D11RenderTargetView * rtv,ID3D11DepthStencilView * dsv)1450 void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv)
1451 {
1452     if ((rtv && unsetConflictingView(rtv)) || (dsv && unsetConflictingView(dsv)))
1453     {
1454         mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
1455     }
1456 
1457     mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
1458     mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
1459 }
1460 
setRenderTargets(ID3D11RenderTargetView ** rtvs,UINT numRTVs,ID3D11DepthStencilView * dsv)1461 void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
1462                                       UINT numRTVs,
1463                                       ID3D11DepthStencilView *dsv)
1464 {
1465     bool anyDirty = false;
1466 
1467     for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex)
1468     {
1469         anyDirty = anyDirty || unsetConflictingView(rtvs[rtvIndex]);
1470     }
1471 
1472     if (dsv)
1473     {
1474         anyDirty = anyDirty || unsetConflictingView(dsv);
1475     }
1476 
1477     if (anyDirty)
1478     {
1479         mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
1480     }
1481 
1482     mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
1483     mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
1484 }
1485 
invalidateVertexAttributeTranslation()1486 void StateManager11::invalidateVertexAttributeTranslation()
1487 {
1488     mVertexAttribsNeedTranslation = true;
1489 }
1490 
onBeginQuery(Query11 * query)1491 void StateManager11::onBeginQuery(Query11 *query)
1492 {
1493     mCurrentQueries.insert(query);
1494 }
1495 
onDeleteQueryObject(Query11 * query)1496 void StateManager11::onDeleteQueryObject(Query11 *query)
1497 {
1498     mCurrentQueries.erase(query);
1499 }
1500 
onMakeCurrent(const gl::Context * context)1501 gl::Error StateManager11::onMakeCurrent(const gl::Context *context)
1502 {
1503     const gl::State &state = context->getGLState();
1504 
1505     for (Query11 *query : mCurrentQueries)
1506     {
1507         ANGLE_TRY(query->pause());
1508     }
1509     mCurrentQueries.clear();
1510 
1511     for (GLenum queryType : QueryTypes)
1512     {
1513         gl::Query *query = state.getActiveQuery(queryType);
1514         if (query != nullptr)
1515         {
1516             Query11 *query11 = GetImplAs<Query11>(query);
1517             ANGLE_TRY(query11->resume());
1518             mCurrentQueries.insert(query11);
1519         }
1520     }
1521 
1522     return gl::NoError();
1523 }
1524 
clearTextures(gl::SamplerType samplerType,size_t rangeStart,size_t rangeEnd)1525 gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
1526                                         size_t rangeStart,
1527                                         size_t rangeEnd)
1528 {
1529     if (rangeStart == rangeEnd)
1530     {
1531         return gl::NoError();
1532     }
1533 
1534     auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
1535 
1536     gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, currentSRVs.highestUsed()));
1537     if (clearRange.empty())
1538     {
1539         return gl::NoError();
1540     }
1541 
1542     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1543     if (samplerType == gl::SAMPLER_VERTEX)
1544     {
1545         deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
1546                                             static_cast<unsigned int>(clearRange.length()),
1547                                             &mNullSRVs[0]);
1548     }
1549     else
1550     {
1551         deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
1552                                             static_cast<unsigned int>(clearRange.length()),
1553                                             &mNullSRVs[0]);
1554     }
1555 
1556     for (size_t samplerIndex : clearRange)
1557     {
1558         currentSRVs.update(samplerIndex, nullptr);
1559     }
1560 
1561     return gl::NoError();
1562 }
1563 
unsetConflictingView(ID3D11View * view)1564 bool StateManager11::unsetConflictingView(ID3D11View *view)
1565 {
1566     uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
1567     return unsetConflictingSRVs(gl::SAMPLER_VERTEX, resource, nullptr) ||
1568            unsetConflictingSRVs(gl::SAMPLER_PIXEL, resource, nullptr);
1569 }
1570 
unsetConflictingSRVs(gl::SamplerType samplerType,uintptr_t resource,const gl::ImageIndex * index)1571 bool StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType,
1572                                           uintptr_t resource,
1573                                           const gl::ImageIndex *index)
1574 {
1575     auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
1576 
1577     bool foundOne = false;
1578 
1579     for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
1580     {
1581         auto &record = currentSRVs[resourceIndex];
1582 
1583         if (record.srv && record.resource == resource &&
1584             (!index || ImageIndexConflictsWithSRV(*index, record.desc)))
1585         {
1586             setShaderResourceInternal<d3d11::ShaderResourceView>(
1587                 samplerType, static_cast<UINT>(resourceIndex), nullptr);
1588             foundOne = true;
1589         }
1590     }
1591 
1592     return foundOne;
1593 }
1594 
unsetConflictingAttachmentResources(const gl::FramebufferAttachment * attachment,ID3D11Resource * resource)1595 void StateManager11::unsetConflictingAttachmentResources(
1596     const gl::FramebufferAttachment *attachment,
1597     ID3D11Resource *resource)
1598 {
1599     // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
1600     if (attachment->type() == GL_TEXTURE)
1601     {
1602         uintptr_t resourcePtr       = reinterpret_cast<uintptr_t>(resource);
1603         const gl::ImageIndex &index = attachment->getTextureImageIndex();
1604         // The index doesn't need to be corrected for the small compressed texture workaround
1605         // because a rendertarget is never compressed.
1606         unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, &index);
1607         unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, &index);
1608     }
1609     else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
1610     {
1611         uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
1612         unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, nullptr);
1613         unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, nullptr);
1614     }
1615 }
1616 
initialize(const gl::Caps & caps,const gl::Extensions & extensions)1617 gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions &extensions)
1618 {
1619     mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
1620     mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
1621 
1622     // Initialize cached NULL SRV block
1623     mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
1624 
1625     mCurrentValueAttribs.resize(caps.maxVertexAttributes);
1626 
1627     mForceSetVertexSamplerStates.resize(caps.maxVertexTextureImageUnits, true);
1628     mForceSetPixelSamplerStates.resize(caps.maxTextureImageUnits, true);
1629     mForceSetComputeSamplerStates.resize(caps.maxComputeTextureImageUnits, true);
1630 
1631     mCurVertexSamplerStates.resize(caps.maxVertexTextureImageUnits);
1632     mCurPixelSamplerStates.resize(caps.maxTextureImageUnits);
1633     mCurComputeSamplerStates.resize(caps.maxComputeTextureImageUnits);
1634 
1635     mShaderConstants.init(caps);
1636 
1637     mIsMultiviewEnabled = extensions.multiview;
1638     mViewportOffsets.resize(1u);
1639 
1640     ANGLE_TRY(mVertexDataManager.initialize());
1641 
1642     mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
1643 
1644     return gl::NoError();
1645 }
1646 
deinitialize()1647 void StateManager11::deinitialize()
1648 {
1649     mCurrentValueAttribs.clear();
1650     mInputLayoutCache.clear();
1651     mVertexDataManager.deinitialize();
1652     mIndexDataManager.deinitialize();
1653 
1654     mDriverConstantBufferVS.reset();
1655     mDriverConstantBufferPS.reset();
1656     mDriverConstantBufferCS.reset();
1657 }
1658 
syncFramebuffer(const gl::Context * context,gl::Framebuffer * framebuffer)1659 gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
1660 {
1661     Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
1662 
1663     // Applies the render target surface, depth stencil surface, viewport rectangle and
1664     // scissor rectangle to the renderer
1665     ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete());
1666 
1667     // Check for zero-sized default framebuffer, which is a special case.
1668     // in this case we do not wish to modify any state and just silently return false.
1669     // this will not report any gl error but will cause the calling method to return.
1670     if (framebuffer->id() == 0)
1671     {
1672         ASSERT(!framebuffer11->hasAnyInternalDirtyBit());
1673         const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize();
1674         if (size.width == 0 || size.height == 0)
1675         {
1676             return gl::NoError();
1677         }
1678     }
1679 
1680     RTVArray framebufferRTVs = {{}};
1681 
1682     const auto &colorRTs = framebuffer11->getCachedColorRenderTargets();
1683 
1684     size_t appliedRTIndex  = 0;
1685     bool skipInactiveRTs   = mRenderer->getWorkarounds().mrtPerfWorkaround;
1686     const auto &drawStates = framebuffer->getDrawBufferStates();
1687     gl::DrawBufferMask activeProgramOutputs =
1688         context->getContextState().getState().getProgram()->getActiveOutputVariables();
1689     UINT maxExistingRT = 0;
1690 
1691     for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex)
1692     {
1693         const RenderTarget11 *renderTarget = colorRTs[rtIndex];
1694 
1695         // Skip inactive rendertargets if the workaround is enabled.
1696         if (skipInactiveRTs &&
1697             (!renderTarget || drawStates[rtIndex] == GL_NONE || !activeProgramOutputs[rtIndex]))
1698         {
1699             continue;
1700         }
1701 
1702         if (renderTarget)
1703         {
1704             framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get();
1705             ASSERT(framebufferRTVs[appliedRTIndex]);
1706             maxExistingRT = static_cast<UINT>(appliedRTIndex) + 1;
1707 
1708             // Unset conflicting texture SRVs
1709             const auto *attachment = framebuffer->getColorbuffer(rtIndex);
1710             ASSERT(attachment);
1711             unsetConflictingAttachmentResources(attachment, renderTarget->getTexture().get());
1712         }
1713 
1714         appliedRTIndex++;
1715     }
1716 
1717     // Get the depth stencil buffers
1718     ID3D11DepthStencilView *framebufferDSV = nullptr;
1719     const auto *depthStencilRenderTarget   = framebuffer11->getCachedDepthStencilRenderTarget();
1720     if (depthStencilRenderTarget)
1721     {
1722         framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get();
1723         ASSERT(framebufferDSV);
1724 
1725         // Unset conflicting texture SRVs
1726         const auto *attachment = framebuffer->getDepthOrStencilbuffer();
1727         ASSERT(attachment);
1728         unsetConflictingAttachmentResources(attachment,
1729                                             depthStencilRenderTarget->getTexture().get());
1730     }
1731 
1732     // TODO(jmadill): Use context caps?
1733     ASSERT(maxExistingRT <= static_cast<UINT>(mRenderer->getNativeCaps().maxDrawBuffers));
1734 
1735     // Apply the render target and depth stencil
1736     mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(),
1737                                                       framebufferDSV);
1738 
1739     return gl::NoError();
1740 }
1741 
invalidateCurrentValueAttrib(size_t attribIndex)1742 void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
1743 {
1744     mDirtyCurrentValueAttribs.set(attribIndex);
1745     mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
1746 }
1747 
syncCurrentValueAttribs(const gl::State & glState)1748 gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &glState)
1749 {
1750     const auto &activeAttribsMask  = glState.getProgram()->getActiveAttribLocationsMask();
1751     const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
1752 
1753     if (!dirtyActiveAttribs.any())
1754     {
1755         return gl::NoError();
1756     }
1757 
1758     const auto &vertexAttributes = glState.getVertexArray()->getVertexAttributes();
1759     const auto &vertexBindings   = glState.getVertexArray()->getVertexBindings();
1760     mDirtyCurrentValueAttribs    = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
1761 
1762     for (auto attribIndex : dirtyActiveAttribs)
1763     {
1764         if (vertexAttributes[attribIndex].enabled)
1765             continue;
1766 
1767         const auto *attrib                   = &vertexAttributes[attribIndex];
1768         const auto &currentValue             = glState.getVertexAttribCurrentValue(attribIndex);
1769         TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex];
1770         currentValueAttrib->currentValueType = currentValue.Type;
1771         currentValueAttrib->attribute        = attrib;
1772         currentValueAttrib->binding          = &vertexBindings[attrib->bindingIndex];
1773 
1774         mDirtyVertexBufferRange.extend(static_cast<unsigned int>(attribIndex));
1775         mInputLayoutIsDirty = true;
1776 
1777         ANGLE_TRY(mVertexDataManager.storeCurrentValue(currentValue, currentValueAttrib,
1778                                                        static_cast<size_t>(attribIndex)));
1779     }
1780 
1781     return gl::NoError();
1782 }
1783 
setInputLayout(const d3d11::InputLayout * inputLayout)1784 void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
1785 {
1786     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1787     if (inputLayout == nullptr)
1788     {
1789         if (!mCurrentInputLayout.empty())
1790         {
1791             deviceContext->IASetInputLayout(nullptr);
1792             mCurrentInputLayout.clear();
1793             mInputLayoutIsDirty = true;
1794         }
1795     }
1796     else if (inputLayout->getSerial() != mCurrentInputLayout)
1797     {
1798         deviceContext->IASetInputLayout(inputLayout->get());
1799         mCurrentInputLayout = inputLayout->getSerial();
1800         mInputLayoutIsDirty = true;
1801     }
1802 }
1803 
queueVertexBufferChange(size_t bufferIndex,ID3D11Buffer * buffer,UINT stride,UINT offset)1804 bool StateManager11::queueVertexBufferChange(size_t bufferIndex,
1805                                              ID3D11Buffer *buffer,
1806                                              UINT stride,
1807                                              UINT offset)
1808 {
1809     if (buffer != mCurrentVertexBuffers[bufferIndex] ||
1810         stride != mCurrentVertexStrides[bufferIndex] ||
1811         offset != mCurrentVertexOffsets[bufferIndex])
1812     {
1813         mInputLayoutIsDirty = true;
1814         mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
1815 
1816         mCurrentVertexBuffers[bufferIndex] = buffer;
1817         mCurrentVertexStrides[bufferIndex] = stride;
1818         mCurrentVertexOffsets[bufferIndex] = offset;
1819         return true;
1820     }
1821 
1822     return false;
1823 }
1824 
queueVertexOffsetChange(size_t bufferIndex,UINT offsetOnly)1825 bool StateManager11::queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly)
1826 {
1827     if (offsetOnly != mCurrentVertexOffsets[bufferIndex])
1828     {
1829         mInputLayoutIsDirty = true;
1830         mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
1831         mCurrentVertexOffsets[bufferIndex] = offsetOnly;
1832         return true;
1833     }
1834     return false;
1835 }
1836 
applyVertexBufferChanges()1837 void StateManager11::applyVertexBufferChanges()
1838 {
1839     if (mDirtyVertexBufferRange.empty())
1840     {
1841         return;
1842     }
1843 
1844     ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS);
1845 
1846     UINT start = static_cast<UINT>(mDirtyVertexBufferRange.low());
1847 
1848     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1849     deviceContext->IASetVertexBuffers(start, static_cast<UINT>(mDirtyVertexBufferRange.length()),
1850                                       &mCurrentVertexBuffers[start], &mCurrentVertexStrides[start],
1851                                       &mCurrentVertexOffsets[start]);
1852 
1853     mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0);
1854 }
1855 
setSingleVertexBuffer(const d3d11::Buffer * buffer,UINT stride,UINT offset)1856 void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset)
1857 {
1858     ID3D11Buffer *native = buffer ? buffer->get() : nullptr;
1859     if (queueVertexBufferChange(0, native, stride, offset))
1860     {
1861         applyVertexBufferChanges();
1862     }
1863 }
1864 
updateState(const gl::Context * context,GLenum drawMode)1865 gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMode)
1866 {
1867     const auto &glState = context->getGLState();
1868     auto *programD3D    = GetImplAs<ProgramD3D>(glState.getProgram());
1869 
1870     // TODO(jmadill): Use dirty bits.
1871     processFramebufferInvalidation(context);
1872 
1873     // TODO(jmadill): Use dirty bits.
1874     if (programD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
1875     {
1876         invalidateTexturesAndSamplers();
1877     }
1878 
1879     // TODO(jmadill): Use dirty bits.
1880     if (programD3D->areVertexUniformsDirty() || programD3D->areFragmentUniformsDirty())
1881     {
1882         mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
1883     }
1884 
1885     // Transform feedback affects the stream-out geometry shader.
1886     // TODO(jmadill): Use dirty bits.
1887     if (glState.isTransformFeedbackActiveUnpaused() != mIsTransformFeedbackCurrentlyActiveUnpaused)
1888     {
1889         mIsTransformFeedbackCurrentlyActiveUnpaused = glState.isTransformFeedbackActiveUnpaused();
1890         invalidateShaders();
1891     }
1892 
1893     // Swizzling can cause internal state changes with blit shaders.
1894     if (mDirtySwizzles)
1895     {
1896         ANGLE_TRY(generateSwizzles(context));
1897         mDirtySwizzles = false;
1898     }
1899 
1900     gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
1901     Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
1902     ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
1903 
1904     if (framebuffer11->hasAnyInternalDirtyBit())
1905     {
1906         ASSERT(framebuffer->id() != 0);
1907         framebuffer11->syncInternalState(context);
1908     }
1909 
1910     bool pointDrawMode = (drawMode == GL_POINTS);
1911     if (pointDrawMode != mCurRasterState.pointDrawMode)
1912     {
1913         mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
1914 
1915         // Changing from points to not points (or vice-versa) affects the geometry shader.
1916         invalidateShaders();
1917     }
1918 
1919     // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask
1920     // state changes.
1921     RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget();
1922     int samples             = (firstRT ? firstRT->getSamples() : 0);
1923     unsigned int sampleMask = GetBlendSampleMask(glState, samples);
1924     if (sampleMask != mCurSampleMask)
1925     {
1926         mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
1927     }
1928 
1929     // Changing the vertex attribute state can affect the vertex shader.
1930     gl::VertexArray *vao = glState.getVertexArray();
1931     VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao);
1932     if (vao11->flushAttribUpdates(context))
1933     {
1934         mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
1935     }
1936 
1937     auto dirtyBitsCopy = mInternalDirtyBits;
1938     mInternalDirtyBits.reset();
1939 
1940     for (auto dirtyBit : dirtyBitsCopy)
1941     {
1942         switch (dirtyBit)
1943         {
1944             case DIRTY_BIT_RENDER_TARGET:
1945                 ANGLE_TRY(syncFramebuffer(context, framebuffer));
1946                 break;
1947             case DIRTY_BIT_VIEWPORT_STATE:
1948                 syncViewport(context);
1949                 break;
1950             case DIRTY_BIT_SCISSOR_STATE:
1951                 syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
1952                 break;
1953             case DIRTY_BIT_RASTERIZER_STATE:
1954                 ANGLE_TRY(syncRasterizerState(context, pointDrawMode));
1955                 break;
1956             case DIRTY_BIT_BLEND_STATE:
1957                 ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(),
1958                                          glState.getBlendColor(), sampleMask));
1959                 break;
1960             case DIRTY_BIT_DEPTH_STENCIL_STATE:
1961                 ANGLE_TRY(syncDepthStencilState(glState));
1962                 break;
1963             case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE:
1964                 // TODO(jmadill): More fine-grained update.
1965                 ANGLE_TRY(syncTextures(context));
1966                 break;
1967             case DIRTY_BIT_PROGRAM_UNIFORMS:
1968                 ANGLE_TRY(applyUniforms(programD3D));
1969                 break;
1970             case DIRTY_BIT_DRIVER_UNIFORMS:
1971                 // This must happen after viewport sync; the viewport affects builtin uniforms.
1972                 ANGLE_TRY(applyDriverUniforms(*programD3D));
1973                 break;
1974             case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
1975                 ANGLE_TRY(syncUniformBuffers(context, programD3D));
1976                 break;
1977             case DIRTY_BIT_SHADERS:
1978                 ANGLE_TRY(syncProgram(context, drawMode));
1979                 break;
1980             case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
1981                 ANGLE_TRY(syncCurrentValueAttribs(glState));
1982                 break;
1983             default:
1984                 UNREACHABLE();
1985                 break;
1986         }
1987     }
1988 
1989     ANGLE_TRY(syncTransformFeedbackBuffers(context));
1990 
1991     // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
1992     ASSERT(mInternalDirtyBits.none());
1993 
1994     return gl::NoError();
1995 }
1996 
setShaderResourceShared(gl::SamplerType shaderType,UINT resourceSlot,const d3d11::SharedSRV * srv)1997 void StateManager11::setShaderResourceShared(gl::SamplerType shaderType,
1998                                              UINT resourceSlot,
1999                                              const d3d11::SharedSRV *srv)
2000 {
2001     setShaderResourceInternal(shaderType, resourceSlot, srv);
2002 
2003     // TODO(jmadill): Narrower dirty region.
2004     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
2005 }
2006 
setShaderResource(gl::SamplerType shaderType,UINT resourceSlot,const d3d11::ShaderResourceView * srv)2007 void StateManager11::setShaderResource(gl::SamplerType shaderType,
2008                                        UINT resourceSlot,
2009                                        const d3d11::ShaderResourceView *srv)
2010 {
2011     setShaderResourceInternal(shaderType, resourceSlot, srv);
2012 
2013     // TODO(jmadill): Narrower dirty region.
2014     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
2015 }
2016 
setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)2017 void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
2018 {
2019     if (primitiveTopology != mCurrentPrimitiveTopology)
2020     {
2021         mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology);
2022         mCurrentPrimitiveTopology = primitiveTopology;
2023     }
2024 }
2025 
setDrawShaders(const d3d11::VertexShader * vertexShader,const d3d11::GeometryShader * geometryShader,const d3d11::PixelShader * pixelShader)2026 void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader,
2027                                     const d3d11::GeometryShader *geometryShader,
2028                                     const d3d11::PixelShader *pixelShader)
2029 {
2030     setVertexShader(vertexShader);
2031     setGeometryShader(geometryShader);
2032     setPixelShader(pixelShader);
2033 }
2034 
setVertexShader(const d3d11::VertexShader * shader)2035 void StateManager11::setVertexShader(const d3d11::VertexShader *shader)
2036 {
2037     ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
2038 
2039     if (serial != mAppliedVertexShader)
2040     {
2041         ID3D11VertexShader *appliedShader = shader ? shader->get() : nullptr;
2042         mRenderer->getDeviceContext()->VSSetShader(appliedShader, nullptr, 0);
2043         mAppliedVertexShader = serial;
2044         invalidateShaders();
2045     }
2046 }
2047 
setGeometryShader(const d3d11::GeometryShader * shader)2048 void StateManager11::setGeometryShader(const d3d11::GeometryShader *shader)
2049 {
2050     ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
2051 
2052     if (serial != mAppliedGeometryShader)
2053     {
2054         ID3D11GeometryShader *appliedShader = shader ? shader->get() : nullptr;
2055         mRenderer->getDeviceContext()->GSSetShader(appliedShader, nullptr, 0);
2056         mAppliedGeometryShader = serial;
2057         invalidateShaders();
2058     }
2059 }
2060 
setPixelShader(const d3d11::PixelShader * shader)2061 void StateManager11::setPixelShader(const d3d11::PixelShader *shader)
2062 {
2063     ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
2064 
2065     if (serial != mAppliedPixelShader)
2066     {
2067         ID3D11PixelShader *appliedShader = shader ? shader->get() : nullptr;
2068         mRenderer->getDeviceContext()->PSSetShader(appliedShader, nullptr, 0);
2069         mAppliedPixelShader = serial;
2070         invalidateShaders();
2071     }
2072 }
2073 
setComputeShader(const d3d11::ComputeShader * shader)2074 void StateManager11::setComputeShader(const d3d11::ComputeShader *shader)
2075 {
2076     ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
2077 
2078     if (serial != mAppliedComputeShader)
2079     {
2080         ID3D11ComputeShader *appliedShader = shader ? shader->get() : nullptr;
2081         mRenderer->getDeviceContext()->CSSetShader(appliedShader, nullptr, 0);
2082         mAppliedComputeShader = serial;
2083         // TODO(jmadill): Dirty bits for compute.
2084     }
2085 }
2086 
setVertexConstantBuffer(unsigned int slot,const d3d11::Buffer * buffer)2087 void StateManager11::setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
2088 {
2089     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2090     auto &currentSerial                = mCurrentConstantBufferVS[slot];
2091 
2092     mCurrentConstantBufferVSOffset[slot] = 0;
2093     mCurrentConstantBufferVSSize[slot]   = 0;
2094 
2095     if (buffer)
2096     {
2097         if (currentSerial != buffer->getSerial())
2098         {
2099             deviceContext->VSSetConstantBuffers(slot, 1, buffer->getPointer());
2100             currentSerial = buffer->getSerial();
2101             invalidateConstantBuffer(slot);
2102         }
2103     }
2104     else
2105     {
2106         if (!currentSerial.empty())
2107         {
2108             ID3D11Buffer *nullBuffer = nullptr;
2109             deviceContext->VSSetConstantBuffers(slot, 1, &nullBuffer);
2110             currentSerial.clear();
2111             invalidateConstantBuffer(slot);
2112         }
2113     }
2114 }
2115 
setPixelConstantBuffer(unsigned int slot,const d3d11::Buffer * buffer)2116 void StateManager11::setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
2117 {
2118     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2119     auto &currentSerial                = mCurrentConstantBufferPS[slot];
2120 
2121     mCurrentConstantBufferPSOffset[slot] = 0;
2122     mCurrentConstantBufferPSSize[slot]   = 0;
2123 
2124     if (buffer)
2125     {
2126         if (currentSerial != buffer->getSerial())
2127         {
2128             deviceContext->PSSetConstantBuffers(slot, 1, buffer->getPointer());
2129             currentSerial = buffer->getSerial();
2130             invalidateConstantBuffer(slot);
2131         }
2132     }
2133     else
2134     {
2135         if (!currentSerial.empty())
2136         {
2137             ID3D11Buffer *nullBuffer = nullptr;
2138             deviceContext->PSSetConstantBuffers(slot, 1, &nullBuffer);
2139             currentSerial.clear();
2140             invalidateConstantBuffer(slot);
2141         }
2142     }
2143 }
2144 
setDepthStencilState(const d3d11::DepthStencilState * depthStencilState,UINT stencilRef)2145 void StateManager11::setDepthStencilState(const d3d11::DepthStencilState *depthStencilState,
2146                                           UINT stencilRef)
2147 {
2148     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2149 
2150     if (depthStencilState)
2151     {
2152         deviceContext->OMSetDepthStencilState(depthStencilState->get(), stencilRef);
2153     }
2154     else
2155     {
2156         deviceContext->OMSetDepthStencilState(nullptr, stencilRef);
2157     }
2158 
2159     mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
2160 }
2161 
setSimpleBlendState(const d3d11::BlendState * blendState)2162 void StateManager11::setSimpleBlendState(const d3d11::BlendState *blendState)
2163 {
2164     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2165 
2166     if (blendState)
2167     {
2168         deviceContext->OMSetBlendState(blendState->get(), nullptr, 0xFFFFFFFF);
2169     }
2170     else
2171     {
2172         deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);
2173     }
2174 
2175     mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
2176 }
2177 
setRasterizerState(const d3d11::RasterizerState * rasterizerState)2178 void StateManager11::setRasterizerState(const d3d11::RasterizerState *rasterizerState)
2179 {
2180     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2181 
2182     if (rasterizerState)
2183     {
2184         deviceContext->RSSetState(rasterizerState->get());
2185     }
2186     else
2187     {
2188         deviceContext->RSSetState(nullptr);
2189     }
2190 
2191     mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
2192 }
2193 
setSimpleViewport(const gl::Extents & extents)2194 void StateManager11::setSimpleViewport(const gl::Extents &extents)
2195 {
2196     setSimpleViewport(extents.width, extents.height);
2197 }
2198 
setSimpleViewport(int width,int height)2199 void StateManager11::setSimpleViewport(int width, int height)
2200 {
2201     D3D11_VIEWPORT viewport;
2202     viewport.TopLeftX = 0;
2203     viewport.TopLeftY = 0;
2204     viewport.Width    = static_cast<FLOAT>(width);
2205     viewport.Height   = static_cast<FLOAT>(height);
2206     viewport.MinDepth = 0.0f;
2207     viewport.MaxDepth = 1.0f;
2208 
2209     mRenderer->getDeviceContext()->RSSetViewports(1, &viewport);
2210     mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
2211 }
2212 
setSimplePixelTextureAndSampler(const d3d11::SharedSRV & srv,const d3d11::SamplerState & samplerState)2213 void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
2214                                                      const d3d11::SamplerState &samplerState)
2215 {
2216     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2217 
2218     setShaderResourceInternal(gl::SAMPLER_PIXEL, 0, &srv);
2219     deviceContext->PSSetSamplers(0, 1, samplerState.getPointer());
2220 
2221     mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
2222     mForceSetPixelSamplerStates[0] = true;
2223 }
2224 
setSimpleScissorRect(const gl::Rectangle & glRect)2225 void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect)
2226 {
2227     D3D11_RECT scissorRect;
2228     scissorRect.left   = glRect.x;
2229     scissorRect.right  = glRect.x + glRect.width;
2230     scissorRect.top    = glRect.y;
2231     scissorRect.bottom = glRect.y + glRect.height;
2232     setScissorRectD3D(scissorRect);
2233 }
2234 
setScissorRectD3D(const D3D11_RECT & d3dRect)2235 void StateManager11::setScissorRectD3D(const D3D11_RECT &d3dRect)
2236 {
2237     mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect);
2238     mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
2239 }
2240 
2241 // For each Direct3D sampler of either the pixel or vertex stage,
2242 // looks up the corresponding OpenGL texture image unit and texture type,
2243 // and sets the texture and its addressing/filtering state (or NULL when inactive).
2244 // Sampler mapping needs to be up-to-date on the program object before this is called.
applyTextures(const gl::Context * context,gl::SamplerType shaderType)2245 gl::Error StateManager11::applyTextures(const gl::Context *context, gl::SamplerType shaderType)
2246 {
2247     const auto &glState    = context->getGLState();
2248     const auto &caps       = context->getCaps();
2249     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
2250 
2251     ASSERT(!programD3D->isSamplerMappingDirty());
2252 
2253     // TODO(jmadill): Use the Program's sampler bindings.
2254     const auto &completeTextures = glState.getCompleteTextureCache();
2255 
2256     unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType);
2257     for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
2258     {
2259         GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
2260         ASSERT(textureUnit != -1);
2261         gl::Texture *texture = completeTextures[textureUnit];
2262 
2263         // A nullptr texture indicates incomplete.
2264         if (texture)
2265         {
2266             gl::Sampler *samplerObject = glState.getSampler(textureUnit);
2267 
2268             const gl::SamplerState &samplerState =
2269                 samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
2270 
2271             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
2272             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture));
2273         }
2274         else
2275         {
2276             GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex);
2277 
2278             // Texture is not sampler complete or it is in use by the framebuffer.  Bind the
2279             // incomplete texture.
2280             gl::Texture *incompleteTexture = nullptr;
2281             ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture));
2282             ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
2283                                       incompleteTexture->getSamplerState()));
2284             ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture));
2285         }
2286     }
2287 
2288     // Set all the remaining textures to NULL
2289     size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
2290                                                             : caps.maxVertexTextureImageUnits;
2291     ANGLE_TRY(clearTextures(shaderType, samplerRange, samplerCount));
2292 
2293     return gl::NoError();
2294 }
2295 
syncTextures(const gl::Context * context)2296 gl::Error StateManager11::syncTextures(const gl::Context *context)
2297 {
2298     ANGLE_TRY(applyTextures(context, gl::SAMPLER_VERTEX));
2299     ANGLE_TRY(applyTextures(context, gl::SAMPLER_PIXEL));
2300     return gl::NoError();
2301 }
2302 
setSamplerState(const gl::Context * context,gl::SamplerType type,int index,gl::Texture * texture,const gl::SamplerState & samplerState)2303 gl::Error StateManager11::setSamplerState(const gl::Context *context,
2304                                           gl::SamplerType type,
2305                                           int index,
2306                                           gl::Texture *texture,
2307                                           const gl::SamplerState &samplerState)
2308 {
2309 #if !defined(NDEBUG)
2310     // Storage should exist, texture should be complete. Only verified in Debug.
2311     TextureD3D *textureD3D  = GetImplAs<TextureD3D>(texture);
2312     TextureStorage *storage = nullptr;
2313     ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
2314     ASSERT(storage);
2315 #endif  // !defined(NDEBUG)
2316 
2317     auto *deviceContext = mRenderer->getDeviceContext();
2318 
2319     if (type == gl::SAMPLER_PIXEL)
2320     {
2321         ASSERT(static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits);
2322 
2323         if (mForceSetPixelSamplerStates[index] ||
2324             memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
2325         {
2326             ID3D11SamplerState *dxSamplerState = nullptr;
2327             ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
2328 
2329             ASSERT(dxSamplerState != nullptr);
2330             deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
2331 
2332             mCurPixelSamplerStates[index] = samplerState;
2333         }
2334 
2335         mForceSetPixelSamplerStates[index] = false;
2336     }
2337     else if (type == gl::SAMPLER_VERTEX)
2338     {
2339         ASSERT(static_cast<unsigned int>(index) <
2340                mRenderer->getNativeCaps().maxVertexTextureImageUnits);
2341 
2342         if (mForceSetVertexSamplerStates[index] ||
2343             memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
2344         {
2345             ID3D11SamplerState *dxSamplerState = nullptr;
2346             ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
2347 
2348             ASSERT(dxSamplerState != nullptr);
2349             deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
2350 
2351             mCurVertexSamplerStates[index] = samplerState;
2352         }
2353 
2354         mForceSetVertexSamplerStates[index] = false;
2355     }
2356     else if (type == gl::SAMPLER_COMPUTE)
2357     {
2358         ASSERT(static_cast<unsigned int>(index) <
2359                mRenderer->getNativeCaps().maxComputeTextureImageUnits);
2360 
2361         if (mForceSetComputeSamplerStates[index] ||
2362             memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0)
2363         {
2364             ID3D11SamplerState *dxSamplerState = nullptr;
2365             ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
2366 
2367             ASSERT(dxSamplerState != nullptr);
2368             deviceContext->CSSetSamplers(index, 1, &dxSamplerState);
2369 
2370             mCurComputeSamplerStates[index] = samplerState;
2371         }
2372 
2373         mForceSetComputeSamplerStates[index] = false;
2374     }
2375     else
2376         UNREACHABLE();
2377 
2378     // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
2379     // sampler state since having it in contiguous memory makes it possible to memcpy to a constant
2380     // buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
2381     mShaderConstants.onSamplerChange(type, index, *texture);
2382 
2383     return gl::NoError();
2384 }
2385 
setTexture(const gl::Context * context,gl::SamplerType type,int index,gl::Texture * texture)2386 gl::Error StateManager11::setTexture(const gl::Context *context,
2387                                      gl::SamplerType type,
2388                                      int index,
2389                                      gl::Texture *texture)
2390 {
2391     const d3d11::SharedSRV *textureSRV = nullptr;
2392 
2393     if (texture)
2394     {
2395         TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
2396 
2397         TextureStorage *texStorage = nullptr;
2398         ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
2399 
2400         // Texture should be complete and have a storage
2401         ASSERT(texStorage);
2402 
2403         TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
2404 
2405         ANGLE_TRY(storage11->getSRV(context, texture->getTextureState(), &textureSRV));
2406 
2407         // If we get an invalid SRV here, something went wrong in the texture class and we're
2408         // unexpectedly missing the shader resource view.
2409         ASSERT(textureSRV->valid());
2410 
2411         textureImpl->resetDirty();
2412     }
2413 
2414     ASSERT(
2415         (type == gl::SAMPLER_PIXEL &&
2416          static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits) ||
2417         (type == gl::SAMPLER_VERTEX &&
2418          static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxVertexTextureImageUnits));
2419 
2420     setShaderResourceInternal(type, index, textureSRV);
2421     return gl::NoError();
2422 }
2423 
2424 // Things that affect a program's dirtyness:
2425 // 1. Directly changing the program executable -> triggered in StateManager11::syncState.
2426 // 2. The vertex attribute layout              -> triggered in VertexArray11::syncState/signal.
2427 // 3. The fragment shader's rendertargets      -> triggered in Framebuffer11::syncState/signal.
2428 // 4. Enabling/disabling rasterizer discard.   -> triggered in StateManager11::syncState.
2429 // 5. Enabling/disabling transform feedback.   -> checked in StateManager11::updateState.
2430 // 6. An internal shader was used.             -> triggered in StateManager11::set*Shader.
2431 // 7. Drawing with/without point sprites.      -> checked in StateManager11::updateState.
2432 // TODO(jmadill): Use dirty bits for transform feedback.
syncProgram(const gl::Context * context,GLenum drawMode)2433 gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMode)
2434 {
2435     Context11 *context11 = GetImplAs<Context11>(context);
2436     ANGLE_TRY(context11->triggerDrawCallProgramRecompilation(context, drawMode));
2437 
2438     const auto &glState = context->getGLState();
2439     const auto *va11    = GetImplAs<VertexArray11>(glState.getVertexArray());
2440     auto *programD3D    = GetImplAs<ProgramD3D>(glState.getProgram());
2441 
2442     programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState);
2443 
2444     // Binaries must be compiled before the sync.
2445     ASSERT(programD3D->hasVertexExecutableForCachedInputLayout());
2446     ASSERT(programD3D->hasGeometryExecutableForPrimitiveType(drawMode));
2447     ASSERT(programD3D->hasPixelExecutableForCachedOutputLayout());
2448 
2449     ShaderExecutableD3D *vertexExe = nullptr;
2450     ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr));
2451 
2452     ShaderExecutableD3D *pixelExe = nullptr;
2453     ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
2454 
2455     ShaderExecutableD3D *geometryExe = nullptr;
2456     ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe,
2457                                                                 nullptr));
2458 
2459     const d3d11::VertexShader *vertexShader =
2460         (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr);
2461 
2462     // Skip pixel shader if we're doing rasterizer discard.
2463     const d3d11::PixelShader *pixelShader = nullptr;
2464     if (!glState.getRasterizerState().rasterizerDiscard)
2465     {
2466         pixelShader = (pixelExe ? &GetAs<ShaderExecutable11>(pixelExe)->getPixelShader() : nullptr);
2467     }
2468 
2469     const d3d11::GeometryShader *geometryShader = nullptr;
2470     if (glState.isTransformFeedbackActiveUnpaused())
2471     {
2472         geometryShader =
2473             (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : nullptr);
2474     }
2475     else
2476     {
2477         geometryShader =
2478             (geometryExe ? &GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : nullptr);
2479     }
2480 
2481     setDrawShaders(vertexShader, geometryShader, pixelShader);
2482 
2483     // Explicitly clear the shaders dirty bit.
2484     mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
2485 
2486     return gl::NoError();
2487 }
2488 
applyVertexBuffer(const gl::Context * context,GLenum mode,const DrawCallVertexParams & vertexParams,bool isIndexedRendering)2489 gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
2490                                             GLenum mode,
2491                                             const DrawCallVertexParams &vertexParams,
2492                                             bool isIndexedRendering)
2493 {
2494     const auto &state       = context->getGLState();
2495     const gl::VertexArray *vertexArray = state.getVertexArray();
2496     VertexArray11 *vertexArray11       = GetImplAs<VertexArray11>(vertexArray);
2497 
2498     if (mVertexAttribsNeedTranslation)
2499     {
2500         ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager,
2501                                                               vertexParams));
2502         mInputLayoutIsDirty = true;
2503 
2504         // Determine if we need to update attribs on the next draw.
2505         mVertexAttribsNeedTranslation = (vertexArray11->hasActiveDynamicAttrib(context));
2506     }
2507 
2508     if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != vertexParams.firstVertex())
2509     {
2510         mLastFirstVertex    = vertexParams.firstVertex();
2511         mInputLayoutIsDirty = true;
2512     }
2513 
2514     if (!mInputLayoutIsDirty)
2515     {
2516         return gl::NoError();
2517     }
2518 
2519     const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs();
2520     gl::Program *program           = state.getProgram();
2521 
2522     // Sort the attributes according to ensure we re-use similar input layouts.
2523     AttribIndexArray sortedSemanticIndices;
2524     SortAttributesByLayout(program, vertexArrayAttribs, mCurrentValueAttribs,
2525                            &sortedSemanticIndices, &mCurrentAttributes);
2526 
2527     auto featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
2528 
2529     // If we are using FL 9_3, make sure the first attribute is not instanced
2530     if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty())
2531     {
2532         if (mCurrentAttributes[0]->divisor > 0)
2533         {
2534             Optional<size_t> firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes);
2535             if (firstNonInstancedIndex.valid())
2536             {
2537                 size_t index = firstNonInstancedIndex.value();
2538                 std::swap(mCurrentAttributes[0], mCurrentAttributes[index]);
2539                 std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
2540             }
2541         }
2542     }
2543 
2544     // Update the applied input layout by querying the cache.
2545     ANGLE_TRY(mInputLayoutCache.updateInputLayout(mRenderer, state, mCurrentAttributes, mode,
2546                                                   sortedSemanticIndices, vertexParams));
2547 
2548     // Update the applied vertex buffers.
2549     ANGLE_TRY(mInputLayoutCache.applyVertexBuffers(context, mCurrentAttributes, mode,
2550                                                    vertexParams.firstVertex(), isIndexedRendering));
2551 
2552     // InputLayoutCache::applyVertexBuffers calls through to the Bufer11 to get the native vertex
2553     // buffer (ID3D11Buffer *). Because we allocate these buffers lazily, this will trigger
2554     // allocation. This in turn will signal that the buffer is dirty. Since we just resolved the
2555     // dirty-ness in VertexArray11::updateDirtyAndDynamicAttribs, this can make us do a needless
2556     // update on the second draw call.
2557     // Hence we clear the flags here, after we've applied vertex data, since we know everything
2558     // is clean. This is a bit of a hack.
2559     vertexArray11->clearDirtyAndPromoteDynamicAttribs(context, vertexParams);
2560 
2561     mInputLayoutIsDirty = false;
2562     return gl::NoError();
2563 }
2564 
applyIndexBuffer(const gl::Context * context,const void * indices,GLsizei count,GLenum type,const gl::HasIndexRange & lazyIndexRange,bool usePrimitiveRestartWorkaround)2565 gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
2566                                            const void *indices,
2567                                            GLsizei count,
2568                                            GLenum type,
2569                                            const gl::HasIndexRange &lazyIndexRange,
2570                                            bool usePrimitiveRestartWorkaround)
2571 {
2572     const auto &glState  = context->getGLState();
2573     gl::VertexArray *vao = glState.getVertexArray();
2574     VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao);
2575 
2576     GLenum destElementType =
2577         GetIndexTranslationDestType(type, lazyIndexRange, usePrimitiveRestartWorkaround);
2578 
2579     if (!vao11->updateElementArrayStorage(context, type, destElementType, indices) &&
2580         !mIndexBufferIsDirty)
2581     {
2582         // No streaming or index buffer application necessary.
2583         return gl::NoError();
2584     }
2585 
2586     gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
2587 
2588     TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo();
2589     ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, destElementType, count,
2590                                                  elementArrayBuffer, indices, indexInfo));
2591 
2592     ID3D11Buffer *buffer = nullptr;
2593     DXGI_FORMAT bufferFormat =
2594         (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
2595 
2596     if (indexInfo->storage)
2597     {
2598         Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
2599         ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDEX), buffer);
2600     }
2601     else
2602     {
2603         IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo->indexBuffer);
2604         buffer                     = indexBuffer->getBuffer().get();
2605     }
2606 
2607     // Track dirty indices in the index range cache.
2608     indexInfo->srcIndexData.srcIndicesChanged =
2609         syncIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
2610 
2611     mIndexBufferIsDirty = false;
2612 
2613     vao11->setCachedIndexInfoValid();
2614     return gl::NoError();
2615 }
2616 
setIndexBuffer(ID3D11Buffer * buffer,DXGI_FORMAT indexFormat,unsigned int offset)2617 void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
2618                                     DXGI_FORMAT indexFormat,
2619                                     unsigned int offset)
2620 {
2621     if (syncIndexBuffer(buffer, indexFormat, offset))
2622     {
2623         mIndexBufferIsDirty = true;
2624     }
2625 }
2626 
syncIndexBuffer(ID3D11Buffer * buffer,DXGI_FORMAT indexFormat,unsigned int offset)2627 bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer,
2628                                      DXGI_FORMAT indexFormat,
2629                                      unsigned int offset)
2630 {
2631     if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
2632     {
2633         mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset);
2634 
2635         mAppliedIB       = buffer;
2636         mAppliedIBFormat = indexFormat;
2637         mAppliedIBOffset = offset;
2638         return true;
2639     }
2640 
2641     return false;
2642 }
2643 
2644 // Vertex buffer is invalidated outside this function.
updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,GLsizei emulatedInstanceId)2645 gl::Error StateManager11::updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
2646                                                                       GLsizei emulatedInstanceId)
2647 {
2648     return mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(
2649         mRenderer, mCurrentAttributes, startVertex, emulatedInstanceId);
2650 }
2651 
generateSwizzle(const gl::Context * context,gl::Texture * texture)2652 gl::Error StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture)
2653 {
2654     if (!texture)
2655     {
2656         return gl::NoError();
2657     }
2658 
2659     TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
2660     ASSERT(textureD3D);
2661 
2662     TextureStorage *texStorage = nullptr;
2663     ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage));
2664 
2665     if (texStorage)
2666     {
2667         TextureStorage11 *storage11          = GetAs<TextureStorage11>(texStorage);
2668         const gl::TextureState &textureState = texture->getTextureState();
2669         ANGLE_TRY(storage11->generateSwizzles(context, textureState.getSwizzleState()));
2670     }
2671 
2672     return gl::NoError();
2673 }
2674 
generateSwizzlesForShader(const gl::Context * context,gl::SamplerType type)2675 gl::Error StateManager11::generateSwizzlesForShader(const gl::Context *context,
2676                                                     gl::SamplerType type)
2677 {
2678     const auto &glState    = context->getGLState();
2679     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
2680 
2681     unsigned int samplerRange = programD3D->getUsedSamplerRange(type);
2682 
2683     for (unsigned int i = 0; i < samplerRange; i++)
2684     {
2685         GLenum textureType = programD3D->getSamplerTextureType(type, i);
2686         GLint textureUnit  = programD3D->getSamplerMapping(type, i, context->getCaps());
2687         if (textureUnit != -1)
2688         {
2689             gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
2690             ASSERT(texture);
2691             if (texture->getTextureState().swizzleRequired())
2692             {
2693                 ANGLE_TRY(generateSwizzle(context, texture));
2694             }
2695         }
2696     }
2697 
2698     return gl::NoError();
2699 }
2700 
generateSwizzles(const gl::Context * context)2701 gl::Error StateManager11::generateSwizzles(const gl::Context *context)
2702 {
2703     ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_VERTEX));
2704     ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_PIXEL));
2705     return gl::NoError();
2706 }
2707 
applyUniforms(ProgramD3D * programD3D)2708 gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
2709 {
2710     UniformStorage11 *vertexUniformStorage =
2711         GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
2712     UniformStorage11 *fragmentUniformStorage =
2713         GetAs<UniformStorage11>(&programD3D->getFragmentUniformStorage());
2714     ASSERT(vertexUniformStorage);
2715     ASSERT(fragmentUniformStorage);
2716 
2717     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2718 
2719     const d3d11::Buffer *vertexConstantBuffer = nullptr;
2720     ANGLE_TRY(vertexUniformStorage->getConstantBuffer(mRenderer, &vertexConstantBuffer));
2721     const d3d11::Buffer *pixelConstantBuffer = nullptr;
2722     ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(mRenderer, &pixelConstantBuffer));
2723 
2724     if (vertexUniformStorage->size() > 0 && programD3D->areVertexUniformsDirty())
2725     {
2726         UpdateUniformBuffer(deviceContext, vertexUniformStorage, vertexConstantBuffer);
2727     }
2728 
2729     if (fragmentUniformStorage->size() > 0 && programD3D->areFragmentUniformsDirty())
2730     {
2731         UpdateUniformBuffer(deviceContext, fragmentUniformStorage, pixelConstantBuffer);
2732     }
2733 
2734     unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK;
2735 
2736     if (mCurrentConstantBufferVS[slot] != vertexConstantBuffer->getSerial())
2737     {
2738         deviceContext->VSSetConstantBuffers(slot, 1, vertexConstantBuffer->getPointer());
2739         mCurrentConstantBufferVS[slot]       = vertexConstantBuffer->getSerial();
2740         mCurrentConstantBufferVSOffset[slot] = 0;
2741         mCurrentConstantBufferVSSize[slot]   = 0;
2742     }
2743 
2744     if (mCurrentConstantBufferPS[slot] != pixelConstantBuffer->getSerial())
2745     {
2746         deviceContext->PSSetConstantBuffers(slot, 1, pixelConstantBuffer->getPointer());
2747         mCurrentConstantBufferPS[slot]       = pixelConstantBuffer->getSerial();
2748         mCurrentConstantBufferPSOffset[slot] = 0;
2749         mCurrentConstantBufferPSSize[slot]   = 0;
2750     }
2751 
2752     programD3D->markUniformsClean();
2753 
2754     return gl::NoError();
2755 }
2756 
applyDriverUniforms(const ProgramD3D & programD3D)2757 gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D)
2758 {
2759     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2760 
2761     if (!mDriverConstantBufferVS.valid())
2762     {
2763         size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_VERTEX);
2764 
2765         D3D11_BUFFER_DESC constantBufferDescription = {0};
2766         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
2767         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferVS));
2768 
2769         ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get();
2770         deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
2771                                             &driverVSConstants);
2772     }
2773 
2774     if (!mDriverConstantBufferPS.valid())
2775     {
2776         size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_PIXEL);
2777 
2778         D3D11_BUFFER_DESC constantBufferDescription = {0};
2779         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
2780         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferPS));
2781 
2782         ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get();
2783         deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
2784                                             &driverVSConstants);
2785     }
2786 
2787     // Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
2788     // constant buffer slots. We update both in the constant buffer if needed.
2789     ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_VERTEX, programD3D,
2790                                             mDriverConstantBufferVS));
2791     ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_PIXEL, programD3D,
2792                                             mDriverConstantBufferPS));
2793 
2794     // needed for the point sprite geometry shader
2795     // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3.
2796     if (mRenderer->isES3Capable())
2797     {
2798         if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS.getSerial())
2799         {
2800             ASSERT(mDriverConstantBufferPS.valid());
2801             deviceContext->GSSetConstantBuffers(0, 1, mDriverConstantBufferPS.getPointer());
2802             mCurrentGeometryConstantBuffer = mDriverConstantBufferPS.getSerial();
2803         }
2804     }
2805 
2806     return gl::NoError();
2807 }
2808 
applyComputeUniforms(ProgramD3D * programD3D)2809 gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
2810 {
2811     UniformStorage11 *computeUniformStorage =
2812         GetAs<UniformStorage11>(&programD3D->getComputeUniformStorage());
2813     ASSERT(computeUniformStorage);
2814 
2815     const d3d11::Buffer *constantBuffer = nullptr;
2816     ANGLE_TRY(computeUniformStorage->getConstantBuffer(mRenderer, &constantBuffer));
2817 
2818     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2819 
2820     if (computeUniformStorage->size() > 0 && programD3D->areComputeUniformsDirty())
2821     {
2822         UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer);
2823         programD3D->markUniformsClean();
2824     }
2825 
2826     if (mCurrentComputeConstantBuffer != constantBuffer->getSerial())
2827     {
2828         deviceContext->CSSetConstantBuffers(
2829             d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1,
2830             constantBuffer->getPointer());
2831         mCurrentComputeConstantBuffer = constantBuffer->getSerial();
2832     }
2833 
2834     if (!mDriverConstantBufferCS.valid())
2835     {
2836         size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_COMPUTE);
2837 
2838         D3D11_BUFFER_DESC constantBufferDescription = {0};
2839         d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
2840         ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferCS));
2841         ID3D11Buffer *buffer = mDriverConstantBufferCS.get();
2842         deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
2843                                             &buffer);
2844     }
2845 
2846     ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_COMPUTE, *programD3D,
2847                                             mDriverConstantBufferCS));
2848 
2849     return gl::NoError();
2850 }
2851 
syncUniformBuffers(const gl::Context * context,ProgramD3D * programD3D)2852 gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D)
2853 {
2854     unsigned int reservedVertex   = mRenderer->getReservedVertexUniformBuffers();
2855     unsigned int reservedFragment = mRenderer->getReservedFragmentUniformBuffers();
2856 
2857     programD3D->updateUniformBufferCache(context->getCaps(), reservedVertex, reservedFragment);
2858 
2859     const auto &vertexUniformBuffers     = programD3D->getVertexUniformBufferCache();
2860     const auto &fragmentUniformBuffers   = programD3D->getFragmentUniformBufferCache();
2861     const auto &glState                  = context->getGLState();
2862     ID3D11DeviceContext *deviceContext   = mRenderer->getDeviceContext();
2863     ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
2864 
2865     for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++)
2866     {
2867         GLint binding = vertexUniformBuffers[bufferIndex];
2868 
2869         if (binding == -1)
2870         {
2871             continue;
2872         }
2873 
2874         const auto &uniformBuffer    = glState.getIndexedUniformBuffer(binding);
2875         GLintptr uniformBufferOffset = uniformBuffer.getOffset();
2876         GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
2877 
2878         if (uniformBuffer.get() == nullptr)
2879         {
2880             continue;
2881         }
2882 
2883         Buffer11 *bufferStorage             = GetImplAs<Buffer11>(uniformBuffer.get());
2884         const d3d11::Buffer *constantBuffer = nullptr;
2885         UINT firstConstant                  = 0;
2886         UINT numConstants                   = 0;
2887 
2888         ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset,
2889                                                         uniformBufferSize, &constantBuffer,
2890                                                         &firstConstant, &numConstants));
2891 
2892         ASSERT(constantBuffer);
2893 
2894         if (mCurrentConstantBufferVS[bufferIndex] == constantBuffer->getSerial() &&
2895             mCurrentConstantBufferVSOffset[bufferIndex] == uniformBufferOffset &&
2896             mCurrentConstantBufferVSSize[bufferIndex] == uniformBufferSize)
2897         {
2898             continue;
2899         }
2900 
2901         unsigned int appliedIndex = reservedVertex + static_cast<unsigned int>(bufferIndex);
2902 
2903         if (firstConstant != 0 && uniformBufferSize != 0)
2904         {
2905             ASSERT(numConstants != 0);
2906             deviceContext1->VSSetConstantBuffers1(appliedIndex, 1, constantBuffer->getPointer(),
2907                                                   &firstConstant, &numConstants);
2908         }
2909         else
2910         {
2911             deviceContext->VSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
2912         }
2913 
2914         mCurrentConstantBufferVS[appliedIndex]       = constantBuffer->getSerial();
2915         mCurrentConstantBufferVSOffset[appliedIndex] = uniformBufferOffset;
2916         mCurrentConstantBufferVSSize[appliedIndex]   = uniformBufferSize;
2917     }
2918 
2919     for (size_t bufferIndex = 0; bufferIndex < fragmentUniformBuffers.size(); bufferIndex++)
2920     {
2921         GLint binding = fragmentUniformBuffers[bufferIndex];
2922 
2923         if (binding == -1)
2924         {
2925             continue;
2926         }
2927 
2928         const auto &uniformBuffer    = glState.getIndexedUniformBuffer(binding);
2929         GLintptr uniformBufferOffset = uniformBuffer.getOffset();
2930         GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
2931 
2932         if (uniformBuffer.get() == nullptr)
2933         {
2934             continue;
2935         }
2936 
2937         Buffer11 *bufferStorage             = GetImplAs<Buffer11>(uniformBuffer.get());
2938         const d3d11::Buffer *constantBuffer = nullptr;
2939         UINT firstConstant                  = 0;
2940         UINT numConstants                   = 0;
2941 
2942         ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset,
2943                                                         uniformBufferSize, &constantBuffer,
2944                                                         &firstConstant, &numConstants));
2945 
2946         ASSERT(constantBuffer);
2947 
2948         if (mCurrentConstantBufferPS[bufferIndex] == constantBuffer->getSerial() &&
2949             mCurrentConstantBufferPSOffset[bufferIndex] == uniformBufferOffset &&
2950             mCurrentConstantBufferPSSize[bufferIndex] == uniformBufferSize)
2951         {
2952             continue;
2953         }
2954 
2955         unsigned int appliedIndex = reservedFragment + static_cast<unsigned int>(bufferIndex);
2956 
2957         if (firstConstant != 0 && uniformBufferSize != 0)
2958         {
2959             deviceContext1->PSSetConstantBuffers1(appliedIndex, 1, constantBuffer->getPointer(),
2960                                                   &firstConstant, &numConstants);
2961         }
2962         else
2963         {
2964             deviceContext->PSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer());
2965         }
2966 
2967         mCurrentConstantBufferPS[appliedIndex]       = constantBuffer->getSerial();
2968         mCurrentConstantBufferPSOffset[appliedIndex] = uniformBufferOffset;
2969         mCurrentConstantBufferPSSize[appliedIndex]   = uniformBufferSize;
2970     }
2971 
2972     return gl::NoError();
2973 }
2974 
syncTransformFeedbackBuffers(const gl::Context * context)2975 gl::Error StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
2976 {
2977     const auto &glState = context->getGLState();
2978 
2979     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2980 
2981     // If transform feedback is not active, unbind all buffers
2982     if (!glState.isTransformFeedbackActiveUnpaused())
2983     {
2984         if (mAppliedTFSerial != mEmptySerial)
2985         {
2986             deviceContext->SOSetTargets(0, nullptr, nullptr);
2987             mAppliedTFSerial = mEmptySerial;
2988         }
2989         return gl::NoError();
2990     }
2991 
2992     gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
2993     TransformFeedback11 *tf11                = GetImplAs<TransformFeedback11>(transformFeedback);
2994     if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty())
2995     {
2996         return gl::NoError();
2997     }
2998 
2999     const std::vector<ID3D11Buffer *> *soBuffers = nullptr;
3000     ANGLE_TRY_RESULT(tf11->getSOBuffers(context), soBuffers);
3001     const std::vector<UINT> &soOffsets = tf11->getSOBufferOffsets();
3002 
3003     deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data());
3004 
3005     mAppliedTFSerial = tf11->getSerial();
3006     tf11->onApply();
3007 
3008     return gl::NoError();
3009 }
3010 
3011 // DrawCallVertexParams implementation.
DrawCallVertexParams(GLint firstVertex,GLsizei vertexCount,GLsizei instances)3012 DrawCallVertexParams::DrawCallVertexParams(GLint firstVertex,
3013                                            GLsizei vertexCount,
3014                                            GLsizei instances)
3015     : mHasIndexRange(nullptr),
3016       mFirstVertex(firstVertex),
3017       mVertexCount(vertexCount),
3018       mInstances(instances),
3019       mBaseVertex(0)
3020 {
3021 }
3022 
3023 // Use when in a drawElements call.
DrawCallVertexParams(bool firstVertexDefinitelyZero,const gl::HasIndexRange & hasIndexRange,GLint baseVertex,GLsizei instances)3024 DrawCallVertexParams::DrawCallVertexParams(bool firstVertexDefinitelyZero,
3025                                            const gl::HasIndexRange &hasIndexRange,
3026                                            GLint baseVertex,
3027                                            GLsizei instances)
3028     : mHasIndexRange(&hasIndexRange),
3029       mFirstVertex(),
3030       mVertexCount(0),
3031       mInstances(instances),
3032       mBaseVertex(baseVertex)
3033 {
3034     if (firstVertexDefinitelyZero)
3035     {
3036         mFirstVertex = baseVertex;
3037     }
3038 }
3039 
firstVertex() const3040 GLint DrawCallVertexParams::firstVertex() const
3041 {
3042     if (!mFirstVertex.valid())
3043     {
3044         ensureResolved();
3045         ASSERT(mFirstVertex.valid());
3046     }
3047     return mFirstVertex.value();
3048 }
3049 
vertexCount() const3050 GLsizei DrawCallVertexParams::vertexCount() const
3051 {
3052     ensureResolved();
3053     return mVertexCount;
3054 }
3055 
instances() const3056 GLsizei DrawCallVertexParams::instances() const
3057 {
3058     return mInstances;
3059 }
3060 
ensureResolved() const3061 void DrawCallVertexParams::ensureResolved() const
3062 {
3063     if (mHasIndexRange)
3064     {
3065         ASSERT(!mFirstVertex.valid() || mFirstVertex == mBaseVertex);
3066 
3067         // Resolve the index range now if we need to.
3068         const auto &indexRange = mHasIndexRange->getIndexRange().value();
3069         mFirstVertex           = mBaseVertex + static_cast<GLint>(indexRange.start);
3070         mVertexCount           = static_cast<GLsizei>(indexRange.vertexCount());
3071         mHasIndexRange         = nullptr;
3072     }
3073 }
3074 
3075 }  // namespace rx
3076