| 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 |