mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 17:05:31 +00:00
GLSL: implement CombineSamplers transform (string version).
This transform converts all separate texture/sampler references in a program into combined texture/samplers. This is required for GLSL, which does not support separate texture/samplers. As input, the transform requires a map from the unique sampler/texture pairs previously gathered by the Resolver to strings, which will be used as the names of the newly-generated combined samplers. Note that binding points are unused by GLSL, and so are set to (0, 0) with collision detection disabled. All function signatures containing textures or samplers are rewritten, as well as function calls and texture intrinsic calls. For texture intrinsic calls, a placeholder sampler is used to satisfy the subsequent Resolver pass (GLSL texture intrinsics do not require a separate sampler, but WGSL intrinsics do). The placeholder is also used if the shader contains only texture references (e.g., textureLoad). Bug: tint:1366 Change-Id: Iff8407d28fdc2a8adac5cb655707a08c8553c389 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/77080 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
committed by
Tint LUCI CQ
parent
7e6989bc26
commit
f9b8b6104d
@@ -437,6 +437,8 @@ libtint_source_set("libtint_core_all_src") {
|
||||
"transform/calculate_array_length.h",
|
||||
"transform/canonicalize_entry_point_io.cc",
|
||||
"transform/canonicalize_entry_point_io.h",
|
||||
"transform/combine_samplers.cc",
|
||||
"transform/combine_samplers.h",
|
||||
"transform/decompose_memory_access.cc",
|
||||
"transform/decompose_memory_access.h",
|
||||
"transform/decompose_strided_matrix.cc",
|
||||
|
||||
@@ -303,6 +303,8 @@ set(TINT_LIB_SRCS
|
||||
transform/binding_remapper.h
|
||||
transform/calculate_array_length.cc
|
||||
transform/calculate_array_length.h
|
||||
transform/combine_samplers.cc
|
||||
transform/combine_samplers.h
|
||||
transform/canonicalize_entry_point_io.cc
|
||||
transform/canonicalize_entry_point_io.h
|
||||
transform/decompose_memory_access.cc
|
||||
@@ -976,6 +978,7 @@ if(TINT_BUILD_TESTS)
|
||||
transform/binding_remapper_test.cc
|
||||
transform/calculate_array_length_test.cc
|
||||
transform/canonicalize_entry_point_io_test.cc
|
||||
transform/combine_samplers_test.cc
|
||||
transform/decompose_memory_access_test.cc
|
||||
transform/decompose_strided_matrix_test.cc
|
||||
transform/external_texture_transform_test.cc
|
||||
|
||||
312
src/transform/combine_samplers.cc
Normal file
312
src/transform/combine_samplers.cc
Normal file
@@ -0,0 +1,312 @@
|
||||
// Copyright 2022 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/transform/combine_samplers.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/sem/function.h"
|
||||
#include "src/sem/statement.h"
|
||||
|
||||
#include "src/utils/map.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::CombineSamplers);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::CombineSamplers::BindingInfo);
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsGlobal(const tint::sem::VariablePair& pair) {
|
||||
return pair.first->Is<tint::sem::GlobalVariable>() &&
|
||||
(!pair.second || pair.second->Is<tint::sem::GlobalVariable>());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace tint {
|
||||
namespace transform {
|
||||
|
||||
CombineSamplers::BindingInfo::BindingInfo(const BindingMap& map)
|
||||
: binding_map(map) {}
|
||||
CombineSamplers::BindingInfo::BindingInfo(const BindingInfo& other) = default;
|
||||
CombineSamplers::BindingInfo::~BindingInfo() = default;
|
||||
|
||||
/// The PIMPL state for the CombineSamplers transform
|
||||
struct CombineSamplers::State {
|
||||
/// The clone context
|
||||
CloneContext& ctx;
|
||||
|
||||
/// The binding info
|
||||
const BindingInfo* binding_info;
|
||||
|
||||
/// Map from a texture/sampler pair to the corresponding combined sampler
|
||||
/// variable
|
||||
using CombinedTextureSamplerMap =
|
||||
std::unordered_map<sem::VariablePair, const ast::Variable*>;
|
||||
|
||||
/// Use sem::BindingPoint without scope.
|
||||
using BindingPoint = sem::BindingPoint;
|
||||
|
||||
/// A map of all global texture/sampler variable pairs to the global
|
||||
/// combined sampler variable that will replace it.
|
||||
CombinedTextureSamplerMap global_combined_texture_samplers_;
|
||||
|
||||
/// A map of all texture/sampler variable pairs that contain a function
|
||||
/// parameter to the combined sampler function paramter that will replace it.
|
||||
std::unordered_map<const sem::Function*, CombinedTextureSamplerMap>
|
||||
function_combined_texture_samplers_;
|
||||
|
||||
/// Placeholder global samplers used when a function contains texture-only
|
||||
/// references (one comparison sampler, one regular). These are also used as
|
||||
/// temporary sampler parameters to the texture intrinsics to satsify the WGSL
|
||||
/// resolver, but are then ignored and removed by the GLSL writer.
|
||||
const ast::Variable* placeholder_samplers_[2] = {};
|
||||
|
||||
/// Group and binding decorations used by all combined sampler globals.
|
||||
/// Group 0 and binding 0 are used, with collisions disabled.
|
||||
/// @returns the newly-created decoration list
|
||||
ast::DecorationList Decorations() const {
|
||||
auto decorations = ctx.dst->GroupAndBinding(0, 0);
|
||||
decorations.push_back(
|
||||
ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision));
|
||||
return decorations;
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
/// @param context the clone context
|
||||
/// @param info the binding map information
|
||||
State(CloneContext& context, const BindingInfo* info)
|
||||
: ctx(context), binding_info(info) {}
|
||||
|
||||
/// Creates a combined sampler global variables.
|
||||
/// (Note this is actually a Texture node at the AST level, but it will be
|
||||
/// written as the corresponding sampler (eg., sampler2D) on GLSL output.)
|
||||
/// @param texture_var the texture (global) variable
|
||||
/// @param sampler_var the sampler (global) variable
|
||||
/// @param name the default name to use (may be overridden by map lookup)
|
||||
/// @returns the newly-created global variable
|
||||
const ast::Variable* CreateCombinedGlobal(const sem::Variable* texture_var,
|
||||
const sem::Variable* sampler_var,
|
||||
std::string name) {
|
||||
SamplerTexturePair bp_pair;
|
||||
bp_pair.texture_binding_point =
|
||||
texture_var->As<sem::GlobalVariable>()->BindingPoint();
|
||||
bp_pair.sampler_binding_point =
|
||||
sampler_var ? sampler_var->As<sem::GlobalVariable>()->BindingPoint()
|
||||
: BindingPoint();
|
||||
auto it = binding_info->binding_map.find(bp_pair);
|
||||
if (it != binding_info->binding_map.end()) {
|
||||
name = it->second;
|
||||
}
|
||||
const ast::Type* type = CreateASTTypeFor(ctx, texture_var->Type());
|
||||
Symbol symbol = ctx.dst->Symbols().New(name);
|
||||
return ctx.dst->Global(symbol, type, Decorations());
|
||||
}
|
||||
|
||||
/// Creates placeholder global sampler variables.
|
||||
/// @param kind the sampler kind to create for
|
||||
/// @returns the newly-created global variable
|
||||
const ast::Variable* CreatePlaceholder(ast::SamplerKind kind) {
|
||||
const ast::Type* type = ctx.dst->ty.sampler(kind);
|
||||
const char* name = kind == ast::SamplerKind::kComparisonSampler
|
||||
? "placeholder_comparison_sampler"
|
||||
: "placeholder_sampler";
|
||||
Symbol symbol = ctx.dst->Symbols().New(name);
|
||||
return ctx.dst->Global(symbol, type, Decorations());
|
||||
}
|
||||
|
||||
/// Performs the transformation
|
||||
void Run() {
|
||||
auto& sem = ctx.src->Sem();
|
||||
|
||||
// Remove all texture and sampler global variables. These will be replaced
|
||||
// by combined samplers.
|
||||
for (auto* var : ctx.src->AST().GlobalVariables()) {
|
||||
if (sem.Get(var->type)->IsAnyOf<sem::Texture, sem::Sampler>()) {
|
||||
ctx.Remove(ctx.src->AST().GlobalDeclarations(), var);
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite all function signatures to use combined samplers, and remove
|
||||
// separate textures & samplers. Create new combined globals where found.
|
||||
ctx.ReplaceAll([&](const ast::Function* src) -> const ast::Function* {
|
||||
if (auto* func = sem.Get(src)) {
|
||||
auto pairs = func->TextureSamplerPairs();
|
||||
if (pairs.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
ast::VariableList params;
|
||||
for (auto pair : func->TextureSamplerPairs()) {
|
||||
const sem::Variable* texture_var = pair.first;
|
||||
const sem::Variable* sampler_var = pair.second;
|
||||
std::string name =
|
||||
ctx.src->Symbols().NameFor(texture_var->Declaration()->symbol);
|
||||
if (sampler_var) {
|
||||
name += "_" + ctx.src->Symbols().NameFor(
|
||||
sampler_var->Declaration()->symbol);
|
||||
}
|
||||
if (IsGlobal(pair)) {
|
||||
// Both texture and sampler are global; add a new global variable
|
||||
// to represent the combined sampler (if not already created).
|
||||
utils::GetOrCreate(global_combined_texture_samplers_, pair, [&] {
|
||||
return CreateCombinedGlobal(texture_var, sampler_var, name);
|
||||
});
|
||||
} else {
|
||||
// Either texture or sampler (or both) is a function parameter;
|
||||
// add a new function parameter to represent the combined sampler.
|
||||
const ast::Type* type = CreateASTTypeFor(ctx, texture_var->Type());
|
||||
const ast::Variable* var =
|
||||
ctx.dst->Param(ctx.dst->Symbols().New(name), type);
|
||||
params.push_back(var);
|
||||
function_combined_texture_samplers_[func][pair] = var;
|
||||
}
|
||||
}
|
||||
// Filter out separate textures and samplers from the original
|
||||
// function signature.
|
||||
for (auto* var : src->params) {
|
||||
if (!sem.Get(var->type)->IsAnyOf<sem::Texture, sem::Sampler>()) {
|
||||
params.push_back(ctx.Clone(var));
|
||||
}
|
||||
}
|
||||
// Create a new function signature that differs only in the parameter
|
||||
// list.
|
||||
auto symbol = ctx.Clone(src->symbol);
|
||||
auto* return_type = ctx.Clone(src->return_type);
|
||||
auto* body = ctx.Clone(src->body);
|
||||
auto decorations = ctx.Clone(src->decorations);
|
||||
auto return_type_decorations = ctx.Clone(src->return_type_decorations);
|
||||
return ctx.dst->create<ast::Function>(
|
||||
symbol, params, return_type, body, std::move(decorations),
|
||||
std::move(return_type_decorations));
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
// Replace all function call expressions containing texture or
|
||||
// sampler parameters to use the current function's combined samplers or
|
||||
// the combined global samplers, as appropriate.
|
||||
ctx.ReplaceAll([&](const ast::CallExpression* expr)
|
||||
-> const ast::Expression* {
|
||||
if (auto* call = sem.Get(expr)) {
|
||||
ast::ExpressionList args;
|
||||
// Replace all texture intrinsic calls.
|
||||
if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
|
||||
const auto& signature = intrinsic->Signature();
|
||||
int sampler_index = signature.IndexOf(sem::ParameterUsage::kSampler);
|
||||
int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
|
||||
if (texture_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
const sem::Expression* texture = call->Arguments()[texture_index];
|
||||
const sem::Expression* sampler =
|
||||
sampler_index != -1 ? call->Arguments()[sampler_index] : nullptr;
|
||||
auto* texture_var = texture->As<sem::VariableUser>()->Variable();
|
||||
auto* sampler_var =
|
||||
sampler ? sampler->As<sem::VariableUser>()->Variable() : nullptr;
|
||||
sem::VariablePair new_pair(texture_var, sampler_var);
|
||||
for (auto* arg : expr->args) {
|
||||
auto* type = ctx.src->TypeOf(arg)->UnwrapRef();
|
||||
if (type->Is<sem::Texture>()) {
|
||||
const ast::Variable* var =
|
||||
IsGlobal(new_pair)
|
||||
? global_combined_texture_samplers_[new_pair]
|
||||
: function_combined_texture_samplers_
|
||||
[call->Stmt()->Function()][new_pair];
|
||||
args.push_back(ctx.dst->Expr(var->symbol));
|
||||
} else if (auto* sampler_type = type->As<sem::Sampler>()) {
|
||||
ast::SamplerKind kind = sampler_type->kind();
|
||||
int index = (kind == ast::SamplerKind::kSampler) ? 0 : 1;
|
||||
const ast::Variable*& p = placeholder_samplers_[index];
|
||||
if (!p) {
|
||||
p = CreatePlaceholder(kind);
|
||||
}
|
||||
args.push_back(ctx.dst->Expr(p->symbol));
|
||||
} else {
|
||||
args.push_back(ctx.Clone(arg));
|
||||
}
|
||||
}
|
||||
return ctx.dst->Call(ctx.Clone(expr->target.name), args);
|
||||
}
|
||||
// Replace all function calls.
|
||||
if (auto* callee = call->Target()->As<sem::Function>()) {
|
||||
for (auto pair : callee->TextureSamplerPairs()) {
|
||||
// Global pairs used by the callee do not require a function
|
||||
// parameter at the call site.
|
||||
if (IsGlobal(pair)) {
|
||||
continue;
|
||||
}
|
||||
const sem::Variable* texture_var = pair.first;
|
||||
const sem::Variable* sampler_var = pair.second;
|
||||
if (auto* param = texture_var->As<sem::Parameter>()) {
|
||||
const sem::Expression* texture =
|
||||
call->Arguments()[param->Index()];
|
||||
texture_var = texture->As<sem::VariableUser>()->Variable();
|
||||
}
|
||||
if (sampler_var) {
|
||||
if (auto* param = sampler_var->As<sem::Parameter>()) {
|
||||
const sem::Expression* sampler =
|
||||
call->Arguments()[param->Index()];
|
||||
sampler_var = sampler->As<sem::VariableUser>()->Variable();
|
||||
}
|
||||
}
|
||||
sem::VariablePair new_pair(texture_var, sampler_var);
|
||||
// If both texture and sampler are (now) global, pass that
|
||||
// global variable to the callee. Otherwise use the caller's
|
||||
// function parameter for this pair.
|
||||
const ast::Variable* var =
|
||||
IsGlobal(new_pair) ? global_combined_texture_samplers_[new_pair]
|
||||
: function_combined_texture_samplers_
|
||||
[call->Stmt()->Function()][new_pair];
|
||||
auto* arg = ctx.dst->Expr(var->symbol);
|
||||
args.push_back(arg);
|
||||
}
|
||||
// Append all of the remaining non-texture and non-sampler
|
||||
// parameters.
|
||||
for (auto* arg : expr->args) {
|
||||
if (!ctx.src->TypeOf(arg)
|
||||
->UnwrapRef()
|
||||
->IsAnyOf<sem::Texture, sem::Sampler>()) {
|
||||
args.push_back(ctx.Clone(arg));
|
||||
}
|
||||
}
|
||||
return ctx.dst->Call(ctx.Clone(expr->target.name), args);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
ctx.Clone();
|
||||
}
|
||||
};
|
||||
|
||||
CombineSamplers::CombineSamplers() = default;
|
||||
|
||||
CombineSamplers::~CombineSamplers() = default;
|
||||
|
||||
void CombineSamplers::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) {
|
||||
auto* binding_info = inputs.Get<BindingInfo>();
|
||||
if (!binding_info) {
|
||||
ctx.dst->Diagnostics().add_error(
|
||||
diag::System::Transform,
|
||||
"missing transform data for " + std::string(TypeInfo().name));
|
||||
return;
|
||||
}
|
||||
|
||||
State(ctx, binding_info).Run();
|
||||
}
|
||||
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
104
src/transform/combine_samplers.h
Normal file
104
src/transform/combine_samplers.h
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2022 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_TRANSFORM_COMBINE_SAMPLERS_H_
|
||||
#define SRC_TRANSFORM_COMBINE_SAMPLERS_H_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/sem/sampler_texture_pair.h"
|
||||
#include "src/transform/transform.h"
|
||||
|
||||
namespace tint {
|
||||
namespace transform {
|
||||
|
||||
/// This transform converts all separate texture/sampler refences in a
|
||||
/// program into combined texture/samplers. This is required for GLSL,
|
||||
/// which does not support separate texture/samplers.
|
||||
///
|
||||
/// It utilizes the texture/sampler information collected by the
|
||||
/// Resolver and stored on each sem::Function. For each function, all
|
||||
/// separate texture/sampler parameters in the function signature are
|
||||
/// removed. For each unique pair, if both texture and sampler are
|
||||
/// global variables, the function passes the corresponding combined
|
||||
/// global stored in global_combined_texture_samplers_ at the call
|
||||
/// site. Otherwise, either the texture or sampler must be a function
|
||||
/// parameter. In this case, a new parameter is added to the function
|
||||
/// signature. All separate texture/sampler parameters are removed.
|
||||
///
|
||||
/// All texture intrinsic callsites are modified to pass the combined
|
||||
/// texture/sampler as the first argument, and separate texture/sampler
|
||||
/// arugments are removed.
|
||||
///
|
||||
/// Note that the sampler may be null, indicating that only a texture
|
||||
/// reference was required (e.g., textureLoad). In this case, a
|
||||
/// placeholder global sampler is used at the AST level. This will be
|
||||
/// combined with the original texture to give a combined global, and
|
||||
/// the placeholder removed (ignored) by the GLSL writer.
|
||||
///
|
||||
/// Note that the combined samplers are actually represented by a
|
||||
/// Texture node at the AST level, since this contains all the
|
||||
/// information needed to represent a combined sampler in GLSL
|
||||
/// (dimensionality, component type, etc). The GLSL writer outputs such
|
||||
/// (Tint) Textures as (GLSL) Samplers.
|
||||
class CombineSamplers : public Castable<CombineSamplers, Transform> {
|
||||
public:
|
||||
/// A pair of binding points.
|
||||
using SamplerTexturePair = sem::SamplerTexturePair;
|
||||
|
||||
/// A map from a sampler/texture pair to a named global.
|
||||
using BindingMap = std::unordered_map<SamplerTexturePair, std::string>;
|
||||
|
||||
/// The client-provided mapping from separate texture and sampler binding
|
||||
/// points to combined sampler binding point.
|
||||
struct BindingInfo : public Castable<Data, transform::Data> {
|
||||
/// Constructor
|
||||
/// @param map the map of all (texture, sampler) -> (combined) pairs
|
||||
explicit BindingInfo(const BindingMap& map);
|
||||
|
||||
/// Copy constructor
|
||||
/// @param other the other BindingInfo to copy
|
||||
BindingInfo(const BindingInfo& other);
|
||||
|
||||
/// Destructor
|
||||
~BindingInfo() override;
|
||||
|
||||
/// A map of bindings from (texture, sampler) -> combined sampler.
|
||||
BindingMap binding_map;
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
CombineSamplers();
|
||||
|
||||
/// Destructor
|
||||
~CombineSamplers() override;
|
||||
|
||||
protected:
|
||||
/// The PIMPL state for this transform
|
||||
struct State;
|
||||
|
||||
/// 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) override;
|
||||
};
|
||||
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TRANSFORM_COMBINE_SAMPLERS_H_
|
||||
656
src/transform/combine_samplers_test.cc
Normal file
656
src/transform/combine_samplers_test.cc
Normal file
@@ -0,0 +1,656 @@
|
||||
// Copyright 2022 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/transform/combine_samplers.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "src/transform/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
namespace transform {
|
||||
namespace {
|
||||
|
||||
using CombineSamplersTest = TransformTest;
|
||||
|
||||
TEST_F(CombineSamplersTest, EmptyModule) {
|
||||
auto* src = "";
|
||||
auto* expect = "";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, SimplePair) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var t : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var s : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var t_s : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, SimplePairInAFunction) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var t : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var s : sampler;
|
||||
|
||||
fn sample(t : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t, s, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return sample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn sample(t_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, coords);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var t_s_1 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return sample(t_s_1, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, SimplePairRename) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(1) var t : texture_2d<f32>;
|
||||
|
||||
@group(2) @binding(3) var s : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var fuzzy : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(fuzzy, placeholder_sampler, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
CombineSamplers::BindingMap map;
|
||||
sem::SamplerTexturePair pair;
|
||||
pair.texture_binding_point.group = 0;
|
||||
pair.texture_binding_point.binding = 1;
|
||||
pair.sampler_binding_point.group = 2;
|
||||
pair.sampler_binding_point.binding = 3;
|
||||
map[pair] = "fuzzy";
|
||||
data.Add<CombineSamplers::BindingInfo>(map);
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, SimplePairRenameMiss) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(1) var t : texture_2d<f32>;
|
||||
|
||||
@group(2) @binding(3) var s : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var t_s : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
CombineSamplers::BindingMap map;
|
||||
sem::SamplerTexturePair pair;
|
||||
pair.texture_binding_point.group = 3;
|
||||
pair.texture_binding_point.binding = 2;
|
||||
pair.sampler_binding_point.group = 1;
|
||||
pair.sampler_binding_point.binding = 0;
|
||||
map[pair] = "fuzzy";
|
||||
data.Add<CombineSamplers::BindingInfo>(map);
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, AliasedTypes) {
|
||||
auto* src = R"(
|
||||
|
||||
type Tex2d = texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) var t : Tex2d;
|
||||
|
||||
@group(0) @binding(1) var s : sampler;
|
||||
|
||||
fn sample(t : Tex2d, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t, s, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return sample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
type Tex2d = texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn sample(t_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, coords);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var t_s_1 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return sample(t_s_1, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, SimplePairInTwoFunctions) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var t : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var s : sampler;
|
||||
|
||||
fn g(t : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t, s, coords);
|
||||
}
|
||||
|
||||
fn f(t : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return g(t, s, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn g(t_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, coords);
|
||||
}
|
||||
|
||||
fn f(t_s_1 : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return g(t_s_1, coords);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var t_s_2 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(t_s_2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TwoFunctionsGenerateSamePair) {
|
||||
auto* src = R"(
|
||||
@group(1) @binding(0) var tex : texture_2d<f32>;
|
||||
|
||||
@group(1) @binding(1) var samp : sampler;
|
||||
|
||||
fn f() -> vec4<f32> {
|
||||
return textureSample(tex, samp, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
|
||||
fn g() -> vec4<f32> {
|
||||
return textureSample(tex, samp, vec2<f32>(3.0, 4.0));
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f() + g();
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn f() -> vec4<f32> {
|
||||
return textureSample(tex_samp, placeholder_sampler, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
|
||||
fn g() -> vec4<f32> {
|
||||
return textureSample(tex_samp, placeholder_sampler, vec2<f32>(3.0, 4.0));
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return (f() + g());
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, ThreeTexturesThreeSamplers) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex1 : texture_2d<f32>;
|
||||
@group(0) @binding(1) var tex2 : texture_2d<f32>;
|
||||
@group(0) @binding(2) var tex3 : texture_2d<f32>;
|
||||
|
||||
@group(1) @binding(0) var samp1 : sampler;
|
||||
@group(1) @binding(1) var samp2: sampler;
|
||||
@group(1) @binding(2) var samp3: sampler;
|
||||
|
||||
fn sample(t : texture_2d<f32>, s : sampler) -> vec4<f32> {
|
||||
return textureSample(t, s, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return sample(tex1, samp1)
|
||||
+ sample(tex1, samp2)
|
||||
+ sample(tex1, samp3)
|
||||
+ sample(tex2, samp1)
|
||||
+ sample(tex2, samp2)
|
||||
+ sample(tex2, samp3)
|
||||
+ sample(tex3, samp1)
|
||||
+ sample(tex3, samp2)
|
||||
+ sample(tex3, samp3);
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn sample(t_s : texture_2d<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex1_samp1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex1_samp2 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex1_samp3 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex2_samp1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex2_samp2 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex2_samp3 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex3_samp1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex3_samp2 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex3_samp3 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return ((((((((sample(tex1_samp1) + sample(tex1_samp2)) + sample(tex1_samp3)) + sample(tex2_samp1)) + sample(tex2_samp2)) + sample(tex2_samp3)) + sample(tex3_samp1)) + sample(tex3_samp2)) + sample(tex3_samp3));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TwoFunctionsTwoTexturesDiamond) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var tex2 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(2) var samp : sampler;
|
||||
|
||||
fn sample(t : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t, s, coords);
|
||||
}
|
||||
|
||||
fn f(t1 : texture_2d<f32>, t2 : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return sample(t1, s, coords) + sample(t2, s, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex1, tex2, samp, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn sample(t_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, coords);
|
||||
}
|
||||
|
||||
fn f(t1_s : texture_2d<f32>, t2_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return (sample(t1_s, coords) + sample(t2_s, coords));
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex1_samp : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex2_samp : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex1_samp, tex2_samp, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TwoFunctionsTwoSamplersDiamond) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var samp1 : sampler;
|
||||
|
||||
@group(0) @binding(2) var samp2 : sampler;
|
||||
|
||||
fn sample(t : texture_2d<f32>, s : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t, s, coords);
|
||||
}
|
||||
|
||||
fn f(t : texture_2d<f32>, s1 : sampler, s2 : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return sample(t, s1, coords) + sample(t, s2, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex, samp1, samp2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn sample(t_s : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t_s, placeholder_sampler, coords);
|
||||
}
|
||||
|
||||
fn f(t_s1 : texture_2d<f32>, t_s2 : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return (sample(t_s1, coords) + sample(t_s2, coords));
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp2 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex_samp1, tex_samp2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, GlobalTextureLocalSampler) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var samp1 : sampler;
|
||||
|
||||
@group(0) @binding(2) var samp2 : sampler;
|
||||
|
||||
fn f(s1 : sampler, s2 : sampler, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(tex, s1, coords) + textureSample(tex, s2, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(samp1, samp2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn f(tex_s1 : texture_2d<f32>, tex_s2 : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return (textureSample(tex_s1, placeholder_sampler, coords) + textureSample(tex_s2, placeholder_sampler, coords));
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp2 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex_samp1, tex_samp2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, LocalTextureGlobalSampler) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex1 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var tex2 : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(2) var samp : sampler;
|
||||
|
||||
fn f(t1 : texture_2d<f32>, t2 : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return textureSample(t1, samp, coords) + textureSample(t2, samp, coords);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex1, tex2, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn f(t1_samp : texture_2d<f32>, t2_samp : texture_2d<f32>, coords : vec2<f32>) -> vec4<f32> {
|
||||
return (textureSample(t1_samp, placeholder_sampler, coords) + textureSample(t2_samp, placeholder_sampler, coords));
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex1_samp : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex2_samp : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex1_samp, tex2_samp, vec2<f32>(1.0, 2.0));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TextureLoadNoSampler) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex : texture_2d<f32>;
|
||||
|
||||
fn f(t : texture_2d<f32>, coords : vec2<i32>) -> vec4<f32> {
|
||||
return textureLoad(t, coords, 0);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex, vec2<i32>(1, 2));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
fn f(t_1 : texture_2d<f32>, coords : vec2<i32>) -> vec4<f32> {
|
||||
return textureLoad(t_1, coords, 0);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_1 : texture_2d<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return f(tex_1, vec2<i32>(1, 2));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TextureSampleCompare) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex : texture_depth_2d;
|
||||
|
||||
@group(0) @binding(1) var samp : sampler_comparison;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return vec4<f32>(textureSampleCompare(tex, samp, vec2<f32>(1.0, 2.0), 0.5));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp : texture_depth_2d;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_comparison_sampler : sampler_comparison;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return vec4<f32>(textureSampleCompare(tex_samp, placeholder_comparison_sampler, vec2<f32>(1.0, 2.0), 0.5));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, TextureSampleCompareInAFunction) {
|
||||
auto* src = R"(
|
||||
@group(0) @binding(0) var tex : texture_depth_2d;
|
||||
|
||||
@group(0) @binding(1) var samp : sampler_comparison;
|
||||
|
||||
fn f(t : texture_depth_2d, s : sampler_comparison, coords : vec2<f32>) -> f32 {
|
||||
return textureSampleCompare(t, s, coords, 5.0f);
|
||||
}
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return vec4<f32>(f(tex, samp, vec2<f32>(1.0, 2.0)));
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_comparison_sampler : sampler_comparison;
|
||||
|
||||
fn f(t_s : texture_depth_2d, coords : vec2<f32>) -> f32 {
|
||||
return textureSampleCompare(t_s, placeholder_comparison_sampler, coords, 5.0);
|
||||
}
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp : texture_depth_2d;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return vec4<f32>(f(tex_samp, vec2<f32>(1.0, 2.0)));
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CombineSamplersTest, BindingPointCollision) {
|
||||
auto* src = R"(
|
||||
@group(1) @binding(0) var tex : texture_2d<f32>;
|
||||
|
||||
@group(1) @binding(1) var samp : sampler;
|
||||
|
||||
@group(0) @binding(0) var<uniform> gcoords : vec2<f32>;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(tex, samp, gcoords);
|
||||
}
|
||||
)";
|
||||
auto* expect = R"(
|
||||
@group(0) @binding(0) var<uniform> gcoords : vec2<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_sampler : sampler;
|
||||
|
||||
fn main() -> vec4<f32> {
|
||||
return textureSample(tex_samp, placeholder_sampler, gcoords);
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
auto got = Run<CombineSamplers>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
@@ -19,8 +19,10 @@
|
||||
#include "src/program_builder.h"
|
||||
#include "src/transform/add_empty_entry_point.h"
|
||||
#include "src/transform/add_spirv_block_decoration.h"
|
||||
#include "src/transform/binding_remapper.h"
|
||||
#include "src/transform/calculate_array_length.h"
|
||||
#include "src/transform/canonicalize_entry_point_io.h"
|
||||
#include "src/transform/combine_samplers.h"
|
||||
#include "src/transform/decompose_memory_access.h"
|
||||
#include "src/transform/external_texture_transform.h"
|
||||
#include "src/transform/fold_trivial_single_use_lets.h"
|
||||
@@ -73,6 +75,20 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) {
|
||||
data.Add<SingleEntryPoint::Config>(cfg->entry_point);
|
||||
}
|
||||
manager.Add<RemovePhonies>();
|
||||
manager.Add<CombineSamplers>();
|
||||
if (auto* binding_info = inputs.Get<CombineSamplers::BindingInfo>()) {
|
||||
data.Add<CombineSamplers::BindingInfo>(*binding_info);
|
||||
} else {
|
||||
data.Add<CombineSamplers::BindingInfo>(CombineSamplers::BindingMap());
|
||||
}
|
||||
manager.Add<BindingRemapper>();
|
||||
if (auto* remappings = inputs.Get<BindingRemapper::Remappings>()) {
|
||||
data.Add<BindingRemapper::Remappings>(*remappings);
|
||||
} else {
|
||||
BindingRemapper::BindingPoints bp;
|
||||
BindingRemapper::AccessControls ac;
|
||||
data.Add<BindingRemapper::Remappings>(bp, ac, /* mayCollide */ true);
|
||||
}
|
||||
manager.Add<CalculateArrayLength>();
|
||||
manager.Add<ExternalTextureTransform>();
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "src/writer/glsl/generator.h"
|
||||
|
||||
#include "src/transform/binding_remapper.h"
|
||||
#include "src/transform/combine_samplers.h"
|
||||
#include "src/transform/glsl.h"
|
||||
#include "src/writer/glsl/generator_impl.h"
|
||||
|
||||
@@ -21,17 +23,25 @@ namespace tint {
|
||||
namespace writer {
|
||||
namespace glsl {
|
||||
|
||||
Options::Options() = default;
|
||||
Options::~Options() = default;
|
||||
Options::Options(const Options&) = default;
|
||||
|
||||
Result::Result() = default;
|
||||
Result::~Result() = default;
|
||||
Result::Result(const Result&) = default;
|
||||
|
||||
Result Generate(const Program* program,
|
||||
const Options&,
|
||||
const Options& options,
|
||||
const std::string& entry_point) {
|
||||
Result result;
|
||||
|
||||
// Run the GLSL sanitizer.
|
||||
transform::DataMap data;
|
||||
data.Add<transform::BindingRemapper::Remappings>(options.binding_points,
|
||||
options.access_controls,
|
||||
options.allow_collisions);
|
||||
data.Add<transform::CombineSamplers::BindingInfo>(options.binding_map);
|
||||
data.Add<transform::Glsl::Config>(entry_point);
|
||||
transform::Glsl sanitizer;
|
||||
auto output = sanitizer.Run(program, data);
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/access.h"
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
#include "src/sem/binding_point.h"
|
||||
#include "src/sem/sampler_texture_pair.h"
|
||||
#include "src/writer/text.h"
|
||||
|
||||
namespace tint {
|
||||
@@ -34,8 +38,35 @@ namespace glsl {
|
||||
// Forward declarations
|
||||
class GeneratorImpl;
|
||||
|
||||
using BindingMap = std::unordered_map<sem::SamplerTexturePair, std::string>;
|
||||
|
||||
/// Configuration options used for generating GLSL.
|
||||
struct Options {};
|
||||
struct Options {
|
||||
/// Constructor
|
||||
Options();
|
||||
|
||||
/// Destructor
|
||||
~Options();
|
||||
|
||||
/// Copy constructor
|
||||
Options(const Options&);
|
||||
|
||||
/// A map of SamplerTexturePair to combined sampler names for the
|
||||
/// CombineSamplers transform
|
||||
BindingMap binding_map;
|
||||
|
||||
/// A map of old binding point to new binding point for the BindingRemapper
|
||||
/// transform
|
||||
std::unordered_map<sem::BindingPoint, sem::BindingPoint> binding_points;
|
||||
|
||||
/// A map of old binding point to new access control for the BindingRemapper
|
||||
/// transform
|
||||
std::unordered_map<sem::BindingPoint, ast::Access> access_controls;
|
||||
|
||||
/// If true, then validation will be disabled for binding point collisions
|
||||
/// generated by the BindingRemapper transform
|
||||
bool allow_collisions = false;
|
||||
};
|
||||
|
||||
/// The result produced when generating GLSL.
|
||||
struct Result {
|
||||
|
||||
@@ -64,41 +64,41 @@ ExpectedResult expected_texture_overload(
|
||||
case ValidTextureOverload::kDimensionsStorageWO3d:
|
||||
return {"imageSize"};
|
||||
case ValidTextureOverload::kGather2dF32:
|
||||
return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f), 0))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f), 0))";
|
||||
case ValidTextureOverload::kGather2dOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4), 0))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4), 0))";
|
||||
case ValidTextureOverload::kGather2dArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3)), 0))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 0))";
|
||||
case ValidTextureOverload::kGather2dArrayOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5), 0))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5), 0))";
|
||||
case ValidTextureOverload::kGatherCubeF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 0))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 0))";
|
||||
case ValidTextureOverload::kGatherCubeArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 0))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 0))";
|
||||
case ValidTextureOverload::kGatherDepth2dF32:
|
||||
return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f)))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f)))";
|
||||
case ValidTextureOverload::kGatherDepth2dOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4)))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4)))";
|
||||
case ValidTextureOverload::kGatherDepth2dArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3))))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3))))";
|
||||
case ValidTextureOverload::kGatherDepth2dArrayOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)))";
|
||||
case ValidTextureOverload::kGatherDepthCubeF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f)))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f)))";
|
||||
case ValidTextureOverload::kGatherDepthCubeArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4))))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4))))";
|
||||
case ValidTextureOverload::kGatherCompareDepth2dF32:
|
||||
return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f), 3.0f))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f))";
|
||||
case ValidTextureOverload::kGatherCompareDepth2dOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5)))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5)))";
|
||||
case ValidTextureOverload::kGatherCompareDepth2dArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f))";
|
||||
case ValidTextureOverload::kGatherCompareDepth2dArrayOffsetF32:
|
||||
return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6)))";
|
||||
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6)))";
|
||||
case ValidTextureOverload::kGatherCompareDepthCubeF32:
|
||||
return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f))";
|
||||
case ValidTextureOverload::kGatherCompareDepthCubeArrayF32:
|
||||
return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f))";
|
||||
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f))";
|
||||
case ValidTextureOverload::kNumLayers2dArray:
|
||||
case ValidTextureOverload::kNumLayersDepth2dArray:
|
||||
case ValidTextureOverload::kNumLayersCubeArray:
|
||||
@@ -118,151 +118,151 @@ ExpectedResult expected_texture_overload(
|
||||
case ValidTextureOverload::kNumSamplesMultisampled2d:
|
||||
return {"textureSamples"};
|
||||
case ValidTextureOverload::kSample1dF32:
|
||||
return R"(texture(tint_symbol, 1.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, 1.0f);)";
|
||||
case ValidTextureOverload::kSample2dF32:
|
||||
return R"(texture(tint_symbol, vec2(1.0f, 2.0f));)";
|
||||
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f));)";
|
||||
case ValidTextureOverload::kSample2dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4));)";
|
||||
case ValidTextureOverload::kSample2dArrayF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)));)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)));)";
|
||||
case ValidTextureOverload::kSample2dArrayOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5));)";
|
||||
case ValidTextureOverload::kSample3dF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f));)";
|
||||
case ValidTextureOverload::kSample3dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, 3.0f), ivec3(4, 5, 6));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), ivec3(4, 5, 6));)";
|
||||
case ValidTextureOverload::kSampleCubeF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f));)";
|
||||
case ValidTextureOverload::kSampleCubeArrayF32:
|
||||
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
|
||||
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
|
||||
case ValidTextureOverload::kSampleDepth2dF32:
|
||||
return R"(texture(tint_symbol, vec2(1.0f, 2.0f)).x;)";
|
||||
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f)).x;)";
|
||||
case ValidTextureOverload::kSampleDepth2dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
|
||||
case ValidTextureOverload::kSampleDepth2dArrayF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3))).x;)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3))).x;)";
|
||||
case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
|
||||
case ValidTextureOverload::kSampleDepthCubeF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f)).x;)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f)).x;)";
|
||||
case ValidTextureOverload::kSampleDepthCubeArrayF32:
|
||||
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
|
||||
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
|
||||
case ValidTextureOverload::kSampleBias2dF32:
|
||||
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleBias2dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(4, 5), 3.0f);)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(4, 5), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleBias2dArrayF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(5, 6), 4.0f);)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(5, 6), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleBias3dF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleBias3dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, 3.0f), ivec3(5, 6, 7), 4.0f);)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), ivec3(5, 6, 7), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleBiasCubeF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleBiasCubeArrayF32:
|
||||
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(3)), 4.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(3)), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleLevel2dF32:
|
||||
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleLevel2dOffsetF32:
|
||||
return R"(textureLodOffset(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
return R"(textureLodOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
case ValidTextureOverload::kSampleLevel2dArrayF32:
|
||||
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f);)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
|
||||
return R"(textureLodOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
|
||||
return R"(textureLodOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
|
||||
case ValidTextureOverload::kSampleLevel3dF32:
|
||||
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleLevel3dOffsetF32:
|
||||
return R"(textureLodOffset(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
|
||||
return R"(textureLodOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
|
||||
case ValidTextureOverload::kSampleLevelCubeF32:
|
||||
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleLevelCubeArrayF32:
|
||||
return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
case ValidTextureOverload::kSampleLevelDepth2dF32:
|
||||
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3).x;)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec2(1.0f, 2.0f), 3).x;)";
|
||||
case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
|
||||
return R"(textureLodOffset(tint_symbol, vec2(1.0f, 2.0f), 3, ivec2(4, 5)).x;)";
|
||||
return R"(textureLodOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3, ivec2(4, 5)).x;)";
|
||||
case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
|
||||
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4).x;)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4).x;)";
|
||||
case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
|
||||
return R"(textureLodOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4, ivec2(5, 6)).x;)";
|
||||
return R"(textureLodOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4, ivec2(5, 6)).x;)";
|
||||
case ValidTextureOverload::kSampleLevelDepthCubeF32:
|
||||
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4).x;)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4).x;)";
|
||||
case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
|
||||
return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5).x;)";
|
||||
return R"(textureLod(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5).x;)";
|
||||
case ValidTextureOverload::kSampleGrad2dF32:
|
||||
return R"(textureGrad(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)";
|
||||
return R"(textureGrad(tint_symbol_sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)";
|
||||
case ValidTextureOverload::kSampleGrad2dOffsetF32:
|
||||
return R"(textureGradOffset(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)";
|
||||
return R"(textureGradOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)";
|
||||
case ValidTextureOverload::kSampleGrad2dArrayF32:
|
||||
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)";
|
||||
return R"(textureGrad(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)";
|
||||
case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
|
||||
return R"(textureGradOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f), ivec2(6, 7));)";
|
||||
return R"(textureGradOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f), ivec2(6, 7));)";
|
||||
case ValidTextureOverload::kSampleGrad3dF32:
|
||||
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
|
||||
return R"(textureGrad(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
|
||||
case ValidTextureOverload::kSampleGrad3dOffsetF32:
|
||||
return R"(textureGradOffset(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f), ivec3(0, 1, 2));)";
|
||||
return R"(textureGradOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f), ivec3(0, 1, 2));)";
|
||||
case ValidTextureOverload::kSampleGradCubeF32:
|
||||
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
|
||||
return R"(textureGrad(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
|
||||
case ValidTextureOverload::kSampleGradCubeArrayF32:
|
||||
return R"(textureGrad(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
|
||||
return R"(textureGrad(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
|
||||
case ValidTextureOverload::kSampleCompareDepth2dF32:
|
||||
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
|
||||
case ValidTextureOverload::kSampleCompareDepthCubeF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
|
||||
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepth2dF32:
|
||||
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepth2dOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayOffsetF32:
|
||||
return R"(textureOffset(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
|
||||
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepthCubeF32:
|
||||
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
|
||||
case ValidTextureOverload::kSampleCompareLevelDepthCubeArrayF32:
|
||||
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
|
||||
case ValidTextureOverload::kLoad1dLevelF32:
|
||||
case ValidTextureOverload::kLoad1dLevelU32:
|
||||
case ValidTextureOverload::kLoad1dLevelI32:
|
||||
return R"(texelFetch(tint_symbol, 1, 3);)";
|
||||
return R"(texelFetch(tint_symbol_2, 1, 3);)";
|
||||
case ValidTextureOverload::kLoad2dLevelF32:
|
||||
case ValidTextureOverload::kLoad2dLevelU32:
|
||||
case ValidTextureOverload::kLoad2dLevelI32:
|
||||
return R"(texelFetch(tint_symbol, ivec2(1, 2), 3);)";
|
||||
return R"(texelFetch(tint_symbol_2, ivec2(1, 2), 3);)";
|
||||
case ValidTextureOverload::kLoad2dArrayLevelF32:
|
||||
case ValidTextureOverload::kLoad2dArrayLevelU32:
|
||||
case ValidTextureOverload::kLoad2dArrayLevelI32:
|
||||
case ValidTextureOverload::kLoad3dLevelF32:
|
||||
case ValidTextureOverload::kLoad3dLevelU32:
|
||||
case ValidTextureOverload::kLoad3dLevelI32:
|
||||
return R"(texelFetch(tint_symbol, ivec3(1, 2, 3), 4);)";
|
||||
return R"(texelFetch(tint_symbol_2, ivec3(1, 2, 3), 4);)";
|
||||
case ValidTextureOverload::kLoadDepthMultisampled2dF32:
|
||||
case ValidTextureOverload::kLoadMultisampled2dF32:
|
||||
case ValidTextureOverload::kLoadMultisampled2dU32:
|
||||
case ValidTextureOverload::kLoadMultisampled2dI32:
|
||||
return R"(texelFetch(tint_symbol, ivec2(1, 2), 3);)";
|
||||
return R"(texelFetch(tint_symbol_2, ivec2(1, 2), 3);)";
|
||||
case ValidTextureOverload::kLoadDepth2dLevelF32:
|
||||
return R"(texelFetch(tint_symbol, ivec2(1, 2), 3).x;)";
|
||||
return R"(texelFetch(tint_symbol_2, ivec2(1, 2), 3).x;)";
|
||||
case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
|
||||
return R"(texelFetch(tint_symbol, ivec3(1, 2, 3), 4).x;)";
|
||||
return R"(texelFetch(tint_symbol_2, ivec3(1, 2, 3), 4).x;)";
|
||||
case ValidTextureOverload::kStoreWO1dRgba32float:
|
||||
return R"(imageStore(tint_symbol, 1, vec4(2.0f, 3.0f, 4.0f, 5.0f));)";
|
||||
return R"(imageStore(tint_symbol_2, 1, vec4(2.0f, 3.0f, 4.0f, 5.0f));)";
|
||||
case ValidTextureOverload::kStoreWO2dRgba32float:
|
||||
return R"(imageStore(tint_symbol, ivec2(1, 2), vec4(3.0f, 4.0f, 5.0f, 6.0f));)";
|
||||
return R"(imageStore(tint_symbol_2, ivec2(1, 2), vec4(3.0f, 4.0f, 5.0f, 6.0f));)";
|
||||
case ValidTextureOverload::kStoreWO2dArrayRgba32float:
|
||||
return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
|
||||
return R"(imageStore(tint_symbol_2, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
|
||||
case ValidTextureOverload::kStoreWO3dRgba32float:
|
||||
return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
|
||||
return R"(imageStore(tint_symbol_2, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
|
||||
}
|
||||
return "<unmatched texture overload>";
|
||||
} // NOLINT - Ignore the length of this function
|
||||
|
||||
Reference in New Issue
Block a user