blob: 6363d96981d69ed15ebf640ad734c15e68631d0c [file] [log] [blame]
/*
* 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;
}