blob: f7a61730a581a3af0795a785b77a41f45fbca815 [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
Brian Salomon94efbf52016-11-29 13:43:05 -050010#include "GrShaderCaps.h"
egdaniel707bbd62016-07-26 07:19:47 -070011#include "vk/GrVkDescriptorSetManager.h"
jvanverth992ad362016-02-26 09:21:02 -080012#include "vk/GrVkGpu.h"
13#include "vk/GrVkRenderPass.h"
jvanverth992ad362016-02-26 09:21:02 -080014
Brian Salomon99938a82016-11-21 13:41:08 -050015
egdaniel22281c12016-03-23 13:49:40 -070016GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
17 GrVkGpu* gpu,
18 const GrPipeline& pipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -070019 const GrStencilSettings& stencil,
egdaniel22281c12016-03-23 13:49:40 -070020 const GrPrimitiveProcessor& primProc,
21 GrPrimitiveType primitiveType,
Ethan Nicholasde4d3012017-01-19 16:58:02 -050022 GrVkPipelineState::Desc* desc,
egdaniel22281c12016-03-23 13:49:40 -070023 const GrVkRenderPass& renderPass) {
jvanverth992ad362016-02-26 09:21:02 -080024 // create a builder. This will be handed off to effects so they can use it to add
25 // uniforms, varyings, textures, etc
egdaniel720dc712016-09-07 11:56:59 -070026 GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);
jvanverth992ad362016-02-26 09:21:02 -080027
28 GrGLSLExpr4 inputColor;
29 GrGLSLExpr4 inputCoverage;
30
cdalton9c3f1432016-03-11 10:07:37 -080031 if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
jvanverth992ad362016-02-26 09:21:02 -080032 builder.cleanupFragmentProcessors();
33 return nullptr;
34 }
35
csmartdaltonc633abb2016-11-01 08:55:55 -070036 return builder.finalize(stencil, primitiveType, renderPass, desc);
jvanverth992ad362016-02-26 09:21:02 -080037}
38
egdaniel22281c12016-03-23 13:49:40 -070039GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
40 const GrPipeline& pipeline,
41 const GrPrimitiveProcessor& primProc,
Ethan Nicholasde4d3012017-01-19 16:58:02 -050042 GrProgramDesc* desc)
halcanary9d524f22016-03-29 09:03:52 -070043 : INHERITED(pipeline, primProc, desc)
jvanverth992ad362016-02-26 09:21:02 -080044 , fGpu(gpu)
halcanary9d524f22016-03-29 09:03:52 -070045 , fVaryingHandler(this)
jvanverth992ad362016-02-26 09:21:02 -080046 , fUniformHandler(this) {
47}
48
egdaniel22281c12016-03-23 13:49:40 -070049const GrCaps* GrVkPipelineStateBuilder::caps() const {
jvanverth992ad362016-02-26 09:21:02 -080050 return fGpu->caps();
51}
jvanverth992ad362016-02-26 09:21:02 -080052
Brian Salomon99938a82016-11-21 13:41:08 -050053void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050054 outputColor.addLayoutQualifier("location = 0, index = 0");
jvanverth992ad362016-02-26 09:21:02 -080055}
56
Brian Salomon99938a82016-11-21 13:41:08 -050057void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
Brian Salomon60397682016-11-22 15:06:46 -050058 outputColor.addLayoutQualifier("location = 0, index = 1");
egdanield632bb42016-03-30 12:06:48 -070059}
60
Ethan Nicholas941e7e22016-12-12 15:33:30 -050061bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage,
egdaniel22281c12016-03-23 13:49:40 -070062 const GrGLSLShaderBuilder& builder,
63 VkShaderModule* shaderModule,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050064 VkPipelineShaderStageCreateInfo* stageInfo,
Ethan Nicholasde4d3012017-01-19 16:58:02 -050065 const SkSL::Program::Settings& settings,
66 GrVkPipelineState::Desc* desc) {
jvanverth992ad362016-02-26 09:21:02 -080067 SkString shaderString;
68 for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
69 if (builder.fCompilerStrings[i]) {
70 shaderString.append(builder.fCompilerStrings[i]);
71 shaderString.append("\n");
72 }
73 }
Ethan Nicholas941e7e22016-12-12 15:33:30 -050074
75 SkSL::Program::Inputs inputs;
76 bool result = GrCompileVkShaderModule(fGpu, shaderString.c_str(), stage, shaderModule,
77 stageInfo, settings, &inputs);
78 if (!result) {
79 return false;
80 }
81 if (inputs.fRTHeight) {
82 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
83 }
Ethan Nicholasde4d3012017-01-19 16:58:02 -050084 if (!inputs.fFlipY) {
85 // the program doesn't care about the surface origin, set the key to zero to indicate that
86 // it doesn't matter
87 desc->setSurfaceOriginKey(0);
88 desc->finalize();
89 }
Ethan Nicholas941e7e22016-12-12 15:33:30 -050090 return result;
jvanverth992ad362016-02-26 09:21:02 -080091}
92
csmartdaltonc633abb2016-11-01 08:55:55 -070093GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
94 GrPrimitiveType primitiveType,
egdaniel22281c12016-03-23 13:49:40 -070095 const GrVkRenderPass& renderPass,
Ethan Nicholasde4d3012017-01-19 16:58:02 -050096 GrVkPipelineState::Desc* desc) {
jvanverth992ad362016-02-26 09:21:02 -080097 VkDescriptorSetLayout dsLayout[2];
98 VkPipelineLayout pipelineLayout;
99 VkShaderModule vertShaderModule;
100 VkShaderModule fragShaderModule;
101
egdaniel707bbd62016-07-26 07:19:47 -0700102 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
Jim Van Verth684d7ce2016-11-17 13:30:22 -0500103 // These layouts are not owned by the PipelineStateBuilder and thus should not be destroyed
egdaniel707bbd62016-07-26 07:19:47 -0700104 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
105
106 GrVkDescriptorSetManager::Handle samplerDSHandle;
107 resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
108 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;
117 layoutCreateInfo.setLayoutCount = 2;
118 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
136 VkPipelineShaderStageCreateInfo shaderStageInfo[2];
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500137 SkSL::Program::Settings settings;
138 settings.fFlipY = this->pipeline().getRenderTarget()->origin() != kTopLeft_GrSurfaceOrigin;
139 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_VERTEX_BIT,
140 fVS,
141 &vertShaderModule,
142 &shaderStageInfo[0],
Ethan Nicholasde4d3012017-01-19 16:58:02 -0500143 settings,
144 desc));
jvanverth992ad362016-02-26 09:21:02 -0800145
csmartdalton276cc412016-11-21 11:55:00 -0700146 // TODO: geometry shader support.
147 SkASSERT(!this->primitiveProcessor().willUseGeoShader());
148
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500149 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_FRAGMENT_BIT,
150 fFS,
151 &fragShaderModule,
152 &shaderStageInfo[1],
Ethan Nicholasde4d3012017-01-19 16:58:02 -0500153 settings,
154 desc));
jvanverth992ad362016-02-26 09:21:02 -0800155
egdaniel0e1853c2016-03-17 11:35:45 -0700156 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -0700157 stencil,
egdaniel0e1853c2016-03-17 11:35:45 -0700158 fPrimProc,
jvanverth992ad362016-02-26 09:21:02 -0800159 shaderStageInfo,
160 2,
161 primitiveType,
162 renderPass,
163 pipelineLayout);
164 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
165 nullptr));
166 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
167 nullptr));
168
169 if (!pipeline) {
170 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
171 nullptr));
egdaniel8af936d2016-04-07 10:17:47 -0700172 this->cleanupFragmentProcessors();
jvanverth992ad362016-02-26 09:21:02 -0800173 return nullptr;
174 }
175
egdaniel22281c12016-03-23 13:49:40 -0700176 return new GrVkPipelineState(fGpu,
Ethan Nicholasde4d3012017-01-19 16:58:02 -0500177 *desc,
egdaniel22281c12016-03-23 13:49:40 -0700178 pipeline,
179 pipelineLayout,
egdaniel707bbd62016-07-26 07:19:47 -0700180 samplerDSHandle,
egdaniel22281c12016-03-23 13:49:40 -0700181 fUniformHandles,
182 fUniformHandler.fUniforms,
183 fUniformHandler.fCurrentVertexUBOOffset,
184 fUniformHandler.fCurrentFragmentUBOOffset,
egdaniel707bbd62016-07-26 07:19:47 -0700185 (uint32_t)fUniformHandler.numSamplers(),
egdaniel22281c12016-03-23 13:49:40 -0700186 fGeometryProcessor,
187 fXferProcessor,
188 fFragmentProcessors);
jvanverth992ad362016-02-26 09:21:02 -0800189}
egdaniel707bbd62016-07-26 07:19:47 -0700190