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;
|
||||
},
|
||||
[&](const ast::IdentifierExpression* expr) {
|
||||
if (auto* user = ctx.src->Sem().Get<sem::VariableUser>(expr)) {
|
||||
// Identifier resolves to a variable
|
||||
if (auto* stmt = user->Stmt()) {
|
||||
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
|
||||
decl && decl->variable->Is<ast::Const>()) {
|
||||
// The identifier is used on the RHS of a 'const' declaration. Ignore.
|
||||
return true;
|
||||
if (auto* sem = ctx.src->Sem().Get(expr)) {
|
||||
if (auto* user = sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
|
||||
// Identifier resolves to a variable
|
||||
if (auto* stmt = user->Stmt()) {
|
||||
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
|
||||
decl && decl->variable->Is<ast::Const>()) {
|
||||
// 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;
|
||||
|
|
|
@ -158,6 +158,37 @@ fn f() {
|
|||
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) {
|
||||
auto* src = R"(
|
||||
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