bool GrCompileVkShaderModule(const GrVkGpu* gpu, const char* shaderString, VkShaderStageFlagBits stage, VkShaderModule* shaderModule, VkPipelineShaderStageCreateInfo* stageInfo, const SkSL::Program::Settings& settings, SkSL::Program::Inputs* outInputs) { std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram( vk_shader_stage_to_skiasl_kind(stage), SkSL::String(shaderString), settings); if (!program) { SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str()); SkASSERT(false); } *outInputs = program->fInputs; SkSL::String code; if (!gpu->shaderCompiler()->toSPIRV(*program, &code)) { SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str()); return false; } VkShaderModuleCreateInfo moduleCreateInfo; memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo)); moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext = nullptr; moduleCreateInfo.flags = 0; moduleCreateInfo.codeSize = code.size(); moduleCreateInfo.pCode = (const uint32_t*)code.c_str(); VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(), &moduleCreateInfo, nullptr, shaderModule)); if (err) { return false; } memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo)); stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stageInfo->pNext = nullptr; stageInfo->flags = 0; stageInfo->stage = skiasl_kind_to_vk_shader_stage(program->fKind); stageInfo->module = *shaderModule; stageInfo->pName = "main"; stageInfo->pSpecializationInfo = nullptr; return true; }
bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu, VkShaderStageFlagBits stage, const GrGLSLShaderBuilder& builder, VkShaderModule* shaderModule, VkPipelineShaderStageCreateInfo* stageInfo) { SkString shaderString; for (int i = 0; i < builder.fCompilerStrings.count(); ++i) { if (builder.fCompilerStrings[i]) { shaderString.append(builder.fCompilerStrings[i]); shaderString.append("\n"); } } VkShaderModuleCreateInfo moduleCreateInfo; memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo)); moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext = nullptr; moduleCreateInfo.flags = 0; #if USE_SKSL std::string code; #else shaderc_compilation_result_t result = nullptr; #endif if (gpu->vkCaps().canUseGLSLForShaderModule()) { moduleCreateInfo.codeSize = strlen(shaderString.c_str()); moduleCreateInfo.pCode = (const uint32_t*)shaderString.c_str(); } else { #if USE_SKSL bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage), std::string(shaderString.c_str()), &code); if (!result) { SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str()); return false; } moduleCreateInfo.codeSize = code.size(); moduleCreateInfo.pCode = (const uint32_t*) code.c_str(); #else shaderc_compiler_t compiler = gpu->shadercCompiler(); shaderc_compile_options_t options = shaderc_compile_options_initialize(); shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage); result = shaderc_compile_into_spv(compiler, shaderString.c_str(), strlen(shaderString.c_str()), shadercStage, "shader", "main", options); shaderc_compile_options_release(options); #ifdef SK_DEBUG if (shaderc_result_get_num_errors(result)) { SkDebugf("%s\n", shaderString.c_str()); SkDebugf("%s\n", shaderc_result_get_error_message(result)); return false; } #endif // SK_DEBUG moduleCreateInfo.codeSize = shaderc_result_get_length(result); moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result); #endif // USE_SKSL } VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(), &moduleCreateInfo, nullptr, shaderModule)); if (!gpu->vkCaps().canUseGLSLForShaderModule()) { #if !USE_SKSL shaderc_result_release(result); #endif } if (err) { return false; } memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo)); stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stageInfo->pNext = nullptr; stageInfo->flags = 0; stageInfo->stage = stage; stageInfo->module = *shaderModule; stageInfo->pName = "main"; stageInfo->pSpecializationInfo = nullptr; return true; }