From 591268db489cd37962f3a85920b4d5dd4122b1eb Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 10 Dec 2020 18:39:41 +0000 Subject: [PATCH] Implement textureWrite() Bug: tint:368 Bug: tint:140 Bug: tint:143 Bug: tint:144 Bug: tint:145 Bug: tint:146 Bug: tint:147 Change-Id: I1b6943d8663fbac8fbaa77a4804afb5a20fdb5e6 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35320 Commit-Queue: Ben Clayton Reviewed-by: dan sinclair --- src/ast/intrinsic.cc | 2 +- src/ast/intrinsic.h | 3 + src/ast/intrinsic_texture_helper_test.cc | 84 +++++++++++ src/ast/intrinsic_texture_helper_test.h | 5 + src/type_determiner.cc | 46 ++++-- src/type_determiner_test.cc | 40 ++++-- src/writer/hlsl/generator_impl.cc | 13 +- .../generator_impl_intrinsic_texture_test.cc | 10 ++ src/writer/msl/generator_impl.cc | 14 +- .../generator_impl_intrinsic_texture_test.cc | 10 ++ src/writer/spirv/builder.cc | 132 ++++++++++-------- .../spirv/builder_intrinsic_texture_test.cc | 130 +++++++++++++++++ 12 files changed, 394 insertions(+), 95 deletions(-) diff --git a/src/ast/intrinsic.cc b/src/ast/intrinsic.cc index 6ebd412873..8057e80090 100644 --- a/src/ast/intrinsic.cc +++ b/src/ast/intrinsic.cc @@ -266,7 +266,7 @@ bool IsTextureIntrinsic(Intrinsic i) { i == Intrinsic::kTextureSampleLevel || i == Intrinsic::kTextureSampleBias || i == Intrinsic::kTextureSampleCompare || - i == Intrinsic::kTextureSampleGrad; + i == Intrinsic::kTextureSampleGrad || i == Intrinsic::kTextureStore; } } // namespace intrinsic diff --git a/src/ast/intrinsic.h b/src/ast/intrinsic.h index 37edca5c6e..09116b6bd6 100644 --- a/src/ast/intrinsic.h +++ b/src/ast/intrinsic.h @@ -91,6 +91,7 @@ enum class Intrinsic { kTextureSampleCompare, kTextureSampleGrad, kTextureSampleLevel, + kTextureStore, kTrunc }; @@ -143,6 +144,8 @@ struct TextureSignature : public Signature { size_t sample_index = kNotUsed; /// `texture` parameter index. size_t texture = kNotUsed; + /// `value` parameter index. + size_t value = kNotUsed; }; /// The indices of all possible parameters. Index idx; diff --git a/src/ast/intrinsic_texture_helper_test.cc b/src/ast/intrinsic_texture_helper_test.cc index e492e0d99b..d0cad38d8d 100644 --- a/src/ast/intrinsic_texture_helper_test.cc +++ b/src/ast/intrinsic_texture_helper_test.cc @@ -1976,6 +1976,90 @@ std::vector TextureOverloadCase::ValidCases() { b->vec3(1, 2, 3)); // coords }, }, + { + ValidTextureOverload::kStoreWO1dRgba32float, + "textureStore(t : texture_storage_wo_1d,\n" + " coords : i32,\n" + " value : vec4) -> void", + ast::AccessControl::kWriteOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k1d, + TextureDataType::kF32, + "textureStore", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + b->vec4(2.f, 3.f, 4.f, 5.f)); // value + }, + }, + { + ValidTextureOverload::kStoreWO1dArrayRgba32float, + "textureStore(t : texture_storage_wo_1d_array,\n" + " coords : i32,\n" + " array_index : i32,\n" + " value : vec4) -> void", + ast::AccessControl::kWriteOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k1dArray, + TextureDataType::kF32, + "textureStore", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + 2, // array_index + b->vec4(3.f, 4.f, 5.f, 6.f)); // value + }, + }, + { + ValidTextureOverload::kStoreWO2dRgba32float, + "textureStore(t : texture_storage_wo_2d,\n" + " coords : vec2,\n" + " value : vec4) -> void", + ast::AccessControl::kWriteOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureStore", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + b->vec4(3.f, 4.f, 5.f, 6.f)); // value + }, + }, + { + ValidTextureOverload::kStoreWO2dArrayRgba32float, + "textureStore(t : texture_storage_wo_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " value : vec4) -> void", + ast::AccessControl::kWriteOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureStore", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + b->vec4(4.f, 5.f, 6.f, 7.f)); // value + }, + }, + { + ValidTextureOverload::kStoreWO3dRgba32float, + "textureStore(t : texture_storage_wo_3d,\n" + " coords : vec3,\n" + " value : vec4) -> void", + ast::AccessControl::kWriteOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureStore", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3), // coords + b->vec4(4.f, 5.f, 6.f, 7.f)); // value + }, + }, }; } diff --git a/src/ast/intrinsic_texture_helper_test.h b/src/ast/intrinsic_texture_helper_test.h index cb42568ab9..557518e106 100644 --- a/src/ast/intrinsic_texture_helper_test.h +++ b/src/ast/intrinsic_texture_helper_test.h @@ -142,6 +142,11 @@ enum class ValidTextureOverload { kLoadStorageRO2dRgba32float, kLoadStorageRO2dArrayRgba32float, // Not permutated for all texel formats kLoadStorageRO3dRgba32float, // Not permutated for all texel formats + kStoreWO1dRgba32float, // Not permutated for all texel formats + kStoreWO1dArrayRgba32float, // Not permutated for all texel formats + kStoreWO2dRgba32float, // Not permutated for all texel formats + kStoreWO2dArrayRgba32float, // Not permutated for all texel formats + kStoreWO3dRgba32float, // Not permutated for all texel formats }; /// Describes a texture intrinsic overload diff --git a/src/type_determiner.cc b/src/type_determiner.cc index b341777407..91fdba5b78 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -52,6 +52,7 @@ #include "src/ast/type/texture_type.h" #include "src/ast/type/u32_type.h" #include "src/ast/type/vector_type.h" +#include "src/ast/type/void_type.h" #include "src/ast/type_constructor_expression.h" #include "src/ast/unary_op_expression.h" #include "src/ast/variable_decl_statement.h" @@ -640,6 +641,14 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, param.idx.offset = param.count++; } break; + case ast::Intrinsic::kTextureStore: + param.idx.texture = param.count++; + param.idx.coords = param.count++; + if (is_array) { + param.idx.array_index = param.count++; + } + param.idx.value = param.count++; + break; default: set_error(expr->source(), "Internal compiler error: Unreachable intrinsic " + @@ -658,23 +667,32 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, ident->set_intrinsic_signature( std::make_unique(param)); - if (texture->Is()) { - expr->func()->set_result_type(mod_->create()); + // Set the function return type + ast::type::Type* return_type = nullptr; + if (ident->intrinsic() == ast::Intrinsic::kTextureStore) { + return_type = mod_->create(); } else { - ast::type::Type* type = nullptr; - if (auto* storage = texture->As()) { - type = storage->type(); - } else if (auto* sampled = texture->As()) { - type = sampled->type(); - } else if (auto* msampled = - texture->As()) { - type = msampled->type(); + if (texture->Is()) { + return_type = mod_->create(); } else { - set_error(expr->source(), "unknown texture type for texture sampling"); - return false; + ast::type::Type* type = nullptr; + if (auto* storage = texture->As()) { + type = storage->type(); + } else if (auto* sampled = texture->As()) { + type = sampled->type(); + } else if (auto* msampled = + texture->As()) { + type = msampled->type(); + } else { + set_error(expr->source(), + "unknown texture type for texture sampling"); + return false; + } + return_type = mod_->create(type, 4); } - expr->func()->set_result_type(mod_->create(type, 4)); } + expr->func()->set_result_type(return_type); + return true; } if (ident->intrinsic() == ast::Intrinsic::kDot) { @@ -996,6 +1014,8 @@ bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) { ident->set_intrinsic(ast::Intrinsic::kTanh); } else if (ident->name() == "textureLoad") { ident->set_intrinsic(ast::Intrinsic::kTextureLoad); + } else if (ident->name() == "textureStore") { + ident->set_intrinsic(ast::Intrinsic::kTextureStore); } else if (ident->name() == "textureSample") { ident->set_intrinsic(ast::Intrinsic::kTextureSample); } else if (ident->name() == "textureSampleBias") { diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index 678141e2b9..9f01813bca 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -4513,6 +4513,7 @@ std::string to_str(const std::string& function, maybe_add_param(sig->params.idx.sampler, "sampler"); maybe_add_param(sig->params.idx.sample_index, "sample_index"); maybe_add_param(sig->params.idx.texture, "texture"); + maybe_add_param(sig->params.idx.value, "value"); std::sort( params.begin(), params.end(), [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; }); @@ -4732,6 +4733,16 @@ const char* expected_texture_overload( return R"(textureLoad(texture, coords, array_index))"; case ValidTextureOverload::kLoadStorageRO3dRgba32float: return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kStoreWO1dRgba32float: + return R"(textureStore(texture, coords, value))"; + case ValidTextureOverload::kStoreWO1dArrayRgba32float: + return R"(textureStore(texture, coords, array_index, value))"; + case ValidTextureOverload::kStoreWO2dRgba32float: + return R"(textureStore(texture, coords, value))"; + case ValidTextureOverload::kStoreWO2dArrayRgba32float: + return R"(textureStore(texture, coords, array_index, value))"; + case ValidTextureOverload::kStoreWO3dRgba32float: + return R"(textureStore(texture, coords, value))"; } return ""; } @@ -4748,18 +4759,23 @@ TEST_P(TypeDeterminerTextureIntrinsicTest, Call) { ASSERT_TRUE(td()->Determine()) << td()->error(); ASSERT_TRUE(td()->DetermineResultType(&call)) << td()->error(); - switch (param.texture_kind) { - case ast::intrinsic::test::TextureKind::kRegular: - case ast::intrinsic::test::TextureKind::kMultisampled: - case ast::intrinsic::test::TextureKind::kStorage: { - auto* datatype = param.resultVectorComponentType(this); - ASSERT_TRUE(call.result_type()->Is()); - EXPECT_EQ(call.result_type()->As()->type(), datatype); - break; - } - case ast::intrinsic::test::TextureKind::kDepth: { - EXPECT_EQ(call.result_type(), ty.f32); - break; + if (std::string(param.function) == "textureStore") { + EXPECT_EQ(call.result_type(), ty.void_); + } else { + switch (param.texture_kind) { + case ast::intrinsic::test::TextureKind::kRegular: + case ast::intrinsic::test::TextureKind::kMultisampled: + case ast::intrinsic::test::TextureKind::kStorage: { + auto* datatype = param.resultVectorComponentType(this); + ASSERT_TRUE(call.result_type()->Is()); + EXPECT_EQ(call.result_type()->As()->type(), + datatype); + break; + } + case ast::intrinsic::test::TextureKind::kDepth: { + EXPECT_EQ(call.result_type(), ty.f32); + break; + } } } diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index b480acf686..ae7baae89b 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -719,8 +719,6 @@ bool GeneratorImpl::EmitCall(std::ostream& pre, bool GeneratorImpl::EmitTextureCall(std::ostream& pre, std::ostream& out, ast::CallExpression* expr) { - make_indent(out); - auto* ident = expr->func()->As(); auto params = expr->params(); @@ -759,6 +757,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, pack_mip_in_coords = true; } break; + case ast::Intrinsic::kTextureStore: + out << "["; + break; default: error_ = "Internal compiler error: Unhandled texture intrinsic '" + ident->name() + "'"; @@ -815,7 +816,13 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, } } - out << ")"; + if (ident->intrinsic() == ast::Intrinsic::kTextureStore) { + out << "] = "; + if (!EmitExpression(pre, out, params[pidx.value])) + return false; + } else { + out << ")"; + } return true; } diff --git a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc index db1f2cd775..42f3b0f155 100644 --- a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc @@ -229,6 +229,16 @@ std::string expected_texture_overload( return R"(texture_tint_0.Load(int3(1, 2, 3)))"; case ValidTextureOverload::kLoadStorageRO3dRgba32float: return R"(texture_tint_0.Load(int3(1, 2, 3)))"; + case ValidTextureOverload::kStoreWO1dRgba32float: + return R"(texture_tint_0[1] = float4(2.0f, 3.0f, 4.0f, 5.0f))"; + case ValidTextureOverload::kStoreWO1dArrayRgba32float: + return R"(texture_tint_0[int2(1, 2)] = float4(3.0f, 4.0f, 5.0f, 6.0f))"; + case ValidTextureOverload::kStoreWO2dRgba32float: + return R"(texture_tint_0[int2(1, 2)] = float4(3.0f, 4.0f, 5.0f, 6.0f))"; + case ValidTextureOverload::kStoreWO2dArrayRgba32float: + return R"(texture_tint_0[int3(1, 2, 3)] = float4(4.0f, 5.0f, 6.0f, 7.0f))"; + case ValidTextureOverload::kStoreWO3dRgba32float: + return R"(texture_tint_0[int3(1, 2, 3)] = float4(4.0f, 5.0f, 6.0f, 7.0f))"; } return ""; } // NOLINT - Ignore the length of this function diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 127a8a3116..9bb21f13fb 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -679,6 +679,9 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { out_ << ".read("; lod_param_is_named = false; break; + case ast::Intrinsic::kTextureStore: + out_ << ".write("; + break; default: error_ = "Internal compiler error: Unhandled texture intrinsic '" + ident->name() + "'"; @@ -693,15 +696,8 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { first_arg = false; }; - if (pidx.sampler != kNotUsed) { - if (!EmitExpression(params[pidx.sampler])) { - return false; - } - first_arg = false; - } - - for (auto idx : - {pidx.coords, pidx.array_index, pidx.depth_ref, pidx.sample_index}) { + for (auto idx : {pidx.value, pidx.sampler, pidx.coords, pidx.array_index, + pidx.depth_ref, pidx.sample_index}) { if (idx != kNotUsed) { maybe_write_comma(); if (!EmitExpression(params[idx])) diff --git a/src/writer/msl/generator_impl_intrinsic_texture_test.cc b/src/writer/msl/generator_impl_intrinsic_texture_test.cc index ee27a3e6a3..9764fbada7 100644 --- a/src/writer/msl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/msl/generator_impl_intrinsic_texture_test.cc @@ -229,6 +229,16 @@ std::string expected_texture_overload( return R"(texture_tint_0.read(int2(1, 2), 3))"; case ValidTextureOverload::kLoadStorageRO3dRgba32float: return R"(texture_tint_0.read(int3(1, 2, 3)))"; + case ValidTextureOverload::kStoreWO1dRgba32float: + return R"(texture_tint_0.write(float4(2.0f, 3.0f, 4.0f, 5.0f), 1))"; + case ValidTextureOverload::kStoreWO1dArrayRgba32float: + return R"(texture_tint_0.write(float4(3.0f, 4.0f, 5.0f, 6.0f), 1, 2))"; + case ValidTextureOverload::kStoreWO2dRgba32float: + return R"(texture_tint_0.write(float4(3.0f, 4.0f, 5.0f, 6.0f), int2(1, 2)))"; + case ValidTextureOverload::kStoreWO2dArrayRgba32float: + return R"(texture_tint_0.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int2(1, 2), 3))"; + case ValidTextureOverload::kStoreWO3dRgba32float: + return R"(texture_tint_0.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int3(1, 2, 3)))"; } return ""; } // NOLINT - Ignore the length of this function diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 20a03fb041..ae26598e45 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -1943,8 +1943,10 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, // Populate the spirv_params with common parameters OperandList spirv_params; spirv_params.reserve(8); // Enough to fit most parameter lists - spirv_params.emplace_back(std::move(result_type)); // result type - spirv_params.emplace_back(std::move(result_id)); // result id + if (ident->intrinsic() != ast::Intrinsic::kTextureStore) { + spirv_params.emplace_back(std::move(result_type)); + spirv_params.emplace_back(std::move(result_id)); + } // Extra image operands, appended to spirv_params. struct ImageOperand { @@ -1977,24 +1979,9 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, } }; - if (ident->intrinsic() == ast::Intrinsic::kTextureLoad) { - op = texture_type->Is() ? spv::Op::OpImageRead - : spv::Op::OpImageFetch; - spirv_params.emplace_back(gen_param(pidx.texture)); - append_coords_to_spirv_params(); - - if (pidx.level != kNotUsed) { - image_operands.emplace_back( - ImageOperand{SpvImageOperandsLodMask, gen_param(pidx.level)}); - } - - if (pidx.sample_index != kNotUsed) { - image_operands.emplace_back(ImageOperand{SpvImageOperandsSampleMask, - gen_param(pidx.sample_index)}); - } - } else { + auto append_image_and_coords_to_spirv_params = [&] { assert(pidx.sampler != kNotUsed); - + assert(pidx.texture != kNotUsed); auto sampler_param = gen_param(pidx.sampler); auto texture_param = gen_param(pidx.texture); auto sampled_image = @@ -2003,51 +1990,82 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, // Populate the spirv_params with the common parameters spirv_params.emplace_back(Operand::Int(sampled_image)); // sampled image append_coords_to_spirv_params(); + }; - switch (ident->intrinsic()) { - case ast::Intrinsic::kTextureSample: { - op = spv::Op::OpImageSampleImplicitLod; - break; - } - case ast::Intrinsic::kTextureSampleBias: { - op = spv::Op::OpImageSampleImplicitLod; - assert(pidx.bias != kNotUsed); - image_operands.emplace_back( - ImageOperand{SpvImageOperandsBiasMask, gen_param(pidx.bias)}); - break; - } - case ast::Intrinsic::kTextureSampleLevel: { - op = spv::Op::OpImageSampleExplicitLod; - assert(pidx.level != kNotUsed); + switch (ident->intrinsic()) { + case ast::Intrinsic::kTextureLoad: { + op = texture_type->Is() + ? spv::Op::OpImageRead + : spv::Op::OpImageFetch; + spirv_params.emplace_back(gen_param(pidx.texture)); + append_coords_to_spirv_params(); + + if (pidx.level != kNotUsed) { image_operands.emplace_back( ImageOperand{SpvImageOperandsLodMask, gen_param(pidx.level)}); - break; } - case ast::Intrinsic::kTextureSampleGrad: { - op = spv::Op::OpImageSampleExplicitLod; - assert(pidx.ddx != kNotUsed); - assert(pidx.ddy != kNotUsed); - image_operands.emplace_back( - ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddx)}); - image_operands.emplace_back( - ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddy)}); - break; - } - case ast::Intrinsic::kTextureSampleCompare: { - op = spv::Op::OpImageSampleDrefExplicitLod; - assert(pidx.depth_ref != kNotUsed); - spirv_params.emplace_back(gen_param(pidx.depth_ref)); - ast::type::F32 f32; - ast::FloatLiteral float_0(&f32, 0.0); - image_operands.emplace_back(ImageOperand{ - SpvImageOperandsLodMask, - Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))}); - break; + if (pidx.sample_index != kNotUsed) { + image_operands.emplace_back(ImageOperand{SpvImageOperandsSampleMask, + gen_param(pidx.sample_index)}); } - default: - break; // unreachable + + break; } + case ast::Intrinsic::kTextureStore: { + op = spv::Op::OpImageWrite; + spirv_params.emplace_back(gen_param(pidx.texture)); + append_coords_to_spirv_params(); + spirv_params.emplace_back(gen_param(pidx.value)); + break; + } + case ast::Intrinsic::kTextureSample: { + op = spv::Op::OpImageSampleImplicitLod; + append_image_and_coords_to_spirv_params(); + break; + } + case ast::Intrinsic::kTextureSampleBias: { + op = spv::Op::OpImageSampleImplicitLod; + append_image_and_coords_to_spirv_params(); + assert(pidx.bias != kNotUsed); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsBiasMask, gen_param(pidx.bias)}); + break; + } + case ast::Intrinsic::kTextureSampleLevel: { + op = spv::Op::OpImageSampleExplicitLod; + append_image_and_coords_to_spirv_params(); + assert(pidx.level != kNotUsed); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsLodMask, gen_param(pidx.level)}); + break; + } + case ast::Intrinsic::kTextureSampleGrad: { + op = spv::Op::OpImageSampleExplicitLod; + append_image_and_coords_to_spirv_params(); + assert(pidx.ddx != kNotUsed); + assert(pidx.ddy != kNotUsed); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddx)}); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddy)}); + break; + } + case ast::Intrinsic::kTextureSampleCompare: { + op = spv::Op::OpImageSampleDrefExplicitLod; + append_image_and_coords_to_spirv_params(); + assert(pidx.depth_ref != kNotUsed); + spirv_params.emplace_back(gen_param(pidx.depth_ref)); + + ast::type::F32 f32; + ast::FloatLiteral float_0(&f32, 0.0); + image_operands.emplace_back(ImageOperand{ + SpvImageOperandsLodMask, + Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))}); + break; + } + default: + break; // unreachable } if (pidx.offset != kNotUsed) { diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc index 106b17e34e..858b3bae78 100644 --- a/src/writer/spirv/builder_intrinsic_texture_test.cc +++ b/src/writer/spirv/builder_intrinsic_texture_test.cc @@ -2563,8 +2563,138 @@ expected_texture_overload_spirv expected_texture_overload( R"( %10 = OpLoad %3 %1 %8 = OpImageRead %9 %10 %16 +)"}; + case ValidTextureOverload::kStoreWO1dRgba32float: + return {R"( +%4 = OpTypeVoid +%3 = OpTypeImage %4 1D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%10 = OpTypeInt 32 1 +%11 = OpConstant %10 1 +%13 = OpTypeFloat 32 +%12 = OpTypeVector %13 4 +%14 = OpConstant %13 2 +%15 = OpConstant %13 3 +%16 = OpConstant %13 4 +%17 = OpConstant %13 5 +%18 = OpConstantComposite %12 %14 %15 %16 %17 +)", + R"( +%9 = OpLoad %3 %1 +OpImageWrite %9 %11 %18 +)"}; + case ValidTextureOverload::kStoreWO1dArrayRgba32float: + return {R"( +%4 = OpTypeVoid +%3 = OpTypeImage %4 1D 0 1 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 2 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstantComposite %10 %12 %13 +%16 = OpTypeFloat 32 +%15 = OpTypeVector %16 4 +%17 = OpConstant %16 3 +%18 = OpConstant %16 4 +%19 = OpConstant %16 5 +%20 = OpConstant %16 6 +%21 = OpConstantComposite %15 %17 %18 %19 %20 +)", + R"( +%9 = OpLoad %3 %1 +OpImageWrite %9 %14 %21 +)"}; + case ValidTextureOverload::kStoreWO2dRgba32float: + return {R"( +%4 = OpTypeVoid +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 2 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstantComposite %10 %12 %13 +%16 = OpTypeFloat 32 +%15 = OpTypeVector %16 4 +%17 = OpConstant %16 3 +%18 = OpConstant %16 4 +%19 = OpConstant %16 5 +%20 = OpConstant %16 6 +%21 = OpConstantComposite %15 %17 %18 %19 %20 +)", + R"( +%9 = OpLoad %3 %1 +OpImageWrite %9 %14 %21 +)"}; + case ValidTextureOverload::kStoreWO2dArrayRgba32float: + return {R"( +%4 = OpTypeVoid +%3 = OpTypeImage %4 2D 0 1 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 3 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstant %11 3 +%15 = OpConstantComposite %10 %12 %13 %14 +%17 = OpTypeFloat 32 +%16 = OpTypeVector %17 4 +%18 = OpConstant %17 4 +%19 = OpConstant %17 5 +%20 = OpConstant %17 6 +%21 = OpConstant %17 7 +%22 = OpConstantComposite %16 %18 %19 %20 %21 +)", + R"( +%9 = OpLoad %3 %1 +OpImageWrite %9 %15 %22 +)"}; + case ValidTextureOverload::kStoreWO3dRgba32float: + return {R"( +%4 = OpTypeVoid +%3 = OpTypeImage %4 3D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 3 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstant %11 3 +%15 = OpConstantComposite %10 %12 %13 %14 +%17 = OpTypeFloat 32 +%16 = OpTypeVector %17 4 +%18 = OpConstant %17 4 +%19 = OpConstant %17 5 +%20 = OpConstant %17 6 +%21 = OpConstant %17 7 +%22 = OpConstantComposite %16 %18 %19 %20 %21 +)", + R"( +%9 = OpLoad %3 %1 +OpImageWrite %9 %15 %22 )"}; } + return {"", ""}; } // NOLINT - Ignore the length of this function