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 14GrVkProgram* GrVkProgramBuilder::CreateProgram(GrVkGpu* gpu, 15 const DrawArgs& args, 16 GrPrimitiveType primitiveType, 17 const GrVkRenderPass& renderPass) { 18 // create a builder. This will be handed off to effects so they can use it to add 19 // uniforms, varyings, textures, etc 20 GrVkProgramBuilder builder(gpu, args); 21 22 GrGLSLExpr4 inputColor; 23 GrGLSLExpr4 inputCoverage; 24 25 if (!builder.emitAndInstallProcs(&inputColor, 26 &inputCoverage, 27 gpu->vkCaps().maxSampledTextures())) { 28 builder.cleanupFragmentProcessors(); 29 return nullptr; 30 } 31 32 return builder.finalize(args, primitiveType, renderPass); 33} 34 35GrVkProgramBuilder::GrVkProgramBuilder(GrVkGpu* gpu, const DrawArgs& args) 36 : INHERITED(args) 37 , fGpu(gpu) 38 , fVaryingHandler(this) 39 , fUniformHandler(this) { 40} 41 42const GrCaps* GrVkProgramBuilder::caps() const { 43 return fGpu->caps(); 44} 45const GrGLSLCaps* GrVkProgramBuilder::glslCaps() const { 46 return fGpu->vkCaps().glslCaps(); 47} 48 49void GrVkProgramBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) { 50 outputColor.setLayoutQualifier("location = 0"); 51} 52 53void GrVkProgramBuilder::emitSamplers(const GrProcessor& processor, 54 GrGLSLTextureSampler::TextureSamplerArray* outSamplers) { 55 int numTextures = processor.numTextures(); 56 UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures); 57 SkString name; 58 for (int t = 0; t < numTextures; ++t) { 59 name.printf("%d", t); 60 localSamplerUniforms[t] = 61 fUniformHandler.addUniform(kFragment_GrShaderFlag, 62 kSampler2D_GrSLType, kDefault_GrSLPrecision, 63 name.c_str()); 64 outSamplers->emplace_back(localSamplerUniforms[t], processor.textureAccess(t)); 65 } 66} 67 68VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) { 69 VkShaderStageFlags flags = 0; 70 71 if (visibility & kVertex_GrShaderFlag) { 72 flags |= VK_SHADER_STAGE_VERTEX_BIT; 73 } 74 if (visibility & kGeometry_GrShaderFlag) { 75 flags |= VK_SHADER_STAGE_GEOMETRY_BIT; 76 } 77 if (visibility & kFragment_GrShaderFlag) { 78 flags |= VK_SHADER_STAGE_FRAGMENT_BIT; 79 } 80 return flags; 81} 82 83shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) { 84 if (VK_SHADER_STAGE_VERTEX_BIT == stage) { 85 return shaderc_glsl_vertex_shader; 86 } 87 SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage); 88 return shaderc_glsl_fragment_shader; 89} 90 91bool GrVkProgramBuilder::CreateVkShaderModule(const GrVkGpu* gpu, 92 VkShaderStageFlagBits stage, 93 const GrGLSLShaderBuilder& builder, 94 VkShaderModule* shaderModule, 95 VkPipelineShaderStageCreateInfo* stageInfo) { 96 SkString shaderString; 97 for (int i = 0; i < builder.fCompilerStrings.count(); ++i) { 98 if (builder.fCompilerStrings[i]) { 99 shaderString.append(builder.fCompilerStrings[i]); 100 shaderString.append("\n"); 101 } 102 } 103 104 shaderc_compiler_t compiler = gpu->shadercCompiler(); 105 106 shaderc_compile_options_t options = shaderc_compile_options_initialize(); 107 shaderc_compile_options_set_forced_version_profile(options, 140, shaderc_profile_none); 108 109 shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage); 110 shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler, 111 shaderString.c_str(), 112 strlen(shaderString.c_str()), 113 shadercStage, 114 "shader", 115 "main", 116 options); 117 shaderc_compile_options_release(options); 118#ifdef SK_DEBUG 119 if (shaderc_result_get_num_errors(result)) { 120 SkDebugf("%s\n", shaderString.c_str()); 121 SkDebugf("%s\n", shaderc_result_get_error_message(result)); 122 return false; 123 } 124#endif 125 126 VkShaderModuleCreateInfo moduleCreateInfo; 127 memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo)); 128 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 129 moduleCreateInfo.pNext = nullptr; 130 moduleCreateInfo.flags = 0; 131 moduleCreateInfo.codeSize = shaderc_result_get_length(result); 132 moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result); 133 134 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(), 135 &moduleCreateInfo, 136 nullptr, 137 shaderModule)); 138 shaderc_result_release(result); 139 if (err) { 140 return false; 141 } 142 143 memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo)); 144 stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 145 stageInfo->pNext = nullptr; 146 stageInfo->flags = 0; 147 stageInfo->stage = stage; 148 stageInfo->module = *shaderModule; 149 stageInfo->pName = "main"; 150 stageInfo->pSpecializationInfo = nullptr; 151 152 return true; 153} 154 155GrVkProgram* GrVkProgramBuilder::finalize(const DrawArgs& args, 156 GrPrimitiveType primitiveType, 157 const GrVkRenderPass& renderPass) { 158 VkDescriptorSetLayout dsLayout[2]; 159 VkPipelineLayout pipelineLayout; 160 VkShaderModule vertShaderModule; 161 VkShaderModule fragShaderModule; 162 163 uint32_t numSamplers = fSamplerUniforms.count(); 164 165 SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings( 166 new VkDescriptorSetLayoutBinding[numSamplers]); 167 for (uint32_t i = 0; i < numSamplers; ++i) { 168 UniformHandle uniHandle = fSamplerUniforms[i]; 169 GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle); 170 SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType()); 171 SkASSERT(0 == uniformInfo.fSetNumber); 172 SkASSERT(uniformInfo.fBinding == i); 173 dsSamplerBindings[i].binding = uniformInfo.fBinding; 174 dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 175 dsSamplerBindings[i].descriptorCount = 1; 176 dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility); 177 dsSamplerBindings[i].pImmutableSamplers = nullptr; 178 } 179 180 VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo; 181 memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); 182 dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 183 dsSamplerLayoutCreateInfo.pNext = nullptr; 184 dsSamplerLayoutCreateInfo.flags = 0; 185 dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count(); 186 // Setting to nullptr fixes an error in the param checker validation layer. Even though 187 // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null. 188 dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() : 189 nullptr; 190 191 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), 192 CreateDescriptorSetLayout(fGpu->device(), 193 &dsSamplerLayoutCreateInfo, 194 nullptr, 195 &dsLayout[GrVkUniformHandler::kSamplerDescSet])); 196 197 // Create Uniform Buffer Descriptor 198 // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have 199 // binding 0 and the fragment binding 1. 200 VkDescriptorSetLayoutBinding dsUniBindings[2]; 201 memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding)); 202 dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding; 203 dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 204 dsUniBindings[0].descriptorCount = fUniformHandler.hasVertexUniforms() ? 1 : 0; 205 dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 206 dsUniBindings[0].pImmutableSamplers = nullptr; 207 dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding; 208 dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 209 dsUniBindings[1].descriptorCount = fUniformHandler.hasFragmentUniforms() ? 1 : 0; 210 dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 211 dsUniBindings[1].pImmutableSamplers = nullptr; 212 213 VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo; 214 memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); 215 dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 216 dsUniformLayoutCreateInfo.pNext = nullptr; 217 dsUniformLayoutCreateInfo.flags = 0; 218 dsUniformLayoutCreateInfo.bindingCount = 2; 219 dsUniformLayoutCreateInfo.pBindings = dsUniBindings; 220 221 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout( 222 fGpu->device(), 223 &dsUniformLayoutCreateInfo, 224 nullptr, 225 &dsLayout[GrVkUniformHandler::kUniformBufferDescSet])); 226 227 // Create the VkPipelineLayout 228 VkPipelineLayoutCreateInfo layoutCreateInfo; 229 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); 230 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 231 layoutCreateInfo.pNext = 0; 232 layoutCreateInfo.flags = 0; 233 layoutCreateInfo.setLayoutCount = 2; 234 layoutCreateInfo.pSetLayouts = dsLayout; 235 layoutCreateInfo.pushConstantRangeCount = 0; 236 layoutCreateInfo.pPushConstantRanges = nullptr; 237 238 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(), 239 &layoutCreateInfo, 240 nullptr, 241 &pipelineLayout)); 242 243 // We need to enable the following extensions so that the compiler can correctly make spir-v 244 // from our glsl shaders. 245 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); 246 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); 247 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); 248 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); 249 250 this->finalizeShaders(); 251 252 VkPipelineShaderStageCreateInfo shaderStageInfo[2]; 253 SkAssertResult(CreateVkShaderModule(fGpu, 254 VK_SHADER_STAGE_VERTEX_BIT, 255 fVS, 256 &vertShaderModule, 257 &shaderStageInfo[0])); 258 259 SkAssertResult(CreateVkShaderModule(fGpu, 260 VK_SHADER_STAGE_FRAGMENT_BIT, 261 fFS, 262 &fragShaderModule, 263 &shaderStageInfo[1])); 264 265 GrVkResourceProvider& resourceProvider = fGpu->resourceProvider(); 266 GrVkPipeline* pipeline = resourceProvider.createPipeline(*args.fPipeline, 267 *args.fPrimitiveProcessor, 268 shaderStageInfo, 269 2, 270 primitiveType, 271 renderPass, 272 pipelineLayout); 273 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule, 274 nullptr)); 275 GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule, 276 nullptr)); 277 278 if (!pipeline) { 279 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout, 280 nullptr)); 281 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[0], 282 nullptr)); 283 GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[1], 284 nullptr)); 285 return nullptr; 286 } 287 288 289 GrVkDescriptorPool::DescriptorTypeCounts typeCounts; 290 typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2); 291 SkASSERT(numSamplers < 256); 292 typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (uint8_t)numSamplers); 293 GrVkDescriptorPool* descriptorPool = 294 fGpu->resourceProvider().findOrCreateCompatibleDescriptorPool(typeCounts); 295 296 VkDescriptorSetAllocateInfo dsAllocateInfo; 297 memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo)); 298 dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 299 dsAllocateInfo.pNext = nullptr; 300 dsAllocateInfo.descriptorPool = descriptorPool->descPool(); 301 dsAllocateInfo.descriptorSetCount = 2; 302 dsAllocateInfo.pSetLayouts = dsLayout; 303 304 VkDescriptorSet descriptorSets[2]; 305 GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(), 306 &dsAllocateInfo, 307 descriptorSets)); 308 309 return new GrVkProgram(fGpu, 310 pipeline, 311 pipelineLayout, 312 dsLayout, 313 descriptorPool, 314 descriptorSets, 315 fUniformHandles, 316 fUniformHandler.fUniforms, 317 fUniformHandler.fCurrentVertexUBOOffset, 318 fUniformHandler.fCurrentFragmentUBOOffset, 319 numSamplers, 320 fGeometryProcessor, 321 fXferProcessor, 322 fFragmentProcessors); 323} 324