blob: 4125938bae8bb3cf741edbb25cf33283af914536 [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 Nicholascae3a4c2017-02-02 10:43:58 -050022 const 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 Nicholascae3a4c2017-02-02 10:43:58 -050042 const 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 Nicholascae3a4c2017-02-02 10:43:58 -050065 const SkSL::Program::Settings& settings) {
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 }
80 if (inputs.fRTHeight) {
81 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
82 }
83 return result;
jvanverth992ad362016-02-26 09:21:02 -080084}
85
csmartdaltonc633abb2016-11-01 08:55:55 -070086GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
87 GrPrimitiveType primitiveType,
egdaniel22281c12016-03-23 13:49:40 -070088 const GrVkRenderPass& renderPass,
Ethan Nicholascae3a4c2017-02-02 10:43:58 -050089 const GrVkPipelineState::Desc& desc) {
jvanverth992ad362016-02-26 09:21:02 -080090 VkDescriptorSetLayout dsLayout[2];
91 VkPipelineLayout pipelineLayout;
92 VkShaderModule vertShaderModule;
93 VkShaderModule fragShaderModule;
94
egdaniel707bbd62016-07-26 07:19:47 -070095 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
Jim Van Verth684d7ce2016-11-17 13:30:22 -050096 // These layouts are not owned by the PipelineStateBuilder and thus should not be destroyed
egdaniel707bbd62016-07-26 07:19:47 -070097 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
98
99 GrVkDescriptorSetManager::Handle samplerDSHandle;
100 resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
101 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
102 resourceProvider.getSamplerDSLayout(samplerDSHandle);
jvanverth992ad362016-02-26 09:21:02 -0800103
104 // Create the VkPipelineLayout
105 VkPipelineLayoutCreateInfo layoutCreateInfo;
106 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
107 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
108 layoutCreateInfo.pNext = 0;
109 layoutCreateInfo.flags = 0;
110 layoutCreateInfo.setLayoutCount = 2;
111 layoutCreateInfo.pSetLayouts = dsLayout;
112 layoutCreateInfo.pushConstantRangeCount = 0;
113 layoutCreateInfo.pPushConstantRanges = nullptr;
114
115 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
116 &layoutCreateInfo,
117 nullptr,
118 &pipelineLayout));
119
120 // We need to enable the following extensions so that the compiler can correctly make spir-v
121 // from our glsl shaders.
122 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
123 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
124 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
125 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
126
127 this->finalizeShaders();
128
129 VkPipelineShaderStageCreateInfo shaderStageInfo[2];
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500130 SkSL::Program::Settings settings;
131 settings.fFlipY = this->pipeline().getRenderTarget()->origin() != kTopLeft_GrSurfaceOrigin;
132 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_VERTEX_BIT,
133 fVS,
134 &vertShaderModule,
135 &shaderStageInfo[0],
Ethan Nicholascae3a4c2017-02-02 10:43:58 -0500136 settings));
jvanverth992ad362016-02-26 09:21:02 -0800137
csmartdalton276cc412016-11-21 11:55:00 -0700138 // TODO: geometry shader support.
139 SkASSERT(!this->primitiveProcessor().willUseGeoShader());
140
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500141 SkAssertResult(this->createVkShaderModule(VK_SHADER_STAGE_FRAGMENT_BIT,
142 fFS,
143 &fragShaderModule,
144 &shaderStageInfo[1],
Ethan Nicholascae3a4c2017-02-02 10:43:58 -0500145 settings));
jvanverth992ad362016-02-26 09:21:02 -0800146
egdaniel0e1853c2016-03-17 11:35:45 -0700147 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -0700148 stencil,
egdaniel0e1853c2016-03-17 11:35:45 -0700149 fPrimProc,
jvanverth992ad362016-02-26 09:21:02 -0800150 shaderStageInfo,
151 2,
152 primitiveType,
153 renderPass,
154 pipelineLayout);
155 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
156 nullptr));
157 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
158 nullptr));
159
160 if (!pipeline) {
161 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
162 nullptr));
egdaniel8af936d2016-04-07 10:17:47 -0700163 this->cleanupFragmentProcessors();
jvanverth992ad362016-02-26 09:21:02 -0800164 return nullptr;
165 }
166
egdaniel22281c12016-03-23 13:49:40 -0700167 return new GrVkPipelineState(fGpu,
Ethan Nicholascae3a4c2017-02-02 10:43:58 -0500168 desc,
egdaniel22281c12016-03-23 13:49:40 -0700169 pipeline,
170 pipelineLayout,
egdaniel707bbd62016-07-26 07:19:47 -0700171 samplerDSHandle,
egdaniel22281c12016-03-23 13:49:40 -0700172 fUniformHandles,
173 fUniformHandler.fUniforms,
174 fUniformHandler.fCurrentVertexUBOOffset,
175 fUniformHandler.fCurrentFragmentUBOOffset,
egdaniel707bbd62016-07-26 07:19:47 -0700176 (uint32_t)fUniformHandler.numSamplers(),
egdaniel22281c12016-03-23 13:49:40 -0700177 fGeometryProcessor,
178 fXferProcessor,
179 fFragmentProcessors);
jvanverth992ad362016-02-26 09:21:02 -0800180}
egdaniel707bbd62016-07-26 07:19:47 -0700181