[tint][msl] Support pixel_local attachments
This change also removes the TINT_ENABLE_PIXEL_LOCAL_EXTENSION build flag
Change-Id: I6ab511c6bafc5b1bf60cdfba95453766159975a9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/150146
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb8b069..c537b05 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -187,9 +187,6 @@
option_if_not_defined(TINT_CHECK_CHROMIUM_STYLE "Check for [chromium-style] issues during build" OFF)
option_if_not_defined(TINT_RANDOMIZE_HASHES "Randomize the hash seed value to detect non-deterministic output" OFF)
-# TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
-option_if_not_defined(TINT_ENABLE_PIXEL_LOCAL_EXTENSION "Enable the WIP 'chromium_experimental_pixel_local' extension" OFF)
-
# Recommended setting for compability with future abseil releases.
set(ABSL_PROPAGATE_CXX_STD ON)
diff --git a/include/tint/tint.h b/include/tint/tint.h
index 899de9a..832bf7e 100644
--- a/include/tint/tint.h
+++ b/include/tint/tint.h
@@ -25,6 +25,7 @@
#include "src/tint/api/options/array_length_from_uniform.h"
#include "src/tint/api/options/binding_remapper.h"
#include "src/tint/api/options/external_texture.h"
+#include "src/tint/api/options/pixel_local.h"
#include "src/tint/api/options/texture_builtins_from_uniform.h"
#include "src/tint/api/tint.h"
#include "src/tint/lang/core/type/manager.h"
diff --git a/scripts/tint_overrides_with_defaults.gni b/scripts/tint_overrides_with_defaults.gni
index 606b530..7e2a646 100644
--- a/scripts/tint_overrides_with_defaults.gni
+++ b/scripts/tint_overrides_with_defaults.gni
@@ -86,11 +86,6 @@
if (!defined(tint_build_unittests)) {
tint_build_unittests = true
}
-
- # TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
- if (!defined(tint_enable_pixel_local_extension)) {
- tint_enable_pixel_local_extension = false
- }
}
declare_args() {
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 2e9e7ae..d6570a1 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -89,13 +89,6 @@
defines += [ "TINT_BUILD_SYNTAX_TREE_WRITER=0" ]
}
- # TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
- if (tint_enable_pixel_local_extension) {
- defines += [ "TINT_ENABLE_PIXEL_LOCAL_EXTENSION=1" ]
- } else {
- defines += [ "TINT_ENABLE_PIXEL_LOCAL_EXTENSION=0" ]
- }
-
include_dirs = [
"${tint_root_dir}/",
"${tint_root_dir}/include/",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 2632230..2da7f95 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -43,9 +43,6 @@
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_WGSL_WRITER=$<BOOL:${TINT_BUILD_WGSL_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_SYNTAX_TREE_WRITER=$<BOOL:${TINT_BUILD_SYNTAX_TREE_WRITER}>)
- # TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
- target_compile_definitions(${TARGET} PUBLIC -DTINT_ENABLE_PIXEL_LOCAL_EXTENSION=$<BOOL:${TINT_ENABLE_PIXEL_LOCAL_EXTENSION}>)
-
common_compile_options(${TARGET})
endfunction()
diff --git a/src/tint/api/options/BUILD.bazel b/src/tint/api/options/BUILD.bazel
index 211f184..0e57862 100644
--- a/src/tint/api/options/BUILD.bazel
+++ b/src/tint/api/options/BUILD.bazel
@@ -32,6 +32,7 @@
"array_length_from_uniform.h",
"binding_remapper.h",
"external_texture.h",
+ "pixel_local.h",
"texture_builtins_from_uniform.h",
],
deps = [
diff --git a/src/tint/api/options/BUILD.cmake b/src/tint/api/options/BUILD.cmake
index bb857ab..6f28382 100644
--- a/src/tint/api/options/BUILD.cmake
+++ b/src/tint/api/options/BUILD.cmake
@@ -30,6 +30,7 @@
api/options/binding_remapper.h
api/options/external_texture.h
api/options/options.cc
+ api/options/pixel_local.h
api/options/texture_builtins_from_uniform.h
)
diff --git a/src/tint/api/options/BUILD.gn b/src/tint/api/options/BUILD.gn
index fa8c423..6b5ccb4 100644
--- a/src/tint/api/options/BUILD.gn
+++ b/src/tint/api/options/BUILD.gn
@@ -31,6 +31,7 @@
"binding_remapper.h",
"external_texture.h",
"options.cc",
+ "pixel_local.h",
"texture_builtins_from_uniform.h",
]
deps = [
diff --git a/src/tint/api/options/pixel_local.h b/src/tint/api/options/pixel_local.h
new file mode 100644
index 0000000..7ab898d
--- /dev/null
+++ b/src/tint/api/options/pixel_local.h
@@ -0,0 +1,35 @@
+// Copyright 2023 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_API_OPTIONS_PIXEL_LOCAL_H_
+#define SRC_TINT_API_OPTIONS_PIXEL_LOCAL_H_
+
+#include <unordered_map>
+
+#include "src/tint/utils/reflection/reflection.h"
+
+namespace tint {
+
+/// Options used to specify pixel local mappings
+struct PixelLocalOptions {
+ /// Index of pixel_local structure member index to attachment index
+ std::unordered_map<uint32_t, uint32_t> attachments;
+
+ /// Reflect the fields of this class so that it can be used by tint::ForeachField()
+ TINT_REFLECT(attachments);
+};
+
+} // namespace tint
+
+#endif // SRC_TINT_API_OPTIONS_PIXEL_LOCAL_H_
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index c93b2dd..da47439 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -33,6 +33,7 @@
#include "spirv-tools/libspirv.hpp"
#endif // TINT_BUILD_SPV_READER || TINT_BUILD_SPV_WRITER
+#include "src/tint/api/options/pixel_local.h"
#include "src/tint/api/tint.h"
#include "src/tint/cmd/common/generate_external_texture_bindings.h"
#include "src/tint/cmd/common/helper.h"
@@ -166,6 +167,7 @@
std::string xcrun_path;
tint::Hashmap<std::string, double, 8> overrides;
std::optional<tint::BindingPoint> hlsl_root_constant_binding_point;
+ tint::PixelLocalOptions pixel_local_options;
bool dump_ir = false;
bool use_ir = false;
@@ -358,6 +360,15 @@
default to binding 0 of the largest used group plus 1,
or group 0 if no resource bound)");
+ auto& pixel_local_attachments =
+ options.Add<StringOption>("pixel_local_attachments",
+ R"(Pixel local storage attachment bindings, comma-separated
+Each binding is of the form MEMBER_INDEX=ATTACHMENT_INDEX,
+where MEMBER_INDEX is the pixel-local structure member
+index and ATTACHMENT_INDEX is the index of the emitted
+attachment.
+)");
+
auto& skip_hash = options.Add<StringOption>(
"skip-hash", R"(Skips validation if the hash of the output is equal to any
of the hash codes in the comma separated list of hashes)");
@@ -438,6 +449,32 @@
opts->hlsl_root_constant_binding_point = tint::BindingPoint{group.Get(), binding.Get()};
}
+ if (pixel_local_attachments.value.has_value()) {
+ auto bindings = tint::Split(*pixel_local_attachments.value, ",");
+ for (auto& binding : bindings) {
+ auto values = tint::Split(binding, "=");
+ if (values.Length() != 2) {
+ std::cerr << "Invalid binding " << pixel_local_attachments.name << ": " << binding
+ << std::endl;
+ return false;
+ }
+ auto member_index = tint::ParseUint32(values[0]);
+ if (!member_index) {
+ std::cerr << "Invalid member index for " << pixel_local_attachments.name << ": "
+ << values[0] << std::endl;
+ return false;
+ }
+ auto attachment_index = tint::ParseUint32(values[1]);
+ if (!attachment_index) {
+ std::cerr << "Invalid attachment index for " << pixel_local_attachments.name << ": "
+ << values[1] << std::endl;
+ return false;
+ }
+ opts->pixel_local_options.attachments.emplace(member_index.Get(),
+ attachment_index.Get());
+ }
+ }
+
auto files = result.Get();
if (files.Length() > 1) {
std::cerr << "More than one input file specified: "
@@ -653,6 +690,7 @@
gen_options.use_tint_ir = options.use_ir;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.disable_workgroup_init = options.disable_workgroup_init;
+ gen_options.pixel_local_options = options.pixel_local_options;
gen_options.external_texture_options.bindings_map =
tint::cmd::GenerateExternalTextureBindings(input_program);
gen_options.array_length_from_uniform.ubo_binding = tint::BindingPoint{0, 30};
@@ -681,7 +719,10 @@
auto msl_version = tint::msl::validate::MslVersion::kMsl_1_2;
for (auto* enable : program->AST().Enables()) {
if (enable->HasExtension(tint::core::Extension::kChromiumExperimentalSubgroups)) {
- msl_version = tint::msl::validate::MslVersion::kMsl_2_1;
+ msl_version = std::max(msl_version, tint::msl::validate::MslVersion::kMsl_2_1);
+ }
+ if (enable->HasExtension(tint::core::Extension::kChromiumExperimentalPixelLocal)) {
+ msl_version = std::max(msl_version, tint::msl::validate::MslVersion::kMsl_2_3);
}
}
diff --git a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
index 1a0a558..22fd118 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
@@ -44,6 +44,7 @@
#include "src/tint/lang/core/type/void.h"
#include "src/tint/lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.h"
#include "src/tint/lang/msl/writer/ast_raise/packed_vec3.h"
+#include "src/tint/lang/msl/writer/ast_raise/pixel_local.h"
#include "src/tint/lang/msl/writer/ast_raise/subgroup_ballot.h"
#include "src/tint/lang/msl/writer/common/printer_support.h"
#include "src/tint/lang/wgsl/ast/alias.h"
@@ -212,6 +213,15 @@
// SubgroupBallot() must come after CanonicalizeEntryPointIO.
manager.Add<SubgroupBallot>();
+ {
+ PixelLocal::Config cfg;
+ for (auto it : options.pixel_local_options.attachments) {
+ cfg.attachments.Add(it.first, it.second);
+ }
+ data.Add<PixelLocal::Config>(cfg);
+ manager.Add<PixelLocal>();
+ }
+
// ArrayLengthFromUniform must come after SimplifyPointers, as
// it assumes that the form of the array length argument is &var.array.
manager.Add<ast::transform::ArrayLengthFromUniform>();
@@ -248,14 +258,15 @@
"MSL", builder_.AST(), diagnostics_,
Vector{
core::Extension::kChromiumDisableUniformityAnalysis,
+ core::Extension::kChromiumExperimentalDp4A,
core::Extension::kChromiumExperimentalFullPtrParameters,
+ core::Extension::kChromiumExperimentalPixelLocal,
core::Extension::kChromiumExperimentalPushConstant,
core::Extension::kChromiumExperimentalReadWriteStorageTexture,
core::Extension::kChromiumExperimentalSubgroups,
+ core::Extension::kChromiumInternalDualSourceBlending,
core::Extension::kChromiumInternalRelaxedUniformLayout,
core::Extension::kF16,
- core::Extension::kChromiumInternalDualSourceBlending,
- core::Extension::kChromiumExperimentalDp4A,
})) {
return false;
}
@@ -1987,8 +1998,20 @@
bool ok = Switch(
type, //
- [&](const core::type::Struct*) {
- out << " [[stage_in]]";
+ [&](const core::type::Struct* str) {
+ bool is_pixel_local = false;
+ if (auto* sem_str = str->As<sem::Struct>()) {
+ for (auto* member : sem_str->Members()) {
+ if (ast::HasAttribute<PixelLocal::Attachment>(
+ member->Declaration()->attributes)) {
+ is_pixel_local = true;
+ break;
+ }
+ }
+ }
+ if (!is_pixel_local) {
+ out << " [[stage_in]]";
+ }
return true;
},
[&](const core::type::Texture*) {
@@ -2801,7 +2824,7 @@
if (auto location = attributes.location) {
auto& pipeline_stage_uses = str->PipelineStageUses();
if (TINT_UNLIKELY(pipeline_stage_uses.size() != 1)) {
- TINT_ICE() << "invalid entry point IO struct uses";
+ TINT_ICE() << "invalid entry point IO struct uses for " << str->Name().NameView();
return false;
}
@@ -2839,6 +2862,13 @@
out << " " << invariant_define_name_;
}
+ if (auto* sem_mem = mem->As<sem::StructMember>()) {
+ if (auto* attachment =
+ ast::GetAttribute<PixelLocal::Attachment>(sem_mem->Declaration()->attributes)) {
+ out << " [[color(" << attachment->index << ")]]";
+ }
+ }
+
out << ";";
if (is_host_shareable) {
diff --git a/src/tint/lang/msl/writer/ast_raise/BUILD.bazel b/src/tint/lang/msl/writer/ast_raise/BUILD.bazel
index 5b004a6..0b080b5 100644
--- a/src/tint/lang/msl/writer/ast_raise/BUILD.bazel
+++ b/src/tint/lang/msl/writer/ast_raise/BUILD.bazel
@@ -28,11 +28,13 @@
srcs = [
"module_scope_var_to_entry_point_param.cc",
"packed_vec3.cc",
+ "pixel_local.cc",
"subgroup_ballot.cc",
],
hdrs = [
"module_scope_var_to_entry_point_param.h",
"packed_vec3.h",
+ "pixel_local.h",
"subgroup_ballot.h",
],
deps = [
@@ -68,6 +70,7 @@
srcs = [
"module_scope_var_to_entry_point_param_test.cc",
"packed_vec3_test.cc",
+ "pixel_local_test.cc",
"subgroup_ballot_test.cc",
],
deps = [
diff --git a/src/tint/lang/msl/writer/ast_raise/BUILD.cmake b/src/tint/lang/msl/writer/ast_raise/BUILD.cmake
index 838ec7d..56fe8bd 100644
--- a/src/tint/lang/msl/writer/ast_raise/BUILD.cmake
+++ b/src/tint/lang/msl/writer/ast_raise/BUILD.cmake
@@ -32,6 +32,8 @@
lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.h
lang/msl/writer/ast_raise/packed_vec3.cc
lang/msl/writer/ast_raise/packed_vec3.h
+ lang/msl/writer/ast_raise/pixel_local.cc
+ lang/msl/writer/ast_raise/pixel_local.h
lang/msl/writer/ast_raise/subgroup_ballot.cc
lang/msl/writer/ast_raise/subgroup_ballot.h
)
@@ -71,6 +73,7 @@
tint_add_target(tint_lang_msl_writer_ast_raise_test test
lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param_test.cc
lang/msl/writer/ast_raise/packed_vec3_test.cc
+ lang/msl/writer/ast_raise/pixel_local_test.cc
lang/msl/writer/ast_raise/subgroup_ballot_test.cc
)
diff --git a/src/tint/lang/msl/writer/ast_raise/BUILD.gn b/src/tint/lang/msl/writer/ast_raise/BUILD.gn
index bf36d87..f6890c2 100644
--- a/src/tint/lang/msl/writer/ast_raise/BUILD.gn
+++ b/src/tint/lang/msl/writer/ast_raise/BUILD.gn
@@ -35,6 +35,8 @@
"module_scope_var_to_entry_point_param.h",
"packed_vec3.cc",
"packed_vec3.h",
+ "pixel_local.cc",
+ "pixel_local.h",
"subgroup_ballot.cc",
"subgroup_ballot.h",
]
@@ -71,6 +73,7 @@
sources = [
"module_scope_var_to_entry_point_param_test.cc",
"packed_vec3_test.cc",
+ "pixel_local_test.cc",
"subgroup_ballot_test.cc",
]
deps = [
diff --git a/src/tint/lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.cc b/src/tint/lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.cc
index 54531f7..4e529a2 100644
--- a/src/tint/lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/lang/msl/writer/ast_raise/module_scope_var_to_entry_point_param.cc
@@ -201,6 +201,8 @@
}
break;
}
+ case core::AddressSpace::kPixelLocal:
+ break; // Ignore
default: {
TINT_ICE() << "unhandled module-scope address space (" << sc << ")";
break;
diff --git a/src/tint/lang/msl/writer/ast_raise/pixel_local.cc b/src/tint/lang/msl/writer/ast_raise/pixel_local.cc
new file mode 100644
index 0000000..53f6dfe
--- /dev/null
+++ b/src/tint/lang/msl/writer/ast_raise/pixel_local.cc
@@ -0,0 +1,287 @@
+// Copyright 2023 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/lang/msl/writer/ast_raise/pixel_local.h"
+
+#include <utility>
+
+#include "src/tint/lang/core/fluent_types.h"
+#include "src/tint/lang/wgsl/program/clone_context.h"
+#include "src/tint/lang/wgsl/resolver/resolve.h"
+#include "src/tint/lang/wgsl/sem/function.h"
+#include "src/tint/lang/wgsl/sem/module.h"
+#include "src/tint/lang/wgsl/sem/statement.h"
+#include "src/tint/lang/wgsl/sem/struct.h"
+#include "src/tint/utils/containers/transform.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::msl::writer::PixelLocal);
+TINT_INSTANTIATE_TYPEINFO(tint::msl::writer::PixelLocal::Attachment);
+TINT_INSTANTIATE_TYPEINFO(tint::msl::writer::PixelLocal::Config);
+
+using namespace tint::core::number_suffixes; // NOLINT
+using namespace tint::core::fluent_types; // NOLINT
+
+namespace tint::msl::writer {
+
+/// PIMPL state for the transform
+struct PixelLocal::State {
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ program::CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
+ /// The transform config
+ const Config& cfg;
+
+ /// Constructor
+ /// @param program the source program
+ /// @param config the transform config
+ State(const Program* program, const Config& config) : src(program), cfg(config) {}
+
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
+ auto& sem = src->Sem();
+
+ // If the pixel local extension isn't enabled, then there must be no use of pixel_local
+ // variables, and so there's nothing for this transform to do.
+ if (!sem.Module()->Extensions().Contains(
+ core::Extension::kChromiumExperimentalPixelLocal)) {
+ return SkipTransform;
+ }
+
+ bool made_changes = false;
+
+ // Change all module scope `var<pixel_local>` variables to `var<private>`.
+ // We need to do this even if the variable is not referenced by the entry point as later
+ // stages do not understand the pixel_local address space.
+ for (auto* global : src->AST().GlobalVariables()) {
+ if (auto* var = global->As<ast::Var>()) {
+ if (sem.Get(var)->AddressSpace() == core::AddressSpace::kPixelLocal) {
+ // Change the 'var<pixel_local>' to 'var<private>'
+ ctx.Replace(var->declared_address_space, b.Expr(core::AddressSpace::kPrivate));
+ made_changes = true;
+ }
+ }
+ }
+
+ // Find the single entry point
+ const sem::Function* entry_point = nullptr;
+ for (auto* fn : src->AST().Functions()) {
+ if (fn->IsEntryPoint()) {
+ if (entry_point != nullptr) {
+ TINT_ICE() << "PixelLocal transform requires that the SingleEntryPoint "
+ "transform has already been run";
+ return SkipTransform;
+ }
+ entry_point = sem.Get(fn);
+
+ // Look for a `var<pixel_local>` used by the entry point...
+ for (auto* global : entry_point->TransitivelyReferencedGlobals()) {
+ if (global->AddressSpace() != core::AddressSpace::kPixelLocal) {
+ continue;
+ }
+
+ // Obtain struct of the pixel local.
+ auto* pixel_local_str = global->Type()->UnwrapRef()->As<sem::Struct>();
+
+ // Add an attachment decoration to each member of the pixel_local structure.
+ for (auto* member : pixel_local_str->Members()) {
+ ctx.InsertBack(member->Declaration()->attributes,
+ Attachment(AttachmentIndex(member->Index())));
+ ctx.InsertBack(member->Declaration()->attributes,
+ b.Disable(ast::DisabledValidation::kEntryPointParameter));
+ }
+
+ TransformEntryPoint(entry_point, global, pixel_local_str);
+ made_changes = true;
+
+ break; // Only a single `var<pixel_local>` can be used by an entry point.
+ }
+ }
+ }
+
+ if (!made_changes) {
+ return SkipTransform;
+ }
+
+ ctx.Clone();
+ return resolver::Resolve(b);
+ }
+
+ /// Transforms the entry point @p entry_point to handle the direct or transitive usage of the
+ /// `var<pixel_local>` @p pixel_local_var.
+ /// @param entry_point the entry point
+ /// @param pixel_local_var the `var<pixel_local>`
+ /// @param pixel_local_str the struct type of the var
+ void TransformEntryPoint(const sem::Function* entry_point,
+ const sem::GlobalVariable* pixel_local_var,
+ const sem::Struct* pixel_local_str) {
+ auto* fn = entry_point->Declaration();
+ auto fn_name = fn->name->symbol.Name();
+ auto pixel_local_str_name = ctx.Clone(pixel_local_str->Name());
+ auto pixel_local_var_name = ctx.Clone(pixel_local_var->Declaration()->name->symbol);
+
+ // Remove the @fragment attribute from the entry point
+ ctx.Remove(fn->attributes, ast::GetAttribute<ast::StageAttribute>(fn->attributes));
+ // Rename the entry point
+ auto inner_name = b.Symbols().New(fn_name + "_inner");
+ ctx.Replace(fn->name, b.Ident(inner_name));
+
+ // Create a new function that wraps the entry point.
+ // This function has all the existing entry point parameters and an additional
+ // parameter for the input pixel local structure.
+ auto params = ctx.Clone(fn->params);
+ auto pl_param = b.Symbols().New("pixel_local");
+ params.Push(b.Param(pl_param, b.ty(pixel_local_str_name)));
+
+ // Remove any entry-point attributes from the inner function.
+ // This must come after `ctx.Clone(fn->params)` as we want these attributes on the outer
+ // function.
+ for (auto* param : fn->params) {
+ for (auto* attr : param->attributes) {
+ if (attr->IsAnyOf<ast::BuiltinAttribute, ast::LocationAttribute,
+ ast::InterpolateAttribute, ast::InvariantAttribute>()) {
+ ctx.Remove(param->attributes, attr);
+ }
+ }
+ }
+
+ // Build the outer function's statements, starting with an assignment of the pixel local
+ // parameter to the module scope var.
+ Vector<const ast::Statement*, 3> body{
+ b.Assign(pixel_local_var_name, pl_param),
+ };
+
+ // Build the arguments to call the inner function
+ auto call_args =
+ tint::Transform(fn->params, [&](auto* p) { return b.Expr(ctx.Clone(p->name)); });
+
+ // Create a structure to hold the combined flattened result of the entry point and the pixel
+ // local structure.
+ auto str_name = b.Symbols().New(fn_name + "_res");
+ Vector<const ast::StructMember*, 8> members;
+ Vector<const ast::Expression*, 8> return_args; // arguments to the final `return` statement
+
+ auto add_member = [&](const core::type::Type* ty, VectorRef<const ast::Attribute*> attrs) {
+ members.Push(b.Member("output_" + std::to_string(members.Length()),
+ CreateASTTypeFor(ctx, ty), std::move(attrs)));
+ };
+ for (auto* member : pixel_local_str->Members()) {
+ add_member(member->Type(), Vector{
+ b.Location(AInt(AttachmentIndex(member->Index()))),
+ });
+ return_args.Push(b.MemberAccessor(pixel_local_var_name, ctx.Clone(member->Name())));
+ }
+ if (fn->return_type) {
+ Symbol call_result = b.Symbols().New("result");
+ if (auto* str = entry_point->ReturnType()->As<sem::Struct>()) {
+ // The entry point returned a structure.
+ for (auto* member : str->Members()) {
+ auto& member_attrs = member->Declaration()->attributes;
+ add_member(member->Type(), ctx.Clone(member_attrs));
+ return_args.Push(b.MemberAccessor(call_result, ctx.Clone(member->Name())));
+ if (auto* location = ast::GetAttribute<ast::LocationAttribute>(member_attrs)) {
+ // Remove the @location attribute from the member of the inner function's
+ // output structure.
+ // Note: This will break other entry points that share the same output
+ // structure, however this transform assumes that the SingleEntryPoint
+ // transform will have already been run.
+ ctx.Remove(member_attrs, location);
+ }
+ }
+ } else {
+ // The entry point returned a non-structure
+ add_member(entry_point->ReturnType(), ctx.Clone(fn->return_type_attributes));
+ return_args.Push(b.Expr(call_result));
+
+ // Remove the @location from the inner function's return type attributes
+ ctx.Remove(fn->return_type_attributes,
+ ast::GetAttribute<ast::LocationAttribute>(fn->return_type_attributes));
+ }
+ body.Push(b.Decl(b.Let(call_result, b.Call(inner_name, std::move(call_args)))));
+ } else {
+ body.Push(b.CallStmt(b.Call(inner_name, std::move(call_args))));
+ }
+
+ // Declare the output structure
+ b.Structure(str_name, std::move(members));
+
+ // Return the output structure
+ body.Push(b.Return(b.Call(str_name, std::move(return_args))));
+
+ // Declare the new entry point that calls the inner function
+ b.Func(fn_name, std::move(params), b.ty(str_name), body,
+ Vector{b.Stage(ast::PipelineStage::kFragment)});
+ }
+
+ /// @returns a new Attachment attribute
+ /// @param index the index of the attachment
+ PixelLocal::Attachment* Attachment(uint32_t index) {
+ return b.ASTNodes().Create<PixelLocal::Attachment>(b.ID(), b.AllocateNodeID(), index);
+ }
+
+ /// @returns the attachment index for the pixel local field with the given index
+ /// @param field_index the pixel local field index
+ uint32_t AttachmentIndex(uint32_t field_index) {
+ auto idx = cfg.attachments.Get(field_index);
+ if (TINT_UNLIKELY(!idx)) {
+ b.Diagnostics().add_error(diag::System::Transform,
+ "PixelLocal::Config::attachments missing entry for field " +
+ std::to_string(field_index));
+ return 0;
+ }
+ return *idx;
+ }
+};
+
+PixelLocal::PixelLocal() = default;
+
+PixelLocal::~PixelLocal() = default;
+
+ast::transform::Transform::ApplyResult PixelLocal::Apply(const Program* src,
+ const ast::transform::DataMap& inputs,
+ ast::transform::DataMap&) const {
+ auto* cfg = inputs.Get<Config>();
+ if (!cfg) {
+ ProgramBuilder b;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return resolver::Resolve(b);
+ }
+
+ return State(src, *cfg).Run();
+}
+
+PixelLocal::Config::Config() = default;
+
+PixelLocal::Config::Config(const Config&) = default;
+
+PixelLocal::Config::~Config() = default;
+
+PixelLocal::Attachment::Attachment(GenerationID pid, ast::NodeID nid, uint32_t idx)
+ : Base(pid, nid, Empty), index(idx) {}
+
+PixelLocal::Attachment::~Attachment() = default;
+
+std::string PixelLocal::Attachment::InternalName() const {
+ return "attachment(" + std::to_string(index) + ")";
+}
+
+const PixelLocal::Attachment* PixelLocal::Attachment::Clone(ast::CloneContext& ctx) const {
+ return ctx.dst->ASTNodes().Create<Attachment>(ctx.dst->ID(), ctx.dst->AllocateNodeID(), index);
+}
+
+} // namespace tint::msl::writer
diff --git a/src/tint/lang/msl/writer/ast_raise/pixel_local.h b/src/tint/lang/msl/writer/ast_raise/pixel_local.h
new file mode 100644
index 0000000..4d1b51f
--- /dev/null
+++ b/src/tint/lang/msl/writer/ast_raise/pixel_local.h
@@ -0,0 +1,96 @@
+// Copyright 2023 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_LANG_MSL_WRITER_AST_RAISE_PIXEL_LOCAL_H_
+#define SRC_TINT_LANG_MSL_WRITER_AST_RAISE_PIXEL_LOCAL_H_
+
+#include <string>
+
+#include "src/tint/lang/wgsl/ast/internal_attribute.h"
+#include "src/tint/lang/wgsl/ast/transform/transform.h"
+#include "src/tint/utils/containers/hashmap.h"
+
+namespace tint::msl::writer {
+
+/// PixelLocal transforms module-scope `var<pixel_local>`s and fragment entry point functions that
+/// use them:
+/// * `var<pixel_local>` will be transformed to `var<private>`.
+/// * The entry point function will be wrapped with another function ('outer') that calls the
+/// 'inner' function.
+/// * The outer function will have an additional parameter of the pixel local struct type, which is
+/// copied to the module-scope var before calling the 'inner' function.
+/// * The outer function will have a new struct return type which holds both the pixel local members
+/// and the returned value(s) of the 'inner' function.
+/// @note PixelLocal requires that the SingleEntryPoint transform has already been run
+class PixelLocal final : public Castable<PixelLocal, ast::transform::Transform> {
+ public:
+ /// Transform configuration options
+ struct Config final : public Castable<Config, ast::transform::Data> {
+ /// Constructor
+ Config();
+
+ /// Copy Constructor
+ Config(const Config&);
+
+ /// Destructor
+ ~Config() override;
+
+ /// Index of pixel_local structure member index to attachment index
+ Hashmap<uint32_t, uint32_t, 8> attachments;
+ };
+
+ /// Intrinsic is an InternalAttribute that's used to decorate a pixel local attachment
+ /// parameter, return value or structure member.
+ class Attachment final : public Castable<Attachment, ast::InternalAttribute> {
+ public:
+ /// Constructor
+ /// @param pid the identifier of the program that owns this node
+ /// @param nid the unique node identifier
+ /// @param idx the attachment index
+ Attachment(GenerationID pid, ast::NodeID nid, uint32_t idx);
+
+ /// Destructor
+ ~Attachment() override;
+
+ /// @return a short description of the internal attribute which will be
+ /// displayed as `@internal(<name>)`
+ std::string InternalName() const override;
+
+ /// Performs a deep clone of this object using the program::CloneContext `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned object
+ const Attachment* Clone(ast::CloneContext& ctx) const override;
+
+ /// The attachment index
+ const uint32_t index;
+ };
+
+ /// Constructor
+ PixelLocal();
+
+ /// Destructor
+ ~PixelLocal() override;
+
+ /// @copydoc ast::transform::Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const ast::transform::DataMap& inputs,
+ ast::transform::DataMap& outputs) const override;
+
+ private:
+ struct State;
+};
+
+} // namespace tint::msl::writer
+
+#endif // SRC_TINT_LANG_MSL_WRITER_AST_RAISE_PIXEL_LOCAL_H_
diff --git a/src/tint/lang/msl/writer/ast_raise/pixel_local_test.cc b/src/tint/lang/msl/writer/ast_raise/pixel_local_test.cc
new file mode 100644
index 0000000..4b634f9
--- /dev/null
+++ b/src/tint/lang/msl/writer/ast_raise/pixel_local_test.cc
@@ -0,0 +1,799 @@
+// Copyright 2023 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/lang/msl/writer/ast_raise/pixel_local.h"
+
+#include <utility>
+
+#include "src/tint/lang/wgsl/ast/transform/helper_test.h"
+
+namespace tint::msl::writer {
+namespace {
+
+struct Binding {
+ uint32_t field_index;
+ uint32_t attachment_index;
+};
+
+ast::transform::DataMap Bindings(std::initializer_list<Binding> bindings) {
+ PixelLocal::Config cfg;
+ for (auto& binding : bindings) {
+ cfg.attachments.Add(binding.field_index, binding.attachment_index);
+ }
+ ast::transform::DataMap data;
+ data.Add<PixelLocal::Config>(std::move(cfg));
+ return data;
+}
+
+using PixelLocalTest = ast::transform::TransformTest;
+
+TEST_F(PixelLocalTest, EmptyModule) {
+ auto* src = "";
+
+ EXPECT_FALSE(ShouldRun<PixelLocal>(src, Bindings({})));
+}
+
+TEST_F(PixelLocalTest, Var) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : i32,
+};
+
+var<pixel_local> P : PixelLocal;
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : i32,
+}
+
+var<private> P : PixelLocal;
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, UseInEntryPoint) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F() {
+ P.a += 42;
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner();
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner() {
+ P.a += 42;
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, UseInCallee) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn X() {
+ P.a += 42;
+}
+
+@fragment
+fn F() {
+ X();
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner();
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn X() {
+ P.a += 42;
+}
+
+fn F_inner() {
+ X();
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, MultipleAttachments) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F() {
+ P.a = 42;
+ P.b = i32(P.c);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+ @location(0)
+ output_1 : i32,
+ @location(10)
+ output_2 : f32,
+}
+
+@fragment
+fn F(pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner();
+ return F_res(P.a, P.b, P.c);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+ @internal(attachment(0)) @internal(disable_validation__entry_point_parameter)
+ b : i32,
+ @internal(attachment(10)) @internal(disable_validation__entry_point_parameter)
+ c : f32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner() {
+ P.a = 42;
+ P.b = i32(P.c);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}, {1, 0}, {2, 10}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithBuiltinInputParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(@builtin(position) pos : vec4f, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(pos);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner(pos : vec4f) {
+ P.a += u32(pos.x);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithInvariantBuiltinInputParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(@invariant @builtin(position) pos : vec4f, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(pos);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner(pos : vec4f) {
+ P.a += u32(pos.x);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithBuiltinInputStructParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position) pos : vec4f,
+}
+
+@fragment
+fn F(in : In) {
+ P.a += u32(in.pos.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(in : In, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(in);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+fn F_inner(in : In) {
+ P.a += u32(in.pos.x);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithInvariantBuiltinInputStructParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position) pos : vec4f,
+}
+
+@fragment
+fn F(in : In) {
+ P.a += u32(in.pos.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(in : In, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(in);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+fn F_inner(in : In) {
+ P.a += u32(in.pos.x);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithLocationInputParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += u32(a.x) + u32(b.y);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(a, b);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner(a : vec4f, b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithLocationInputStructParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0) a : vec4f,
+ @interpolate(flat) @location(1) b : vec4f,
+}
+
+@fragment
+fn F(in : In) {
+ P.a += u32(in.a.x) + u32(in.b.y);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(in : In, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(in);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+fn F_inner(in : In) {
+ P.a += (u32(in.a.x) + u32(in.b.y));
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithBuiltinAndLocationInputParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += u32(pos.x) + u32(uv.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(@builtin(position) pos : vec4f, @location(0) uv : vec4f, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(pos, uv);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner(pos : vec4f, uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithBuiltinAndLocationInputStructParameter) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position) pos : vec4f,
+ @location(0) uv : vec4f,
+}
+
+@fragment
+fn F(in : In) {
+ P.a += u32(in.pos.x) + u32(in.uv.x);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+}
+
+@fragment
+fn F(in : In, pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ F_inner(in);
+ return F_res(P.a);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+fn F_inner(in : In) {
+ P.a += (u32(in.pos.x) + u32(in.uv.x));
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithSingleFragmentOutput) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn F() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(1);
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+ @location(0)
+ output_1 : vec4<f32>,
+}
+
+@fragment
+fn F(pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ let result = F_inner();
+ return F_res(P.a, result);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+}
+
+var<private> P : PixelLocal;
+
+fn F_inner() -> vec4f {
+ P.a += 42;
+ return vec4f(1);
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PixelLocalTest, WithMultipleFragmentOutputs) {
+ auto* src = R"(
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Output {
+ @location(0) x : vec4f,
+ @location(2) y : vec4f,
+}
+
+@fragment
+fn F() -> Output {
+ P.a += 42;
+ return Output(vec4f(1), vec4f(9));
+}
+)";
+
+ auto* expect =
+ R"(
+enable chromium_experimental_pixel_local;
+
+struct F_res {
+ @location(1)
+ output_0 : u32,
+ @location(5)
+ output_1 : u32,
+ @location(0)
+ output_2 : vec4<f32>,
+ @location(2)
+ output_3 : vec4<f32>,
+}
+
+@fragment
+fn F(pixel_local_1 : PixelLocal) -> F_res {
+ P = pixel_local_1;
+ let result = F_inner();
+ return F_res(P.a, P.b, result.x, result.y);
+}
+
+struct PixelLocal {
+ @internal(attachment(1)) @internal(disable_validation__entry_point_parameter)
+ a : u32,
+ @internal(attachment(5)) @internal(disable_validation__entry_point_parameter)
+ b : u32,
+}
+
+var<private> P : PixelLocal;
+
+struct Output {
+ x : vec4f,
+ y : vec4f,
+}
+
+fn F_inner() -> Output {
+ P.a += 42;
+ return Output(vec4f(1), vec4f(9));
+}
+)";
+
+ auto got = Run<PixelLocal>(src, Bindings({{0, 1}, {1, 5}}));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace
+} // namespace tint::msl::writer
diff --git a/src/tint/lang/msl/writer/common/options.h b/src/tint/lang/msl/writer/common/options.h
index 0b23a08..763b1d3 100644
--- a/src/tint/lang/msl/writer/common/options.h
+++ b/src/tint/lang/msl/writer/common/options.h
@@ -18,6 +18,7 @@
#include "src/tint/api/options/array_length_from_uniform.h"
#include "src/tint/api/options/binding_remapper.h"
#include "src/tint/api/options/external_texture.h"
+#include "src/tint/api/options/pixel_local.h"
#include "src/tint/utils/reflection/reflection.h"
namespace tint::msl::writer {
@@ -52,6 +53,9 @@
/// Set to `true` to disable workgroup memory zero initialization
bool disable_workgroup_init = false;
+ /// Options used for dealing with pixel local storage
+ PixelLocalOptions pixel_local_options = {};
+
/// Options used in the binding mappings for external textures
ExternalTextureOptions external_texture_options = {};
diff --git a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
index be33712..e9d244e 100644
--- a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
@@ -176,16 +176,16 @@
}
}
- /// Clones the shader IO attributes from @p in.
+ /// Clones the shader IO and internal attributes from @p in.
/// @param in the attributes to clone
/// @param do_interpolate whether to clone InterpolateAttribute
/// @return the cloned attributes
- template <size_t N>
- auto CloneShaderIOAttributes(const tint::Vector<const Attribute*, N> in, bool do_interpolate) {
- tint::Vector<const Attribute*, N> out;
+ auto CloneShaderIOAttributes(tint::VectorRef<const Attribute*> in, bool do_interpolate) {
+ tint::Vector<const Attribute*, 8> out;
for (auto* attr : in) {
- if (IsShaderIOAttribute(attr) &&
- (do_interpolate || !attr->template Is<InterpolateAttribute>())) {
+ if ((IsShaderIOAttribute(attr) &&
+ (do_interpolate || !attr->template Is<InterpolateAttribute>())) ||
+ attr->Is<ast::InternalAttribute>()) {
CloneAttribute(attr, out);
}
}
diff --git a/src/tint/lang/wgsl/resolver/function_validation_test.cc b/src/tint/lang/wgsl/resolver/function_validation_test.cc
index 5119f6e..e1d479a 100644
--- a/src/tint/lang/wgsl/resolver/function_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/function_validation_test.cc
@@ -1054,13 +1054,7 @@
Func("f", Vector{arg}, ty.void_(), tint::Empty);
if (param.address_space == core::AddressSpace::kPixelLocal) {
-#if !TINT_ENABLE_PIXEL_LOCAL_EXTENSION
- // TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is
- // production-ready
- GTEST_SKIP() << "requires TINT_ENABLE_PIXEL_LOCAL_EXTENSION";
-#else
Enable(core::Extension::kChromiumExperimentalPixelLocal);
-#endif
}
if (param.expectation == Expectation::kAlwaysPass) {
@@ -1090,13 +1084,7 @@
Func("f", Vector{arg}, ty.void_(), tint::Empty);
if (param.address_space == core::AddressSpace::kPixelLocal) {
-#if !TINT_ENABLE_PIXEL_LOCAL_EXTENSION
- // TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is
- // production-ready
- GTEST_SKIP() << "requires TINT_ENABLE_PIXEL_LOCAL_EXTENSION";
-#else
Enable(core::Extension::kChromiumExperimentalPixelLocal);
-#endif
}
if (param.expectation == Expectation::kAlwaysPass ||
diff --git a/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc b/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
index 31684c7..2c97b5d 100644
--- a/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
@@ -35,15 +35,7 @@
GlobalVar("v", ty("S"), core::AddressSpace::kPixelLocal);
-#if TINT_ENABLE_PIXEL_LOCAL_EXTENSION
EXPECT_TRUE(r()->Resolve()) << r()->error();
-#else
- // TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(12:34 error: chromium_experimental_pixel_local requires TINT_ENABLE_PIXEL_LOCAL_EXTENSION)");
-#endif
}
TEST_F(ResolverPixelLocalExtensionTest, AddressSpaceUsedWithoutExtension) {
@@ -66,8 +58,6 @@
R"(12:34 error: 'pixel_local' address space requires the 'chromium_experimental_pixel_local' extension enabled)");
}
-#if TINT_ENABLE_PIXEL_LOCAL_EXTENSION
-
TEST_F(ResolverPixelLocalExtensionTest, PixelLocalTwoVariablesUsedInEntryPoint) {
// enable chromium_experimental_pixel_local;
// struct S { i : i32 }
@@ -357,7 +347,5 @@
} // namespace type_tests
-#endif
-
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 5ac5d21..5327b0d 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -3998,16 +3998,6 @@
for (auto* ext : enable->extensions) {
Mark(ext);
enabled_extensions_.Add(ext->name);
-
-// TODO(crbug.com/dawn/1704): Remove when chromium_experimental_pixel_local is production-ready
-#if !TINT_ENABLE_PIXEL_LOCAL_EXTENSION
- if (ext->name == core::Extension::kChromiumExperimentalPixelLocal) {
- AddError(std::string(core::ToString(core::Extension::kChromiumExperimentalPixelLocal)) +
- " requires TINT_ENABLE_PIXEL_LOCAL_EXTENSION",
- enable->source);
- return false;
- }
-#endif
}
return true;
}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl
new file mode 100644
index 0000000..f9fbbad
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl
@@ -0,0 +1,14 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..63afc81
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..63afc81
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.glsl
new file mode 100644
index 0000000..2b71f5c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.glsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.msl
new file mode 100644
index 0000000..50d6a5b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.msl
@@ -0,0 +1,38 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + tint_ftou(pos[0]));
+}
+
+void f_inner_1(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ f_inner(pos, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.spvasm
new file mode 100644
index 0000000..0d6260a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.wgsl
new file mode 100644
index 0000000..13cc93c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl
new file mode 100644
index 0000000..d675132
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl
@@ -0,0 +1,14 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += u32(pos.x) + u32(uv.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..5bafbcc
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..5bafbcc
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.glsl
new file mode 100644
index 0000000..a39202c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.glsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.msl
new file mode 100644
index 0000000..45aa35f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.msl
@@ -0,0 +1,42 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 uv [[user(locn0)]];
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(float4 pos, float4 uv, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(pos[0]) + tint_ftou(uv[0])));
+}
+
+void f_inner_1(float4 pos, tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ f_inner(pos, tint_symbol.uv, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.spvasm
new file mode 100644
index 0000000..0c7901e
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.wgsl
new file mode 100644
index 0000000..98e107a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@builtin(position) pos : vec4f, @location(0) uv : vec4f) {
+ P.a += (u32(pos.x) + u32(uv.x));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl
new file mode 100644
index 0000000..a3ecc54
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl
@@ -0,0 +1,18 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0) uv : vec4f,
+}
+
+@fragment fn f(@builtin(position) pos : vec4f, in : In) {
+ P.a += u32(pos.x) + u32(in.uv.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f4c0ede
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(@builtin(position) pos : vec4f, tint_symbol : In) {
+ P.a += (u32(pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f4c0ede
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(@builtin(position) pos : vec4f, tint_symbol : In) {
+ P.a += (u32(pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..4c18e73
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(@builtin(position) pos : vec4f, tint_symbol : In) {
+ P.a += (u32(pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.msl
new file mode 100644
index 0000000..1273933
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.msl
@@ -0,0 +1,47 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 uv [[user(locn0)]];
+};
+
+struct In {
+ float4 uv;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(float4 pos, In in, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(pos[0]) + tint_ftou(in.uv[0])));
+}
+
+void f_inner_1(float4 pos, tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol_2 = {.uv=tint_symbol.uv};
+ f_inner(pos, tint_symbol_2, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..88fb4a1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.spvasm
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(@builtin(position) pos : vec4f, in : In) {
+ P.a += (u32(pos.x) + u32(in.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..c796f85
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_and_location_in_struct.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(@builtin(position) pos : vec4f, in : In) {
+ P.a += (u32(pos.x) + u32(in.uv.x));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl
new file mode 100644
index 0000000..89c5296
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl
@@ -0,0 +1,18 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position) pos : vec4f,
+}
+
+@fragment fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..3193793
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..3193793
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..215cab1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.msl
new file mode 100644
index 0000000..c34efb8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.msl
@@ -0,0 +1,43 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct In {
+ float4 pos;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(In in, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + tint_ftou(in.pos[0]));
+}
+
+void f_inner_1(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol = {.pos=pos};
+ f_inner(tint_symbol, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..14dba3f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.spvasm
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..95b10b5
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl
new file mode 100644
index 0000000..bbd0a13
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl
@@ -0,0 +1,18 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position) pos : vec4f,
+}
+
+@fragment fn f(in : In, @location(0) uv : vec4f) {
+ P.a += u32(in.pos.x) + u32(uv.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..527af3f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.dxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In, @location(0) uv : vec4f) {
+ P.a += (u32(tint_symbol.pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..527af3f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.fxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In, @location(0) uv : vec4f) {
+ P.a += (u32(tint_symbol.pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.glsl
new file mode 100644
index 0000000..101433e
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In, @location(0) uv : vec4f) {
+ P.a += (u32(tint_symbol.pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.msl
new file mode 100644
index 0000000..36509ab
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.msl
@@ -0,0 +1,47 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 uv [[user(locn0)]];
+};
+
+struct In {
+ float4 pos;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(In in, float4 uv, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(in.pos[0]) + tint_ftou(uv[0])));
+}
+
+void f_inner_1(float4 pos, tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol_2 = {.pos=pos};
+ f_inner(tint_symbol_2, tint_symbol.uv, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.spvasm
new file mode 100644
index 0000000..0874362
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.spvasm
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In, @location(0) uv : vec4f) {
+ P.a += (u32(in.pos.x) + u32(uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.wgsl
new file mode 100644
index 0000000..a4dbf65
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In, @location(0) uv : vec4f) {
+ P.a += (u32(in.pos.x) + u32(uv.x));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl
new file mode 100644
index 0000000..b9b9eb9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl
@@ -0,0 +1,19 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position) pos : vec4f,
+ @location(0) uv : vec4f,
+}
+
+@fragment fn f(in : In) {
+ P.a += u32(in.pos.x) + u32(in.uv.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..2f42cc9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..2f42cc9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..7a123de
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.glsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.pos.x) + u32(tint_symbol.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.msl
new file mode 100644
index 0000000..bfabcb6
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.msl
@@ -0,0 +1,48 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 uv [[user(locn0)]];
+};
+
+struct In {
+ float4 pos;
+ float4 uv;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(In in, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(in.pos[0]) + tint_ftou(in.uv[0])));
+}
+
+void f_inner_1(float4 pos, tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol_2 = {.pos=pos, .uv=tint_symbol.uv};
+ f_inner(tint_symbol_2, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..6758d7c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.spvasm
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += (u32(in.pos.x) + u32(in.uv.x));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..7d2ec06
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/builtin_in_struct_and_location_in_struct.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @builtin(position)
+ pos : vec4f,
+ @location(0)
+ uv : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += (u32(in.pos.x) + u32(in.uv.x));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl
new file mode 100644
index 0000000..02916e3
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl
@@ -0,0 +1,14 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..98e76da
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..98e76da
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.glsl
new file mode 100644
index 0000000..7c0b2bb
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.glsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.msl
new file mode 100644
index 0000000..50d6a5b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.msl
@@ -0,0 +1,38 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + tint_ftou(pos[0]));
+}
+
+void f_inner_1(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ f_inner(pos, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.spvasm
new file mode 100644
index 0000000..adce8e5
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.wgsl
new file mode 100644
index 0000000..a32b186
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@invariant @builtin(position) pos : vec4f) {
+ P.a += u32(pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl
new file mode 100644
index 0000000..6c31d00
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl
@@ -0,0 +1,18 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position) pos : vec4f,
+}
+
+@fragment fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..db03744
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..db03744
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..dcb5826
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += u32(tint_symbol.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.msl
new file mode 100644
index 0000000..c34efb8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.msl
@@ -0,0 +1,43 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct In {
+ float4 pos;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(In in, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + tint_ftou(in.pos[0]));
+}
+
+void f_inner_1(float4 pos, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol = {.pos=pos};
+ f_inner(tint_symbol, tint_private_vars);
+}
+
+fragment f_res f(float4 pos [[position]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(pos, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..acf24af
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.spvasm
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..07449a8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/invariant_builtin_in_struct.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @invariant @builtin(position)
+ pos : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += u32(in.pos.x);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl
new file mode 100644
index 0000000..0273ad9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl
@@ -0,0 +1,14 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += u32(a.x) + u32(b.y);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..228feef
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..228feef
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.glsl
new file mode 100644
index 0000000..1b82ec6
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.glsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.msl
new file mode 100644
index 0000000..8061bf4
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.msl
@@ -0,0 +1,43 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 a [[user(locn0)]];
+ float4 b [[user(locn1)]] [[flat]];
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(float4 a, float4 b, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(a[0]) + tint_ftou(b[1])));
+}
+
+void f_inner_1(tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ f_inner(tint_symbol.a, tint_symbol.b, tint_private_vars);
+}
+
+fragment f_res f(tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.spvasm
new file mode 100644
index 0000000..dde84f8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.wgsl
new file mode 100644
index 0000000..9fe91df
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f(@location(0) a : vec4f, @interpolate(flat) @location(1) b : vec4f) {
+ P.a += (u32(a.x) + u32(b.y));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl
new file mode 100644
index 0000000..b9666cc
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl
@@ -0,0 +1,19 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0) a : vec4f,
+ @interpolate(flat) @location(1) b : vec4f,
+}
+
+@fragment fn f(in : In) {
+ P.a += u32(in.a.x) + u32(in.b.y);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..6b2953b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.a.x) + u32(tint_symbol.b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..6b2953b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.a.x) + u32(tint_symbol.b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..c370c80
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.glsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+@fragment
+fn f(tint_symbol : In) {
+ P.a += (u32(tint_symbol.a.x) + u32(tint_symbol.b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.msl
new file mode 100644
index 0000000..faec0aa
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.msl
@@ -0,0 +1,49 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+struct tint_symbol_1 {
+ float4 a [[user(locn0)]];
+ float4 b [[user(locn1)]] [[flat]];
+};
+
+struct In {
+ float4 a;
+ float4 b;
+};
+
+uint tint_ftou(float v) {
+ return select(4294967295u, select(uint(v), 0u, (v < 0.0f)), (v < 4294967040.0f));
+}
+
+void f_inner(In in, thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + (tint_ftou(in.a[0]) + tint_ftou(in.b[1])));
+}
+
+void f_inner_1(tint_symbol_1 tint_symbol, thread tint_private_vars_struct* const tint_private_vars) {
+ In const tint_symbol_2 = {.a=tint_symbol.a, .b=tint_symbol.b};
+ f_inner(tint_symbol_2, tint_private_vars);
+}
+
+fragment f_res f(tint_symbol_1 tint_symbol [[stage_in]], PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner_1(tint_symbol, &(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..70f7310
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.spvasm
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += (u32(in.a.x) + u32(in.b.y));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..3d16f93
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/additional_params/location_in_struct.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct In {
+ @location(0)
+ a : vec4f,
+ @interpolate(flat) @location(1)
+ b : vec4f,
+}
+
+@fragment
+fn f(in : In) {
+ P.a += (u32(in.a.x) + u32(in.b.y));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl
new file mode 100644
index 0000000..e106db5
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl
@@ -0,0 +1,21 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0) x : vec4f,
+ @location(2) y : vec4f,
+ @location(4) z : vec4f,
+}
+
+@fragment fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..5fb3ea9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..5fb3ea9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..c9275ef
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..fb1717d
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,56 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+ float4 output_3 [[color(0)]];
+ float4 output_4 [[color(2)]];
+ float4 output_5 [[color(4)]];
+};
+
+struct tint_symbol {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+struct Out {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+Out f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+ Out const tint_symbol_1 = Out{.x=float4(10.0f), .y=float4(20.0f), .z=float4(30.0f)};
+ return tint_symbol_1;
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ Out const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.x = inner_result.x;
+ wrapper_result.y = inner_result.y;
+ wrapper_result.z = inner_result.z;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c, .output_3=result.x, .output_4=result.y, .output_5=result.z};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..9577480
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..a63e4b9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,24 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl
new file mode 100644
index 0000000..393b271
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl
@@ -0,0 +1,19 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0) x : vec4f,
+ @location(2) y : vec4f,
+ @location(3) z : vec4f,
+}
+
+@fragment fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..21598b3
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..21598b3
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..817125f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..5fc419e
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.msl
@@ -0,0 +1,52 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ float4 output_1 [[color(0)]];
+ float4 output_2 [[color(2)]];
+ float4 output_3 [[color(3)]];
+};
+
+struct tint_symbol {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+struct Out {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+Out f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+ Out const tint_symbol_1 = Out{.x=float4(10.0f), .y=float4(20.0f), .z=float4(30.0f)};
+ return tint_symbol_1;
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ Out const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.x = inner_result.x;
+ wrapper_result.y = inner_result.y;
+ wrapper_result.z = inner_result.z;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=result.x, .output_2=result.y, .output_3=result.z};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..c8a36a3
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..096501a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/multiple_outputs/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,22 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+@fragment
+fn f() -> Out {
+ P.a += 42;
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl
new file mode 100644
index 0000000..62c1c27
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl
@@ -0,0 +1,15 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..45e9e60
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,23 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..45e9e60
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,23 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..865897f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,23 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..c8a44f9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,43 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+ float4 output_3 [[color(0)]];
+};
+
+struct tint_symbol {
+ float4 value;
+};
+
+float4 f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+ return float4(2.0f);
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ float4 const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.value = inner_result;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c, .output_3=result.value};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..5888403
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,23 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..9c9f9f6
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,15 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl
new file mode 100644
index 0000000..4bbbaaa
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl
@@ -0,0 +1,13 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..8d4e6f1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..8d4e6f1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..89096e8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..1300a70
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.msl
@@ -0,0 +1,39 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ float4 output_1 [[color(0)]];
+};
+
+struct tint_symbol {
+ float4 value;
+};
+
+float4 f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+ return float4(2.0f);
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ float4 const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.value = inner_result;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=result.value};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..abc1e39
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..137ee5a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/one_output/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,13 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() -> @location(0) vec4f {
+ P.a += 42;
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl
new file mode 100644
index 0000000..988b86f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl
@@ -0,0 +1,14 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f() {
+ P.a += 42;
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..46fa77f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..46fa77f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..1d5f098
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..b12ffe8
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,30 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+void f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..132062d
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..c424b4b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl
new file mode 100644
index 0000000..b704ddb
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl
@@ -0,0 +1,12 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment fn f() {
+ P.a += 42;
+}
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..26fc6e7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..26fc6e7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..a6316f2
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..f86668b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.msl
@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+};
+
+void f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 42u);
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a};
+}
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..6c4082b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
+
+Failed to generate: extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..56a1697
--- /dev/null
+++ b/test/tint/extensions/pixel_local/entry_point_use/zero_outputs/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,12 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+@fragment
+fn f() {
+ P.a += 42;
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl
new file mode 100644
index 0000000..6087c37
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl
@@ -0,0 +1,35 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0) x : vec4f,
+ @location(2) y : vec4f,
+ @location(4) z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..8d3d555
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..8d3d555
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..ca1b6d7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..30fd975
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,70 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+ float4 output_3 [[color(0)]];
+ float4 output_4 [[color(2)]];
+ float4 output_5 [[color(4)]];
+};
+
+struct tint_symbol {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+struct Out {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+Out f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+ Out const tint_symbol_1 = Out{.x=float4(10.0f), .y=float4(20.0f), .z=float4(30.0f)};
+ return tint_symbol_1;
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ Out const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.x = inner_result.x;
+ wrapper_result.y = inner_result.y;
+ wrapper_result.z = inner_result.z;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c, .output_3=result.x, .output_4=result.y, .output_5=result.z};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..efb9a58
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..d098380
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,38 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(4)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl
new file mode 100644
index 0000000..bccdc57
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl
@@ -0,0 +1,33 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0) x : vec4f,
+ @location(2) y : vec4f,
+ @location(3) z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..217519c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,44 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..217519c
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,44 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..4463a4e
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,44 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..25974dd
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.msl
@@ -0,0 +1,66 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ float4 output_1 [[color(0)]];
+ float4 output_2 [[color(2)]];
+ float4 output_3 [[color(3)]];
+};
+
+struct tint_symbol {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+struct Out {
+ float4 x;
+ float4 y;
+ float4 z;
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+Out f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+ Out const tint_symbol_1 = Out{.x=float4(10.0f), .y=float4(20.0f), .z=float4(30.0f)};
+ return tint_symbol_1;
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ Out const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.x = inner_result.x;
+ wrapper_result.y = inner_result.y;
+ wrapper_result.z = inner_result.z;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=result.x, .output_2=result.y, .output_3=result.z};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..bd27f7a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,44 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..480fb58
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/multiple_outputs/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,36 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+struct Out {
+ @location(0)
+ x : vec4f,
+ @location(2)
+ y : vec4f,
+ @location(3)
+ z : vec4f,
+}
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> Out {
+ f2();
+ return Out(vec4f(10), vec4f(20), vec4f(30));
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl
new file mode 100644
index 0000000..cfc3b25
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl
@@ -0,0 +1,29 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..a32d13d
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..a32d13d
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..31f33e1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..8e356a7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,57 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+ float4 output_3 [[color(0)]];
+};
+
+struct tint_symbol {
+ float4 value;
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+float4 f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+ return float4(2.0f);
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ float4 const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.value = inner_result;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c, .output_3=result.value};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..feb0dc7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..63893e5
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,29 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl
new file mode 100644
index 0000000..fcab73b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl
@@ -0,0 +1,27 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..4b6423a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..4b6423a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..2ed05a1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,35 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..8637100
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.msl
@@ -0,0 +1,53 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ float4 output_1 [[color(0)]];
+};
+
+struct tint_symbol {
+ float4 value;
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+float4 f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+ return float4(2.0f);
+}
+
+tint_symbol f_inner_1(thread tint_private_vars_struct* const tint_private_vars) {
+ float4 const inner_result = f_inner(tint_private_vars);
+ tint_symbol wrapper_result = {};
+ wrapper_result.value = inner_result;
+ return wrapper_result;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ tint_symbol const result = f_inner_1(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=result.value};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..5f1577b
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,35 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..6f8ab7f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/one_output/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,27 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() -> @location(0) vec4f {
+ f2();
+ return vec4f(2);
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl
new file mode 100644
index 0000000..7bc316fe
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl
@@ -0,0 +1,28 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() {
+ f2();
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..961d901
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.dxc.hlsl
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..961d901
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.fxc.hlsl
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.glsl
new file mode 100644
index 0000000..c9fe6f1
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.glsl
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.msl
new file mode 100644
index 0000000..6e843eb
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.msl
@@ -0,0 +1,44 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+ int b [[color(6)]];
+ float c [[color(3)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+ int output_1 [[color(6)]];
+ float output_2 [[color(3)]];
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+void f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a, .output_1=tint_private_vars.P.b, .output_2=tint_private_vars.P.c};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm
new file mode 100644
index 0000000..95c7a59
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.spvasm
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl
new file mode 100644
index 0000000..48882e9
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/multiple_attachments.wgsl.expected.wgsl
@@ -0,0 +1,28 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+ b : i32,
+ c : f32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl
new file mode 100644
index 0000000..44fae7d
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl
@@ -0,0 +1,26 @@
+// flags: --pixel_local_attachments 0=1
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment fn f() {
+ f2();
+}
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..be9ab4f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..be9ab4f
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.glsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.glsl
new file mode 100644
index 0000000..1d46180
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.glsl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.msl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.msl
new file mode 100644
index 0000000..5c5a3a2
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.msl
@@ -0,0 +1,40 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal P;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+};
+
+void f0(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 9u);
+}
+
+void f1(thread tint_private_vars_struct* const tint_private_vars) {
+ f0(tint_private_vars);
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 8u);
+}
+
+void f2(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).P.a = ((*(tint_private_vars)).P.a + 7u);
+ f1(tint_private_vars);
+}
+
+void f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ f2(tint_private_vars);
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.P = pixel_local_1;
+ f_inner(&(tint_private_vars));
+ return {.output_0=tint_private_vars.P.a};
+}
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.spvasm
new file mode 100644
index 0000000..3aaefc3
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.spvasm
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
+
+Failed to generate: extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.wgsl
new file mode 100644
index 0000000..77f85a0
--- /dev/null
+++ b/test/tint/extensions/pixel_local/indirect_use/zero_outputs/single_attachment.wgsl.expected.wgsl
@@ -0,0 +1,26 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> P : PixelLocal;
+
+fn f0() {
+ P.a += 9;
+}
+
+fn f1() {
+ f0();
+ P.a += 8;
+}
+
+fn f2() {
+ P.a += 7;
+ f1();
+}
+
+@fragment
+fn f() {
+ f2();
+}
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl b/test/tint/extensions/pixel_local/ptr/local.wgsl
new file mode 100644
index 0000000..6f66cc7
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl
@@ -0,0 +1,13 @@
+// flags: --pixel_local_attachments 0=1,1=6,2=3
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment fn f() {
+ let p = &V;
+ (*p).a = 42;
+}
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.dxc.hlsl b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f795a17
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.dxc.hlsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment
+fn f() {
+ let p = &(V);
+ (*(p)).a = 42;
+}
+
+Failed to generate: extensions/pixel_local/ptr/local.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.fxc.hlsl b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f795a17
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.fxc.hlsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment
+fn f() {
+ let p = &(V);
+ (*(p)).a = 42;
+}
+
+Failed to generate: extensions/pixel_local/ptr/local.wgsl:2:8 error: HLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.glsl b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.glsl
new file mode 100644
index 0000000..dcca860
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.glsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment
+fn f() {
+ let p = &(V);
+ (*(p)).a = 42;
+}
+
+Failed to generate: extensions/pixel_local/ptr/local.wgsl:2:8 error: GLSL backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.msl b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.msl
new file mode 100644
index 0000000..97a249a
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.msl
@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PixelLocal {
+ uint a [[color(1)]];
+};
+
+struct tint_private_vars_struct {
+ PixelLocal V;
+};
+
+struct f_res {
+ uint output_0 [[color(1)]];
+};
+
+void f_inner(thread tint_private_vars_struct* const tint_private_vars) {
+ (*(tint_private_vars)).V.a = 42u;
+}
+
+fragment f_res f(PixelLocal pixel_local_1) {
+ thread tint_private_vars_struct tint_private_vars = {};
+ tint_private_vars.V = pixel_local_1;
+ f_inner(&(tint_private_vars));
+ return {.output_0=tint_private_vars.V.a};
+}
+
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.spvasm b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.spvasm
new file mode 100644
index 0000000..76d9d07
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.spvasm
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment
+fn f() {
+ let p = &(V);
+ (*(p)).a = 42;
+}
+
+Failed to generate: extensions/pixel_local/ptr/local.wgsl:2:8 error: SPIR-V backend does not support extension 'chromium_experimental_pixel_local'
+enable chromium_experimental_pixel_local;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.wgsl b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.wgsl
new file mode 100644
index 0000000..66c3329
--- /dev/null
+++ b/test/tint/extensions/pixel_local/ptr/local.wgsl.expected.wgsl
@@ -0,0 +1,13 @@
+enable chromium_experimental_pixel_local;
+
+struct PixelLocal {
+ a : u32,
+}
+
+var<pixel_local> V : PixelLocal;
+
+@fragment
+fn f() {
+ let p = &(V);
+ (*(p)).a = 42;
+}