spirv-reader: Fix texel type confusion in loop
Started from https://dawn-review.googlesource.com/c/dawn/+/99001 Fixed: tint:1642 Change-Id: Ia5d7e45dc3de5de8303a2f161c9bf365227f9b5e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101068 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
434d6edd2b
commit
ece807852d
|
@ -5716,7 +5716,7 @@ const ast::Expression* FunctionEmitter::ConvertTexelForStorage(
|
|||
TypedExpression texel,
|
||||
const Texture* texture_type) {
|
||||
auto* storage_texture_type = As<StorageTexture>(texture_type);
|
||||
auto* src_type = texel.type;
|
||||
auto* src_type = texel.type->UnwrapRef();
|
||||
if (!storage_texture_type) {
|
||||
Fail() << "writing to other than storage texture: " << inst.PrettyPrint();
|
||||
return nullptr;
|
||||
|
@ -5764,14 +5764,14 @@ const ast::Expression* FunctionEmitter::ConvertTexelForStorage(
|
|||
|
||||
if (src_count < dest_count) {
|
||||
// Expand the texel to a 4 element vector.
|
||||
auto* component_type = texel.type->IsScalar() ? texel.type : texel.type->As<Vector>()->type;
|
||||
texel.type = ty_.Vector(component_type, dest_count);
|
||||
auto* component_type = src_type->IsScalar() ? src_type : src_type->As<Vector>()->type;
|
||||
src_type = ty_.Vector(component_type, dest_count);
|
||||
ExpressionList exprs;
|
||||
exprs.Push(texel.expr);
|
||||
for (auto i = src_count; i < dest_count; i++) {
|
||||
exprs.Push(parser_impl_.MakeNullExpression(component_type).expr);
|
||||
}
|
||||
texel.expr = builder_.Construct(Source{}, texel.type->Build(builder_), std::move(exprs));
|
||||
texel.expr = builder_.Construct(Source{}, src_type->Build(builder_), std::move(exprs));
|
||||
}
|
||||
|
||||
return texel.expr;
|
||||
|
|
|
@ -3840,5 +3840,94 @@ return;
|
|||
ASSERT_EQ(expect, got);
|
||||
}
|
||||
|
||||
TEST_F(SpvParserHandleTest, TexelTypeWhenLoop) {
|
||||
// Demonstrates fix for crbug.com/tint/1642
|
||||
// The problem is the texel value for an image write
|
||||
// can be given in 'var' declaration.
|
||||
//
|
||||
// The texel value handling has to unwrap the ref type first.
|
||||
const auto assembly = Preamble() + R"(
|
||||
OpCapability Shader
|
||||
OpCapability StorageImageExtendedFormats
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %100 "main"
|
||||
OpExecutionMode %100 LocalSize 8 8 1
|
||||
OpSource HLSL 600
|
||||
OpName %type_2d_image "type.2d.image"
|
||||
OpName %Output2Texture2D "Output2Texture2D"
|
||||
OpName %100 "main"
|
||||
OpDecorate %Output2Texture2D DescriptorSet 0
|
||||
OpDecorate %Output2Texture2D Binding 0
|
||||
%float = OpTypeFloat 32
|
||||
%float_0 = OpConstant %float 0
|
||||
%v2float = OpTypeVector %float 2
|
||||
%7 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_2 = OpConstant %int 2
|
||||
%float_1 = OpConstant %float 1
|
||||
%12 = OpConstantComposite %v2float %float_1 %float_1
|
||||
%int_1 = OpConstant %int 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%v2uint = OpTypeVector %uint 2
|
||||
%17 = OpConstantComposite %v2uint %uint_1 %uint_1
|
||||
%type_2d_image = OpTypeImage %float 2D 2 0 0 2 Rg32f
|
||||
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
|
||||
%void = OpTypeVoid
|
||||
%20 = OpTypeFunction %void
|
||||
%bool = OpTypeBool
|
||||
%Output2Texture2D = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
|
||||
%100 = OpFunction %void None %20
|
||||
%22 = OpLabel
|
||||
OpBranch %23
|
||||
%23 = OpLabel
|
||||
%24 = OpPhi %v2float %7 %22 %12 %25
|
||||
%26 = OpPhi %int %int_0 %22 %27 %25
|
||||
%28 = OpSLessThan %bool %26 %int_2
|
||||
OpLoopMerge %29 %25 None
|
||||
OpBranchConditional %28 %25 %29
|
||||
%25 = OpLabel
|
||||
%27 = OpIAdd %int %26 %int_1
|
||||
OpBranch %23
|
||||
%29 = OpLabel
|
||||
%30 = OpLoad %type_2d_image %Output2Texture2D
|
||||
OpImageWrite %30 %17 %24 None
|
||||
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_24 : vec2<f32>;
|
||||
var x_24_phi_1 : vec2<f32>;
|
||||
var x_26_phi_1 : i32;
|
||||
x_24_phi_1 = vec2<f32>(0.0f, 0.0f);
|
||||
x_26_phi_1 = 0i;
|
||||
loop {
|
||||
var x_27 : i32;
|
||||
x_24 = x_24_phi_1;
|
||||
let x_26 : i32 = x_26_phi_1;
|
||||
if ((x_26 < 2i)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
x_27 = (x_26 + 1i);
|
||||
x_24_phi_1 = vec2<f32>(1.0f, 1.0f);
|
||||
x_26_phi_1 = x_27;
|
||||
}
|
||||
}
|
||||
textureStore(Output2Texture2D, vec2<i32>(vec2<u32>(1u, 1u)), vec4<f32>(x_24, 0.0f, 0.0f));
|
||||
return;
|
||||
)";
|
||||
ASSERT_EQ(expect, got);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::reader::spirv
|
||||
|
|
Loading…
Reference in New Issue