spirv-reader: Fix for SelectUsingReferenceVariable
Started from https://dawn-review.googlesource.com/c/dawn/+/99220/2 Fixed: tint:1650 Change-Id: Ic5e097135a54c68e2cb9736198082179b522a4ba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101069 Commit-Queue: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
8478dfca56
commit
89dd52881c
|
@ -5000,7 +5000,7 @@ TypedExpression FunctionEmitter::MakeSimpleSelect(const spvtools::opt::Instructi
|
|||
// - true_value false_value, and result type to match.
|
||||
// - you can't select over pointers or pointer vectors, unless you also have
|
||||
// a VariablePointers* capability, which is not allowed in by WebGPU.
|
||||
auto* op_ty = true_value.type;
|
||||
auto* op_ty = true_value.type->UnwrapRef();
|
||||
if (op_ty->Is<Vector>() || op_ty->IsFloatScalar() || op_ty->IsIntegerScalar() ||
|
||||
op_ty->Is<Bool>()) {
|
||||
ExpressionList params;
|
||||
|
|
|
@ -4009,5 +4009,82 @@ return;
|
|||
ASSERT_EQ(expect, got);
|
||||
}
|
||||
|
||||
TEST_F(SpvParserHandleTest, SimpleSelectCanSelectFromHoistedConstant) {
|
||||
// Demonstrates fix for crbug.com/tint/1642
|
||||
// The problem is an operand to a simple select can be a value
|
||||
// that is hoisted into a 'var' declaration.
|
||||
//
|
||||
// The selection-generation logic has to UnwrapRef if needed.
|
||||
const auto assembly = Preamble() + R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %100 "main" %gl_Position
|
||||
OpSource HLSL 600
|
||||
OpName %100 "main"
|
||||
OpDecorate %gl_Position BuiltIn Position
|
||||
%float = OpTypeFloat 32
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%void = OpTypeVoid
|
||||
%9 = OpTypeFunction %void
|
||||
%bool = OpTypeBool
|
||||
%gl_Position = OpVariable %_ptr_Output_v4float Output
|
||||
%11 = OpUndef %float
|
||||
%100 = OpFunction %void None %9
|
||||
%12 = OpLabel
|
||||
OpBranch %13
|
||||
%13 = OpLabel
|
||||
%14 = OpPhi %float %11 %12 %15 %16
|
||||
%15 = OpPhi %float %float_0 %12 %17 %16
|
||||
%18 = OpFOrdLessThan %bool %15 %float_1
|
||||
OpLoopMerge %19 %16 None
|
||||
OpBranchConditional %18 %16 %19
|
||||
%16 = OpLabel
|
||||
%17 = OpFAdd %float %15 %float_1
|
||||
OpBranch %13
|
||||
%19 = OpLabel
|
||||
%20 = OpFOrdGreaterThan %bool %14 %float_1
|
||||
%21 = OpSelect %float %20 %14 %float_0
|
||||
%22 = OpCompositeConstruct %v4float %21 %21 %21 %21
|
||||
OpStore %gl_Position %22
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto p = parser(test::Assemble(assembly));
|
||||
EXPECT_TRUE(p->BuildAndParseInternalModule()) << assembly;
|
||||
auto fe = p->function_emitter(100);
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_TRUE(p->error().empty()) << p->error();
|
||||
auto ast_body = fe.ast_body();
|
||||
const auto got = test::ToString(p->program(), ast_body);
|
||||
auto* expect = R"(var x_14 : f32;
|
||||
var x_14_phi_1 : f32;
|
||||
var x_15_phi_1 : f32;
|
||||
x_14_phi_1 = 0.0f;
|
||||
x_15_phi_1 = 0.0f;
|
||||
loop {
|
||||
var x_17 : f32;
|
||||
x_14 = x_14_phi_1;
|
||||
let x_15 : f32 = x_15_phi_1;
|
||||
if ((x_15 < 1.0f)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
x_17 = (x_15 + 1.0f);
|
||||
x_14_phi_1 = x_15;
|
||||
x_15_phi_1 = x_17;
|
||||
}
|
||||
}
|
||||
let x_21 : f32 = select(0.0f, x_14, (x_14 > 1.0f));
|
||||
x_1 = vec4<f32>(x_21, x_21, x_21, x_21);
|
||||
return;
|
||||
)";
|
||||
ASSERT_EQ(expect, got);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::reader::spirv
|
||||
|
|
Loading…
Reference in New Issue