| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/ganesh/vk/GrVkUtil.h" |
| |
| #include "include/gpu/GrDirectContext.h" |
| #include "include/private/SkSLProgramKind.h" |
| #include "src/core/SkTraceEvent.h" |
| #include "src/gpu/ganesh/GrDataUtils.h" |
| #include "src/gpu/ganesh/GrDirectContextPriv.h" |
| #include "src/gpu/ganesh/vk/GrVkGpu.h" |
| #include "src/sksl/SkSLCompiler.h" |
| #include "src/sksl/SkSLProgramSettings.h" |
| |
| bool GrVkFormatIsSupported(VkFormat format) { |
| switch (format) { |
| case VK_FORMAT_R8G8B8A8_UNORM: |
| case VK_FORMAT_B8G8R8A8_UNORM: |
| case VK_FORMAT_R8G8B8A8_SRGB: |
| case VK_FORMAT_R8G8B8_UNORM: |
| case VK_FORMAT_R8G8_UNORM: |
| case VK_FORMAT_A2B10G10R10_UNORM_PACK32: |
| case VK_FORMAT_A2R10G10B10_UNORM_PACK32: |
| case VK_FORMAT_R5G6B5_UNORM_PACK16: |
| case VK_FORMAT_B4G4R4A4_UNORM_PACK16: |
| case VK_FORMAT_R4G4B4A4_UNORM_PACK16: |
| case VK_FORMAT_R8_UNORM: |
| case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: |
| case VK_FORMAT_BC1_RGB_UNORM_BLOCK: |
| case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: |
| case VK_FORMAT_R16G16B16A16_SFLOAT: |
| case VK_FORMAT_R16_SFLOAT: |
| case VK_FORMAT_R16_UNORM: |
| case VK_FORMAT_R16G16_UNORM: |
| case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: |
| case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: |
| case VK_FORMAT_R16G16B16A16_UNORM: |
| case VK_FORMAT_R16G16_SFLOAT: |
| case VK_FORMAT_S8_UINT: |
| case VK_FORMAT_D24_UNORM_S8_UINT: |
| case VK_FORMAT_D32_SFLOAT_S8_UINT: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| SkSL::ProgramKind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) { |
| if (VK_SHADER_STAGE_VERTEX_BIT == stage) { |
| return SkSL::ProgramKind::kVertex; |
| } |
| SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage); |
| return SkSL::ProgramKind::kFragment; |
| } |
| |
| bool GrCompileVkShaderModule(GrVkGpu* gpu, |
| const std::string& shaderString, |
| VkShaderStageFlagBits stage, |
| VkShaderModule* shaderModule, |
| VkPipelineShaderStageCreateInfo* stageInfo, |
| const SkSL::ProgramSettings& settings, |
| std::string* outSPIRV, |
| SkSL::Program::Inputs* outInputs) { |
| TRACE_EVENT0("skia.shaders", "CompileVkShaderModule"); |
| auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler(); |
| std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram( |
| vk_shader_stage_to_skiasl_kind(stage), shaderString, settings); |
| if (!program) { |
| errorHandler->compileError(shaderString.c_str(), |
| gpu->shaderCompiler()->errorText().c_str()); |
| return false; |
| } |
| *outInputs = program->fInputs; |
| if (!gpu->shaderCompiler()->toSPIRV(*program, outSPIRV)) { |
| errorHandler->compileError(shaderString.c_str(), |
| gpu->shaderCompiler()->errorText().c_str()); |
| return false; |
| } |
| |
| return GrInstallVkShaderModule(gpu, *outSPIRV, stage, shaderModule, stageInfo); |
| } |
| |
| bool GrInstallVkShaderModule(GrVkGpu* gpu, |
| const std::string& spirv, |
| VkShaderStageFlagBits stage, |
| VkShaderModule* shaderModule, |
| VkPipelineShaderStageCreateInfo* stageInfo) { |
| TRACE_EVENT0("skia.shaders", "InstallVkShaderModule"); |
| VkShaderModuleCreateInfo moduleCreateInfo; |
| memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo)); |
| moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; |
| moduleCreateInfo.pNext = nullptr; |
| moduleCreateInfo.flags = 0; |
| moduleCreateInfo.codeSize = spirv.size(); |
| moduleCreateInfo.pCode = (const uint32_t*)spirv.c_str(); |
| |
| VkResult err; |
| GR_VK_CALL_RESULT(gpu, err, 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 = stage; |
| stageInfo->module = *shaderModule; |
| stageInfo->pName = "main"; |
| stageInfo->pSpecializationInfo = nullptr; |
| |
| return true; |
| } |
| |