| OLD | NEW | 
|---|
|  | (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 } |  | 
| OLD | NEW | 
|---|