| // Copyright 2023 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "src/tint/lang/core/builtin_fn.h" |
| #include "src/tint/lang/core/fluent_types.h" |
| #include "src/tint/lang/core/type/depth_multisampled_texture.h" |
| #include "src/tint/lang/spirv/writer/common/helper_test.h" |
| |
| using namespace tint::core::number_suffixes; // NOLINT |
| using namespace tint::core::fluent_types; // NOLINT |
| |
| namespace tint::spirv::writer { |
| namespace { |
| |
| enum TextureType { |
| kSampledTexture, |
| kMultisampledTexture, |
| kDepthTexture, |
| kDepthMultisampledTexture, |
| kStorageTexture, |
| }; |
| |
| enum SamplerUsage { |
| kNoSampler, |
| kSampler, |
| kComparisonSampler, |
| }; |
| |
| /// A typed argument or result for a texture builtin. |
| struct NameAndType { |
| /// The name. |
| const char* name; |
| /// The vector width of the value (1 means scalar). |
| uint32_t width; |
| /// The element type of the value. |
| TestElementType type; |
| }; |
| |
| /// A parameterized texture builtin function test case. |
| struct TextureBuiltinTestCase { |
| /// The texture type. |
| TextureType texture_type; |
| /// The dimensionality of the texture. |
| core::type::TextureDimension dim; |
| /// The texel type of the texture. |
| TestElementType texel_type; |
| /// The builtin function arguments. |
| Vector<NameAndType, 4> args; |
| /// The result type. |
| NameAndType result; |
| /// The expected SPIR-V instruction strings. |
| Vector<const char*, 2> instructions; |
| }; |
| |
| template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>> |
| auto& operator<<(STREAM& out, TextureType type) { |
| switch (type) { |
| case kSampledTexture: |
| out << "SampleTexture"; |
| break; |
| case kMultisampledTexture: |
| out << "MultisampleTexture"; |
| break; |
| case kDepthTexture: |
| out << "DepthTexture"; |
| break; |
| case kDepthMultisampledTexture: |
| out << "DepthMultisampledTexture"; |
| break; |
| case kStorageTexture: |
| out << "StorageTexture"; |
| break; |
| } |
| return out; |
| } |
| |
| std::string PrintCase(testing::TestParamInfo<TextureBuiltinTestCase> cc) { |
| StringStream ss; |
| ss << cc.param.texture_type << cc.param.dim << "_" << cc.param.texel_type; |
| for (const auto& arg : cc.param.args) { |
| ss << "_" << arg.name; |
| } |
| return ss.str(); |
| } |
| |
| class TextureBuiltinTest : public SpirvWriterTestWithParam<TextureBuiltinTestCase> { |
| protected: |
| const core::type::Texture* MakeTextureType(TextureType type, |
| core::type::TextureDimension dim, |
| TestElementType texel_type) { |
| switch (type) { |
| case kSampledTexture: |
| return ty.Get<core::type::SampledTexture>(dim, MakeScalarType(texel_type)); |
| case kMultisampledTexture: |
| return ty.Get<core::type::MultisampledTexture>(dim, MakeScalarType(texel_type)); |
| case kDepthTexture: |
| return ty.Get<core::type::DepthTexture>(dim); |
| case kDepthMultisampledTexture: |
| return ty.Get<core::type::DepthMultisampledTexture>(dim); |
| case kStorageTexture: |
| core::TexelFormat format; |
| switch (texel_type) { |
| case kF32: |
| format = core::TexelFormat::kR32Float; |
| break; |
| case kI32: |
| format = core::TexelFormat::kR32Sint; |
| break; |
| case kU32: |
| format = core::TexelFormat::kR32Uint; |
| break; |
| default: |
| return nullptr; |
| } |
| return ty.Get<core::type::StorageTexture>( |
| dim, format, core::Access::kWrite, |
| core::type::StorageTexture::SubtypeFor(format, ty)); |
| } |
| return nullptr; |
| } |
| |
| void Run(enum core::BuiltinFn function, SamplerUsage sampler) { |
| auto params = GetParam(); |
| |
| auto* result_ty = MakeScalarType(params.result.type); |
| if (function == core::BuiltinFn::kTextureStore) { |
| result_ty = ty.void_(); |
| } |
| if (params.result.width > 1) { |
| result_ty = ty.vec(result_ty, params.result.width); |
| } |
| |
| Vector<core::ir::FunctionParam*, 4> func_params; |
| |
| auto* t = b.FunctionParam( |
| "t", MakeTextureType(params.texture_type, params.dim, params.texel_type)); |
| func_params.Push(t); |
| core::ir::FunctionParam* s = nullptr; |
| if (sampler == kSampler) { |
| s = b.FunctionParam("s", ty.sampler()); |
| func_params.Push(s); |
| } else if (sampler == kComparisonSampler) { |
| s = b.FunctionParam("s", ty.comparison_sampler()); |
| func_params.Push(s); |
| } |
| |
| auto* func = b.Function("foo", result_ty); |
| func->SetParams(std::move(func_params)); |
| |
| b.Append(func->Block(), [&] { |
| uint32_t arg_value = 1; |
| |
| Vector<core::ir::Value*, 4> args; |
| if (function == core::BuiltinFn::kTextureGather && |
| params.texture_type != kDepthTexture) { |
| // Special case for textureGather, which has a component argument first. |
| auto* component = MakeScalarValue(kU32, arg_value++); |
| args.Push(component); |
| mod.SetName(component, "component"); |
| } |
| args.Push(t); |
| if (s) { |
| args.Push(s); |
| } |
| |
| for (const auto& arg : params.args) { |
| auto* value = MakeScalarValue(arg.type, arg_value++); |
| if (arg.width > 1) { |
| value = b.Splat(ty.vec(value->Type(), arg.width), value, arg.width); |
| } |
| args.Push(value); |
| mod.SetName(value, arg.name); |
| } |
| auto* result = b.Call(result_ty, function, std::move(args)); |
| if (result_ty->Is<core::type::Void>()) { |
| b.Return(func); |
| } else { |
| b.Return(func, result); |
| mod.SetName(result, "result"); |
| } |
| }); |
| |
| Options options; |
| options.disable_image_robustness = true; |
| ASSERT_TRUE(Generate(options)) << Error() << output_; |
| for (auto& inst : params.instructions) { |
| EXPECT_INST(inst); |
| } |
| } |
| }; |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSample |
| //////////////////////////////////////////////////////////////// |
| using TextureSample = TextureBuiltinTest; |
| TEST_P(TextureSample, Emit) { |
| Run(core::BuiltinFn::kTextureSample, kSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSample, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {{"coord", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coord None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %16 None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %16 ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"offset", 3, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %15 None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleImplicitLod %v4float %9 %coords None", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleImplicitLod %v4float %9 %coords ConstOffset %offset", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleImplicitLod %v4float %9 %coords None", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleImplicitLod %v4float %9 %15 None", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleImplicitLod %v4float %9 %15 ConstOffset %offset", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %11", |
| "OpImageSampleImplicitLod %v4float %9 %15 None", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleBias |
| //////////////////////////////////////////////////////////////// |
| using TextureSampleBias = TextureBuiltinTest; |
| TEST_P(TextureSampleBias, Emit) { |
| Run(core::BuiltinFn::kTextureSampleBias, kSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSampleBias, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"bias", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords Bias %bias", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"bias", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords Bias|ConstOffset %bias %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"bias", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %16 Bias %bias", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"bias", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %16 Bias|ConstOffset %bias %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"bias", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords Bias %bias", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"bias", 1, kF32}, {"offset", 3, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords Bias|ConstOffset %bias %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"bias", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleImplicitLod %v4float %10 %coords Bias %bias", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"bias", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "OpImageSampleImplicitLod %v4float %10 %15 Bias %bias", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleGrad |
| //////////////////////////////////////////////////////////////// |
| using TextureSampleGrad = TextureBuiltinTest; |
| TEST_P(TextureSampleGrad, Emit) { |
| Run(core::BuiltinFn::kTextureSampleGrad, kSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSampleGrad, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"ddx", 2, kF32}, {"ddy", 2, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Grad %ddx %ddy", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"ddx", 2, kF32}, {"ddy", 2, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Grad|ConstOffset %ddx %ddy %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"ddx", 2, kF32}, {"ddy", 2, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %16 Grad %ddx %ddy", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, |
| {"array_idx", 1, kI32}, |
| {"ddx", 2, kF32}, |
| {"ddy", 2, kF32}, |
| {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %16 Grad|ConstOffset %ddx %ddy %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"ddx", 3, kF32}, {"ddy", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Grad %ddx %ddy", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"ddx", 3, kF32}, {"ddy", 3, kF32}, {"offset", 3, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Grad|ConstOffset %ddx %ddy %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"ddx", 3, kF32}, {"ddy", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Grad %ddx %ddy", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"ddx", 3, kF32}, {"ddy", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %15 Grad %ddx %ddy", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleLevel |
| //////////////////////////////////////////////////////////////// |
| using TextureSampleLevel = TextureBuiltinTest; |
| TEST_P(TextureSampleLevel, Emit) { |
| Run(core::BuiltinFn::kTextureSampleLevel, kSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSampleLevel, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"lod", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"lod", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Lod|ConstOffset %lod %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %16 Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %16 Lod|ConstOffset %lod %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"lod", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"lod", 1, kF32}, {"offset", 3, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Lod|ConstOffset %lod %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"lod", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "OpImageSampleExplicitLod %v4float %10 %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "OpImageSampleExplicitLod %v4float %10 %15 Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %coords Lod %11", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"lod", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %coords Lod|ConstOffset %11 %offset", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "%19 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %15 Lod %19", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "%19 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %15 Lod|ConstOffset %19 %offset", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %coords Lod %11", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %11", |
| "%19 = OpConvertSToF %float %lod", |
| "OpImageSampleExplicitLod %v4float %9 %15 Lod %19", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleCompare |
| //////////////////////////////////////////////////////////////// |
| using TextureSampleCompare = TextureBuiltinTest; |
| TEST_P(TextureSampleCompare, Emit) { |
| Run(core::BuiltinFn::kTextureSampleCompare, kComparisonSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSampleCompare, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefImplicitLod %float %9 %coords %depth", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefImplicitLod %float %9 %coords %depth ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleDrefImplicitLod %float %9 %15 %depth", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleDrefImplicitLod %float %9 %15 %depth ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"depth", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefImplicitLod %float %9 %coords %depth", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %11", |
| "OpImageSampleDrefImplicitLod %float %9 %15 %depth", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleCompareLevel |
| //////////////////////////////////////////////////////////////// |
| using TextureSampleCompareLevel = TextureBuiltinTest; |
| TEST_P(TextureSampleCompareLevel, Emit) { |
| Run(core::BuiltinFn::kTextureSampleCompareLevel, kComparisonSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureSampleCompareLevel, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth_l0", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefExplicitLod %float %9 %coords %depth_l0 Lod %float_0", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth_l0", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefExplicitLod %float %9 %coords %depth_l0 Lod|ConstOffset %float_0 " |
| "%offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"depth_l0", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleDrefExplicitLod %float %9 %15 %depth_l0 Lod %float_0", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, |
| {"array_idx", 1, kI32}, |
| {"depth_l0", 1, kF32}, |
| {"offset", 2, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v3float %coords %11", |
| "OpImageSampleDrefExplicitLod %float %9 %15 %depth_l0 Lod|ConstOffset %float_0 " |
| "%offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"depth_l0", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "OpImageSampleDrefExplicitLod %float %9 %coords %depth_l0 Lod %float_0", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"depth_l0", 1, kF32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpSampledImage %10 %t %s", |
| "%11 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %11", |
| "OpImageSampleDrefExplicitLod %float %9 %15 %depth_l0 Lod %float_0", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureGather |
| //////////////////////////////////////////////////////////////// |
| using TextureGather = TextureBuiltinTest; |
| TEST_P(TextureGather, Emit) { |
| Run(core::BuiltinFn::kTextureGather, kSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureGather, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %component None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %component ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageGather %v4float %10 %16 %component None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageGather %v4float %10 %16 %component ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %component None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "%result = OpImageGather %v4float %10 %15 %component None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %uint_0 None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %uint_0 ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4float %10 %coords %uint_0 None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageGather %v4float %10 %16 %uint_0 None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageGather %v4float %10 %16 %uint_0 ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "%result = OpImageGather %v4float %10 %15 %uint_0 None", |
| }, |
| }, |
| |
| // Test some textures with integer texel types. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kI32, |
| {{"coords", 2, kF32}}, |
| {"result", 4, kI32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4int %10 %coords %component None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kU32, |
| {{"coords", 2, kF32}}, |
| {"result", 4, kU32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageGather %v4uint %10 %coords %component None", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureGatherCompare |
| //////////////////////////////////////////////////////////////// |
| using TextureGatherCompare = TextureBuiltinTest; |
| TEST_P(TextureGatherCompare, Emit) { |
| Run(core::BuiltinFn::kTextureGatherCompare, kComparisonSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P( |
| SpirvWriterTest, |
| TextureGatherCompare, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageDrefGather %v4float %10 %coords %depth None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"depth", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageDrefGather %v4float %10 %coords %depth ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageDrefGather %v4float %10 %16 %depth None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}, {"offset", 2, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%16 = OpCompositeConstruct %v3float %coords %12", |
| "%result = OpImageDrefGather %v4float %10 %16 %depth ConstOffset %offset", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"depth", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%result = OpImageDrefGather %v4float %10 %coords %depth None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"coords", 3, kF32}, {"array_idx", 1, kI32}, {"depth", 1, kF32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpSampledImage %11 %t %s", |
| "%12 = OpConvertSToF %float %array_idx", |
| "%15 = OpCompositeConstruct %v4float %coords %12", |
| "%result = OpImageDrefGather %v4float %10 %15 %depth None", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureLoad |
| //////////////////////////////////////////////////////////////// |
| using TextureLoad = TextureBuiltinTest; |
| TEST_P(TextureLoad, Emit) { |
| Run(core::BuiltinFn::kTextureLoad, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureLoad, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {{"coord", 1, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "OpImageFetch %v4float %t %coord Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "OpImageFetch %v4float %t %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"array_idx", 1, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "%10 = OpCompositeConstruct %v3int %coords %array_idx", |
| "OpImageFetch %v4float %t %10 Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "OpImageFetch %v4float %t %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"sample_idx", 1, kI32}}, |
| {"result", 4, kF32}, |
| { |
| "OpImageFetch %v4float %t %coords Sample %sample_idx", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "OpImageFetch %v4float %t %coords Lod %lod", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"array_idx", 1, kI32}, {"lod", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "%9 = OpCompositeConstruct %v3int %coords %array_idx", |
| "OpImageFetch %v4float %t %9 Lod %lod", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"sample_idx", 1, kI32}}, |
| {"result", 1, kF32}, |
| { |
| "OpImageFetch %v4float %t %coords Sample %sample_idx", |
| "%result = OpCompositeExtract %float", |
| }, |
| }, |
| |
| // Test some textures with integer texel types. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kI32, |
| {{"coords", 2, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kI32}, |
| { |
| "OpImageFetch %v4int %t %coords Lod %lod", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kU32, |
| {{"coords", 2, kI32}, {"lod", 1, kI32}}, |
| {"result", 4, kU32}, |
| { |
| "OpImageFetch %v4uint %t %coords Lod %lod", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureStore |
| //////////////////////////////////////////////////////////////// |
| using TextureStore = TextureBuiltinTest; |
| TEST_P(TextureStore, Emit) { |
| Run(core::BuiltinFn::kTextureStore, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureStore, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {{"coord", 1, kI32}, {"texel", 4, kF32}}, |
| {}, |
| { |
| "OpImageWrite %t %coord %texel None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"texel", 4, kF32}}, |
| {}, |
| { |
| "OpImageWrite %t %coords %texel None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"coords", 2, kI32}, {"array_idx", 1, kI32}, {"texel", 4, kF32}}, |
| {}, |
| { |
| "%10 = OpCompositeConstruct %v3int %coords %array_idx", |
| "OpImageWrite %t %10 %texel None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"coords", 3, kI32}, {"texel", 4, kF32}}, |
| {}, |
| { |
| "OpImageWrite %t %coords %texel None", |
| }, |
| }, |
| |
| // Test some textures with integer texel types. |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kI32, |
| {{"coords", 2, kI32}, {"texel", 4, kI32}}, |
| {}, |
| { |
| "OpImageWrite %t %coords %texel None", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kU32, |
| {{"coords", 2, kI32}, {"texel", 4, kU32}}, |
| {}, |
| { |
| "OpImageWrite %t %coords %texel None", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureDimensions |
| //////////////////////////////////////////////////////////////// |
| using TextureDimensions = TextureBuiltinTest; |
| TEST_P(TextureDimensions, Emit) { |
| Run(core::BuiltinFn::kTextureDimensions, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureDimensions, |
| testing::Values( |
| // 1D implicit Lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQuerySizeLod %uint %t %uint_0"}, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQuerySize %uint %t"}, |
| }, |
| |
| // 1D explicit Lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQuerySizeLod %uint %t %lod"}, |
| }, |
| |
| // 2D implicit Lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %uint_0"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %uint_0"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySize %v2uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %uint_0"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %uint_0"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySize %v2uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySize %v2uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySize %v3uint %t", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| |
| // 2D explicit Lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %lod"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %lod", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %lod"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %lod", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %lod"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %lod", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| {"%result = OpImageQuerySizeLod %v2uint %t %lod"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 2, kU32}, |
| { |
| "%9 = OpImageQuerySizeLod %v3uint %t %lod", |
| "%result = OpVectorShuffle %v2uint %9 %9 0 1", |
| }, |
| }, |
| |
| // 3D implicit lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 3, kU32}, |
| {"%result = OpImageQuerySizeLod %v3uint %t %uint_0"}, |
| }, |
| |
| // 3D explicit lod. |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {{"lod", 1, kU32}}, |
| {"result", 3, kU32}, |
| {"%result = OpImageQuerySizeLod %v3uint %t %lod"}, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureNumLayers |
| //////////////////////////////////////////////////////////////// |
| using TextureNumLayers = TextureBuiltinTest; |
| TEST_P(TextureNumLayers, Emit) { |
| Run(core::BuiltinFn::kTextureNumLayers, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureNumLayers, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| { |
| "%8 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpCompositeExtract %uint %8 2", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| { |
| "%8 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpCompositeExtract %uint %8 2", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| { |
| "%8 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpCompositeExtract %uint %8 2", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| { |
| "%8 = OpImageQuerySizeLod %v3uint %t %uint_0", |
| "%result = OpCompositeExtract %uint %8 2", |
| }, |
| }, |
| TextureBuiltinTestCase{ |
| kStorageTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| { |
| "%8 = OpImageQuerySize %v3uint %t", |
| "%result = OpCompositeExtract %uint %8 2", |
| }, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureNumLevels |
| //////////////////////////////////////////////////////////////// |
| using TextureNumLevels = TextureBuiltinTest; |
| TEST_P(TextureNumLevels, Emit) { |
| Run(core::BuiltinFn::kTextureNumLevels, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureNumLevels, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k1d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::k3d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kSampledTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::k2dArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCube, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthTexture, |
| core::type::TextureDimension::kCubeArray, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQueryLevels %uint %t"}, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureNumSamples |
| //////////////////////////////////////////////////////////////// |
| using TextureNumSamples = TextureBuiltinTest; |
| TEST_P(TextureNumSamples, Emit) { |
| Run(core::BuiltinFn::kTextureNumSamples, kNoSampler); |
| } |
| INSTANTIATE_TEST_SUITE_P(SpirvWriterTest, |
| TextureNumSamples, |
| testing::Values( |
| TextureBuiltinTestCase{ |
| kMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQuerySamples %uint %t"}, |
| }, |
| TextureBuiltinTestCase{ |
| kDepthMultisampledTexture, |
| core::type::TextureDimension::k2d, |
| /* texel type */ kF32, |
| {}, |
| {"result", 1, kU32}, |
| {"%result = OpImageQuerySamples %uint %t"}, |
| }), |
| PrintCase); |
| |
| //////////////////////////////////////////////////////////////// |
| //// textureSampleBaseClampToEdge |
| //////////////////////////////////////////////////////////////// |
| |
| TEST_F(SpirvWriterTest, TextureSampleBaseClampToEdge_2d_f32) { |
| auto* texture_ty = |
| ty.Get<core::type::SampledTexture>(core::type::TextureDimension::k2d, ty.f32()); |
| |
| Vector<core::ir::FunctionParam*, 4> args; |
| args.Push(b.FunctionParam("texture", texture_ty)); |
| args.Push(b.FunctionParam("sampler", ty.sampler())); |
| args.Push(b.FunctionParam("coords", ty.vec2<f32>())); |
| |
| auto* func = b.Function("foo", ty.vec4<f32>()); |
| func->SetParams(args); |
| b.Append(func->Block(), [&] { |
| auto* result = b.Call(ty.vec4<f32>(), core::BuiltinFn::kTextureSampleBaseClampToEdge, args); |
| b.Return(func, result); |
| mod.SetName(result, "result"); |
| }); |
| |
| ASSERT_TRUE(Generate()) << Error() << output_; |
| EXPECT_INST("%18 = OpConstantComposite %v2float %float_0_5 %float_0_5"); |
| EXPECT_INST("%21 = OpConstantComposite %v2float %float_1 %float_1"); |
| EXPECT_INST(R"( |
| %12 = OpImageQuerySizeLod %v2uint %texture %uint_0 |
| %16 = OpConvertUToF %v2float %12 |
| %17 = OpFDiv %v2float %18 %16 |
| %20 = OpFSub %v2float %21 %17 |
| %23 = OpExtInst %v2float %24 NClamp %coords %17 %20 |
| %25 = OpSampledImage %26 %texture %sampler |
| %result = OpImageSampleExplicitLod %v4float %25 %23 Lod %float_0 |
| )"); |
| } |
| |
| //////////////////////////////////////////////////////////////// |
| //// Storage textures with bgra8unorm texel formats |
| //////////////////////////////////////////////////////////////// |
| |
| TEST_F(SpirvWriterTest, Bgra8Unorm_textureStore) { |
| auto format = core::TexelFormat::kBgra8Unorm; |
| auto* texture_ty = ty.Get<core::type::StorageTexture>( |
| core::type::TextureDimension::k2d, format, core::Access::kWrite, |
| core::type::StorageTexture::SubtypeFor(format, ty)); |
| |
| auto* texture = b.FunctionParam("texture", texture_ty); |
| auto* coords = b.FunctionParam("coords", ty.vec2<u32>()); |
| auto* value = b.FunctionParam("value", ty.vec4<f32>()); |
| auto* func = b.Function("foo", ty.void_()); |
| func->SetParams({texture, coords, value}); |
| b.Append(func->Block(), [&] { |
| b.Call(ty.void_(), core::BuiltinFn::kTextureStore, texture, coords, value); |
| b.Return(func); |
| }); |
| |
| Options options; |
| options.disable_image_robustness = true; |
| ASSERT_TRUE(Generate(options)) << Error() << output_; |
| EXPECT_INST(R"( |
| %13 = OpVectorShuffle %v4float %value %value 2 1 0 3 |
| OpImageWrite %texture %coords %13 None |
| )"); |
| } |
| |
| //////////////////////////////////////////////////////////////// |
| //// Texture robustness enabled. |
| //////////////////////////////////////////////////////////////// |
| |
| TEST_F(SpirvWriterTest, TextureDimensions_WithRobustness) { |
| auto* texture_ty = |
| ty.Get<core::type::SampledTexture>(core::type::TextureDimension::k2d, ty.f32()); |
| |
| auto* texture = b.FunctionParam("texture", texture_ty); |
| auto* level = b.FunctionParam("level", ty.i32()); |
| auto* func = b.Function("foo", ty.vec2<u32>()); |
| func->SetParams({texture, level}); |
| b.Append(func->Block(), [&] { |
| auto* dims = b.Call(ty.vec2<u32>(), core::BuiltinFn::kTextureDimensions, texture, level); |
| b.Return(func, dims); |
| mod.SetName(dims, "dims"); |
| }); |
| |
| ASSERT_TRUE(Generate()) << Error() << output_; |
| EXPECT_INST(R"( |
| %11 = OpImageQueryLevels %uint %texture |
| %12 = OpISub %uint %11 %uint_1 |
| %14 = OpBitcast %uint %level |
| %15 = OpExtInst %uint %16 UMin %14 %12 |
| %dims = OpImageQuerySizeLod %v2uint %texture %15 |
| )"); |
| } |
| |
| TEST_F(SpirvWriterTest, TextureLoad_WithRobustness) { |
| auto* texture_ty = |
| ty.Get<core::type::SampledTexture>(core::type::TextureDimension::k2d, ty.f32()); |
| |
| auto* texture = b.FunctionParam("texture", texture_ty); |
| auto* coords = b.FunctionParam("coords", ty.vec2<u32>()); |
| auto* level = b.FunctionParam("level", ty.i32()); |
| auto* func = b.Function("foo", ty.vec4<f32>()); |
| func->SetParams({texture, coords, level}); |
| b.Append(func->Block(), [&] { |
| auto* result = |
| b.Call(ty.vec4<f32>(), core::BuiltinFn::kTextureLoad, texture, coords, level); |
| b.Return(func, result); |
| mod.SetName(result, "result"); |
| }); |
| |
| ASSERT_TRUE(Generate()) << Error() << output_; |
| EXPECT_INST(R"( |
| %13 = OpImageQuerySizeLod %v2uint %texture %uint_0 |
| %15 = OpISub %v2uint %13 %16 |
| %18 = OpExtInst %v2uint %19 UMin %coords %15 |
| %20 = OpImageQueryLevels %uint %texture |
| %21 = OpISub %uint %20 %uint_1 |
| %22 = OpBitcast %uint %level |
| %23 = OpExtInst %uint %19 UMin %22 %21 |
| %result = OpImageFetch %v4float %texture %18 Lod %23 |
| )"); |
| } |
| |
| TEST_F(SpirvWriterTest, TextureStore_WithRobustness) { |
| auto format = core::TexelFormat::kRgba8Unorm; |
| auto* texture_ty = ty.Get<core::type::StorageTexture>( |
| core::type::TextureDimension::k2dArray, format, core::Access::kWrite, |
| core::type::StorageTexture::SubtypeFor(format, ty)); |
| |
| auto* texture = b.FunctionParam("texture", texture_ty); |
| auto* coords = b.FunctionParam("coords", ty.vec2<u32>()); |
| auto* layer = b.FunctionParam("layer", ty.i32()); |
| auto* value = b.FunctionParam("value", ty.vec4<f32>()); |
| auto* func = b.Function("foo", ty.void_()); |
| func->SetParams({texture, coords, layer, value}); |
| b.Append(func->Block(), [&] { |
| b.Call(ty.void_(), core::BuiltinFn::kTextureStore, texture, coords, layer, value); |
| b.Return(func); |
| }); |
| |
| ASSERT_TRUE(Generate()) << Error() << output_; |
| EXPECT_INST(R"( |
| %15 = OpImageQuerySize %v3uint %texture |
| %17 = OpVectorShuffle %v2uint %15 %15 0 1 |
| %18 = OpISub %v2uint %17 %19 |
| %21 = OpExtInst %v2uint %22 UMin %coords %18 |
| %23 = OpImageQuerySize %v3uint %texture |
| %24 = OpCompositeExtract %uint %23 2 |
| %25 = OpISub %uint %24 %uint_1 |
| %26 = OpBitcast %uint %layer |
| %27 = OpExtInst %uint %22 UMin %26 %25 |
| %28 = OpCompositeConstruct %v3uint %21 %27 |
| OpImageWrite %texture %28 %value None |
| )"); |
| } |
| |
| } // namespace |
| } // namespace tint::spirv::writer |