tint/transform: Fix PromoteInitializersToLetTest for materialized constants
PromoteInitializersToLet was not handling sem::Materialize nodes. This can happen for const arrays when they are dynamically indexed. Fixed: tint:1653 Change-Id: I3d67d8139e481c89b31a3a30c7ef44384b7545ba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99500 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
873f92e741
commit
0f0ba20208
|
@ -75,19 +75,22 @@ void PromoteInitializersToLet::Run(CloneContext& ctx, const DataMap&, DataMap&)
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::IdentifierExpression* expr) {
|
[&](const ast::IdentifierExpression* expr) {
|
||||||
if (auto* user = ctx.src->Sem().Get<sem::VariableUser>(expr)) {
|
if (auto* sem = ctx.src->Sem().Get(expr)) {
|
||||||
// Identifier resolves to a variable
|
if (auto* user = sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
|
||||||
if (auto* stmt = user->Stmt()) {
|
// Identifier resolves to a variable
|
||||||
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
|
if (auto* stmt = user->Stmt()) {
|
||||||
decl && decl->variable->Is<ast::Const>()) {
|
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
|
||||||
// The identifier is used on the RHS of a 'const' declaration. Ignore.
|
decl && decl->variable->Is<ast::Const>()) {
|
||||||
return true;
|
// The identifier is used on the RHS of a 'const' declaration.
|
||||||
|
// Ignore.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (user->Variable()->Declaration()->Is<ast::Const>()) {
|
||||||
|
// The identifier resolves to a 'const' variable, but isn't used to
|
||||||
|
// initialize another 'const'. This needs promoting.
|
||||||
|
return promote(user);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (user->Variable()->Declaration()->Is<ast::Const>()) {
|
|
||||||
// The identifier resolves to a 'const' variable, but isn't used to
|
|
||||||
// initialize another 'const'. This needs promoting.
|
|
||||||
return promote(user);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -158,6 +158,37 @@ fn f() {
|
||||||
EXPECT_EQ(expect, str(got));
|
EXPECT_EQ(expect, str(got));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PromoteInitializersToLetTest, GlobalConstArrayDynamicIndex) {
|
||||||
|
auto* src = R"(
|
||||||
|
const TRI_VERTICES = array(
|
||||||
|
vec4(0., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.),
|
||||||
|
vec4(1., 1., 0., 1.),
|
||||||
|
);
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
|
||||||
|
// note: TRI_VERTICES requires a materialize before the dynamic index.
|
||||||
|
return TRI_VERTICES[in_vertex_index];
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto* expect = R"(
|
||||||
|
const TRI_VERTICES = array(vec4(0.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(@builtin(vertex_index) in_vertex_index : u32) -> @builtin(position) vec4<f32> {
|
||||||
|
let tint_symbol = TRI_VERTICES;
|
||||||
|
return tint_symbol[in_vertex_index];
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
DataMap data;
|
||||||
|
auto got = Run<PromoteInitializersToLet>(src);
|
||||||
|
|
||||||
|
EXPECT_EQ(expect, str(got));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PromoteInitializersToLetTest, GlobalConstBasicArray_OutOfOrder) {
|
TEST_F(PromoteInitializersToLetTest, GlobalConstBasicArray_OutOfOrder) {
|
||||||
auto* src = R"(
|
auto* src = R"(
|
||||||
fn f() {
|
fn f() {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
const TRI_VERTICES = array(
|
||||||
|
vec4(0., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.),
|
||||||
|
vec4(1., 1., 0., 1.),
|
||||||
|
);
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
|
||||||
|
return TRI_VERTICES[in_vertex_index];
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
struct tint_symbol_1 {
|
||||||
|
uint in_vertex_index : SV_VertexID;
|
||||||
|
};
|
||||||
|
struct tint_symbol_2 {
|
||||||
|
float4 value : SV_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 vs_main_inner(uint in_vertex_index) {
|
||||||
|
const float4 tint_symbol_3[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
|
||||||
|
return tint_symbol_3[in_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
tint_symbol_2 vs_main(tint_symbol_1 tint_symbol) {
|
||||||
|
const float4 inner_result = vs_main_inner(tint_symbol.in_vertex_index);
|
||||||
|
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||||
|
wrapper_result.value = inner_result;
|
||||||
|
return wrapper_result;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
struct tint_symbol_1 {
|
||||||
|
uint in_vertex_index : SV_VertexID;
|
||||||
|
};
|
||||||
|
struct tint_symbol_2 {
|
||||||
|
float4 value : SV_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 vs_main_inner(uint in_vertex_index) {
|
||||||
|
const float4 tint_symbol_3[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
|
||||||
|
return tint_symbol_3[in_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
tint_symbol_2 vs_main(tint_symbol_1 tint_symbol) {
|
||||||
|
const float4 inner_result = vs_main_inner(tint_symbol.in_vertex_index);
|
||||||
|
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||||
|
wrapper_result.value = inner_result;
|
||||||
|
return wrapper_result;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
vec4 vs_main(uint in_vertex_index) {
|
||||||
|
vec4 tint_symbol[3] = vec4[3](vec4(0.0f, 0.0f, 0.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f));
|
||||||
|
return tint_symbol[in_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_PointSize = 1.0;
|
||||||
|
vec4 inner_result = vs_main(uint(gl_VertexID));
|
||||||
|
gl_Position = inner_result;
|
||||||
|
gl_Position.y = -(gl_Position.y);
|
||||||
|
gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
template<typename T, size_t N>
|
||||||
|
struct tint_array {
|
||||||
|
const constant T& operator[](size_t i) const constant { return elements[i]; }
|
||||||
|
device T& operator[](size_t i) device { return elements[i]; }
|
||||||
|
const device T& operator[](size_t i) const device { return elements[i]; }
|
||||||
|
thread T& operator[](size_t i) thread { return elements[i]; }
|
||||||
|
const thread T& operator[](size_t i) const thread { return elements[i]; }
|
||||||
|
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
|
||||||
|
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
|
||||||
|
T elements[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tint_symbol {
|
||||||
|
float4 value [[position]];
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 vs_main_inner(uint in_vertex_index) {
|
||||||
|
tint_array<float4, 3> const tint_symbol_1 = tint_array<float4, 3>{float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
|
||||||
|
return tint_symbol_1[in_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex tint_symbol vs_main(uint in_vertex_index [[vertex_id]]) {
|
||||||
|
float4 const inner_result = vs_main_inner(in_vertex_index);
|
||||||
|
tint_symbol wrapper_result = {};
|
||||||
|
wrapper_result.value = inner_result;
|
||||||
|
return wrapper_result;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 35
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Vertex %vs_main "vs_main" %in_vertex_index_1 %value %vertex_point_size
|
||||||
|
OpName %in_vertex_index_1 "in_vertex_index_1"
|
||||||
|
OpName %value "value"
|
||||||
|
OpName %vertex_point_size "vertex_point_size"
|
||||||
|
OpName %vs_main_inner "vs_main_inner"
|
||||||
|
OpName %in_vertex_index "in_vertex_index"
|
||||||
|
OpName %var_for_index "var_for_index"
|
||||||
|
OpName %vs_main "vs_main"
|
||||||
|
OpDecorate %in_vertex_index_1 BuiltIn VertexIndex
|
||||||
|
OpDecorate %value BuiltIn Position
|
||||||
|
OpDecorate %vertex_point_size BuiltIn PointSize
|
||||||
|
OpDecorate %_arr_v4float_uint_3 ArrayStride 16
|
||||||
|
%uint = OpTypeInt 32 0
|
||||||
|
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||||
|
%in_vertex_index_1 = OpVariable %_ptr_Input_uint Input
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%v4float = OpTypeVector %float 4
|
||||||
|
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||||
|
%8 = OpConstantNull %v4float
|
||||||
|
%value = OpVariable %_ptr_Output_v4float Output %8
|
||||||
|
%_ptr_Output_float = OpTypePointer Output %float
|
||||||
|
%11 = OpConstantNull %float
|
||||||
|
%vertex_point_size = OpVariable %_ptr_Output_float Output %11
|
||||||
|
%12 = OpTypeFunction %v4float %uint
|
||||||
|
%uint_3 = OpConstant %uint 3
|
||||||
|
%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
|
||||||
|
%float_1 = OpConstant %float 1
|
||||||
|
%19 = OpConstantComposite %v4float %11 %11 %11 %float_1
|
||||||
|
%20 = OpConstantComposite %v4float %11 %float_1 %11 %float_1
|
||||||
|
%21 = OpConstantComposite %v4float %float_1 %float_1 %11 %float_1
|
||||||
|
%22 = OpConstantComposite %_arr_v4float_uint_3 %19 %20 %21
|
||||||
|
%_ptr_Function__arr_v4float_uint_3 = OpTypePointer Function %_arr_v4float_uint_3
|
||||||
|
%25 = OpConstantNull %_arr_v4float_uint_3
|
||||||
|
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%29 = OpTypeFunction %void
|
||||||
|
%vs_main_inner = OpFunction %v4float None %12
|
||||||
|
%in_vertex_index = OpFunctionParameter %uint
|
||||||
|
%15 = OpLabel
|
||||||
|
%var_for_index = OpVariable %_ptr_Function__arr_v4float_uint_3 Function %25
|
||||||
|
OpStore %var_for_index %22
|
||||||
|
%27 = OpAccessChain %_ptr_Function_v4float %var_for_index %in_vertex_index
|
||||||
|
%28 = OpLoad %v4float %27
|
||||||
|
OpReturnValue %28
|
||||||
|
OpFunctionEnd
|
||||||
|
%vs_main = OpFunction %void None %29
|
||||||
|
%32 = OpLabel
|
||||||
|
%34 = OpLoad %uint %in_vertex_index_1
|
||||||
|
%33 = OpFunctionCall %v4float %vs_main_inner %34
|
||||||
|
OpStore %value %33
|
||||||
|
OpStore %vertex_point_size %float_1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
|
@ -0,0 +1,6 @@
|
||||||
|
const TRI_VERTICES = array(vec4(0.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(@builtin(vertex_index) in_vertex_index : u32) -> @builtin(position) vec4<f32> {
|
||||||
|
return TRI_VERTICES[in_vertex_index];
|
||||||
|
}
|
Loading…
Reference in New Issue