diff --git a/src/ast/intrinsic.cc b/src/ast/intrinsic.cc index 3f6f8ac210..2282650927 100644 --- a/src/ast/intrinsic.cc +++ b/src/ast/intrinsic.cc @@ -212,6 +212,9 @@ std::ostream& operator<<(std::ostream& out, Intrinsic i) { case Intrinsic::kTextureNumLayers: out << "textureNumLayers"; return out; + case Intrinsic::kTextureNumLevels: + out << "textureNumLevels"; + return out; case Intrinsic::kTextureSample: out << "textureSample"; return out; @@ -268,8 +271,8 @@ bool IsFloatClassificationIntrinsic(Intrinsic i) { } bool IsTextureIntrinsic(Intrinsic i) { - return i == Intrinsic::kTextureDimensions || i == Intrinsic::kTextureLoad || - i == Intrinsic::kTextureNumLayers || i == Intrinsic::kTextureSample || + return IsImageQueryIntrinsic(i) || i == Intrinsic::kTextureLoad || + i == Intrinsic::kTextureSample || i == Intrinsic::kTextureSampleLevel || i == Intrinsic::kTextureSampleBias || i == Intrinsic::kTextureSampleCompare || @@ -278,7 +281,7 @@ bool IsTextureIntrinsic(Intrinsic i) { bool IsImageQueryIntrinsic(Intrinsic i) { return i == ast::Intrinsic::kTextureDimensions || - i == Intrinsic::kTextureNumLayers; + i == Intrinsic::kTextureNumLayers || i == Intrinsic::kTextureNumLevels; } } // namespace intrinsic diff --git a/src/ast/intrinsic.h b/src/ast/intrinsic.h index 36eb5ad1ca..bdf310e6dd 100644 --- a/src/ast/intrinsic.h +++ b/src/ast/intrinsic.h @@ -86,6 +86,7 @@ enum class Intrinsic { kTextureDimensions, kTextureLoad, kTextureNumLayers, + kTextureNumLevels, kTextureSample, kTextureSampleBias, kTextureSampleCompare, diff --git a/src/ast/intrinsic_texture_helper_test.cc b/src/ast/intrinsic_texture_helper_test.cc index ac3c61a8f7..280236d089 100644 --- a/src/ast/intrinsic_texture_helper_test.cc +++ b/src/ast/intrinsic_texture_helper_test.cc @@ -543,7 +543,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayers1dArray, - "textureNumLayers(t : texture_1d_array) -> i32", + "textureNumLayers(t : texture_1d_array) -> i32", TextureKind::kRegular, type::SamplerKind::kSampler, type::TextureDimension::k1dArray, @@ -553,7 +553,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayers2dArray, - "textureNumLayers(t : texture_2d_array) -> i32", + "textureNumLayers(t : texture_2d_array) -> i32", TextureKind::kRegular, type::SamplerKind::kSampler, type::TextureDimension::k2dArray, @@ -563,7 +563,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayersCubeArray, - "textureNumLayers(t : texture_cube_array) -> i32", + "textureNumLayers(t : texture_cube_array) -> i32", TextureKind::kRegular, type::SamplerKind::kSampler, type::TextureDimension::kCubeArray, @@ -573,7 +573,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayersMultisampled_2dArray, - "textureNumLayers(t : texture_multisampled_2d_array) -> i32", + "textureNumLayers(t : texture_multisampled_2d_array) -> i32", TextureKind::kMultisampled, type::SamplerKind::kSampler, type::TextureDimension::k2dArray, @@ -603,7 +603,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayersStorageWO1dArray, - "textureNumLayers(t : texture_storage_1d_array) -> i32", + "textureNumLayers(t : texture_storage_1d_array) -> i32", ast::AccessControl::kWriteOnly, ast::type::ImageFormat::kRgba32Float, type::TextureDimension::k1dArray, @@ -613,7 +613,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kNumLayersStorageWO2dArray, - "textureNumLayers(t : texture_storage_2d_array) -> i32", + "textureNumLayers(t : texture_storage_2d_array) -> i32", ast::AccessControl::kWriteOnly, ast::type::ImageFormat::kRgba32Float, type::TextureDimension::k2dArray, @@ -621,6 +621,96 @@ std::vector TextureOverloadCase::ValidCases() { "textureNumLayers", [](Builder* b) { return b->ExprList("texture"); }, }, + { + ValidTextureOverload::kNumLevels2d, + "textureNumLevels(t : texture_2d) -> i32", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevels2dArray, + "textureNumLevels(t : texture_2d_array) -> i32", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevels3d, + "textureNumLevels(t : texture_3d) -> i32", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsCube, + "textureNumLevels(t : texture_cube) -> i32", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsCubeArray, + "textureNumLevels(t : texture_cube_array) -> i32", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsDepth2d, + "textureNumLevels(t : texture_depth_2d) -> i32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsDepth2dArray, + "textureNumLevels(t : texture_depth_2d_array) -> i32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsDepthCube, + "textureNumLevels(t : texture_depth_cube) -> i32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, + { + ValidTextureOverload::kNumLevelsDepthCubeArray, + "textureNumLevels(t : texture_depth_cube_array) -> i32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureNumLevels", + [](Builder* b) { return b->ExprList("texture"); }, + }, { ValidTextureOverload::kSample1dF32, "textureSample(t : texture_1d,\n" @@ -2413,7 +2503,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kStoreWO1dRgba32float, - "textureStore(t : texture_storage_1d,\n" + "textureStore(t : texture_storage_1d,\n" " coords : i32,\n" " value : vec4) -> void", ast::AccessControl::kWriteOnly, @@ -2429,7 +2519,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kStoreWO1dArrayRgba32float, - "textureStore(t : texture_storage_1d_array,\n" + "textureStore(t : texture_storage_1d_array,\n" " coords : i32,\n" " array_index : i32,\n" " value : vec4) -> void", @@ -2447,7 +2537,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kStoreWO2dRgba32float, - "textureStore(t : texture_storage_2d,\n" + "textureStore(t : texture_storage_2d,\n" " coords : vec2,\n" " value : vec4) -> void", ast::AccessControl::kWriteOnly, @@ -2463,7 +2553,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kStoreWO2dArrayRgba32float, - "textureStore(t : texture_storage_2d_array,\n" + "textureStore(t : texture_storage_2d_array,\n" " coords : vec2,\n" " array_index : i32,\n" " value : vec4) -> void", @@ -2481,7 +2571,7 @@ std::vector TextureOverloadCase::ValidCases() { }, { ValidTextureOverload::kStoreWO3dRgba32float, - "textureStore(t : texture_storage_3d,\n" + "textureStore(t : texture_storage_3d,\n" " coords : vec3,\n" " value : vec4) -> void", ast::AccessControl::kWriteOnly, diff --git a/src/ast/intrinsic_texture_helper_test.h b/src/ast/intrinsic_texture_helper_test.h index ca0d655626..c30f1be891 100644 --- a/src/ast/intrinsic_texture_helper_test.h +++ b/src/ast/intrinsic_texture_helper_test.h @@ -77,6 +77,15 @@ enum class ValidTextureOverload { kNumLayersDepthCubeArray, kNumLayersStorageWO1dArray, kNumLayersStorageWO2dArray, + kNumLevels2d, + kNumLevels2dArray, + kNumLevels3d, + kNumLevelsCube, + kNumLevelsCubeArray, + kNumLevelsDepth2d, + kNumLevelsDepth2dArray, + kNumLevelsDepthCube, + kNumLevelsDepthCubeArray, kSample1dF32, kSample1dArrayF32, kSample2dF32, diff --git a/src/type_determiner.cc b/src/type_determiner.cc index 57ba1013a6..84f9b6f501 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -567,6 +567,7 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, } break; case ast::Intrinsic::kTextureNumLayers: + case ast::Intrinsic::kTextureNumLevels: param.idx.texture = param.count++; break; case ast::Intrinsic::kTextureLoad: @@ -696,6 +697,7 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, break; } case ast::Intrinsic::kTextureNumLayers: + case ast::Intrinsic::kTextureNumLevels: return_type = mod_->create(); break; case ast::Intrinsic::kTextureStore: @@ -1034,6 +1036,8 @@ bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) { ident->set_intrinsic(ast::Intrinsic::kTextureDimensions); } else if (name == "textureNumLayers") { ident->set_intrinsic(ast::Intrinsic::kTextureNumLayers); + } else if (name == "textureNumLevels") { + ident->set_intrinsic(ast::Intrinsic::kTextureNumLevels); } else if (name == "textureLoad") { ident->set_intrinsic(ast::Intrinsic::kTextureLoad); } else if (name == "textureStore") { diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index dcd35196c7..542d0bef2a 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -1765,6 +1765,7 @@ INSTANTIATE_TEST_SUITE_P( IntrinsicData{"textureDimensions", ast::Intrinsic::kTextureDimensions}, IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad}, IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers}, + IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels}, IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample}, IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias}, IntrinsicData{"textureSampleCompare", @@ -2938,6 +2939,16 @@ const char* expected_texture_overload( case ValidTextureOverload::kNumLayersStorageWO1dArray: case ValidTextureOverload::kNumLayersStorageWO2dArray: return R"(textureNumLayers(texture))"; + case ValidTextureOverload::kNumLevels2d: + case ValidTextureOverload::kNumLevels2dArray: + case ValidTextureOverload::kNumLevels3d: + case ValidTextureOverload::kNumLevelsCube: + case ValidTextureOverload::kNumLevelsCubeArray: + case ValidTextureOverload::kNumLevelsDepth2d: + case ValidTextureOverload::kNumLevelsDepth2dArray: + case ValidTextureOverload::kNumLevelsDepthCube: + case ValidTextureOverload::kNumLevelsDepthCubeArray: + return R"(textureNumLevels(texture))"; case ValidTextureOverload::kDimensions2dLevel: case ValidTextureOverload::kDimensions2dArrayLevel: case ValidTextureOverload::kDimensions3dLevel: @@ -3193,6 +3204,8 @@ TEST_P(TypeDeterminerTextureIntrinsicTest, Call) { } } else if (std::string(param.function) == "textureNumLayers") { EXPECT_EQ(call->result_type(), ty.i32); + } else if (std::string(param.function) == "textureNumLevels") { + EXPECT_EQ(call->result_type(), ty.i32); } else if (std::string(param.function) == "textureStore") { EXPECT_EQ(call->result_type(), ty.void_); } else { diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index a750271fbb..187020d065 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -697,7 +697,8 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, switch (ident->intrinsic()) { case ast::Intrinsic::kTextureDimensions: - case ast::Intrinsic::kTextureNumLayers: { + case ast::Intrinsic::kTextureNumLayers: + case ast::Intrinsic::kTextureNumLevels: { // Declare a variable to hold the queried texture info auto dims = generate_name(kTempNamePrefix); @@ -706,85 +707,120 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, return false; } - auto get_dimensions = [&](std::initializer_list&& suffixes) { - pre << texture_name.str() << ".GetDimensions("; - if (pidx.level != kNotUsed) { - pre << pidx.level << ", "; - } - bool first = true; - for (auto* suffix : suffixes) { - if (!first) { - pre << ", "; - } - first = false; - pre << dims << suffix; - } - pre << ");"; - }; + int num_dimensions = 0; + const char* swizzle = ""; + bool add_mip_level_in = false; - const char* dims_swizzle = ""; - const char* num_els_swizzle = ""; - - std::stringstream ss; - switch (texture_type->dim()) { - case ast::type::TextureDimension::kNone: - error_ = "texture dimension is kNone"; - return false; - case ast::type::TextureDimension::k1d: - pre << "int " << dims << ";\n"; - get_dimensions({""}); - break; - case ast::type::TextureDimension::k1dArray: - pre << "int2 " << dims << ";\n"; - get_dimensions({".x", ".y"}); - dims_swizzle = ".x"; - num_els_swizzle = ".y"; - break; - case ast::type::TextureDimension::k2d: - pre << "int2 " << dims << ";\n"; - get_dimensions({".x", ".y"}); - break; - case ast::type::TextureDimension::k2dArray: - pre << "int3 " << dims << ";\n"; - get_dimensions({".x", ".y", ".z"}); - dims_swizzle = ".xy"; - num_els_swizzle = ".z"; - break; - case ast::type::TextureDimension::k3d: - pre << "int3 " << dims << ";\n"; - get_dimensions({".x", ".y", ".z"}); - break; - case ast::type::TextureDimension::kCube: - // width == height == depth for cubes - // See https://github.com/gpuweb/gpuweb/issues/1345 - pre << "int2 " << dims << ";\n"; - get_dimensions({".x", ".y"}); - dims_swizzle = ".xyy"; // [width, height, height] - break; - case ast::type::TextureDimension::kCubeArray: - // width == height == depth for cubes - // See https://github.com/gpuweb/gpuweb/issues/1345 - pre << "int3 " << dims << ";\n"; - get_dimensions({".x", ".y", ".z"}); - dims_swizzle = ".xyy"; // [width, height, height] - num_els_swizzle = ".z"; - break; - } - - // The result of the textureDimensions() call is now in temporary - // variable. This may be packed with other data, so the final expression - // may require a swizzle. switch (ident->intrinsic()) { case ast::Intrinsic::kTextureDimensions: - out << dims << dims_swizzle; - return true; + switch (texture_type->dim()) { + case ast::type::TextureDimension::kNone: + error_ = "texture dimension is kNone"; + return false; + case ast::type::TextureDimension::k1d: + num_dimensions = 1; + break; + case ast::type::TextureDimension::k1dArray: + num_dimensions = 2; + swizzle = ".x"; + break; + case ast::type::TextureDimension::k2d: + num_dimensions = 2; + break; + case ast::type::TextureDimension::k2dArray: + num_dimensions = 3; + swizzle = ".xy"; + break; + case ast::type::TextureDimension::k3d: + num_dimensions = 3; + break; + case ast::type::TextureDimension::kCube: + // width == height == depth for cubes + // See https://github.com/gpuweb/gpuweb/issues/1345 + num_dimensions = 2; + swizzle = ".xyy"; // [width, height, height] + break; + case ast::type::TextureDimension::kCubeArray: + // width == height == depth for cubes + // See https://github.com/gpuweb/gpuweb/issues/1345 + num_dimensions = 3; + swizzle = ".xyy"; // [width, height, height] + break; + } + break; case ast::Intrinsic::kTextureNumLayers: - out << dims << num_els_swizzle; - return true; + switch (texture_type->dim()) { + default: + error_ = "texture dimension is not arrayed"; + return false; + case ast::type::TextureDimension::k1dArray: + num_dimensions = 2; + swizzle = ".y"; + break; + case ast::type::TextureDimension::k2dArray: + case ast::type::TextureDimension::kCubeArray: + num_dimensions = 3; + swizzle = ".z"; + break; + } + break; + case ast::Intrinsic::kTextureNumLevels: + add_mip_level_in = true; + switch (texture_type->dim()) { + default: + error_ = "texture dimension does not support mips"; + return false; + case ast::type::TextureDimension::k2d: + case ast::type::TextureDimension::kCube: + num_dimensions = 3; + swizzle = ".z"; + break; + case ast::type::TextureDimension::k2dArray: + case ast::type::TextureDimension::k3d: + case ast::type::TextureDimension::kCubeArray: + num_dimensions = 4; + swizzle = ".w"; + break; + } + break; default: - error_ = "Unhandled intrinsic"; + error_ = "unexpected intrinsic"; return false; } + + if (num_dimensions == 1) { + pre << "int " << dims << ";\n"; + } else { + pre << "int" << num_dimensions << " " << dims << ";\n"; + } + + pre << texture_name.str() << ".GetDimensions("; + if (pidx.level != kNotUsed) { + pre << pidx.level << ", "; + } else if (add_mip_level_in) { + pre << "0, "; + } + + if (num_dimensions == 1) { + pre << dims; + } else { + assert(num_dimensions > 0); + assert(num_dimensions <= 4); + static constexpr char xyzw[] = {'x', 'y', 'z', 'w'}; + for (int i = 0; i < num_dimensions; i++) { + if (i > 0) { + pre << ", "; + } + pre << dims << "." << xyzw[i]; + } + } + pre << ");"; + + // The out parameters of the GetDimensions() call is now in temporary + // `dims` variable. This may be packed with other data, so the final + // expression may require a swizzle. + out << dims << swizzle; + return true; } default: break; diff --git a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc index 972283c258..4a15b4ca30 100644 --- a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc @@ -157,6 +157,27 @@ ExpectedResult expected_texture_overload( "GetDimensions(_tint_tmp.x, _tint_tmp.y, _tint_tmp.z);", "_tint_tmp.z", }; + case ValidTextureOverload::kNumLevels2d: + case ValidTextureOverload::kNumLevelsCube: + case ValidTextureOverload::kNumLevelsDepth2d: + case ValidTextureOverload::kNumLevelsDepthCube: + return { + "int3 _tint_tmp;\n" + "texture_tint_0." + "GetDimensions(0, _tint_tmp.x, _tint_tmp.y, _tint_tmp.z);", + "_tint_tmp.z", + }; + case ValidTextureOverload::kNumLevels2dArray: + case ValidTextureOverload::kNumLevels3d: + case ValidTextureOverload::kNumLevelsCubeArray: + case ValidTextureOverload::kNumLevelsDepth2dArray: + case ValidTextureOverload::kNumLevelsDepthCubeArray: + return { + "int4 _tint_tmp;\n" + "texture_tint_0.GetDimensions(0, " + "_tint_tmp.x, _tint_tmp.y, _tint_tmp.z, _tint_tmp.w);", + "_tint_tmp.w", + }; case ValidTextureOverload::kSample1dF32: return R"(texture_tint_0.Sample(sampler_tint_0, 1.0f))"; case ValidTextureOverload::kSample1dArrayF32: diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 30c1887516..f3a55e4f5f 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -679,6 +679,14 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { out_ << ".get_array_size())"; return true; } + case ast::Intrinsic::kTextureNumLevels: { + out_ << "int("; + if (!EmitExpression(params[pidx.texture])) { + return false; + } + out_ << ".get_num_mip_levels())"; + return true; + } default: break; } diff --git a/src/writer/msl/generator_impl_intrinsic_texture_test.cc b/src/writer/msl/generator_impl_intrinsic_texture_test.cc index 67bbdc7602..962a18be1d 100644 --- a/src/writer/msl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/msl/generator_impl_intrinsic_texture_test.cc @@ -80,6 +80,16 @@ std::string expected_texture_overload( case ValidTextureOverload::kNumLayersStorageWO1dArray: case ValidTextureOverload::kNumLayersStorageWO2dArray: return R"(int(texture_tint_0.get_array_size()))"; + case ValidTextureOverload::kNumLevels2d: + case ValidTextureOverload::kNumLevels2dArray: + case ValidTextureOverload::kNumLevels3d: + case ValidTextureOverload::kNumLevelsCube: + case ValidTextureOverload::kNumLevelsCubeArray: + case ValidTextureOverload::kNumLevelsDepth2d: + case ValidTextureOverload::kNumLevelsDepth2dArray: + case ValidTextureOverload::kNumLevelsDepthCube: + case ValidTextureOverload::kNumLevelsDepthCubeArray: + return R"(int(texture_tint_0.get_num_mip_levels()))"; case ValidTextureOverload::kSample1dF32: return R"(texture_tint_0.sample(sampler_tint_0, 1.0f))"; case ValidTextureOverload::kSample1dArrayF32: diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 8887d63946..7f913a5bbb 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -2245,6 +2245,12 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, } break; } + case ast::Intrinsic::kTextureNumLevels: { + op = spv::Op::OpImageQueryLevels; + append_result_type_and_id_to_spirv_params(); + spirv_params.emplace_back(gen_param(pidx.texture)); + break; + } case ast::Intrinsic::kTextureLoad: { op = texture_type->Is() ? spv::Op::OpImageRead diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc index abb588fb5e..92672804cc 100644 --- a/src/writer/spirv/builder_intrinsic_texture_test.cc +++ b/src/writer/spirv/builder_intrinsic_texture_test.cc @@ -909,6 +909,170 @@ OpCapability ImageQuery )", R"( OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevels2d: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevels2dArray: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevels3d: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsCube: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 Cube 0 0 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsCubeArray: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 Cube 0 1 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability SampledCubeArray +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsDepth2d: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 0 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsDepth2dArray: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 1 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsDepthCube: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 Cube 1 0 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability ImageQuery +)"}; + case ValidTextureOverload::kNumLevelsDepthCubeArray: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 Cube 1 1 0 1 Unknown +%2 = OpTypePointer UniformConstant %3 +%1 = OpVariable %2 UniformConstant +%7 = OpTypeSampler +%6 = OpTypePointer UniformConstant %7 +%5 = OpVariable %6 UniformConstant +%9 = OpTypeInt 32 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageQueryLevels %9 %10 +)", + R"( +OpCapability SampledCubeArray +OpCapability ImageQuery )"}; case ValidTextureOverload::kSample1dF32: return {