1 /*
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
8 #include "vk/GrVkPipelineStateBuilder.h"
9
10 #include "vk/GrVkDescriptorSetManager.h"
11 #include "vk/GrVkGpu.h"
12 #include "vk/GrVkRenderPass.h"
13
CreatePipelineState(GrVkGpu * gpu,const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,GrPrimitiveType primitiveType,const GrVkPipelineState::Desc & desc,const GrVkRenderPass & renderPass)14 GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
15 GrVkGpu* gpu,
16 const GrPipeline& pipeline,
17 const GrPrimitiveProcessor& primProc,
18 GrPrimitiveType primitiveType,
19 const GrVkPipelineState::Desc& desc,
20 const GrVkRenderPass& renderPass) {
21 // create a builder. This will be handed off to effects so they can use it to add
22 // uniforms, varyings, textures, etc
23 GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);
24
25 GrGLSLExpr4 inputColor;
26 GrGLSLExpr4 inputCoverage;
27
28 if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
29 builder.cleanupFragmentProcessors();
30 return nullptr;
31 }
32
33 return builder.finalize(primitiveType, renderPass, desc);
34 }
35
GrVkPipelineStateBuilder(GrVkGpu * gpu,const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,const GrProgramDesc & desc)36 GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
37 const GrPipeline& pipeline,
38 const GrPrimitiveProcessor& primProc,
39 const GrProgramDesc& desc)
40 : INHERITED(pipeline, primProc, desc)
41 , fGpu(gpu)
42 , fVaryingHandler(this)
43 , fUniformHandler(this) {
44 }
45
caps() const46 const GrCaps* GrVkPipelineStateBuilder::caps() const {
47 return fGpu->caps();
48 }
glslCaps() const49 const GrGLSLCaps* GrVkPipelineStateBuilder::glslCaps() const {
50 return fGpu->vkCaps().glslCaps();
51 }
52
finalizeFragmentOutputColor(GrGLSLShaderVar & outputColor)53 void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
54 outputColor.setLayoutQualifier("location = 0, index = 0");
55 }
56
finalizeFragmentSecondaryColor(GrGLSLShaderVar & outputColor)57 void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {
58 outputColor.setLayoutQualifier("location = 0, index = 1");
59 }
60
CreateVkShaderModule(const GrVkGpu * gpu,VkShaderStageFlagBits stage,const GrGLSLShaderBuilder & builder,VkShaderModule * shaderModule,VkPipelineShaderStageCreateInfo * stageInfo)61 bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
62 VkShaderStageFlagBits stage,
63 const GrGLSLShaderBuilder& builder,
64 VkShaderModule* shaderModule,
65 VkPipelineShaderStageCreateInfo* stageInfo) {
66 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 }
73 return GrCompileVkShaderModule(gpu, shaderString.c_str(), stage, shaderModule, stageInfo);
74 }
75
finalize(GrPrimitiveType primitiveType,const GrVkRenderPass & renderPass,const GrVkPipelineState::Desc & desc)76 GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveType,
77 const GrVkRenderPass& renderPass,
78 const GrVkPipelineState::Desc& desc) {
79 VkDescriptorSetLayout dsLayout[2];
80 VkPipelineLayout pipelineLayout;
81 VkShaderModule vertShaderModule;
82 VkShaderModule fragShaderModule;
83
84 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
85 // This layout is not owned by the PipelineStateBuilder and thus should no be destroyed
86 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
87
88 GrVkDescriptorSetManager::Handle samplerDSHandle;
89 resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
90 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
91 resourceProvider.getSamplerDSLayout(samplerDSHandle);
92
93 // Create the VkPipelineLayout
94 VkPipelineLayoutCreateInfo layoutCreateInfo;
95 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
96 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
97 layoutCreateInfo.pNext = 0;
98 layoutCreateInfo.flags = 0;
99 layoutCreateInfo.setLayoutCount = 2;
100 layoutCreateInfo.pSetLayouts = dsLayout;
101 layoutCreateInfo.pushConstantRangeCount = 0;
102 layoutCreateInfo.pPushConstantRanges = nullptr;
103
104 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
105 &layoutCreateInfo,
106 nullptr,
107 &pipelineLayout));
108
109 // We need to enable the following extensions so that the compiler can correctly make spir-v
110 // from our glsl shaders.
111 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
112 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
113 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
114 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
115
116 this->finalizeShaders();
117
118 VkPipelineShaderStageCreateInfo shaderStageInfo[2];
119 SkAssertResult(CreateVkShaderModule(fGpu,
120 VK_SHADER_STAGE_VERTEX_BIT,
121 fVS,
122 &vertShaderModule,
123 &shaderStageInfo[0]));
124
125 SkAssertResult(CreateVkShaderModule(fGpu,
126 VK_SHADER_STAGE_FRAGMENT_BIT,
127 fFS,
128 &fragShaderModule,
129 &shaderStageInfo[1]));
130
131 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
132 fPrimProc,
133 shaderStageInfo,
134 2,
135 primitiveType,
136 renderPass,
137 pipelineLayout);
138 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
139 nullptr));
140 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
141 nullptr));
142
143 if (!pipeline) {
144 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
145 nullptr));
146 GR_VK_CALL(fGpu->vkInterface(),
147 DestroyDescriptorSetLayout(fGpu->device(),
148 dsLayout[GrVkUniformHandler::kSamplerDescSet],
149 nullptr));
150
151 this->cleanupFragmentProcessors();
152 return nullptr;
153 }
154
155 return new GrVkPipelineState(fGpu,
156 desc,
157 pipeline,
158 pipelineLayout,
159 samplerDSHandle,
160 fUniformHandles,
161 fUniformHandler.fUniforms,
162 fUniformHandler.fCurrentVertexUBOOffset,
163 fUniformHandler.fCurrentFragmentUBOOffset,
164 (uint32_t)fUniformHandler.numSamplers(),
165 fGeometryProcessor,
166 fXferProcessor,
167 fFragmentProcessors);
168 }
169
170