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