Index: src/gpu/vk/GrVkUtil.cpp |
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp |
index e0d5daf99dc001437f993bc47414ddd92138c404..0d07e1f57a7318d4b3b613af361143fdb89be313 100644 |
--- a/src/gpu/vk/GrVkUtil.cpp |
+++ b/src/gpu/vk/GrVkUtil.cpp |
@@ -7,6 +7,11 @@ |
#include "GrVkUtil.h" |
+#include "vk/GrVkGpu.h" |
+#if USE_SKSL |
+#include "SkSLCompiler.h" |
+#endif |
+ |
bool GrPixelConfigToVkFormat(GrPixelConfig config, VkFormat* format) { |
VkFormat dontCare; |
if (!format) { |
@@ -249,3 +254,106 @@ bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSam |
return false; |
} |
} |
+ |
+#if USE_SKSL |
+SkSL::Program::Kind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) { |
+ if (VK_SHADER_STAGE_VERTEX_BIT == stage) { |
+ return SkSL::Program::kVertex_Kind; |
+ } |
+ SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage); |
+ return SkSL::Program::kFragment_Kind; |
+} |
+#else |
+shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) { |
+ if (VK_SHADER_STAGE_VERTEX_BIT == stage) { |
+ return shaderc_glsl_vertex_shader; |
+ } |
+ SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage); |
+ return shaderc_glsl_fragment_shader; |
+} |
+#endif |
+ |
+bool GrCompileVkShaderModule(const GrVkGpu* gpu, |
+ const char* shaderString, |
+ VkShaderStageFlagBits stage, |
+ VkShaderModule* shaderModule, |
+ VkPipelineShaderStageCreateInfo* stageInfo) { |
+ 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); |
+ moduleCreateInfo.pCode = (const uint32_t*)shaderString; |
+ } else { |
+ |
+#if USE_SKSL |
+ bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage), |
+ std::string(shaderString), |
+ &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), |
+ shadercStage, |
+ "shader", |
+ "main", |
+ options); |
+ shaderc_compile_options_release(options); |
+#ifdef SK_DEBUG |
+ if (shaderc_result_get_num_errors(result)) { |
+ SkDebugf("%s\n", shaderString); |
+ 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; |
+} |