1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ProgramExecutableVk.cpp: Collects the information and interfaces common to both ProgramVks and
7*8975f5c5SAndroid Build Coastguard Worker // ProgramPipelineVks in order to execute/draw with either.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ProgramExecutableVk.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/BufferVk.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/DisplayVk.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/FramebufferVk.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ProgramPipelineVk.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ProgramVk.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/TextureVk.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/TransformFeedbackVk.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_helpers.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_utils.h"
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard Worker namespace rx
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker namespace
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker // Limit decompressed vulkan pipelines to 10MB per program.
28*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kMaxLocalPipelineCacheSize = 10 * 1024 * 1024;
29*8975f5c5SAndroid Build Coastguard Worker
ValidateTransformedSpirV(vk::Context * context,const gl::ShaderBitSet & linkedShaderStages,const ShaderInterfaceVariableInfoMap & variableInfoMap,const gl::ShaderMap<angle::spirv::Blob> & spirvBlobs)30*8975f5c5SAndroid Build Coastguard Worker bool ValidateTransformedSpirV(vk::Context *context,
31*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet &linkedShaderStages,
32*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfoMap &variableInfoMap,
33*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<angle::spirv::Blob> &spirvBlobs)
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType lastPreFragmentStage = gl::GetLastPreFragmentStage(linkedShaderStages);
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : linkedShaderStages)
38*8975f5c5SAndroid Build Coastguard Worker {
39*8975f5c5SAndroid Build Coastguard Worker SpvTransformOptions options;
40*8975f5c5SAndroid Build Coastguard Worker options.shaderType = shaderType;
41*8975f5c5SAndroid Build Coastguard Worker options.isLastPreFragmentStage =
42*8975f5c5SAndroid Build Coastguard Worker shaderType == lastPreFragmentStage && shaderType != gl::ShaderType::TessControl;
43*8975f5c5SAndroid Build Coastguard Worker options.isTransformFeedbackStage = options.isLastPreFragmentStage;
44*8975f5c5SAndroid Build Coastguard Worker options.useSpirvVaryingPrecisionFixer =
45*8975f5c5SAndroid Build Coastguard Worker context->getFeatures().varyingsRequireMatchingPrecisionInSpirv.enabled;
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob transformed;
48*8975f5c5SAndroid Build Coastguard Worker if (SpvTransformSpirvCode(options, variableInfoMap, spirvBlobs[shaderType], &transformed) !=
49*8975f5c5SAndroid Build Coastguard Worker angle::Result::Continue)
50*8975f5c5SAndroid Build Coastguard Worker {
51*8975f5c5SAndroid Build Coastguard Worker return false;
52*8975f5c5SAndroid Build Coastguard Worker }
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker return true;
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker
GetInterfaceBlockArraySize(const std::vector<gl::InterfaceBlock> & blocks,uint32_t bufferIndex)57*8975f5c5SAndroid Build Coastguard Worker uint32_t GetInterfaceBlockArraySize(const std::vector<gl::InterfaceBlock> &blocks,
58*8975f5c5SAndroid Build Coastguard Worker uint32_t bufferIndex)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker const gl::InterfaceBlock &block = blocks[bufferIndex];
61*8975f5c5SAndroid Build Coastguard Worker
62*8975f5c5SAndroid Build Coastguard Worker if (!block.pod.isArray)
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker return 1;
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker ASSERT(block.pod.arrayElement == 0);
68*8975f5c5SAndroid Build Coastguard Worker
69*8975f5c5SAndroid Build Coastguard Worker // Search consecutively until all array indices of this block are visited.
70*8975f5c5SAndroid Build Coastguard Worker uint32_t arraySize;
71*8975f5c5SAndroid Build Coastguard Worker for (arraySize = 1; bufferIndex + arraySize < blocks.size(); ++arraySize)
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker const gl::InterfaceBlock &nextBlock = blocks[bufferIndex + arraySize];
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker if (nextBlock.pod.arrayElement != arraySize)
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker break;
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard Worker // It's unexpected for an array to start at a non-zero array size, so we can always rely on
81*8975f5c5SAndroid Build Coastguard Worker // the sequential `arrayElement`s to belong to the same block.
82*8975f5c5SAndroid Build Coastguard Worker ASSERT(nextBlock.name == block.name);
83*8975f5c5SAndroid Build Coastguard Worker ASSERT(nextBlock.pod.isArray);
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker return arraySize;
87*8975f5c5SAndroid Build Coastguard Worker }
88*8975f5c5SAndroid Build Coastguard Worker
SetupDefaultPipelineState(const vk::Context * context,const gl::ProgramExecutable & glExecutable,gl::PrimitiveMode mode,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,vk::GraphicsPipelineSubset subset,vk::GraphicsPipelineDesc * graphicsPipelineDescOut)89*8975f5c5SAndroid Build Coastguard Worker void SetupDefaultPipelineState(const vk::Context *context,
90*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramExecutable &glExecutable,
91*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
92*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
93*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
94*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset subset,
95*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc *graphicsPipelineDescOut)
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->initDefaults(context, vk::GraphicsPipelineSubset::Complete,
98*8975f5c5SAndroid Build Coastguard Worker pipelineRobustness, pipelineProtectedAccess);
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker // Set render pass state, affecting both complete and shaders-only pipelines.
101*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setTopology(mode);
102*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setRenderPassSampleCount(1);
103*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setRenderPassFramebufferFetchMode(
104*8975f5c5SAndroid Build Coastguard Worker vk::GetProgramFramebufferFetchMode(&glExecutable));
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::ProgramOutput> &outputVariables = glExecutable.getOutputVariables();
107*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::VariableLocation> &outputLocations = glExecutable.getOutputLocations();
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker gl::DrawBufferMask drawBuffers;
110*8975f5c5SAndroid Build Coastguard Worker
111*8975f5c5SAndroid Build Coastguard Worker for (const gl::VariableLocation &outputLocation : outputLocations)
112*8975f5c5SAndroid Build Coastguard Worker {
113*8975f5c5SAndroid Build Coastguard Worker if (outputLocation.arrayIndex == 0 && outputLocation.used() && !outputLocation.ignored)
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramOutput &outputVar = outputVariables[outputLocation.index];
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker if (angle::BeginsWith(outputVar.name, "gl_") && outputVar.name != "gl_FragColor")
118*8975f5c5SAndroid Build Coastguard Worker {
119*8975f5c5SAndroid Build Coastguard Worker continue;
120*8975f5c5SAndroid Build Coastguard Worker }
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Worker uint32_t location = 0;
123*8975f5c5SAndroid Build Coastguard Worker if (outputVar.pod.location != -1)
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker location = outputVar.pod.location;
126*8975f5c5SAndroid Build Coastguard Worker }
127*8975f5c5SAndroid Build Coastguard Worker
128*8975f5c5SAndroid Build Coastguard Worker GLenum type = gl::VariableComponentType(outputVar.pod.type);
129*8975f5c5SAndroid Build Coastguard Worker angle::FormatID format = angle::FormatID::R8G8B8A8_UNORM;
130*8975f5c5SAndroid Build Coastguard Worker if (type == GL_INT)
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker format = angle::FormatID::R8G8B8A8_SINT;
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker else if (type == GL_UNSIGNED_INT)
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker format = angle::FormatID::R8G8B8A8_UINT;
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker const size_t arraySize = outputVar.isArray() ? outputVar.getOutermostArraySize() : 1;
140*8975f5c5SAndroid Build Coastguard Worker for (size_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex)
141*8975f5c5SAndroid Build Coastguard Worker {
142*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setRenderPassColorAttachmentFormat(location + arrayIndex,
143*8975f5c5SAndroid Build Coastguard Worker format);
144*8975f5c5SAndroid Build Coastguard Worker drawBuffers.set(location + arrayIndex);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker }
147*8975f5c5SAndroid Build Coastguard Worker }
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker for (const gl::ProgramOutput &outputVar : outputVariables)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker if (outputVar.name == "gl_FragColor" || outputVar.name == "gl_FragData")
152*8975f5c5SAndroid Build Coastguard Worker {
153*8975f5c5SAndroid Build Coastguard Worker const size_t arraySize = outputVar.isArray() ? outputVar.getOutermostArraySize() : 1;
154*8975f5c5SAndroid Build Coastguard Worker for (size_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setRenderPassColorAttachmentFormat(
157*8975f5c5SAndroid Build Coastguard Worker arrayIndex, angle::FormatID::R8G8B8A8_UNORM);
158*8975f5c5SAndroid Build Coastguard Worker drawBuffers.set(arrayIndex);
159*8975f5c5SAndroid Build Coastguard Worker }
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker if (subset == vk::GraphicsPipelineSubset::Complete)
164*8975f5c5SAndroid Build Coastguard Worker {
165*8975f5c5SAndroid Build Coastguard Worker // Include vertex input state
166*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setVertexShaderComponentTypes(
167*8975f5c5SAndroid Build Coastguard Worker glExecutable.getNonBuiltinAttribLocationsMask(), glExecutable.getAttributesTypeMask());
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker // Include fragment output state
170*8975f5c5SAndroid Build Coastguard Worker gl::BlendStateExt::ColorMaskStorage::Type colorMask =
171*8975f5c5SAndroid Build Coastguard Worker gl::BlendStateExt::ColorMaskStorage::GetReplicatedValue(
172*8975f5c5SAndroid Build Coastguard Worker gl::BlendStateExt::PackColorMask(true, true, true, true),
173*8975f5c5SAndroid Build Coastguard Worker gl::BlendStateExt::ColorMaskStorage::GetMask(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS));
174*8975f5c5SAndroid Build Coastguard Worker graphicsPipelineDescOut->setColorWriteMasks(colorMask, {}, drawBuffers);
175*8975f5c5SAndroid Build Coastguard Worker }
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
GetPipelineCacheData(ContextVk * contextVk,const vk::PipelineCache & pipelineCache,angle::MemoryBuffer * cacheDataOut)178*8975f5c5SAndroid Build Coastguard Worker void GetPipelineCacheData(ContextVk *contextVk,
179*8975f5c5SAndroid Build Coastguard Worker const vk::PipelineCache &pipelineCache,
180*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *cacheDataOut)
181*8975f5c5SAndroid Build Coastguard Worker {
182*8975f5c5SAndroid Build Coastguard Worker ASSERT(pipelineCache.valid() || contextVk->getState().isGLES1() ||
183*8975f5c5SAndroid Build Coastguard Worker !contextVk->getFeatures().warmUpPipelineCacheAtLink.enabled ||
184*8975f5c5SAndroid Build Coastguard Worker !contextVk->getFeatures().hasEffectivePipelineCacheSerialization.enabled);
185*8975f5c5SAndroid Build Coastguard Worker if (!pipelineCache.valid() ||
186*8975f5c5SAndroid Build Coastguard Worker !contextVk->getFeatures().hasEffectivePipelineCacheSerialization.enabled)
187*8975f5c5SAndroid Build Coastguard Worker {
188*8975f5c5SAndroid Build Coastguard Worker return;
189*8975f5c5SAndroid Build Coastguard Worker }
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker // Extract the pipeline data. If failed, or empty, it's simply not stored on disk.
192*8975f5c5SAndroid Build Coastguard Worker size_t pipelineCacheSize = 0;
193*8975f5c5SAndroid Build Coastguard Worker VkResult result =
194*8975f5c5SAndroid Build Coastguard Worker pipelineCache.getCacheData(contextVk->getDevice(), &pipelineCacheSize, nullptr);
195*8975f5c5SAndroid Build Coastguard Worker if (result != VK_SUCCESS || pipelineCacheSize == 0)
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker return;
198*8975f5c5SAndroid Build Coastguard Worker }
199*8975f5c5SAndroid Build Coastguard Worker
200*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().enablePipelineCacheDataCompression.enabled)
201*8975f5c5SAndroid Build Coastguard Worker {
202*8975f5c5SAndroid Build Coastguard Worker std::vector<uint8_t> pipelineCacheData(pipelineCacheSize);
203*8975f5c5SAndroid Build Coastguard Worker result = pipelineCache.getCacheData(contextVk->getDevice(), &pipelineCacheSize,
204*8975f5c5SAndroid Build Coastguard Worker pipelineCacheData.data());
205*8975f5c5SAndroid Build Coastguard Worker if (result != VK_SUCCESS && result != VK_INCOMPLETE)
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker return;
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
210*8975f5c5SAndroid Build Coastguard Worker // Compress it.
211*8975f5c5SAndroid Build Coastguard Worker if (!angle::CompressBlob(pipelineCacheData.size(), pipelineCacheData.data(), cacheDataOut))
212*8975f5c5SAndroid Build Coastguard Worker {
213*8975f5c5SAndroid Build Coastguard Worker cacheDataOut->clear();
214*8975f5c5SAndroid Build Coastguard Worker }
215*8975f5c5SAndroid Build Coastguard Worker }
216*8975f5c5SAndroid Build Coastguard Worker else
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker if (!cacheDataOut->resize(pipelineCacheSize))
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker ERR() << "Failed to allocate memory for pipeline cache data.";
221*8975f5c5SAndroid Build Coastguard Worker return;
222*8975f5c5SAndroid Build Coastguard Worker }
223*8975f5c5SAndroid Build Coastguard Worker result = pipelineCache.getCacheData(contextVk->getDevice(), &pipelineCacheSize,
224*8975f5c5SAndroid Build Coastguard Worker cacheDataOut->data());
225*8975f5c5SAndroid Build Coastguard Worker if (result != VK_SUCCESS && result != VK_INCOMPLETE)
226*8975f5c5SAndroid Build Coastguard Worker {
227*8975f5c5SAndroid Build Coastguard Worker cacheDataOut->clear();
228*8975f5c5SAndroid Build Coastguard Worker }
229*8975f5c5SAndroid Build Coastguard Worker }
230*8975f5c5SAndroid Build Coastguard Worker }
231*8975f5c5SAndroid Build Coastguard Worker
MakeSpecConsts(ProgramTransformOptions transformOptions,const vk::GraphicsPipelineDesc & desc)232*8975f5c5SAndroid Build Coastguard Worker vk::SpecializationConstants MakeSpecConsts(ProgramTransformOptions transformOptions,
233*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker vk::SpecializationConstants specConsts;
236*8975f5c5SAndroid Build Coastguard Worker
237*8975f5c5SAndroid Build Coastguard Worker specConsts.surfaceRotation = transformOptions.surfaceRotation;
238*8975f5c5SAndroid Build Coastguard Worker specConsts.dither = desc.getEmulatedDitherControl();
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker return specConsts;
241*8975f5c5SAndroid Build Coastguard Worker }
242*8975f5c5SAndroid Build Coastguard Worker
GetWarmUpSubset(const angle::FeaturesVk & features)243*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset GetWarmUpSubset(const angle::FeaturesVk &features)
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker // Only build the shaders subset of the pipeline if VK_EXT_graphics_pipeline_library is
246*8975f5c5SAndroid Build Coastguard Worker // supported.
247*8975f5c5SAndroid Build Coastguard Worker return features.supportsGraphicsPipelineLibrary.enabled ? vk::GraphicsPipelineSubset::Shaders
248*8975f5c5SAndroid Build Coastguard Worker : vk::GraphicsPipelineSubset::Complete;
249*8975f5c5SAndroid Build Coastguard Worker }
250*8975f5c5SAndroid Build Coastguard Worker
UpdateFullTexturesDescriptorSet(vk::Context * context,const ShaderInterfaceVariableInfoMap & variableInfoMap,const vk::WriteDescriptorDescs & writeDescriptorDescs,UpdateDescriptorSetsBuilder * updateBuilder,const gl::ProgramExecutable & executable,const gl::ActiveTextureArray<TextureVk * > & textures,const gl::SamplerBindingVector & samplers,VkDescriptorSet descriptorSet)251*8975f5c5SAndroid Build Coastguard Worker angle::Result UpdateFullTexturesDescriptorSet(vk::Context *context,
252*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfoMap &variableInfoMap,
253*8975f5c5SAndroid Build Coastguard Worker const vk::WriteDescriptorDescs &writeDescriptorDescs,
254*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder,
255*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramExecutable &executable,
256*8975f5c5SAndroid Build Coastguard Worker const gl::ActiveTextureArray<TextureVk *> &textures,
257*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerBindingVector &samplers,
258*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet)
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = context->getRenderer();
261*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::SamplerBinding> &samplerBindings = executable.getSamplerBindings();
262*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLuint> &samplerBoundTextureUnits = executable.getSamplerBoundTextureUnits();
263*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::LinkedUniform> &uniforms = executable.getUniforms();
264*8975f5c5SAndroid Build Coastguard Worker const gl::ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
265*8975f5c5SAndroid Build Coastguard Worker
266*8975f5c5SAndroid Build Coastguard Worker // Allocate VkWriteDescriptorSet and initialize the data structure
267*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet *writeDescriptorSets =
268*8975f5c5SAndroid Build Coastguard Worker updateBuilder->allocWriteDescriptorSets(writeDescriptorDescs.size());
269*8975f5c5SAndroid Build Coastguard Worker for (uint32_t writeIndex = 0; writeIndex < writeDescriptorDescs.size(); ++writeIndex)
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker ASSERT(writeDescriptorDescs[writeIndex].descriptorCount > 0);
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet &writeSet = writeDescriptorSets[writeIndex];
274*8975f5c5SAndroid Build Coastguard Worker writeSet.descriptorCount = writeDescriptorDescs[writeIndex].descriptorCount;
275*8975f5c5SAndroid Build Coastguard Worker writeSet.descriptorType =
276*8975f5c5SAndroid Build Coastguard Worker static_cast<VkDescriptorType>(writeDescriptorDescs[writeIndex].descriptorType);
277*8975f5c5SAndroid Build Coastguard Worker writeSet.dstArrayElement = 0;
278*8975f5c5SAndroid Build Coastguard Worker writeSet.dstBinding = writeIndex;
279*8975f5c5SAndroid Build Coastguard Worker writeSet.dstSet = descriptorSet;
280*8975f5c5SAndroid Build Coastguard Worker writeSet.pBufferInfo = nullptr;
281*8975f5c5SAndroid Build Coastguard Worker writeSet.pImageInfo = nullptr;
282*8975f5c5SAndroid Build Coastguard Worker writeSet.pNext = nullptr;
283*8975f5c5SAndroid Build Coastguard Worker writeSet.pTexelBufferView = nullptr;
284*8975f5c5SAndroid Build Coastguard Worker writeSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
285*8975f5c5SAndroid Build Coastguard Worker // Always allocate VkDescriptorImageInfo. In less common case that descriptorType is
286*8975f5c5SAndroid Build Coastguard Worker // VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, this will not used.
287*8975f5c5SAndroid Build Coastguard Worker writeSet.pImageInfo = updateBuilder->allocDescriptorImageInfos(
288*8975f5c5SAndroid Build Coastguard Worker writeDescriptorDescs[writeIndex].descriptorCount);
289*8975f5c5SAndroid Build Coastguard Worker }
290*8975f5c5SAndroid Build Coastguard Worker
291*8975f5c5SAndroid Build Coastguard Worker for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex)
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker uint32_t uniformIndex = executable.getUniformIndexFromSamplerIndex(samplerIndex);
294*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &samplerUniform = uniforms[uniformIndex];
295*8975f5c5SAndroid Build Coastguard Worker if (samplerUniform.activeShaders().none())
296*8975f5c5SAndroid Build Coastguard Worker {
297*8975f5c5SAndroid Build Coastguard Worker continue;
298*8975f5c5SAndroid Build Coastguard Worker }
299*8975f5c5SAndroid Build Coastguard Worker
300*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType firstShaderType = samplerUniform.getFirstActiveShaderType();
301*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info =
302*8975f5c5SAndroid Build Coastguard Worker variableInfoMap.getVariableById(firstShaderType, samplerUniform.getId(firstShaderType));
303*8975f5c5SAndroid Build Coastguard Worker
304*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerBinding &samplerBinding = samplerBindings[samplerIndex];
305*8975f5c5SAndroid Build Coastguard Worker uint32_t arraySize = static_cast<uint32_t>(samplerBinding.textureUnitsCount);
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet &writeSet = writeDescriptorSets[info.binding];
308*8975f5c5SAndroid Build Coastguard Worker // Now fill pImageInfo or pTexelBufferView for writeSet
309*8975f5c5SAndroid Build Coastguard Worker for (uint32_t arrayElement = 0; arrayElement < arraySize; ++arrayElement)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker GLuint textureUnit =
312*8975f5c5SAndroid Build Coastguard Worker samplerBinding.getTextureUnit(samplerBoundTextureUnits, arrayElement);
313*8975f5c5SAndroid Build Coastguard Worker TextureVk *textureVk = textures[textureUnit];
314*8975f5c5SAndroid Build Coastguard Worker
315*8975f5c5SAndroid Build Coastguard Worker if (textureTypes[textureUnit] == gl::TextureType::Buffer)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker ASSERT(writeSet.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
318*8975f5c5SAndroid Build Coastguard Worker const vk::BufferView *view = nullptr;
319*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
320*8975f5c5SAndroid Build Coastguard Worker textureVk->getBufferView(context, nullptr, &samplerBinding, false, &view));
321*8975f5c5SAndroid Build Coastguard Worker
322*8975f5c5SAndroid Build Coastguard Worker VkBufferView &bufferView = updateBuilder->allocBufferView();
323*8975f5c5SAndroid Build Coastguard Worker bufferView = view->getHandle();
324*8975f5c5SAndroid Build Coastguard Worker writeSet.pTexelBufferView = &bufferView;
325*8975f5c5SAndroid Build Coastguard Worker }
326*8975f5c5SAndroid Build Coastguard Worker else
327*8975f5c5SAndroid Build Coastguard Worker {
328*8975f5c5SAndroid Build Coastguard Worker ASSERT(writeSet.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
329*8975f5c5SAndroid Build Coastguard Worker bool isSamplerExternalY2Y =
330*8975f5c5SAndroid Build Coastguard Worker samplerBinding.samplerType == GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
331*8975f5c5SAndroid Build Coastguard Worker gl::Sampler *sampler = samplers[textureUnit].get();
332*8975f5c5SAndroid Build Coastguard Worker const SamplerVk *samplerVk = sampler ? vk::GetImpl(sampler) : nullptr;
333*8975f5c5SAndroid Build Coastguard Worker const vk::SamplerHelper &samplerHelper =
334*8975f5c5SAndroid Build Coastguard Worker samplerVk ? samplerVk->getSampler()
335*8975f5c5SAndroid Build Coastguard Worker : textureVk->getSampler(isSamplerExternalY2Y);
336*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerState &samplerState =
337*8975f5c5SAndroid Build Coastguard Worker sampler ? sampler->getSamplerState() : textureVk->getState().getSamplerState();
338*8975f5c5SAndroid Build Coastguard Worker
339*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout imageLayout = textureVk->getImage().getCurrentImageLayout();
340*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView &imageView = textureVk->getReadImageView(
341*8975f5c5SAndroid Build Coastguard Worker samplerState.getSRGBDecode(), samplerUniform.isTexelFetchStaticUse(),
342*8975f5c5SAndroid Build Coastguard Worker isSamplerExternalY2Y);
343*8975f5c5SAndroid Build Coastguard Worker
344*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo *imageInfo = const_cast<VkDescriptorImageInfo *>(
345*8975f5c5SAndroid Build Coastguard Worker &writeSet.pImageInfo[arrayElement + samplerUniform.getOuterArrayOffset()]);
346*8975f5c5SAndroid Build Coastguard Worker imageInfo->imageLayout = ConvertImageLayoutToVkImageLayout(renderer, imageLayout);
347*8975f5c5SAndroid Build Coastguard Worker imageInfo->imageView = imageView.getHandle();
348*8975f5c5SAndroid Build Coastguard Worker imageInfo->sampler = samplerHelper.get().getHandle();
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker }
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker
353*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker } // namespace
356*8975f5c5SAndroid Build Coastguard Worker
357*8975f5c5SAndroid Build Coastguard Worker class ProgramExecutableVk::WarmUpTaskCommon : public vk::Context, public LinkSubTask
358*8975f5c5SAndroid Build Coastguard Worker {
359*8975f5c5SAndroid Build Coastguard Worker public:
WarmUpTaskCommon(vk::Renderer * renderer)360*8975f5c5SAndroid Build Coastguard Worker WarmUpTaskCommon(vk::Renderer *renderer) : vk::Context(renderer) {}
WarmUpTaskCommon(vk::Renderer * renderer,ProgramExecutableVk * executableVk,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess)361*8975f5c5SAndroid Build Coastguard Worker WarmUpTaskCommon(vk::Renderer *renderer,
362*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk *executableVk,
363*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
364*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess)
365*8975f5c5SAndroid Build Coastguard Worker : vk::Context(renderer),
366*8975f5c5SAndroid Build Coastguard Worker mExecutableVk(executableVk),
367*8975f5c5SAndroid Build Coastguard Worker mPipelineRobustness(pipelineRobustness),
368*8975f5c5SAndroid Build Coastguard Worker mPipelineProtectedAccess(pipelineProtectedAccess)
369*8975f5c5SAndroid Build Coastguard Worker {}
370*8975f5c5SAndroid Build Coastguard Worker ~WarmUpTaskCommon() override = default;
371*8975f5c5SAndroid Build Coastguard Worker
handleError(VkResult result,const char * file,const char * function,unsigned int line)372*8975f5c5SAndroid Build Coastguard Worker void handleError(VkResult result,
373*8975f5c5SAndroid Build Coastguard Worker const char *file,
374*8975f5c5SAndroid Build Coastguard Worker const char *function,
375*8975f5c5SAndroid Build Coastguard Worker unsigned int line) override
376*8975f5c5SAndroid Build Coastguard Worker {
377*8975f5c5SAndroid Build Coastguard Worker mErrorCode = result;
378*8975f5c5SAndroid Build Coastguard Worker mErrorFile = file;
379*8975f5c5SAndroid Build Coastguard Worker mErrorFunction = function;
380*8975f5c5SAndroid Build Coastguard Worker mErrorLine = line;
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker
operator ()()383*8975f5c5SAndroid Build Coastguard Worker void operator()() override { UNREACHABLE(); }
384*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,gl::InfoLog & infoLog)385*8975f5c5SAndroid Build Coastguard Worker angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
386*8975f5c5SAndroid Build Coastguard Worker {
387*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk = vk::GetImpl(context);
388*8975f5c5SAndroid Build Coastguard Worker return getResultImpl(contextVk, infoLog);
389*8975f5c5SAndroid Build Coastguard Worker }
390*8975f5c5SAndroid Build Coastguard Worker
getResultImpl(ContextVk * contextVk,gl::InfoLog & infoLog)391*8975f5c5SAndroid Build Coastguard Worker angle::Result getResultImpl(ContextVk *contextVk, gl::InfoLog &infoLog)
392*8975f5c5SAndroid Build Coastguard Worker {
393*8975f5c5SAndroid Build Coastguard Worker // Forward any errors
394*8975f5c5SAndroid Build Coastguard Worker if (mErrorCode != VK_SUCCESS)
395*8975f5c5SAndroid Build Coastguard Worker {
396*8975f5c5SAndroid Build Coastguard Worker contextVk->handleError(mErrorCode, mErrorFile, mErrorFunction, mErrorLine);
397*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker
400*8975f5c5SAndroid Build Coastguard Worker // Accumulate relevant perf counters
401*8975f5c5SAndroid Build Coastguard Worker const angle::VulkanPerfCounters &from = getPerfCounters();
402*8975f5c5SAndroid Build Coastguard Worker angle::VulkanPerfCounters &to = contextVk->getPerfCounters();
403*8975f5c5SAndroid Build Coastguard Worker
404*8975f5c5SAndroid Build Coastguard Worker to.pipelineCreationCacheHits += from.pipelineCreationCacheHits;
405*8975f5c5SAndroid Build Coastguard Worker to.pipelineCreationCacheMisses += from.pipelineCreationCacheMisses;
406*8975f5c5SAndroid Build Coastguard Worker to.pipelineCreationTotalCacheHitsDurationNs +=
407*8975f5c5SAndroid Build Coastguard Worker from.pipelineCreationTotalCacheHitsDurationNs;
408*8975f5c5SAndroid Build Coastguard Worker to.pipelineCreationTotalCacheMissesDurationNs +=
409*8975f5c5SAndroid Build Coastguard Worker from.pipelineCreationTotalCacheMissesDurationNs;
410*8975f5c5SAndroid Build Coastguard Worker
411*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
412*8975f5c5SAndroid Build Coastguard Worker }
413*8975f5c5SAndroid Build Coastguard Worker
414*8975f5c5SAndroid Build Coastguard Worker protected:
mergeProgramExecutablePipelineCacheToRenderer()415*8975f5c5SAndroid Build Coastguard Worker void mergeProgramExecutablePipelineCacheToRenderer()
416*8975f5c5SAndroid Build Coastguard Worker {
417*8975f5c5SAndroid Build Coastguard Worker angle::Result mergeResult = mExecutableVk->mergePipelineCacheToRenderer(this);
418*8975f5c5SAndroid Build Coastguard Worker
419*8975f5c5SAndroid Build Coastguard Worker // Treat error during merge as non fatal, log it and move on
420*8975f5c5SAndroid Build Coastguard Worker if (mergeResult != angle::Result::Continue)
421*8975f5c5SAndroid Build Coastguard Worker {
422*8975f5c5SAndroid Build Coastguard Worker INFO() << "Error while merging to Renderer's pipeline cache";
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker }
425*8975f5c5SAndroid Build Coastguard Worker
426*8975f5c5SAndroid Build Coastguard Worker // The front-end ensures that the program is not modified while the subtask is running, so it is
427*8975f5c5SAndroid Build Coastguard Worker // safe to directly access the executable from this parallel job. Note that this is the reason
428*8975f5c5SAndroid Build Coastguard Worker // why the front-end does not let the parallel job continue when a relink happens or the first
429*8975f5c5SAndroid Build Coastguard Worker // draw with this program.
430*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk *mExecutableVk = nullptr;
431*8975f5c5SAndroid Build Coastguard Worker const vk::PipelineRobustness mPipelineRobustness = vk::PipelineRobustness::NonRobust;
432*8975f5c5SAndroid Build Coastguard Worker const vk::PipelineProtectedAccess mPipelineProtectedAccess =
433*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess::Unprotected;
434*8975f5c5SAndroid Build Coastguard Worker
435*8975f5c5SAndroid Build Coastguard Worker // Error handling
436*8975f5c5SAndroid Build Coastguard Worker VkResult mErrorCode = VK_SUCCESS;
437*8975f5c5SAndroid Build Coastguard Worker const char *mErrorFile = nullptr;
438*8975f5c5SAndroid Build Coastguard Worker const char *mErrorFunction = nullptr;
439*8975f5c5SAndroid Build Coastguard Worker unsigned int mErrorLine = 0;
440*8975f5c5SAndroid Build Coastguard Worker };
441*8975f5c5SAndroid Build Coastguard Worker
442*8975f5c5SAndroid Build Coastguard Worker class ProgramExecutableVk::WarmUpComputeTask : public WarmUpTaskCommon
443*8975f5c5SAndroid Build Coastguard Worker {
444*8975f5c5SAndroid Build Coastguard Worker public:
WarmUpComputeTask(vk::Renderer * renderer,ProgramExecutableVk * executableVk,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess)445*8975f5c5SAndroid Build Coastguard Worker WarmUpComputeTask(vk::Renderer *renderer,
446*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk *executableVk,
447*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
448*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess)
449*8975f5c5SAndroid Build Coastguard Worker : WarmUpTaskCommon(renderer, executableVk, pipelineRobustness, pipelineProtectedAccess)
450*8975f5c5SAndroid Build Coastguard Worker {}
451*8975f5c5SAndroid Build Coastguard Worker ~WarmUpComputeTask() override = default;
452*8975f5c5SAndroid Build Coastguard Worker
operator ()()453*8975f5c5SAndroid Build Coastguard Worker void operator()() override
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker angle::Result result = mExecutableVk->warmUpComputePipelineCache(this, mPipelineRobustness,
456*8975f5c5SAndroid Build Coastguard Worker mPipelineProtectedAccess);
457*8975f5c5SAndroid Build Coastguard Worker ASSERT((result == angle::Result::Continue) == (mErrorCode == VK_SUCCESS));
458*8975f5c5SAndroid Build Coastguard Worker
459*8975f5c5SAndroid Build Coastguard Worker mergeProgramExecutablePipelineCacheToRenderer();
460*8975f5c5SAndroid Build Coastguard Worker }
461*8975f5c5SAndroid Build Coastguard Worker };
462*8975f5c5SAndroid Build Coastguard Worker
463*8975f5c5SAndroid Build Coastguard Worker using SharedRenderPass = vk::AtomicRefCounted<vk::RenderPass>;
464*8975f5c5SAndroid Build Coastguard Worker class ProgramExecutableVk::WarmUpGraphicsTask : public WarmUpTaskCommon
465*8975f5c5SAndroid Build Coastguard Worker {
466*8975f5c5SAndroid Build Coastguard Worker public:
WarmUpGraphicsTask(vk::Renderer * renderer,ProgramExecutableVk * executableVk,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,vk::GraphicsPipelineSubset subset,const bool isSurfaceRotated,const vk::GraphicsPipelineDesc & graphicsPipelineDesc,SharedRenderPass * compatibleRenderPass,vk::PipelineHelper * placeholderPipelineHelper)467*8975f5c5SAndroid Build Coastguard Worker WarmUpGraphicsTask(vk::Renderer *renderer,
468*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk *executableVk,
469*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
470*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
471*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset subset,
472*8975f5c5SAndroid Build Coastguard Worker const bool isSurfaceRotated,
473*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &graphicsPipelineDesc,
474*8975f5c5SAndroid Build Coastguard Worker SharedRenderPass *compatibleRenderPass,
475*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *placeholderPipelineHelper)
476*8975f5c5SAndroid Build Coastguard Worker : WarmUpTaskCommon(renderer, executableVk, pipelineRobustness, pipelineProtectedAccess),
477*8975f5c5SAndroid Build Coastguard Worker mPipelineSubset(subset),
478*8975f5c5SAndroid Build Coastguard Worker mIsSurfaceRotated(isSurfaceRotated),
479*8975f5c5SAndroid Build Coastguard Worker mGraphicsPipelineDesc(graphicsPipelineDesc),
480*8975f5c5SAndroid Build Coastguard Worker mWarmUpPipelineHelper(placeholderPipelineHelper),
481*8975f5c5SAndroid Build Coastguard Worker mCompatibleRenderPass(compatibleRenderPass)
482*8975f5c5SAndroid Build Coastguard Worker {
483*8975f5c5SAndroid Build Coastguard Worker ASSERT(mCompatibleRenderPass);
484*8975f5c5SAndroid Build Coastguard Worker mCompatibleRenderPass->addRef();
485*8975f5c5SAndroid Build Coastguard Worker }
486*8975f5c5SAndroid Build Coastguard Worker ~WarmUpGraphicsTask() override = default;
487*8975f5c5SAndroid Build Coastguard Worker
operator ()()488*8975f5c5SAndroid Build Coastguard Worker void operator()() override
489*8975f5c5SAndroid Build Coastguard Worker {
490*8975f5c5SAndroid Build Coastguard Worker angle::Result result = mExecutableVk->warmUpGraphicsPipelineCache(
491*8975f5c5SAndroid Build Coastguard Worker this, mPipelineRobustness, mPipelineProtectedAccess, mPipelineSubset, mIsSurfaceRotated,
492*8975f5c5SAndroid Build Coastguard Worker mGraphicsPipelineDesc, mCompatibleRenderPass->get(), mWarmUpPipelineHelper);
493*8975f5c5SAndroid Build Coastguard Worker ASSERT((result == angle::Result::Continue) == (mErrorCode == VK_SUCCESS));
494*8975f5c5SAndroid Build Coastguard Worker
495*8975f5c5SAndroid Build Coastguard Worker // Release reference to shared renderpass. If this is the last reference -
496*8975f5c5SAndroid Build Coastguard Worker // 1. merge ProgramExecutableVk's pipeline cache into the Renderer's cache
497*8975f5c5SAndroid Build Coastguard Worker // 2. cleanup temporary renderpass
498*8975f5c5SAndroid Build Coastguard Worker //
499*8975f5c5SAndroid Build Coastguard Worker // Note: with dynamic rendering, |mCompatibleRenderPass| holds a VK_NULL_HANDLE, and it's
500*8975f5c5SAndroid Build Coastguard Worker // just used as a ref count for this purpose.
501*8975f5c5SAndroid Build Coastguard Worker const bool isLastWarmUpTask = mCompatibleRenderPass->getAndReleaseRef() == 1;
502*8975f5c5SAndroid Build Coastguard Worker if (isLastWarmUpTask)
503*8975f5c5SAndroid Build Coastguard Worker {
504*8975f5c5SAndroid Build Coastguard Worker mergeProgramExecutablePipelineCacheToRenderer();
505*8975f5c5SAndroid Build Coastguard Worker
506*8975f5c5SAndroid Build Coastguard Worker mCompatibleRenderPass->get().destroy(getDevice());
507*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mCompatibleRenderPass);
508*8975f5c5SAndroid Build Coastguard Worker }
509*8975f5c5SAndroid Build Coastguard Worker }
510*8975f5c5SAndroid Build Coastguard Worker
511*8975f5c5SAndroid Build Coastguard Worker private:
512*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset mPipelineSubset;
513*8975f5c5SAndroid Build Coastguard Worker bool mIsSurfaceRotated;
514*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc mGraphicsPipelineDesc;
515*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *mWarmUpPipelineHelper;
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker // Temporary objects to clean up at the end
518*8975f5c5SAndroid Build Coastguard Worker SharedRenderPass *mCompatibleRenderPass;
519*8975f5c5SAndroid Build Coastguard Worker };
520*8975f5c5SAndroid Build Coastguard Worker
521*8975f5c5SAndroid Build Coastguard Worker // ShaderInfo implementation.
ShaderInfo()522*8975f5c5SAndroid Build Coastguard Worker ShaderInfo::ShaderInfo() {}
523*8975f5c5SAndroid Build Coastguard Worker
524*8975f5c5SAndroid Build Coastguard Worker ShaderInfo::~ShaderInfo() = default;
525*8975f5c5SAndroid Build Coastguard Worker
initShaders(vk::Context * context,const gl::ShaderBitSet & linkedShaderStages,const gl::ShaderMap<const angle::spirv::Blob * > & spirvBlobs,const ShaderInterfaceVariableInfoMap & variableInfoMap,bool isGLES1)526*8975f5c5SAndroid Build Coastguard Worker angle::Result ShaderInfo::initShaders(vk::Context *context,
527*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet &linkedShaderStages,
528*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<const angle::spirv::Blob *> &spirvBlobs,
529*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfoMap &variableInfoMap,
530*8975f5c5SAndroid Build Coastguard Worker bool isGLES1)
531*8975f5c5SAndroid Build Coastguard Worker {
532*8975f5c5SAndroid Build Coastguard Worker clear();
533*8975f5c5SAndroid Build Coastguard Worker
534*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker if (spirvBlobs[shaderType] != nullptr)
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker mSpirvBlobs[shaderType] = *spirvBlobs[shaderType];
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker }
541*8975f5c5SAndroid Build Coastguard Worker
542*8975f5c5SAndroid Build Coastguard Worker // Assert that SPIR-V transformation is correct, even if the test never issues a draw call.
543*8975f5c5SAndroid Build Coastguard Worker // Don't validate GLES1 programs because they are always created right before a draw, so they
544*8975f5c5SAndroid Build Coastguard Worker // will naturally be validated. This improves GLES1 test run times.
545*8975f5c5SAndroid Build Coastguard Worker if (!isGLES1)
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker ASSERT(ValidateTransformedSpirV(context, linkedShaderStages, variableInfoMap, mSpirvBlobs));
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker
550*8975f5c5SAndroid Build Coastguard Worker mIsInitialized = true;
551*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
552*8975f5c5SAndroid Build Coastguard Worker }
553*8975f5c5SAndroid Build Coastguard Worker
initShaderFromProgram(gl::ShaderType shaderType,const ShaderInfo & programShaderInfo)554*8975f5c5SAndroid Build Coastguard Worker void ShaderInfo::initShaderFromProgram(gl::ShaderType shaderType,
555*8975f5c5SAndroid Build Coastguard Worker const ShaderInfo &programShaderInfo)
556*8975f5c5SAndroid Build Coastguard Worker {
557*8975f5c5SAndroid Build Coastguard Worker mSpirvBlobs[shaderType] = programShaderInfo.mSpirvBlobs[shaderType];
558*8975f5c5SAndroid Build Coastguard Worker mIsInitialized = true;
559*8975f5c5SAndroid Build Coastguard Worker }
560*8975f5c5SAndroid Build Coastguard Worker
clear()561*8975f5c5SAndroid Build Coastguard Worker void ShaderInfo::clear()
562*8975f5c5SAndroid Build Coastguard Worker {
563*8975f5c5SAndroid Build Coastguard Worker for (angle::spirv::Blob &spirvBlob : mSpirvBlobs)
564*8975f5c5SAndroid Build Coastguard Worker {
565*8975f5c5SAndroid Build Coastguard Worker spirvBlob.clear();
566*8975f5c5SAndroid Build Coastguard Worker }
567*8975f5c5SAndroid Build Coastguard Worker mIsInitialized = false;
568*8975f5c5SAndroid Build Coastguard Worker }
569*8975f5c5SAndroid Build Coastguard Worker
load(gl::BinaryInputStream * stream)570*8975f5c5SAndroid Build Coastguard Worker void ShaderInfo::load(gl::BinaryInputStream *stream)
571*8975f5c5SAndroid Build Coastguard Worker {
572*8975f5c5SAndroid Build Coastguard Worker clear();
573*8975f5c5SAndroid Build Coastguard Worker
574*8975f5c5SAndroid Build Coastguard Worker // Read in shader codes for all shader types
575*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
576*8975f5c5SAndroid Build Coastguard Worker {
577*8975f5c5SAndroid Build Coastguard Worker stream->readVector(&mSpirvBlobs[shaderType]);
578*8975f5c5SAndroid Build Coastguard Worker }
579*8975f5c5SAndroid Build Coastguard Worker
580*8975f5c5SAndroid Build Coastguard Worker mIsInitialized = true;
581*8975f5c5SAndroid Build Coastguard Worker }
582*8975f5c5SAndroid Build Coastguard Worker
save(gl::BinaryOutputStream * stream)583*8975f5c5SAndroid Build Coastguard Worker void ShaderInfo::save(gl::BinaryOutputStream *stream)
584*8975f5c5SAndroid Build Coastguard Worker {
585*8975f5c5SAndroid Build Coastguard Worker ASSERT(valid());
586*8975f5c5SAndroid Build Coastguard Worker
587*8975f5c5SAndroid Build Coastguard Worker // Write out shader codes for all shader types
588*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker stream->writeVector(mSpirvBlobs[shaderType]);
591*8975f5c5SAndroid Build Coastguard Worker }
592*8975f5c5SAndroid Build Coastguard Worker }
593*8975f5c5SAndroid Build Coastguard Worker
594*8975f5c5SAndroid Build Coastguard Worker // ProgramInfo implementation.
ProgramInfo()595*8975f5c5SAndroid Build Coastguard Worker ProgramInfo::ProgramInfo() {}
596*8975f5c5SAndroid Build Coastguard Worker
597*8975f5c5SAndroid Build Coastguard Worker ProgramInfo::~ProgramInfo() = default;
598*8975f5c5SAndroid Build Coastguard Worker
initProgram(vk::Context * context,gl::ShaderType shaderType,bool isLastPreFragmentStage,bool isTransformFeedbackProgram,const ShaderInfo & shaderInfo,ProgramTransformOptions optionBits,const ShaderInterfaceVariableInfoMap & variableInfoMap)599*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramInfo::initProgram(vk::Context *context,
600*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType,
601*8975f5c5SAndroid Build Coastguard Worker bool isLastPreFragmentStage,
602*8975f5c5SAndroid Build Coastguard Worker bool isTransformFeedbackProgram,
603*8975f5c5SAndroid Build Coastguard Worker const ShaderInfo &shaderInfo,
604*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions optionBits,
605*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfoMap &variableInfoMap)
606*8975f5c5SAndroid Build Coastguard Worker {
607*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<angle::spirv::Blob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs();
608*8975f5c5SAndroid Build Coastguard Worker const angle::spirv::Blob &originalSpirvBlob = originalSpirvBlobs[shaderType];
609*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<angle::spirv::Blob> transformedSpirvBlobs;
610*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob &transformedSpirvBlob = transformedSpirvBlobs[shaderType];
611*8975f5c5SAndroid Build Coastguard Worker
612*8975f5c5SAndroid Build Coastguard Worker SpvTransformOptions options;
613*8975f5c5SAndroid Build Coastguard Worker options.shaderType = shaderType;
614*8975f5c5SAndroid Build Coastguard Worker options.isLastPreFragmentStage = isLastPreFragmentStage;
615*8975f5c5SAndroid Build Coastguard Worker options.isTransformFeedbackStage = isLastPreFragmentStage && isTransformFeedbackProgram &&
616*8975f5c5SAndroid Build Coastguard Worker !optionBits.removeTransformFeedbackEmulation;
617*8975f5c5SAndroid Build Coastguard Worker options.isTransformFeedbackEmulated = context->getFeatures().emulateTransformFeedback.enabled;
618*8975f5c5SAndroid Build Coastguard Worker options.isMultisampledFramebufferFetch =
619*8975f5c5SAndroid Build Coastguard Worker optionBits.multiSampleFramebufferFetch && shaderType == gl::ShaderType::Fragment;
620*8975f5c5SAndroid Build Coastguard Worker options.enableSampleShading = optionBits.enableSampleShading;
621*8975f5c5SAndroid Build Coastguard Worker
622*8975f5c5SAndroid Build Coastguard Worker options.useSpirvVaryingPrecisionFixer =
623*8975f5c5SAndroid Build Coastguard Worker context->getFeatures().varyingsRequireMatchingPrecisionInSpirv.enabled;
624*8975f5c5SAndroid Build Coastguard Worker
625*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
626*8975f5c5SAndroid Build Coastguard Worker SpvTransformSpirvCode(options, variableInfoMap, originalSpirvBlob, &transformedSpirvBlob));
627*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(vk::InitShaderModule(context, &mShaders[shaderType], transformedSpirvBlob.data(),
628*8975f5c5SAndroid Build Coastguard Worker transformedSpirvBlob.size() * sizeof(uint32_t)));
629*8975f5c5SAndroid Build Coastguard Worker
630*8975f5c5SAndroid Build Coastguard Worker mProgramHelper.setShader(shaderType, mShaders[shaderType]);
631*8975f5c5SAndroid Build Coastguard Worker
632*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
633*8975f5c5SAndroid Build Coastguard Worker }
634*8975f5c5SAndroid Build Coastguard Worker
release(ContextVk * contextVk)635*8975f5c5SAndroid Build Coastguard Worker void ProgramInfo::release(ContextVk *contextVk)
636*8975f5c5SAndroid Build Coastguard Worker {
637*8975f5c5SAndroid Build Coastguard Worker mProgramHelper.release(contextVk);
638*8975f5c5SAndroid Build Coastguard Worker
639*8975f5c5SAndroid Build Coastguard Worker for (vk::ShaderModulePtr &shader : mShaders)
640*8975f5c5SAndroid Build Coastguard Worker {
641*8975f5c5SAndroid Build Coastguard Worker shader.reset();
642*8975f5c5SAndroid Build Coastguard Worker }
643*8975f5c5SAndroid Build Coastguard Worker }
644*8975f5c5SAndroid Build Coastguard Worker
ProgramExecutableVk(const gl::ProgramExecutable * executable)645*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk::ProgramExecutableVk(const gl::ProgramExecutable *executable)
646*8975f5c5SAndroid Build Coastguard Worker : ProgramExecutableImpl(executable),
647*8975f5c5SAndroid Build Coastguard Worker mImmutableSamplersMaxDescriptorCount(1),
648*8975f5c5SAndroid Build Coastguard Worker mUniformBufferDescriptorType(VK_DESCRIPTOR_TYPE_MAX_ENUM),
649*8975f5c5SAndroid Build Coastguard Worker mDynamicUniformDescriptorOffsets{},
650*8975f5c5SAndroid Build Coastguard Worker mValidGraphicsPermutations{},
651*8975f5c5SAndroid Build Coastguard Worker mValidComputePermutations{}
652*8975f5c5SAndroid Build Coastguard Worker {
653*8975f5c5SAndroid Build Coastguard Worker for (std::shared_ptr<BufferAndLayout> &defaultBlock : mDefaultUniformBlocks)
654*8975f5c5SAndroid Build Coastguard Worker {
655*8975f5c5SAndroid Build Coastguard Worker defaultBlock = std::make_shared<BufferAndLayout>();
656*8975f5c5SAndroid Build Coastguard Worker }
657*8975f5c5SAndroid Build Coastguard Worker }
658*8975f5c5SAndroid Build Coastguard Worker
~ProgramExecutableVk()659*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableVk::~ProgramExecutableVk()
660*8975f5c5SAndroid Build Coastguard Worker {
661*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mPipelineCache.valid());
662*8975f5c5SAndroid Build Coastguard Worker }
663*8975f5c5SAndroid Build Coastguard Worker
destroy(const gl::Context * context)664*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::destroy(const gl::Context *context)
665*8975f5c5SAndroid Build Coastguard Worker {
666*8975f5c5SAndroid Build Coastguard Worker reset(vk::GetImpl(context));
667*8975f5c5SAndroid Build Coastguard Worker }
668*8975f5c5SAndroid Build Coastguard Worker
resetLayout(ContextVk * contextVk)669*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::resetLayout(ContextVk *contextVk)
670*8975f5c5SAndroid Build Coastguard Worker {
671*8975f5c5SAndroid Build Coastguard Worker if (!mPipelineLayout)
672*8975f5c5SAndroid Build Coastguard Worker {
673*8975f5c5SAndroid Build Coastguard Worker ASSERT(mValidGraphicsPermutations.none());
674*8975f5c5SAndroid Build Coastguard Worker ASSERT(mValidComputePermutations.none());
675*8975f5c5SAndroid Build Coastguard Worker return;
676*8975f5c5SAndroid Build Coastguard Worker }
677*8975f5c5SAndroid Build Coastguard Worker
678*8975f5c5SAndroid Build Coastguard Worker waitForPostLinkTasksImpl(contextVk);
679*8975f5c5SAndroid Build Coastguard Worker
680*8975f5c5SAndroid Build Coastguard Worker for (auto &descriptorSetLayout : mDescriptorSetLayouts)
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker descriptorSetLayout.reset();
683*8975f5c5SAndroid Build Coastguard Worker }
684*8975f5c5SAndroid Build Coastguard Worker mImmutableSamplersMaxDescriptorCount = 1;
685*8975f5c5SAndroid Build Coastguard Worker mImmutableSamplerIndexMap.clear();
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker for (vk::DescriptorSetPointer &descriptorSet : mDescriptorSets)
688*8975f5c5SAndroid Build Coastguard Worker {
689*8975f5c5SAndroid Build Coastguard Worker descriptorSet.reset();
690*8975f5c5SAndroid Build Coastguard Worker }
691*8975f5c5SAndroid Build Coastguard Worker
692*8975f5c5SAndroid Build Coastguard Worker for (vk::DynamicDescriptorPoolPointer &pool : mDynamicDescriptorPools)
693*8975f5c5SAndroid Build Coastguard Worker {
694*8975f5c5SAndroid Build Coastguard Worker pool.reset();
695*8975f5c5SAndroid Build Coastguard Worker }
696*8975f5c5SAndroid Build Coastguard Worker
697*8975f5c5SAndroid Build Coastguard Worker // Initialize with an invalid BufferSerial
698*8975f5c5SAndroid Build Coastguard Worker mCurrentDefaultUniformBufferSerial = vk::BufferSerial();
699*8975f5c5SAndroid Build Coastguard Worker
700*8975f5c5SAndroid Build Coastguard Worker for (size_t index : mValidGraphicsPermutations)
701*8975f5c5SAndroid Build Coastguard Worker {
702*8975f5c5SAndroid Build Coastguard Worker mCompleteGraphicsPipelines[index].release(contextVk);
703*8975f5c5SAndroid Build Coastguard Worker mShadersGraphicsPipelines[index].release(contextVk);
704*8975f5c5SAndroid Build Coastguard Worker
705*8975f5c5SAndroid Build Coastguard Worker // Program infos and pipeline layout must be released after pipelines are; they might be
706*8975f5c5SAndroid Build Coastguard Worker // having pending jobs that are referencing them.
707*8975f5c5SAndroid Build Coastguard Worker mGraphicsProgramInfos[index].release(contextVk);
708*8975f5c5SAndroid Build Coastguard Worker }
709*8975f5c5SAndroid Build Coastguard Worker mValidGraphicsPermutations.reset();
710*8975f5c5SAndroid Build Coastguard Worker
711*8975f5c5SAndroid Build Coastguard Worker for (size_t index : mValidComputePermutations)
712*8975f5c5SAndroid Build Coastguard Worker {
713*8975f5c5SAndroid Build Coastguard Worker mComputePipelines[index].release(contextVk);
714*8975f5c5SAndroid Build Coastguard Worker }
715*8975f5c5SAndroid Build Coastguard Worker mComputeProgramInfo.release(contextVk);
716*8975f5c5SAndroid Build Coastguard Worker mValidComputePermutations.reset();
717*8975f5c5SAndroid Build Coastguard Worker
718*8975f5c5SAndroid Build Coastguard Worker mPipelineLayout.reset();
719*8975f5c5SAndroid Build Coastguard Worker
720*8975f5c5SAndroid Build Coastguard Worker contextVk->onProgramExecutableReset(this);
721*8975f5c5SAndroid Build Coastguard Worker }
722*8975f5c5SAndroid Build Coastguard Worker
reset(ContextVk * contextVk)723*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::reset(ContextVk *contextVk)
724*8975f5c5SAndroid Build Coastguard Worker {
725*8975f5c5SAndroid Build Coastguard Worker resetLayout(contextVk);
726*8975f5c5SAndroid Build Coastguard Worker
727*8975f5c5SAndroid Build Coastguard Worker if (mPipelineCache.valid())
728*8975f5c5SAndroid Build Coastguard Worker {
729*8975f5c5SAndroid Build Coastguard Worker mPipelineCache.destroy(contextVk->getDevice());
730*8975f5c5SAndroid Build Coastguard Worker }
731*8975f5c5SAndroid Build Coastguard Worker }
732*8975f5c5SAndroid Build Coastguard Worker
initializePipelineCache(vk::Context * context,bool compressed,const std::vector<uint8_t> & pipelineData)733*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::initializePipelineCache(vk::Context *context,
734*8975f5c5SAndroid Build Coastguard Worker bool compressed,
735*8975f5c5SAndroid Build Coastguard Worker const std::vector<uint8_t> &pipelineData)
736*8975f5c5SAndroid Build Coastguard Worker {
737*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mPipelineCache.valid());
738*8975f5c5SAndroid Build Coastguard Worker
739*8975f5c5SAndroid Build Coastguard Worker size_t dataSize = pipelineData.size();
740*8975f5c5SAndroid Build Coastguard Worker const uint8_t *dataPointer = pipelineData.data();
741*8975f5c5SAndroid Build Coastguard Worker
742*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer uncompressedData;
743*8975f5c5SAndroid Build Coastguard Worker if (compressed)
744*8975f5c5SAndroid Build Coastguard Worker {
745*8975f5c5SAndroid Build Coastguard Worker if (!angle::DecompressBlob(dataPointer, dataSize, kMaxLocalPipelineCacheSize,
746*8975f5c5SAndroid Build Coastguard Worker &uncompressedData))
747*8975f5c5SAndroid Build Coastguard Worker {
748*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
749*8975f5c5SAndroid Build Coastguard Worker }
750*8975f5c5SAndroid Build Coastguard Worker dataSize = uncompressedData.size();
751*8975f5c5SAndroid Build Coastguard Worker dataPointer = uncompressedData.data();
752*8975f5c5SAndroid Build Coastguard Worker }
753*8975f5c5SAndroid Build Coastguard Worker
754*8975f5c5SAndroid Build Coastguard Worker VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
755*8975f5c5SAndroid Build Coastguard Worker pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
756*8975f5c5SAndroid Build Coastguard Worker pipelineCacheCreateInfo.initialDataSize = dataSize;
757*8975f5c5SAndroid Build Coastguard Worker pipelineCacheCreateInfo.pInitialData = dataPointer;
758*8975f5c5SAndroid Build Coastguard Worker
759*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_TRY(context, mPipelineCache.init(context->getDevice(), pipelineCacheCreateInfo));
760*8975f5c5SAndroid Build Coastguard Worker
761*8975f5c5SAndroid Build Coastguard Worker // Merge the pipeline cache into Renderer's.
762*8975f5c5SAndroid Build Coastguard Worker if (context->getFeatures().mergeProgramPipelineCachesToGlobalCache.enabled)
763*8975f5c5SAndroid Build Coastguard Worker {
764*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(context->getRenderer()->mergeIntoPipelineCache(context, mPipelineCache));
765*8975f5c5SAndroid Build Coastguard Worker }
766*8975f5c5SAndroid Build Coastguard Worker
767*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
768*8975f5c5SAndroid Build Coastguard Worker }
769*8975f5c5SAndroid Build Coastguard Worker
ensurePipelineCacheInitialized(vk::Context * context)770*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::ensurePipelineCacheInitialized(vk::Context *context)
771*8975f5c5SAndroid Build Coastguard Worker {
772*8975f5c5SAndroid Build Coastguard Worker if (!mPipelineCache.valid())
773*8975f5c5SAndroid Build Coastguard Worker {
774*8975f5c5SAndroid Build Coastguard Worker VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
775*8975f5c5SAndroid Build Coastguard Worker pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
776*8975f5c5SAndroid Build Coastguard Worker
777*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_TRY(context, mPipelineCache.init(context->getDevice(), pipelineCacheCreateInfo));
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker
780*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
781*8975f5c5SAndroid Build Coastguard Worker }
782*8975f5c5SAndroid Build Coastguard Worker
load(ContextVk * contextVk,bool isSeparable,gl::BinaryInputStream * stream,egl::CacheGetResult * resultOut)783*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::load(ContextVk *contextVk,
784*8975f5c5SAndroid Build Coastguard Worker bool isSeparable,
785*8975f5c5SAndroid Build Coastguard Worker gl::BinaryInputStream *stream,
786*8975f5c5SAndroid Build Coastguard Worker egl::CacheGetResult *resultOut)
787*8975f5c5SAndroid Build Coastguard Worker {
788*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.load(stream);
789*8975f5c5SAndroid Build Coastguard Worker mOriginalShaderInfo.load(stream);
790*8975f5c5SAndroid Build Coastguard Worker
791*8975f5c5SAndroid Build Coastguard Worker // Deserializes the uniformLayout data of mDefaultUniformBlocks
792*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
793*8975f5c5SAndroid Build Coastguard Worker {
794*8975f5c5SAndroid Build Coastguard Worker stream->readVector(&mDefaultUniformBlocks[shaderType]->uniformLayout);
795*8975f5c5SAndroid Build Coastguard Worker }
796*8975f5c5SAndroid Build Coastguard Worker
797*8975f5c5SAndroid Build Coastguard Worker // Deserializes required uniform block memory sizes
798*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<size_t> requiredBufferSize;
799*8975f5c5SAndroid Build Coastguard Worker stream->readPackedEnumMap(&requiredBufferSize);
800*8975f5c5SAndroid Build Coastguard Worker
801*8975f5c5SAndroid Build Coastguard Worker if (!isSeparable)
802*8975f5c5SAndroid Build Coastguard Worker {
803*8975f5c5SAndroid Build Coastguard Worker size_t compressedPipelineDataSize = 0;
804*8975f5c5SAndroid Build Coastguard Worker stream->readInt<size_t>(&compressedPipelineDataSize);
805*8975f5c5SAndroid Build Coastguard Worker
806*8975f5c5SAndroid Build Coastguard Worker std::vector<uint8_t> compressedPipelineData(compressedPipelineDataSize);
807*8975f5c5SAndroid Build Coastguard Worker if (compressedPipelineDataSize > 0)
808*8975f5c5SAndroid Build Coastguard Worker {
809*8975f5c5SAndroid Build Coastguard Worker bool compressedData = false;
810*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&compressedData);
811*8975f5c5SAndroid Build Coastguard Worker stream->readBytes(compressedPipelineData.data(), compressedPipelineDataSize);
812*8975f5c5SAndroid Build Coastguard Worker // Initialize the pipeline cache based on cached data.
813*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializePipelineCache(contextVk, compressedData, compressedPipelineData));
814*8975f5c5SAndroid Build Coastguard Worker }
815*8975f5c5SAndroid Build Coastguard Worker }
816*8975f5c5SAndroid Build Coastguard Worker
817*8975f5c5SAndroid Build Coastguard Worker // Initialize and resize the mDefaultUniformBlocks' memory
818*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(resizeUniformBlockMemory(contextVk, requiredBufferSize));
819*8975f5c5SAndroid Build Coastguard Worker
820*8975f5c5SAndroid Build Coastguard Worker resetLayout(contextVk);
821*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createPipelineLayout(contextVk, &contextVk->getPipelineLayoutCache(),
822*8975f5c5SAndroid Build Coastguard Worker &contextVk->getDescriptorSetLayoutCache(), nullptr));
823*8975f5c5SAndroid Build Coastguard Worker
824*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeDescriptorPools(contextVk, &contextVk->getDescriptorSetLayoutCache(),
825*8975f5c5SAndroid Build Coastguard Worker &contextVk->getMetaDescriptorPools()));
826*8975f5c5SAndroid Build Coastguard Worker
827*8975f5c5SAndroid Build Coastguard Worker *resultOut = egl::CacheGetResult::Success;
828*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
829*8975f5c5SAndroid Build Coastguard Worker }
830*8975f5c5SAndroid Build Coastguard Worker
save(ContextVk * contextVk,bool isSeparable,gl::BinaryOutputStream * stream)831*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::save(ContextVk *contextVk,
832*8975f5c5SAndroid Build Coastguard Worker bool isSeparable,
833*8975f5c5SAndroid Build Coastguard Worker gl::BinaryOutputStream *stream)
834*8975f5c5SAndroid Build Coastguard Worker {
835*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.save(stream);
836*8975f5c5SAndroid Build Coastguard Worker mOriginalShaderInfo.save(stream);
837*8975f5c5SAndroid Build Coastguard Worker
838*8975f5c5SAndroid Build Coastguard Worker // Serializes the uniformLayout data of mDefaultUniformBlocks
839*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
840*8975f5c5SAndroid Build Coastguard Worker {
841*8975f5c5SAndroid Build Coastguard Worker stream->writeVector(mDefaultUniformBlocks[shaderType]->uniformLayout);
842*8975f5c5SAndroid Build Coastguard Worker }
843*8975f5c5SAndroid Build Coastguard Worker
844*8975f5c5SAndroid Build Coastguard Worker // Serializes required uniform block memory sizes
845*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<size_t> uniformDataSize;
846*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
847*8975f5c5SAndroid Build Coastguard Worker {
848*8975f5c5SAndroid Build Coastguard Worker uniformDataSize[shaderType] = mDefaultUniformBlocks[shaderType]->uniformData.size();
849*8975f5c5SAndroid Build Coastguard Worker }
850*8975f5c5SAndroid Build Coastguard Worker stream->writePackedEnumMap(uniformDataSize);
851*8975f5c5SAndroid Build Coastguard Worker
852*8975f5c5SAndroid Build Coastguard Worker // Need to wait for warm up tasks to complete.
853*8975f5c5SAndroid Build Coastguard Worker waitForPostLinkTasksImpl(contextVk);
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker // Compress and save mPipelineCache. Separable programs don't warm up the cache, while program
856*8975f5c5SAndroid Build Coastguard Worker // pipelines do. However, currently ANGLE doesn't sync program pipelines to cache. ANGLE could
857*8975f5c5SAndroid Build Coastguard Worker // potentially use VK_EXT_graphics_pipeline_library to create separate pipelines for
858*8975f5c5SAndroid Build Coastguard Worker // pre-rasterization and fragment subsets, but currently those subsets are bundled together.
859*8975f5c5SAndroid Build Coastguard Worker if (!isSeparable)
860*8975f5c5SAndroid Build Coastguard Worker {
861*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer cacheData;
862*8975f5c5SAndroid Build Coastguard Worker
863*8975f5c5SAndroid Build Coastguard Worker GetPipelineCacheData(contextVk, mPipelineCache, &cacheData);
864*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(cacheData.size());
865*8975f5c5SAndroid Build Coastguard Worker if (cacheData.size() > 0)
866*8975f5c5SAndroid Build Coastguard Worker {
867*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(contextVk->getFeatures().enablePipelineCacheDataCompression.enabled);
868*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(cacheData.data(), cacheData.size());
869*8975f5c5SAndroid Build Coastguard Worker }
870*8975f5c5SAndroid Build Coastguard Worker }
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker
clearVariableInfoMap()873*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::clearVariableInfoMap()
874*8975f5c5SAndroid Build Coastguard Worker {
875*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.clear();
876*8975f5c5SAndroid Build Coastguard Worker }
877*8975f5c5SAndroid Build Coastguard Worker
getPipelineCacheWarmUpTasks(vk::Renderer * renderer,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,std::vector<std::shared_ptr<LinkSubTask>> * postLinkSubTasksOut)878*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::getPipelineCacheWarmUpTasks(
879*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer,
880*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
881*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
882*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut)
883*8975f5c5SAndroid Build Coastguard Worker {
884*8975f5c5SAndroid Build Coastguard Worker ASSERT(!postLinkSubTasksOut || postLinkSubTasksOut->empty());
885*8975f5c5SAndroid Build Coastguard Worker
886*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineSubset subset = GetWarmUpSubset(renderer->getFeatures());
887*8975f5c5SAndroid Build Coastguard Worker
888*8975f5c5SAndroid Build Coastguard Worker bool isCompute = false;
889*8975f5c5SAndroid Build Coastguard Worker angle::FixedVector<bool, 2> surfaceRotationVariations = {false};
890*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc *graphicsPipelineDesc = nullptr;
891*8975f5c5SAndroid Build Coastguard Worker vk::RenderPass compatibleRenderPass;
892*8975f5c5SAndroid Build Coastguard Worker
893*8975f5c5SAndroid Build Coastguard Worker WarmUpTaskCommon prepForWarmUpContext(renderer);
894*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(prepareForWarmUpPipelineCache(
895*8975f5c5SAndroid Build Coastguard Worker &prepForWarmUpContext, pipelineRobustness, pipelineProtectedAccess, subset, &isCompute,
896*8975f5c5SAndroid Build Coastguard Worker &surfaceRotationVariations, &graphicsPipelineDesc, &compatibleRenderPass));
897*8975f5c5SAndroid Build Coastguard Worker
898*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<rx::LinkSubTask>> warmUpSubTasks;
899*8975f5c5SAndroid Build Coastguard Worker if (isCompute)
900*8975f5c5SAndroid Build Coastguard Worker {
901*8975f5c5SAndroid Build Coastguard Worker ASSERT(!compatibleRenderPass.valid());
902*8975f5c5SAndroid Build Coastguard Worker
903*8975f5c5SAndroid Build Coastguard Worker warmUpSubTasks.push_back(std::make_shared<WarmUpComputeTask>(
904*8975f5c5SAndroid Build Coastguard Worker renderer, this, pipelineRobustness, pipelineProtectedAccess));
905*8975f5c5SAndroid Build Coastguard Worker }
906*8975f5c5SAndroid Build Coastguard Worker else
907*8975f5c5SAndroid Build Coastguard Worker {
908*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = {};
909*8975f5c5SAndroid Build Coastguard Worker SharedRenderPass *sharedRenderPass = new SharedRenderPass(std::move(compatibleRenderPass));
910*8975f5c5SAndroid Build Coastguard Worker for (bool surfaceRotation : surfaceRotationVariations)
911*8975f5c5SAndroid Build Coastguard Worker {
912*8975f5c5SAndroid Build Coastguard Worker // Add a placeholder entry in GraphicsPipelineCache
913*8975f5c5SAndroid Build Coastguard Worker transformOptions.surfaceRotation = surfaceRotation;
914*8975f5c5SAndroid Build Coastguard Worker const uint8_t programIndex = transformOptions.permutationIndex;
915*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *pipelineHelper = nullptr;
916*8975f5c5SAndroid Build Coastguard Worker if (subset == vk::GraphicsPipelineSubset::Complete)
917*8975f5c5SAndroid Build Coastguard Worker {
918*8975f5c5SAndroid Build Coastguard Worker CompleteGraphicsPipelineCache &pipelines = mCompleteGraphicsPipelines[programIndex];
919*8975f5c5SAndroid Build Coastguard Worker pipelines.populate(mWarmUpGraphicsPipelineDesc, vk::Pipeline(), &pipelineHelper);
920*8975f5c5SAndroid Build Coastguard Worker }
921*8975f5c5SAndroid Build Coastguard Worker else
922*8975f5c5SAndroid Build Coastguard Worker {
923*8975f5c5SAndroid Build Coastguard Worker ASSERT(subset == vk::GraphicsPipelineSubset::Shaders);
924*8975f5c5SAndroid Build Coastguard Worker ShadersGraphicsPipelineCache &pipelines = mShadersGraphicsPipelines[programIndex];
925*8975f5c5SAndroid Build Coastguard Worker pipelines.populate(mWarmUpGraphicsPipelineDesc, vk::Pipeline(), &pipelineHelper);
926*8975f5c5SAndroid Build Coastguard Worker }
927*8975f5c5SAndroid Build Coastguard Worker
928*8975f5c5SAndroid Build Coastguard Worker warmUpSubTasks.push_back(std::make_shared<WarmUpGraphicsTask>(
929*8975f5c5SAndroid Build Coastguard Worker renderer, this, pipelineRobustness, pipelineProtectedAccess, subset,
930*8975f5c5SAndroid Build Coastguard Worker surfaceRotation, *graphicsPipelineDesc, sharedRenderPass, pipelineHelper));
931*8975f5c5SAndroid Build Coastguard Worker }
932*8975f5c5SAndroid Build Coastguard Worker }
933*8975f5c5SAndroid Build Coastguard Worker
934*8975f5c5SAndroid Build Coastguard Worker // If the caller hasn't provided a valid async task container, inline the warmUp tasks.
935*8975f5c5SAndroid Build Coastguard Worker if (postLinkSubTasksOut)
936*8975f5c5SAndroid Build Coastguard Worker {
937*8975f5c5SAndroid Build Coastguard Worker *postLinkSubTasksOut = std::move(warmUpSubTasks);
938*8975f5c5SAndroid Build Coastguard Worker }
939*8975f5c5SAndroid Build Coastguard Worker else
940*8975f5c5SAndroid Build Coastguard Worker {
941*8975f5c5SAndroid Build Coastguard Worker for (std::shared_ptr<rx::LinkSubTask> &task : warmUpSubTasks)
942*8975f5c5SAndroid Build Coastguard Worker {
943*8975f5c5SAndroid Build Coastguard Worker (*task)();
944*8975f5c5SAndroid Build Coastguard Worker }
945*8975f5c5SAndroid Build Coastguard Worker warmUpSubTasks.clear();
946*8975f5c5SAndroid Build Coastguard Worker }
947*8975f5c5SAndroid Build Coastguard Worker
948*8975f5c5SAndroid Build Coastguard Worker ASSERT(warmUpSubTasks.empty());
949*8975f5c5SAndroid Build Coastguard Worker
950*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
951*8975f5c5SAndroid Build Coastguard Worker }
952*8975f5c5SAndroid Build Coastguard Worker
prepareForWarmUpPipelineCache(vk::Context * context,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,vk::GraphicsPipelineSubset subset,bool * isComputeOut,angle::FixedVector<bool,2> * surfaceRotationVariationsOut,vk::GraphicsPipelineDesc ** graphicsPipelineDescOut,vk::RenderPass * renderPassOut)953*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::prepareForWarmUpPipelineCache(
954*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
955*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
956*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
957*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset subset,
958*8975f5c5SAndroid Build Coastguard Worker bool *isComputeOut,
959*8975f5c5SAndroid Build Coastguard Worker angle::FixedVector<bool, 2> *surfaceRotationVariationsOut,
960*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc **graphicsPipelineDescOut,
961*8975f5c5SAndroid Build Coastguard Worker vk::RenderPass *renderPassOut)
962*8975f5c5SAndroid Build Coastguard Worker {
963*8975f5c5SAndroid Build Coastguard Worker ASSERT(isComputeOut);
964*8975f5c5SAndroid Build Coastguard Worker ASSERT(surfaceRotationVariationsOut);
965*8975f5c5SAndroid Build Coastguard Worker ASSERT(graphicsPipelineDescOut);
966*8975f5c5SAndroid Build Coastguard Worker ASSERT(renderPassOut);
967*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getFeatures().warmUpPipelineCacheAtLink.enabled);
968*8975f5c5SAndroid Build Coastguard Worker
969*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensurePipelineCacheInitialized(context));
970*8975f5c5SAndroid Build Coastguard Worker
971*8975f5c5SAndroid Build Coastguard Worker *isComputeOut = false;
972*8975f5c5SAndroid Build Coastguard Worker const bool isCompute = mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute);
973*8975f5c5SAndroid Build Coastguard Worker if (isCompute)
974*8975f5c5SAndroid Build Coastguard Worker {
975*8975f5c5SAndroid Build Coastguard Worker // Initialize compute program.
976*8975f5c5SAndroid Build Coastguard Worker vk::ComputePipelineOptions pipelineOptions =
977*8975f5c5SAndroid Build Coastguard Worker vk::GetComputePipelineOptions(pipelineRobustness, pipelineProtectedAccess);
978*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
979*8975f5c5SAndroid Build Coastguard Worker initComputeProgram(context, &mComputeProgramInfo, mVariableInfoMap, pipelineOptions));
980*8975f5c5SAndroid Build Coastguard Worker
981*8975f5c5SAndroid Build Coastguard Worker *isComputeOut = true;
982*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
983*8975f5c5SAndroid Build Coastguard Worker }
984*8975f5c5SAndroid Build Coastguard Worker
985*8975f5c5SAndroid Build Coastguard Worker // It is only at drawcall time that we will have complete information required to build the
986*8975f5c5SAndroid Build Coastguard Worker // graphics pipeline descriptor. Use the most "commonly seen" state values and create the
987*8975f5c5SAndroid Build Coastguard Worker // pipeline.
988*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode = (mExecutable->hasLinkedShaderStage(gl::ShaderType::TessControl) ||
989*8975f5c5SAndroid Build Coastguard Worker mExecutable->hasLinkedShaderStage(gl::ShaderType::TessEvaluation))
990*8975f5c5SAndroid Build Coastguard Worker ? gl::PrimitiveMode::Patches
991*8975f5c5SAndroid Build Coastguard Worker : gl::PrimitiveMode::TriangleStrip;
992*8975f5c5SAndroid Build Coastguard Worker SetupDefaultPipelineState(context, *mExecutable, mode, pipelineRobustness,
993*8975f5c5SAndroid Build Coastguard Worker pipelineProtectedAccess, subset, &mWarmUpGraphicsPipelineDesc);
994*8975f5c5SAndroid Build Coastguard Worker
995*8975f5c5SAndroid Build Coastguard Worker // Create a temporary compatible RenderPass. The render pass cache in ContextVk cannot be used
996*8975f5c5SAndroid Build Coastguard Worker // because this function may be called from a worker thread.
997*8975f5c5SAndroid Build Coastguard Worker vk::AttachmentOpsArray ops;
998*8975f5c5SAndroid Build Coastguard Worker RenderPassCache::InitializeOpsForCompatibleRenderPass(
999*8975f5c5SAndroid Build Coastguard Worker mWarmUpGraphicsPipelineDesc.getRenderPassDesc(), &ops);
1000*8975f5c5SAndroid Build Coastguard Worker if (!context->getFeatures().preferDynamicRendering.enabled)
1001*8975f5c5SAndroid Build Coastguard Worker {
1002*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(RenderPassCache::MakeRenderPass(
1003*8975f5c5SAndroid Build Coastguard Worker context, mWarmUpGraphicsPipelineDesc.getRenderPassDesc(), ops, renderPassOut, nullptr));
1004*8975f5c5SAndroid Build Coastguard Worker }
1005*8975f5c5SAndroid Build Coastguard Worker
1006*8975f5c5SAndroid Build Coastguard Worker *graphicsPipelineDescOut = &mWarmUpGraphicsPipelineDesc;
1007*8975f5c5SAndroid Build Coastguard Worker
1008*8975f5c5SAndroid Build Coastguard Worker // Variations that definitely matter:
1009*8975f5c5SAndroid Build Coastguard Worker //
1010*8975f5c5SAndroid Build Coastguard Worker // - PreRotation: It's a boolean specialization constant
1011*8975f5c5SAndroid Build Coastguard Worker // - Depth correction: It's a SPIR-V transformation
1012*8975f5c5SAndroid Build Coastguard Worker //
1013*8975f5c5SAndroid Build Coastguard Worker // There are a number of states that are not currently dynamic (and may never be, such as sample
1014*8975f5c5SAndroid Build Coastguard Worker // shading), but pre-creating shaders for them is impractical. Most such state is likely unused
1015*8975f5c5SAndroid Build Coastguard Worker // by most applications, but variations can be added here for certain apps that are known to
1016*8975f5c5SAndroid Build Coastguard Worker // benefit from it.
1017*8975f5c5SAndroid Build Coastguard Worker *surfaceRotationVariationsOut = {false};
1018*8975f5c5SAndroid Build Coastguard Worker if (context->getFeatures().enablePreRotateSurfaces.enabled &&
1019*8975f5c5SAndroid Build Coastguard Worker !context->getFeatures().preferDriverUniformOverSpecConst.enabled)
1020*8975f5c5SAndroid Build Coastguard Worker {
1021*8975f5c5SAndroid Build Coastguard Worker surfaceRotationVariationsOut->push_back(true);
1022*8975f5c5SAndroid Build Coastguard Worker }
1023*8975f5c5SAndroid Build Coastguard Worker
1024*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = {};
1025*8975f5c5SAndroid Build Coastguard Worker for (bool rotation : *surfaceRotationVariationsOut)
1026*8975f5c5SAndroid Build Coastguard Worker {
1027*8975f5c5SAndroid Build Coastguard Worker // Initialize graphics programs.
1028*8975f5c5SAndroid Build Coastguard Worker transformOptions.surfaceRotation = rotation;
1029*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initGraphicsShaderPrograms(context, transformOptions));
1030*8975f5c5SAndroid Build Coastguard Worker }
1031*8975f5c5SAndroid Build Coastguard Worker
1032*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1033*8975f5c5SAndroid Build Coastguard Worker }
1034*8975f5c5SAndroid Build Coastguard Worker
warmUpComputePipelineCache(vk::Context * context,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess)1035*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::warmUpComputePipelineCache(
1036*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1037*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
1038*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess)
1039*8975f5c5SAndroid Build Coastguard Worker {
1040*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle", "ProgramExecutableVk::warmUpComputePipelineCache");
1041*8975f5c5SAndroid Build Coastguard Worker
1042*8975f5c5SAndroid Build Coastguard Worker // This method assumes that all the state necessary to create a compute pipeline has already
1043*8975f5c5SAndroid Build Coastguard Worker // been setup by the caller. Assert that all required state is valid so all that is left will
1044*8975f5c5SAndroid Build Coastguard Worker // be the call to `vkCreateComputePipelines`
1045*8975f5c5SAndroid Build Coastguard Worker
1046*8975f5c5SAndroid Build Coastguard Worker // Make sure the shader module for compute shader stage is valid.
1047*8975f5c5SAndroid Build Coastguard Worker ASSERT(mComputeProgramInfo.valid(gl::ShaderType::Compute));
1048*8975f5c5SAndroid Build Coastguard Worker
1049*8975f5c5SAndroid Build Coastguard Worker // No synchronization necessary since mPipelineCache is internally synchronized.
1050*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess pipelineCache;
1051*8975f5c5SAndroid Build Coastguard Worker pipelineCache.init(&mPipelineCache, nullptr);
1052*8975f5c5SAndroid Build Coastguard Worker
1053*8975f5c5SAndroid Build Coastguard Worker // There is no state associated with compute programs, so only one pipeline needs creation
1054*8975f5c5SAndroid Build Coastguard Worker // to warm up the cache.
1055*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *pipeline = nullptr;
1056*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getOrCreateComputePipeline(context, &pipelineCache, PipelineSource::WarmUp,
1057*8975f5c5SAndroid Build Coastguard Worker pipelineRobustness, pipelineProtectedAccess, &pipeline));
1058*8975f5c5SAndroid Build Coastguard Worker
1059*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1060*8975f5c5SAndroid Build Coastguard Worker }
1061*8975f5c5SAndroid Build Coastguard Worker
warmUpGraphicsPipelineCache(vk::Context * context,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,vk::GraphicsPipelineSubset subset,const bool isSurfaceRotated,const vk::GraphicsPipelineDesc & graphicsPipelineDesc,const vk::RenderPass & renderPass,vk::PipelineHelper * placeholderPipelineHelper)1062*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::warmUpGraphicsPipelineCache(
1063*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1064*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
1065*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
1066*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset subset,
1067*8975f5c5SAndroid Build Coastguard Worker const bool isSurfaceRotated,
1068*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &graphicsPipelineDesc,
1069*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass &renderPass,
1070*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *placeholderPipelineHelper)
1071*8975f5c5SAndroid Build Coastguard Worker {
1072*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle", "ProgramExecutableVk::warmUpGraphicsPipelineCache");
1073*8975f5c5SAndroid Build Coastguard Worker
1074*8975f5c5SAndroid Build Coastguard Worker ASSERT(placeholderPipelineHelper && !placeholderPipelineHelper->valid());
1075*8975f5c5SAndroid Build Coastguard Worker
1076*8975f5c5SAndroid Build Coastguard Worker // No synchronization necessary since mPipelineCache is internally synchronized.
1077*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess pipelineCache;
1078*8975f5c5SAndroid Build Coastguard Worker pipelineCache.init(&mPipelineCache, nullptr);
1079*8975f5c5SAndroid Build Coastguard Worker
1080*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc *descPtr = nullptr;
1081*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = {};
1082*8975f5c5SAndroid Build Coastguard Worker transformOptions.surfaceRotation = isSurfaceRotated;
1083*8975f5c5SAndroid Build Coastguard Worker
1084*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createGraphicsPipelineImpl(context, transformOptions, subset, &pipelineCache,
1085*8975f5c5SAndroid Build Coastguard Worker PipelineSource::WarmUp, graphicsPipelineDesc, renderPass,
1086*8975f5c5SAndroid Build Coastguard Worker &descPtr, &placeholderPipelineHelper));
1087*8975f5c5SAndroid Build Coastguard Worker
1088*8975f5c5SAndroid Build Coastguard Worker ASSERT(placeholderPipelineHelper->valid());
1089*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1090*8975f5c5SAndroid Build Coastguard Worker }
1091*8975f5c5SAndroid Build Coastguard Worker
waitForPostLinkTasksImpl(ContextVk * contextVk)1092*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::waitForPostLinkTasksImpl(ContextVk *contextVk)
1093*8975f5c5SAndroid Build Coastguard Worker {
1094*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::shared_ptr<rx::LinkSubTask>> &postLinkSubTasks =
1095*8975f5c5SAndroid Build Coastguard Worker mExecutable->getPostLinkSubTasks();
1096*8975f5c5SAndroid Build Coastguard Worker
1097*8975f5c5SAndroid Build Coastguard Worker if (postLinkSubTasks.empty())
1098*8975f5c5SAndroid Build Coastguard Worker {
1099*8975f5c5SAndroid Build Coastguard Worker return;
1100*8975f5c5SAndroid Build Coastguard Worker }
1101*8975f5c5SAndroid Build Coastguard Worker
1102*8975f5c5SAndroid Build Coastguard Worker // Wait for all post-link tasks to finish
1103*8975f5c5SAndroid Build Coastguard Worker angle::WaitableEvent::WaitMany(&mExecutable->getPostLinkSubTaskWaitableEvents());
1104*8975f5c5SAndroid Build Coastguard Worker
1105*8975f5c5SAndroid Build Coastguard Worker // Get results and clean up
1106*8975f5c5SAndroid Build Coastguard Worker for (const std::shared_ptr<rx::LinkSubTask> &task : postLinkSubTasks)
1107*8975f5c5SAndroid Build Coastguard Worker {
1108*8975f5c5SAndroid Build Coastguard Worker WarmUpTaskCommon *warmUpTask = static_cast<WarmUpTaskCommon *>(task.get());
1109*8975f5c5SAndroid Build Coastguard Worker
1110*8975f5c5SAndroid Build Coastguard Worker // As these tasks can be run post-link, their results are ignored. Failure is harmless, but
1111*8975f5c5SAndroid Build Coastguard Worker // more importantly the error (effectively due to a link event) may not be allowed through
1112*8975f5c5SAndroid Build Coastguard Worker // the entry point that results in this call.
1113*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog infoLog;
1114*8975f5c5SAndroid Build Coastguard Worker angle::Result result = warmUpTask->getResultImpl(contextVk, infoLog);
1115*8975f5c5SAndroid Build Coastguard Worker if (result != angle::Result::Continue)
1116*8975f5c5SAndroid Build Coastguard Worker {
1117*8975f5c5SAndroid Build Coastguard Worker ANGLE_PERF_WARNING(contextVk->getDebug(), GL_DEBUG_SEVERITY_LOW,
1118*8975f5c5SAndroid Build Coastguard Worker "Post-link task unexpectedly failed. Performance may degrade, or "
1119*8975f5c5SAndroid Build Coastguard Worker "device may soon be lost");
1120*8975f5c5SAndroid Build Coastguard Worker }
1121*8975f5c5SAndroid Build Coastguard Worker }
1122*8975f5c5SAndroid Build Coastguard Worker
1123*8975f5c5SAndroid Build Coastguard Worker mExecutable->onPostLinkTasksComplete();
1124*8975f5c5SAndroid Build Coastguard Worker }
1125*8975f5c5SAndroid Build Coastguard Worker
waitForGraphicsPostLinkTasks(ContextVk * contextVk,const vk::GraphicsPipelineDesc & currentGraphicsPipelineDesc)1126*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::waitForGraphicsPostLinkTasks(
1127*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1128*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc ¤tGraphicsPipelineDesc)
1129*8975f5c5SAndroid Build Coastguard Worker {
1130*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex));
1131*8975f5c5SAndroid Build Coastguard Worker
1132*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->getPostLinkSubTasks().empty())
1133*8975f5c5SAndroid Build Coastguard Worker {
1134*8975f5c5SAndroid Build Coastguard Worker return;
1135*8975f5c5SAndroid Build Coastguard Worker }
1136*8975f5c5SAndroid Build Coastguard Worker
1137*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineSubset subset = GetWarmUpSubset(contextVk->getFeatures());
1138*8975f5c5SAndroid Build Coastguard Worker
1139*8975f5c5SAndroid Build Coastguard Worker if (!mWarmUpGraphicsPipelineDesc.keyEqual(currentGraphicsPipelineDesc, subset))
1140*8975f5c5SAndroid Build Coastguard Worker {
1141*8975f5c5SAndroid Build Coastguard Worker // The GraphicsPipelineDesc used for warmup differs from the one used by the draw call.
1142*8975f5c5SAndroid Build Coastguard Worker // There is no need to wait for the warmup tasks to complete.
1143*8975f5c5SAndroid Build Coastguard Worker ANGLE_PERF_WARNING(
1144*8975f5c5SAndroid Build Coastguard Worker contextVk->getDebug(), GL_DEBUG_SEVERITY_LOW,
1145*8975f5c5SAndroid Build Coastguard Worker "GraphicsPipelineDesc used for warmup differs from the one used by draw.");
1146*8975f5c5SAndroid Build Coastguard Worker
1147*8975f5c5SAndroid Build Coastguard Worker // If the warm up tasks are finished anyway, let |waitForPostLinkTasksImpl| clean them up.
1148*8975f5c5SAndroid Build Coastguard Worker if (!angle::WaitableEvent::AllReady(&mExecutable->getPostLinkSubTaskWaitableEvents()))
1149*8975f5c5SAndroid Build Coastguard Worker {
1150*8975f5c5SAndroid Build Coastguard Worker return;
1151*8975f5c5SAndroid Build Coastguard Worker }
1152*8975f5c5SAndroid Build Coastguard Worker }
1153*8975f5c5SAndroid Build Coastguard Worker
1154*8975f5c5SAndroid Build Coastguard Worker waitForPostLinkTasksImpl(contextVk);
1155*8975f5c5SAndroid Build Coastguard Worker }
1156*8975f5c5SAndroid Build Coastguard Worker
mergePipelineCacheToRenderer(vk::Context * context) const1157*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::mergePipelineCacheToRenderer(vk::Context *context) const
1158*8975f5c5SAndroid Build Coastguard Worker {
1159*8975f5c5SAndroid Build Coastguard Worker // Merge the cache with Renderer's
1160*8975f5c5SAndroid Build Coastguard Worker if (context->getFeatures().mergeProgramPipelineCachesToGlobalCache.enabled)
1161*8975f5c5SAndroid Build Coastguard Worker {
1162*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle", "ProgramExecutableVk::mergePipelineCacheToRenderer");
1163*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(context->getRenderer()->mergeIntoPipelineCache(context, mPipelineCache));
1164*8975f5c5SAndroid Build Coastguard Worker }
1165*8975f5c5SAndroid Build Coastguard Worker
1166*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1167*8975f5c5SAndroid Build Coastguard Worker }
1168*8975f5c5SAndroid Build Coastguard Worker
addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> & blocks,gl::ShaderBitSet shaderTypes,VkDescriptorType descType,vk::DescriptorSetLayoutDesc * descOut)1169*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc(
1170*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::InterfaceBlock> &blocks,
1171*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet shaderTypes,
1172*8975f5c5SAndroid Build Coastguard Worker VkDescriptorType descType,
1173*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc *descOut)
1174*8975f5c5SAndroid Build Coastguard Worker {
1175*8975f5c5SAndroid Build Coastguard Worker for (uint32_t bufferIndex = 0, arraySize = 0; bufferIndex < blocks.size();
1176*8975f5c5SAndroid Build Coastguard Worker bufferIndex += arraySize)
1177*8975f5c5SAndroid Build Coastguard Worker {
1178*8975f5c5SAndroid Build Coastguard Worker gl::InterfaceBlock block = blocks[bufferIndex];
1179*8975f5c5SAndroid Build Coastguard Worker arraySize = GetInterfaceBlockArraySize(blocks, bufferIndex);
1180*8975f5c5SAndroid Build Coastguard Worker
1181*8975f5c5SAndroid Build Coastguard Worker if (block.activeShaders().none())
1182*8975f5c5SAndroid Build Coastguard Worker {
1183*8975f5c5SAndroid Build Coastguard Worker continue;
1184*8975f5c5SAndroid Build Coastguard Worker }
1185*8975f5c5SAndroid Build Coastguard Worker
1186*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType firstShaderType = block.getFirstActiveShaderType();
1187*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info =
1188*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.getVariableById(firstShaderType, block.getId(firstShaderType));
1189*8975f5c5SAndroid Build Coastguard Worker
1190*8975f5c5SAndroid Build Coastguard Worker const VkShaderStageFlags activeStages = gl_vk::GetShaderStageFlags(info.activeStages);
1191*8975f5c5SAndroid Build Coastguard Worker
1192*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(info.binding, descType, arraySize, activeStages, nullptr);
1193*8975f5c5SAndroid Build Coastguard Worker }
1194*8975f5c5SAndroid Build Coastguard Worker }
1195*8975f5c5SAndroid Build Coastguard Worker
addAtomicCounterBufferDescriptorSetDesc(const std::vector<gl::AtomicCounterBuffer> & atomicCounterBuffers,vk::DescriptorSetLayoutDesc * descOut)1196*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::addAtomicCounterBufferDescriptorSetDesc(
1197*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::AtomicCounterBuffer> &atomicCounterBuffers,
1198*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc *descOut)
1199*8975f5c5SAndroid Build Coastguard Worker {
1200*8975f5c5SAndroid Build Coastguard Worker if (atomicCounterBuffers.empty())
1201*8975f5c5SAndroid Build Coastguard Worker {
1202*8975f5c5SAndroid Build Coastguard Worker return;
1203*8975f5c5SAndroid Build Coastguard Worker }
1204*8975f5c5SAndroid Build Coastguard Worker
1205*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info =
1206*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.getAtomicCounterInfo(atomicCounterBuffers[0].getFirstActiveShaderType());
1207*8975f5c5SAndroid Build Coastguard Worker VkShaderStageFlags activeStages = gl_vk::GetShaderStageFlags(info.activeStages);
1208*8975f5c5SAndroid Build Coastguard Worker
1209*8975f5c5SAndroid Build Coastguard Worker // A single storage buffer array is used for all stages for simplicity.
1210*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(info.binding, vk::kStorageBufferDescriptorType,
1211*8975f5c5SAndroid Build Coastguard Worker gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, activeStages,
1212*8975f5c5SAndroid Build Coastguard Worker nullptr);
1213*8975f5c5SAndroid Build Coastguard Worker }
1214*8975f5c5SAndroid Build Coastguard Worker
addImageDescriptorSetDesc(vk::DescriptorSetLayoutDesc * descOut)1215*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::addImageDescriptorSetDesc(vk::DescriptorSetLayoutDesc *descOut)
1216*8975f5c5SAndroid Build Coastguard Worker {
1217*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::ImageBinding> &imageBindings = mExecutable->getImageBindings();
1218*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::LinkedUniform> &uniforms = mExecutable->getUniforms();
1219*8975f5c5SAndroid Build Coastguard Worker
1220*8975f5c5SAndroid Build Coastguard Worker for (uint32_t imageIndex = 0; imageIndex < imageBindings.size(); ++imageIndex)
1221*8975f5c5SAndroid Build Coastguard Worker {
1222*8975f5c5SAndroid Build Coastguard Worker uint32_t uniformIndex = mExecutable->getUniformIndexFromImageIndex(imageIndex);
1223*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &imageUniform = uniforms[uniformIndex];
1224*8975f5c5SAndroid Build Coastguard Worker
1225*8975f5c5SAndroid Build Coastguard Worker // 2D arrays are split into multiple 1D arrays when generating LinkedUniforms. Since they
1226*8975f5c5SAndroid Build Coastguard Worker // are flattened into one array, ignore the nonzero elements and expand the array to the
1227*8975f5c5SAndroid Build Coastguard Worker // total array size.
1228*8975f5c5SAndroid Build Coastguard Worker if (imageUniform.activeShaders().none() || imageUniform.getOuterArrayOffset() > 0)
1229*8975f5c5SAndroid Build Coastguard Worker {
1230*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::SamplerNameContainsNonZeroArrayElement(
1231*8975f5c5SAndroid Build Coastguard Worker mExecutable->getUniformNameByIndex(uniformIndex)));
1232*8975f5c5SAndroid Build Coastguard Worker continue;
1233*8975f5c5SAndroid Build Coastguard Worker }
1234*8975f5c5SAndroid Build Coastguard Worker
1235*8975f5c5SAndroid Build Coastguard Worker ASSERT(!gl::SamplerNameContainsNonZeroArrayElement(
1236*8975f5c5SAndroid Build Coastguard Worker mExecutable->getUniformNameByIndex(uniformIndex)));
1237*8975f5c5SAndroid Build Coastguard Worker
1238*8975f5c5SAndroid Build Coastguard Worker // The front-end always binds array image units sequentially.
1239*8975f5c5SAndroid Build Coastguard Worker const gl::ImageBinding &imageBinding = imageBindings[imageIndex];
1240*8975f5c5SAndroid Build Coastguard Worker uint32_t arraySize = static_cast<uint32_t>(imageBinding.boundImageUnits.size());
1241*8975f5c5SAndroid Build Coastguard Worker arraySize *= imageUniform.getOuterArraySizeProduct();
1242*8975f5c5SAndroid Build Coastguard Worker
1243*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType firstShaderType = imageUniform.getFirstActiveShaderType();
1244*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info =
1245*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.getVariableById(firstShaderType, imageUniform.getId(firstShaderType));
1246*8975f5c5SAndroid Build Coastguard Worker
1247*8975f5c5SAndroid Build Coastguard Worker const VkShaderStageFlags activeStages = gl_vk::GetShaderStageFlags(info.activeStages);
1248*8975f5c5SAndroid Build Coastguard Worker
1249*8975f5c5SAndroid Build Coastguard Worker const VkDescriptorType descType = imageBinding.textureType == gl::TextureType::Buffer
1250*8975f5c5SAndroid Build Coastguard Worker ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
1251*8975f5c5SAndroid Build Coastguard Worker : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1252*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(info.binding, descType, arraySize, activeStages, nullptr);
1253*8975f5c5SAndroid Build Coastguard Worker }
1254*8975f5c5SAndroid Build Coastguard Worker }
1255*8975f5c5SAndroid Build Coastguard Worker
addInputAttachmentDescriptorSetDesc(vk::Context * context,vk::DescriptorSetLayoutDesc * descOut)1256*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::addInputAttachmentDescriptorSetDesc(vk::Context *context,
1257*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc *descOut)
1258*8975f5c5SAndroid Build Coastguard Worker {
1259*8975f5c5SAndroid Build Coastguard Worker if (!mExecutable->getLinkedShaderStages()[gl::ShaderType::Fragment])
1260*8975f5c5SAndroid Build Coastguard Worker {
1261*8975f5c5SAndroid Build Coastguard Worker return;
1262*8975f5c5SAndroid Build Coastguard Worker }
1263*8975f5c5SAndroid Build Coastguard Worker
1264*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->usesDepthFramebufferFetch())
1265*8975f5c5SAndroid Build Coastguard Worker {
1266*8975f5c5SAndroid Build Coastguard Worker const uint32_t depthBinding =
1267*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap
1268*8975f5c5SAndroid Build Coastguard Worker .getVariableById(gl::ShaderType::Fragment, sh::vk::spirv::kIdDepthInputAttachment)
1269*8975f5c5SAndroid Build Coastguard Worker .binding;
1270*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(depthBinding, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1,
1271*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
1272*8975f5c5SAndroid Build Coastguard Worker }
1273*8975f5c5SAndroid Build Coastguard Worker
1274*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->usesStencilFramebufferFetch())
1275*8975f5c5SAndroid Build Coastguard Worker {
1276*8975f5c5SAndroid Build Coastguard Worker const uint32_t stencilBinding =
1277*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap
1278*8975f5c5SAndroid Build Coastguard Worker .getVariableById(gl::ShaderType::Fragment, sh::vk::spirv::kIdStencilInputAttachment)
1279*8975f5c5SAndroid Build Coastguard Worker .binding;
1280*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(stencilBinding, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1,
1281*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
1282*8975f5c5SAndroid Build Coastguard Worker }
1283*8975f5c5SAndroid Build Coastguard Worker
1284*8975f5c5SAndroid Build Coastguard Worker if (!mExecutable->usesColorFramebufferFetch())
1285*8975f5c5SAndroid Build Coastguard Worker {
1286*8975f5c5SAndroid Build Coastguard Worker return;
1287*8975f5c5SAndroid Build Coastguard Worker }
1288*8975f5c5SAndroid Build Coastguard Worker
1289*8975f5c5SAndroid Build Coastguard Worker const uint32_t firstInputAttachment =
1290*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(mExecutable->getFragmentInoutIndices().first());
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &baseInfo = mVariableInfoMap.getVariableById(
1293*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Fragment, sh::vk::spirv::kIdInputAttachment0 + firstInputAttachment);
1294*8975f5c5SAndroid Build Coastguard Worker
1295*8975f5c5SAndroid Build Coastguard Worker uint32_t baseBinding = baseInfo.binding - firstInputAttachment;
1296*8975f5c5SAndroid Build Coastguard Worker
1297*8975f5c5SAndroid Build Coastguard Worker const uint32_t maxColorInputAttachmentCount =
1298*8975f5c5SAndroid Build Coastguard Worker context->getRenderer()->getMaxColorInputAttachmentCount();
1299*8975f5c5SAndroid Build Coastguard Worker for (uint32_t colorIndex = 0; colorIndex < maxColorInputAttachmentCount; ++colorIndex)
1300*8975f5c5SAndroid Build Coastguard Worker {
1301*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(baseBinding, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1,
1302*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
1303*8975f5c5SAndroid Build Coastguard Worker baseBinding++;
1304*8975f5c5SAndroid Build Coastguard Worker }
1305*8975f5c5SAndroid Build Coastguard Worker }
1306*8975f5c5SAndroid Build Coastguard Worker
addTextureDescriptorSetDesc(vk::Context * context,const gl::ActiveTextureArray<TextureVk * > * activeTextures,vk::DescriptorSetLayoutDesc * descOut)1307*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::addTextureDescriptorSetDesc(
1308*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1309*8975f5c5SAndroid Build Coastguard Worker const gl::ActiveTextureArray<TextureVk *> *activeTextures,
1310*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc *descOut)
1311*8975f5c5SAndroid Build Coastguard Worker {
1312*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::SamplerBinding> &samplerBindings = mExecutable->getSamplerBindings();
1313*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::LinkedUniform> &uniforms = mExecutable->getUniforms();
1314*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLuint> &samplerBoundTextureUnits =
1315*8975f5c5SAndroid Build Coastguard Worker mExecutable->getSamplerBoundTextureUnits();
1316*8975f5c5SAndroid Build Coastguard Worker
1317*8975f5c5SAndroid Build Coastguard Worker for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex)
1318*8975f5c5SAndroid Build Coastguard Worker {
1319*8975f5c5SAndroid Build Coastguard Worker uint32_t uniformIndex = mExecutable->getUniformIndexFromSamplerIndex(samplerIndex);
1320*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &samplerUniform = uniforms[uniformIndex];
1321*8975f5c5SAndroid Build Coastguard Worker
1322*8975f5c5SAndroid Build Coastguard Worker // 2D arrays are split into multiple 1D arrays when generating LinkedUniforms. Since they
1323*8975f5c5SAndroid Build Coastguard Worker // are flattened into one array, ignore the nonzero elements and expand the array to the
1324*8975f5c5SAndroid Build Coastguard Worker // total array size.
1325*8975f5c5SAndroid Build Coastguard Worker if (samplerUniform.activeShaders().none() || samplerUniform.getOuterArrayOffset() > 0)
1326*8975f5c5SAndroid Build Coastguard Worker {
1327*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::SamplerNameContainsNonZeroArrayElement(
1328*8975f5c5SAndroid Build Coastguard Worker mExecutable->getUniformNameByIndex(uniformIndex)));
1329*8975f5c5SAndroid Build Coastguard Worker continue;
1330*8975f5c5SAndroid Build Coastguard Worker }
1331*8975f5c5SAndroid Build Coastguard Worker
1332*8975f5c5SAndroid Build Coastguard Worker ASSERT(!gl::SamplerNameContainsNonZeroArrayElement(
1333*8975f5c5SAndroid Build Coastguard Worker mExecutable->getUniformNameByIndex(uniformIndex)));
1334*8975f5c5SAndroid Build Coastguard Worker
1335*8975f5c5SAndroid Build Coastguard Worker // The front-end always binds array sampler units sequentially.
1336*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerBinding &samplerBinding = samplerBindings[samplerIndex];
1337*8975f5c5SAndroid Build Coastguard Worker uint32_t arraySize = static_cast<uint32_t>(samplerBinding.textureUnitsCount);
1338*8975f5c5SAndroid Build Coastguard Worker arraySize *= samplerUniform.getOuterArraySizeProduct();
1339*8975f5c5SAndroid Build Coastguard Worker
1340*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType firstShaderType = samplerUniform.getFirstActiveShaderType();
1341*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getVariableById(
1342*8975f5c5SAndroid Build Coastguard Worker firstShaderType, samplerUniform.getId(firstShaderType));
1343*8975f5c5SAndroid Build Coastguard Worker
1344*8975f5c5SAndroid Build Coastguard Worker const VkShaderStageFlags activeStages = gl_vk::GetShaderStageFlags(info.activeStages);
1345*8975f5c5SAndroid Build Coastguard Worker
1346*8975f5c5SAndroid Build Coastguard Worker // TODO: https://issuetracker.google.com/issues/158215272: how do we handle array of
1347*8975f5c5SAndroid Build Coastguard Worker // immutable samplers?
1348*8975f5c5SAndroid Build Coastguard Worker GLuint textureUnit = samplerBinding.getTextureUnit(samplerBoundTextureUnits, 0);
1349*8975f5c5SAndroid Build Coastguard Worker if (activeTextures != nullptr &&
1350*8975f5c5SAndroid Build Coastguard Worker (*activeTextures)[textureUnit]->getImage().hasImmutableSampler())
1351*8975f5c5SAndroid Build Coastguard Worker {
1352*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplerBinding.textureUnitsCount == 1);
1353*8975f5c5SAndroid Build Coastguard Worker
1354*8975f5c5SAndroid Build Coastguard Worker // In the case of samplerExternal2DY2YEXT, we need
1355*8975f5c5SAndroid Build Coastguard Worker // samplerYcbcrConversion object with IDENTITY conversion model
1356*8975f5c5SAndroid Build Coastguard Worker bool isSamplerExternalY2Y =
1357*8975f5c5SAndroid Build Coastguard Worker samplerBinding.samplerType == GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
1358*8975f5c5SAndroid Build Coastguard Worker
1359*8975f5c5SAndroid Build Coastguard Worker // Always take the texture's sampler, that's only way to get to yuv conversion for
1360*8975f5c5SAndroid Build Coastguard Worker // externalFormat
1361*8975f5c5SAndroid Build Coastguard Worker const TextureVk *textureVk = (*activeTextures)[textureUnit];
1362*8975f5c5SAndroid Build Coastguard Worker const vk::Sampler &immutableSampler = textureVk->getSampler(isSamplerExternalY2Y).get();
1363*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(info.binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize,
1364*8975f5c5SAndroid Build Coastguard Worker activeStages, &immutableSampler);
1365*8975f5c5SAndroid Build Coastguard Worker const vk::ImageHelper &image = textureVk->getImage();
1366*8975f5c5SAndroid Build Coastguard Worker const vk::YcbcrConversionDesc ycbcrConversionDesc =
1367*8975f5c5SAndroid Build Coastguard Worker isSamplerExternalY2Y ? image.getY2YConversionDesc()
1368*8975f5c5SAndroid Build Coastguard Worker : image.getYcbcrConversionDesc();
1369*8975f5c5SAndroid Build Coastguard Worker mImmutableSamplerIndexMap[ycbcrConversionDesc] = samplerIndex;
1370*8975f5c5SAndroid Build Coastguard Worker // The Vulkan spec has the following note -
1371*8975f5c5SAndroid Build Coastguard Worker // All descriptors in a binding use the same maximum
1372*8975f5c5SAndroid Build Coastguard Worker // combinedImageSamplerDescriptorCount descriptors to allow implementations to use a
1373*8975f5c5SAndroid Build Coastguard Worker // uniform stride for dynamic indexing of the descriptors in the binding.
1374*8975f5c5SAndroid Build Coastguard Worker uint64_t externalFormat = image.getExternalFormat();
1375*8975f5c5SAndroid Build Coastguard Worker uint32_t formatDescriptorCount = 0;
1376*8975f5c5SAndroid Build Coastguard Worker
1377*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = context->getRenderer();
1378*8975f5c5SAndroid Build Coastguard Worker
1379*8975f5c5SAndroid Build Coastguard Worker if (externalFormat != 0)
1380*8975f5c5SAndroid Build Coastguard Worker {
1381*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->getFormatDescriptorCountForExternalFormat(
1382*8975f5c5SAndroid Build Coastguard Worker context, externalFormat, &formatDescriptorCount));
1383*8975f5c5SAndroid Build Coastguard Worker }
1384*8975f5c5SAndroid Build Coastguard Worker else
1385*8975f5c5SAndroid Build Coastguard Worker {
1386*8975f5c5SAndroid Build Coastguard Worker VkFormat vkFormat = image.getActualVkFormat(renderer);
1387*8975f5c5SAndroid Build Coastguard Worker ASSERT(vkFormat != 0);
1388*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->getFormatDescriptorCountForVkFormat(context, vkFormat,
1389*8975f5c5SAndroid Build Coastguard Worker &formatDescriptorCount));
1390*8975f5c5SAndroid Build Coastguard Worker }
1391*8975f5c5SAndroid Build Coastguard Worker
1392*8975f5c5SAndroid Build Coastguard Worker ASSERT(formatDescriptorCount > 0);
1393*8975f5c5SAndroid Build Coastguard Worker mImmutableSamplersMaxDescriptorCount =
1394*8975f5c5SAndroid Build Coastguard Worker std::max(mImmutableSamplersMaxDescriptorCount, formatDescriptorCount);
1395*8975f5c5SAndroid Build Coastguard Worker }
1396*8975f5c5SAndroid Build Coastguard Worker else
1397*8975f5c5SAndroid Build Coastguard Worker {
1398*8975f5c5SAndroid Build Coastguard Worker const VkDescriptorType descType = samplerBinding.textureType == gl::TextureType::Buffer
1399*8975f5c5SAndroid Build Coastguard Worker ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
1400*8975f5c5SAndroid Build Coastguard Worker : VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1401*8975f5c5SAndroid Build Coastguard Worker descOut->addBinding(info.binding, descType, arraySize, activeStages, nullptr);
1402*8975f5c5SAndroid Build Coastguard Worker }
1403*8975f5c5SAndroid Build Coastguard Worker }
1404*8975f5c5SAndroid Build Coastguard Worker
1405*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1406*8975f5c5SAndroid Build Coastguard Worker }
1407*8975f5c5SAndroid Build Coastguard Worker
initializeWriteDescriptorDesc(vk::Context * context)1408*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::initializeWriteDescriptorDesc(vk::Context *context)
1409*8975f5c5SAndroid Build Coastguard Worker {
1410*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet &linkedShaderStages = mExecutable->getLinkedShaderStages();
1411*8975f5c5SAndroid Build Coastguard Worker
1412*8975f5c5SAndroid Build Coastguard Worker // Update mShaderResourceWriteDescriptorDescBuilder
1413*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.reset();
1414*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.updateShaderBuffers(
1415*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap, mExecutable->getUniformBlocks(), getUniformBufferDescriptorType());
1416*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.updateShaderBuffers(
1417*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap, mExecutable->getShaderStorageBlocks(), getStorageBufferDescriptorType());
1418*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.updateAtomicCounters(
1419*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap, mExecutable->getAtomicCounterBuffers());
1420*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.updateImages(*mExecutable, mVariableInfoMap);
1421*8975f5c5SAndroid Build Coastguard Worker mShaderResourceWriteDescriptorDescs.updateDynamicDescriptorsCount();
1422*8975f5c5SAndroid Build Coastguard Worker
1423*8975f5c5SAndroid Build Coastguard Worker // Update mTextureWriteDescriptors
1424*8975f5c5SAndroid Build Coastguard Worker mTextureWriteDescriptorDescs.reset();
1425*8975f5c5SAndroid Build Coastguard Worker mTextureWriteDescriptorDescs.updateExecutableActiveTextures(mVariableInfoMap, *mExecutable);
1426*8975f5c5SAndroid Build Coastguard Worker mTextureWriteDescriptorDescs.updateDynamicDescriptorsCount();
1427*8975f5c5SAndroid Build Coastguard Worker
1428*8975f5c5SAndroid Build Coastguard Worker // Update mDefaultUniformWriteDescriptors
1429*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformWriteDescriptorDescs.reset();
1430*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformWriteDescriptorDescs.updateDefaultUniform(linkedShaderStages, mVariableInfoMap,
1431*8975f5c5SAndroid Build Coastguard Worker *mExecutable);
1432*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformWriteDescriptorDescs.updateDynamicDescriptorsCount();
1433*8975f5c5SAndroid Build Coastguard Worker
1434*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbWriteDescriptorDescs.reset();
1435*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->hasTransformFeedbackOutput() &&
1436*8975f5c5SAndroid Build Coastguard Worker context->getFeatures().emulateTransformFeedback.enabled)
1437*8975f5c5SAndroid Build Coastguard Worker {
1438*8975f5c5SAndroid Build Coastguard Worker // Update mDefaultUniformAndXfbWriteDescriptorDescs for the emulation code path.
1439*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbWriteDescriptorDescs.updateDefaultUniform(
1440*8975f5c5SAndroid Build Coastguard Worker linkedShaderStages, mVariableInfoMap, *mExecutable);
1441*8975f5c5SAndroid Build Coastguard Worker if (linkedShaderStages[gl::ShaderType::Vertex])
1442*8975f5c5SAndroid Build Coastguard Worker {
1443*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbWriteDescriptorDescs.updateTransformFeedbackWrite(mVariableInfoMap,
1444*8975f5c5SAndroid Build Coastguard Worker *mExecutable);
1445*8975f5c5SAndroid Build Coastguard Worker }
1446*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbWriteDescriptorDescs.updateDynamicDescriptorsCount();
1447*8975f5c5SAndroid Build Coastguard Worker }
1448*8975f5c5SAndroid Build Coastguard Worker else
1449*8975f5c5SAndroid Build Coastguard Worker {
1450*8975f5c5SAndroid Build Coastguard Worker // Otherwise it will be the same as default uniform
1451*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbWriteDescriptorDescs = mDefaultUniformWriteDescriptorDescs;
1452*8975f5c5SAndroid Build Coastguard Worker }
1453*8975f5c5SAndroid Build Coastguard Worker }
1454*8975f5c5SAndroid Build Coastguard Worker
getTransformOptions(ContextVk * contextVk,const vk::GraphicsPipelineDesc & desc)1455*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions ProgramExecutableVk::getTransformOptions(
1456*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1457*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc)
1458*8975f5c5SAndroid Build Coastguard Worker {
1459*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = {};
1460*8975f5c5SAndroid Build Coastguard Worker
1461*8975f5c5SAndroid Build Coastguard Worker transformOptions.surfaceRotation = desc.getSurfaceRotation();
1462*8975f5c5SAndroid Build Coastguard Worker transformOptions.removeTransformFeedbackEmulation =
1463*8975f5c5SAndroid Build Coastguard Worker contextVk->getFeatures().emulateTransformFeedback.enabled &&
1464*8975f5c5SAndroid Build Coastguard Worker !contextVk->getState().isTransformFeedbackActiveUnpaused();
1465*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *drawFrameBuffer = vk::GetImpl(contextVk->getState().getDrawFramebuffer());
1466*8975f5c5SAndroid Build Coastguard Worker const bool hasFramebufferFetch = mExecutable->usesColorFramebufferFetch() ||
1467*8975f5c5SAndroid Build Coastguard Worker mExecutable->usesDepthFramebufferFetch() ||
1468*8975f5c5SAndroid Build Coastguard Worker mExecutable->usesStencilFramebufferFetch();
1469*8975f5c5SAndroid Build Coastguard Worker const bool isMultisampled = drawFrameBuffer->getSamples() > 1;
1470*8975f5c5SAndroid Build Coastguard Worker transformOptions.multiSampleFramebufferFetch = hasFramebufferFetch && isMultisampled;
1471*8975f5c5SAndroid Build Coastguard Worker transformOptions.enableSampleShading =
1472*8975f5c5SAndroid Build Coastguard Worker contextVk->getState().isSampleShadingEnabled() && isMultisampled;
1473*8975f5c5SAndroid Build Coastguard Worker
1474*8975f5c5SAndroid Build Coastguard Worker return transformOptions;
1475*8975f5c5SAndroid Build Coastguard Worker }
1476*8975f5c5SAndroid Build Coastguard Worker
initGraphicsShaderPrograms(vk::Context * context,ProgramTransformOptions transformOptions)1477*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::initGraphicsShaderPrograms(
1478*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1479*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions)
1480*8975f5c5SAndroid Build Coastguard Worker {
1481*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex));
1482*8975f5c5SAndroid Build Coastguard Worker
1483*8975f5c5SAndroid Build Coastguard Worker const uint8_t programIndex = transformOptions.permutationIndex;
1484*8975f5c5SAndroid Build Coastguard Worker ProgramInfo &programInfo = mGraphicsProgramInfos[programIndex];
1485*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet linkedShaderStages = mExecutable->getLinkedShaderStages();
1486*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType lastPreFragmentStage = gl::GetLastPreFragmentStage(linkedShaderStages);
1487*8975f5c5SAndroid Build Coastguard Worker
1488*8975f5c5SAndroid Build Coastguard Worker const bool isTransformFeedbackProgram =
1489*8975f5c5SAndroid Build Coastguard Worker !mExecutable->getLinkedTransformFeedbackVaryings().empty();
1490*8975f5c5SAndroid Build Coastguard Worker
1491*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : linkedShaderStages)
1492*8975f5c5SAndroid Build Coastguard Worker {
1493*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initGraphicsShaderProgram(context, shaderType, shaderType == lastPreFragmentStage,
1494*8975f5c5SAndroid Build Coastguard Worker isTransformFeedbackProgram, transformOptions,
1495*8975f5c5SAndroid Build Coastguard Worker &programInfo, mVariableInfoMap));
1496*8975f5c5SAndroid Build Coastguard Worker }
1497*8975f5c5SAndroid Build Coastguard Worker
1498*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1499*8975f5c5SAndroid Build Coastguard Worker }
1500*8975f5c5SAndroid Build Coastguard Worker
initProgramThenCreateGraphicsPipeline(vk::Context * context,ProgramTransformOptions transformOptions,vk::GraphicsPipelineSubset pipelineSubset,vk::PipelineCacheAccess * pipelineCache,PipelineSource source,const vk::GraphicsPipelineDesc & desc,const vk::RenderPass & compatibleRenderPass,const vk::GraphicsPipelineDesc ** descPtrOut,vk::PipelineHelper ** pipelineOut)1501*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::initProgramThenCreateGraphicsPipeline(
1502*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1503*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions,
1504*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset pipelineSubset,
1505*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess *pipelineCache,
1506*8975f5c5SAndroid Build Coastguard Worker PipelineSource source,
1507*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc,
1508*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass &compatibleRenderPass,
1509*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc **descPtrOut,
1510*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1511*8975f5c5SAndroid Build Coastguard Worker {
1512*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initGraphicsShaderPrograms(context, transformOptions));
1513*8975f5c5SAndroid Build Coastguard Worker
1514*8975f5c5SAndroid Build Coastguard Worker return createGraphicsPipelineImpl(context, transformOptions, pipelineSubset, pipelineCache,
1515*8975f5c5SAndroid Build Coastguard Worker source, desc, compatibleRenderPass, descPtrOut, pipelineOut);
1516*8975f5c5SAndroid Build Coastguard Worker }
1517*8975f5c5SAndroid Build Coastguard Worker
createGraphicsPipelineImpl(vk::Context * context,ProgramTransformOptions transformOptions,vk::GraphicsPipelineSubset pipelineSubset,vk::PipelineCacheAccess * pipelineCache,PipelineSource source,const vk::GraphicsPipelineDesc & desc,const vk::RenderPass & compatibleRenderPass,const vk::GraphicsPipelineDesc ** descPtrOut,vk::PipelineHelper ** pipelineOut)1518*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::createGraphicsPipelineImpl(
1519*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1520*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions,
1521*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset pipelineSubset,
1522*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess *pipelineCache,
1523*8975f5c5SAndroid Build Coastguard Worker PipelineSource source,
1524*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc,
1525*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass &compatibleRenderPass,
1526*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc **descPtrOut,
1527*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1528*8975f5c5SAndroid Build Coastguard Worker {
1529*8975f5c5SAndroid Build Coastguard Worker // This method assumes that all the state necessary to create a graphics pipeline has already
1530*8975f5c5SAndroid Build Coastguard Worker // been setup by the caller. Assert that all required state is valid so all that is left will
1531*8975f5c5SAndroid Build Coastguard Worker // be the call to `vkCreateGraphicsPipelines`
1532*8975f5c5SAndroid Build Coastguard Worker
1533*8975f5c5SAndroid Build Coastguard Worker // Make sure program index is within range
1534*8975f5c5SAndroid Build Coastguard Worker const uint8_t programIndex = transformOptions.permutationIndex;
1535*8975f5c5SAndroid Build Coastguard Worker ASSERT(programIndex >= 0 && programIndex < ProgramTransformOptions::kPermutationCount);
1536*8975f5c5SAndroid Build Coastguard Worker
1537*8975f5c5SAndroid Build Coastguard Worker // Make sure the shader modules for all linked shader stages are valid.
1538*8975f5c5SAndroid Build Coastguard Worker ProgramInfo &programInfo = mGraphicsProgramInfos[programIndex];
1539*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
1540*8975f5c5SAndroid Build Coastguard Worker {
1541*8975f5c5SAndroid Build Coastguard Worker ASSERT(programInfo.valid(shaderType));
1542*8975f5c5SAndroid Build Coastguard Worker }
1543*8975f5c5SAndroid Build Coastguard Worker
1544*8975f5c5SAndroid Build Coastguard Worker // Generate spec consts, a change in which results in a new pipeline.
1545*8975f5c5SAndroid Build Coastguard Worker vk::SpecializationConstants specConsts = MakeSpecConsts(transformOptions, desc);
1546*8975f5c5SAndroid Build Coastguard Worker
1547*8975f5c5SAndroid Build Coastguard Worker // Choose appropriate pipeline cache based on pipeline subset
1548*8975f5c5SAndroid Build Coastguard Worker if (pipelineSubset == vk::GraphicsPipelineSubset::Complete)
1549*8975f5c5SAndroid Build Coastguard Worker {
1550*8975f5c5SAndroid Build Coastguard Worker CompleteGraphicsPipelineCache &pipelines = mCompleteGraphicsPipelines[programIndex];
1551*8975f5c5SAndroid Build Coastguard Worker return programInfo.getShaderProgram().createGraphicsPipeline(
1552*8975f5c5SAndroid Build Coastguard Worker context, &pipelines, pipelineCache, compatibleRenderPass, getPipelineLayout(), source,
1553*8975f5c5SAndroid Build Coastguard Worker desc, specConsts, descPtrOut, pipelineOut);
1554*8975f5c5SAndroid Build Coastguard Worker }
1555*8975f5c5SAndroid Build Coastguard Worker else
1556*8975f5c5SAndroid Build Coastguard Worker {
1557*8975f5c5SAndroid Build Coastguard Worker // Vertex input and fragment output subsets are independent of shaders, and are not created
1558*8975f5c5SAndroid Build Coastguard Worker // through the program executable.
1559*8975f5c5SAndroid Build Coastguard Worker ASSERT(pipelineSubset == vk::GraphicsPipelineSubset::Shaders);
1560*8975f5c5SAndroid Build Coastguard Worker
1561*8975f5c5SAndroid Build Coastguard Worker ShadersGraphicsPipelineCache &pipelines = mShadersGraphicsPipelines[programIndex];
1562*8975f5c5SAndroid Build Coastguard Worker return programInfo.getShaderProgram().createGraphicsPipeline(
1563*8975f5c5SAndroid Build Coastguard Worker context, &pipelines, pipelineCache, compatibleRenderPass, getPipelineLayout(), source,
1564*8975f5c5SAndroid Build Coastguard Worker desc, specConsts, descPtrOut, pipelineOut);
1565*8975f5c5SAndroid Build Coastguard Worker }
1566*8975f5c5SAndroid Build Coastguard Worker }
1567*8975f5c5SAndroid Build Coastguard Worker
getGraphicsPipeline(ContextVk * contextVk,vk::GraphicsPipelineSubset pipelineSubset,const vk::GraphicsPipelineDesc & desc,const vk::GraphicsPipelineDesc ** descPtrOut,vk::PipelineHelper ** pipelineOut)1568*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::getGraphicsPipeline(ContextVk *contextVk,
1569*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset pipelineSubset,
1570*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc,
1571*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc **descPtrOut,
1572*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1573*8975f5c5SAndroid Build Coastguard Worker {
1574*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = getTransformOptions(contextVk, desc);
1575*8975f5c5SAndroid Build Coastguard Worker
1576*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initGraphicsShaderPrograms(contextVk, transformOptions));
1577*8975f5c5SAndroid Build Coastguard Worker
1578*8975f5c5SAndroid Build Coastguard Worker const uint8_t programIndex = transformOptions.permutationIndex;
1579*8975f5c5SAndroid Build Coastguard Worker
1580*8975f5c5SAndroid Build Coastguard Worker *descPtrOut = nullptr;
1581*8975f5c5SAndroid Build Coastguard Worker *pipelineOut = nullptr;
1582*8975f5c5SAndroid Build Coastguard Worker
1583*8975f5c5SAndroid Build Coastguard Worker if (pipelineSubset == vk::GraphicsPipelineSubset::Complete)
1584*8975f5c5SAndroid Build Coastguard Worker {
1585*8975f5c5SAndroid Build Coastguard Worker mCompleteGraphicsPipelines[programIndex].getPipeline(desc, descPtrOut, pipelineOut);
1586*8975f5c5SAndroid Build Coastguard Worker }
1587*8975f5c5SAndroid Build Coastguard Worker else
1588*8975f5c5SAndroid Build Coastguard Worker {
1589*8975f5c5SAndroid Build Coastguard Worker // Vertex input and fragment output subsets are independent of shaders, and are not created
1590*8975f5c5SAndroid Build Coastguard Worker // through the program executable.
1591*8975f5c5SAndroid Build Coastguard Worker ASSERT(pipelineSubset == vk::GraphicsPipelineSubset::Shaders);
1592*8975f5c5SAndroid Build Coastguard Worker
1593*8975f5c5SAndroid Build Coastguard Worker mShadersGraphicsPipelines[programIndex].getPipeline(desc, descPtrOut, pipelineOut);
1594*8975f5c5SAndroid Build Coastguard Worker }
1595*8975f5c5SAndroid Build Coastguard Worker
1596*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1597*8975f5c5SAndroid Build Coastguard Worker }
1598*8975f5c5SAndroid Build Coastguard Worker
createGraphicsPipeline(ContextVk * contextVk,vk::GraphicsPipelineSubset pipelineSubset,vk::PipelineCacheAccess * pipelineCache,PipelineSource source,const vk::GraphicsPipelineDesc & desc,const vk::GraphicsPipelineDesc ** descPtrOut,vk::PipelineHelper ** pipelineOut)1599*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::createGraphicsPipeline(
1600*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1601*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineSubset pipelineSubset,
1602*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess *pipelineCache,
1603*8975f5c5SAndroid Build Coastguard Worker PipelineSource source,
1604*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc,
1605*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc **descPtrOut,
1606*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1607*8975f5c5SAndroid Build Coastguard Worker {
1608*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = getTransformOptions(contextVk, desc);
1609*8975f5c5SAndroid Build Coastguard Worker
1610*8975f5c5SAndroid Build Coastguard Worker // When creating monolithic pipelines, the renderer's pipeline cache is used as passed in.
1611*8975f5c5SAndroid Build Coastguard Worker // When creating the shaders subset of pipelines, the program's own pipeline cache is used.
1612*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess perProgramPipelineCache;
1613*8975f5c5SAndroid Build Coastguard Worker const bool useProgramPipelineCache = pipelineSubset == vk::GraphicsPipelineSubset::Shaders;
1614*8975f5c5SAndroid Build Coastguard Worker if (useProgramPipelineCache)
1615*8975f5c5SAndroid Build Coastguard Worker {
1616*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensurePipelineCacheInitialized(contextVk));
1617*8975f5c5SAndroid Build Coastguard Worker
1618*8975f5c5SAndroid Build Coastguard Worker perProgramPipelineCache.init(&mPipelineCache, nullptr);
1619*8975f5c5SAndroid Build Coastguard Worker pipelineCache = &perProgramPipelineCache;
1620*8975f5c5SAndroid Build Coastguard Worker }
1621*8975f5c5SAndroid Build Coastguard Worker
1622*8975f5c5SAndroid Build Coastguard Worker // Pull in a compatible RenderPass.
1623*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass *compatibleRenderPass = nullptr;
1624*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getCompatibleRenderPass(desc.getRenderPassDesc(), &compatibleRenderPass));
1625*8975f5c5SAndroid Build Coastguard Worker
1626*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initProgramThenCreateGraphicsPipeline(
1627*8975f5c5SAndroid Build Coastguard Worker contextVk, transformOptions, pipelineSubset, pipelineCache, source, desc,
1628*8975f5c5SAndroid Build Coastguard Worker *compatibleRenderPass, descPtrOut, pipelineOut));
1629*8975f5c5SAndroid Build Coastguard Worker
1630*8975f5c5SAndroid Build Coastguard Worker if (useProgramPipelineCache &&
1631*8975f5c5SAndroid Build Coastguard Worker contextVk->getFeatures().mergeProgramPipelineCachesToGlobalCache.enabled)
1632*8975f5c5SAndroid Build Coastguard Worker {
1633*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getRenderer()->mergeIntoPipelineCache(contextVk, mPipelineCache));
1634*8975f5c5SAndroid Build Coastguard Worker }
1635*8975f5c5SAndroid Build Coastguard Worker
1636*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1637*8975f5c5SAndroid Build Coastguard Worker }
1638*8975f5c5SAndroid Build Coastguard Worker
linkGraphicsPipelineLibraries(ContextVk * contextVk,vk::PipelineCacheAccess * pipelineCache,const vk::GraphicsPipelineDesc & desc,vk::PipelineHelper * vertexInputPipeline,vk::PipelineHelper * shadersPipeline,vk::PipelineHelper * fragmentOutputPipeline,const vk::GraphicsPipelineDesc ** descPtrOut,vk::PipelineHelper ** pipelineOut)1639*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::linkGraphicsPipelineLibraries(
1640*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1641*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess *pipelineCache,
1642*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc &desc,
1643*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *vertexInputPipeline,
1644*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *shadersPipeline,
1645*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *fragmentOutputPipeline,
1646*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc **descPtrOut,
1647*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1648*8975f5c5SAndroid Build Coastguard Worker {
1649*8975f5c5SAndroid Build Coastguard Worker ProgramTransformOptions transformOptions = getTransformOptions(contextVk, desc);
1650*8975f5c5SAndroid Build Coastguard Worker const uint8_t programIndex = transformOptions.permutationIndex;
1651*8975f5c5SAndroid Build Coastguard Worker
1652*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mCompleteGraphicsPipelines[programIndex].linkLibraries(
1653*8975f5c5SAndroid Build Coastguard Worker contextVk, pipelineCache, desc, getPipelineLayout(), vertexInputPipeline, shadersPipeline,
1654*8975f5c5SAndroid Build Coastguard Worker fragmentOutputPipeline, descPtrOut, pipelineOut));
1655*8975f5c5SAndroid Build Coastguard Worker
1656*8975f5c5SAndroid Build Coastguard Worker // If monolithic pipelines are preferred over libraries, create a task so that it can be created
1657*8975f5c5SAndroid Build Coastguard Worker // asynchronously.
1658*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().preferMonolithicPipelinesOverLibraries.enabled)
1659*8975f5c5SAndroid Build Coastguard Worker {
1660*8975f5c5SAndroid Build Coastguard Worker vk::SpecializationConstants specConsts = MakeSpecConsts(transformOptions, desc);
1661*8975f5c5SAndroid Build Coastguard Worker
1662*8975f5c5SAndroid Build Coastguard Worker mGraphicsProgramInfos[programIndex].getShaderProgram().createMonolithicPipelineCreationTask(
1663*8975f5c5SAndroid Build Coastguard Worker contextVk, pipelineCache, desc, getPipelineLayout(), specConsts, *pipelineOut);
1664*8975f5c5SAndroid Build Coastguard Worker }
1665*8975f5c5SAndroid Build Coastguard Worker
1666*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1667*8975f5c5SAndroid Build Coastguard Worker }
1668*8975f5c5SAndroid Build Coastguard Worker
getOrCreateComputePipeline(vk::Context * context,vk::PipelineCacheAccess * pipelineCache,PipelineSource source,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess,vk::PipelineHelper ** pipelineOut)1669*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::getOrCreateComputePipeline(
1670*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1671*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess *pipelineCache,
1672*8975f5c5SAndroid Build Coastguard Worker PipelineSource source,
1673*8975f5c5SAndroid Build Coastguard Worker vk::PipelineRobustness pipelineRobustness,
1674*8975f5c5SAndroid Build Coastguard Worker vk::PipelineProtectedAccess pipelineProtectedAccess,
1675*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper **pipelineOut)
1676*8975f5c5SAndroid Build Coastguard Worker {
1677*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute));
1678*8975f5c5SAndroid Build Coastguard Worker
1679*8975f5c5SAndroid Build Coastguard Worker vk::ComputePipelineOptions pipelineOptions =
1680*8975f5c5SAndroid Build Coastguard Worker vk::GetComputePipelineOptions(pipelineRobustness, pipelineProtectedAccess);
1681*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initComputeProgram(context, &mComputeProgramInfo, mVariableInfoMap, pipelineOptions));
1682*8975f5c5SAndroid Build Coastguard Worker
1683*8975f5c5SAndroid Build Coastguard Worker return mComputeProgramInfo.getShaderProgram().getOrCreateComputePipeline(
1684*8975f5c5SAndroid Build Coastguard Worker context, &mComputePipelines, pipelineCache, getPipelineLayout(), pipelineOptions, source,
1685*8975f5c5SAndroid Build Coastguard Worker pipelineOut, nullptr, nullptr);
1686*8975f5c5SAndroid Build Coastguard Worker }
1687*8975f5c5SAndroid Build Coastguard Worker
createPipelineLayout(vk::Context * context,PipelineLayoutCache * pipelineLayoutCache,DescriptorSetLayoutCache * descriptorSetLayoutCache,gl::ActiveTextureArray<TextureVk * > * activeTextures)1688*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::createPipelineLayout(
1689*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1690*8975f5c5SAndroid Build Coastguard Worker PipelineLayoutCache *pipelineLayoutCache,
1691*8975f5c5SAndroid Build Coastguard Worker DescriptorSetLayoutCache *descriptorSetLayoutCache,
1692*8975f5c5SAndroid Build Coastguard Worker gl::ActiveTextureArray<TextureVk *> *activeTextures)
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet &linkedShaderStages = mExecutable->getLinkedShaderStages();
1695*8975f5c5SAndroid Build Coastguard Worker
1696*8975f5c5SAndroid Build Coastguard Worker // Store a reference to the pipeline and descriptor set layouts. This will create them if they
1697*8975f5c5SAndroid Build Coastguard Worker // don't already exist in the cache.
1698*8975f5c5SAndroid Build Coastguard Worker
1699*8975f5c5SAndroid Build Coastguard Worker // Default uniforms and transform feedback:
1700*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbSetDesc = {};
1701*8975f5c5SAndroid Build Coastguard Worker uint32_t numDefaultUniformDescriptors = 0;
1702*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : linkedShaderStages)
1703*8975f5c5SAndroid Build Coastguard Worker {
1704*8975f5c5SAndroid Build Coastguard Worker const ShaderInterfaceVariableInfo &info =
1705*8975f5c5SAndroid Build Coastguard Worker mVariableInfoMap.getDefaultUniformInfo(shaderType);
1706*8975f5c5SAndroid Build Coastguard Worker // Note that currently the default uniform block is added unconditionally.
1707*8975f5c5SAndroid Build Coastguard Worker ASSERT(info.activeStages[shaderType]);
1708*8975f5c5SAndroid Build Coastguard Worker
1709*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbSetDesc.addBinding(info.binding,
1710*8975f5c5SAndroid Build Coastguard Worker VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
1711*8975f5c5SAndroid Build Coastguard Worker gl_vk::kShaderStageMap[shaderType], nullptr);
1712*8975f5c5SAndroid Build Coastguard Worker numDefaultUniformDescriptors++;
1713*8975f5c5SAndroid Build Coastguard Worker }
1714*8975f5c5SAndroid Build Coastguard Worker
1715*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType linkedTransformFeedbackStage = mExecutable->getLinkedTransformFeedbackStage();
1716*8975f5c5SAndroid Build Coastguard Worker bool hasXfbVaryings = linkedTransformFeedbackStage != gl::ShaderType::InvalidEnum &&
1717*8975f5c5SAndroid Build Coastguard Worker !mExecutable->getLinkedTransformFeedbackVaryings().empty();
1718*8975f5c5SAndroid Build Coastguard Worker if (context->getFeatures().emulateTransformFeedback.enabled && hasXfbVaryings)
1719*8975f5c5SAndroid Build Coastguard Worker {
1720*8975f5c5SAndroid Build Coastguard Worker size_t xfbBufferCount = mExecutable->getTransformFeedbackBufferCount();
1721*8975f5c5SAndroid Build Coastguard Worker for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
1722*8975f5c5SAndroid Build Coastguard Worker {
1723*8975f5c5SAndroid Build Coastguard Worker const uint32_t binding = mVariableInfoMap.getEmulatedXfbBufferBinding(bufferIndex);
1724*8975f5c5SAndroid Build Coastguard Worker ASSERT(binding != std::numeric_limits<uint32_t>::max());
1725*8975f5c5SAndroid Build Coastguard Worker
1726*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbSetDesc.addBinding(binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
1727*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_VERTEX_BIT, nullptr);
1728*8975f5c5SAndroid Build Coastguard Worker }
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker
1731*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(descriptorSetLayoutCache->getDescriptorSetLayout(
1732*8975f5c5SAndroid Build Coastguard Worker context, mDefaultUniformAndXfbSetDesc,
1733*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSetLayouts[DescriptorSetIndex::UniformsAndXfb]));
1734*8975f5c5SAndroid Build Coastguard Worker
1735*8975f5c5SAndroid Build Coastguard Worker // Uniform and storage buffers, atomic counter buffers and images:
1736*8975f5c5SAndroid Build Coastguard Worker mShaderResourceSetDesc = {};
1737*8975f5c5SAndroid Build Coastguard Worker
1738*8975f5c5SAndroid Build Coastguard Worker // Count the number of active uniform buffer descriptors.
1739*8975f5c5SAndroid Build Coastguard Worker uint32_t numActiveUniformBufferDescriptors = 0;
1740*8975f5c5SAndroid Build Coastguard Worker const std::vector<gl::InterfaceBlock> &blocks = mExecutable->getUniformBlocks();
1741*8975f5c5SAndroid Build Coastguard Worker for (uint32_t bufferIndex = 0; bufferIndex < blocks.size();)
1742*8975f5c5SAndroid Build Coastguard Worker {
1743*8975f5c5SAndroid Build Coastguard Worker const gl::InterfaceBlock &block = blocks[bufferIndex];
1744*8975f5c5SAndroid Build Coastguard Worker const uint32_t arraySize = GetInterfaceBlockArraySize(blocks, bufferIndex);
1745*8975f5c5SAndroid Build Coastguard Worker bufferIndex += arraySize;
1746*8975f5c5SAndroid Build Coastguard Worker
1747*8975f5c5SAndroid Build Coastguard Worker if (block.activeShaders().any())
1748*8975f5c5SAndroid Build Coastguard Worker {
1749*8975f5c5SAndroid Build Coastguard Worker numActiveUniformBufferDescriptors += arraySize;
1750*8975f5c5SAndroid Build Coastguard Worker }
1751*8975f5c5SAndroid Build Coastguard Worker }
1752*8975f5c5SAndroid Build Coastguard Worker
1753*8975f5c5SAndroid Build Coastguard Worker // Decide if we should use dynamic or fixed descriptor types.
1754*8975f5c5SAndroid Build Coastguard Worker VkPhysicalDeviceLimits limits = context->getRenderer()->getPhysicalDeviceProperties().limits;
1755*8975f5c5SAndroid Build Coastguard Worker uint32_t totalDynamicUniformBufferCount =
1756*8975f5c5SAndroid Build Coastguard Worker numActiveUniformBufferDescriptors + numDefaultUniformDescriptors;
1757*8975f5c5SAndroid Build Coastguard Worker if (totalDynamicUniformBufferCount <= limits.maxDescriptorSetUniformBuffersDynamic)
1758*8975f5c5SAndroid Build Coastguard Worker {
1759*8975f5c5SAndroid Build Coastguard Worker mUniformBufferDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
1760*8975f5c5SAndroid Build Coastguard Worker }
1761*8975f5c5SAndroid Build Coastguard Worker else
1762*8975f5c5SAndroid Build Coastguard Worker {
1763*8975f5c5SAndroid Build Coastguard Worker mUniformBufferDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1764*8975f5c5SAndroid Build Coastguard Worker }
1765*8975f5c5SAndroid Build Coastguard Worker
1766*8975f5c5SAndroid Build Coastguard Worker addInterfaceBlockDescriptorSetDesc(mExecutable->getUniformBlocks(), linkedShaderStages,
1767*8975f5c5SAndroid Build Coastguard Worker mUniformBufferDescriptorType, &mShaderResourceSetDesc);
1768*8975f5c5SAndroid Build Coastguard Worker addInterfaceBlockDescriptorSetDesc(mExecutable->getShaderStorageBlocks(), linkedShaderStages,
1769*8975f5c5SAndroid Build Coastguard Worker vk::kStorageBufferDescriptorType, &mShaderResourceSetDesc);
1770*8975f5c5SAndroid Build Coastguard Worker addAtomicCounterBufferDescriptorSetDesc(mExecutable->getAtomicCounterBuffers(),
1771*8975f5c5SAndroid Build Coastguard Worker &mShaderResourceSetDesc);
1772*8975f5c5SAndroid Build Coastguard Worker addImageDescriptorSetDesc(&mShaderResourceSetDesc);
1773*8975f5c5SAndroid Build Coastguard Worker addInputAttachmentDescriptorSetDesc(context, &mShaderResourceSetDesc);
1774*8975f5c5SAndroid Build Coastguard Worker
1775*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(descriptorSetLayoutCache->getDescriptorSetLayout(
1776*8975f5c5SAndroid Build Coastguard Worker context, mShaderResourceSetDesc,
1777*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSetLayouts[DescriptorSetIndex::ShaderResource]));
1778*8975f5c5SAndroid Build Coastguard Worker
1779*8975f5c5SAndroid Build Coastguard Worker // Textures:
1780*8975f5c5SAndroid Build Coastguard Worker mTextureSetDesc = {};
1781*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(addTextureDescriptorSetDesc(context, activeTextures, &mTextureSetDesc));
1782*8975f5c5SAndroid Build Coastguard Worker
1783*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(descriptorSetLayoutCache->getDescriptorSetLayout(
1784*8975f5c5SAndroid Build Coastguard Worker context, mTextureSetDesc, &mDescriptorSetLayouts[DescriptorSetIndex::Texture]));
1785*8975f5c5SAndroid Build Coastguard Worker
1786*8975f5c5SAndroid Build Coastguard Worker // Create pipeline layout with these 3 descriptor sets.
1787*8975f5c5SAndroid Build Coastguard Worker vk::PipelineLayoutDesc pipelineLayoutDesc;
1788*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::UniformsAndXfb,
1789*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformAndXfbSetDesc);
1790*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::ShaderResource,
1791*8975f5c5SAndroid Build Coastguard Worker mShaderResourceSetDesc);
1792*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::Texture, mTextureSetDesc);
1793*8975f5c5SAndroid Build Coastguard Worker
1794*8975f5c5SAndroid Build Coastguard Worker // Set up driver uniforms as push constants. The size is set for a graphics pipeline, as there
1795*8975f5c5SAndroid Build Coastguard Worker // are more driver uniforms for a graphics pipeline than there are for a compute pipeline. As
1796*8975f5c5SAndroid Build Coastguard Worker // for the shader stages, both graphics and compute stages are used.
1797*8975f5c5SAndroid Build Coastguard Worker VkShaderStageFlags pushConstantShaderStageFlags =
1798*8975f5c5SAndroid Build Coastguard Worker context->getRenderer()->getSupportedVulkanShaderStageMask();
1799*8975f5c5SAndroid Build Coastguard Worker
1800*8975f5c5SAndroid Build Coastguard Worker uint32_t pushConstantSize = GetDriverUniformSize(context, PipelineType::Graphics);
1801*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updatePushConstantRange(pushConstantShaderStageFlags, 0, pushConstantSize);
1802*8975f5c5SAndroid Build Coastguard Worker
1803*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(pipelineLayoutCache->getPipelineLayout(context, pipelineLayoutDesc,
1804*8975f5c5SAndroid Build Coastguard Worker mDescriptorSetLayouts, &mPipelineLayout));
1805*8975f5c5SAndroid Build Coastguard Worker
1806*8975f5c5SAndroid Build Coastguard Worker mDynamicUniformDescriptorOffsets.clear();
1807*8975f5c5SAndroid Build Coastguard Worker mDynamicUniformDescriptorOffsets.resize(mExecutable->getLinkedShaderStageCount(), 0);
1808*8975f5c5SAndroid Build Coastguard Worker
1809*8975f5c5SAndroid Build Coastguard Worker initializeWriteDescriptorDesc(context);
1810*8975f5c5SAndroid Build Coastguard Worker
1811*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1812*8975f5c5SAndroid Build Coastguard Worker }
1813*8975f5c5SAndroid Build Coastguard Worker
initializeDescriptorPools(vk::Context * context,DescriptorSetLayoutCache * descriptorSetLayoutCache,vk::DescriptorSetArray<vk::MetaDescriptorPool> * metaDescriptorPools)1814*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::initializeDescriptorPools(
1815*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1816*8975f5c5SAndroid Build Coastguard Worker DescriptorSetLayoutCache *descriptorSetLayoutCache,
1817*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetArray<vk::MetaDescriptorPool> *metaDescriptorPools)
1818*8975f5c5SAndroid Build Coastguard Worker {
1819*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY((*metaDescriptorPools)[DescriptorSetIndex::UniformsAndXfb].bindCachedDescriptorPool(
1820*8975f5c5SAndroid Build Coastguard Worker context, mDefaultUniformAndXfbSetDesc, 1, descriptorSetLayoutCache,
1821*8975f5c5SAndroid Build Coastguard Worker &mDynamicDescriptorPools[DescriptorSetIndex::UniformsAndXfb]));
1822*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY((*metaDescriptorPools)[DescriptorSetIndex::Texture].bindCachedDescriptorPool(
1823*8975f5c5SAndroid Build Coastguard Worker context, mTextureSetDesc, mImmutableSamplersMaxDescriptorCount, descriptorSetLayoutCache,
1824*8975f5c5SAndroid Build Coastguard Worker &mDynamicDescriptorPools[DescriptorSetIndex::Texture]));
1825*8975f5c5SAndroid Build Coastguard Worker return (*metaDescriptorPools)[DescriptorSetIndex::ShaderResource].bindCachedDescriptorPool(
1826*8975f5c5SAndroid Build Coastguard Worker context, mShaderResourceSetDesc, 1, descriptorSetLayoutCache,
1827*8975f5c5SAndroid Build Coastguard Worker &mDynamicDescriptorPools[DescriptorSetIndex::ShaderResource]);
1828*8975f5c5SAndroid Build Coastguard Worker }
1829*8975f5c5SAndroid Build Coastguard Worker
resolvePrecisionMismatch(const gl::ProgramMergedVaryings & mergedVaryings)1830*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::resolvePrecisionMismatch(const gl::ProgramMergedVaryings &mergedVaryings)
1831*8975f5c5SAndroid Build Coastguard Worker {
1832*8975f5c5SAndroid Build Coastguard Worker for (const gl::ProgramVaryingRef &mergedVarying : mergedVaryings)
1833*8975f5c5SAndroid Build Coastguard Worker {
1834*8975f5c5SAndroid Build Coastguard Worker if (!mergedVarying.frontShader || !mergedVarying.backShader)
1835*8975f5c5SAndroid Build Coastguard Worker {
1836*8975f5c5SAndroid Build Coastguard Worker continue;
1837*8975f5c5SAndroid Build Coastguard Worker }
1838*8975f5c5SAndroid Build Coastguard Worker
1839*8975f5c5SAndroid Build Coastguard Worker GLenum frontPrecision = mergedVarying.frontShader->precision;
1840*8975f5c5SAndroid Build Coastguard Worker GLenum backPrecision = mergedVarying.backShader->precision;
1841*8975f5c5SAndroid Build Coastguard Worker if (frontPrecision == backPrecision)
1842*8975f5c5SAndroid Build Coastguard Worker {
1843*8975f5c5SAndroid Build Coastguard Worker continue;
1844*8975f5c5SAndroid Build Coastguard Worker }
1845*8975f5c5SAndroid Build Coastguard Worker
1846*8975f5c5SAndroid Build Coastguard Worker ASSERT(frontPrecision >= GL_LOW_FLOAT && frontPrecision <= GL_HIGH_INT);
1847*8975f5c5SAndroid Build Coastguard Worker ASSERT(backPrecision >= GL_LOW_FLOAT && backPrecision <= GL_HIGH_INT);
1848*8975f5c5SAndroid Build Coastguard Worker
1849*8975f5c5SAndroid Build Coastguard Worker if (frontPrecision > backPrecision)
1850*8975f5c5SAndroid Build Coastguard Worker {
1851*8975f5c5SAndroid Build Coastguard Worker // The output is higher precision than the input
1852*8975f5c5SAndroid Build Coastguard Worker ShaderInterfaceVariableInfo &info = mVariableInfoMap.getMutable(
1853*8975f5c5SAndroid Build Coastguard Worker mergedVarying.frontShaderStage, mergedVarying.frontShader->id);
1854*8975f5c5SAndroid Build Coastguard Worker info.varyingIsOutput = true;
1855*8975f5c5SAndroid Build Coastguard Worker info.useRelaxedPrecision = true;
1856*8975f5c5SAndroid Build Coastguard Worker }
1857*8975f5c5SAndroid Build Coastguard Worker else
1858*8975f5c5SAndroid Build Coastguard Worker {
1859*8975f5c5SAndroid Build Coastguard Worker // The output is lower precision than the input, adjust the input
1860*8975f5c5SAndroid Build Coastguard Worker ASSERT(backPrecision > frontPrecision);
1861*8975f5c5SAndroid Build Coastguard Worker ShaderInterfaceVariableInfo &info = mVariableInfoMap.getMutable(
1862*8975f5c5SAndroid Build Coastguard Worker mergedVarying.backShaderStage, mergedVarying.backShader->id);
1863*8975f5c5SAndroid Build Coastguard Worker info.varyingIsInput = true;
1864*8975f5c5SAndroid Build Coastguard Worker info.useRelaxedPrecision = true;
1865*8975f5c5SAndroid Build Coastguard Worker }
1866*8975f5c5SAndroid Build Coastguard Worker }
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker
getOrAllocateDescriptorSet(vk::Context * context,uint32_t currentFrame,UpdateDescriptorSetsBuilder * updateBuilder,const vk::DescriptorSetDescBuilder & descriptorSetDesc,const vk::WriteDescriptorDescs & writeDescriptorDescs,DescriptorSetIndex setIndex,vk::SharedDescriptorSetCacheKey * newSharedCacheKeyOut)1869*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::getOrAllocateDescriptorSet(
1870*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1871*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
1872*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder,
1873*8975f5c5SAndroid Build Coastguard Worker const vk::DescriptorSetDescBuilder &descriptorSetDesc,
1874*8975f5c5SAndroid Build Coastguard Worker const vk::WriteDescriptorDescs &writeDescriptorDescs,
1875*8975f5c5SAndroid Build Coastguard Worker DescriptorSetIndex setIndex,
1876*8975f5c5SAndroid Build Coastguard Worker vk::SharedDescriptorSetCacheKey *newSharedCacheKeyOut)
1877*8975f5c5SAndroid Build Coastguard Worker {
1878*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = context->getRenderer();
1879*8975f5c5SAndroid Build Coastguard Worker
1880*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().descriptorSetCache.enabled)
1881*8975f5c5SAndroid Build Coastguard Worker {
1882*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mDynamicDescriptorPools[setIndex]->getOrAllocateDescriptorSet(
1883*8975f5c5SAndroid Build Coastguard Worker context, currentFrame, descriptorSetDesc.getDesc(), *mDescriptorSetLayouts[setIndex],
1884*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSets[setIndex], newSharedCacheKeyOut));
1885*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDescriptorSets[setIndex]);
1886*8975f5c5SAndroid Build Coastguard Worker
1887*8975f5c5SAndroid Build Coastguard Worker if (*newSharedCacheKeyOut)
1888*8975f5c5SAndroid Build Coastguard Worker {
1889*8975f5c5SAndroid Build Coastguard Worker ASSERT((*newSharedCacheKeyOut)->valid());
1890*8975f5c5SAndroid Build Coastguard Worker // Cache miss. A new cache entry has been created.
1891*8975f5c5SAndroid Build Coastguard Worker descriptorSetDesc.updateDescriptorSet(renderer, writeDescriptorDescs, updateBuilder,
1892*8975f5c5SAndroid Build Coastguard Worker mDescriptorSets[setIndex]->getDescriptorSet());
1893*8975f5c5SAndroid Build Coastguard Worker }
1894*8975f5c5SAndroid Build Coastguard Worker }
1895*8975f5c5SAndroid Build Coastguard Worker else
1896*8975f5c5SAndroid Build Coastguard Worker {
1897*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mDynamicDescriptorPools[setIndex]->allocateDescriptorSet(
1898*8975f5c5SAndroid Build Coastguard Worker context, *mDescriptorSetLayouts[setIndex], &mDescriptorSets[setIndex]));
1899*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDescriptorSets[setIndex]);
1900*8975f5c5SAndroid Build Coastguard Worker
1901*8975f5c5SAndroid Build Coastguard Worker descriptorSetDesc.updateDescriptorSet(renderer, writeDescriptorDescs, updateBuilder,
1902*8975f5c5SAndroid Build Coastguard Worker mDescriptorSets[setIndex]->getDescriptorSet());
1903*8975f5c5SAndroid Build Coastguard Worker }
1904*8975f5c5SAndroid Build Coastguard Worker
1905*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1906*8975f5c5SAndroid Build Coastguard Worker }
1907*8975f5c5SAndroid Build Coastguard Worker
updateShaderResourcesDescriptorSet(vk::Context * context,uint32_t currentFrame,UpdateDescriptorSetsBuilder * updateBuilder,const vk::WriteDescriptorDescs & writeDescriptorDescs,const vk::DescriptorSetDescBuilder & shaderResourcesDesc,vk::SharedDescriptorSetCacheKey * newSharedCacheKeyOut)1908*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet(
1909*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1910*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
1911*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder,
1912*8975f5c5SAndroid Build Coastguard Worker const vk::WriteDescriptorDescs &writeDescriptorDescs,
1913*8975f5c5SAndroid Build Coastguard Worker const vk::DescriptorSetDescBuilder &shaderResourcesDesc,
1914*8975f5c5SAndroid Build Coastguard Worker vk::SharedDescriptorSetCacheKey *newSharedCacheKeyOut)
1915*8975f5c5SAndroid Build Coastguard Worker {
1916*8975f5c5SAndroid Build Coastguard Worker if (!mDynamicDescriptorPools[DescriptorSetIndex::ShaderResource])
1917*8975f5c5SAndroid Build Coastguard Worker {
1918*8975f5c5SAndroid Build Coastguard Worker (*newSharedCacheKeyOut).reset();
1919*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1920*8975f5c5SAndroid Build Coastguard Worker }
1921*8975f5c5SAndroid Build Coastguard Worker
1922*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getOrAllocateDescriptorSet(context, currentFrame, updateBuilder, shaderResourcesDesc,
1923*8975f5c5SAndroid Build Coastguard Worker writeDescriptorDescs, DescriptorSetIndex::ShaderResource,
1924*8975f5c5SAndroid Build Coastguard Worker newSharedCacheKeyOut));
1925*8975f5c5SAndroid Build Coastguard Worker
1926*8975f5c5SAndroid Build Coastguard Worker size_t numOffsets = writeDescriptorDescs.getDynamicDescriptorSetCount();
1927*8975f5c5SAndroid Build Coastguard Worker mDynamicShaderResourceDescriptorOffsets.resize(numOffsets);
1928*8975f5c5SAndroid Build Coastguard Worker if (numOffsets > 0)
1929*8975f5c5SAndroid Build Coastguard Worker {
1930*8975f5c5SAndroid Build Coastguard Worker memcpy(mDynamicShaderResourceDescriptorOffsets.data(),
1931*8975f5c5SAndroid Build Coastguard Worker shaderResourcesDesc.getDynamicOffsets(), numOffsets * sizeof(uint32_t));
1932*8975f5c5SAndroid Build Coastguard Worker }
1933*8975f5c5SAndroid Build Coastguard Worker
1934*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1935*8975f5c5SAndroid Build Coastguard Worker }
1936*8975f5c5SAndroid Build Coastguard Worker
updateUniformsAndXfbDescriptorSet(vk::Context * context,uint32_t currentFrame,UpdateDescriptorSetsBuilder * updateBuilder,const vk::WriteDescriptorDescs & writeDescriptorDescs,vk::BufferHelper * defaultUniformBuffer,vk::DescriptorSetDescBuilder * uniformsAndXfbDesc,vk::SharedDescriptorSetCacheKey * sharedCacheKeyOut)1937*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::updateUniformsAndXfbDescriptorSet(
1938*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1939*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
1940*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder,
1941*8975f5c5SAndroid Build Coastguard Worker const vk::WriteDescriptorDescs &writeDescriptorDescs,
1942*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *defaultUniformBuffer,
1943*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetDescBuilder *uniformsAndXfbDesc,
1944*8975f5c5SAndroid Build Coastguard Worker vk::SharedDescriptorSetCacheKey *sharedCacheKeyOut)
1945*8975f5c5SAndroid Build Coastguard Worker {
1946*8975f5c5SAndroid Build Coastguard Worker mCurrentDefaultUniformBufferSerial =
1947*8975f5c5SAndroid Build Coastguard Worker defaultUniformBuffer ? defaultUniformBuffer->getBufferSerial() : vk::kInvalidBufferSerial;
1948*8975f5c5SAndroid Build Coastguard Worker
1949*8975f5c5SAndroid Build Coastguard Worker return getOrAllocateDescriptorSet(context, currentFrame, updateBuilder, *uniformsAndXfbDesc,
1950*8975f5c5SAndroid Build Coastguard Worker writeDescriptorDescs, DescriptorSetIndex::UniformsAndXfb,
1951*8975f5c5SAndroid Build Coastguard Worker sharedCacheKeyOut);
1952*8975f5c5SAndroid Build Coastguard Worker }
1953*8975f5c5SAndroid Build Coastguard Worker
updateTexturesDescriptorSet(vk::Context * context,uint32_t currentFrame,const gl::ActiveTextureArray<TextureVk * > & textures,const gl::SamplerBindingVector & samplers,PipelineType pipelineType,UpdateDescriptorSetsBuilder * updateBuilder)1954*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(
1955*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1956*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
1957*8975f5c5SAndroid Build Coastguard Worker const gl::ActiveTextureArray<TextureVk *> &textures,
1958*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerBindingVector &samplers,
1959*8975f5c5SAndroid Build Coastguard Worker PipelineType pipelineType,
1960*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder)
1961*8975f5c5SAndroid Build Coastguard Worker {
1962*8975f5c5SAndroid Build Coastguard Worker if (context->getFeatures().descriptorSetCache.enabled)
1963*8975f5c5SAndroid Build Coastguard Worker {
1964*8975f5c5SAndroid Build Coastguard Worker vk::SharedDescriptorSetCacheKey newSharedCacheKey;
1965*8975f5c5SAndroid Build Coastguard Worker
1966*8975f5c5SAndroid Build Coastguard Worker // We use textureSerial to optimize texture binding updates. Each permutation of a
1967*8975f5c5SAndroid Build Coastguard Worker // {VkImage/VkSampler} generates a unique serial. These object ids are combined to form a
1968*8975f5c5SAndroid Build Coastguard Worker // unique signature for each descriptor set. This allows us to keep a cache of descriptor
1969*8975f5c5SAndroid Build Coastguard Worker // sets and avoid calling vkAllocateDesctiporSets each texture update.
1970*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetDescBuilder descriptorBuilder;
1971*8975f5c5SAndroid Build Coastguard Worker descriptorBuilder.updatePreCacheActiveTextures(context, *mExecutable, textures, samplers);
1972*8975f5c5SAndroid Build Coastguard Worker
1973*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mDynamicDescriptorPools[DescriptorSetIndex::Texture]->getOrAllocateDescriptorSet(
1974*8975f5c5SAndroid Build Coastguard Worker context, currentFrame, descriptorBuilder.getDesc(),
1975*8975f5c5SAndroid Build Coastguard Worker *mDescriptorSetLayouts[DescriptorSetIndex::Texture],
1976*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSets[DescriptorSetIndex::Texture], &newSharedCacheKey));
1977*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDescriptorSets[DescriptorSetIndex::Texture]);
1978*8975f5c5SAndroid Build Coastguard Worker
1979*8975f5c5SAndroid Build Coastguard Worker if (newSharedCacheKey)
1980*8975f5c5SAndroid Build Coastguard Worker {
1981*8975f5c5SAndroid Build Coastguard Worker ASSERT(newSharedCacheKey->valid());
1982*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(UpdateFullTexturesDescriptorSet(
1983*8975f5c5SAndroid Build Coastguard Worker context, mVariableInfoMap, mTextureWriteDescriptorDescs, updateBuilder,
1984*8975f5c5SAndroid Build Coastguard Worker *mExecutable, textures, samplers,
1985*8975f5c5SAndroid Build Coastguard Worker mDescriptorSets[DescriptorSetIndex::Texture]->getDescriptorSet()));
1986*8975f5c5SAndroid Build Coastguard Worker
1987*8975f5c5SAndroid Build Coastguard Worker const gl::ActiveTextureMask &activeTextureMask = mExecutable->getActiveSamplersMask();
1988*8975f5c5SAndroid Build Coastguard Worker for (size_t textureUnit : activeTextureMask)
1989*8975f5c5SAndroid Build Coastguard Worker {
1990*8975f5c5SAndroid Build Coastguard Worker ASSERT(textures[textureUnit] != nullptr);
1991*8975f5c5SAndroid Build Coastguard Worker textures[textureUnit]->onNewDescriptorSet(newSharedCacheKey);
1992*8975f5c5SAndroid Build Coastguard Worker }
1993*8975f5c5SAndroid Build Coastguard Worker }
1994*8975f5c5SAndroid Build Coastguard Worker }
1995*8975f5c5SAndroid Build Coastguard Worker else
1996*8975f5c5SAndroid Build Coastguard Worker {
1997*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mDynamicDescriptorPools[DescriptorSetIndex::Texture]->allocateDescriptorSet(
1998*8975f5c5SAndroid Build Coastguard Worker context, *mDescriptorSetLayouts[DescriptorSetIndex::Texture],
1999*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSets[DescriptorSetIndex::Texture]));
2000*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDescriptorSets[DescriptorSetIndex::Texture]);
2001*8975f5c5SAndroid Build Coastguard Worker
2002*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(UpdateFullTexturesDescriptorSet(
2003*8975f5c5SAndroid Build Coastguard Worker context, mVariableInfoMap, mTextureWriteDescriptorDescs, updateBuilder, *mExecutable,
2004*8975f5c5SAndroid Build Coastguard Worker textures, samplers, mDescriptorSets[DescriptorSetIndex::Texture]->getDescriptorSet()));
2005*8975f5c5SAndroid Build Coastguard Worker }
2006*8975f5c5SAndroid Build Coastguard Worker
2007*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2008*8975f5c5SAndroid Build Coastguard Worker }
2009*8975f5c5SAndroid Build Coastguard Worker
2010*8975f5c5SAndroid Build Coastguard Worker template <typename CommandBufferT>
bindDescriptorSets(vk::Context * context,uint32_t currentFrame,vk::CommandBufferHelperCommon * commandBufferHelper,CommandBufferT * commandBuffer,PipelineType pipelineType)2011*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::bindDescriptorSets(
2012*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
2013*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
2014*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
2015*8975f5c5SAndroid Build Coastguard Worker CommandBufferT *commandBuffer,
2016*8975f5c5SAndroid Build Coastguard Worker PipelineType pipelineType)
2017*8975f5c5SAndroid Build Coastguard Worker {
2018*8975f5c5SAndroid Build Coastguard Worker // Can probably use better dirty bits here.
2019*8975f5c5SAndroid Build Coastguard Worker
2020*8975f5c5SAndroid Build Coastguard Worker // Find the maximum non-null descriptor set. This is used in conjunction with a driver
2021*8975f5c5SAndroid Build Coastguard Worker // workaround to bind empty descriptor sets only for gaps in between 0 and max and avoid
2022*8975f5c5SAndroid Build Coastguard Worker // binding unnecessary empty descriptor sets for the sets beyond max.
2023*8975f5c5SAndroid Build Coastguard Worker DescriptorSetIndex lastNonNullDescriptorSetIndex = DescriptorSetIndex::InvalidEnum;
2024*8975f5c5SAndroid Build Coastguard Worker for (DescriptorSetIndex descriptorSetIndex : angle::AllEnums<DescriptorSetIndex>())
2025*8975f5c5SAndroid Build Coastguard Worker {
2026*8975f5c5SAndroid Build Coastguard Worker if (mDescriptorSets[descriptorSetIndex])
2027*8975f5c5SAndroid Build Coastguard Worker {
2028*8975f5c5SAndroid Build Coastguard Worker lastNonNullDescriptorSetIndex = descriptorSetIndex;
2029*8975f5c5SAndroid Build Coastguard Worker }
2030*8975f5c5SAndroid Build Coastguard Worker }
2031*8975f5c5SAndroid Build Coastguard Worker
2032*8975f5c5SAndroid Build Coastguard Worker const VkPipelineBindPoint pipelineBindPoint = pipelineType == PipelineType::Compute
2033*8975f5c5SAndroid Build Coastguard Worker ? VK_PIPELINE_BIND_POINT_COMPUTE
2034*8975f5c5SAndroid Build Coastguard Worker : VK_PIPELINE_BIND_POINT_GRAPHICS;
2035*8975f5c5SAndroid Build Coastguard Worker
2036*8975f5c5SAndroid Build Coastguard Worker for (DescriptorSetIndex descriptorSetIndex : angle::AllEnums<DescriptorSetIndex>())
2037*8975f5c5SAndroid Build Coastguard Worker {
2038*8975f5c5SAndroid Build Coastguard Worker if (ToUnderlying(descriptorSetIndex) > ToUnderlying(lastNonNullDescriptorSetIndex))
2039*8975f5c5SAndroid Build Coastguard Worker {
2040*8975f5c5SAndroid Build Coastguard Worker continue;
2041*8975f5c5SAndroid Build Coastguard Worker }
2042*8975f5c5SAndroid Build Coastguard Worker
2043*8975f5c5SAndroid Build Coastguard Worker if (!mDescriptorSets[descriptorSetIndex])
2044*8975f5c5SAndroid Build Coastguard Worker {
2045*8975f5c5SAndroid Build Coastguard Worker continue;
2046*8975f5c5SAndroid Build Coastguard Worker }
2047*8975f5c5SAndroid Build Coastguard Worker
2048*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descSet = mDescriptorSets[descriptorSetIndex]->getDescriptorSet();
2049*8975f5c5SAndroid Build Coastguard Worker ASSERT(descSet != VK_NULL_HANDLE);
2050*8975f5c5SAndroid Build Coastguard Worker
2051*8975f5c5SAndroid Build Coastguard Worker // Default uniforms are encompassed in a block per shader stage, and they are assigned
2052*8975f5c5SAndroid Build Coastguard Worker // through dynamic uniform buffers (requiring dynamic offsets). No other descriptor
2053*8975f5c5SAndroid Build Coastguard Worker // requires a dynamic offset.
2054*8975f5c5SAndroid Build Coastguard Worker if (descriptorSetIndex == DescriptorSetIndex::UniformsAndXfb)
2055*8975f5c5SAndroid Build Coastguard Worker {
2056*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindDescriptorSets(
2057*8975f5c5SAndroid Build Coastguard Worker getPipelineLayout(), pipelineBindPoint, descriptorSetIndex, 1, &descSet,
2058*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(mDynamicUniformDescriptorOffsets.size()),
2059*8975f5c5SAndroid Build Coastguard Worker mDynamicUniformDescriptorOffsets.data());
2060*8975f5c5SAndroid Build Coastguard Worker }
2061*8975f5c5SAndroid Build Coastguard Worker else if (descriptorSetIndex == DescriptorSetIndex::ShaderResource)
2062*8975f5c5SAndroid Build Coastguard Worker {
2063*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindDescriptorSets(
2064*8975f5c5SAndroid Build Coastguard Worker getPipelineLayout(), pipelineBindPoint, descriptorSetIndex, 1, &descSet,
2065*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(mDynamicShaderResourceDescriptorOffsets.size()),
2066*8975f5c5SAndroid Build Coastguard Worker mDynamicShaderResourceDescriptorOffsets.data());
2067*8975f5c5SAndroid Build Coastguard Worker }
2068*8975f5c5SAndroid Build Coastguard Worker else
2069*8975f5c5SAndroid Build Coastguard Worker {
2070*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindDescriptorSets(getPipelineLayout(), pipelineBindPoint,
2071*8975f5c5SAndroid Build Coastguard Worker descriptorSetIndex, 1, &descSet, 0, nullptr);
2072*8975f5c5SAndroid Build Coastguard Worker }
2073*8975f5c5SAndroid Build Coastguard Worker
2074*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(mDescriptorSets[descriptorSetIndex].get());
2075*8975f5c5SAndroid Build Coastguard Worker mDescriptorSets[descriptorSetIndex]->updateLastUsedFrame(currentFrame);
2076*8975f5c5SAndroid Build Coastguard Worker }
2077*8975f5c5SAndroid Build Coastguard Worker
2078*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2079*8975f5c5SAndroid Build Coastguard Worker }
2080*8975f5c5SAndroid Build Coastguard Worker
2081*8975f5c5SAndroid Build Coastguard Worker template angle::Result ProgramExecutableVk::bindDescriptorSets<vk::priv::SecondaryCommandBuffer>(
2082*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
2083*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
2084*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
2085*8975f5c5SAndroid Build Coastguard Worker vk::priv::SecondaryCommandBuffer *commandBuffer,
2086*8975f5c5SAndroid Build Coastguard Worker PipelineType pipelineType);
2087*8975f5c5SAndroid Build Coastguard Worker template angle::Result ProgramExecutableVk::bindDescriptorSets<vk::VulkanSecondaryCommandBuffer>(
2088*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
2089*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
2090*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
2091*8975f5c5SAndroid Build Coastguard Worker vk::VulkanSecondaryCommandBuffer *commandBuffer,
2092*8975f5c5SAndroid Build Coastguard Worker PipelineType pipelineType);
2093*8975f5c5SAndroid Build Coastguard Worker
setAllDefaultUniformsDirty()2094*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setAllDefaultUniformsDirty()
2095*8975f5c5SAndroid Build Coastguard Worker {
2096*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformBlocksDirty.reset();
2097*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
2098*8975f5c5SAndroid Build Coastguard Worker {
2099*8975f5c5SAndroid Build Coastguard Worker if (!mDefaultUniformBlocks[shaderType]->uniformData.empty())
2100*8975f5c5SAndroid Build Coastguard Worker {
2101*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformBlocksDirty.set(shaderType);
2102*8975f5c5SAndroid Build Coastguard Worker }
2103*8975f5c5SAndroid Build Coastguard Worker }
2104*8975f5c5SAndroid Build Coastguard Worker }
2105*8975f5c5SAndroid Build Coastguard Worker
updateUniforms(vk::Context * context,uint32_t currentFrame,UpdateDescriptorSetsBuilder * updateBuilder,vk::BufferHelper * emptyBuffer,vk::DynamicBuffer * defaultUniformStorage,bool isTransformFeedbackActiveUnpaused,TransformFeedbackVk * transformFeedbackVk)2106*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::updateUniforms(vk::Context *context,
2107*8975f5c5SAndroid Build Coastguard Worker uint32_t currentFrame,
2108*8975f5c5SAndroid Build Coastguard Worker UpdateDescriptorSetsBuilder *updateBuilder,
2109*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *emptyBuffer,
2110*8975f5c5SAndroid Build Coastguard Worker vk::DynamicBuffer *defaultUniformStorage,
2111*8975f5c5SAndroid Build Coastguard Worker bool isTransformFeedbackActiveUnpaused,
2112*8975f5c5SAndroid Build Coastguard Worker TransformFeedbackVk *transformFeedbackVk)
2113*8975f5c5SAndroid Build Coastguard Worker {
2114*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDefaultUniformBlocksDirty.any());
2115*8975f5c5SAndroid Build Coastguard Worker
2116*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *defaultUniformBuffer;
2117*8975f5c5SAndroid Build Coastguard Worker bool anyNewBufferAllocated = false;
2118*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<VkDeviceSize> offsets = {}; // offset to the beginning of bufferData
2119*8975f5c5SAndroid Build Coastguard Worker uint32_t offsetIndex = 0;
2120*8975f5c5SAndroid Build Coastguard Worker size_t requiredSpace;
2121*8975f5c5SAndroid Build Coastguard Worker
2122*8975f5c5SAndroid Build Coastguard Worker // We usually only update uniform data for shader stages that are actually dirty. But when the
2123*8975f5c5SAndroid Build Coastguard Worker // buffer for uniform data have switched, because all shader stages are using the same buffer,
2124*8975f5c5SAndroid Build Coastguard Worker // we then must update uniform data for all shader stages to keep all shader stages' uniform
2125*8975f5c5SAndroid Build Coastguard Worker // data in the same buffer.
2126*8975f5c5SAndroid Build Coastguard Worker requiredSpace = calcUniformUpdateRequiredSpace(context, &offsets);
2127*8975f5c5SAndroid Build Coastguard Worker ASSERT(requiredSpace > 0);
2128*8975f5c5SAndroid Build Coastguard Worker
2129*8975f5c5SAndroid Build Coastguard Worker // Allocate space from dynamicBuffer. Always try to allocate from the current buffer first.
2130*8975f5c5SAndroid Build Coastguard Worker // If that failed, we deal with fall out and try again.
2131*8975f5c5SAndroid Build Coastguard Worker if (!defaultUniformStorage->allocateFromCurrentBuffer(requiredSpace, &defaultUniformBuffer))
2132*8975f5c5SAndroid Build Coastguard Worker {
2133*8975f5c5SAndroid Build Coastguard Worker setAllDefaultUniformsDirty();
2134*8975f5c5SAndroid Build Coastguard Worker
2135*8975f5c5SAndroid Build Coastguard Worker requiredSpace = calcUniformUpdateRequiredSpace(context, &offsets);
2136*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(defaultUniformStorage->allocate(context, requiredSpace, &defaultUniformBuffer,
2137*8975f5c5SAndroid Build Coastguard Worker &anyNewBufferAllocated));
2138*8975f5c5SAndroid Build Coastguard Worker }
2139*8975f5c5SAndroid Build Coastguard Worker
2140*8975f5c5SAndroid Build Coastguard Worker ASSERT(defaultUniformBuffer);
2141*8975f5c5SAndroid Build Coastguard Worker
2142*8975f5c5SAndroid Build Coastguard Worker uint8_t *bufferData = defaultUniformBuffer->getMappedMemory();
2143*8975f5c5SAndroid Build Coastguard Worker VkDeviceSize bufferOffset = defaultUniformBuffer->getOffset();
2144*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
2145*8975f5c5SAndroid Build Coastguard Worker {
2146*8975f5c5SAndroid Build Coastguard Worker if (mDefaultUniformBlocksDirty[shaderType])
2147*8975f5c5SAndroid Build Coastguard Worker {
2148*8975f5c5SAndroid Build Coastguard Worker const angle::MemoryBuffer &uniformData = mDefaultUniformBlocks[shaderType]->uniformData;
2149*8975f5c5SAndroid Build Coastguard Worker memcpy(&bufferData[offsets[shaderType]], uniformData.data(), uniformData.size());
2150*8975f5c5SAndroid Build Coastguard Worker mDynamicUniformDescriptorOffsets[offsetIndex] =
2151*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(bufferOffset + offsets[shaderType]);
2152*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformBlocksDirty.reset(shaderType);
2153*8975f5c5SAndroid Build Coastguard Worker }
2154*8975f5c5SAndroid Build Coastguard Worker ++offsetIndex;
2155*8975f5c5SAndroid Build Coastguard Worker }
2156*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(defaultUniformBuffer->flush(context->getRenderer()));
2157*8975f5c5SAndroid Build Coastguard Worker
2158*8975f5c5SAndroid Build Coastguard Worker // Because the uniform buffers are per context, we can't rely on dynamicBuffer's allocate
2159*8975f5c5SAndroid Build Coastguard Worker // function to tell us if you have got a new buffer or not. Other program's use of the buffer
2160*8975f5c5SAndroid Build Coastguard Worker // might already pushed dynamicBuffer to a new buffer. We record which buffer (represented by
2161*8975f5c5SAndroid Build Coastguard Worker // the unique BufferSerial number) we were using with the current descriptor set and then we
2162*8975f5c5SAndroid Build Coastguard Worker // use that recorded BufferSerial compare to the current uniform buffer to quickly detect if
2163*8975f5c5SAndroid Build Coastguard Worker // there is a buffer switch or not. We need to retrieve from the descriptor set cache or
2164*8975f5c5SAndroid Build Coastguard Worker // allocate a new descriptor set whenever there is uniform buffer switch.
2165*8975f5c5SAndroid Build Coastguard Worker if (mCurrentDefaultUniformBufferSerial != defaultUniformBuffer->getBufferSerial())
2166*8975f5c5SAndroid Build Coastguard Worker {
2167*8975f5c5SAndroid Build Coastguard Worker // We need to reinitialize the descriptor sets if we newly allocated buffers since we can't
2168*8975f5c5SAndroid Build Coastguard Worker // modify the descriptor sets once initialized.
2169*8975f5c5SAndroid Build Coastguard Worker const vk::WriteDescriptorDescs &writeDescriptorDescs =
2170*8975f5c5SAndroid Build Coastguard Worker getDefaultUniformWriteDescriptorDescs(transformFeedbackVk);
2171*8975f5c5SAndroid Build Coastguard Worker
2172*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetDescBuilder uniformsAndXfbDesc(
2173*8975f5c5SAndroid Build Coastguard Worker writeDescriptorDescs.getTotalDescriptorCount());
2174*8975f5c5SAndroid Build Coastguard Worker uniformsAndXfbDesc.updateUniformsAndXfb(
2175*8975f5c5SAndroid Build Coastguard Worker context, *mExecutable, writeDescriptorDescs, defaultUniformBuffer, *emptyBuffer,
2176*8975f5c5SAndroid Build Coastguard Worker isTransformFeedbackActiveUnpaused,
2177*8975f5c5SAndroid Build Coastguard Worker mExecutable->hasTransformFeedbackOutput() ? transformFeedbackVk : nullptr);
2178*8975f5c5SAndroid Build Coastguard Worker
2179*8975f5c5SAndroid Build Coastguard Worker vk::SharedDescriptorSetCacheKey newSharedCacheKey;
2180*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateUniformsAndXfbDescriptorSet(context, currentFrame, updateBuilder,
2181*8975f5c5SAndroid Build Coastguard Worker writeDescriptorDescs, defaultUniformBuffer,
2182*8975f5c5SAndroid Build Coastguard Worker &uniformsAndXfbDesc, &newSharedCacheKey));
2183*8975f5c5SAndroid Build Coastguard Worker if (newSharedCacheKey)
2184*8975f5c5SAndroid Build Coastguard Worker {
2185*8975f5c5SAndroid Build Coastguard Worker defaultUniformBuffer->getBufferBlock()->onNewDescriptorSet(newSharedCacheKey);
2186*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->hasTransformFeedbackOutput() &&
2187*8975f5c5SAndroid Build Coastguard Worker context->getFeatures().emulateTransformFeedback.enabled)
2188*8975f5c5SAndroid Build Coastguard Worker {
2189*8975f5c5SAndroid Build Coastguard Worker transformFeedbackVk->onNewDescriptorSet(*mExecutable, newSharedCacheKey);
2190*8975f5c5SAndroid Build Coastguard Worker }
2191*8975f5c5SAndroid Build Coastguard Worker }
2192*8975f5c5SAndroid Build Coastguard Worker }
2193*8975f5c5SAndroid Build Coastguard Worker
2194*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2195*8975f5c5SAndroid Build Coastguard Worker }
2196*8975f5c5SAndroid Build Coastguard Worker
calcUniformUpdateRequiredSpace(vk::Context * context,gl::ShaderMap<VkDeviceSize> * uniformOffsets) const2197*8975f5c5SAndroid Build Coastguard Worker size_t ProgramExecutableVk::calcUniformUpdateRequiredSpace(
2198*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
2199*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<VkDeviceSize> *uniformOffsets) const
2200*8975f5c5SAndroid Build Coastguard Worker {
2201*8975f5c5SAndroid Build Coastguard Worker size_t requiredSpace = 0;
2202*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
2203*8975f5c5SAndroid Build Coastguard Worker {
2204*8975f5c5SAndroid Build Coastguard Worker if (mDefaultUniformBlocksDirty[shaderType])
2205*8975f5c5SAndroid Build Coastguard Worker {
2206*8975f5c5SAndroid Build Coastguard Worker (*uniformOffsets)[shaderType] = requiredSpace;
2207*8975f5c5SAndroid Build Coastguard Worker requiredSpace += getDefaultUniformAlignedSize(context, shaderType);
2208*8975f5c5SAndroid Build Coastguard Worker }
2209*8975f5c5SAndroid Build Coastguard Worker }
2210*8975f5c5SAndroid Build Coastguard Worker return requiredSpace;
2211*8975f5c5SAndroid Build Coastguard Worker }
2212*8975f5c5SAndroid Build Coastguard Worker
onProgramBind()2213*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::onProgramBind()
2214*8975f5c5SAndroid Build Coastguard Worker {
2215*8975f5c5SAndroid Build Coastguard Worker // Because all programs share default uniform buffers, when we switch programs, we have to
2216*8975f5c5SAndroid Build Coastguard Worker // re-update all uniform data. We could do more tracking to avoid update if the context's
2217*8975f5c5SAndroid Build Coastguard Worker // current uniform buffer is still the same buffer we last time used and buffer has not been
2218*8975f5c5SAndroid Build Coastguard Worker // recycled. But statistics gathered on gfxbench shows that app always update uniform data on
2219*8975f5c5SAndroid Build Coastguard Worker // program bind anyway, so not really worth it to add more tracking logic here.
2220*8975f5c5SAndroid Build Coastguard Worker //
2221*8975f5c5SAndroid Build Coastguard Worker // Note: if this is changed, PPO uniform checks need to be updated as well
2222*8975f5c5SAndroid Build Coastguard Worker setAllDefaultUniformsDirty();
2223*8975f5c5SAndroid Build Coastguard Worker }
2224*8975f5c5SAndroid Build Coastguard Worker
resizeUniformBlockMemory(vk::Context * context,const gl::ShaderMap<size_t> & requiredBufferSize)2225*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableVk::resizeUniformBlockMemory(
2226*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
2227*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<size_t> &requiredBufferSize)
2228*8975f5c5SAndroid Build Coastguard Worker {
2229*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
2230*8975f5c5SAndroid Build Coastguard Worker {
2231*8975f5c5SAndroid Build Coastguard Worker if (requiredBufferSize[shaderType] > 0)
2232*8975f5c5SAndroid Build Coastguard Worker {
2233*8975f5c5SAndroid Build Coastguard Worker if (!mDefaultUniformBlocks[shaderType]->uniformData.resize(
2234*8975f5c5SAndroid Build Coastguard Worker requiredBufferSize[shaderType]))
2235*8975f5c5SAndroid Build Coastguard Worker {
2236*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_CHECK(context, false, VK_ERROR_OUT_OF_HOST_MEMORY);
2237*8975f5c5SAndroid Build Coastguard Worker }
2238*8975f5c5SAndroid Build Coastguard Worker
2239*8975f5c5SAndroid Build Coastguard Worker // Initialize uniform buffer memory to zero by default.
2240*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformBlocks[shaderType]->uniformData.fill(0);
2241*8975f5c5SAndroid Build Coastguard Worker mDefaultUniformBlocksDirty.set(shaderType);
2242*8975f5c5SAndroid Build Coastguard Worker }
2243*8975f5c5SAndroid Build Coastguard Worker }
2244*8975f5c5SAndroid Build Coastguard Worker
2245*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2246*8975f5c5SAndroid Build Coastguard Worker }
2247*8975f5c5SAndroid Build Coastguard Worker
setUniform1fv(GLint location,GLsizei count,const GLfloat * v)2248*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
2249*8975f5c5SAndroid Build Coastguard Worker {
2250*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_FLOAT, &mDefaultUniformBlocks,
2251*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2252*8975f5c5SAndroid Build Coastguard Worker }
2253*8975f5c5SAndroid Build Coastguard Worker
setUniform2fv(GLint location,GLsizei count,const GLfloat * v)2254*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
2255*8975f5c5SAndroid Build Coastguard Worker {
2256*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC2, &mDefaultUniformBlocks,
2257*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2258*8975f5c5SAndroid Build Coastguard Worker }
2259*8975f5c5SAndroid Build Coastguard Worker
setUniform3fv(GLint location,GLsizei count,const GLfloat * v)2260*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
2261*8975f5c5SAndroid Build Coastguard Worker {
2262*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC3, &mDefaultUniformBlocks,
2263*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2264*8975f5c5SAndroid Build Coastguard Worker }
2265*8975f5c5SAndroid Build Coastguard Worker
setUniform4fv(GLint location,GLsizei count,const GLfloat * v)2266*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
2267*8975f5c5SAndroid Build Coastguard Worker {
2268*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC4, &mDefaultUniformBlocks,
2269*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2270*8975f5c5SAndroid Build Coastguard Worker }
2271*8975f5c5SAndroid Build Coastguard Worker
setUniform1iv(GLint location,GLsizei count,const GLint * v)2272*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
2273*8975f5c5SAndroid Build Coastguard Worker {
2274*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = mExecutable->getUniformLocations()[location];
2275*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &linkedUniform = mExecutable->getUniforms()[locationInfo.index];
2276*8975f5c5SAndroid Build Coastguard Worker if (linkedUniform.isSampler())
2277*8975f5c5SAndroid Build Coastguard Worker {
2278*8975f5c5SAndroid Build Coastguard Worker // We could potentially cache some indexing here. For now this is a no-op since the mapping
2279*8975f5c5SAndroid Build Coastguard Worker // is handled entirely in ContextVk.
2280*8975f5c5SAndroid Build Coastguard Worker return;
2281*8975f5c5SAndroid Build Coastguard Worker }
2282*8975f5c5SAndroid Build Coastguard Worker
2283*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_INT, &mDefaultUniformBlocks,
2284*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2285*8975f5c5SAndroid Build Coastguard Worker }
2286*8975f5c5SAndroid Build Coastguard Worker
setUniform2iv(GLint location,GLsizei count,const GLint * v)2287*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
2288*8975f5c5SAndroid Build Coastguard Worker {
2289*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_INT_VEC2, &mDefaultUniformBlocks,
2290*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2291*8975f5c5SAndroid Build Coastguard Worker }
2292*8975f5c5SAndroid Build Coastguard Worker
setUniform3iv(GLint location,GLsizei count,const GLint * v)2293*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
2294*8975f5c5SAndroid Build Coastguard Worker {
2295*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_INT_VEC3, &mDefaultUniformBlocks,
2296*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2297*8975f5c5SAndroid Build Coastguard Worker }
2298*8975f5c5SAndroid Build Coastguard Worker
setUniform4iv(GLint location,GLsizei count,const GLint * v)2299*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
2300*8975f5c5SAndroid Build Coastguard Worker {
2301*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_INT_VEC4, &mDefaultUniformBlocks,
2302*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2303*8975f5c5SAndroid Build Coastguard Worker }
2304*8975f5c5SAndroid Build Coastguard Worker
setUniform1uiv(GLint location,GLsizei count,const GLuint * v)2305*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
2306*8975f5c5SAndroid Build Coastguard Worker {
2307*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT, &mDefaultUniformBlocks,
2308*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2309*8975f5c5SAndroid Build Coastguard Worker }
2310*8975f5c5SAndroid Build Coastguard Worker
setUniform2uiv(GLint location,GLsizei count,const GLuint * v)2311*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
2312*8975f5c5SAndroid Build Coastguard Worker {
2313*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC2, &mDefaultUniformBlocks,
2314*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2315*8975f5c5SAndroid Build Coastguard Worker }
2316*8975f5c5SAndroid Build Coastguard Worker
setUniform3uiv(GLint location,GLsizei count,const GLuint * v)2317*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
2318*8975f5c5SAndroid Build Coastguard Worker {
2319*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC3, &mDefaultUniformBlocks,
2320*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2321*8975f5c5SAndroid Build Coastguard Worker }
2322*8975f5c5SAndroid Build Coastguard Worker
setUniform4uiv(GLint location,GLsizei count,const GLuint * v)2323*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
2324*8975f5c5SAndroid Build Coastguard Worker {
2325*8975f5c5SAndroid Build Coastguard Worker SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC4, &mDefaultUniformBlocks,
2326*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2327*8975f5c5SAndroid Build Coastguard Worker }
2328*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2329*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix2fv(GLint location,
2330*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2331*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2332*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2333*8975f5c5SAndroid Build Coastguard Worker {
2334*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<2, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2335*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2336*8975f5c5SAndroid Build Coastguard Worker }
2337*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2338*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix3fv(GLint location,
2339*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2340*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2341*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2342*8975f5c5SAndroid Build Coastguard Worker {
2343*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<3, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2344*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2345*8975f5c5SAndroid Build Coastguard Worker }
2346*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2347*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix4fv(GLint location,
2348*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2349*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2350*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2351*8975f5c5SAndroid Build Coastguard Worker {
2352*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<4, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2353*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2354*8975f5c5SAndroid Build Coastguard Worker }
2355*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2356*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix2x3fv(GLint location,
2357*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2358*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2359*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2360*8975f5c5SAndroid Build Coastguard Worker {
2361*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<2, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2362*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2363*8975f5c5SAndroid Build Coastguard Worker }
2364*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2365*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix3x2fv(GLint location,
2366*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2367*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2368*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2369*8975f5c5SAndroid Build Coastguard Worker {
2370*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<3, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2371*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2372*8975f5c5SAndroid Build Coastguard Worker }
2373*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2374*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix2x4fv(GLint location,
2375*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2376*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2377*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2378*8975f5c5SAndroid Build Coastguard Worker {
2379*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<2, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2380*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2381*8975f5c5SAndroid Build Coastguard Worker }
2382*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2383*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix4x2fv(GLint location,
2384*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2385*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2386*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2387*8975f5c5SAndroid Build Coastguard Worker {
2388*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<4, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2389*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2390*8975f5c5SAndroid Build Coastguard Worker }
2391*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2392*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix3x4fv(GLint location,
2393*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2394*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2395*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2396*8975f5c5SAndroid Build Coastguard Worker {
2397*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<3, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2398*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2399*8975f5c5SAndroid Build Coastguard Worker }
2400*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2401*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::setUniformMatrix4x3fv(GLint location,
2402*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2403*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2404*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2405*8975f5c5SAndroid Build Coastguard Worker {
2406*8975f5c5SAndroid Build Coastguard Worker SetUniformMatrixfv<4, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
2407*8975f5c5SAndroid Build Coastguard Worker &mDefaultUniformBlocksDirty);
2408*8975f5c5SAndroid Build Coastguard Worker }
2409*8975f5c5SAndroid Build Coastguard Worker
getUniformfv(const gl::Context * context,GLint location,GLfloat * params) const2410*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::getUniformfv(const gl::Context *context,
2411*8975f5c5SAndroid Build Coastguard Worker GLint location,
2412*8975f5c5SAndroid Build Coastguard Worker GLfloat *params) const
2413*8975f5c5SAndroid Build Coastguard Worker {
2414*8975f5c5SAndroid Build Coastguard Worker GetUniform(mExecutable, location, params, GL_FLOAT, &mDefaultUniformBlocks);
2415*8975f5c5SAndroid Build Coastguard Worker }
2416*8975f5c5SAndroid Build Coastguard Worker
getUniformiv(const gl::Context * context,GLint location,GLint * params) const2417*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::getUniformiv(const gl::Context *context,
2418*8975f5c5SAndroid Build Coastguard Worker GLint location,
2419*8975f5c5SAndroid Build Coastguard Worker GLint *params) const
2420*8975f5c5SAndroid Build Coastguard Worker {
2421*8975f5c5SAndroid Build Coastguard Worker GetUniform(mExecutable, location, params, GL_INT, &mDefaultUniformBlocks);
2422*8975f5c5SAndroid Build Coastguard Worker }
2423*8975f5c5SAndroid Build Coastguard Worker
getUniformuiv(const gl::Context * context,GLint location,GLuint * params) const2424*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableVk::getUniformuiv(const gl::Context *context,
2425*8975f5c5SAndroid Build Coastguard Worker GLint location,
2426*8975f5c5SAndroid Build Coastguard Worker GLuint *params) const
2427*8975f5c5SAndroid Build Coastguard Worker {
2428*8975f5c5SAndroid Build Coastguard Worker GetUniform(mExecutable, location, params, GL_UNSIGNED_INT, &mDefaultUniformBlocks);
2429*8975f5c5SAndroid Build Coastguard Worker }
2430*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
2431