Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2704,10 +2704,6 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) {

// Regression test for https://github.com/flutter/flutter/issues/126701 .
TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
if (!BackendSupportsFragmentProgram()) {
GTEST_SKIP_("This backend doesn't support runtime effects.");
}

auto runtime_stages =
OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");

Expand Down Expand Up @@ -2741,10 +2737,6 @@ TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
}

TEST_P(AiksTest, DrawPaintTransformsBounds) {
if (!BackendSupportsFragmentProgram()) {
GTEST_SKIP_("This backend doesn't support runtime effects.");
}

auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
auto runtime_stage = runtime_stages[RuntimeStageBackend::kMetal];
ASSERT_TRUE(runtime_stage);
Expand Down
31 changes: 18 additions & 13 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "impeller/compiler/includer.h"
#include "impeller/compiler/logger.h"
#include "impeller/compiler/spirv_compiler.h"
#include "impeller/compiler/types.h"
#include "impeller/compiler/uniform_sorter.h"
#include "impeller/compiler/utilities.h"

Expand Down Expand Up @@ -122,15 +123,13 @@ static CompilerBackend CreateMSLCompiler(
static CompilerBackend CreateVulkanCompiler(
const spirv_cross::ParsedIR& ir,
const SourceOptions& source_options) {
// TODO(dnfield): It seems like what we'd want is a CompilerGLSL with
// vulkan_semantics set to true, but that has regressed some things on GLES
// somehow. In the mean time, go back to using CompilerMSL, but set the Metal
// Language version to something really high so that we don't get weird
// complaints about using Metal features while trying to build Vulkan shaders.
// https://github.com/flutter/flutter/issues/123795
return CreateMSLCompiler(
ir, source_options,
spirv_cross::CompilerMSL::Options::make_msl_version(3, 0, 0));
auto gl_compiler = std::make_shared<spirv_cross::CompilerGLSL>(ir);
spirv_cross::CompilerGLSL::Options sl_options;
sl_options.force_zero_initialized_variables = true;
sl_options.vertex.fixup_clipspace = true;
sl_options.vulkan_semantics = true;
gl_compiler->set_common_options(sl_options);
return CompilerBackend(gl_compiler);
}

static CompilerBackend CreateGLSLCompiler(const spirv_cross::ParsedIR& ir,
Expand Down Expand Up @@ -302,18 +301,23 @@ Compiler::Compiler(const std::shared_ptr<const fml::Mapping>& source_mapping,
} break;
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kVulkan: {
case TargetPlatform::kVulkan:
case TargetPlatform::kRuntimeStageVulkan: {
SPIRVCompilerTargetEnv target;

target.env = shaderc_target_env::shaderc_target_env_vulkan;
target.version = shaderc_env_version::shaderc_env_version_vulkan_1_1;
target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_3;

if (source_options.target_platform ==
TargetPlatform::kRuntimeStageVulkan) {
spirv_options.macro_definitions.push_back("IMPELLER_GRAPHICS_BACKEND");
spirv_options.relaxed_vulkan_rules = true;
}
spirv_options.target = target;
} break;
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageVulkan: {
case TargetPlatform::kRuntimeStageGLES: {
SPIRVCompilerTargetEnv target;

target.env = shaderc_target_env::shaderc_target_env_opengl;
Expand Down Expand Up @@ -398,7 +402,8 @@ Compiler::Compiler(const std::shared_ptr<const fml::Mapping>& source_mapping,
// If the target is Vulkan, our shading language is SPIRV which we already
// have. We just need to strip it of debug information. If it isn't, we need
// to invoke the appropriate compiler to compile the SPIRV to the target SL.
if (source_options.target_platform == TargetPlatform::kVulkan) {
if (source_options.target_platform == TargetPlatform::kVulkan ||
source_options.target_platform == TargetPlatform::kRuntimeStageVulkan) {
auto stripped_spirv_options = spirv_options;
stripped_spirv_options.generate_debug_info = false;
sl_mapping_ = spv_compiler.CompileToSPV(
Expand Down
5 changes: 4 additions & 1 deletion impeller/compiler/compiler_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ CompilerBackend::CompilerBackend(MSLCompiler compiler)
: CompilerBackend(Type::kMSL, compiler) {}

CompilerBackend::CompilerBackend(GLSLCompiler compiler)
: CompilerBackend(Type::kGLSL, compiler) {}
: CompilerBackend(compiler->get_common_options().vulkan_semantics
? Type::kGLSLVulkan
: Type::kGLSL,
compiler) {}

CompilerBackend::CompilerBackend(SkSLCompiler compiler)
: CompilerBackend(Type::kSkSL, compiler) {}
Expand Down
1 change: 1 addition & 0 deletions impeller/compiler/compiler_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct CompilerBackend {
enum class Type {
kMSL,
kGLSL,
kGLSLVulkan,
kSkSL,
};

Expand Down
120 changes: 71 additions & 49 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sstream>

#include "flutter/fml/logging.h"
#include "fml/backtrace.h"
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/compiler/code_gen_template.h"
Expand All @@ -23,54 +24,12 @@
#include "impeller/geometry/half.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"
#include "impeller/runtime_stage/runtime_stage.h"
#include "spirv_common.hpp"

namespace impeller {
namespace compiler {

static std::string BaseTypeToString(spirv_cross::SPIRType::BaseType type) {
using Type = spirv_cross::SPIRType::BaseType;
switch (type) {
case Type::Void:
return "ShaderType::kVoid";
case Type::Boolean:
return "ShaderType::kBoolean";
case Type::SByte:
return "ShaderType::kSignedByte";
case Type::UByte:
return "ShaderType::kUnsignedByte";
case Type::Short:
return "ShaderType::kSignedShort";
case Type::UShort:
return "ShaderType::kUnsignedShort";
case Type::Int:
return "ShaderType::kSignedInt";
case Type::UInt:
return "ShaderType::kUnsignedInt";
case Type::Int64:
return "ShaderType::kSignedInt64";
case Type::UInt64:
return "ShaderType::kUnsignedInt64";
case Type::AtomicCounter:
return "ShaderType::kAtomicCounter";
case Type::Half:
return "ShaderType::kHalfFloat";
case Type::Float:
return "ShaderType::kFloat";
case Type::Double:
return "ShaderType::kDouble";
case Type::Struct:
return "ShaderType::kStruct";
case Type::Image:
return "ShaderType::kImage";
case Type::SampledImage:
return "ShaderType::kSampledImage";
case Type::Sampler:
return "ShaderType::kSampler";
default:
return "ShaderType::kUnknown";
}
}

static std::string ExecutionModelToString(spv::ExecutionModel model) {
switch (model) {
case spv::ExecutionModel::ExecutionModelVertex:
Expand Down Expand Up @@ -370,7 +329,6 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
// Sort the IR so that the uniforms are in declaration order.
std::vector<spirv_cross::ID> uniforms =
SortUniforms(ir_.get(), compiler_.GetCompiler());

for (auto& sorted_id : uniforms) {
auto var = ir_->ids[sorted_id].get<spirv_cross::SPIRVariable>();
const auto spir_type = compiler_->get_type(var.basetype);
Expand All @@ -383,9 +341,69 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
uniform_description.columns = spir_type.columns;
uniform_description.bit_width = spir_type.width;
uniform_description.array_elements = GetArrayElements(spir_type);
FML_CHECK(data->backend != RuntimeStageBackend::kVulkan ||
spir_type.basetype ==
spirv_cross::SPIRType::BaseType::SampledImage)
<< "Vulkan runtime effect had unexpected uniforms outside of the "
"uniform buffer object.";
data->uniforms.emplace_back(std::move(uniform_description));
}

const auto ubos = compiler_->get_shader_resources().uniform_buffers;
if (data->backend == RuntimeStageBackend::kVulkan && !ubos.empty()) {
if (ubos.size() != 1 && ubos[0].name != RuntimeStage::kVulkanUBOName) {
VALIDATION_LOG << "Expected a single UBO resource named "
"'"
<< RuntimeStage::kVulkanUBOName
<< "' "
"for Vulkan runtime stage backend.";
return nullptr;
}

const auto& ubo = ubos[0];

auto members = ReadStructMembers(ubo.type_id);
std::vector<uint8_t> struct_layout;
size_t float_count = 0;

for (size_t i = 0; i < members.size(); i += 1) {
const auto& member = members[i];
std::vector<int> bytes;
switch (member.underlying_type) {
case StructMember::UnderlyingType::kPadding: {
size_t padding_count =
(member.size + sizeof(float) - 1) / sizeof(float);
while (padding_count > 0) {
struct_layout.push_back(0);
padding_count--;
}
break;
}
case StructMember::UnderlyingType::kFloat: {
size_t member_float_count = member.byte_length / sizeof(float);
float_count += member_float_count;
while (member_float_count > 0) {
struct_layout.push_back(1);
member_float_count--;
}
break;
}
case StructMember::UnderlyingType::kOther:
VALIDATION_LOG << "Non-floating-type struct member " << member.name
<< " is not supported.";
return nullptr;
}
}
data->uniforms.emplace_back(UniformDescription{
.name = ubo.name,
.location = 64, // Magic constant that must match the descriptor set
// location for fragment programs.
.type = spirv_cross::SPIRType::Struct,
.struct_layout = std::move(struct_layout),
.struct_float_count = float_count,
});
}

// We only need to worry about storing vertex attributes.
if (entrypoints.front().execution_model == spv::ExecutionModelVertex) {
const auto inputs = compiler_->get_shader_resources().stage_inputs;
Expand Down Expand Up @@ -532,6 +550,8 @@ static std::string ToString(CompilerBackend::Type type) {
return "Metal Shading Language";
case CompilerBackend::Type::kGLSL:
return "OpenGL Shading Language";
case CompilerBackend::Type::kGLSLVulkan:
return "OpenGL Shading Language (Relaxed Vulkan Semantics)";
case CompilerBackend::Type::kSkSL:
return "SkSL Shading Language";
}
Expand Down Expand Up @@ -627,7 +647,7 @@ std::optional<nlohmann::json::object_t> Reflector::ReflectType(

const auto type = compiler_->get_type(type_id);

result["type_name"] = BaseTypeToString(type.basetype);
result["type_name"] = StructMember::BaseTypeToString(type.basetype);
result["bit_width"] = type.width;
result["vec_size"] = type.vecsize;
result["columns"] = type.columns;
Expand All @@ -637,7 +657,8 @@ std::optional<nlohmann::json::object_t> Reflector::ReflectType(
auto member = nlohmann::json::object_t{};
member["name"] = struct_member.name;
member["type"] = struct_member.type;
member["base_type"] = BaseTypeToString(struct_member.base_type);
member["base_type"] =
StructMember::BaseTypeToString(struct_member.base_type);
member["offset"] = struct_member.offset;
member["size"] = struct_member.size;
member["byte_length"] = struct_member.byte_length;
Expand Down Expand Up @@ -1117,7 +1138,8 @@ nlohmann::json::object_t Reflector::EmitStructDefinition(
auto& member = members.emplace_back(nlohmann::json::object_t{});
member["name"] = struct_member.name;
member["type"] = struct_member.type;
member["base_type"] = BaseTypeToString(struct_member.base_type);
member["base_type"] =
StructMember::BaseTypeToString(struct_member.base_type);
member["offset"] = struct_member.offset;
member["byte_length"] = struct_member.byte_length;
if (struct_member.array_elements.has_value()) {
Expand All @@ -1142,7 +1164,7 @@ static VertexType VertexTypeFromInputResource(
const spirv_cross::Resource* resource) {
VertexType result;
result.variable_name = resource->name;
const auto type = compiler.get_type(resource->type_id);
const auto& type = compiler.get_type(resource->type_id);
result.base_type = type.basetype;
const auto total_size = type.columns * type.vecsize * type.width / 8u;
result.byte_length = total_size;
Expand Down
Loading