blob: e2ccbdaa598a9365f4baaa34f2745bafd6b468d5 [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
egdaniel22281c12016-03-23 13:49:40 -07008#include "vk/GrVkPipelineStateBuilder.h"
Brian Osman8a83ca42018-02-12 14:32:17 -05009#include "GrContext.h"
10#include "GrContextPriv.h"
Brian Salomon94efbf52016-11-29 13:43:05 -050011#include "GrShaderCaps.h"
Brian Salomon1471df92018-06-08 10:49:00 -040012#include "GrStencilSettings.h"
13#include "GrVkRenderTarget.h"
egdaniel707bbd62016-07-26 07:19:47 -070014#include "vk/GrVkDescriptorSetManager.h"
jvanverth992ad362016-02-26 09:21:02 -080015#include "vk/GrVkGpu.h"
16#include "vk/GrVkRenderPass.h"
jvanverth992ad362016-02-26 09:21:02 -080017
egdaniel22281c12016-03-23 13:49:40 -070018GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
Brian Salomon1471df92018-06-08 10:49:00 -040019 GrVkGpu* gpu,
Brian Salomonff168d92018-06-23 15:17:27 -040020 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050021 const GrTextureProxy* const primProcProxies[],
Brian Salomon1471df92018-06-08 10:49:00 -040022 const GrPipeline& pipeline,
23 const GrStencilSettings& stencil,
Brian Salomon1471df92018-06-08 10:49:00 -040024 GrPrimitiveType primitiveType,
25 Desc* desc,
Greg Daniel99b88e02018-10-03 15:31:20 -040026 VkRenderPass compatibleRenderPass) {
jvanverth992ad362016-02-26 09:21:02 -080027 // create a builder. This will be handed off to effects so they can use it to add
28 // uniforms, varyings, textures, etc
Greg Daniel9a51a862018-11-30 10:18:14 -050029 GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, primProcProxies, desc);
jvanverth992ad362016-02-26 09:21:02 -080030
Ethan Nicholas2983f402017-05-08 09:36:08 -040031 if (!builder.emitAndInstallProcs()) {
jvanverth992ad362016-02-26 09:21:02 -080032 return nullptr;
33 }
34
Greg Daniel99b88e02018-10-03 15:31:20 -040035 return builder.finalize(stencil, primitiveType, compatibleRenderPass, desc);
jvanverth992ad362016-02-26 09:21:02 -080036}
37
egdaniel22281c12016-03-23 13:49:40 -070038GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
39 const GrPipeline& pipeline,
40 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050041 const GrTextureProxy* const primProcProxies[],
Ethan Nicholas38657112017-02-09 17:01:22 -050042 GrProgramDesc* desc)
Greg Daniel9a51a862018-11-30 10:18:14 -050043 : INHERITED(primProc, primProcProxies, pipeline, desc)
Brian Salomonff168d92018-06-23 15:17:27 -040044 , fGpu(gpu)
45 , fVaryingHandler(this)
46 , fUniformHandler(this) {}
jvanverth992ad362016-02-26 09:21:02 -080047
egdaniel22281c12016-03-23 13:49:40 -070048const GrCaps* GrVkPipelineStateBuilder::caps() const {
jvanverth992ad362016-02-26 09:21:02 -080049 return fGpu->caps();
50}
jvanverth992ad362016-02-26 09:21:02 -080051
Brian Salomon99938a82016-11-21 13:41:08 -050052void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050053 outputColor.addLayoutQualifier("location = 0, index = 0");
jvanverth992ad362016-02-26 09:21:02 -080054}
55
Brian Salomon99938a82016-11-21 13:41:08 -050056void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050057 outputColor.addLayoutQualifier("location = 0, index = 1");
egdanield632bb42016-03-30 12:06:48 -070058}
59
Ethan Nicholas941e7e22016-12-12 15:33:30 -050060bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage,
egdaniel22281c12016-03-23 13:49:40 -070061 const GrGLSLShaderBuilder& builder,
62 VkShaderModule* shaderModule,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050063 VkPipelineShaderStageCreateInfo* stageInfo,
Ethan Nicholas38657112017-02-09 17:01:22 -050064 const SkSL::Program::Settings& settings,
Brian Salomon1471df92018-06-08 10:49:00 -040065 Desc* desc) {
jvanverth992ad362016-02-26 09:21:02 -080066 SkString shaderString;
67 for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
68 if (builder.fCompilerStrings[i]) {
69 shaderString.append(builder.fCompilerStrings[i]);
70 shaderString.append("\n");
71 }
72 }
Ethan Nicholas941e7e22016-12-12 15:33:30 -050073
74 SkSL::Program::Inputs inputs;
75 bool result = GrCompileVkShaderModule(fGpu, shaderString.c_str(), stage, shaderModule,
76 stageInfo, settings, &inputs);
77 if (!result) {
78 return false;
79 }
Greg Daniele6ab9982018-08-22 13:56:32 +000080 if (inputs.fRTHeight) {
81 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
Ethan Nicholas941e7e22016-12-12 15:33:30 -050082 }
Ethan Nicholas38657112017-02-09 17:01:22 -050083 if (inputs.fFlipY) {
Robert Phillips7f861922018-01-30 13:13:42 +000084 desc->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
85 this->pipeline().proxy()->origin()));
Ethan Nicholas38657112017-02-09 17:01:22 -050086 desc->finalize();
87 }
Ethan Nicholas941e7e22016-12-12 15:33:30 -050088 return result;
jvanverth992ad362016-02-26 09:21:02 -080089}
90
csmartdaltonc633abb2016-11-01 08:55:55 -070091GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
92 GrPrimitiveType primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -040093 VkRenderPass compatibleRenderPass,
Brian Salomon1471df92018-06-08 10:49:00 -040094 Desc* desc) {
Brian Salomon662ea4b2018-07-12 14:53:49 -040095 VkDescriptorSetLayout dsLayout[2];
jvanverth992ad362016-02-26 09:21:02 -080096 VkPipelineLayout pipelineLayout;
Greg Daniel852d7152017-05-08 12:10:12 -040097 VkShaderModule vertShaderModule = VK_NULL_HANDLE;
98 VkShaderModule geomShaderModule = VK_NULL_HANDLE;
99 VkShaderModule fragShaderModule = VK_NULL_HANDLE;
jvanverth992ad362016-02-26 09:21:02 -0800100
egdaniel707bbd62016-07-26 07:19:47 -0700101 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
Jim Van Verth684d7ce2016-11-17 13:30:22 -0500102 // These layouts are not owned by the PipelineStateBuilder and thus should not be destroyed
egdaniel707bbd62016-07-26 07:19:47 -0700103 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
104
105 GrVkDescriptorSetManager::Handle samplerDSHandle;
Greg Daniela7543782017-05-02 14:01:43 -0400106 resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
107 fUniformHandler, &samplerDSHandle);
egdaniel707bbd62016-07-26 07:19:47 -0700108 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
109 resourceProvider.getSamplerDSLayout(samplerDSHandle);
jvanverth992ad362016-02-26 09:21:02 -0800110
111 // Create the VkPipelineLayout
112 VkPipelineLayoutCreateInfo layoutCreateInfo;
113 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
114 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
115 layoutCreateInfo.pNext = 0;
116 layoutCreateInfo.flags = 0;
Brian Salomon662ea4b2018-07-12 14:53:49 -0400117 layoutCreateInfo.setLayoutCount = 2;
jvanverth992ad362016-02-26 09:21:02 -0800118 layoutCreateInfo.pSetLayouts = dsLayout;
119 layoutCreateInfo.pushConstantRangeCount = 0;
120 layoutCreateInfo.pPushConstantRanges = nullptr;
121
122 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
123 &layoutCreateInfo,
124 nullptr,
125 &pipelineLayout));
126
127 // We need to enable the following extensions so that the compiler can correctly make spir-v
128 // from our glsl shaders.
129 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
130 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
131 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
132 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
133
134 this->finalizeShaders();
135
Greg Daniel852d7152017-05-08 12:10:12 -0400136 VkPipelineShaderStageCreateInfo shaderStageInfo[3];
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500137 SkSL::Program::Settings settings;
Ethan Nicholase4682862017-07-18 14:08:18 -0400138 settings.fCaps = this->caps()->shaderCaps();
Robert Phillips2890fbf2017-07-26 15:48:41 -0400139 settings.fFlipY = this->pipeline().proxy()->origin() != kTopLeft_GrSurfaceOrigin;
Brian Osman8a83ca42018-02-12 14:32:17 -0500140 settings.fSharpenTextures = this->gpu()->getContext()->contextPriv().sharpenMipmappedTextures();
Brian Salomondc092132018-04-04 10:14:16 -0400141 SkASSERT(!this->fragColorIsInOut());
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500142 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_VERTEX_BIT,
143 fVS,
144 &vertShaderModule,
145 &shaderStageInfo[0],
Ethan Nicholas38657112017-02-09 17:01:22 -0500146 settings,
147 desc));
jvanverth992ad362016-02-26 09:21:02 -0800148
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500149 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_FRAGMENT_BIT,
150 fFS,
151 &fragShaderModule,
152 &shaderStageInfo[1],
Ethan Nicholas38657112017-02-09 17:01:22 -0500153 settings,
154 desc));
jvanverth992ad362016-02-26 09:21:02 -0800155
Greg Daniel852d7152017-05-08 12:10:12 -0400156 int numShaderStages = 2; // We always have at least vertex and fragment stages.
157 if (this->primitiveProcessor().willUseGeoShader()) {
158 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_GEOMETRY_BIT,
159 fGS,
160 &geomShaderModule,
161 &shaderStageInfo[2],
162 settings,
163 desc));
164 ++numShaderStages;
165 }
166
Brian Salomonff168d92018-06-23 15:17:27 -0400167 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPrimProc,
168 fPipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -0700169 stencil,
jvanverth992ad362016-02-26 09:21:02 -0800170 shaderStageInfo,
Greg Daniel852d7152017-05-08 12:10:12 -0400171 numShaderStages,
jvanverth992ad362016-02-26 09:21:02 -0800172 primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -0400173 compatibleRenderPass,
jvanverth992ad362016-02-26 09:21:02 -0800174 pipelineLayout);
175 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
176 nullptr));
177 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
178 nullptr));
Greg Daniel852d7152017-05-08 12:10:12 -0400179 // This if check should not be needed since calling destroy on a VK_NULL_HANDLE is allowed.
180 // However this is causing a crash in certain drivers (e.g. NVidia).
181 if (this->primitiveProcessor().willUseGeoShader()) {
182 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), geomShaderModule,
183 nullptr));
184 }
jvanverth992ad362016-02-26 09:21:02 -0800185
186 if (!pipeline) {
187 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
188 nullptr));
jvanverth992ad362016-02-26 09:21:02 -0800189 return nullptr;
190 }
191
egdaniel22281c12016-03-23 13:49:40 -0700192 return new GrVkPipelineState(fGpu,
egdaniel22281c12016-03-23 13:49:40 -0700193 pipeline,
194 pipelineLayout,
egdaniel707bbd62016-07-26 07:19:47 -0700195 samplerDSHandle,
egdaniel22281c12016-03-23 13:49:40 -0700196 fUniformHandles,
197 fUniformHandler.fUniforms,
Greg Daniel18f96022017-05-04 15:09:03 -0400198 fUniformHandler.fCurrentGeometryUBOOffset,
egdaniel22281c12016-03-23 13:49:40 -0700199 fUniformHandler.fCurrentFragmentUBOOffset,
Greg Daniel7a82edf2018-12-04 10:54:34 -0500200 fUniformHandler.fSamplers,
Robert Phillips369e8b72017-08-01 16:13:04 -0400201 std::move(fGeometryProcessor),
202 std::move(fXferProcessor),
Brian Salomon4d3f5172018-06-07 14:42:52 -0400203 std::move(fFragmentProcessors),
204 fFragmentProcessorCnt);
jvanverth992ad362016-02-26 09:21:02 -0800205}
egdaniel707bbd62016-07-26 07:19:47 -0700206
Brian Salomon1471df92018-06-08 10:49:00 -0400207//////////////////////////////////////////////////////////////////////////////
208
Chris Daltonb91c4662018-08-01 10:46:22 -0600209uint32_t get_blend_info_key(const GrPipeline& pipeline) {
210 GrXferProcessor::BlendInfo blendInfo;
211 pipeline.getXferProcessor().getBlendInfo(&blendInfo);
212
213 static const uint32_t kBlendWriteShift = 1;
Brian Salomon1471df92018-06-08 10:49:00 -0400214 static const uint32_t kBlendCoeffShift = 5;
215 GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
216 GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4);
217
Chris Daltonb91c4662018-08-01 10:46:22 -0600218 uint32_t key = blendInfo.fWriteColor;
219 key |= (blendInfo.fSrcBlend << kBlendWriteShift);
220 key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
221 key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
Brian Salomon1471df92018-06-08 10:49:00 -0400222
223 return key;
224}
225
226bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
227 const GrPrimitiveProcessor& primProc,
228 const GrPipeline& pipeline,
229 const GrStencilSettings& stencil,
230 GrPrimitiveType primitiveType,
Greg Daniel7a82edf2018-12-04 10:54:34 -0500231 GrVkGpu* gpu) {
Brian Salomon1471df92018-06-08 10:49:00 -0400232 if (!INHERITED::Build(desc, primProc, primitiveType == GrPrimitiveType::kPoints, pipeline,
Greg Daniel7a82edf2018-12-04 10:54:34 -0500233 gpu)) {
Brian Salomon1471df92018-06-08 10:49:00 -0400234 return false;
235 }
236
237 GrProcessorKeyBuilder b(&desc->key());
238 GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.renderTarget();
239 vkRT->simpleRenderPass()->genKey(&b);
240
241 stencil.genKey(&b);
242
Chris Daltonb91c4662018-08-01 10:46:22 -0600243 b.add32(get_blend_info_key(pipeline));
Brian Salomon1471df92018-06-08 10:49:00 -0400244
245 b.add32((uint32_t)primitiveType);
246
247 return true;
248}