Add SkSL test for functions that operate on structs
This is a known deficiency of runtime effects, next step is to fix how they manage function signatures to solve the problem. Bug: skia:10939 Change-Id: Id934e0acdf774b03bd6edce78d7b2c077bdeae00 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360603 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
00fea5b41f
commit
bf7b4b8890
@ -371,6 +371,7 @@ sksl_shared_tests = [
|
||||
"/sksl/shared/StaticSwitchWithStaticConditionalBreak.sksl",
|
||||
"/sksl/shared/StaticSwitchWithStaticConditionalBreakInsideBlock.sksl",
|
||||
"/sksl/shared/Structs.sksl",
|
||||
"/sksl/shared/StructsInFunctions.sksl",
|
||||
"/sksl/shared/StructMaxDepth.sksl",
|
||||
"/sksl/shared/Switch.sksl",
|
||||
"/sksl/shared/SwitchContainingDeadCode.sksl",
|
||||
|
30
resources/sksl/shared/StructsInFunctions.sksl
Normal file
30
resources/sksl/shared/StructsInFunctions.sksl
Normal file
@ -0,0 +1,30 @@
|
||||
/*#pragma settings NoInline*/
|
||||
|
||||
uniform half4 colorRed, colorGreen;
|
||||
|
||||
struct S { float x; int y; };
|
||||
|
||||
S returns_a_struct() {
|
||||
S s;
|
||||
s.x = 1;
|
||||
s.y = 2;
|
||||
return s;
|
||||
}
|
||||
|
||||
float accepts_a_struct(S s) {
|
||||
return s.x + float(s.y);
|
||||
}
|
||||
|
||||
void modifies_a_struct(inout S s) {
|
||||
s.x++;
|
||||
s.y++;
|
||||
}
|
||||
|
||||
half4 main() {
|
||||
S s = returns_a_struct();
|
||||
float x = accepts_a_struct(s);
|
||||
modifies_a_struct(s);
|
||||
|
||||
bool valid = (x == 3) && (s.x == 2) && (s.y == 3);
|
||||
return valid ? colorGreen : colorRed;
|
||||
}
|
@ -108,6 +108,11 @@ SKSL_TEST(SkSLVectorVectorFolding, "folding/VectorVectorFolding.sksl")
|
||||
|
||||
SKSL_TEST(SkSLForLoopControlFlow, "shared/ForLoopControlFlow.sksl")
|
||||
|
||||
/*
|
||||
TODO(skia:10939): enable this test when Runtime Effects supports structs in function signatures
|
||||
SKSL_TEST(SkSLStructsInFunctions, "shared/StructsInFunctions.sksl")
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO(skia:11209): enable these tests when Runtime Effects have support for ES3
|
||||
|
||||
|
168
tests/sksl/shared/StructsInFunctions.asm.frag
Normal file
168
tests/sksl/shared/StructsInFunctions.asm.frag
Normal file
@ -0,0 +1,168 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: SPIR-V validation error: Uniform OpVariable <id> '13[%colorRed]' has illegal type.
|
||||
From Vulkan spec, section 14.5.2:
|
||||
Variables identified with the Uniform storage class are used to access transparent buffer backed resources. Such variables must be typed as OpTypeStruct, or an array of this type
|
||||
%colorRed = OpVariable %_ptr_Uniform_v4float Uniform
|
||||
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %_entrypoint "_entrypoint" %sk_FragColor %sk_Clockwise
|
||||
OpExecutionMode %_entrypoint OriginUpperLeft
|
||||
OpName %sk_FragColor "sk_FragColor"
|
||||
OpName %sk_Clockwise "sk_Clockwise"
|
||||
OpName %colorRed "colorRed"
|
||||
OpName %colorGreen "colorGreen"
|
||||
OpName %_entrypoint "_entrypoint"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "x"
|
||||
OpMemberName %S 1 "y"
|
||||
OpName %returns_a_struct "returns_a_struct"
|
||||
OpName %s "s"
|
||||
OpName %accepts_a_struct "accepts_a_struct"
|
||||
OpName %modifies_a_struct "modifies_a_struct"
|
||||
OpName %main "main"
|
||||
OpName %s_0 "s"
|
||||
OpName %x "x"
|
||||
OpName %valid "valid"
|
||||
OpDecorate %sk_FragColor RelaxedPrecision
|
||||
OpDecorate %sk_FragColor Location 0
|
||||
OpDecorate %sk_FragColor Index 0
|
||||
OpDecorate %sk_Clockwise RelaxedPrecision
|
||||
OpDecorate %sk_Clockwise BuiltIn FrontFacing
|
||||
OpDecorate %colorRed RelaxedPrecision
|
||||
OpDecorate %colorRed DescriptorSet 0
|
||||
OpDecorate %colorGreen RelaxedPrecision
|
||||
OpDecorate %colorGreen DescriptorSet 0
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpMemberDecorate %S 1 Offset 4
|
||||
OpDecorate %35 RelaxedPrecision
|
||||
OpDecorate %59 RelaxedPrecision
|
||||
OpDecorate %83 RelaxedPrecision
|
||||
OpDecorate %89 RelaxedPrecision
|
||||
OpDecorate %90 RelaxedPrecision
|
||||
OpDecorate %91 RelaxedPrecision
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%sk_FragColor = OpVariable %_ptr_Output_v4float Output
|
||||
%bool = OpTypeBool
|
||||
%_ptr_Input_bool = OpTypePointer Input %bool
|
||||
%sk_Clockwise = OpVariable %_ptr_Input_bool Input
|
||||
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
|
||||
%colorRed = OpVariable %_ptr_Uniform_v4float Uniform
|
||||
%colorGreen = OpVariable %_ptr_Uniform_v4float Uniform
|
||||
%void = OpTypeVoid
|
||||
%18 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%S = OpTypeStruct %float %int
|
||||
%23 = OpTypeFunction %S
|
||||
%_ptr_Function_S = OpTypePointer Function %S
|
||||
%float_1 = OpConstant %float 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%36 = OpTypeFunction %float %_ptr_Function_S
|
||||
%45 = OpTypeFunction %void %_ptr_Function_S
|
||||
%54 = OpTypeFunction %v4float
|
||||
%_ptr_Function_bool = OpTypePointer Function %bool
|
||||
%false = OpConstantFalse %bool
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_2 = OpConstant %float 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_entrypoint = OpFunction %void None %18
|
||||
%19 = OpLabel
|
||||
%20 = OpFunctionCall %v4float %main
|
||||
OpStore %sk_FragColor %20
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%returns_a_struct = OpFunction %S None %23
|
||||
%24 = OpLabel
|
||||
%s = OpVariable %_ptr_Function_S Function
|
||||
%29 = OpAccessChain %_ptr_Function_float %s %int_0
|
||||
OpStore %29 %float_1
|
||||
%33 = OpAccessChain %_ptr_Function_int %s %int_1
|
||||
OpStore %33 %int_2
|
||||
%35 = OpLoad %S %s
|
||||
OpReturnValue %35
|
||||
OpFunctionEnd
|
||||
%accepts_a_struct = OpFunction %float None %36
|
||||
%37 = OpFunctionParameter %_ptr_Function_S
|
||||
%38 = OpLabel
|
||||
%39 = OpAccessChain %_ptr_Function_float %37 %int_0
|
||||
%40 = OpLoad %float %39
|
||||
%41 = OpAccessChain %_ptr_Function_int %37 %int_1
|
||||
%42 = OpLoad %int %41
|
||||
%43 = OpConvertSToF %float %42
|
||||
%44 = OpFAdd %float %40 %43
|
||||
OpReturnValue %44
|
||||
OpFunctionEnd
|
||||
%modifies_a_struct = OpFunction %void None %45
|
||||
%46 = OpFunctionParameter %_ptr_Function_S
|
||||
%47 = OpLabel
|
||||
%48 = OpAccessChain %_ptr_Function_float %46 %int_0
|
||||
%49 = OpLoad %float %48
|
||||
%50 = OpFAdd %float %49 %float_1
|
||||
OpStore %48 %50
|
||||
%51 = OpAccessChain %_ptr_Function_int %46 %int_1
|
||||
%52 = OpLoad %int %51
|
||||
%53 = OpIAdd %int %52 %int_1
|
||||
OpStore %51 %53
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %v4float None %54
|
||||
%55 = OpLabel
|
||||
%s_0 = OpVariable %_ptr_Function_S Function
|
||||
%x = OpVariable %_ptr_Function_float Function
|
||||
%60 = OpVariable %_ptr_Function_S Function
|
||||
%valid = OpVariable %_ptr_Function_bool Function
|
||||
%84 = OpVariable %_ptr_Function_v4float Function
|
||||
%57 = OpFunctionCall %S %returns_a_struct
|
||||
OpStore %s_0 %57
|
||||
%59 = OpLoad %S %s_0
|
||||
OpStore %60 %59
|
||||
%61 = OpFunctionCall %float %accepts_a_struct %60
|
||||
OpStore %x %61
|
||||
%62 = OpFunctionCall %void %modifies_a_struct %s_0
|
||||
%66 = OpLoad %float %x
|
||||
%68 = OpFOrdEqual %bool %66 %float_3
|
||||
OpSelectionMerge %70 None
|
||||
OpBranchConditional %68 %69 %70
|
||||
%69 = OpLabel
|
||||
%71 = OpAccessChain %_ptr_Function_float %s_0 %int_0
|
||||
%72 = OpLoad %float %71
|
||||
%74 = OpFOrdEqual %bool %72 %float_2
|
||||
OpBranch %70
|
||||
%70 = OpLabel
|
||||
%75 = OpPhi %bool %false %55 %74 %69
|
||||
OpSelectionMerge %77 None
|
||||
OpBranchConditional %75 %76 %77
|
||||
%76 = OpLabel
|
||||
%78 = OpAccessChain %_ptr_Function_int %s_0 %int_1
|
||||
%79 = OpLoad %int %78
|
||||
%81 = OpIEqual %bool %79 %int_3
|
||||
OpBranch %77
|
||||
%77 = OpLabel
|
||||
%82 = OpPhi %bool %false %70 %81 %76
|
||||
OpStore %valid %82
|
||||
%83 = OpLoad %bool %valid
|
||||
OpSelectionMerge %88 None
|
||||
OpBranchConditional %83 %86 %87
|
||||
%86 = OpLabel
|
||||
%89 = OpLoad %v4float %colorGreen
|
||||
OpStore %84 %89
|
||||
OpBranch %88
|
||||
%87 = OpLabel
|
||||
%90 = OpLoad %v4float %colorRed
|
||||
OpStore %84 %90
|
||||
OpBranch %88
|
||||
%88 = OpLabel
|
||||
%91 = OpLoad %v4float %84
|
||||
OpReturnValue %91
|
||||
OpFunctionEnd
|
||||
|
||||
1 error
|
28
tests/sksl/shared/StructsInFunctions.glsl
Normal file
28
tests/sksl/shared/StructsInFunctions.glsl
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
out vec4 sk_FragColor;
|
||||
uniform vec4 colorRed;
|
||||
uniform vec4 colorGreen;
|
||||
struct S {
|
||||
float x;
|
||||
int y;
|
||||
};
|
||||
S returns_a_struct() {
|
||||
S s;
|
||||
s.x = 1.0;
|
||||
s.y = 2;
|
||||
return s;
|
||||
}
|
||||
float accepts_a_struct(S s) {
|
||||
return s.x + float(s.y);
|
||||
}
|
||||
void modifies_a_struct(inout S s) {
|
||||
s.x++;
|
||||
s.y++;
|
||||
}
|
||||
vec4 main() {
|
||||
S s = returns_a_struct();
|
||||
float x = accepts_a_struct(s);
|
||||
modifies_a_struct(s);
|
||||
bool valid = (x == 3.0 && s.x == 2.0) && s.y == 3;
|
||||
return valid ? colorGreen : colorRed;
|
||||
}
|
47
tests/sksl/shared/StructsInFunctions.metal
Normal file
47
tests/sksl/shared/StructsInFunctions.metal
Normal file
@ -0,0 +1,47 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
using namespace metal;
|
||||
struct S {
|
||||
float x;
|
||||
int y;
|
||||
};
|
||||
struct Uniforms {
|
||||
float4 colorRed;
|
||||
float4 colorGreen;
|
||||
};
|
||||
struct Inputs {
|
||||
};
|
||||
struct Outputs {
|
||||
float4 sk_FragColor [[color(0)]];
|
||||
};
|
||||
void modifies_a_struct(thread S& s);
|
||||
void _skOutParamHelper0_modifies_a_struct(thread S& s) {
|
||||
S _var0 = s;
|
||||
modifies_a_struct(_var0);
|
||||
s = _var0;
|
||||
}
|
||||
|
||||
|
||||
S returns_a_struct() {
|
||||
S s;
|
||||
s.x = 1.0;
|
||||
s.y = 2;
|
||||
return s;
|
||||
}
|
||||
float accepts_a_struct(S s) {
|
||||
return s.x + float(s.y);
|
||||
}
|
||||
void modifies_a_struct(thread S& s) {
|
||||
s.x++;
|
||||
s.y++;
|
||||
}
|
||||
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
|
||||
Outputs _out;
|
||||
(void)_out;
|
||||
S s = returns_a_struct();
|
||||
float x = accepts_a_struct(s);
|
||||
_skOutParamHelper0_modifies_a_struct(s);
|
||||
bool valid = (x == 3.0 && s.x == 2.0) && s.y == 3;
|
||||
_out.sk_FragColor = valid ? _uniforms.colorGreen : _uniforms.colorRed;
|
||||
return _out;
|
||||
}
|
Loading…
Reference in New Issue
Block a user