blob: 51c8a47f4ce222f02b1e5a2f11c7203ab12d6a64 [file] [log] [blame]
jvanverth992ad362016-02-26 09:21:02 -08001/*
2* Copyright 2016 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
Greg Daniel37fd6582020-09-14 12:36:09 -04008#include "src/gpu/vk/GrVkPipelineStateBuilder.h"
9
Adlai Holler3d0359a2020-07-09 15:35:55 -040010#include "include/gpu/GrDirectContext.h"
John Stilesf2c2d302021-04-09 17:56:58 -040011#include "src/core/SkReadBuffer.h"
Brian Osman43542fc2020-04-02 10:38:16 -040012#include "src/core/SkTraceEvent.h"
Ethan Nicholasb6538132019-10-22 16:00:18 -040013#include "src/gpu/GrAutoLocaleSetter.h"
Adlai Hollera0693042020-10-14 11:23:11 -040014#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrPersistentCacheUtils.h"
16#include "src/gpu/GrShaderCaps.h"
Brian Osmanac9be9d2019-05-01 10:29:34 -040017#include "src/gpu/GrShaderUtils.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/GrStencilSettings.h"
19#include "src/gpu/vk/GrVkDescriptorSetManager.h"
20#include "src/gpu/vk/GrVkGpu.h"
Greg Daniel3ef052c2021-01-05 12:20:27 -050021#include "src/gpu/vk/GrVkPipeline.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/gpu/vk/GrVkRenderPass.h"
23#include "src/gpu/vk/GrVkRenderTarget.h"
jvanverth992ad362016-02-26 09:21:02 -080024
egdaniel22281c12016-03-23 13:49:40 -070025GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
Brian Salomon1471df92018-06-08 10:49:00 -040026 GrVkGpu* gpu,
Stephen Whiteb1857852020-02-07 15:33:23 +000027 const GrProgramDesc& desc,
Robert Phillips901aff02019-10-08 12:32:56 -040028 const GrProgramInfo& programInfo,
Greg Daniel91b37b12021-01-05 15:40:54 -050029 VkRenderPass compatibleRenderPass,
30 bool overrideSubpassForResolveLoad) {
Robert Phillipsf497c362020-05-12 10:35:18 -040031
Robert Phillipsae67c522021-03-03 11:03:38 -050032 GrVkResourceProvider& resourceProvider = gpu->resourceProvider();
33
34 resourceProvider.pipelineStateCache()->stats()->incShaderCompilations();
Robert Phillipsf497c362020-05-12 10:35:18 -040035
Ethan Nicholasb6538132019-10-22 16:00:18 -040036 // ensure that we use "." as a decimal separator when creating SkSL code
37 GrAutoLocaleSetter als("C");
38
jvanverth992ad362016-02-26 09:21:02 -080039 // create a builder. This will be handed off to effects so they can use it to add
40 // uniforms, varyings, textures, etc
Greg Daniel374f96c2021-04-21 10:32:34 -040041 GrVkPipelineStateBuilder builder(gpu, desc, programInfo);
jvanverth992ad362016-02-26 09:21:02 -080042
Ethan Nicholas2983f402017-05-08 09:36:08 -040043 if (!builder.emitAndInstallProcs()) {
jvanverth992ad362016-02-26 09:21:02 -080044 return nullptr;
45 }
46
Greg Daniel91b37b12021-01-05 15:40:54 -050047 return builder.finalize(desc, compatibleRenderPass, overrideSubpassForResolveLoad);
jvanverth992ad362016-02-26 09:21:02 -080048}
49
egdaniel22281c12016-03-23 13:49:40 -070050GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
Stephen Whiteb1857852020-02-07 15:33:23 +000051 const GrProgramDesc& desc,
52 const GrProgramInfo& programInfo)
Greg Daniel374f96c2021-04-21 10:32:34 -040053 : INHERITED(desc, programInfo)
Brian Salomonff168d92018-06-23 15:17:27 -040054 , fGpu(gpu)
55 , fVaryingHandler(this)
56 , fUniformHandler(this) {}
jvanverth992ad362016-02-26 09:21:02 -080057
egdaniel22281c12016-03-23 13:49:40 -070058const GrCaps* GrVkPipelineStateBuilder::caps() const {
jvanverth992ad362016-02-26 09:21:02 -080059 return fGpu->caps();
60}
jvanverth992ad362016-02-26 09:21:02 -080061
Ethan Nicholasee9cb6a2021-02-02 11:59:09 -050062SkSL::Compiler* GrVkPipelineStateBuilder::shaderCompiler() const {
63 return fGpu->shaderCompiler();
64}
65
Brian Salomon99938a82016-11-21 13:41:08 -050066void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050067 outputColor.addLayoutQualifier("location = 0, index = 0");
jvanverth992ad362016-02-26 09:21:02 -080068}
69
Brian Salomon99938a82016-11-21 13:41:08 -050070void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050071 outputColor.addLayoutQualifier("location = 0, index = 1");
egdanield632bb42016-03-30 12:06:48 -070072}
73
Ethan Nicholas941e7e22016-12-12 15:33:30 -050074bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage,
Brian Osmanfd7657c2019-04-25 11:34:07 -040075 const SkSL::String& sksl,
egdaniel22281c12016-03-23 13:49:40 -070076 VkShaderModule* shaderModule,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050077 VkPipelineShaderStageCreateInfo* stageInfo,
Ethan Nicholas38657112017-02-09 17:01:22 -050078 const SkSL::Program::Settings& settings,
Ethan Nicholas92e01cf2018-12-19 13:12:10 -050079 SkSL::String* outSPIRV,
80 SkSL::Program::Inputs* outInputs) {
Brian Osmanfd7657c2019-04-25 11:34:07 -040081 if (!GrCompileVkShaderModule(fGpu, sksl, stage, shaderModule,
Ethan Nicholas92e01cf2018-12-19 13:12:10 -050082 stageInfo, settings, outSPIRV, outInputs)) {
83 return false;
84 }
Brian Salomond8d85b92021-07-07 09:41:17 -040085 if (outInputs->fUseFlipRTUniform) {
86 this->addRTFlipUniform(SKSL_RTFLIP_NAME);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -050087 }
Ethan Nicholas92e01cf2018-12-19 13:12:10 -050088 return true;
89}
90
91bool GrVkPipelineStateBuilder::installVkShaderModule(VkShaderStageFlagBits stage,
92 const GrGLSLShaderBuilder& builder,
93 VkShaderModule* shaderModule,
94 VkPipelineShaderStageCreateInfo* stageInfo,
95 SkSL::String spirv,
96 SkSL::Program::Inputs inputs) {
97 if (!GrInstallVkShaderModule(fGpu, spirv, stage, shaderModule, stageInfo)) {
Ethan Nicholas941e7e22016-12-12 15:33:30 -050098 return false;
99 }
Brian Salomond8d85b92021-07-07 09:41:17 -0400100 if (inputs.fUseFlipRTUniform) {
101 this->addRTFlipUniform(SKSL_RTFLIP_NAME);
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500102 }
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500103 return true;
104}
105
Brian Osmana085a412019-04-25 09:44:43 -0400106static constexpr SkFourByteTag kSPIRV_Tag = SkSetFourByteTag('S', 'P', 'R', 'V');
Brian Osmanfd7657c2019-04-25 11:34:07 -0400107static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
Brian Osmana085a412019-04-25 09:44:43 -0400108
Brian Osman9e4e4c72020-06-10 07:19:34 -0400109int GrVkPipelineStateBuilder::loadShadersFromCache(SkReadBuffer* cached,
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400110 VkShaderModule outShaderModules[],
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500111 VkPipelineShaderStageCreateInfo* outStageInfo) {
Brian Osmana5a010b2019-04-08 15:01:32 -0400112 SkSL::String shaders[kGrShaderTypeCount];
113 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500114
Brian Osman9e4e4c72020-06-10 07:19:34 -0400115 if (!GrPersistentCacheUtils::UnpackCachedShaders(cached, shaders, inputs, kGrShaderTypeCount)) {
116 return 0;
117 }
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500118
Brian Osman9e4e4c72020-06-10 07:19:34 -0400119 bool success = this->installVkShaderModule(VK_SHADER_STAGE_VERTEX_BIT,
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500120 fVS,
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400121 &outShaderModules[kVertex_GrShaderType],
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500122 &outStageInfo[0],
Brian Osmana5a010b2019-04-08 15:01:32 -0400123 shaders[kVertex_GrShaderType],
Brian Osman9e4e4c72020-06-10 07:19:34 -0400124 inputs[kVertex_GrShaderType]);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500125
Brian Osman9e4e4c72020-06-10 07:19:34 -0400126 success = success && this->installVkShaderModule(VK_SHADER_STAGE_FRAGMENT_BIT,
127 fFS,
128 &outShaderModules[kFragment_GrShaderType],
129 &outStageInfo[1],
130 shaders[kFragment_GrShaderType],
131 inputs[kFragment_GrShaderType]);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500132
Brian Osman9e4e4c72020-06-10 07:19:34 -0400133 if (!success) {
134 for (int i = 0; i < kGrShaderTypeCount; ++i) {
135 if (outShaderModules[i]) {
136 GR_VK_CALL(fGpu->vkInterface(),
137 DestroyShaderModule(fGpu->device(), outShaderModules[i], nullptr));
138 }
139 }
140 return 0;
141 }
Brian Osman99ddd2a2021-08-27 11:21:12 -0400142 return 2;
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500143}
144
Brian Osmana5a010b2019-04-08 15:01:32 -0400145void GrVkPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
Brian Osmanfd7657c2019-04-25 11:34:07 -0400146 const SkSL::Program::Inputs inputs[],
Brian Osman4524e842019-09-24 16:03:41 -0400147 bool isSkSL) {
Robert Phillipsd5c1f342019-10-14 09:50:05 -0400148 // Here we shear off the Vk-specific portion of the Desc in order to create the
149 // persistent key. This is bc Vk only caches the SPIRV code, not the fully compiled
150 // program, and that only depends on the base GrProgramDesc data.
Robert Phillipsc15e8902019-11-26 14:26:36 -0500151 // The +4 is to include the kShader_PersistentCacheKeyType code the Vulkan backend adds
152 // to the key right after the base key.
Stephen Whiteb1857852020-02-07 15:33:23 +0000153 sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(),
154 this->desc().initialKeyLength()+4);
Robert Phillipsced5e832021-03-23 09:36:53 -0400155 SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
Robert Phillips03e4c952019-11-26 16:20:22 -0500156
Brian Osmanfd7657c2019-04-25 11:34:07 -0400157 sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(isSkSL ? kSKSL_Tag : kSPIRV_Tag,
158 shaders,
Brian Osman4524e842019-09-24 16:03:41 -0400159 inputs, kGrShaderTypeCount);
Brian Osmanf0de96f2021-02-26 13:54:11 -0500160
161 this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data, description);
jvanverth992ad362016-02-26 09:21:02 -0800162}
163
Stephen Whiteb1857852020-02-07 15:33:23 +0000164GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrProgramDesc& desc,
Greg Daniel91b37b12021-01-05 15:40:54 -0500165 VkRenderPass compatibleRenderPass,
166 bool overrideSubpassForResolveLoad) {
Brian Osman7a20b5c2021-03-15 16:23:33 -0400167 TRACE_EVENT0("skia.shaders", TRACE_FUNC);
Brian Osman43542fc2020-04-02 10:38:16 -0400168
Greg Daniel37fd6582020-09-14 12:36:09 -0400169 VkDescriptorSetLayout dsLayout[GrVkUniformHandler::kDescSetCount];
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400170 VkShaderModule shaderModules[kGrShaderTypeCount] = { VK_NULL_HANDLE,
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400171 VK_NULL_HANDLE };
jvanverth992ad362016-02-26 09:21:02 -0800172
egdaniel707bbd62016-07-26 07:19:47 -0700173 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
Jim Van Verth684d7ce2016-11-17 13:30:22 -0500174 // These layouts are not owned by the PipelineStateBuilder and thus should not be destroyed
egdaniel707bbd62016-07-26 07:19:47 -0700175 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
176
177 GrVkDescriptorSetManager::Handle samplerDSHandle;
Greg Daniela7543782017-05-02 14:01:43 -0400178 resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
179 fUniformHandler, &samplerDSHandle);
egdaniel707bbd62016-07-26 07:19:47 -0700180 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
181 resourceProvider.getSamplerDSLayout(samplerDSHandle);
jvanverth992ad362016-02-26 09:21:02 -0800182
Greg Daniel37fd6582020-09-14 12:36:09 -0400183 dsLayout[GrVkUniformHandler::kInputDescSet] = resourceProvider.getInputDSLayout();
184
jvanverth992ad362016-02-26 09:21:02 -0800185 this->finalizeShaders();
186
Jim Van Verth205e99a2021-02-08 18:02:41 -0500187 bool usePushConstants = fUniformHandler.usePushConstants();
Greg Daniel852d7152017-05-08 12:10:12 -0400188 VkPipelineShaderStageCreateInfo shaderStageInfo[3];
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500189 SkSL::Program::Settings settings;
Brian Salomond8d85b92021-07-07 09:41:17 -0400190 settings.fRTFlipBinding = this->gpu()->vkCaps().getFragmentUniformBinding();
191 settings.fRTFlipSet = this->gpu()->vkCaps().getFragmentUniformSet();
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500192 settings.fSharpenTextures =
Robert Phillips9da87e02019-02-04 13:26:26 -0500193 this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
Brian Salomond8d85b92021-07-07 09:41:17 -0400194 settings.fRTFlipOffset = fUniformHandler.getRTFlipOffset();
Jim Van Verth205e99a2021-02-08 18:02:41 -0500195 settings.fUsePushConstants = usePushConstants;
Ethan Nicholas8f352ce2021-03-17 14:12:20 -0400196 if (fFS.fForceHighPrecision) {
197 settings.fForceHighPrecision = true;
198 }
Brian Salomondc092132018-04-04 10:14:16 -0400199 SkASSERT(!this->fragColorIsInOut());
jvanverth992ad362016-02-26 09:21:02 -0800200
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500201 sk_sp<SkData> cached;
Brian Osman9e4e4c72020-06-10 07:19:34 -0400202 SkReadBuffer reader;
Brian Osmana66081d2019-09-03 14:59:26 -0400203 SkFourByteTag shaderType = 0;
Robert Phillips9da87e02019-02-04 13:26:26 -0500204 auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500205 if (persistentCache) {
Robert Phillipsd5c1f342019-10-14 09:50:05 -0400206 // Here we shear off the Vk-specific portion of the Desc in order to create the
207 // persistent key. This is bc Vk only caches the SPIRV code, not the fully compiled
208 // program, and that only depends on the base GrProgramDesc data.
Robert Phillipsc15e8902019-11-26 14:26:36 -0500209 // The +4 is to include the kShader_PersistentCacheKeyType code the Vulkan backend adds
210 // to the key right after the base key.
Stephen Whiteb1857852020-02-07 15:33:23 +0000211 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.initialKeyLength()+4);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500212 cached = persistentCache->load(*key);
Brian Osmana66081d2019-09-03 14:59:26 -0400213 if (cached) {
214 reader.setMemory(cached->data(), cached->size());
Brian Osman1facd5e2020-03-16 16:21:24 -0400215 shaderType = GrPersistentCacheUtils::GetType(&reader);
Brian Osmana66081d2019-09-03 14:59:26 -0400216 }
Brian Osmanfd7657c2019-04-25 11:34:07 -0400217 }
218
Brian Osmana66081d2019-09-03 14:59:26 -0400219 int numShaderStages = 0;
220 if (kSPIRV_Tag == shaderType) {
221 numShaderStages = this->loadShadersFromCache(&reader, shaderModules, shaderStageInfo);
Brian Osman9e4e4c72020-06-10 07:19:34 -0400222 }
223
224 // Proceed from sources if we didn't get a SPIRV cache (or the cache was invalid)
225 if (!numShaderStages) {
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500226 numShaderStages = 2; // We always have at least vertex and fragment stages.
Brian Osmana5a010b2019-04-08 15:01:32 -0400227 SkSL::String shaders[kGrShaderTypeCount];
228 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
Brian Osmanfd7657c2019-04-25 11:34:07 -0400229
230 SkSL::String* sksl[kGrShaderTypeCount] = {
231 &fVS.fCompilerString,
Brian Osmanfd7657c2019-04-25 11:34:07 -0400232 &fFS.fCompilerString,
233 };
Brian Osmanfd7657c2019-04-25 11:34:07 -0400234 SkSL::String cached_sksl[kGrShaderTypeCount];
Brian Osmana66081d2019-09-03 14:59:26 -0400235 if (kSKSL_Tag == shaderType) {
Brian Osman9e4e4c72020-06-10 07:19:34 -0400236 if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs,
237 kGrShaderTypeCount)) {
238 for (int i = 0; i < kGrShaderTypeCount; ++i) {
239 sksl[i] = &cached_sksl[i];
240 }
Brian Osmanfd7657c2019-04-25 11:34:07 -0400241 }
242 }
Brian Osmanfd7657c2019-04-25 11:34:07 -0400243
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400244 bool success = this->createVkShaderModule(VK_SHADER_STAGE_VERTEX_BIT,
Brian Osmanfd7657c2019-04-25 11:34:07 -0400245 *sksl[kVertex_GrShaderType],
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400246 &shaderModules[kVertex_GrShaderType],
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500247 &shaderStageInfo[0],
248 settings,
Brian Osmana5a010b2019-04-08 15:01:32 -0400249 &shaders[kVertex_GrShaderType],
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400250 &inputs[kVertex_GrShaderType]);
Greg Daniel852d7152017-05-08 12:10:12 -0400251
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400252 success = success && this->createVkShaderModule(VK_SHADER_STAGE_FRAGMENT_BIT,
253 *sksl[kFragment_GrShaderType],
254 &shaderModules[kFragment_GrShaderType],
255 &shaderStageInfo[1],
256 settings,
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400257 &shaders[kFragment_GrShaderType],
258 &inputs[kFragment_GrShaderType]);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500259
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400260 if (!success) {
261 for (int i = 0; i < kGrShaderTypeCount; ++i) {
262 if (shaderModules[i]) {
263 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(),
264 shaderModules[i], nullptr));
265 }
266 }
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400267 return nullptr;
268 }
269
Brian Osmanfd7657c2019-04-25 11:34:07 -0400270 if (persistentCache && !cached) {
271 bool isSkSL = false;
Brian Osmana66081d2019-09-03 14:59:26 -0400272 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
273 GrContextOptions::ShaderCacheStrategy::kSkSL) {
Brian Osmanfd7657c2019-04-25 11:34:07 -0400274 for (int i = 0; i < kGrShaderTypeCount; ++i) {
Brian Osmanac9be9d2019-05-01 10:29:34 -0400275 shaders[i] = GrShaderUtils::PrettyPrint(*sksl[i]);
Brian Osmanfd7657c2019-04-25 11:34:07 -0400276 }
277 isSkSL = true;
278 }
Brian Osman4524e842019-09-24 16:03:41 -0400279 this->storeShadersInCache(shaders, inputs, isSkSL);
Ethan Nicholas92e01cf2018-12-19 13:12:10 -0500280 }
281 }
Robert Phillipsa87c5292019-11-12 10:12:42 -0500282
Jim Van Verth205e99a2021-02-08 18:02:41 -0500283 bool usesInput = SkToBool(fProgramInfo.renderPassBarriers() & GrXferBarrierFlags::kTexture);
284 uint32_t layoutCount =
285 usesInput ? GrVkUniformHandler::kDescSetCount : (GrVkUniformHandler::kDescSetCount - 1);
286 // Create the VkPipelineLayout
287 VkPipelineLayoutCreateInfo layoutCreateInfo;
288 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
289 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
290 layoutCreateInfo.pNext = nullptr;
291 layoutCreateInfo.flags = 0;
292 layoutCreateInfo.setLayoutCount = layoutCount;
293 layoutCreateInfo.pSetLayouts = dsLayout;
294 VkPushConstantRange pushConstantRange = {};
295 if (usePushConstants) {
296 pushConstantRange.stageFlags = fGpu->vkCaps().getPushConstantStageFlags();
297 pushConstantRange.offset = 0;
298 // size must be a multiple of 4
299 SkASSERT(!SkToBool(fUniformHandler.currentOffset() & 0x3));
300 pushConstantRange.size = fUniformHandler.currentOffset();
301 layoutCreateInfo.pushConstantRangeCount = 1;
302 layoutCreateInfo.pPushConstantRanges = &pushConstantRange;
303 } else {
304 layoutCreateInfo.pushConstantRangeCount = 0;
305 layoutCreateInfo.pPushConstantRanges = nullptr;
306 }
307
308 VkPipelineLayout pipelineLayout;
309 VkResult result;
310 GR_VK_CALL_RESULT(fGpu, result, CreatePipelineLayout(fGpu->device(), &layoutCreateInfo, nullptr,
311 &pipelineLayout));
312 if (result != VK_SUCCESS) {
313 return nullptr;
314 }
315
Greg Daniel91b37b12021-01-05 15:40:54 -0500316 // For the vast majority of cases we only have one subpass so we default piplines to subpass 0.
317 // However, if we need to load a resolve into msaa attachment for discardable msaa then the
318 // main subpass will be 1.
319 uint32_t subpass = 0;
320 if (overrideSubpassForResolveLoad ||
321 (fProgramInfo.colorLoadOp() == GrLoadOp::kLoad &&
Greg Daniel1e169372021-08-24 15:44:15 -0400322 fGpu->vkCaps().programInfoWillUseDiscardableMSAA(fProgramInfo))) {
Greg Daniel91b37b12021-01-05 15:40:54 -0500323 subpass = 1;
324 }
Greg Daniel3ef052c2021-01-05 12:20:27 -0500325 sk_sp<const GrVkPipeline> pipeline = resourceProvider.makePipeline(
Greg Daniel91b37b12021-01-05 15:40:54 -0500326 fProgramInfo, shaderStageInfo, numShaderStages, compatibleRenderPass, pipelineLayout,
327 subpass);
328
Brian Osman5e7fbfd2019-05-03 13:13:35 -0400329 for (int i = 0; i < kGrShaderTypeCount; ++i) {
330 // This if check should not be needed since calling destroy on a VK_NULL_HANDLE is allowed.
331 // However this is causing a crash in certain drivers (e.g. NVidia).
332 if (shaderModules[i]) {
333 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), shaderModules[i],
334 nullptr));
335 }
Greg Daniel852d7152017-05-08 12:10:12 -0400336 }
jvanverth992ad362016-02-26 09:21:02 -0800337
338 if (!pipeline) {
339 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
340 nullptr));
jvanverth992ad362016-02-26 09:21:02 -0800341 return nullptr;
342 }
343
egdaniel22281c12016-03-23 13:49:40 -0700344 return new GrVkPipelineState(fGpu,
Greg Daniel3ef052c2021-01-05 12:20:27 -0500345 std::move(pipeline),
egdaniel707bbd62016-07-26 07:19:47 -0700346 samplerDSHandle,
egdaniel22281c12016-03-23 13:49:40 -0700347 fUniformHandles,
348 fUniformHandler.fUniforms,
Jim Van Verth205e99a2021-02-08 18:02:41 -0500349 fUniformHandler.currentOffset(),
350 fUniformHandler.usePushConstants(),
Greg Daniel7a82edf2018-12-04 10:54:34 -0500351 fUniformHandler.fSamplers,
Brian Salomonf95940b2021-08-09 15:56:24 -0400352 std::move(fGPImpl),
Brian Salomond89d4452021-08-09 16:42:36 -0400353 std::move(fXPImpl),
Brian Salomon17f95b12021-02-23 09:35:08 -0500354 std::move(fFPImpls));
jvanverth992ad362016-02-26 09:21:02 -0800355}