[impellerc] Namespace user functions (flutter/engine#35155)

This commit is contained in:
Zachary Anderson 2022-08-04 12:10:38 -07:00 committed by GitHub
parent e1a6ff373d
commit da2eeac15b
5 changed files with 77 additions and 0 deletions

View File

@ -38,6 +38,8 @@ std::string CompilerSkSL::compile() {
backend.use_array_constructor = true;
backend.workgroup_size_is_hidden = true;
fixup_user_functions();
fixup_anonymous_struct_names();
fixup_type_alias();
reorder_type_alias();
@ -72,6 +74,30 @@ std::string CompilerSkSL::compile() {
return buffer.str();
}
void CompilerSkSL::fixup_user_functions() {
const std::string prefix = "__flutter_local_";
ir.for_each_typed_id<SPIRFunction>([&](uint32_t, const SPIRFunction& func) {
const auto& original_name = get_name(func.self);
// Just in case. Don't add the prefix a second time.
if (original_name.rfind(prefix, 0) == 0) {
return;
}
std::string new_name = prefix + original_name;
set_name(func.self, new_name);
});
ir.for_each_typed_id<SPIRFunctionPrototype>(
[&](uint32_t, const SPIRFunctionPrototype& func) {
const auto& original_name = get_name(func.self);
// Just in case. Don't add the prefix a second time.
if (original_name.rfind(prefix, 0) == 0) {
return;
}
std::string new_name = prefix + original_name;
set_name(func.self, new_name);
});
}
void CompilerSkSL::emit_header() {
statement("// This SkSL shader is autogenerated by spirv-cross.");
statement("");

View File

@ -38,6 +38,8 @@ class CompilerSkSL : public spirv_cross::CompilerGLSL {
void emit_uniform(const spirv_cross::SPIRVariable& var) override;
void fixup_user_functions();
void detect_unsupported_resources();
bool emit_constant_resources();
bool emit_struct_resources();

View File

@ -11,6 +11,7 @@ if (enable_unittests) {
"blue_green_sampler.frag",
"children_and_uniforms.frag",
"functions.frag",
"no_builtin_redefinition.frag",
"no_uniforms.frag",
"simple.frag",
"uniforms.frag",

View File

@ -0,0 +1,38 @@
#version 320 es
// 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.
precision highp float;
layout ( location = 0 ) out vec4 oColor;
layout ( location = 0 ) uniform float a; // should be 1.0
float saturate(float x) {
return clamp(x, 0.0, 1.0);
}
float addA(float x) {
return x + a;
}
vec2 pairWithA(float x) {
return vec2(x, a);
}
vec3 composedFunction(float x) {
return vec3(addA(x), pairWithA(x));
}
float multiParam(float x, float y, float z) {
return x * y * z * a;
}
void main() {
float x = saturate(addA(0.0)); // x = 0 + 1;
vec3 v3 = composedFunction(x); // v3 = vec3(2, 1, 1);
x = multiParam(v3.x, v3.y, v3.z); // x = 2 * 1 * 1 * 1;
oColor = vec4(0.0, x / 2.0, 0.0, 1.0); // vec4(0, 1, 0, 1);
}

View File

@ -118,6 +118,16 @@ void main() async {
expect(throws, equals(true));
});
test('user defined functions do not redefine builtins', () async {
final FragmentProgram program = await FragmentProgram.fromAsset(
'no_builtin_redefinition.frag.iplr',
);
final Shader shader = program.shader(
floatUniforms: Float32List.fromList(<double>[1.0]),
);
await _expectShaderRendersGreen(shader);
});
test('fromAsset accepts a shader with no uniforms', () async {
final FragmentProgram program = await FragmentProgram.fromAsset(
'no_uniforms.frag.iplr',