/* * 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/vk/GrVkUtil.h" #include "include/gpu/GrDirectContext.h" #include "src/core/SkTraceEvent.h" #include "src/gpu/GrDataUtils.h" #include "src/gpu/GrDirectContextPriv.h" #include "src/gpu/vk/GrVkGpu.h" #include "src/sksl/SkSLCompiler.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; } } bool GrVkFormatNeedsYcbcrSampler(VkFormat format) { return format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; } bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSamples) { SkASSERT(samples >= 1); switch (samples) { case 1: *vkSamples = VK_SAMPLE_COUNT_1_BIT; return true; case 2: *vkSamples = VK_SAMPLE_COUNT_2_BIT; return true; case 4: *vkSamples = VK_SAMPLE_COUNT_4_BIT; return true; case 8: *vkSamples = VK_SAMPLE_COUNT_8_BIT; return true; case 16: *vkSamples = VK_SAMPLE_COUNT_16_BIT; 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; } if (VK_SHADER_STAGE_GEOMETRY_BIT == stage) { return SkSL::ProgramKind::kGeometry; } SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage); return SkSL::ProgramKind::kFragment; } bool GrCompileVkShaderModule(GrVkGpu* gpu, const SkSL::String& shaderString, VkShaderStageFlagBits stage, VkShaderModule* shaderModule, VkPipelineShaderStageCreateInfo* stageInfo, const SkSL::Program::Settings& settings, SkSL::String* outSPIRV, SkSL::Program::Inputs* outInputs) { TRACE_EVENT0("skia.shaders", "CompileVkShaderModule"); auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler(); std::unique_ptr 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 SkSL::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; } bool GrVkFormatIsCompressed(VkFormat vkFormat) { switch (vkFormat) { case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: case VK_FORMAT_BC1_RGB_UNORM_BLOCK: case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return true; default: return false; } SkUNREACHABLE; }