Home | History | Annotate | Download | only in vk
      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 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 
     35 GrVkProgramBuilder::GrVkProgramBuilder(GrVkGpu* gpu, const DrawArgs& args)
     36     : INHERITED(args)
     37     , fGpu(gpu)
     38     , fVaryingHandler(this)
     39     , fUniformHandler(this) {
     40 }
     41 
     42 const GrCaps* GrVkProgramBuilder::caps() const {
     43     return fGpu->caps();
     44 }
     45 const GrGLSLCaps* GrVkProgramBuilder::glslCaps() const {
     46     return fGpu->vkCaps().glslCaps();
     47 }
     48 
     49 void GrVkProgramBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
     50     outputColor.setLayoutQualifier("location = 0");
     51 }
     52 
     53 void 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 
     68 VkShaderStageFlags 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 
     83 shaderc_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 
     91 bool 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 
    155 GrVkProgram* 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