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