blob: 08b4eb9b14c7abf679ed049224047bcf3860c646 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/compiler/types.h"
#include <filesystem>
#include <sstream>
#include "flutter/fml/logging.h"
#include "impeller/compiler/utilities.h"
namespace impeller {
namespace compiler {
static bool StringEndWith(const std::string& string,
const std::string& suffix) {
if (suffix.size() > string.size()) {
return false;
}
if (suffix.empty() || suffix.empty()) {
return false;
}
return string.rfind(suffix) == (string.size() - suffix.size());
}
SourceType SourceTypeFromFileName(const std::string& file_name) {
if (StringEndWith(file_name, ".vert")) {
return SourceType::kVertexShader;
}
if (StringEndWith(file_name, ".frag")) {
return SourceType::kFragmentShader;
}
if (StringEndWith(file_name, ".tesc")) {
return SourceType::kTessellationControlShader;
}
if (StringEndWith(file_name, ".tese")) {
return SourceType::kTessellationEvaluationShader;
}
if (StringEndWith(file_name, ".comp")) {
return SourceType::kComputeShader;
}
return SourceType::kUnknown;
}
std::string TargetPlatformToString(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kUnknown:
return "Unknown";
case TargetPlatform::kMetalDesktop:
return "MetalDesktop";
case TargetPlatform::kMetalIOS:
return "MetaliOS";
case TargetPlatform::kOpenGLES:
return "OpenGLES";
case TargetPlatform::kOpenGLDesktop:
return "OpenGLDesktop";
case TargetPlatform::kVulkan:
return "Vulkan";
case TargetPlatform::kRuntimeStageMetal:
return "RuntimeStageMetal";
case TargetPlatform::kRuntimeStageGLES:
return "RuntimeStageGLES";
case TargetPlatform::kSkSL:
return "SkSL";
}
FML_UNREACHABLE();
}
std::string SourceLanguageToString(SourceLanguage source_language) {
switch (source_language) {
case SourceLanguage::kUnknown:
return "Unknown";
case SourceLanguage::kGLSL:
return "GLSL";
case SourceLanguage::kHLSL:
return "HLSL";
}
}
std::string EntryPointFunctionNameFromSourceName(
const std::string& file_name,
SourceType type,
SourceLanguage source_language,
const std::string& entry_point_name) {
if (source_language == SourceLanguage::kHLSL) {
return entry_point_name;
}
std::stringstream stream;
std::filesystem::path file_path(file_name);
stream << Utf8FromPath(file_path.stem()) << "_";
switch (type) {
case SourceType::kUnknown:
stream << "unknown";
break;
case SourceType::kVertexShader:
stream << "vertex";
break;
case SourceType::kFragmentShader:
stream << "fragment";
break;
case SourceType::kTessellationControlShader:
stream << "tess_control";
break;
case SourceType::kTessellationEvaluationShader:
stream << "tess_eval";
break;
case SourceType::kComputeShader:
stream << "compute";
break;
}
stream << "_main";
return stream.str();
}
bool TargetPlatformNeedsSL(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kMetalIOS:
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kSkSL:
case TargetPlatform::kVulkan:
return true;
case TargetPlatform::kUnknown:
return false;
}
FML_UNREACHABLE();
}
bool TargetPlatformNeedsReflection(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kMetalIOS:
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kVulkan:
return true;
case TargetPlatform::kUnknown:
case TargetPlatform::kSkSL:
return false;
}
FML_UNREACHABLE();
}
std::string ShaderCErrorToString(shaderc_compilation_status status) {
using Status = shaderc_compilation_status;
switch (status) {
case Status::shaderc_compilation_status_success:
return "Success";
case Status::shaderc_compilation_status_invalid_stage:
return "Invalid shader stage specified";
case Status::shaderc_compilation_status_compilation_error:
return "Compilation error";
case Status::shaderc_compilation_status_internal_error:
return "Internal error";
case Status::shaderc_compilation_status_null_result_object:
return "Internal error. Null result object";
case Status::shaderc_compilation_status_invalid_assembly:
return "Invalid assembly";
case Status::shaderc_compilation_status_validation_error:
return "Validation error";
case Status::shaderc_compilation_status_transformation_error:
return "Transformation error";
case Status::shaderc_compilation_status_configuration_error:
return "Configuration error";
}
return "Unknown internal error";
}
shaderc_shader_kind ToShaderCShaderKind(SourceType type) {
switch (type) {
case SourceType::kVertexShader:
return shaderc_shader_kind::shaderc_vertex_shader;
case SourceType::kFragmentShader:
return shaderc_shader_kind::shaderc_fragment_shader;
case SourceType::kTessellationControlShader:
return shaderc_shader_kind::shaderc_tess_control_shader;
case SourceType::kTessellationEvaluationShader:
return shaderc_shader_kind::shaderc_tess_evaluation_shader;
case SourceType::kComputeShader:
return shaderc_shader_kind::shaderc_compute_shader;
case SourceType::kUnknown:
break;
}
return shaderc_shader_kind::shaderc_glsl_infer_from_source;
}
spv::ExecutionModel ToExecutionModel(SourceType type) {
switch (type) {
case SourceType::kVertexShader:
return spv::ExecutionModel::ExecutionModelVertex;
case SourceType::kFragmentShader:
return spv::ExecutionModel::ExecutionModelFragment;
case SourceType::kTessellationControlShader:
return spv::ExecutionModel::ExecutionModelTessellationControl;
case SourceType::kTessellationEvaluationShader:
return spv::ExecutionModel::ExecutionModelTessellationEvaluation;
case SourceType::kComputeShader:
return spv::ExecutionModel::ExecutionModelGLCompute;
case SourceType::kUnknown:
break;
}
return spv::ExecutionModel::ExecutionModelMax;
}
spirv_cross::CompilerMSL::Options::Platform TargetPlatformToMSLPlatform(
TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kMetalIOS:
case TargetPlatform::kRuntimeStageMetal:
return spirv_cross::CompilerMSL::Options::Platform::iOS;
case TargetPlatform::kMetalDesktop:
return spirv_cross::CompilerMSL::Options::Platform::macOS;
case TargetPlatform::kSkSL:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kVulkan:
case TargetPlatform::kUnknown:
return spirv_cross::CompilerMSL::Options::Platform::macOS;
}
FML_UNREACHABLE();
}
std::string SourceTypeToString(SourceType type) {
switch (type) {
case SourceType::kUnknown:
return "unknown";
case SourceType::kVertexShader:
return "vert";
case SourceType::kFragmentShader:
return "frag";
case SourceType::kTessellationControlShader:
return "tesc";
case SourceType::kTessellationEvaluationShader:
return "tese";
case SourceType::kComputeShader:
return "comp";
}
FML_UNREACHABLE();
}
std::string TargetPlatformSLExtension(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kUnknown:
return "unknown";
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
case TargetPlatform::kRuntimeStageMetal:
return "metal";
case TargetPlatform::kSkSL:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
return "glsl";
case TargetPlatform::kVulkan:
return "vk.spirv";
}
FML_UNREACHABLE();
}
bool TargetPlatformIsOpenGL(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
return true;
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kMetalIOS:
case TargetPlatform::kUnknown:
case TargetPlatform::kSkSL:
case TargetPlatform::kVulkan:
return false;
}
FML_UNREACHABLE();
}
bool TargetPlatformIsMetal(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
case TargetPlatform::kRuntimeStageMetal:
return true;
case TargetPlatform::kUnknown:
case TargetPlatform::kSkSL:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kVulkan:
return false;
}
FML_UNREACHABLE();
}
bool TargetPlatformBundlesSkSL(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kSkSL:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
return true;
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
case TargetPlatform::kUnknown:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kVulkan:
return false;
}
FML_UNREACHABLE();
}
} // namespace compiler
} // namespace impeller