[tint][spirv] Inline image_from_texture in builtin_polyfill
The helper function in this file is only used for builtin_polyfill now
so it can be merged in this file.
Also reworks how the computation of replacement types is done in
builtin_polyfill to make it easier to extend in the future.
Bug: 411573958
Change-Id: Id79bdd433c1f43f40e390ba737599e56e85bca50
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/237916
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tint/lang/spirv/ir/BUILD.bazel b/src/tint/lang/spirv/ir/BUILD.bazel
index 1926b21..f71d6a4 100644
--- a/src/tint/lang/spirv/ir/BUILD.bazel
+++ b/src/tint/lang/spirv/ir/BUILD.bazel
@@ -40,12 +40,10 @@
name = "ir",
srcs = [
"builtin_call.cc",
- "image_from_texture.cc",
"literal_operand.cc",
],
hdrs = [
"builtin_call.h",
- "image_from_texture.h",
"literal_operand.h",
],
deps = [
@@ -57,7 +55,6 @@
"//src/tint/lang/core/type",
"//src/tint/lang/spirv",
"//src/tint/lang/spirv/intrinsic",
- "//src/tint/lang/spirv/type",
"//src/tint/utils",
"//src/tint/utils/containers",
"//src/tint/utils/diagnostic",
diff --git a/src/tint/lang/spirv/ir/BUILD.cmake b/src/tint/lang/spirv/ir/BUILD.cmake
index 20f8765..d4abd09 100644
--- a/src/tint/lang/spirv/ir/BUILD.cmake
+++ b/src/tint/lang/spirv/ir/BUILD.cmake
@@ -41,8 +41,6 @@
tint_add_target(tint_lang_spirv_ir lib
lang/spirv/ir/builtin_call.cc
lang/spirv/ir/builtin_call.h
- lang/spirv/ir/image_from_texture.cc
- lang/spirv/ir/image_from_texture.h
lang/spirv/ir/literal_operand.cc
lang/spirv/ir/literal_operand.h
)
@@ -56,7 +54,6 @@
tint_lang_core_type
tint_lang_spirv
tint_lang_spirv_intrinsic
- tint_lang_spirv_type
tint_utils
tint_utils_containers
tint_utils_diagnostic
diff --git a/src/tint/lang/spirv/ir/BUILD.gn b/src/tint/lang/spirv/ir/BUILD.gn
index 3498df0..c06651b 100644
--- a/src/tint/lang/spirv/ir/BUILD.gn
+++ b/src/tint/lang/spirv/ir/BUILD.gn
@@ -47,8 +47,6 @@
sources = [
"builtin_call.cc",
"builtin_call.h",
- "image_from_texture.cc",
- "image_from_texture.h",
"literal_operand.cc",
"literal_operand.h",
]
@@ -62,7 +60,6 @@
"${tint_src_dir}/lang/core/type",
"${tint_src_dir}/lang/spirv",
"${tint_src_dir}/lang/spirv/intrinsic",
- "${tint_src_dir}/lang/spirv/type",
"${tint_src_dir}/utils",
"${tint_src_dir}/utils/containers",
"${tint_src_dir}/utils/diagnostic",
diff --git a/src/tint/lang/spirv/ir/image_from_texture.cc b/src/tint/lang/spirv/ir/image_from_texture.cc
deleted file mode 100644
index 806647e..0000000
--- a/src/tint/lang/spirv/ir/image_from_texture.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2025 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/spirv/ir/image_from_texture.h"
-#include "src/tint/lang/core/type/f32.h"
-#include "src/tint/lang/core/type/i32.h"
-#include "src/tint/lang/core/type/input_attachment.h"
-#include "src/tint/lang/core/type/sampled_texture.h"
-#include "src/tint/lang/core/type/storage_texture.h"
-#include "src/tint/lang/core/type/u32.h"
-#include "src/tint/utils/rtti/switch.h"
-
-namespace tint::spirv::ir {
-
-const spirv::type::Image* ImageFromTexture(core::type::Manager& ty,
- const core::type::Texture* tex_ty) {
- auto dim = type::Dim::kD1;
- auto depth = type::Depth::kNotDepth;
- auto arrayed = type::Arrayed::kNonArrayed;
- auto ms = type::Multisampled::kSingleSampled;
- auto sampled = type::Sampled::kSamplingCompatible;
- auto fmt = core::TexelFormat::kUndefined;
- auto access = core::Access::kReadWrite;
- const core::type::Type* sample_ty = ty.f32();
-
- switch (tex_ty->Dim()) {
- case core::type::TextureDimension::k1d:
- dim = type::Dim::kD1;
- break;
- case core::type::TextureDimension::k2d:
- dim = type::Dim::kD2;
- break;
- case core::type::TextureDimension::k2dArray:
- dim = type::Dim::kD2;
- arrayed = type::Arrayed::kArrayed;
- break;
- case core::type::TextureDimension::k3d:
- dim = type::Dim::kD3;
- break;
- case core::type::TextureDimension::kCube:
- dim = type::Dim::kCube;
- break;
- case core::type::TextureDimension::kCubeArray:
- dim = type::Dim::kCube;
- arrayed = type::Arrayed::kArrayed;
- break;
- default:
- TINT_ICE() << "Invalid texture dimension: " << tex_ty->Dim();
- }
-
- tint::Switch(
- tex_ty, //
- [&](const core::type::DepthTexture*) { //
- depth = type::Depth::kDepth;
- },
- [&](const core::type::DepthMultisampledTexture*) {
- depth = type::Depth::kDepth;
- ms = type::Multisampled::kMultisampled;
- },
- [&](const core::type::MultisampledTexture* mt) {
- ms = type::Multisampled::kMultisampled;
- sample_ty = mt->Type();
- },
- [&](const core::type::SampledTexture* st) {
- sampled = type::Sampled::kSamplingCompatible;
- sample_ty = st->Type();
- },
- [&](const core::type::StorageTexture* st) {
- sampled = type::Sampled::kReadWriteOpCompatible;
- fmt = st->TexelFormat();
- sample_ty = st->Type();
- access = st->Access();
- },
- [&](const core::type::InputAttachment* ia) {
- dim = type::Dim::kSubpassData;
- sampled = type::Sampled::kReadWriteOpCompatible;
- sample_ty = ia->Type();
- },
- TINT_ICE_ON_NO_MATCH);
-
- return ty.Get<type::Image>(sample_ty, dim, depth, arrayed, ms, sampled, fmt, access);
-}
-
-} // namespace tint::spirv::ir
diff --git a/src/tint/lang/spirv/ir/image_from_texture.h b/src/tint/lang/spirv/ir/image_from_texture.h
deleted file mode 100644
index f95a787..0000000
--- a/src/tint/lang/spirv/ir/image_from_texture.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2025 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.
-
-#ifndef SRC_TINT_LANG_SPIRV_IR_IMAGE_FROM_TEXTURE_H_
-#define SRC_TINT_LANG_SPIRV_IR_IMAGE_FROM_TEXTURE_H_
-
-#include "src/tint/lang/core/type/manager.h"
-#include "src/tint/lang/core/type/texture.h"
-#include "src/tint/lang/spirv/type/image.h"
-
-namespace tint::spirv::ir {
-
-const spirv::type::Image* ImageFromTexture(core::type::Manager& ty,
- const core::type::Texture* tex_ty);
-
-}
-
-#endif // SRC_TINT_LANG_SPIRV_IR_IMAGE_FROM_TEXTURE_H_
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index 75895cf..a9889bd 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -90,7 +90,6 @@
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/lang/spirv/ir/builtin_call.h"
-#include "src/tint/lang/spirv/ir/image_from_texture.h"
#include "src/tint/lang/spirv/ir/literal_operand.h"
#include "src/tint/lang/spirv/type/explicit_layout_array.h"
#include "src/tint/lang/spirv/type/sampled_image.h"
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
index 0b9a7ef..6db6703 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
@@ -43,7 +43,6 @@
#include "src/tint/lang/core/type/storage_texture.h"
#include "src/tint/lang/core/type/texture.h"
#include "src/tint/lang/spirv/ir/builtin_call.h"
-#include "src/tint/lang/spirv/ir/image_from_texture.h"
#include "src/tint/lang/spirv/ir/literal_operand.h"
#include "src/tint/lang/spirv/type/sampled_image.h"
#include "src/tint/utils/ice/ice.h"
@@ -55,6 +54,92 @@
namespace {
+const spirv::type::Image* ImageFromTexture(core::type::Manager& ty,
+ const core::type::Texture* tex_ty) {
+ auto dim = type::Dim::kD1;
+ auto depth = type::Depth::kNotDepth;
+ auto arrayed = type::Arrayed::kNonArrayed;
+ auto ms = type::Multisampled::kSingleSampled;
+ auto sampled = type::Sampled::kSamplingCompatible;
+ auto fmt = core::TexelFormat::kUndefined;
+ auto access = core::Access::kReadWrite;
+ const core::type::Type* sample_ty = ty.f32();
+
+ switch (tex_ty->Dim()) {
+ case core::type::TextureDimension::k1d:
+ dim = type::Dim::kD1;
+ break;
+ case core::type::TextureDimension::k2d:
+ dim = type::Dim::kD2;
+ break;
+ case core::type::TextureDimension::k2dArray:
+ dim = type::Dim::kD2;
+ arrayed = type::Arrayed::kArrayed;
+ break;
+ case core::type::TextureDimension::k3d:
+ dim = type::Dim::kD3;
+ break;
+ case core::type::TextureDimension::kCube:
+ dim = type::Dim::kCube;
+ break;
+ case core::type::TextureDimension::kCubeArray:
+ dim = type::Dim::kCube;
+ arrayed = type::Arrayed::kArrayed;
+ break;
+ default:
+ TINT_ICE() << "Invalid texture dimension: " << tex_ty->Dim();
+ }
+
+ tint::Switch(
+ tex_ty, //
+ [&](const core::type::DepthTexture*) { //
+ depth = type::Depth::kDepth;
+ },
+ [&](const core::type::DepthMultisampledTexture*) {
+ depth = type::Depth::kDepth;
+ ms = type::Multisampled::kMultisampled;
+ },
+ [&](const core::type::MultisampledTexture* mt) {
+ ms = type::Multisampled::kMultisampled;
+ sample_ty = mt->Type();
+ },
+ [&](const core::type::SampledTexture* st) {
+ sampled = type::Sampled::kSamplingCompatible;
+ sample_ty = st->Type();
+ },
+ [&](const core::type::StorageTexture* st) {
+ sampled = type::Sampled::kReadWriteOpCompatible;
+ fmt = st->TexelFormat();
+ sample_ty = st->Type();
+ access = st->Access();
+ },
+ [&](const core::type::InputAttachment* ia) {
+ dim = type::Dim::kSubpassData;
+ sampled = type::Sampled::kReadWriteOpCompatible;
+ sample_ty = ia->Type();
+ },
+ TINT_ICE_ON_NO_MATCH);
+
+ return ty.Get<type::Image>(sample_ty, dim, depth, arrayed, ms, sampled, fmt, access);
+}
+
+/// Returns a replacement type if type replacement is necessary.
+/// @param ty the type manager
+/// @param type the type to replace
+/// @returns the replacement type if replacement needs to happen
+const core::type::Type* ReplacementType(core::type::Manager& ty, const core::type::Type* type) {
+ return Switch(
+ type,
+ [&](const core::type::Pointer* ptr) -> const core::type::Type* {
+ if (auto* replacement = ReplacementType(ty, ptr->StoreType())) {
+ return ty.ptr(ptr->AddressSpace(), replacement, ptr->Access());
+ }
+ return nullptr;
+ },
+ [&](const core::type::Texture* tex) { return ImageFromTexture(ty, tex); },
+ [&](Default) { return nullptr; });
+}
+
/// PIMPL state for the transform.
struct State {
/// The IR module.
@@ -74,28 +159,20 @@
// Find the builtins that need replacing.
Vector<core::ir::CoreBuiltinCall*, 4> worklist;
- // Convert function parameters to `spirv::type::Image` if necessary
+ // Replace types for function parameters if necessary
for (auto fn : ir.functions) {
for (auto* param : fn->Params()) {
- if (auto* tex = param->Type()->As<core::type::Texture>()) {
- param->SetType(ir::ImageFromTexture(ty, tex));
+ if (auto* replacement = ReplacementType(ty, param->Type())) {
+ param->SetType(replacement);
}
}
}
for (auto* inst : ir.Instructions()) {
- // Convert instruction results to `spirv::type::Image` if necessary
- if (!inst->Results().IsEmpty()) {
- if (auto* res = inst->Result(0)->As<core::ir::InstructionResult>()) {
- // Watch for pointers, which would be wrapping any texture on a `var`
- if (auto* tex = res->Type()->UnwrapPtr()->As<core::type::Texture>()) {
- auto* tex_ty = ir::ImageFromTexture(ty, tex);
- const core::type::Type* res_ty = tex_ty;
- if (auto* orig_ptr = res->Type()->As<core::type::Pointer>()) {
- res_ty = ty.ptr(orig_ptr->AddressSpace(), res_ty, orig_ptr->Access());
- }
- res->SetType(res_ty);
- }
+ // Replace types for instruction results if necessary
+ for (auto* result : inst->Results()) {
+ if (auto* replacement = ReplacementType(ty, result->Type())) {
+ result->SetType(replacement);
}
}
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.h b/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
index 8fff29e..79459db 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
@@ -39,7 +39,8 @@
namespace tint::spirv::writer::raise {
/// BuiltinPolyfill is a transform that replaces calls to builtins with polyfills and calls to
-/// SPIR-V backend intrinsic functions.
+/// SPIR-V backend intrinsic functions. It replaces core types with SPIR-V specific types at the
+/// same time to produce valid IR (e.g. texture types to spirv.image).
/// @param module the module to transform
/// @param use_vulkan_memory_model set `true` to use the vulkan memory model
/// @returns success or failure