Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/gpu/vk/GrVkProgramBuilder.cpp

Issue 1816153002: Set up cache in vulkan to reuse GrVkPrograms (aka VkPipelines) (Closed) Base URL: https://skia.googlesource.com/skia.git@progSamplers
Patch Set: rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/vk/GrVkProgramBuilder.h ('k') | src/gpu/vk/GrVkProgramDataManager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/GrVkProgramBuilder.h"
9
10 #include "vk/GrVkGpu.h"
11 #include "vk/GrVkRenderPass.h"
12 #include "vk/GrVkProgram.h"
13
14 GrVkProgram* GrVkProgramBuilder::CreateProgram(GrVkGpu* gpu,
15 const GrPipeline& pipeline,
16 const GrPrimitiveProcessor& primP roc,
17 GrPrimitiveType primitiveType,
18 const GrVkProgramDesc& desc,
19 const GrVkRenderPass& renderPass) {
20 // create a builder. This will be handed off to effects so they can use it to add
21 // uniforms, varyings, textures, etc
22 GrVkProgramBuilder builder(gpu, pipeline, primProc, desc);
23
24 GrGLSLExpr4 inputColor;
25 GrGLSLExpr4 inputCoverage;
26
27 if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
28 builder.cleanupFragmentProcessors();
29 return nullptr;
30 }
31
32 return builder.finalize(primitiveType, renderPass);
33 }
34
35 GrVkProgramBuilder::GrVkProgramBuilder(GrVkGpu* gpu,
36 const GrPipeline& pipeline,
37 const GrPrimitiveProcessor& primProc,
38 const GrVkProgramDesc& desc)
39 : INHERITED(pipeline, primProc, desc)
40 , fGpu(gpu)
41 , fVaryingHandler(this)
42 , fUniformHandler(this) {
43 }
44
45 const GrCaps* GrVkProgramBuilder::caps() const {
46 return fGpu->caps();
47 }
48 const GrGLSLCaps* GrVkProgramBuilder::glslCaps() const {
49 return fGpu->vkCaps().glslCaps();
50 }
51
52 void GrVkProgramBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColo r) {
53 outputColor.setLayoutQualifier("location = 0");
54 }
55
56 VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
57 VkShaderStageFlags flags = 0;
58
59 if (visibility & kVertex_GrShaderFlag) {
60 flags |= VK_SHADER_STAGE_VERTEX_BIT;
61 }
62 if (visibility & kGeometry_GrShaderFlag) {
63 flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
64 }
65 if (visibility & kFragment_GrShaderFlag) {
66 flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
67 }
68 return flags;
69 }
70
71 shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) {
72 if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
73 return shaderc_glsl_vertex_shader;
74 }
75 SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
76 return shaderc_glsl_fragment_shader;
77 }
78
79 bool GrVkProgramBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
80 VkShaderStageFlagBits stage,
81 const GrGLSLShaderBuilder& builder ,
82 VkShaderModule* shaderModule,
83 VkPipelineShaderStageCreateInfo* s tageInfo) {
84 SkString shaderString;
85 for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
86 if (builder.fCompilerStrings[i]) {
87 shaderString.append(builder.fCompilerStrings[i]);
88 shaderString.append("\n");
89 }
90 }
91
92 shaderc_compiler_t compiler = gpu->shadercCompiler();
93
94 shaderc_compile_options_t options = shaderc_compile_options_initialize();
95 shaderc_compile_options_set_forced_version_profile(options, 140, shaderc_pro file_none);
96
97 shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage);
98 shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler,
99 shaderString. c_str(),
100 strlen(shader String.c_str()),
101 shadercStage,
102 "shader",
103 "main",
104 options);
105 shaderc_compile_options_release(options);
106 #ifdef SK_DEBUG
107 if (shaderc_result_get_num_errors(result)) {
108 SkDebugf("%s\n", shaderString.c_str());
109 SkDebugf("%s\n", shaderc_result_get_error_message(result));
110 return false;
111 }
112 #endif
113
114 VkShaderModuleCreateInfo moduleCreateInfo;
115 memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo));
116 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
117 moduleCreateInfo.pNext = nullptr;
118 moduleCreateInfo.flags = 0;
119 moduleCreateInfo.codeSize = shaderc_result_get_length(result);
120 moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result);
121
122 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device (),
123 &moduleCrea teInfo,
124 nullptr,
125 shaderModul e));
126 shaderc_result_release(result);
127 if (err) {
128 return false;
129 }
130
131 memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo));
132 stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
133 stageInfo->pNext = nullptr;
134 stageInfo->flags = 0;
135 stageInfo->stage = stage;
136 stageInfo->module = *shaderModule;
137 stageInfo->pName = "main";
138 stageInfo->pSpecializationInfo = nullptr;
139
140 return true;
141 }
142
143 GrVkProgram* GrVkProgramBuilder::finalize(GrPrimitiveType primitiveType,
144 const GrVkRenderPass& renderPass) {
145 VkDescriptorSetLayout dsLayout[2];
146 VkPipelineLayout pipelineLayout;
147 VkShaderModule vertShaderModule;
148 VkShaderModule fragShaderModule;
149
150 uint32_t numSamplers = fSamplerUniforms.count();
151
152 SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
153 new VkDescriptorSetLayoutBi nding[numSamplers]);
154 for (uint32_t i = 0; i < numSamplers; ++i) {
155 UniformHandle uniHandle = fSamplerUniforms[i];
156 GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniform Info(uniHandle);
157 SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType());
158 SkASSERT(0 == uniformInfo.fSetNumber);
159 SkASSERT(uniformInfo.fBinding == i);
160 dsSamplerBindings[i].binding = uniformInfo.fBinding;
161 dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_ SAMPLER;
162 dsSamplerBindings[i].descriptorCount = 1;
163 dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformIn fo.fVisibility);
164 dsSamplerBindings[i].pImmutableSamplers = nullptr;
165 }
166
167 VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
168 memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo ));
169 dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CR EATE_INFO;
170 dsSamplerLayoutCreateInfo.pNext = nullptr;
171 dsSamplerLayoutCreateInfo.flags = 0;
172 dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count();
173 // Setting to nullptr fixes an error in the param checker validation layer. Even though
174 // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
175 dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBi ndings.get() :
176 nullptr;
177
178 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
179 CreateDescriptorSetLayout(fGpu->device(),
180 &dsSamplerLayoutCreateInfo,
181 nullptr,
182 &dsLayout[GrVkUniformHandler:: kSamplerDescSet]));
183
184 // Create Uniform Buffer Descriptor
185 // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have
186 // binding 0 and the fragment binding 1.
187 VkDescriptorSetLayoutBinding dsUniBindings[2];
188 memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
189 dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
190 dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
191 dsUniBindings[0].descriptorCount = fUniformHandler.hasVertexUniforms() ? 1 : 0;
192 dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
193 dsUniBindings[0].pImmutableSamplers = nullptr;
194 dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
195 dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
196 dsUniBindings[1].descriptorCount = fUniformHandler.hasFragmentUniforms() ? 1 : 0;
197 dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
198 dsUniBindings[1].pImmutableSamplers = nullptr;
199
200 VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo;
201 memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo ));
202 dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CR EATE_INFO;
203 dsUniformLayoutCreateInfo.pNext = nullptr;
204 dsUniformLayoutCreateInfo.flags = 0;
205 dsUniformLayoutCreateInfo.bindingCount = 2;
206 dsUniformLayoutCreateInfo.pBindings = dsUniBindings;
207
208 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(
209 fGpu->device(),
210 &dsUniformLayoutCreateInfo,
211 nullptr,
212 &dsLayout[GrVkUniformHandler::kUnif ormBufferDescSet]));
213
214 // Create the VkPipelineLayout
215 VkPipelineLayoutCreateInfo layoutCreateInfo;
216 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
217 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
218 layoutCreateInfo.pNext = 0;
219 layoutCreateInfo.flags = 0;
220 layoutCreateInfo.setLayoutCount = 2;
221 layoutCreateInfo.pSetLayouts = dsLayout;
222 layoutCreateInfo.pushConstantRangeCount = 0;
223 layoutCreateInfo.pPushConstantRanges = nullptr;
224
225 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device() ,
226 &layoutCreateI nfo,
227 nullptr,
228 &pipelineLayou t));
229
230 // We need to enable the following extensions so that the compiler can corre ctly make spir-v
231 // from our glsl shaders.
232 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable \n");
233 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable \n");
234 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enabl e\n");
235 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enabl e\n");
236
237 this->finalizeShaders();
238
239 VkPipelineShaderStageCreateInfo shaderStageInfo[2];
240 SkAssertResult(CreateVkShaderModule(fGpu,
241 VK_SHADER_STAGE_VERTEX_BIT,
242 fVS,
243 &vertShaderModule,
244 &shaderStageInfo[0]));
245
246 SkAssertResult(CreateVkShaderModule(fGpu,
247 VK_SHADER_STAGE_FRAGMENT_BIT,
248 fFS,
249 &fragShaderModule,
250 &shaderStageInfo[1]));
251
252 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
253 GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
254 fPrimProc,
255 shaderStageInfo,
256 2,
257 primitiveType,
258 renderPass,
259 pipelineLayout);
260 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShad erModule,
261 nullptr));
262 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShad erModule,
263 nullptr));
264
265 if (!pipeline) {
266 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pi pelineLayout,
267 nullptr));
268 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device( ), dsLayout[0],
269 nullptr));
270 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device( ), dsLayout[1],
271 nullptr));
272 return nullptr;
273 }
274
275 return new GrVkProgram(fGpu,
276 pipeline,
277 pipelineLayout,
278 dsLayout,
279 fUniformHandles,
280 fUniformHandler.fUniforms,
281 fUniformHandler.fCurrentVertexUBOOffset,
282 fUniformHandler.fCurrentFragmentUBOOffset,
283 numSamplers,
284 fGeometryProcessor,
285 fXferProcessor,
286 fFragmentProcessors);
287 }
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkProgramBuilder.h ('k') | src/gpu/vk/GrVkProgramDataManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698