Delete Single-Plane External Texture Transform

The multiplanar external texture transform has been integrated into
Dawn, which means we have no use for the single plane transform - so it
should be deleted.

Bug: dawn:1082
Change-Id: Id8977d03839b76c90ae6e70400d048c13fbe85f4
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/80120
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
This commit is contained in:
Brandon Jones
2022-02-25 20:14:52 +00:00
committed by Tint LUCI CQ
parent dbf75bc217
commit 6661b28d1e
25 changed files with 258 additions and 1075 deletions

View File

@@ -450,8 +450,6 @@ libtint_source_set("libtint_core_all_src") {
"transform/decompose_strided_array.h",
"transform/decompose_strided_matrix.cc",
"transform/decompose_strided_matrix.h",
"transform/external_texture_transform.cc",
"transform/external_texture_transform.h",
"transform/first_index_offset.cc",
"transform/first_index_offset.h",
"transform/fold_constants.cc",

View File

@@ -326,8 +326,6 @@ set(TINT_LIB_SRCS
transform/decompose_strided_array.h
transform/decompose_strided_matrix.cc
transform/decompose_strided_matrix.h
transform/external_texture_transform.cc
transform/external_texture_transform.h
transform/first_index_offset.cc
transform/first_index_offset.h
transform/fold_constants.cc
@@ -1015,7 +1013,6 @@ if(TINT_BUILD_TESTS)
transform/decompose_memory_access_test.cc
transform/decompose_strided_array_test.cc
transform/decompose_strided_matrix_test.cc
transform/external_texture_transform_test.cc
transform/first_index_offset_test.cc
transform/fold_constants_test.cc
transform/fold_trivial_single_use_lets_test.cc

View File

@@ -1,131 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/variable.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::ExternalTextureTransform);
namespace tint {
namespace transform {
ExternalTextureTransform::ExternalTextureTransform() = default;
ExternalTextureTransform::~ExternalTextureTransform() = default;
void ExternalTextureTransform::Run(CloneContext& ctx,
const DataMap&,
DataMap&) const {
auto& sem = ctx.src->Sem();
// Within this transform, usages of texture_external are replaced with a
// texture_2d<f32>, which will allow us perform operations on a
// texture_external without maintaining texture_external-specific code
// generation paths in the backends.
// When replacing instances of texture_external with texture_2d<f32> we must
// also modify calls to the texture_external overloads of textureLoad and
// textureSampleLevel, which unlike their texture_2d<f32> overloads do not
// require a level parameter. To do this we identify calls to textureLoad and
// textureSampleLevel that use texture_external as the first parameter and add
// a parameter for the level (which is always 0).
// Scan the AST nodes for calls to textureLoad or textureSampleLevel.
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* call_expr = node->As<ast::CallExpression>()) {
if (auto* builtin = sem.Get(call_expr)->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kTextureLoad ||
builtin->Type() == sem::BuiltinType::kTextureSampleLevel) {
// When a textureLoad or textureSampleLevel has been identified, check
// if the first parameter is an external texture.
if (auto* var =
sem.Get(call_expr->args[0])->As<sem::VariableUser>()) {
if (var->Variable()
->Type()
->UnwrapRef()
->Is<sem::ExternalTexture>()) {
if (builtin->Type() == sem::BuiltinType::kTextureLoad &&
call_expr->args.size() != 2) {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "expected textureLoad call with a texture_external to "
"have 2 parameters, found "
<< call_expr->args.size() << " parameters";
}
if (builtin->Type() == sem::BuiltinType::kTextureSampleLevel &&
call_expr->args.size() != 3) {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "expected textureSampleLevel call with a "
"texture_external to have 3 parameters, found "
<< call_expr->args.size() << " parameters";
}
// Replace the call with another that has the same parameters in
// addition to a level parameter (always zero for external
// textures).
auto* exp = ctx.Clone(call_expr->target.name);
auto* externalTextureParam = ctx.Clone(call_expr->args[0]);
ast::ExpressionList params;
if (builtin->Type() == sem::BuiltinType::kTextureLoad) {
auto* coordsParam = ctx.Clone(call_expr->args[1]);
auto* levelParam = ctx.dst->Expr(0);
params = {externalTextureParam, coordsParam, levelParam};
} else if (builtin->Type() ==
sem::BuiltinType::kTextureSampleLevel) {
auto* samplerParam = ctx.Clone(call_expr->args[1]);
auto* coordsParam = ctx.Clone(call_expr->args[2]);
auto* levelParam = ctx.dst->Expr(0.0f);
params = {externalTextureParam, samplerParam, coordsParam,
levelParam};
}
auto* newCall = ctx.dst->create<ast::CallExpression>(exp, params);
ctx.Replace(call_expr, newCall);
}
}
}
}
}
}
// Scan the AST nodes for external texture declarations.
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* var = node->As<ast::Variable>()) {
if (::tint::Is<ast::ExternalTexture>(var->type)) {
// Replace a single-plane external texture with a 2D, f32 sampled
// texture.
auto* newType = ctx.dst->ty.sampled_texture(ast::TextureDimension::k2d,
ctx.dst->ty.f32());
auto clonedSrc = ctx.Clone(var->source);
auto clonedSym = ctx.Clone(var->symbol);
auto* clonedConstructor = ctx.Clone(var->constructor);
auto clonedAttributes = ctx.Clone(var->attributes);
auto* newVar = ctx.dst->create<ast::Variable>(
clonedSrc, clonedSym, var->declared_storage_class,
var->declared_access, newType, false, false, clonedConstructor,
clonedAttributes);
ctx.Replace(var, newVar);
}
}
}
ctx.Clone();
}
} // namespace transform
} // namespace tint

View File

@@ -1,53 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TINT_TRANSFORM_EXTERNAL_TEXTURE_TRANSFORM_H_
#define SRC_TINT_TRANSFORM_EXTERNAL_TEXTURE_TRANSFORM_H_
#include <utility>
#include "src/tint/transform/transform.h"
namespace tint {
namespace transform {
/// Because an external texture is comprised of 1-3 texture views we can simply
/// transform external textures into the appropriate number of sampled textures.
/// This allows us to share SPIR-V/HLSL writer paths for sampled textures
/// instead of adding dedicated writer paths for external textures.
/// ExternalTextureTransform performs this transformation.
class ExternalTextureTransform
: public Castable<ExternalTextureTransform, Transform> {
public:
/// Constructor
ExternalTextureTransform();
/// Destructor
~ExternalTextureTransform() override;
protected:
/// Runs the transform using the CloneContext built for transforming a
/// program. Run() is responsible for calling Clone() on the CloneContext.
/// @param ctx the CloneContext primed with the input program and
/// ProgramBuilder
/// @param inputs optional extra transform-specific input data
/// @param outputs optional extra transform-specific output data
void Run(CloneContext& ctx,
const DataMap& inputs,
DataMap& outputs) const override;
};
} // namespace transform
} // namespace tint
#endif // SRC_TINT_TRANSFORM_EXTERNAL_TEXTURE_TRANSFORM_H_

View File

@@ -1,187 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/transform/test_helper.h"
namespace tint {
namespace transform {
namespace {
using ExternalTextureTransformTest = TransformTest;
TEST_F(ExternalTextureTransformTest, SampleLevelSinglePlane) {
auto* src = R"(
@group(0) @binding(0) var s : sampler;
@group(0) @binding(1) var t : texture_external;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureSampleLevel(t, s, (coord.xy / vec2<f32>(4.0, 4.0)));
}
)";
auto* expect = R"(
@group(0) @binding(0) var s : sampler;
@group(0) @binding(1) var t : texture_2d<f32>;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureSampleLevel(t, s, (coord.xy / vec2<f32>(4.0, 4.0)), 0.0);
}
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(ExternalTextureTransformTest, SampleLevelSinglePlane_OutOfOrder) {
auto* src = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureSampleLevel(t, s, (coord.xy / vec2<f32>(4.0, 4.0)));
}
@group(0) @binding(1) var t : texture_external;
@group(0) @binding(0) var s : sampler;
)";
auto* expect = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureSampleLevel(t, s, (coord.xy / vec2<f32>(4.0, 4.0)), 0.0);
}
@group(0) @binding(1) var t : texture_2d<f32>;
@group(0) @binding(0) var s : sampler;
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(ExternalTextureTransformTest, LoadSinglePlane) {
auto* src = R"(
@group(0) @binding(0) var t : texture_external;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureLoad(t, vec2<i32>(1, 1));
}
)";
auto* expect = R"(
@group(0) @binding(0) var t : texture_2d<f32>;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureLoad(t, vec2<i32>(1, 1), 0);
}
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(ExternalTextureTransformTest, LoadSinglePlane_OutOfOrder) {
auto* src = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureLoad(t, vec2<i32>(1, 1));
}
@group(0) @binding(0) var t : texture_external;
)";
auto* expect = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
return textureLoad(t, vec2<i32>(1, 1), 0);
}
@group(0) @binding(0) var t : texture_2d<f32>;
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(ExternalTextureTransformTest, DimensionsSinglePlane) {
auto* src = R"(
@group(0) @binding(0) var t : texture_external;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
var dim : vec2<i32>;
dim = textureDimensions(t);
return vec4<f32>(0.0, 0.0, 0.0, 0.0);
}
)";
auto* expect = R"(
@group(0) @binding(0) var t : texture_2d<f32>;
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
var dim : vec2<i32>;
dim = textureDimensions(t);
return vec4<f32>(0.0, 0.0, 0.0, 0.0);
}
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(ExternalTextureTransformTest, DimensionsSinglePlane_OutOfOrder) {
auto* src = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
var dim : vec2<i32>;
dim = textureDimensions(t);
return vec4<f32>(0.0, 0.0, 0.0, 0.0);
}
@group(0) @binding(0) var t : texture_external;
)";
auto* expect = R"(
@stage(fragment)
fn main(@builtin(position) coord : vec4<f32>) -> @location(0) vec4<f32> {
var dim : vec2<i32>;
dim = textureDimensions(t);
return vec4<f32>(0.0, 0.0, 0.0, 0.0);
}
@group(0) @binding(0) var t : texture_2d<f32>;
)";
auto got = Run<ExternalTextureTransform>(src);
EXPECT_EQ(expect, str(got));
}
} // namespace
} // namespace transform
} // namespace tint

View File

@@ -24,7 +24,6 @@
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/combine_samplers.h"
#include "src/tint/transform/decompose_memory_access.h"
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/loop_to_for_loop.h"
#include "src/tint/transform/manager.h"
@@ -102,7 +101,6 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) const {
BindingRemapper::AccessControls ac;
data.Add<BindingRemapper::Remappings>(bp, ac, /* mayCollide */ true);
}
manager.Add<ExternalTextureTransform>();
manager.Add<PromoteInitializersToConstVar>();
manager.Add<PadArrayElements>();

View File

@@ -2552,6 +2552,12 @@ bool GeneratorImpl::EmitType(std::ostream& out,
} else if (auto* str = type->As<sem::Struct>()) {
out << StructName(str);
} else if (auto* tex = type->As<sem::Texture>()) {
if (tex->Is<sem::ExternalTexture>()) {
TINT_ICE(Writer, diagnostics_)
<< "Multiplanar external texture transform was not run.";
return false;
}
auto* storage = tex->As<sem::StorageTexture>();
auto* ms = tex->As<sem::MultisampledTexture>();
auto* depth_ms = tex->As<sem::DepthMultisampledTexture>();

View File

@@ -52,7 +52,6 @@
#include "src/tint/transform/calculate_array_length.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/decompose_memory_access.h"
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/localize_struct_array_assignment.h"
#include "src/tint/transform/loop_to_for_loop.h"
@@ -206,7 +205,6 @@ SanitizedResult Sanitize(
// DecomposeMemoryAccess special-cases the arrayLength() intrinsic, which
// will be transformed by CalculateArrayLength
manager.Add<transform::CalculateArrayLength>();
manager.Add<transform::ExternalTextureTransform>();
manager.Add<transform::PromoteInitializersToConstVar>();
manager.Add<transform::PadArrayElements>();
@@ -3645,6 +3643,12 @@ bool GeneratorImpl::EmitType(std::ostream& out,
return true;
},
[&](const sem::Texture* tex) {
if (tex->Is<sem::ExternalTexture>()) {
TINT_ICE(Writer, diagnostics_)
<< "Multiplanar external texture transform was not run.";
return false;
}
auto* storage = tex->As<sem::StorageTexture>();
auto* ms = tex->As<sem::MultisampledTexture>();
auto* depth_ms = tex->As<sem::DepthMultisampledTexture>();

View File

@@ -61,7 +61,6 @@
#include "src/tint/transform/array_length_from_uniform.h"
#include "src/tint/transform/builtin_polyfill.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/transform/manager.h"
#include "src/tint/transform/module_scope_var_to_entry_point_param.h"
#include "src/tint/transform/pad_array_elements.h"
@@ -174,7 +173,6 @@ SanitizedResult Sanitize(
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::ExternalTextureTransform>();
manager.Add<transform::PromoteInitializersToConstVar>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();
@@ -2366,6 +2364,12 @@ bool GeneratorImpl::EmitType(std::ostream& out,
return true;
},
[&](const sem::Texture* tex) {
if (tex->Is<sem::ExternalTexture>()) {
TINT_ICE(Writer, diagnostics_)
<< "Multiplanar external texture transform was not run.";
return false;
}
if (tex->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) {
out << "depth";
} else {

View File

@@ -45,7 +45,6 @@
#include "src/tint/transform/add_spirv_block_attribute.h"
#include "src/tint/transform/builtin_polyfill.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/external_texture_transform.h"
#include "src/tint/transform/fold_constants.h"
#include "src/tint/transform/for_loop_to_loop.h"
#include "src/tint/transform/manager.h"
@@ -279,7 +278,6 @@ SanitizedResult Sanitize(const Program* in,
manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
manager.Add<transform::FoldConstants>();
manager.Add<transform::ExternalTextureTransform>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();
manager.Add<transform::ForLoopToLoop>(); // Must come after
// ZeroInitWorkgroupMemory
@@ -4033,6 +4031,12 @@ uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) {
bool Builder::GenerateTextureType(const sem::Texture* texture,
const Operand& result) {
if (texture->Is<sem::ExternalTexture>()) {
TINT_ICE(Writer, builder_.Diagnostics())
<< "Multiplanar external texture transform was not run.";
return false;
}
uint32_t array_literal = 0u;
const auto dim = texture->dim();
if (dim == ast::TextureDimension::k2dArray ||