blob: 2bd80033dd885bf71a1013bb3c848530a6861cdf [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"
jvanverth992ad362016-02-26 09:21:02 -08009
10#include "vk/GrVkGpu.h"
11#include "vk/GrVkRenderPass.h"
jvanverth992ad362016-02-26 09:21:02 -080012
egdaniel22281c12016-03-23 13:49:40 -070013GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
14 GrVkGpu* gpu,
15 const GrPipeline& pipeline,
16 const GrPrimitiveProcessor& primProc,
17 GrPrimitiveType primitiveType,
18 const GrVkPipelineState::Desc& desc,
19 const GrVkRenderPass& renderPass) {
jvanverth992ad362016-02-26 09:21:02 -080020 // create a builder. This will be handed off to effects so they can use it to add
21 // uniforms, varyings, textures, etc
egdaniel22281c12016-03-23 13:49:40 -070022 GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc.fProgramDesc);
jvanverth992ad362016-02-26 09:21:02 -080023
24 GrGLSLExpr4 inputColor;
25 GrGLSLExpr4 inputCoverage;
26
cdalton9c3f1432016-03-11 10:07:37 -080027 if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
jvanverth992ad362016-02-26 09:21:02 -080028 builder.cleanupFragmentProcessors();
29 return nullptr;
30 }
31
egdaniel22281c12016-03-23 13:49:40 -070032 return builder.finalize(primitiveType, renderPass, desc);
jvanverth992ad362016-02-26 09:21:02 -080033}
34
egdaniel22281c12016-03-23 13:49:40 -070035GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
36 const GrPipeline& pipeline,
37 const GrPrimitiveProcessor& primProc,
38 const GrVkProgramDesc& desc)
halcanary9d524f22016-03-29 09:03:52 -070039 : INHERITED(pipeline, primProc, desc)
jvanverth992ad362016-02-26 09:21:02 -080040 , fGpu(gpu)
halcanary9d524f22016-03-29 09:03:52 -070041 , fVaryingHandler(this)
jvanverth992ad362016-02-26 09:21:02 -080042 , fUniformHandler(this) {
43}
44
egdaniel22281c12016-03-23 13:49:40 -070045const GrCaps* GrVkPipelineStateBuilder::caps() const {
jvanverth992ad362016-02-26 09:21:02 -080046 return fGpu->caps();
47}
egdaniel22281c12016-03-23 13:49:40 -070048const GrGLSLCaps* GrVkPipelineStateBuilder::glslCaps() const {
jvanverth992ad362016-02-26 09:21:02 -080049 return fGpu->vkCaps().glslCaps();
50}
51
egdaniel22281c12016-03-23 13:49:40 -070052void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
egdaniel3a15fd42016-04-05 11:00:29 -070053 outputColor.setLayoutQualifier("location = 0, index = 0");
jvanverth992ad362016-02-26 09:21:02 -080054}
55
egdanield632bb42016-03-30 12:06:48 -070056void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {
egdaniel3a15fd42016-04-05 11:00:29 -070057 outputColor.setLayoutQualifier("location = 0, index = 1");
egdanield632bb42016-03-30 12:06:48 -070058}
59
jvanverth992ad362016-02-26 09:21:02 -080060VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
61 VkShaderStageFlags flags = 0;
62
63 if (visibility & kVertex_GrShaderFlag) {
64 flags |= VK_SHADER_STAGE_VERTEX_BIT;
65 }
66 if (visibility & kGeometry_GrShaderFlag) {
67 flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
68 }
69 if (visibility & kFragment_GrShaderFlag) {
70 flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
71 }
72 return flags;
73}
74
75shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) {
76 if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
77 return shaderc_glsl_vertex_shader;
78 }
79 SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
80 return shaderc_glsl_fragment_shader;
81}
82
egdaniel22281c12016-03-23 13:49:40 -070083bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
84 VkShaderStageFlagBits stage,
85 const GrGLSLShaderBuilder& builder,
86 VkShaderModule* shaderModule,
87 VkPipelineShaderStageCreateInfo* stageInfo) {
jvanverth992ad362016-02-26 09:21:02 -080088 SkString shaderString;
89 for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
90 if (builder.fCompilerStrings[i]) {
91 shaderString.append(builder.fCompilerStrings[i]);
92 shaderString.append("\n");
93 }
94 }
95
jvanverth992ad362016-02-26 09:21:02 -080096 VkShaderModuleCreateInfo moduleCreateInfo;
97 memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo));
98 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
99 moduleCreateInfo.pNext = nullptr;
100 moduleCreateInfo.flags = 0;
egdanielc5ec1402016-03-28 12:14:42 -0700101
egdanielb60c3372016-04-01 08:47:35 -0700102 shaderc_compilation_result_t result = nullptr;
egdanielc5ec1402016-03-28 12:14:42 -0700103
104 if (gpu->vkCaps().canUseGLSLForShaderModule()) {
105 moduleCreateInfo.codeSize = strlen(shaderString.c_str());
106 moduleCreateInfo.pCode = (const uint32_t*)shaderString.c_str();
107 } else {
108
109 shaderc_compiler_t compiler = gpu->shadercCompiler();
110
111 shaderc_compile_options_t options = shaderc_compile_options_initialize();
egdanielc5ec1402016-03-28 12:14:42 -0700112
113 shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage);
114 result = shaderc_compile_into_spv(compiler,
115 shaderString.c_str(),
116 strlen(shaderString.c_str()),
117 shadercStage,
118 "shader",
119 "main",
120 options);
121 shaderc_compile_options_release(options);
122#ifdef SK_DEBUG
123 if (shaderc_result_get_num_errors(result)) {
124 SkDebugf("%s\n", shaderString.c_str());
125 SkDebugf("%s\n", shaderc_result_get_error_message(result));
126 return false;
127 }
128#endif
129
130 moduleCreateInfo.codeSize = shaderc_result_get_length(result);
131 moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result);
132 }
jvanverth992ad362016-02-26 09:21:02 -0800133
134 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(),
135 &moduleCreateInfo,
136 nullptr,
137 shaderModule));
egdanielc5ec1402016-03-28 12:14:42 -0700138 if (!gpu->vkCaps().canUseGLSLForShaderModule()) {
139 shaderc_result_release(result);
140 }
jvanverth992ad362016-02-26 09:21:02 -0800141 if (err) {
142 return false;
143 }
144
145 memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo));
146 stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
147 stageInfo->pNext = nullptr;
148 stageInfo->flags = 0;
149 stageInfo->stage = stage;
150 stageInfo->module = *shaderModule;
151 stageInfo->pName = "main";
152 stageInfo->pSpecializationInfo = nullptr;
153
154 return true;
155}
156
egdaniel22281c12016-03-23 13:49:40 -0700157GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveType,
158 const GrVkRenderPass& renderPass,
159 const GrVkPipelineState::Desc& desc) {
jvanverth992ad362016-02-26 09:21:02 -0800160 VkDescriptorSetLayout dsLayout[2];
161 VkPipelineLayout pipelineLayout;
162 VkShaderModule vertShaderModule;
163 VkShaderModule fragShaderModule;
164
165 uint32_t numSamplers = fSamplerUniforms.count();
166
167 SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
168 new VkDescriptorSetLayoutBinding[numSamplers]);
169 for (uint32_t i = 0; i < numSamplers; ++i) {
170 UniformHandle uniHandle = fSamplerUniforms[i];
171 GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle);
172 SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType());
egdanielb4aa3622016-04-06 13:47:08 -0700173 SkASSERT(GrVkUniformHandler::kSamplerDescSet == uniformInfo.fSetNumber);
jvanverth992ad362016-02-26 09:21:02 -0800174 SkASSERT(uniformInfo.fBinding == i);
175 dsSamplerBindings[i].binding = uniformInfo.fBinding;
176 dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
177 dsSamplerBindings[i].descriptorCount = 1;
178 dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility);
179 dsSamplerBindings[i].pImmutableSamplers = nullptr;
180 }
181
182 VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
183 memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
184 dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
185 dsSamplerLayoutCreateInfo.pNext = nullptr;
186 dsSamplerLayoutCreateInfo.flags = 0;
187 dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count();
188 // Setting to nullptr fixes an error in the param checker validation layer. Even though
189 // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
190 dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() :
191 nullptr;
192
193 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
194 CreateDescriptorSetLayout(fGpu->device(),
195 &dsSamplerLayoutCreateInfo,
196 nullptr,
197 &dsLayout[GrVkUniformHandler::kSamplerDescSet]));
198
199 // Create Uniform Buffer Descriptor
200 // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have
201 // binding 0 and the fragment binding 1.
202 VkDescriptorSetLayoutBinding dsUniBindings[2];
203 memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
204 dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
205 dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
egdanielb4aa3622016-04-06 13:47:08 -0700206 dsUniBindings[0].descriptorCount = 1;
jvanverth992ad362016-02-26 09:21:02 -0800207 dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
208 dsUniBindings[0].pImmutableSamplers = nullptr;
209 dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
210 dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
egdanielb4aa3622016-04-06 13:47:08 -0700211 dsUniBindings[1].descriptorCount = 1;
jvanverth992ad362016-02-26 09:21:02 -0800212 dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
213 dsUniBindings[1].pImmutableSamplers = nullptr;
214
215 VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo;
216 memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
217 dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
218 dsUniformLayoutCreateInfo.pNext = nullptr;
219 dsUniformLayoutCreateInfo.flags = 0;
220 dsUniformLayoutCreateInfo.bindingCount = 2;
221 dsUniformLayoutCreateInfo.pBindings = dsUniBindings;
222
223 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(
224 fGpu->device(),
225 &dsUniformLayoutCreateInfo,
226 nullptr,
227 &dsLayout[GrVkUniformHandler::kUniformBufferDescSet]));
228
229 // Create the VkPipelineLayout
230 VkPipelineLayoutCreateInfo layoutCreateInfo;
231 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
232 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
233 layoutCreateInfo.pNext = 0;
234 layoutCreateInfo.flags = 0;
235 layoutCreateInfo.setLayoutCount = 2;
236 layoutCreateInfo.pSetLayouts = dsLayout;
237 layoutCreateInfo.pushConstantRangeCount = 0;
238 layoutCreateInfo.pPushConstantRanges = nullptr;
239
240 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
241 &layoutCreateInfo,
242 nullptr,
243 &pipelineLayout));
244
245 // We need to enable the following extensions so that the compiler can correctly make spir-v
246 // from our glsl shaders.
247 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
248 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
249 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
250 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
251
252 this->finalizeShaders();
253
254 VkPipelineShaderStageCreateInfo shaderStageInfo[2];
255 SkAssertResult(CreateVkShaderModule(fGpu,
256 VK_SHADER_STAGE_VERTEX_BIT,
257 fVS,
258 &vertShaderModule,
259 &shaderStageInfo[0]));
260
261 SkAssertResult(CreateVkShaderModule(fGpu,
262 VK_SHADER_STAGE_FRAGMENT_BIT,
263 fFS,
264 &fragShaderModule,
265 &shaderStageInfo[1]));
266
267 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
egdaniel0e1853c2016-03-17 11:35:45 -0700268 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
269 fPrimProc,
jvanverth992ad362016-02-26 09:21:02 -0800270 shaderStageInfo,
271 2,
272 primitiveType,
273 renderPass,
274 pipelineLayout);
275 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
276 nullptr));
277 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
278 nullptr));
279
280 if (!pipeline) {
281 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
282 nullptr));
283 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[0],
284 nullptr));
285 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[1],
286 nullptr));
egdaniel8af936d2016-04-07 10:17:47 -0700287 this->cleanupFragmentProcessors();
jvanverth992ad362016-02-26 09:21:02 -0800288 return nullptr;
289 }
290
egdaniel22281c12016-03-23 13:49:40 -0700291 return new GrVkPipelineState(fGpu,
292 desc,
293 pipeline,
294 pipelineLayout,
295 dsLayout,
296 fUniformHandles,
297 fUniformHandler.fUniforms,
298 fUniformHandler.fCurrentVertexUBOOffset,
299 fUniformHandler.fCurrentFragmentUBOOffset,
300 numSamplers,
301 fGeometryProcessor,
302 fXferProcessor,
303 fFragmentProcessors);
jvanverth992ad362016-02-26 09:21:02 -0800304}