tint/transform: Implement div / mod polyfill

Prevents UB for divide-by-zero and integer overflow when dividing

Fixed: tint:1349
Change-Id: Ieef66d27d7aec3011628ced076b2bccc7770a8af
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/108925
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2022-11-09 22:04:11 +00:00 committed by Dawn LUCI CQ
parent 9418152d08
commit 46ee63933c
427 changed files with 7255 additions and 3789 deletions

View File

@ -124,6 +124,9 @@ struct Number : NumberBase<Number<T>> {
/// type is the underlying type of the Number /// type is the underlying type of the Number
using type = T; using type = T;
/// Number of bits in the number.
static constexpr size_t kNumBits = sizeof(T) * 8;
/// Highest finite representable value of this type. /// Highest finite representable value of this type.
static constexpr type kHighestValue = std::numeric_limits<type>::max(); static constexpr type kHighestValue = std::numeric_limits<type>::max();
@ -187,6 +190,9 @@ struct Number<detail::NumberKindF16> : NumberBase<Number<detail::NumberKindF16>>
/// C++ does not have a native float16 type, so we use a 32-bit float instead. /// C++ does not have a native float16 type, so we use a 32-bit float instead.
using type = float; using type = float;
/// Number of bits in the number.
static constexpr size_t kNumBits = 16;
/// Highest finite representable value of this type. /// Highest finite representable value of this type.
static constexpr type kHighestValue = 65504.0f; // 2¹⁵ × (1 + 1023/1024) static constexpr type kHighestValue = 65504.0f; // 2¹⁵ × (1 + 1023/1024)

View File

@ -3267,6 +3267,14 @@ class ProgramBuilder {
//! @cond Doxygen_Suppress //! @cond Doxygen_Suppress
// Various template specializations for ProgramBuilder::TypesBuilder::CToAST. // Various template specializations for ProgramBuilder::TypesBuilder::CToAST.
template <> template <>
struct ProgramBuilder::TypesBuilder::CToAST<AInt> {
static const ast::Type* get(const ProgramBuilder::TypesBuilder*) { return nullptr; }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<AFloat> {
static const ast::Type* get(const ProgramBuilder::TypesBuilder*) { return nullptr; }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<i32> { struct ProgramBuilder::TypesBuilder::CToAST<i32> {
static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->i32(); } static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->i32(); }
}; };

View File

@ -14,6 +14,8 @@
#include "src/tint/transform/builtin_polyfill.h" #include "src/tint/transform/builtin_polyfill.h"
#include <algorithm>
#include <tuple>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
@ -29,6 +31,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::transform::BuiltinPolyfill::Config);
namespace tint::transform { namespace tint::transform {
/// BinaryOpSignature is tuple of a binary op, LHS type and RHS type
using BinaryOpSignature = std::tuple<ast::BinaryOp, const sem::Type*, const sem::Type*>;
/// PIMPL state for the transform /// PIMPL state for the transform
struct BuiltinPolyfill::State { struct BuiltinPolyfill::State {
/// Constructor /// Constructor
@ -36,15 +41,6 @@ struct BuiltinPolyfill::State {
/// @param p the builtins to polyfill /// @param p the builtins to polyfill
State(CloneContext& c, Builtins p) : ctx(c), polyfill(p) {} State(CloneContext& c, Builtins p) : ctx(c), polyfill(p) {}
/// The clone context
CloneContext& ctx;
/// The builtins to polyfill
Builtins polyfill;
/// The destination program builder
ProgramBuilder& b = *ctx.dst;
/// The source clone context
const sem::Info& sem = ctx.src->Sem();
/// Builds the polyfill function for the `acosh` builtin /// Builds the polyfill function for the `acosh` builtin
/// @param ty the parameter and return type for the function /// @param ty the parameter and return type for the function
/// @return the polyfill function name /// @return the polyfill function name
@ -563,6 +559,63 @@ struct BuiltinPolyfill::State {
return name; return name;
} }
/// Builds the polyfill function for a divide or modulo operator with integer scalar or vector
/// operands.
/// @param sig the signature of the binary operator
/// @return the polyfill function name
Symbol int_div_mod(const BinaryOpSignature& sig) {
const auto op = std::get<0>(sig);
const auto* lhs_ty = std::get<1>(sig);
const auto* rhs_ty = std::get<2>(sig);
const bool is_div = op == ast::BinaryOp::kDivide;
uint32_t lhs_width = 1;
uint32_t rhs_width = 1;
const auto* lhs_el_ty = sem::Type::ElementOf(lhs_ty, &lhs_width);
const auto* rhs_el_ty = sem::Type::ElementOf(rhs_ty, &rhs_width);
const uint32_t width = std::max(lhs_width, rhs_width);
const char* lhs = "lhs";
const char* rhs = "rhs";
utils::Vector<const ast::Statement*, 4> body;
if (lhs_width < width) {
// lhs is scalar, rhs is vector. Convert lhs to vector.
body.Push(b.Decl(b.Let("l", b.vec(T(lhs_el_ty), width, b.Expr(lhs)))));
lhs = "l";
}
if (rhs_width < width) {
// lhs is vector, rhs is scalar. Convert rhs to vector.
body.Push(b.Decl(b.Let("r", b.vec(T(rhs_el_ty), width, b.Expr(rhs)))));
rhs = "r";
}
auto name = b.Symbols().New(is_div ? "tint_div" : "tint_mod");
auto* use_one = b.Equal(rhs, ScalarOrVector(width, 0_a));
if (lhs_ty->is_signed_scalar_or_vector()) {
const auto bits = lhs_el_ty->Size() * 8;
auto min_int = AInt(AInt::kLowestValue >> (AInt::kNumBits - bits));
const ast::Expression* lhs_is_min = b.Equal(lhs, ScalarOrVector(width, min_int));
const ast::Expression* rhs_is_minus_one = b.Equal(rhs, ScalarOrVector(width, -1_a));
// use_one = use_one | ((lhs == MIN_INT) & (rhs == -1))
use_one = b.Or(use_one, b.And(lhs_is_min, rhs_is_minus_one));
}
auto* select = b.Call("select", rhs, ScalarOrVector(width, 1_a), use_one);
body.Push(b.Return(is_div ? b.Div(lhs, select) : b.Mod(lhs, select)));
b.Func(name,
utils::Vector{
b.Param("lhs", T(lhs_ty)),
b.Param("rhs", T(rhs_ty)),
},
width == 1 ? T(lhs_ty) : b.ty.vec(T(lhs_el_ty), width), // return type
std::move(body));
return name;
}
/// Builds the polyfill function for the `saturate` builtin /// Builds the polyfill function for the `saturate` builtin
/// @param ty the parameter and return type for the function /// @param ty the parameter and return type for the function
/// @return the polyfill function name /// @return the polyfill function name
@ -625,6 +678,15 @@ struct BuiltinPolyfill::State {
} }
private: private:
/// The clone context
CloneContext& ctx;
/// The builtins to polyfill
Builtins polyfill;
/// The destination program builder
ProgramBuilder& b = *ctx.dst;
/// The source clone context
const sem::Info& sem = ctx.src->Sem();
/// @returns the AST type for the given sem type /// @returns the AST type for the given sem type
const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); } const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); }
@ -659,13 +721,14 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
return SkipTransform; return SkipTransform;
} }
auto& builtins = cfg->builtins; auto& polyfill = cfg->builtins;
utils::Hashmap<const sem::Builtin*, Symbol, 8> builtin_polyfills; utils::Hashmap<const sem::Builtin*, Symbol, 8> builtin_polyfills;
utils::Hashmap<BinaryOpSignature, Symbol, 8> binary_op_polyfills;
ProgramBuilder b; ProgramBuilder b;
CloneContext ctx{&b, src, /* auto_clone_symbols */ true}; CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
State s{ctx, builtins}; State s{ctx, polyfill};
bool made_changes = false; bool made_changes = false;
for (auto* node : src->ASTNodes().Objects()) { for (auto* node : src->ASTNodes().Objects()) {
@ -679,84 +742,84 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
if (!builtin) { if (!builtin) {
continue; continue;
} }
Symbol polyfill; Symbol fn;
switch (builtin->Type()) { switch (builtin->Type()) {
case sem::BuiltinType::kAcosh: case sem::BuiltinType::kAcosh:
if (builtins.acosh != Level::kNone) { if (polyfill.acosh != Level::kNone) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.acosh(builtin->ReturnType()); }); builtin, [&] { return s.acosh(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kAsinh: case sem::BuiltinType::kAsinh:
if (builtins.asinh) { if (polyfill.asinh) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.asinh(builtin->ReturnType()); }); builtin, [&] { return s.asinh(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kAtanh: case sem::BuiltinType::kAtanh:
if (builtins.atanh != Level::kNone) { if (polyfill.atanh != Level::kNone) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.atanh(builtin->ReturnType()); }); builtin, [&] { return s.atanh(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kClamp: case sem::BuiltinType::kClamp:
if (builtins.clamp_int) { if (polyfill.clamp_int) {
auto& sig = builtin->Signature(); auto& sig = builtin->Signature();
if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) { if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.clampInteger(builtin->ReturnType()); }); builtin, [&] { return s.clampInteger(builtin->ReturnType()); });
} }
} }
break; break;
case sem::BuiltinType::kCountLeadingZeros: case sem::BuiltinType::kCountLeadingZeros:
if (builtins.count_leading_zeros) { if (polyfill.count_leading_zeros) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.countLeadingZeros(builtin->ReturnType()); }); builtin, [&] { return s.countLeadingZeros(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kCountTrailingZeros: case sem::BuiltinType::kCountTrailingZeros:
if (builtins.count_trailing_zeros) { if (polyfill.count_trailing_zeros) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.countTrailingZeros(builtin->ReturnType()); }); builtin, [&] { return s.countTrailingZeros(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kExtractBits: case sem::BuiltinType::kExtractBits:
if (builtins.extract_bits != Level::kNone) { if (polyfill.extract_bits != Level::kNone) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.extractBits(builtin->ReturnType()); }); builtin, [&] { return s.extractBits(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kFirstLeadingBit: case sem::BuiltinType::kFirstLeadingBit:
if (builtins.first_leading_bit) { if (polyfill.first_leading_bit) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); }); builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kFirstTrailingBit: case sem::BuiltinType::kFirstTrailingBit:
if (builtins.first_trailing_bit) { if (polyfill.first_trailing_bit) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); }); builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kInsertBits: case sem::BuiltinType::kInsertBits:
if (builtins.insert_bits != Level::kNone) { if (polyfill.insert_bits != Level::kNone) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.insertBits(builtin->ReturnType()); }); builtin, [&] { return s.insertBits(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kSaturate: case sem::BuiltinType::kSaturate:
if (builtins.saturate) { if (polyfill.saturate) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.saturate(builtin->ReturnType()); }); builtin, [&] { return s.saturate(builtin->ReturnType()); });
} }
break; break;
case sem::BuiltinType::kTextureSampleBaseClampToEdge: case sem::BuiltinType::kTextureSampleBaseClampToEdge:
if (builtins.texture_sample_base_clamp_to_edge_2d_f32) { if (polyfill.texture_sample_base_clamp_to_edge_2d_f32) {
auto& sig = builtin->Signature(); auto& sig = builtin->Signature();
auto* tex = sig.Parameter(sem::ParameterUsage::kTexture); auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
if (auto* stex = tex->Type()->As<sem::SampledTexture>()) { if (auto* stex = tex->Type()->As<sem::SampledTexture>()) {
if (stex->type()->Is<sem::F32>()) { if (stex->type()->Is<sem::F32>()) {
polyfill = builtin_polyfills.GetOrCreate(builtin, [&] { fn = builtin_polyfills.GetOrCreate(builtin, [&] {
return s.textureSampleBaseClampToEdge_2d_f32(); return s.textureSampleBaseClampToEdge_2d_f32();
}); });
} }
@ -764,9 +827,9 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
} }
break; break;
case sem::BuiltinType::kQuantizeToF16: case sem::BuiltinType::kQuantizeToF16:
if (builtins.quantize_to_vec_f16) { if (polyfill.quantize_to_vec_f16) {
if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) { if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
polyfill = builtin_polyfills.GetOrCreate( fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.quantizeToF16(vec); }); builtin, [&] { return s.quantizeToF16(vec); });
} }
} }
@ -776,16 +839,16 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
break; break;
} }
if (polyfill.IsValid()) { if (fn.IsValid()) {
auto* replacement = s.b.Call(polyfill, ctx.Clone(call->Declaration()->args)); auto* replacement = b.Call(fn, ctx.Clone(call->Declaration()->args));
ctx.Replace(call->Declaration(), replacement); ctx.Replace(call->Declaration(), replacement);
made_changes = true; made_changes = true;
} }
} else if (auto* bin_op = node->As<ast::BinaryExpression>()) { } else if (auto* bin_op = node->As<ast::BinaryExpression>()) {
switch (bin_op->op) { switch (bin_op->op) {
case ast::BinaryOp::kShiftLeft: case ast::BinaryOp::kShiftLeft:
case ast::BinaryOp::kShiftRight: case ast::BinaryOp::kShiftRight: {
if (builtins.bitshift_modulo) { if (polyfill.bitshift_modulo) {
auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef(); auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef(); auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef();
auto* lhs_el_ty = sem::Type::DeepestElementOf(lhs_ty); auto* lhs_el_ty = sem::Type::DeepestElementOf(lhs_ty);
@ -798,6 +861,24 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
made_changes = true; made_changes = true;
} }
break; break;
}
case ast::BinaryOp::kDivide:
case ast::BinaryOp::kModulo: {
if (polyfill.int_div_mod) {
auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
if (lhs_ty->is_integer_scalar_or_vector()) {
auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef();
BinaryOpSignature sig{bin_op->op, lhs_ty, rhs_ty};
auto fn = binary_op_polyfills.GetOrCreate(
sig, [&] { return s.int_div_mod(sig); });
auto* lhs = ctx.Clone(bin_op->lhs);
auto* rhs = ctx.Clone(bin_op->rhs);
ctx.Replace(bin_op, b.Call(fn, lhs, rhs));
made_changes = true;
}
}
break;
}
default: default:
break; break;
} }

View File

@ -63,6 +63,9 @@ class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
bool first_trailing_bit = false; bool first_trailing_bit = false;
/// Should `insertBits()` be polyfilled? /// Should `insertBits()` be polyfilled?
Level insert_bits = Level::kNone; Level insert_bits = Level::kNone;
/// Should integer scalar / vector divides and modulos be polyfilled to avoid DBZ and
/// integer overflows?
bool int_div_mod = false;
/// Should `saturate()` be polyfilled? /// Should `saturate()` be polyfilled?
bool saturate = false; bool saturate = false;
/// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d<f32> textures? /// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d<f32> textures?

View File

@ -1920,6 +1920,775 @@ fn f() {
EXPECT_EQ(expect, str(got)); EXPECT_EQ(expect, str(got));
} }
////////////////////////////////////////////////////////////////////////////////
// int_div_mod
////////////////////////////////////////////////////////////////////////////////
DataMap polyfillIntDivMod() {
BuiltinPolyfill::Builtins builtins;
builtins.int_div_mod = true;
DataMap data;
data.Add<BuiltinPolyfill::Config>(builtins);
return data;
}
TEST_F(BuiltinPolyfillTest, ShouldRunIntDiv) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i / v;
}
)";
EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillIntDivMod()));
}
TEST_F(BuiltinPolyfillTest, ShouldRunIntMod) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i % v;
}
)";
EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillIntDivMod()));
}
TEST_F(BuiltinPolyfillTest, IntDiv_ai_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20 / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : i32, rhs : i32) -> i32 {
return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_div(20, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_ai_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20 % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : i32, rhs : i32) -> i32 {
return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_mod(20, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_i32_ai) {
auto* src = R"(
fn f() {
let v = 10i;
let x = v / 20;
}
)";
auto* expect = R"(
fn tint_div(lhs : i32, rhs : i32) -> i32 {
return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_div(v, 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_i32_ai) {
auto* src = R"(
fn f() {
let v = 10i;
let x = v % 20;
}
)";
auto* expect = R"(
fn tint_mod(lhs : i32, rhs : i32) -> i32 {
return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_mod(v, 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_i32_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : i32, rhs : i32) -> i32 {
return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_div(20i, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_i32_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : i32, rhs : i32) -> i32 {
return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))));
}
fn f() {
let v = 10i;
let x = tint_mod(20i, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_ai_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20 / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : u32, rhs : u32) -> u32 {
return (lhs / select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_div(20, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_ai_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20 % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : u32, rhs : u32) -> u32 {
return (lhs % select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_mod(20, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_u32_ai) {
auto* src = R"(
fn f() {
let v = 10u;
let x = v / 20;
}
)";
auto* expect = R"(
fn tint_div(lhs : u32, rhs : u32) -> u32 {
return (lhs / select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_div(v, 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_u32_ai) {
auto* src = R"(
fn f() {
let v = 10u;
let x = v % 20;
}
)";
auto* expect = R"(
fn tint_mod(lhs : u32, rhs : u32) -> u32 {
return (lhs % select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_mod(v, 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_u32_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20u / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : u32, rhs : u32) -> u32 {
return (lhs / select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_div(20u, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_u32_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20u % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : u32, rhs : u32) -> u32 {
return (lhs % select(rhs, 1, (rhs == 0)));
}
fn f() {
let v = 10u;
let x = tint_mod(20u, v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_ai_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3(20) / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(vec3(20), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_ai_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3(20) % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(vec3(20), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_ai) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3(v) / 20;
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(vec3(v), 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_ai) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3(v) % 20;
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(vec3(v), 20);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3<i32>(20i) / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(vec3<i32>(20i), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3<i32>(20i) % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<i32>, rhs : i32) -> vec3<i32> {
let r = vec3<i32>(rhs);
return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(vec3<i32>(20i), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_u32_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = vec3<u32>(20u) / v;
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<u32>, rhs : u32) -> vec3<u32> {
let r = vec3<u32>(rhs);
return (lhs / select(r, vec3(1), (r == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_div(vec3<u32>(20u), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_u32_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = vec3<u32>(20u) % v;
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<u32>, rhs : u32) -> vec3<u32> {
let r = vec3<u32>(rhs);
return (lhs % select(r, vec3(1), (r == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_mod(vec3<u32>(20u), v);
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_ai_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20 / vec3(v);
}
)";
auto* expect = R"(
fn tint_div(lhs : i32, rhs : vec3<i32>) -> vec3<i32> {
let l = vec3<i32>(lhs);
return (l / select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(20, vec3(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_ai_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20 % vec3(v);
}
)";
auto* expect = R"(
fn tint_mod(lhs : i32, rhs : vec3<i32>) -> vec3<i32> {
let l = vec3<i32>(lhs);
return (l % select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(20, vec3(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_i32_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i / vec3<i32>(v);
}
)";
auto* expect = R"(
fn tint_div(lhs : i32, rhs : vec3<i32>) -> vec3<i32> {
let l = vec3<i32>(lhs);
return (l / select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(20i, vec3<i32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_i32_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = 20i % vec3<i32>(v);
}
)";
auto* expect = R"(
fn tint_mod(lhs : i32, rhs : vec3<i32>) -> vec3<i32> {
let l = vec3<i32>(lhs);
return (l % select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(20i, vec3<i32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_u32_vec3_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20u / vec3<u32>(v);
}
)";
auto* expect = R"(
fn tint_div(lhs : u32, rhs : vec3<u32>) -> vec3<u32> {
let l = vec3<u32>(lhs);
return (l / select(rhs, vec3(1), (rhs == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_div(20u, vec3<u32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_u32_vec3_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = 20u % vec3<u32>(v);
}
)";
auto* expect = R"(
fn tint_mod(lhs : u32, rhs : vec3<u32>) -> vec3<u32> {
let l = vec3<u32>(lhs);
return (l % select(rhs, vec3(1), (rhs == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_mod(20u, vec3<u32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3<i32>(20i) / vec3<i32>(v);
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<i32>, rhs : vec3<i32>) -> vec3<i32> {
return (lhs / select(rhs, vec3(1), ((rhs == vec3(0)) | ((lhs == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_div(vec3<i32>(20i), vec3<i32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_vec3_i32) {
auto* src = R"(
fn f() {
let v = 10i;
let x = vec3<i32>(20i) % vec3<i32>(v);
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<i32>, rhs : vec3<i32>) -> vec3<i32> {
return (lhs % select(rhs, vec3(1), ((rhs == vec3(0)) | ((lhs == vec3(-2147483648)) & (rhs == vec3(-1))))));
}
fn f() {
let v = 10i;
let x = tint_mod(vec3<i32>(20i), vec3<i32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntDiv_vec3_u32_vec3_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = vec3<u32>(20u) / vec3<u32>(v);
}
)";
auto* expect = R"(
fn tint_div(lhs : vec3<u32>, rhs : vec3<u32>) -> vec3<u32> {
return (lhs / select(rhs, vec3(1), (rhs == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_div(vec3<u32>(20u), vec3<u32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
TEST_F(BuiltinPolyfillTest, IntMod_vec3_u32_vec3_u32) {
auto* src = R"(
fn f() {
let v = 10u;
let x = vec3<u32>(20u) % vec3<u32>(v);
}
)";
auto* expect = R"(
fn tint_mod(lhs : vec3<u32>, rhs : vec3<u32>) -> vec3<u32> {
return (lhs % select(rhs, vec3(1), (rhs == vec3(0))));
}
fn f() {
let v = 10u;
let x = tint_mod(vec3<u32>(20u), vec3<u32>(v));
}
)";
auto got = Run<BuiltinPolyfill>(src, polyfillIntDivMod());
EXPECT_EQ(expect, str(got));
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// saturate // saturate
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -182,6 +182,9 @@ SanitizedResult Sanitize(const Program* in,
manager.Add<transform::DisableUniformityAnalysis>(); manager.Add<transform::DisableUniformityAnalysis>();
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
{ // Builtin polyfills { // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills; transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
@ -193,6 +196,7 @@ SanitizedResult Sanitize(const Program* in,
polyfills.first_leading_bit = true; polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true; polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.int_div_mod = true;
polyfills.saturate = true; polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
@ -214,7 +218,6 @@ SanitizedResult Sanitize(const Program* in,
manager.Add<transform::ZeroInitWorkgroupMemory>(); manager.Add<transform::ZeroInitWorkgroupMemory>();
} }
manager.Add<transform::CanonicalizeEntryPointIO>(); manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>(); manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::PadStructs>(); manager.Add<transform::PadStructs>();

View File

@ -157,6 +157,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::DisableUniformityAnalysis>(); manager.Add<transform::DisableUniformityAnalysis>();
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
{ // Builtin polyfills { // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills; transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kFull; polyfills.acosh = transform::BuiltinPolyfill::Level::kFull;
@ -172,6 +175,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.first_leading_bit = true; polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true; polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull;
polyfills.int_div_mod = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
@ -211,7 +215,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
// assumes that num_workgroups builtins only appear as struct members and are // assumes that num_workgroups builtins only appear as struct members and are
// only accessed directly via member accessors. // only accessed directly via member accessors.
manager.Add<transform::NumWorkgroupsFromUniform>(); manager.Add<transform::NumWorkgroupsFromUniform>();
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>(); manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::VectorizeScalarMatrixInitializers>(); manager.Add<transform::VectorizeScalarMatrixInitializers>();
manager.Add<transform::SimplifyPointers>(); manager.Add<transform::SimplifyPointers>();
@ -661,117 +664,6 @@ bool GeneratorImpl::EmitAssign(const ast::AssignmentStatement* stmt) {
return true; return true;
} }
bool GeneratorImpl::EmitExpressionOrOneIfZero(std::ostream& out, const ast::Expression* expr) {
// For constants, replace literal 0 with 1.
if (const auto* val = builder_.Sem().Get(expr)->ConstantValue()) {
if (!val->AnyZero()) {
return EmitExpression(out, expr);
}
auto* ty = val->Type();
if (ty->IsAnyOf<sem::I32, sem::U32>()) {
return EmitValue(out, ty, 1);
}
if (auto* vec = ty->As<sem::Vector>()) {
auto* elem_ty = vec->type();
if (!EmitType(out, ty, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
return false;
}
out << "(";
for (size_t i = 0; i < vec->Width(); ++i) {
if (i != 0) {
out << ", ";
}
auto s = val->Index(i)->As<AInt>();
if (!EmitValue(out, elem_ty, (s == 0) ? 1 : static_cast<int>(s))) {
return false;
}
}
out << ")";
return true;
}
TINT_ICE(Writer, diagnostics_)
<< "EmitExpressionOrOneIfZero expects integer scalar or vector";
return false;
}
auto* ty = TypeOf(expr)->UnwrapRef();
// For non-constants, we need to emit runtime code to check if the value is 0,
// and return 1 in that case.
std::string zero;
{
std::ostringstream ss;
EmitValue(ss, ty, 0);
zero = ss.str();
}
std::string one;
{
std::ostringstream ss;
EmitValue(ss, ty, 1);
one = ss.str();
}
// For identifiers, no need for a function call as it's fine to evaluate
// `expr` more than once.
if (expr->Is<ast::IdentifierExpression>()) {
out << "(";
if (!EmitExpression(out, expr)) {
return false;
}
out << " == " << zero << " ? " << one << " : ";
if (!EmitExpression(out, expr)) {
return false;
}
out << ")";
return true;
}
// For non-identifier expressions, call a function to make sure `expr` is only
// evaluated once.
auto name = utils::GetOrCreate(value_or_one_if_zero_, ty, [&]() -> std::string {
// Example:
// int4 tint_value_or_one_if_zero_int4(int4 value) {
// return value == 0 ? 0 : value;
// }
std::string ty_name;
{
std::ostringstream ss;
if (!EmitType(ss, ty, tint::ast::AddressSpace::kUndefined, ast::Access::kUndefined,
"")) {
return "";
}
ty_name = ss.str();
}
std::string fn = UniqueIdentifier("value_or_one_if_zero_" + ty_name);
line(&helpers_) << ty_name << " " << fn << "(" << ty_name << " value) {";
{
ScopedIndent si(&helpers_);
line(&helpers_) << "return value == " << zero << " ? " << one << " : value;";
}
line(&helpers_) << "}";
line(&helpers_);
return fn;
});
if (name.empty()) {
return false;
}
out << name << "(";
if (!EmitExpression(out, expr)) {
return false;
}
out << ")";
return true;
}
bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* expr) { bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* expr) {
if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) { if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) {
auto name = UniqueIdentifier(kTempNamePrefix); auto name = UniqueIdentifier(kTempNamePrefix);
@ -892,21 +784,9 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* e
break; break;
case ast::BinaryOp::kDivide: case ast::BinaryOp::kDivide:
out << "/"; out << "/";
// BUG(crbug.com/tint/1083): Integer divide/modulo by zero is a FXC
// compile error, and undefined behavior in WGSL.
if (TypeOf(expr->rhs)->UnwrapRef()->is_integer_scalar_or_vector()) {
out << " ";
return EmitExpressionOrOneIfZero(out, expr->rhs);
}
break; break;
case ast::BinaryOp::kModulo: case ast::BinaryOp::kModulo:
out << "%"; out << "%";
// BUG(crbug.com/tint/1083): Integer divide/modulo by zero is a FXC
// compile error, and undefined behavior in WGSL.
if (TypeOf(expr->rhs)->UnwrapRef()->is_integer_scalar_or_vector()) {
out << " ";
return EmitExpressionOrOneIfZero(out, expr->rhs);
}
break; break;
case ast::BinaryOp::kNone: case ast::BinaryOp::kNone:
diagnostics_.add_error(diag::System::Writer, "missing binary operation type"); diagnostics_.add_error(diag::System::Writer, "missing binary operation type");

View File

@ -93,12 +93,6 @@ class GeneratorImpl : public TextGenerator {
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully /// @returns true if the statement was emitted successfully
bool EmitAssign(const ast::AssignmentStatement* stmt); bool EmitAssign(const ast::AssignmentStatement* stmt);
/// Emits code such that if `expr` is zero, it emits one, else `expr`.
/// Used to avoid divide-by-zeros by substituting constant zeros with ones.
/// @param out the output of the expression stream
/// @param expr the expression
/// @returns true if the expression was emitted, false otherwise
bool EmitExpressionOrOneIfZero(std::ostream& out, const ast::Expression* expr);
/// Handles generating a binary expression /// Handles generating a binary expression
/// @param out the output of the expression stream /// @param out the output of the expression stream
/// @param expr the binary expression /// @param expr the binary expression

View File

@ -653,295 +653,5 @@ foo((tint_tmp), (tint_tmp_1), (tint_tmp_2));
)"); )");
} }
namespace HlslGeneratorDivMod {
struct Params {
enum class Type { Div, Mod };
Type type;
};
struct HlslGeneratorDivModTest : TestParamHelper<Params> {
std::string Token() { return GetParam().type == Params::Type::Div ? "/" : "%"; }
template <typename... Args>
auto Op(Args... args) {
return GetParam().type == Params::Type::Div ? Div(std::forward<Args>(args)...)
: Mod(std::forward<Args>(args)...);
}
};
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest,
HlslGeneratorDivModTest,
testing::Values(Params{Params::Type::Div}, Params{Params::Type::Mod}));
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_i32) {
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", Op("a", 0_i))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn() {
int a = 0;
const int r = (a )" + Token() +
R"( 1);
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_u32) {
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", Op("a", 0_u))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn() {
uint a = 0u;
const uint r = (a )" + Token() +
R"( 1u);
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_vec_i32) {
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", vec4<i32>(100_i, 100_i, 100_i, 100_i))),
Decl(Let("r", Op("a", vec4<i32>(50_i, 0_i, 25_i, 0_i)))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn() {
int4 a = (100).xxxx;
const int4 r = (a )" + Token() +
R"( int4(50, 1, 25, 1));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_scalar_i32) {
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", vec4<i32>(100_i, 100_i, 100_i, 100_i))),
Decl(Let("r", Op("a", 0_i))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn() {
int4 a = (100).xxxx;
const int4 r = (a )" + Token() +
R"( 1);
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_i32) {
Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(),
utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", Op("a", "b"))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn(int b) {
int a = 0;
const int r = (a )" + Token() +
R"( (b == 0 ? 1 : b));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_u32) {
Func("fn", utils::Vector{Param("b", ty.u32())}, ty.void_(),
utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", Op("a", "b"))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn(uint b) {
uint a = 0u;
const uint r = (a )" + Token() +
R"( (b == 0u ? 1u : b));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_vec_i32) {
Func("fn", utils::Vector{Param("b", ty.vec3<i32>())}, ty.void_(),
utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", Op("a", "b"))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn(int3 b) {
int3 a = int3(0, 0, 0);
const int3 r = (a )" + Token() +
R"( (b == int3(0, 0, 0) ? int3(1, 1, 1) : b));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_scalar_i32) {
Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(),
utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", Op("a", "b"))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(void fn(int b) {
int3 a = int3(0, 0, 0);
const int3 r = (a )" + Token() +
R"( (b == 0 ? 1 : b));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_i32) {
Func("zero", utils::Empty, ty.i32(),
utils::Vector{
Return(Expr(0_i)),
});
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", Op("a", Call("zero")))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(int value_or_one_if_zero_int(int value) {
return value == 0 ? 1 : value;
}
int zero() {
return 0;
}
void fn() {
int a = 0;
const int r = (a )" + Token() +
R"( value_or_one_if_zero_int(zero()));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_u32) {
Func("zero", utils::Empty, ty.u32(),
utils::Vector{
Return(Expr(0_u)),
});
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", Op("a", Call("zero")))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(uint value_or_one_if_zero_uint(uint value) {
return value == 0u ? 1u : value;
}
uint zero() {
return 0u;
}
void fn() {
uint a = 0u;
const uint r = (a )" + Token() +
R"( value_or_one_if_zero_uint(zero()));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_vec_i32) {
Func("zero", utils::Empty, ty.vec3<i32>(),
utils::Vector{
Return(vec3<i32>(0_i, 0_i, 0_i)),
});
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", Op("a", Call("zero")))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(int3 value_or_one_if_zero_int3(int3 value) {
return value == int3(0, 0, 0) ? int3(1, 1, 1) : value;
}
int3 zero() {
return (0).xxx;
}
void fn() {
int3 a = int3(0, 0, 0);
const int3 r = (a )" + Token() +
R"( value_or_one_if_zero_int3(zero()));
}
)");
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_scalar_i32) {
Func("zero", utils::Empty, ty.i32(),
utils::Vector{
Return(0_i),
});
Func("fn", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", Op("a", Call("zero")))),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(), R"(int value_or_one_if_zero_int(int value) {
return value == 0 ? 1 : value;
}
int zero() {
return 0;
}
void fn() {
int3 a = int3(0, 0, 0);
const int3 r = (a )" + Token() +
R"( value_or_one_if_zero_int(zero()));
}
)");
}
} // namespace HlslGeneratorDivMod
} // namespace } // namespace
} // namespace tint::writer::hlsl } // namespace tint::writer::hlsl

View File

@ -167,6 +167,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::DisableUniformityAnalysis>(); manager.Add<transform::DisableUniformityAnalysis>();
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
{ // Builtin polyfills { // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills; transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
@ -177,6 +180,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.first_leading_bit = true; polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true; polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.int_div_mod = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
@ -224,7 +228,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::ZeroInitWorkgroupMemory>(); manager.Add<transform::ZeroInitWorkgroupMemory>();
} }
manager.Add<transform::CanonicalizeEntryPointIO>(); manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>(); manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::PromoteInitializersToLet>(); manager.Add<transform::PromoteInitializersToLet>();

View File

@ -48,6 +48,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::DisableUniformityAnalysis>(); manager.Add<transform::DisableUniformityAnalysis>();
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
{ // Builtin polyfills { // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills; transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
@ -60,6 +63,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.first_leading_bit = true; polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true; polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.int_div_mod = true;
polyfills.saturate = true; polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741 polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741
@ -80,7 +84,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::ZeroInitWorkgroupMemory>(); manager.Add<transform::ZeroInitWorkgroupMemory>();
} }
manager.Add<transform::RemoveUnreachableStatements>(); manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>(); manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength() manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
manager.Add<transform::RemovePhonies>(); manager.Add<transform::RemovePhonies>();

View File

@ -1,5 +1,9 @@
uint value_or_one_if_zero_uint(uint value) { uint tint_div(uint lhs, uint rhs) {
return value == 0u ? 1u : value; return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
} }
void marg8uintin() { void marg8uintin() {
@ -32,9 +36,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex4D(uint gridSize, uint index) { uint3 toIndex4D(uint gridSize, uint index) {
uint z_1 = (gridSize / value_or_one_if_zero_uint((index * index))); uint z_1 = tint_div(gridSize, (index * index));
uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); uint x_1 = tint_mod(index, gridSize);
return uint3(z_1, y_1, y_1); return uint3(z_1, y_1, y_1);
} }

View File

@ -1,5 +1,9 @@
uint value_or_one_if_zero_uint(uint value) { uint tint_div(uint lhs, uint rhs) {
return value == 0u ? 1u : value; return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
} }
void marg8uintin() { void marg8uintin() {
@ -32,9 +36,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex4D(uint gridSize, uint index) { uint3 toIndex4D(uint gridSize, uint index) {
uint z_1 = (gridSize / value_or_one_if_zero_uint((index * index))); uint z_1 = tint_div(gridSize, (index * index));
uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); uint x_1 = tint_mod(index, gridSize);
return uint3(z_1, y_1, y_1); return uint3(z_1, y_1, y_1);
} }

View File

@ -14,6 +14,14 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % select(rhs, 1u, (rhs == 0u)));
}
void marg8uintin() { void marg8uintin() {
} }
@ -81,9 +89,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex4D(uint gridSize, uint index) { uint3 toIndex4D(uint gridSize, uint index) {
uint z_1 = (gridSize / (index * index)); uint z_1 = tint_div(gridSize, (index * index));
uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / gridSize); uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % gridSize); uint x_1 = tint_mod(index, gridSize);
return uint3(z_1, y_1, y_1); return uint3(z_1, y_1, y_1);
} }

View File

@ -1,10 +1,10 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 275 ; Bound: 290
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
%69 = OpExtInstImport "GLSL.std.450" %86 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1 OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1
OpExecutionMode %main_count LocalSize 128 1 1 OpExecutionMode %main_count LocalSize 128 1 1
@ -47,6 +47,12 @@
OpMemberName %Dbg 10 "value_f32_2" OpMemberName %Dbg 10 "value_f32_2"
OpMemberName %Dbg 11 "value_f32_3" OpMemberName %Dbg 11 "value_f32_3"
OpName %dbg "dbg" OpName %dbg "dbg"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %tint_mod "tint_mod"
OpName %lhs_0 "lhs"
OpName %rhs_0 "rhs"
OpName %marg8uintin "marg8uintin" OpName %marg8uintin "marg8uintin"
OpName %toVoxelPos "toVoxelPos" OpName %toVoxelPos "toVoxelPos"
OpName %position "position" OpName %position "position"
@ -171,291 +177,310 @@
%dbg_block = OpTypeStruct %Dbg %dbg_block = OpTypeStruct %Dbg
%_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block %_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block
%dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer %dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer
%32 = OpTypeFunction %uint %uint %uint
%38 = OpConstantNull %uint
%bool = OpTypeBool
%uint_1 = OpConstant %uint 1
%void = OpTypeVoid %void = OpTypeVoid
%32 = OpTypeFunction %void %50 = OpTypeFunction %void
%36 = OpTypeFunction %v3float %v3float %54 = OpTypeFunction %v3float %v3float
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%uint_4 = OpConstant %uint 4 %uint_4 = OpConstant %uint 4
%_ptr_Uniform_float = OpTypePointer Uniform %float %_ptr_Uniform_float = OpTypePointer Uniform %float
%uint_1 = OpConstant %uint 1
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%_ptr_Function_v3float = OpTypePointer Function %v3float %_ptr_Function_v3float = OpTypePointer Function %v3float
%54 = OpConstantNull %v3float %71 = OpConstantNull %v3float
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%_ptr_Function_float = OpTypePointer Function %float %_ptr_Function_float = OpTypePointer Function %float
%79 = OpConstantNull %float %96 = OpConstantNull %float
%_ptr_Uniform_uint = OpTypePointer Uniform %uint %_ptr_Uniform_uint = OpTypePointer Uniform %uint
%116 = OpTypeFunction %uint %uint %v3float %133 = OpTypeFunction %uint %uint %v3float
%_ptr_Function_v3uint = OpTypePointer Function %v3uint %_ptr_Function_v3uint = OpTypePointer Function %v3uint
%124 = OpConstantNull %v3uint %141 = OpConstantNull %v3uint
%_ptr_Function_uint = OpTypePointer Function %uint %_ptr_Function_uint = OpTypePointer Function %uint
%137 = OpTypeFunction %v3uint %uint %uint %154 = OpTypeFunction %v3uint %uint %uint
%145 = OpConstantNull %uint %174 = OpTypeFunction %v3float %uint
%158 = OpTypeFunction %v3float %uint
%uint_3 = OpConstant %uint 3 %uint_3 = OpConstant %uint 3
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
%190 = OpConstantNull %int %206 = OpConstantNull %int
%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%206 = OpTypeFunction %void %v3uint %222 = OpTypeFunction %void %v3uint
%bool = OpTypeBool
%float_3 = OpConstant %float 3 %float_3 = OpConstant %float 3
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%marg8uintin = OpFunction %void None %32 %tint_div = OpFunction %uint None %32
%35 = OpLabel %lhs = OpFunctionParameter %uint
%rhs = OpFunctionParameter %uint
%36 = OpLabel
%39 = OpIEqual %bool %rhs %38
%37 = OpSelect %uint %39 %uint_1 %rhs
%42 = OpUDiv %uint %lhs %37
OpReturnValue %42
OpFunctionEnd
%tint_mod = OpFunction %uint None %32
%lhs_0 = OpFunctionParameter %uint
%rhs_0 = OpFunctionParameter %uint
%46 = OpLabel
%48 = OpIEqual %bool %rhs_0 %38
%47 = OpSelect %uint %48 %uint_1 %rhs_0
%49 = OpUMod %uint %lhs_0 %47
OpReturnValue %49
OpFunctionEnd
%marg8uintin = OpFunction %void None %50
%53 = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%toVoxelPos = OpFunction %v3float None %36 %toVoxelPos = OpFunction %v3float None %54
%position = OpFunctionParameter %v3float %position = OpFunctionParameter %v3float
%39 = OpLabel %57 = OpLabel
%bbMin = OpVariable %_ptr_Function_v3float Function %54 %bbMin = OpVariable %_ptr_Function_v3float Function %71
%bbMax = OpVariable %_ptr_Function_v3float Function %54 %bbMax = OpVariable %_ptr_Function_v3float Function %71
%bbSize = OpVariable %_ptr_Function_v3float Function %54 %bbSize = OpVariable %_ptr_Function_v3float Function %71
%cubeSize = OpVariable %_ptr_Function_float Function %79 %cubeSize = OpVariable %_ptr_Function_float Function %96
%gridSize = OpVariable %_ptr_Function_float Function %79 %gridSize = OpVariable %_ptr_Function_float Function %96
%gx = OpVariable %_ptr_Function_float Function %79 %gx = OpVariable %_ptr_Function_float Function %96
%gy = OpVariable %_ptr_Function_float Function %79 %gy = OpVariable %_ptr_Function_float Function %96
%gz = OpVariable %_ptr_Function_float Function %79 %gz = OpVariable %_ptr_Function_float Function %96
%43 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 %61 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%44 = OpLoad %float %43 %62 = OpLoad %float %61
%46 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 %63 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%47 = OpLoad %float %46 %64 = OpLoad %float %63
%49 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 %66 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%50 = OpLoad %float %49 %67 = OpLoad %float %66
%51 = OpCompositeConstruct %v3float %44 %47 %50 %68 = OpCompositeConstruct %v3float %62 %64 %67
OpStore %bbMin %51 OpStore %bbMin %68
%56 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0 %73 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0
%57 = OpLoad %float %56 %74 = OpLoad %float %73
%58 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1 %75 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1
%59 = OpLoad %float %58 %76 = OpLoad %float %75
%60 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2 %77 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2
%61 = OpLoad %float %60 %78 = OpLoad %float %77
%62 = OpCompositeConstruct %v3float %57 %59 %61 %79 = OpCompositeConstruct %v3float %74 %76 %78
OpStore %bbMax %62 OpStore %bbMax %79
%64 = OpLoad %v3float %bbMin %81 = OpLoad %v3float %bbMin
%65 = OpLoad %v3float %bbMin %82 = OpLoad %v3float %bbMin
%66 = OpFSub %v3float %64 %65 %83 = OpFSub %v3float %81 %82
OpStore %bbSize %66 OpStore %bbSize %83
%72 = OpAccessChain %_ptr_Function_float %bbMax %uint_0 %89 = OpAccessChain %_ptr_Function_float %bbMax %uint_0
%73 = OpLoad %float %72 %90 = OpLoad %float %89
%74 = OpAccessChain %_ptr_Function_float %bbMax %uint_1 %91 = OpAccessChain %_ptr_Function_float %bbMax %uint_1
%75 = OpLoad %float %74 %92 = OpLoad %float %91
%70 = OpExtInst %float %69 NMax %73 %75 %87 = OpExtInst %float %86 NMax %90 %92
%76 = OpAccessChain %_ptr_Function_float %bbSize %uint_2 %93 = OpAccessChain %_ptr_Function_float %bbSize %uint_2
%77 = OpLoad %float %76 %94 = OpLoad %float %93
%68 = OpExtInst %float %69 NMax %70 %77 %85 = OpExtInst %float %86 NMax %87 %94
OpStore %cubeSize %68 OpStore %cubeSize %85
%82 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %99 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%83 = OpLoad %uint %82 %100 = OpLoad %uint %99
%80 = OpConvertUToF %float %83 %97 = OpConvertUToF %float %100
OpStore %gridSize %80 OpStore %gridSize %97
%85 = OpLoad %float %cubeSize %102 = OpLoad %float %cubeSize
%86 = OpCompositeExtract %float %position 0 %103 = OpCompositeExtract %float %position 0
%87 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 %104 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%88 = OpLoad %float %87 %105 = OpLoad %float %104
%89 = OpFSub %float %86 %88 %106 = OpFSub %float %103 %105
%90 = OpFMul %float %85 %89 %107 = OpFMul %float %102 %106
%91 = OpLoad %float %cubeSize %108 = OpLoad %float %cubeSize
%92 = OpFDiv %float %90 %91 %109 = OpFDiv %float %107 %108
OpStore %gx %92 OpStore %gx %109
%94 = OpLoad %float %gx %111 = OpLoad %float %gx
%95 = OpCompositeExtract %float %position 1 %112 = OpCompositeExtract %float %position 1
%96 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 %113 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%97 = OpLoad %float %96 %114 = OpLoad %float %113
%98 = OpFSub %float %95 %97 %115 = OpFSub %float %112 %114
%99 = OpFMul %float %94 %98 %116 = OpFMul %float %111 %115
%100 = OpLoad %float %gridSize %117 = OpLoad %float %gridSize
%101 = OpFDiv %float %99 %100 %118 = OpFDiv %float %116 %117
OpStore %gy %101 OpStore %gy %118
%103 = OpLoad %float %gridSize %120 = OpLoad %float %gridSize
%104 = OpCompositeExtract %float %position 2 %121 = OpCompositeExtract %float %position 2
%105 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 %122 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%106 = OpLoad %float %105 %123 = OpLoad %float %122
%107 = OpFSub %float %104 %106 %124 = OpFSub %float %121 %123
%108 = OpFMul %float %103 %107 %125 = OpFMul %float %120 %124
%109 = OpLoad %float %gridSize %126 = OpLoad %float %gridSize
%110 = OpFDiv %float %108 %109 %127 = OpFDiv %float %125 %126
OpStore %gz %110 OpStore %gz %127
%112 = OpLoad %float %gz %129 = OpLoad %float %gz
%113 = OpLoad %float %gz %130 = OpLoad %float %gz
%114 = OpLoad %float %gz %131 = OpLoad %float %gz
%115 = OpCompositeConstruct %v3float %112 %113 %114 %132 = OpCompositeConstruct %v3float %129 %130 %131
OpReturnValue %115 OpReturnValue %132
OpFunctionEnd OpFunctionEnd
%toIndex1D = OpFunction %uint None %116 %toIndex1D = OpFunction %uint None %133
%gridSize_0 = OpFunctionParameter %uint %gridSize_0 = OpFunctionParameter %uint
%voxelPos = OpFunctionParameter %v3float %voxelPos = OpFunctionParameter %v3float
%120 = OpLabel %137 = OpLabel
%icoord = OpVariable %_ptr_Function_v3uint Function %124 %icoord = OpVariable %_ptr_Function_v3uint Function %141
%121 = OpConvertFToU %v3uint %voxelPos %138 = OpConvertFToU %v3uint %voxelPos
OpStore %icoord %121 OpStore %icoord %138
%126 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 %143 = OpAccessChain %_ptr_Function_uint %icoord %uint_0
%127 = OpLoad %uint %126 %144 = OpLoad %uint %143
%128 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 %145 = OpAccessChain %_ptr_Function_uint %icoord %uint_1
%129 = OpLoad %uint %128 %146 = OpLoad %uint %145
%130 = OpIMul %uint %gridSize_0 %129 %147 = OpIMul %uint %gridSize_0 %146
%131 = OpIAdd %uint %127 %130 %148 = OpIAdd %uint %144 %147
%132 = OpIMul %uint %gridSize_0 %gridSize_0 %149 = OpIMul %uint %gridSize_0 %gridSize_0
%133 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 %150 = OpAccessChain %_ptr_Function_uint %icoord %uint_2
%134 = OpLoad %uint %133 %151 = OpLoad %uint %150
%135 = OpIMul %uint %132 %134 %152 = OpIMul %uint %149 %151
%136 = OpIAdd %uint %131 %135 %153 = OpIAdd %uint %148 %152
OpReturnValue %136 OpReturnValue %153
OpFunctionEnd OpFunctionEnd
%toIndex4D = OpFunction %v3uint None %137 %toIndex4D = OpFunction %v3uint None %154
%gridSize_1 = OpFunctionParameter %uint %gridSize_1 = OpFunctionParameter %uint
%index = OpFunctionParameter %uint %index = OpFunctionParameter %uint
%141 = OpLabel %158 = OpLabel
%z = OpVariable %_ptr_Function_uint Function %145 %z = OpVariable %_ptr_Function_uint Function %38
%y = OpVariable %_ptr_Function_uint Function %145 %y = OpVariable %_ptr_Function_uint Function %38
%x = OpVariable %_ptr_Function_uint Function %145 %x = OpVariable %_ptr_Function_uint Function %38
%142 = OpIMul %uint %index %index %160 = OpIMul %uint %index %index
%143 = OpUDiv %uint %gridSize_1 %142 %159 = OpFunctionCall %uint %tint_div %gridSize_1 %160
OpStore %z %143 OpStore %z %159
%146 = OpIMul %uint %gridSize_1 %gridSize_1 %163 = OpIMul %uint %gridSize_1 %gridSize_1
%147 = OpLoad %uint %z %164 = OpLoad %uint %z
%148 = OpIMul %uint %146 %147 %165 = OpIMul %uint %163 %164
%149 = OpISub %uint %gridSize_1 %148 %166 = OpISub %uint %gridSize_1 %165
%150 = OpUDiv %uint %149 %gridSize_1 %162 = OpFunctionCall %uint %tint_div %166 %gridSize_1
OpStore %y %150 OpStore %y %162
%152 = OpUMod %uint %index %gridSize_1 %168 = OpFunctionCall %uint %tint_mod %index %gridSize_1
OpStore %x %152 OpStore %x %168
%154 = OpLoad %uint %z %170 = OpLoad %uint %z
%155 = OpLoad %uint %y %171 = OpLoad %uint %y
%156 = OpLoad %uint %y %172 = OpLoad %uint %y
%157 = OpCompositeConstruct %v3uint %154 %155 %156 %173 = OpCompositeConstruct %v3uint %170 %171 %172
OpReturnValue %157 OpReturnValue %173
OpFunctionEnd OpFunctionEnd
%loadPosition = OpFunction %v3float None %158 %loadPosition = OpFunction %v3float None %174
%vertexIndex = OpFunctionParameter %uint %vertexIndex = OpFunctionParameter %uint
%161 = OpLabel %177 = OpLabel
%position_0 = OpVariable %_ptr_Function_v3float Function %54 %position_0 = OpVariable %_ptr_Function_v3float Function %71
%163 = OpIMul %uint %uint_3 %vertexIndex %179 = OpIMul %uint %uint_3 %vertexIndex
%164 = OpIAdd %uint %163 %145 %180 = OpIAdd %uint %179 %38
%166 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %164 %182 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %180
%167 = OpLoad %float %166 %183 = OpLoad %float %182
%168 = OpIMul %uint %uint_3 %vertexIndex %184 = OpIMul %uint %uint_3 %vertexIndex
%169 = OpIAdd %uint %168 %uint_1 %185 = OpIAdd %uint %184 %uint_1
%170 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %169 %186 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %185
%171 = OpLoad %float %170 %187 = OpLoad %float %186
%172 = OpIMul %uint %uint_3 %vertexIndex %188 = OpIMul %uint %uint_3 %vertexIndex
%173 = OpIAdd %uint %172 %uint_2 %189 = OpIAdd %uint %188 %uint_2
%174 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %173 %190 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %189
%175 = OpLoad %float %174 %191 = OpLoad %float %190
%176 = OpCompositeConstruct %v3float %167 %171 %175 %192 = OpCompositeConstruct %v3float %183 %187 %191
OpStore %position_0 %176 OpStore %position_0 %192
%178 = OpLoad %v3float %position_0 %194 = OpLoad %v3float %position_0
OpReturnValue %178 OpReturnValue %194
OpFunctionEnd OpFunctionEnd
%doIgnore = OpFunction %void None %32 %doIgnore = OpFunction %void None %50
%180 = OpLabel %196 = OpLabel
%g43 = OpVariable %_ptr_Function_uint Function %145 %g43 = OpVariable %_ptr_Function_uint Function %38
%kj6 = OpVariable %_ptr_Function_uint Function %145 %kj6 = OpVariable %_ptr_Function_uint Function %38
%b53 = OpVariable %_ptr_Function_uint Function %145 %b53 = OpVariable %_ptr_Function_uint Function %38
%rwg = OpVariable %_ptr_Function_uint Function %145 %rwg = OpVariable %_ptr_Function_uint Function %38
%rb5 = OpVariable %_ptr_Function_float Function %79 %rb5 = OpVariable %_ptr_Function_float Function %96
%g55 = OpVariable %_ptr_Function_int Function %190 %g55 = OpVariable %_ptr_Function_int Function %206
%181 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %197 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0
%182 = OpLoad %uint %181 %198 = OpLoad %uint %197
OpStore %g43 %182 OpStore %g43 %198
%185 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 %201 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5
%186 = OpLoad %uint %185 %202 = OpLoad %uint %201
OpStore %kj6 %186 OpStore %kj6 %202
%192 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %190 %208 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %206
%188 = OpAtomicLoad %uint %192 %uint_1 %uint_0 %204 = OpAtomicLoad %uint %208 %uint_1 %uint_0
OpStore %b53 %188 OpStore %b53 %204
%194 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %190 %210 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %206
%195 = OpLoad %uint %194 %211 = OpLoad %uint %210
OpStore %rwg %195 OpStore %rwg %211
%197 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %190 %213 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %206
%198 = OpLoad %float %197 %214 = OpLoad %float %213
OpStore %rb5 %198 OpStore %rb5 %214
%203 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %190 %219 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %206
%200 = OpAtomicLoad %int %203 %uint_1 %uint_0 %216 = OpAtomicLoad %int %219 %uint_1 %uint_0
OpStore %g55 %200 OpStore %g55 %216
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_count_inner = OpFunction %void None %206 %main_count_inner = OpFunction %void None %222
%GlobalInvocationID = OpFunctionParameter %v3uint %GlobalInvocationID = OpFunctionParameter %v3uint
%209 = OpLabel %225 = OpLabel
%triangleIndex = OpVariable %_ptr_Function_uint Function %145 %triangleIndex = OpVariable %_ptr_Function_uint Function %38
%i0 = OpVariable %_ptr_Function_uint Function %145 %i0 = OpVariable %_ptr_Function_uint Function %38
%i1 = OpVariable %_ptr_Function_uint Function %145 %i1 = OpVariable %_ptr_Function_uint Function %38
%i2 = OpVariable %_ptr_Function_uint Function %145 %i2 = OpVariable %_ptr_Function_uint Function %38
%p0 = OpVariable %_ptr_Function_v3float Function %54 %p0 = OpVariable %_ptr_Function_v3float Function %71
%p1 = OpVariable %_ptr_Function_v3float Function %54 %p1 = OpVariable %_ptr_Function_v3float Function %71
%p2 = OpVariable %_ptr_Function_v3float Function %54 %p2 = OpVariable %_ptr_Function_v3float Function %71
%254 = OpVariable %_ptr_Function_v3float Function %54 %269 = OpVariable %_ptr_Function_v3float Function %71
%center = OpVariable %_ptr_Function_v3float Function %54 %center = OpVariable %_ptr_Function_v3float Function %71
%voxelPos_0 = OpVariable %_ptr_Function_v3float Function %54 %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %71
%lIndex = OpVariable %_ptr_Function_uint Function %145 %lIndex = OpVariable %_ptr_Function_uint Function %38
%triangleOffset = OpVariable %_ptr_Function_int Function %190 %triangleOffset = OpVariable %_ptr_Function_int Function %206
%210 = OpCompositeExtract %uint %GlobalInvocationID 0 %226 = OpCompositeExtract %uint %GlobalInvocationID 0
OpStore %triangleIndex %210 OpStore %triangleIndex %226
%212 = OpLoad %uint %triangleIndex %228 = OpLoad %uint %triangleIndex
%213 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %229 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0
%214 = OpLoad %uint %213
%215 = OpUGreaterThanEqual %bool %212 %214
OpSelectionMerge %217 None
OpBranchConditional %215 %218 %217
%218 = OpLabel
OpReturn
%217 = OpLabel
%219 = OpFunctionCall %void %doIgnore
%220 = OpLoad %uint %triangleIndex
%221 = OpIMul %uint %uint_3 %220
%222 = OpIAdd %uint %221 %145
%223 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %222
%224 = OpLoad %uint %223
OpStore %i0 %224
%226 = OpLoad %uint %i0
%227 = OpIMul %uint %uint_3 %226
%228 = OpIAdd %uint %227 %uint_1
%229 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %228
%230 = OpLoad %uint %229 %230 = OpLoad %uint %229
OpStore %i1 %230 %231 = OpUGreaterThanEqual %bool %228 %230
%232 = OpLoad %uint %i0 OpSelectionMerge %232 None
%233 = OpIMul %uint %uint_3 %232 OpBranchConditional %231 %233 %232
%234 = OpIAdd %uint %233 %uint_2 %233 = OpLabel
%235 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %234 OpReturn
%236 = OpLoad %uint %235 %232 = OpLabel
OpStore %i2 %236 %234 = OpFunctionCall %void %doIgnore
%239 = OpLoad %uint %i0 %235 = OpLoad %uint %triangleIndex
%238 = OpFunctionCall %v3float %loadPosition %239 %236 = OpIMul %uint %uint_3 %235
OpStore %p0 %238 %237 = OpIAdd %uint %236 %38
%242 = OpLoad %uint %i0 %238 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %237
%241 = OpFunctionCall %v3float %loadPosition %242 %239 = OpLoad %uint %238
OpStore %p1 %241 OpStore %i0 %239
%245 = OpLoad %uint %i2 %241 = OpLoad %uint %i0
%244 = OpFunctionCall %v3float %loadPosition %245 %242 = OpIMul %uint %uint_3 %241
OpStore %p2 %244 %243 = OpIAdd %uint %242 %uint_1
%247 = OpLoad %v3float %p0 %244 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %243
%248 = OpLoad %v3float %p2 %245 = OpLoad %uint %244
%249 = OpFAdd %v3float %247 %248 OpStore %i1 %245
%250 = OpLoad %v3float %p1 %247 = OpLoad %uint %i0
%251 = OpFAdd %v3float %249 %250 %248 = OpIMul %uint %uint_3 %247
%255 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 %249 = OpIAdd %uint %248 %uint_2
%253 = OpFDiv %v3float %251 %255 %250 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %249
OpStore %center %253 %251 = OpLoad %uint %250
%258 = OpLoad %v3float %p1 OpStore %i2 %251
%257 = OpFunctionCall %v3float %toVoxelPos %258 %254 = OpLoad %uint %i0
OpStore %voxelPos_0 %257 %253 = OpFunctionCall %v3float %loadPosition %254
%261 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 OpStore %p0 %253
%262 = OpLoad %uint %261 %257 = OpLoad %uint %i0
%263 = OpLoad %v3float %p0 %256 = OpFunctionCall %v3float %loadPosition %257
%260 = OpFunctionCall %uint %toIndex1D %262 %263 OpStore %p1 %256
OpStore %lIndex %260 %260 = OpLoad %uint %i2
%267 = OpLoad %uint %i1 %259 = OpFunctionCall %v3float %loadPosition %260
%268 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %267 OpStore %p2 %259
%265 = OpAtomicIAdd %int %268 %uint_1 %uint_0 %int_1 %262 = OpLoad %v3float %p0
OpStore %triangleOffset %265 %263 = OpLoad %v3float %p2
%264 = OpFAdd %v3float %262 %263
%265 = OpLoad %v3float %p1
%266 = OpFAdd %v3float %264 %265
%270 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
%268 = OpFDiv %v3float %266 %270
OpStore %center %268
%273 = OpLoad %v3float %p1
%272 = OpFunctionCall %v3float %toVoxelPos %273
OpStore %voxelPos_0 %272
%276 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%277 = OpLoad %uint %276
%278 = OpLoad %v3float %p0
%275 = OpFunctionCall %uint %toIndex1D %277 %278
OpStore %lIndex %275
%282 = OpLoad %uint %i1
%283 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %282
%280 = OpAtomicIAdd %int %283 %uint_1 %uint_0 %int_1
OpStore %triangleOffset %280
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_count = OpFunction %void None %32 %main_count = OpFunction %void None %50
%272 = OpLabel %287 = OpLabel
%274 = OpLoad %v3uint %GlobalInvocationID_1 %289 = OpLoad %v3uint %GlobalInvocationID_1
%273 = OpFunctionCall %void %main_count_inner %274 %288 = OpFunctionCall %void %main_count_inner %289
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 0; const int b = 0;
const int c = (a / (b == 0 ? 1 : b)); const int c = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 0; const int b = 0;
const int c = (a / (b == 0 ? 1 : b)); const int c = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
int tint_div(int lhs, int rhs) {
return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs));
}
void f() { void f() {
int a = 1; int a = 1;
int b = 0; int b = 0;
int c = (a / b); int c = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int tint_div(int lhs, int rhs) {
return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))));
}
kernel void f() { kernel void f() {
int const a = 1; int const a = 1;
int const b = 0; int const b = 0;
int const c = (a / b); int const c = tint_div(a, b);
return; return;
} }

View File

@ -1,20 +1,40 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 9 ; Bound: 24
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%1 = OpTypeFunction %int %int %int
%8 = OpConstantNull %int
%bool = OpTypeBool
%int_n2147483648 = OpConstant %int -2147483648
%int_n1 = OpConstant %int -1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%7 = OpConstantNull %int %void = OpTypeVoid
%f = OpFunction %void None %1 %19 = OpTypeFunction %void
%4 = OpLabel %tint_div = OpFunction %int None %1
%8 = OpSDiv %int %int_1 %7 %lhs = OpFunctionParameter %int
%rhs = OpFunctionParameter %int
%6 = OpLabel
%9 = OpIEqual %bool %rhs %8
%12 = OpIEqual %bool %lhs %int_n2147483648
%14 = OpIEqual %bool %rhs %int_n1
%15 = OpLogicalAnd %bool %12 %14
%16 = OpLogicalOr %bool %9 %15
%7 = OpSelect %int %16 %int_1 %rhs
%18 = OpSDiv %int %lhs %7
OpReturnValue %18
OpFunctionEnd
%f = OpFunction %void None %19
%22 = OpLabel
%23 = OpFunctionCall %int %tint_div %int_1 %8
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,5 +1,9 @@
uint value_or_one_if_zero_uint(uint value) { uint tint_div(uint lhs, uint rhs) {
return value == 0u ? 1u : value; return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
} }
cbuffer cbuffer_uniforms : register(b0, space0) { cbuffer cbuffer_uniforms : register(b0, space0) {
@ -29,9 +33,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex3D(uint gridSize, uint index) { uint3 toIndex3D(uint gridSize, uint index) {
uint z_1 = (index / value_or_one_if_zero_uint((gridSize * gridSize))); uint z_1 = tint_div(index, (gridSize * gridSize));
uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); uint x_1 = tint_mod(index, gridSize);
return uint3(x_1, y_1, z_1); return uint3(x_1, y_1, z_1);
} }

View File

@ -1,5 +1,9 @@
uint value_or_one_if_zero_uint(uint value) { uint tint_div(uint lhs, uint rhs) {
return value == 0u ? 1u : value; return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
} }
cbuffer cbuffer_uniforms : register(b0, space0) { cbuffer cbuffer_uniforms : register(b0, space0) {
@ -29,9 +33,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex3D(uint gridSize, uint index) { uint3 toIndex3D(uint gridSize, uint index) {
uint z_1 = (index / value_or_one_if_zero_uint((gridSize * gridSize))); uint z_1 = tint_div(index, (gridSize * gridSize));
uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); uint x_1 = tint_mod(index, gridSize);
return uint3(x_1, y_1, z_1); return uint3(x_1, y_1, z_1);
} }

View File

@ -14,6 +14,14 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % select(rhs, 1u, (rhs == 0u)));
}
struct Uniforms { struct Uniforms {
/* 0x0000 */ uint numTriangles; /* 0x0000 */ uint numTriangles;
/* 0x0004 */ uint gridSize; /* 0x0004 */ uint gridSize;
@ -78,9 +86,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) {
} }
uint3 toIndex3D(uint gridSize, uint index) { uint3 toIndex3D(uint gridSize, uint index) {
uint z_1 = (index / (gridSize * gridSize)); uint z_1 = tint_div(index, (gridSize * gridSize));
uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / gridSize); uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize);
uint x_1 = (index % gridSize); uint x_1 = tint_mod(index, gridSize);
return uint3(x_1, y_1, z_1); return uint3(x_1, y_1, z_1);
} }

View File

@ -1,10 +1,10 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 404 ; Bound: 419
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
%67 = OpExtInstImport "GLSL.std.450" %84 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1 OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1
OpEntryPoint GLCompute %main_create_lut "main_create_lut" %GlobalInvocationID_2 OpEntryPoint GLCompute %main_create_lut "main_create_lut" %GlobalInvocationID_2
@ -53,6 +53,12 @@
OpMemberName %Dbg 10 "value_f32_2" OpMemberName %Dbg 10 "value_f32_2"
OpMemberName %Dbg 11 "value_f32_3" OpMemberName %Dbg 11 "value_f32_3"
OpName %dbg "dbg" OpName %dbg "dbg"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %tint_mod "tint_mod"
OpName %lhs_0 "lhs"
OpName %rhs_0 "rhs"
OpName %toVoxelPos "toVoxelPos" OpName %toVoxelPos "toVoxelPos"
OpName %position "position" OpName %position "position"
OpName %bbMin "bbMin" OpName %bbMin "bbMin"
@ -201,452 +207,471 @@
%dbg_block = OpTypeStruct %Dbg %dbg_block = OpTypeStruct %Dbg
%_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block %_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block
%dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer %dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer
%34 = OpTypeFunction %v3float %v3float %34 = OpTypeFunction %uint %uint %uint
%40 = OpConstantNull %uint
%bool = OpTypeBool
%uint_1 = OpConstant %uint 1
%52 = OpTypeFunction %v3float %v3float
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%uint_4 = OpConstant %uint 4 %uint_4 = OpConstant %uint 4
%_ptr_Uniform_float = OpTypePointer Uniform %float %_ptr_Uniform_float = OpTypePointer Uniform %float
%uint_1 = OpConstant %uint 1
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%_ptr_Function_v3float = OpTypePointer Function %v3float %_ptr_Function_v3float = OpTypePointer Function %v3float
%52 = OpConstantNull %v3float %69 = OpConstantNull %v3float
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%_ptr_Function_float = OpTypePointer Function %float %_ptr_Function_float = OpTypePointer Function %float
%77 = OpConstantNull %float %94 = OpConstantNull %float
%_ptr_Uniform_uint = OpTypePointer Uniform %uint %_ptr_Uniform_uint = OpTypePointer Uniform %uint
%114 = OpTypeFunction %uint %uint %v3float %131 = OpTypeFunction %uint %uint %v3float
%_ptr_Function_v3uint = OpTypePointer Function %v3uint %_ptr_Function_v3uint = OpTypePointer Function %v3uint
%122 = OpConstantNull %v3uint %139 = OpConstantNull %v3uint
%_ptr_Function_uint = OpTypePointer Function %uint %_ptr_Function_uint = OpTypePointer Function %uint
%135 = OpTypeFunction %v3uint %uint %uint %152 = OpTypeFunction %v3uint %uint %uint
%143 = OpConstantNull %uint %172 = OpTypeFunction %v3float %uint
%156 = OpTypeFunction %v3float %uint
%uint_3 = OpConstant %uint 3 %uint_3 = OpConstant %uint 3
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
%void = OpTypeVoid %void = OpTypeVoid
%177 = OpTypeFunction %void %193 = OpTypeFunction %void
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
%190 = OpConstantNull %int %206 = OpConstantNull %int
%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%206 = OpTypeFunction %void %v3uint %222 = OpTypeFunction %void %v3uint
%bool = OpTypeBool
%float_3 = OpConstant %float 3 %float_3 = OpConstant %float 3
%uint_8 = OpConstant %uint 8 %uint_8 = OpConstant %uint 8
%uint_9 = OpConstant %uint 9 %uint_9 = OpConstant %uint 9
%uint_10 = OpConstant %uint 10 %uint_10 = OpConstant %uint 10
%int_n1 = OpConstant %int -1 %int_n1 = OpConstant %int -1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%toVoxelPos = OpFunction %v3float None %34 %tint_div = OpFunction %uint None %34
%position = OpFunctionParameter %v3float %lhs = OpFunctionParameter %uint
%37 = OpLabel %rhs = OpFunctionParameter %uint
%bbMin = OpVariable %_ptr_Function_v3float Function %52 %38 = OpLabel
%bbMax = OpVariable %_ptr_Function_v3float Function %52 %41 = OpIEqual %bool %rhs %40
%bbSize = OpVariable %_ptr_Function_v3float Function %52 %39 = OpSelect %uint %41 %uint_1 %rhs
%cubeSize = OpVariable %_ptr_Function_float Function %77 %44 = OpUDiv %uint %lhs %39
%gridSize = OpVariable %_ptr_Function_float Function %77 OpReturnValue %44
%gx = OpVariable %_ptr_Function_float Function %77
%gy = OpVariable %_ptr_Function_float Function %77
%gz = OpVariable %_ptr_Function_float Function %77
%41 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%42 = OpLoad %float %41
%44 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%45 = OpLoad %float %44
%47 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%48 = OpLoad %float %47
%49 = OpCompositeConstruct %v3float %42 %45 %48
OpStore %bbMin %49
%54 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0
%55 = OpLoad %float %54
%56 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1
%57 = OpLoad %float %56
%58 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2
%59 = OpLoad %float %58
%60 = OpCompositeConstruct %v3float %55 %57 %59
OpStore %bbMax %60
%62 = OpLoad %v3float %bbMax
%63 = OpLoad %v3float %bbMin
%64 = OpFSub %v3float %62 %63
OpStore %bbSize %64
%70 = OpAccessChain %_ptr_Function_float %bbSize %uint_0
%71 = OpLoad %float %70
%72 = OpAccessChain %_ptr_Function_float %bbSize %uint_1
%73 = OpLoad %float %72
%68 = OpExtInst %float %67 NMax %71 %73
%74 = OpAccessChain %_ptr_Function_float %bbSize %uint_2
%75 = OpLoad %float %74
%66 = OpExtInst %float %67 NMax %68 %75
OpStore %cubeSize %66
%80 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%81 = OpLoad %uint %80
%78 = OpConvertUToF %float %81
OpStore %gridSize %78
%83 = OpLoad %float %gridSize
%84 = OpCompositeExtract %float %position 0
%85 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%86 = OpLoad %float %85
%87 = OpFSub %float %84 %86
%88 = OpFMul %float %83 %87
%89 = OpLoad %float %cubeSize
%90 = OpFDiv %float %88 %89
OpStore %gx %90
%92 = OpLoad %float %gridSize
%93 = OpCompositeExtract %float %position 1
%94 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%95 = OpLoad %float %94
%96 = OpFSub %float %93 %95
%97 = OpFMul %float %92 %96
%98 = OpLoad %float %cubeSize
%99 = OpFDiv %float %97 %98
OpStore %gy %99
%101 = OpLoad %float %gridSize
%102 = OpCompositeExtract %float %position 2
%103 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%104 = OpLoad %float %103
%105 = OpFSub %float %102 %104
%106 = OpFMul %float %101 %105
%107 = OpLoad %float %cubeSize
%108 = OpFDiv %float %106 %107
OpStore %gz %108
%110 = OpLoad %float %gx
%111 = OpLoad %float %gy
%112 = OpLoad %float %gz
%113 = OpCompositeConstruct %v3float %110 %111 %112
OpReturnValue %113
OpFunctionEnd OpFunctionEnd
%toIndex1D = OpFunction %uint None %114 %tint_mod = OpFunction %uint None %34
%lhs_0 = OpFunctionParameter %uint
%rhs_0 = OpFunctionParameter %uint
%48 = OpLabel
%50 = OpIEqual %bool %rhs_0 %40
%49 = OpSelect %uint %50 %uint_1 %rhs_0
%51 = OpUMod %uint %lhs_0 %49
OpReturnValue %51
OpFunctionEnd
%toVoxelPos = OpFunction %v3float None %52
%position = OpFunctionParameter %v3float
%55 = OpLabel
%bbMin = OpVariable %_ptr_Function_v3float Function %69
%bbMax = OpVariable %_ptr_Function_v3float Function %69
%bbSize = OpVariable %_ptr_Function_v3float Function %69
%cubeSize = OpVariable %_ptr_Function_float Function %94
%gridSize = OpVariable %_ptr_Function_float Function %94
%gx = OpVariable %_ptr_Function_float Function %94
%gy = OpVariable %_ptr_Function_float Function %94
%gz = OpVariable %_ptr_Function_float Function %94
%59 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%60 = OpLoad %float %59
%61 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%62 = OpLoad %float %61
%64 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%65 = OpLoad %float %64
%66 = OpCompositeConstruct %v3float %60 %62 %65
OpStore %bbMin %66
%71 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0
%72 = OpLoad %float %71
%73 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1
%74 = OpLoad %float %73
%75 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2
%76 = OpLoad %float %75
%77 = OpCompositeConstruct %v3float %72 %74 %76
OpStore %bbMax %77
%79 = OpLoad %v3float %bbMax
%80 = OpLoad %v3float %bbMin
%81 = OpFSub %v3float %79 %80
OpStore %bbSize %81
%87 = OpAccessChain %_ptr_Function_float %bbSize %uint_0
%88 = OpLoad %float %87
%89 = OpAccessChain %_ptr_Function_float %bbSize %uint_1
%90 = OpLoad %float %89
%85 = OpExtInst %float %84 NMax %88 %90
%91 = OpAccessChain %_ptr_Function_float %bbSize %uint_2
%92 = OpLoad %float %91
%83 = OpExtInst %float %84 NMax %85 %92
OpStore %cubeSize %83
%97 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%98 = OpLoad %uint %97
%95 = OpConvertUToF %float %98
OpStore %gridSize %95
%100 = OpLoad %float %gridSize
%101 = OpCompositeExtract %float %position 0
%102 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0
%103 = OpLoad %float %102
%104 = OpFSub %float %101 %103
%105 = OpFMul %float %100 %104
%106 = OpLoad %float %cubeSize
%107 = OpFDiv %float %105 %106
OpStore %gx %107
%109 = OpLoad %float %gridSize
%110 = OpCompositeExtract %float %position 1
%111 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1
%112 = OpLoad %float %111
%113 = OpFSub %float %110 %112
%114 = OpFMul %float %109 %113
%115 = OpLoad %float %cubeSize
%116 = OpFDiv %float %114 %115
OpStore %gy %116
%118 = OpLoad %float %gridSize
%119 = OpCompositeExtract %float %position 2
%120 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2
%121 = OpLoad %float %120
%122 = OpFSub %float %119 %121
%123 = OpFMul %float %118 %122
%124 = OpLoad %float %cubeSize
%125 = OpFDiv %float %123 %124
OpStore %gz %125
%127 = OpLoad %float %gx
%128 = OpLoad %float %gy
%129 = OpLoad %float %gz
%130 = OpCompositeConstruct %v3float %127 %128 %129
OpReturnValue %130
OpFunctionEnd
%toIndex1D = OpFunction %uint None %131
%gridSize_0 = OpFunctionParameter %uint %gridSize_0 = OpFunctionParameter %uint
%voxelPos = OpFunctionParameter %v3float %voxelPos = OpFunctionParameter %v3float
%118 = OpLabel %135 = OpLabel
%icoord = OpVariable %_ptr_Function_v3uint Function %122 %icoord = OpVariable %_ptr_Function_v3uint Function %139
%119 = OpConvertFToU %v3uint %voxelPos %136 = OpConvertFToU %v3uint %voxelPos
OpStore %icoord %119 OpStore %icoord %136
%124 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 %141 = OpAccessChain %_ptr_Function_uint %icoord %uint_0
%125 = OpLoad %uint %124 %142 = OpLoad %uint %141
%126 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 %143 = OpAccessChain %_ptr_Function_uint %icoord %uint_1
%127 = OpLoad %uint %126 %144 = OpLoad %uint %143
%128 = OpIMul %uint %gridSize_0 %127 %145 = OpIMul %uint %gridSize_0 %144
%129 = OpIAdd %uint %125 %128 %146 = OpIAdd %uint %142 %145
%130 = OpIMul %uint %gridSize_0 %gridSize_0 %147 = OpIMul %uint %gridSize_0 %gridSize_0
%131 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 %148 = OpAccessChain %_ptr_Function_uint %icoord %uint_2
%132 = OpLoad %uint %131 %149 = OpLoad %uint %148
%133 = OpIMul %uint %130 %132 %150 = OpIMul %uint %147 %149
%134 = OpIAdd %uint %129 %133 %151 = OpIAdd %uint %146 %150
OpReturnValue %134 OpReturnValue %151
OpFunctionEnd OpFunctionEnd
%toIndex3D = OpFunction %v3uint None %135 %toIndex3D = OpFunction %v3uint None %152
%gridSize_1 = OpFunctionParameter %uint %gridSize_1 = OpFunctionParameter %uint
%index = OpFunctionParameter %uint %index = OpFunctionParameter %uint
%139 = OpLabel %156 = OpLabel
%z = OpVariable %_ptr_Function_uint Function %143 %z = OpVariable %_ptr_Function_uint Function %40
%y = OpVariable %_ptr_Function_uint Function %143 %y = OpVariable %_ptr_Function_uint Function %40
%x = OpVariable %_ptr_Function_uint Function %143 %x = OpVariable %_ptr_Function_uint Function %40
%140 = OpIMul %uint %gridSize_1 %gridSize_1 %158 = OpIMul %uint %gridSize_1 %gridSize_1
%141 = OpUDiv %uint %index %140 %157 = OpFunctionCall %uint %tint_div %index %158
OpStore %z %141 OpStore %z %157
%144 = OpIMul %uint %gridSize_1 %gridSize_1 %161 = OpIMul %uint %gridSize_1 %gridSize_1
%145 = OpLoad %uint %z %162 = OpLoad %uint %z
%146 = OpIMul %uint %144 %145 %163 = OpIMul %uint %161 %162
%147 = OpISub %uint %index %146 %164 = OpISub %uint %index %163
%148 = OpUDiv %uint %147 %gridSize_1 %160 = OpFunctionCall %uint %tint_div %164 %gridSize_1
OpStore %y %148 OpStore %y %160
%150 = OpUMod %uint %index %gridSize_1 %166 = OpFunctionCall %uint %tint_mod %index %gridSize_1
OpStore %x %150 OpStore %x %166
%152 = OpLoad %uint %x %168 = OpLoad %uint %x
%153 = OpLoad %uint %y %169 = OpLoad %uint %y
%154 = OpLoad %uint %z %170 = OpLoad %uint %z
%155 = OpCompositeConstruct %v3uint %152 %153 %154 %171 = OpCompositeConstruct %v3uint %168 %169 %170
OpReturnValue %155 OpReturnValue %171
OpFunctionEnd OpFunctionEnd
%loadPosition = OpFunction %v3float None %156 %loadPosition = OpFunction %v3float None %172
%vertexIndex = OpFunctionParameter %uint %vertexIndex = OpFunctionParameter %uint
%159 = OpLabel %175 = OpLabel
%position_0 = OpVariable %_ptr_Function_v3float Function %52 %position_0 = OpVariable %_ptr_Function_v3float Function %69
%161 = OpIMul %uint %uint_3 %vertexIndex %177 = OpIMul %uint %uint_3 %vertexIndex
%162 = OpIAdd %uint %161 %143 %178 = OpIAdd %uint %177 %40
%164 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %162 %180 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %178
%165 = OpLoad %float %164 %181 = OpLoad %float %180
%166 = OpIMul %uint %uint_3 %vertexIndex %182 = OpIMul %uint %uint_3 %vertexIndex
%167 = OpIAdd %uint %166 %uint_1 %183 = OpIAdd %uint %182 %uint_1
%168 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %167 %184 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %183
%169 = OpLoad %float %168 %185 = OpLoad %float %184
%170 = OpIMul %uint %uint_3 %vertexIndex %186 = OpIMul %uint %uint_3 %vertexIndex
%171 = OpIAdd %uint %170 %uint_2 %187 = OpIAdd %uint %186 %uint_2
%172 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %171 %188 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %187
%173 = OpLoad %float %172 %189 = OpLoad %float %188
%174 = OpCompositeConstruct %v3float %165 %169 %173 %190 = OpCompositeConstruct %v3float %181 %185 %189
OpStore %position_0 %174 OpStore %position_0 %190
%176 = OpLoad %v3float %position_0 %192 = OpLoad %v3float %position_0
OpReturnValue %176 OpReturnValue %192
OpFunctionEnd OpFunctionEnd
%doIgnore = OpFunction %void None %177 %doIgnore = OpFunction %void None %193
%180 = OpLabel %196 = OpLabel
%g42 = OpVariable %_ptr_Function_uint Function %143 %g42 = OpVariable %_ptr_Function_uint Function %40
%kj6 = OpVariable %_ptr_Function_uint Function %143 %kj6 = OpVariable %_ptr_Function_uint Function %40
%b53 = OpVariable %_ptr_Function_uint Function %143 %b53 = OpVariable %_ptr_Function_uint Function %40
%rwg = OpVariable %_ptr_Function_uint Function %143 %rwg = OpVariable %_ptr_Function_uint Function %40
%rb5 = OpVariable %_ptr_Function_float Function %77 %rb5 = OpVariable %_ptr_Function_float Function %94
%g55 = OpVariable %_ptr_Function_int Function %190 %g55 = OpVariable %_ptr_Function_int Function %206
%181 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %197 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0
%182 = OpLoad %uint %181 %198 = OpLoad %uint %197
OpStore %g42 %182 OpStore %g42 %198
%185 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 %201 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5
%186 = OpLoad %uint %185 %202 = OpLoad %uint %201
OpStore %kj6 %186 OpStore %kj6 %202
%192 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %190 %208 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %206
%188 = OpAtomicLoad %uint %192 %uint_1 %uint_0 %204 = OpAtomicLoad %uint %208 %uint_1 %uint_0
OpStore %b53 %188 OpStore %b53 %204
%194 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %190 %210 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %206
%195 = OpLoad %uint %194 %211 = OpLoad %uint %210
OpStore %rwg %195 OpStore %rwg %211
%197 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %190 %213 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %206
%198 = OpLoad %float %197 %214 = OpLoad %float %213
OpStore %rb5 %198 OpStore %rb5 %214
%203 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %190 %219 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %206
%200 = OpAtomicLoad %int %203 %uint_1 %uint_0 %216 = OpAtomicLoad %int %219 %uint_1 %uint_0
OpStore %g55 %200 OpStore %g55 %216
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_count_inner = OpFunction %void None %206 %main_count_inner = OpFunction %void None %222
%GlobalInvocationID = OpFunctionParameter %v3uint %GlobalInvocationID = OpFunctionParameter %v3uint
%209 = OpLabel %225 = OpLabel
%triangleIndex = OpVariable %_ptr_Function_uint Function %143 %triangleIndex = OpVariable %_ptr_Function_uint Function %40
%i0 = OpVariable %_ptr_Function_uint Function %143 %i0 = OpVariable %_ptr_Function_uint Function %40
%i1 = OpVariable %_ptr_Function_uint Function %143 %i1 = OpVariable %_ptr_Function_uint Function %40
%i2 = OpVariable %_ptr_Function_uint Function %143 %i2 = OpVariable %_ptr_Function_uint Function %40
%p0 = OpVariable %_ptr_Function_v3float Function %52 %p0 = OpVariable %_ptr_Function_v3float Function %69
%p1 = OpVariable %_ptr_Function_v3float Function %52 %p1 = OpVariable %_ptr_Function_v3float Function %69
%p2 = OpVariable %_ptr_Function_v3float Function %52 %p2 = OpVariable %_ptr_Function_v3float Function %69
%254 = OpVariable %_ptr_Function_v3float Function %52 %269 = OpVariable %_ptr_Function_v3float Function %69
%center = OpVariable %_ptr_Function_v3float Function %52 %center = OpVariable %_ptr_Function_v3float Function %69
%voxelPos_0 = OpVariable %_ptr_Function_v3float Function %52 %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %69
%voxelIndex = OpVariable %_ptr_Function_uint Function %143 %voxelIndex = OpVariable %_ptr_Function_uint Function %40
%acefg = OpVariable %_ptr_Function_uint Function %143 %acefg = OpVariable %_ptr_Function_uint Function %40
%210 = OpCompositeExtract %uint %GlobalInvocationID 0 %226 = OpCompositeExtract %uint %GlobalInvocationID 0
OpStore %triangleIndex %210 OpStore %triangleIndex %226
%212 = OpLoad %uint %triangleIndex %228 = OpLoad %uint %triangleIndex
%213 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %229 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0
%214 = OpLoad %uint %213
%215 = OpUGreaterThanEqual %bool %212 %214
OpSelectionMerge %217 None
OpBranchConditional %215 %218 %217
%218 = OpLabel
OpReturn
%217 = OpLabel
%219 = OpFunctionCall %void %doIgnore
%220 = OpLoad %uint %triangleIndex
%221 = OpIMul %uint %uint_3 %220
%222 = OpIAdd %uint %221 %143
%223 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %222
%224 = OpLoad %uint %223
OpStore %i0 %224
%226 = OpLoad %uint %triangleIndex
%227 = OpIMul %uint %uint_3 %226
%228 = OpIAdd %uint %227 %uint_1
%229 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %228
%230 = OpLoad %uint %229 %230 = OpLoad %uint %229
OpStore %i1 %230 %231 = OpUGreaterThanEqual %bool %228 %230
%232 = OpLoad %uint %triangleIndex OpSelectionMerge %232 None
%233 = OpIMul %uint %uint_3 %232 OpBranchConditional %231 %233 %232
%234 = OpIAdd %uint %233 %uint_2 %233 = OpLabel
%235 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %234 OpReturn
%236 = OpLoad %uint %235 %232 = OpLabel
OpStore %i2 %236 %234 = OpFunctionCall %void %doIgnore
%239 = OpLoad %uint %i0 %235 = OpLoad %uint %triangleIndex
%238 = OpFunctionCall %v3float %loadPosition %239 %236 = OpIMul %uint %uint_3 %235
OpStore %p0 %238 %237 = OpIAdd %uint %236 %40
%242 = OpLoad %uint %i1 %238 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %237
%241 = OpFunctionCall %v3float %loadPosition %242 %239 = OpLoad %uint %238
OpStore %p1 %241 OpStore %i0 %239
%245 = OpLoad %uint %i2 %241 = OpLoad %uint %triangleIndex
%244 = OpFunctionCall %v3float %loadPosition %245 %242 = OpIMul %uint %uint_3 %241
OpStore %p2 %244 %243 = OpIAdd %uint %242 %uint_1
%247 = OpLoad %v3float %p0 %244 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %243
%248 = OpLoad %v3float %p1 %245 = OpLoad %uint %244
%249 = OpFAdd %v3float %247 %248 OpStore %i1 %245
%250 = OpLoad %v3float %p2 %247 = OpLoad %uint %triangleIndex
%251 = OpFAdd %v3float %249 %250 %248 = OpIMul %uint %uint_3 %247
%255 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 %249 = OpIAdd %uint %248 %uint_2
%253 = OpFDiv %v3float %251 %255 %250 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %249
OpStore %center %253 %251 = OpLoad %uint %250
%258 = OpLoad %v3float %center OpStore %i2 %251
%257 = OpFunctionCall %v3float %toVoxelPos %258 %254 = OpLoad %uint %i0
OpStore %voxelPos_0 %257 %253 = OpFunctionCall %v3float %loadPosition %254
%261 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 OpStore %p0 %253
%262 = OpLoad %uint %261 %257 = OpLoad %uint %i1
%263 = OpLoad %v3float %voxelPos_0 %256 = OpFunctionCall %v3float %loadPosition %257
%260 = OpFunctionCall %uint %toIndex1D %262 %263 OpStore %p1 %256
OpStore %voxelIndex %260 %260 = OpLoad %uint %i2
%267 = OpLoad %uint %voxelIndex %259 = OpFunctionCall %v3float %loadPosition %260
%268 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %267 OpStore %p2 %259
%265 = OpAtomicIAdd %uint %268 %uint_1 %uint_0 %uint_1 %262 = OpLoad %v3float %p0
OpStore %acefg %265 %263 = OpLoad %v3float %p1
%270 = OpLoad %uint %triangleIndex %264 = OpFAdd %v3float %262 %263
%271 = OpIEqual %bool %270 %143 %265 = OpLoad %v3float %p2
OpSelectionMerge %272 None %266 = OpFAdd %v3float %264 %265
OpBranchConditional %271 %273 %272 %270 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
%273 = OpLabel %268 = OpFDiv %v3float %266 %270
%274 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_4 OpStore %center %268
%275 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %273 = OpLoad %v3float %center
%276 = OpLoad %uint %275 %272 = OpFunctionCall %v3float %toVoxelPos %273
OpStore %274 %276 OpStore %voxelPos_0 %272
%278 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_8 %276 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%279 = OpAccessChain %_ptr_Function_float %center %uint_0 %277 = OpLoad %uint %276
%280 = OpLoad %float %279 %278 = OpLoad %v3float %voxelPos_0
OpStore %278 %280 %275 = OpFunctionCall %uint %toIndex1D %277 %278
%282 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_9 OpStore %voxelIndex %275
%283 = OpAccessChain %_ptr_Function_float %center %uint_1 %282 = OpLoad %uint %voxelIndex
%284 = OpLoad %float %283 %283 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %282
OpStore %282 %284 %280 = OpAtomicIAdd %uint %283 %uint_1 %uint_0 %uint_1
%286 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_10 OpStore %acefg %280
%287 = OpAccessChain %_ptr_Function_float %center %uint_2 %285 = OpLoad %uint %triangleIndex
%288 = OpLoad %float %287 %286 = OpIEqual %bool %285 %40
OpStore %286 %288 OpSelectionMerge %287 None
OpBranch %272 OpBranchConditional %286 %288 %287
%272 = OpLabel %288 = OpLabel
%289 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_4
%290 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%291 = OpLoad %uint %290
OpStore %289 %291
%293 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_8
%294 = OpAccessChain %_ptr_Function_float %center %uint_0
%295 = OpLoad %float %294
OpStore %293 %295
%297 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_9
%298 = OpAccessChain %_ptr_Function_float %center %uint_1
%299 = OpLoad %float %298
OpStore %297 %299
%301 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_10
%302 = OpAccessChain %_ptr_Function_float %center %uint_2
%303 = OpLoad %float %302
OpStore %301 %303
OpBranch %287
%287 = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_count = OpFunction %void None %177 %main_count = OpFunction %void None %193
%290 = OpLabel %305 = OpLabel
%292 = OpLoad %v3uint %GlobalInvocationID_1 %307 = OpLoad %v3uint %GlobalInvocationID_1
%291 = OpFunctionCall %void %main_count_inner %292 %306 = OpFunctionCall %void %main_count_inner %307
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_create_lut_inner = OpFunction %void None %206 %main_create_lut_inner = OpFunction %void None %222
%GlobalInvocationID_0 = OpFunctionParameter %v3uint %GlobalInvocationID_0 = OpFunctionParameter %v3uint
%295 = OpLabel %310 = OpLabel
%voxelIndex_0 = OpVariable %_ptr_Function_uint Function %143 %voxelIndex_0 = OpVariable %_ptr_Function_uint Function %40
%maxVoxels = OpVariable %_ptr_Function_uint Function %143 %maxVoxels = OpVariable %_ptr_Function_uint Function %40
%numTriangles = OpVariable %_ptr_Function_uint Function %143 %numTriangles = OpVariable %_ptr_Function_uint Function %40
%offset = OpVariable %_ptr_Function_int Function %190 %offset = OpVariable %_ptr_Function_int Function %206
%296 = OpCompositeExtract %uint %GlobalInvocationID_0 0 %311 = OpCompositeExtract %uint %GlobalInvocationID_0 0
OpStore %voxelIndex_0 %296 OpStore %voxelIndex_0 %311
%298 = OpFunctionCall %void %doIgnore %313 = OpFunctionCall %void %doIgnore
%299 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %314 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%300 = OpLoad %uint %299 %315 = OpLoad %uint %314
%301 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %316 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%302 = OpLoad %uint %301 %317 = OpLoad %uint %316
%303 = OpIMul %uint %300 %302 %318 = OpIMul %uint %315 %317
%304 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %319 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%305 = OpLoad %uint %304 %320 = OpLoad %uint %319
%306 = OpIMul %uint %303 %305 %321 = OpIMul %uint %318 %320
OpStore %maxVoxels %306 OpStore %maxVoxels %321
%308 = OpLoad %uint %voxelIndex_0 %323 = OpLoad %uint %voxelIndex_0
%309 = OpLoad %uint %maxVoxels %324 = OpLoad %uint %maxVoxels
%310 = OpUGreaterThanEqual %bool %308 %309 %325 = OpUGreaterThanEqual %bool %323 %324
OpSelectionMerge %311 None OpSelectionMerge %326 None
OpBranchConditional %310 %312 %311 OpBranchConditional %325 %327 %326
%312 = OpLabel %327 = OpLabel
OpReturn OpReturn
%311 = OpLabel %326 = OpLabel
%315 = OpLoad %uint %voxelIndex_0 %330 = OpLoad %uint %voxelIndex_0
%316 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %315 %331 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %330
%313 = OpAtomicLoad %uint %316 %uint_1 %uint_0 %328 = OpAtomicLoad %uint %331 %uint_1 %uint_0
OpStore %numTriangles %313 OpStore %numTriangles %328
OpStore %offset %int_n1 OpStore %offset %int_n1
%320 = OpLoad %uint %numTriangles %335 = OpLoad %uint %numTriangles
%321 = OpUGreaterThan %bool %320 %143 %336 = OpUGreaterThan %bool %335 %40
OpSelectionMerge %322 None OpSelectionMerge %337 None
OpBranchConditional %321 %323 %322 OpBranchConditional %336 %338 %337
%323 = OpLabel %338 = OpLabel
%326 = OpAccessChain %_ptr_StorageBuffer_uint_0 %dbg %uint_0 %uint_0 %341 = OpAccessChain %_ptr_StorageBuffer_uint_0 %dbg %uint_0 %uint_0
%327 = OpLoad %uint %numTriangles %342 = OpLoad %uint %numTriangles
%324 = OpAtomicIAdd %uint %326 %uint_1 %uint_0 %327 %339 = OpAtomicIAdd %uint %341 %uint_1 %uint_0 %342
%328 = OpBitcast %int %324 %343 = OpBitcast %int %339
OpStore %offset %328 OpStore %offset %343
OpBranch %322 OpBranch %337
%322 = OpLabel %337 = OpLabel
%331 = OpLoad %uint %voxelIndex_0 %346 = OpLoad %uint %voxelIndex_0
%332 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %331 %347 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %346
%333 = OpLoad %int %offset %348 = OpLoad %int %offset
OpAtomicStore %332 %uint_1 %uint_0 %333 OpAtomicStore %347 %uint_1 %uint_0 %348
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_create_lut = OpFunction %void None %177 %main_create_lut = OpFunction %void None %193
%335 = OpLabel %350 = OpLabel
%337 = OpLoad %v3uint %GlobalInvocationID_2 %352 = OpLoad %v3uint %GlobalInvocationID_2
%336 = OpFunctionCall %void %main_create_lut_inner %337 %351 = OpFunctionCall %void %main_create_lut_inner %352
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_sort_triangles_inner = OpFunction %void None %206 %main_sort_triangles_inner = OpFunction %void None %222
%GlobalInvocationID_4 = OpFunctionParameter %v3uint %GlobalInvocationID_4 = OpFunctionParameter %v3uint
%340 = OpLabel %355 = OpLabel
%triangleIndex_0 = OpVariable %_ptr_Function_uint Function %143 %triangleIndex_0 = OpVariable %_ptr_Function_uint Function %40
%i0_0 = OpVariable %_ptr_Function_uint Function %143 %i0_0 = OpVariable %_ptr_Function_uint Function %40
%i1_0 = OpVariable %_ptr_Function_uint Function %143 %i1_0 = OpVariable %_ptr_Function_uint Function %40
%i2_0 = OpVariable %_ptr_Function_uint Function %143 %i2_0 = OpVariable %_ptr_Function_uint Function %40
%p0_0 = OpVariable %_ptr_Function_v3float Function %52 %p0_0 = OpVariable %_ptr_Function_v3float Function %69
%p1_0 = OpVariable %_ptr_Function_v3float Function %52 %p1_0 = OpVariable %_ptr_Function_v3float Function %69
%p2_0 = OpVariable %_ptr_Function_v3float Function %52 %p2_0 = OpVariable %_ptr_Function_v3float Function %69
%383 = OpVariable %_ptr_Function_v3float Function %52 %398 = OpVariable %_ptr_Function_v3float Function %69
%center_0 = OpVariable %_ptr_Function_v3float Function %52 %center_0 = OpVariable %_ptr_Function_v3float Function %69
%voxelPos_1 = OpVariable %_ptr_Function_v3float Function %52 %voxelPos_1 = OpVariable %_ptr_Function_v3float Function %69
%voxelIndex_1 = OpVariable %_ptr_Function_uint Function %143 %voxelIndex_1 = OpVariable %_ptr_Function_uint Function %40
%triangleOffset = OpVariable %_ptr_Function_int Function %190 %triangleOffset = OpVariable %_ptr_Function_int Function %206
%341 = OpCompositeExtract %uint %GlobalInvocationID_4 0 %356 = OpCompositeExtract %uint %GlobalInvocationID_4 0
OpStore %triangleIndex_0 %341 OpStore %triangleIndex_0 %356
%343 = OpFunctionCall %void %doIgnore %358 = OpFunctionCall %void %doIgnore
%344 = OpLoad %uint %triangleIndex_0 %359 = OpLoad %uint %triangleIndex_0
%345 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %360 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0
%346 = OpLoad %uint %345 %361 = OpLoad %uint %360
%347 = OpUGreaterThanEqual %bool %344 %346 %362 = OpUGreaterThanEqual %bool %359 %361
OpSelectionMerge %348 None OpSelectionMerge %363 None
OpBranchConditional %347 %349 %348 OpBranchConditional %362 %364 %363
%349 = OpLabel %364 = OpLabel
OpReturn OpReturn
%348 = OpLabel %363 = OpLabel
%350 = OpLoad %uint %triangleIndex_0 %365 = OpLoad %uint %triangleIndex_0
%351 = OpIMul %uint %uint_3 %350 %366 = OpIMul %uint %uint_3 %365
%352 = OpIAdd %uint %351 %143 %367 = OpIAdd %uint %366 %40
%353 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %352 %368 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %367
%354 = OpLoad %uint %353 %369 = OpLoad %uint %368
OpStore %i0_0 %354 OpStore %i0_0 %369
%356 = OpLoad %uint %triangleIndex_0 %371 = OpLoad %uint %triangleIndex_0
%357 = OpIMul %uint %uint_3 %356 %372 = OpIMul %uint %uint_3 %371
%358 = OpIAdd %uint %357 %uint_1 %373 = OpIAdd %uint %372 %uint_1
%359 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %358 %374 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %373
%360 = OpLoad %uint %359 %375 = OpLoad %uint %374
OpStore %i1_0 %360 OpStore %i1_0 %375
%362 = OpLoad %uint %triangleIndex_0 %377 = OpLoad %uint %triangleIndex_0
%363 = OpIMul %uint %uint_3 %362 %378 = OpIMul %uint %uint_3 %377
%364 = OpIAdd %uint %363 %uint_2 %379 = OpIAdd %uint %378 %uint_2
%365 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %364 %380 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %379
%366 = OpLoad %uint %365 %381 = OpLoad %uint %380
OpStore %i2_0 %366 OpStore %i2_0 %381
%369 = OpLoad %uint %i0_0 %384 = OpLoad %uint %i0_0
%368 = OpFunctionCall %v3float %loadPosition %369 %383 = OpFunctionCall %v3float %loadPosition %384
OpStore %p0_0 %368 OpStore %p0_0 %383
%372 = OpLoad %uint %i1_0 %387 = OpLoad %uint %i1_0
%371 = OpFunctionCall %v3float %loadPosition %372 %386 = OpFunctionCall %v3float %loadPosition %387
OpStore %p1_0 %371 OpStore %p1_0 %386
%375 = OpLoad %uint %i2_0 %390 = OpLoad %uint %i2_0
%374 = OpFunctionCall %v3float %loadPosition %375 %389 = OpFunctionCall %v3float %loadPosition %390
OpStore %p2_0 %374 OpStore %p2_0 %389
%377 = OpLoad %v3float %p0_0 %392 = OpLoad %v3float %p0_0
%378 = OpLoad %v3float %p1_0 %393 = OpLoad %v3float %p1_0
%379 = OpFAdd %v3float %377 %378 %394 = OpFAdd %v3float %392 %393
%380 = OpLoad %v3float %p2_0 %395 = OpLoad %v3float %p2_0
%381 = OpFAdd %v3float %379 %380 %396 = OpFAdd %v3float %394 %395
%384 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 %399 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
%382 = OpFDiv %v3float %381 %384 %397 = OpFDiv %v3float %396 %399
OpStore %center_0 %382 OpStore %center_0 %397
%387 = OpLoad %v3float %center_0 %402 = OpLoad %v3float %center_0
%386 = OpFunctionCall %v3float %toVoxelPos %387 %401 = OpFunctionCall %v3float %toVoxelPos %402
OpStore %voxelPos_1 %386 OpStore %voxelPos_1 %401
%390 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 %405 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1
%391 = OpLoad %uint %390 %406 = OpLoad %uint %405
%392 = OpLoad %v3float %voxelPos_1 %407 = OpLoad %v3float %voxelPos_1
%389 = OpFunctionCall %uint %toIndex1D %391 %392 %404 = OpFunctionCall %uint %toIndex1D %406 %407
OpStore %voxelIndex_1 %389 OpStore %voxelIndex_1 %404
%396 = OpLoad %uint %voxelIndex_1 %411 = OpLoad %uint %voxelIndex_1
%397 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %396 %412 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %411
%394 = OpAtomicIAdd %int %397 %uint_1 %uint_0 %int_1 %409 = OpAtomicIAdd %int %412 %uint_1 %uint_0 %int_1
OpStore %triangleOffset %394 OpStore %triangleOffset %409
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_sort_triangles = OpFunction %void None %177 %main_sort_triangles = OpFunction %void None %193
%401 = OpLabel %416 = OpLabel
%403 = OpLoad %v3uint %GlobalInvocationID_3 %418 = OpLoad %v3uint %GlobalInvocationID_3
%402 = OpFunctionCall %void %main_sort_triangles_inner %403 %417 = OpFunctionCall %void %main_sort_triangles_inner %418
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,5 +1,5 @@
int4 value_or_one_if_zero_int4(int4 value) { int4 tint_div(int4 lhs, int4 rhs) {
return value == int4(0, 0, 0, 0) ? int4(1, 1, 1, 1) : value; return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs));
} }
cbuffer cbuffer_x_4 : register(b0, space0) { cbuffer cbuffer_x_4 : register(b0, space0) {
@ -25,7 +25,8 @@ bool test_int_S1_c0_b() {
ok = true; ok = true;
x_41 = false; x_41 = false;
if (true) { if (true) {
x_40 = all((((0).xxxx / value_or_one_if_zero_int4(int4(x_27, x_27, x_27, x_27))) == (0).xxxx)); const int4 tint_symbol_3 = tint_div((0).xxxx, int4(x_27, x_27, x_27, x_27));
x_40 = all((tint_symbol_3 == (0).xxxx));
x_41 = x_40; x_41 = x_40;
} }
ok = x_41; ok = x_41;
@ -47,11 +48,11 @@ bool test_int_S1_c0_b() {
ok = x_55; ok = x_55;
const int4 x_58 = (x_50 * (2).xxxx); const int4 x_58 = (x_50 * (2).xxxx);
val = x_58; val = x_58;
const int4 x_59 = (x_58 / (2).xxxx); const int4 x_59 = tint_div(x_58, (2).xxxx);
val = x_59; val = x_59;
const int4 x_60 = (x_59 * (2).xxxx); const int4 x_60 = (x_59 * (2).xxxx);
val = x_60; val = x_60;
const int4 x_61 = (x_60 / (2).xxxx); const int4 x_61 = tint_div(x_60, (2).xxxx);
val = x_61; val = x_61;
x_66 = false; x_66 = false;
if (x_55) { if (x_55) {
@ -151,8 +152,8 @@ main_out main_inner(bool sk_Clockwise_param, float4 vcolor_S0_param) {
sk_Clockwise = sk_Clockwise_param; sk_Clockwise = sk_Clockwise_param;
vcolor_S0 = vcolor_S0_param; vcolor_S0 = vcolor_S0_param;
main_1(); main_1();
const main_out tint_symbol_5 = {sk_FragColor}; const main_out tint_symbol_6 = {sk_FragColor};
return tint_symbol_5; return tint_symbol_6;
} }
tint_symbol_2 main(tint_symbol_1 tint_symbol) { tint_symbol_2 main(tint_symbol_1 tint_symbol) {

View File

@ -1,5 +1,5 @@
int4 value_or_one_if_zero_int4(int4 value) { int4 tint_div(int4 lhs, int4 rhs) {
return value == int4(0, 0, 0, 0) ? int4(1, 1, 1, 1) : value; return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs));
} }
cbuffer cbuffer_x_4 : register(b0, space0) { cbuffer cbuffer_x_4 : register(b0, space0) {
@ -25,7 +25,8 @@ bool test_int_S1_c0_b() {
ok = true; ok = true;
x_41 = false; x_41 = false;
if (true) { if (true) {
x_40 = all((((0).xxxx / value_or_one_if_zero_int4(int4(x_27, x_27, x_27, x_27))) == (0).xxxx)); const int4 tint_symbol_3 = tint_div((0).xxxx, int4(x_27, x_27, x_27, x_27));
x_40 = all((tint_symbol_3 == (0).xxxx));
x_41 = x_40; x_41 = x_40;
} }
ok = x_41; ok = x_41;
@ -47,11 +48,11 @@ bool test_int_S1_c0_b() {
ok = x_55; ok = x_55;
const int4 x_58 = (x_50 * (2).xxxx); const int4 x_58 = (x_50 * (2).xxxx);
val = x_58; val = x_58;
const int4 x_59 = (x_58 / (2).xxxx); const int4 x_59 = tint_div(x_58, (2).xxxx);
val = x_59; val = x_59;
const int4 x_60 = (x_59 * (2).xxxx); const int4 x_60 = (x_59 * (2).xxxx);
val = x_60; val = x_60;
const int4 x_61 = (x_60 / (2).xxxx); const int4 x_61 = tint_div(x_60, (2).xxxx);
val = x_61; val = x_61;
x_66 = false; x_66 = false;
if (x_55) { if (x_55) {
@ -151,8 +152,8 @@ main_out main_inner(bool sk_Clockwise_param, float4 vcolor_S0_param) {
sk_Clockwise = sk_Clockwise_param; sk_Clockwise = sk_Clockwise_param;
vcolor_S0 = vcolor_S0_param; vcolor_S0 = vcolor_S0_param;
main_1(); main_1();
const main_out tint_symbol_5 = {sk_FragColor}; const main_out tint_symbol_6 = {sk_FragColor};
return tint_symbol_5; return tint_symbol_6;
} }
tint_symbol_2 main(tint_symbol_1 tint_symbol) { tint_symbol_2 main(tint_symbol_1 tint_symbol) {

View File

@ -3,6 +3,10 @@ precision mediump float;
layout(location = 0) in vec4 vcolor_S0_param_1; layout(location = 0) in vec4 vcolor_S0_param_1;
layout(location = 0) out vec4 sk_FragColor_1_1; layout(location = 0) out vec4 sk_FragColor_1_1;
ivec4 tint_div(ivec4 lhs, ivec4 rhs) {
return (lhs / mix(rhs, ivec4(1), bvec4(uvec4(equal(rhs, ivec4(0))) | uvec4(bvec4(uvec4(equal(lhs, ivec4(-2147483648))) & uvec4(equal(rhs, ivec4(-1))))))));
}
struct UniformBuffer { struct UniformBuffer {
uint pad; uint pad;
uint pad_1; uint pad_1;
@ -40,7 +44,8 @@ bool test_int_S1_c0_b() {
ok = true; ok = true;
x_41 = false; x_41 = false;
if (true) { if (true) {
x_40 = all(equal((ivec4(0) / ivec4(x_27, x_27, x_27, x_27)), ivec4(0))); ivec4 tint_symbol_1 = tint_div(ivec4(0), ivec4(x_27, x_27, x_27, x_27));
x_40 = all(equal(tint_symbol_1, ivec4(0)));
x_41 = x_40; x_41 = x_40;
} }
ok = x_41; ok = x_41;
@ -62,11 +67,11 @@ bool test_int_S1_c0_b() {
ok = x_55; ok = x_55;
ivec4 x_58 = (x_50 * ivec4(2)); ivec4 x_58 = (x_50 * ivec4(2));
val = x_58; val = x_58;
ivec4 x_59 = (x_58 / ivec4(2)); ivec4 x_59 = tint_div(x_58, ivec4(2));
val = x_59; val = x_59;
ivec4 x_60 = (x_59 * ivec4(2)); ivec4 x_60 = (x_59 * ivec4(2));
val = x_60; val = x_60;
ivec4 x_61 = (x_60 / ivec4(2)); ivec4 x_61 = tint_div(x_60, ivec4(2));
val = x_61; val = x_61;
x_66 = false; x_66 = false;
if (x_55) { if (x_55) {
@ -159,8 +164,8 @@ main_out tint_symbol(bool sk_Clockwise_param, vec4 vcolor_S0_param) {
sk_Clockwise = sk_Clockwise_param; sk_Clockwise = sk_Clockwise_param;
vcolor_S0 = vcolor_S0_param; vcolor_S0 = vcolor_S0_param;
main_1(); main_1();
main_out tint_symbol_1 = main_out(sk_FragColor); main_out tint_symbol_2 = main_out(sk_FragColor);
return tint_symbol_1; return tint_symbol_2;
} }
void main() { void main() {

View File

@ -14,6 +14,10 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
int4 tint_div(int4 lhs, int4 rhs) {
return (lhs / select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1))))));
}
struct UniformBuffer { struct UniformBuffer {
/* 0x0000 */ tint_array<int8_t, 16> tint_pad; /* 0x0000 */ tint_array<int8_t, 16> tint_pad;
/* 0x0010 */ float unknownInput_S1_c0; /* 0x0010 */ float unknownInput_S1_c0;
@ -23,7 +27,7 @@ struct UniformBuffer {
/* 0x0040 */ float3x3 umatrix_S1; /* 0x0040 */ float3x3 umatrix_S1;
}; };
bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_6) {
int unknown = 0; int unknown = 0;
bool ok = false; bool ok = false;
int4 val = 0; int4 val = 0;
@ -33,13 +37,14 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) {
bool x_55 = false; bool x_55 = false;
bool x_65 = false; bool x_65 = false;
bool x_66 = false; bool x_66 = false;
float const x_26 = (*(tint_symbol_5)).unknownInput_S1_c0; float const x_26 = (*(tint_symbol_6)).unknownInput_S1_c0;
int const x_27 = int(x_26); int const x_27 = int(x_26);
unknown = x_27; unknown = x_27;
ok = true; ok = true;
x_41 = false; x_41 = false;
if (true) { if (true) {
x_40 = all(((int4(0) / int4(x_27, x_27, x_27, x_27)) == int4(0))); int4 const tint_symbol_4 = tint_div(int4(0), int4(x_27, x_27, x_27, x_27));
x_40 = all((tint_symbol_4 == int4(0)));
x_41 = x_40; x_41 = x_40;
} }
ok = x_41; ok = x_41;
@ -61,11 +66,11 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) {
ok = x_55; ok = x_55;
int4 const x_58 = as_type<int4>((as_type<uint4>(x_50) * as_type<uint4>(int4(2)))); int4 const x_58 = as_type<int4>((as_type<uint4>(x_50) * as_type<uint4>(int4(2))));
val = x_58; val = x_58;
int4 const x_59 = (x_58 / int4(2)); int4 const x_59 = tint_div(x_58, int4(2));
val = x_59; val = x_59;
int4 const x_60 = as_type<int4>((as_type<uint4>(x_59) * as_type<uint4>(int4(2)))); int4 const x_60 = as_type<int4>((as_type<uint4>(x_59) * as_type<uint4>(int4(2))));
val = x_60; val = x_60;
int4 const x_61 = (x_60 / int4(2)); int4 const x_61 = tint_div(x_60, int4(2));
val = x_61; val = x_61;
x_66 = false; x_66 = false;
if (x_55) { if (x_55) {
@ -76,7 +81,7 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) {
return x_66; return x_66;
} }
void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* const tint_symbol_7, thread float4* const tint_symbol_8) { void main_1(thread float4* const tint_symbol_7, const constant UniformBuffer* const tint_symbol_8, thread float4* const tint_symbol_9) {
float4 outputColor_S0 = 0.0f; float4 outputColor_S0 = 0.0f;
float4 output_S1 = 0.0f; float4 output_S1 = 0.0f;
float x_8_unknown = 0.0f; float x_8_unknown = 0.0f;
@ -91,9 +96,9 @@ void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* co
bool x_111 = false; bool x_111 = false;
bool x_114 = false; bool x_114 = false;
bool x_115 = false; bool x_115 = false;
float4 const x_72 = *(tint_symbol_6); float4 const x_72 = *(tint_symbol_7);
outputColor_S0 = x_72; outputColor_S0 = x_72;
float const x_77 = (*(tint_symbol_7)).unknownInput_S1_c0; float const x_77 = (*(tint_symbol_8)).unknownInput_S1_c0;
x_8_unknown = x_77; x_8_unknown = x_77;
x_9_ok = true; x_9_ok = true;
x_87 = false; x_87 = false;
@ -134,19 +139,19 @@ void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* co
x_9_ok = x_111; x_9_ok = x_111;
x_115 = false; x_115 = false;
if (x_111) { if (x_111) {
x_114 = test_int_S1_c0_b(tint_symbol_7); x_114 = test_int_S1_c0_b(tint_symbol_8);
x_115 = x_114; x_115 = x_114;
} }
if (x_115) { if (x_115) {
float4 const x_122 = (*(tint_symbol_7)).ucolorGreen_S1_c0; float4 const x_122 = (*(tint_symbol_8)).ucolorGreen_S1_c0;
x_116 = x_122; x_116 = x_122;
} else { } else {
float4 const x_124 = (*(tint_symbol_7)).ucolorRed_S1_c0; float4 const x_124 = (*(tint_symbol_8)).ucolorRed_S1_c0;
x_116 = x_124; x_116 = x_124;
} }
float4 const x_125 = x_116; float4 const x_125 = x_116;
output_S1 = x_125; output_S1 = x_125;
*(tint_symbol_8) = x_125; *(tint_symbol_9) = x_125;
return; return;
} }
@ -162,19 +167,19 @@ struct tint_symbol_3 {
float4 sk_FragColor_1 [[color(0)]]; float4 sk_FragColor_1 [[color(0)]];
}; };
main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread float4* const tint_symbol_10, const constant UniformBuffer* const tint_symbol_11, thread float4* const tint_symbol_12) { main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread float4* const tint_symbol_11, const constant UniformBuffer* const tint_symbol_12, thread float4* const tint_symbol_13) {
thread bool tint_symbol_9 = false; thread bool tint_symbol_10 = false;
tint_symbol_9 = sk_Clockwise_param; tint_symbol_10 = sk_Clockwise_param;
*(tint_symbol_10) = vcolor_S0_param; *(tint_symbol_11) = vcolor_S0_param;
main_1(tint_symbol_10, tint_symbol_11, tint_symbol_12); main_1(tint_symbol_11, tint_symbol_12, tint_symbol_13);
main_out const tint_symbol_4 = {.sk_FragColor_1=*(tint_symbol_12)}; main_out const tint_symbol_5 = {.sk_FragColor_1=*(tint_symbol_13)};
return tint_symbol_4; return tint_symbol_5;
} }
fragment tint_symbol_3 tint_symbol(const constant UniformBuffer* tint_symbol_14 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) { fragment tint_symbol_3 tint_symbol(const constant UniformBuffer* tint_symbol_15 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
thread float4 tint_symbol_13 = 0.0f; thread float4 tint_symbol_14 = 0.0f;
thread float4 tint_symbol_15 = 0.0f; thread float4 tint_symbol_16 = 0.0f;
main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_symbol_13), tint_symbol_14, &(tint_symbol_15)); main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_symbol_14), tint_symbol_15, &(tint_symbol_16));
tint_symbol_3 wrapper_result = {}; tint_symbol_3 wrapper_result = {};
wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1; wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1;
return wrapper_result; return wrapper_result;

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 177 ; Bound: 193
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -21,6 +21,9 @@
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %vcolor_S0 "vcolor_S0" OpName %vcolor_S0 "vcolor_S0"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %test_int_S1_c0_b "test_int_S1_c0_b" OpName %test_int_S1_c0_b "test_int_S1_c0_b"
OpName %unknown "unknown" OpName %unknown "unknown"
OpName %ok "ok" OpName %ok "ok"
@ -89,122 +92,140 @@
%21 = OpConstantNull %bool %21 = OpConstantNull %bool
%sk_Clockwise = OpVariable %_ptr_Private_bool Private %21 %sk_Clockwise = OpVariable %_ptr_Private_bool Private %21
%vcolor_S0 = OpVariable %_ptr_Private_v4float Private %10 %vcolor_S0 = OpVariable %_ptr_Private_v4float Private %10
%23 = OpTypeFunction %bool
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%_ptr_Function_int = OpTypePointer Function %int
%29 = OpConstantNull %int
%_ptr_Function_bool = OpTypePointer Function %bool
%v4int = OpTypeVector %int 4 %v4int = OpTypeVector %int 4
%23 = OpTypeFunction %v4int %v4int %v4int
%31 = OpConstantNull %v4int
%v4bool = OpTypeVector %bool 4
%int_n2147483648 = OpConstant %int -2147483648
%35 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648
%int_n1 = OpConstant %int -1
%38 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1
%int_1 = OpConstant %int 1
%43 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1
%45 = OpTypeFunction %bool
%_ptr_Function_int = OpTypePointer Function %int
%50 = OpConstantNull %int
%_ptr_Function_bool = OpTypePointer Function %bool
%_ptr_Function_v4int = OpTypePointer Function %v4int %_ptr_Function_v4int = OpTypePointer Function %v4int
%35 = OpConstantNull %v4int
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float %_ptr_Uniform_float = OpTypePointer Uniform %float
%true = OpConstantTrue %bool %true = OpConstantTrue %bool
%v4bool = OpTypeVector %bool 4
%int_1 = OpConstant %int 1
%60 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%73 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 %89 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2
%void = OpTypeVoid %void = OpTypeVoid
%86 = OpTypeFunction %void %102 = OpTypeFunction %void
%_ptr_Function_v4float = OpTypePointer Function %v4float %_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Function_float = OpTypePointer Function %float %_ptr_Function_float = OpTypePointer Function %float
%95 = OpConstantNull %float %111 = OpConstantNull %float
%float_1 = OpConstant %float 1 %float_1 = OpConstant %float 1
%120 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 %136 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
%float_2 = OpConstant %float 2 %float_2 = OpConstant %float 2
%133 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 %149 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%main_out = OpTypeStruct %v4float %main_out = OpTypeStruct %v4float
%162 = OpTypeFunction %main_out %bool %v4float %178 = OpTypeFunction %main_out %bool %v4float
%test_int_S1_c0_b = OpFunction %bool None %23 %tint_div = OpFunction %v4int None %23
%25 = OpLabel %lhs = OpFunctionParameter %v4int
%unknown = OpVariable %_ptr_Function_int Function %29 %rhs = OpFunctionParameter %v4int
%29 = OpLabel
%32 = OpIEqual %v4bool %rhs %31
%36 = OpIEqual %v4bool %lhs %35
%39 = OpIEqual %v4bool %rhs %38
%40 = OpLogicalAnd %v4bool %36 %39
%41 = OpLogicalOr %v4bool %32 %40
%30 = OpSelect %v4int %41 %43 %rhs
%44 = OpSDiv %v4int %lhs %30
OpReturnValue %44
OpFunctionEnd
%test_int_S1_c0_b = OpFunction %bool None %45
%47 = OpLabel
%unknown = OpVariable %_ptr_Function_int Function %50
%ok = OpVariable %_ptr_Function_bool Function %21 %ok = OpVariable %_ptr_Function_bool Function %21
%val = OpVariable %_ptr_Function_v4int Function %35 %val = OpVariable %_ptr_Function_v4int Function %31
%x_40 = OpVariable %_ptr_Function_bool Function %21 %x_40 = OpVariable %_ptr_Function_bool Function %21
%x_41 = OpVariable %_ptr_Function_bool Function %21 %x_41 = OpVariable %_ptr_Function_bool Function %21
%x_54 = OpVariable %_ptr_Function_bool Function %21 %x_54 = OpVariable %_ptr_Function_bool Function %21
%x_55 = OpVariable %_ptr_Function_bool Function %21 %x_55 = OpVariable %_ptr_Function_bool Function %21
%x_65 = OpVariable %_ptr_Function_bool Function %21 %x_65 = OpVariable %_ptr_Function_bool Function %21
%x_66 = OpVariable %_ptr_Function_bool Function %21 %x_66 = OpVariable %_ptr_Function_bool Function %21
%45 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 %64 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0
%46 = OpLoad %float %45 %65 = OpLoad %float %64
%47 = OpConvertFToS %int %46 %66 = OpConvertFToS %int %65
OpStore %unknown %47 OpStore %unknown %66
OpStore %ok %true OpStore %ok %true
OpStore %x_41 %21 OpStore %x_41 %21
OpSelectionMerge %49 None OpSelectionMerge %68 None
OpBranchConditional %true %50 %49 OpBranchConditional %true %69 %68
%50 = OpLabel %69 = OpLabel
%52 = OpCompositeConstruct %v4int %47 %47 %47 %47 %71 = OpCompositeConstruct %v4int %66 %66 %66 %66
%53 = OpSDiv %v4int %35 %52 %70 = OpFunctionCall %v4int %tint_div %31 %71
%54 = OpIEqual %v4bool %53 %35 %73 = OpIEqual %v4bool %70 %31
%51 = OpAll %bool %54 %72 = OpAll %bool %73
OpStore %x_40 %51 OpStore %x_40 %72
%56 = OpLoad %bool %x_40 %74 = OpLoad %bool %x_40
OpStore %x_41 %56 OpStore %x_41 %74
OpBranch %49 OpBranch %68
%49 = OpLabel %68 = OpLabel
%57 = OpLoad %bool %x_41 %75 = OpLoad %bool %x_41
OpStore %ok %57 OpStore %ok %75
%58 = OpCompositeConstruct %v4int %47 %47 %47 %47 %76 = OpCompositeConstruct %v4int %66 %66 %66 %66
OpStore %val %58
%61 = OpIAdd %v4int %58 %60
OpStore %val %61
%62 = OpISub %v4int %61 %60
OpStore %val %62
%63 = OpIAdd %v4int %62 %60
OpStore %val %63
%64 = OpISub %v4int %63 %60
OpStore %val %64
OpStore %x_55 %21
%65 = OpLoad %bool %x_41
OpSelectionMerge %66 None
OpBranchConditional %65 %67 %66
%67 = OpLabel
%69 = OpIEqual %v4bool %64 %58
%68 = OpAll %bool %69
OpStore %x_54 %68
%70 = OpLoad %bool %x_54
OpStore %x_55 %70
OpBranch %66
%66 = OpLabel
%71 = OpLoad %bool %x_55
OpStore %ok %71
%74 = OpIMul %v4int %64 %73
OpStore %val %74
%75 = OpSDiv %v4int %74 %73
OpStore %val %75
%76 = OpIMul %v4int %75 %73
OpStore %val %76 OpStore %val %76
%77 = OpSDiv %v4int %76 %73 %77 = OpIAdd %v4int %76 %43
OpStore %val %77 OpStore %val %77
%78 = OpISub %v4int %77 %43
OpStore %val %78
%79 = OpIAdd %v4int %78 %43
OpStore %val %79
%80 = OpISub %v4int %79 %43
OpStore %val %80
OpStore %x_55 %21
%81 = OpLoad %bool %x_41
OpSelectionMerge %82 None
OpBranchConditional %81 %83 %82
%83 = OpLabel
%85 = OpIEqual %v4bool %80 %76
%84 = OpAll %bool %85
OpStore %x_54 %84
%86 = OpLoad %bool %x_54
OpStore %x_55 %86
OpBranch %82
%82 = OpLabel
%87 = OpLoad %bool %x_55
OpStore %ok %87
%90 = OpIMul %v4int %80 %89
OpStore %val %90
%91 = OpFunctionCall %v4int %tint_div %90 %89
OpStore %val %91
%92 = OpIMul %v4int %91 %89
OpStore %val %92
%93 = OpFunctionCall %v4int %tint_div %92 %89
OpStore %val %93
OpStore %x_66 %21 OpStore %x_66 %21
%78 = OpLoad %bool %x_55 %94 = OpLoad %bool %x_55
OpSelectionMerge %79 None OpSelectionMerge %95 None
OpBranchConditional %78 %80 %79 OpBranchConditional %94 %96 %95
%80 = OpLabel %96 = OpLabel
%82 = OpIEqual %v4bool %77 %58 %98 = OpIEqual %v4bool %93 %76
%81 = OpAll %bool %82 %97 = OpAll %bool %98
OpStore %x_65 %81 OpStore %x_65 %97
%83 = OpLoad %bool %x_65 %99 = OpLoad %bool %x_65
OpStore %x_66 %83 OpStore %x_66 %99
OpBranch %79 OpBranch %95
%79 = OpLabel %95 = OpLabel
%84 = OpLoad %bool %x_66 %100 = OpLoad %bool %x_66
OpStore %ok %84 OpStore %ok %100
%85 = OpLoad %bool %x_66 %101 = OpLoad %bool %x_66
OpReturnValue %85 OpReturnValue %101
OpFunctionEnd OpFunctionEnd
%main_1 = OpFunction %void None %86 %main_1 = OpFunction %void None %102
%89 = OpLabel %105 = OpLabel
%outputColor_S0 = OpVariable %_ptr_Function_v4float Function %10 %outputColor_S0 = OpVariable %_ptr_Function_v4float Function %10
%output_S1 = OpVariable %_ptr_Function_v4float Function %10 %output_S1 = OpVariable %_ptr_Function_v4float Function %10
%x_8_unknown = OpVariable %_ptr_Function_float Function %95 %x_8_unknown = OpVariable %_ptr_Function_float Function %111
%x_9_ok = OpVariable %_ptr_Function_bool Function %21 %x_9_ok = OpVariable %_ptr_Function_bool Function %21
%x_10_val = OpVariable %_ptr_Function_v4float Function %10 %x_10_val = OpVariable %_ptr_Function_v4float Function %10
%x_116 = OpVariable %_ptr_Function_v4float Function %10 %x_116 = OpVariable %_ptr_Function_v4float Function %10
@ -216,120 +237,120 @@
%x_111 = OpVariable %_ptr_Function_bool Function %21 %x_111 = OpVariable %_ptr_Function_bool Function %21
%x_114 = OpVariable %_ptr_Function_bool Function %21 %x_114 = OpVariable %_ptr_Function_bool Function %21
%x_115 = OpVariable %_ptr_Function_bool Function %21 %x_115 = OpVariable %_ptr_Function_bool Function %21
%107 = OpLoad %v4float %vcolor_S0 %123 = OpLoad %v4float %vcolor_S0
OpStore %outputColor_S0 %107 OpStore %outputColor_S0 %123
%108 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 %124 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0
%109 = OpLoad %float %108 %125 = OpLoad %float %124
OpStore %x_8_unknown %109 OpStore %x_8_unknown %125
OpStore %x_9_ok %true OpStore %x_9_ok %true
OpStore %x_87 %21 OpStore %x_87 %21
OpSelectionMerge %110 None
OpBranchConditional %true %111 %110
%111 = OpLabel
%113 = OpCompositeConstruct %v4float %109 %109 %109 %109
%114 = OpFDiv %v4float %10 %113
%115 = OpFOrdEqual %v4bool %114 %10
%112 = OpAll %bool %115
OpStore %x_86 %112
%116 = OpLoad %bool %x_86
OpStore %x_87 %116
OpBranch %110
%110 = OpLabel
%117 = OpLoad %bool %x_87
OpStore %x_9_ok %117
%118 = OpCompositeConstruct %v4float %109 %109 %109 %109
OpStore %x_10_val %118
%121 = OpFAdd %v4float %118 %120
OpStore %x_10_val %121
%122 = OpFSub %v4float %121 %120
OpStore %x_10_val %122
%123 = OpFAdd %v4float %122 %120
OpStore %x_10_val %123
%124 = OpFSub %v4float %123 %120
OpStore %x_10_val %124
OpStore %x_100 %21
%125 = OpLoad %bool %x_87
OpSelectionMerge %126 None OpSelectionMerge %126 None
OpBranchConditional %125 %127 %126 OpBranchConditional %true %127 %126
%127 = OpLabel %127 = OpLabel
%129 = OpFOrdEqual %v4bool %124 %118 %129 = OpCompositeConstruct %v4float %125 %125 %125 %125
%128 = OpAll %bool %129 %130 = OpFDiv %v4float %10 %129
OpStore %x_99 %128 %131 = OpFOrdEqual %v4bool %130 %10
%130 = OpLoad %bool %x_99 %128 = OpAll %bool %131
OpStore %x_100 %130 OpStore %x_86 %128
%132 = OpLoad %bool %x_86
OpStore %x_87 %132
OpBranch %126 OpBranch %126
%126 = OpLabel %126 = OpLabel
%131 = OpLoad %bool %x_100 %133 = OpLoad %bool %x_87
OpStore %x_9_ok %131 OpStore %x_9_ok %133
%134 = OpFMul %v4float %124 %133 %134 = OpCompositeConstruct %v4float %125 %125 %125 %125
OpStore %x_10_val %134 OpStore %x_10_val %134
%135 = OpFDiv %v4float %134 %133 %137 = OpFAdd %v4float %134 %136
OpStore %x_10_val %135
%136 = OpFMul %v4float %135 %133
OpStore %x_10_val %136
%137 = OpFDiv %v4float %136 %133
OpStore %x_10_val %137 OpStore %x_10_val %137
%138 = OpFSub %v4float %137 %136
OpStore %x_10_val %138
%139 = OpFAdd %v4float %138 %136
OpStore %x_10_val %139
%140 = OpFSub %v4float %139 %136
OpStore %x_10_val %140
OpStore %x_100 %21
%141 = OpLoad %bool %x_87
OpSelectionMerge %142 None
OpBranchConditional %141 %143 %142
%143 = OpLabel
%145 = OpFOrdEqual %v4bool %140 %134
%144 = OpAll %bool %145
OpStore %x_99 %144
%146 = OpLoad %bool %x_99
OpStore %x_100 %146
OpBranch %142
%142 = OpLabel
%147 = OpLoad %bool %x_100
OpStore %x_9_ok %147
%150 = OpFMul %v4float %140 %149
OpStore %x_10_val %150
%151 = OpFDiv %v4float %150 %149
OpStore %x_10_val %151
%152 = OpFMul %v4float %151 %149
OpStore %x_10_val %152
%153 = OpFDiv %v4float %152 %149
OpStore %x_10_val %153
OpStore %x_111 %21 OpStore %x_111 %21
%138 = OpLoad %bool %x_100 %154 = OpLoad %bool %x_100
OpSelectionMerge %139 None OpSelectionMerge %155 None
OpBranchConditional %138 %140 %139 OpBranchConditional %154 %156 %155
%140 = OpLabel %156 = OpLabel
%142 = OpFOrdEqual %v4bool %137 %118 %158 = OpFOrdEqual %v4bool %153 %134
%141 = OpAll %bool %142 %157 = OpAll %bool %158
OpStore %x_110 %141 OpStore %x_110 %157
%143 = OpLoad %bool %x_110 %159 = OpLoad %bool %x_110
OpStore %x_111 %143 OpStore %x_111 %159
OpBranch %139 OpBranch %155
%139 = OpLabel %155 = OpLabel
%144 = OpLoad %bool %x_111 %160 = OpLoad %bool %x_111
OpStore %x_9_ok %144 OpStore %x_9_ok %160
OpStore %x_115 %21 OpStore %x_115 %21
%145 = OpLoad %bool %x_111 %161 = OpLoad %bool %x_111
OpSelectionMerge %146 None OpSelectionMerge %162 None
OpBranchConditional %145 %147 %146 OpBranchConditional %161 %163 %162
%147 = OpLabel %163 = OpLabel
%148 = OpFunctionCall %bool %test_int_S1_c0_b %164 = OpFunctionCall %bool %test_int_S1_c0_b
OpStore %x_114 %148 OpStore %x_114 %164
%149 = OpLoad %bool %x_114 %165 = OpLoad %bool %x_114
OpStore %x_115 %149 OpStore %x_115 %165
OpBranch %146 OpBranch %162
%146 = OpLabel %162 = OpLabel
%150 = OpLoad %bool %x_115 %166 = OpLoad %bool %x_115
OpSelectionMerge %151 None OpSelectionMerge %167 None
OpBranchConditional %150 %152 %153 OpBranchConditional %166 %168 %169
%152 = OpLabel %168 = OpLabel
%156 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_2 %172 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_2
%157 = OpLoad %v4float %156 %173 = OpLoad %v4float %172
OpStore %x_116 %157 OpStore %x_116 %173
OpBranch %151 OpBranch %167
%153 = OpLabel %169 = OpLabel
%159 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_1 %175 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_1
%160 = OpLoad %v4float %159 %176 = OpLoad %v4float %175
OpStore %x_116 %160 OpStore %x_116 %176
OpBranch %151 OpBranch %167
%151 = OpLabel %167 = OpLabel
%161 = OpLoad %v4float %x_116 %177 = OpLoad %v4float %x_116
OpStore %output_S1 %161 OpStore %output_S1 %177
OpStore %sk_FragColor %161 OpStore %sk_FragColor %177
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main_inner = OpFunction %main_out None %162 %main_inner = OpFunction %main_out None %178
%sk_Clockwise_param = OpFunctionParameter %bool %sk_Clockwise_param = OpFunctionParameter %bool
%vcolor_S0_param = OpFunctionParameter %v4float %vcolor_S0_param = OpFunctionParameter %v4float
%167 = OpLabel %183 = OpLabel
OpStore %sk_Clockwise %sk_Clockwise_param OpStore %sk_Clockwise %sk_Clockwise_param
OpStore %vcolor_S0 %vcolor_S0_param OpStore %vcolor_S0 %vcolor_S0_param
%168 = OpFunctionCall %void %main_1 %184 = OpFunctionCall %void %main_1
%169 = OpLoad %v4float %sk_FragColor %185 = OpLoad %v4float %sk_FragColor
%170 = OpCompositeConstruct %main_out %169 %186 = OpCompositeConstruct %main_out %185
OpReturnValue %170 OpReturnValue %186
OpFunctionEnd OpFunctionEnd
%main = OpFunction %void None %86 %main = OpFunction %void None %102
%172 = OpLabel %188 = OpLabel
%174 = OpLoad %bool %sk_Clockwise_param_1 %190 = OpLoad %bool %sk_Clockwise_param_1
%175 = OpLoad %v4float %vcolor_S0_param_1 %191 = OpLoad %v4float %vcolor_S0_param_1
%173 = OpFunctionCall %main_out %main_inner %174 %175 %189 = OpFunctionCall %main_out %main_inner %190 %191
%176 = OpCompositeExtract %v4float %173 0 %192 = OpCompositeExtract %v4float %189 0
OpStore %sk_FragColor_1_1 %176 OpStore %sk_FragColor_1_1 %192
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,3 +1,7 @@
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
RWByteAddressBuffer b : register(u0, space0); RWByteAddressBuffer b : register(u0, space0);
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
@ -8,7 +12,8 @@ void main() {
break; break;
} }
const uint p_save = i; const uint p_save = i;
if (((i % 2u) == 0u)) { const uint tint_symbol = tint_mod(i, 2u);
if ((tint_symbol == 0u)) {
{ {
b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u))); b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
i = (i + 1u); i = (i + 1u);

View File

@ -1,3 +1,7 @@
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
RWByteAddressBuffer b : register(u0, space0); RWByteAddressBuffer b : register(u0, space0);
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
@ -8,7 +12,8 @@ void main() {
break; break;
} }
const uint p_save = i; const uint p_save = i;
if (((i % 2u) == 0u)) { const uint tint_symbol = tint_mod(i, 2u);
if ((tint_symbol == 0u)) {
{ {
b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u))); b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
i = (i + 1u); i = (i + 1u);

View File

@ -1,5 +1,9 @@
#version 310 es #version 310 es
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
struct Buf { struct Buf {
uint count; uint count;
uint data[50]; uint data[50];
@ -16,7 +20,8 @@ void tint_symbol() {
break; break;
} }
uint p_save = i; uint p_save = i;
if (((i % 2u) == 0u)) { uint tint_symbol_1 = tint_mod(i, 2u);
if ((tint_symbol_1 == 0u)) {
{ {
b.inner.data[p_save] = (b.inner.data[p_save] * 2u); b.inner.data[p_save] = (b.inner.data[p_save] * 2u);
i = (i + 1u); i = (i + 1u);

View File

@ -14,28 +14,33 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
uint tint_mod(uint lhs, uint rhs) {
return (lhs % select(rhs, 1u, (rhs == 0u)));
}
struct Buf { struct Buf {
/* 0x0000 */ uint count; /* 0x0000 */ uint count;
/* 0x0004 */ tint_array<uint, 50> data; /* 0x0004 */ tint_array<uint, 50> data;
}; };
kernel void tint_symbol(device Buf* tint_symbol_1 [[buffer(0)]]) { kernel void tint_symbol(device Buf* tint_symbol_2 [[buffer(0)]]) {
uint i = 0u; uint i = 0u;
while (true) { while (true) {
if ((i >= (*(tint_symbol_1)).count)) { if ((i >= (*(tint_symbol_2)).count)) {
break; break;
} }
uint const p_save = i; uint const p_save = i;
if (((i % 2u) == 0u)) { uint const tint_symbol_1 = tint_mod(i, 2u);
if ((tint_symbol_1 == 0u)) {
{ {
(*(tint_symbol_1)).data[p_save] = ((*(tint_symbol_1)).data[p_save] * 2u); (*(tint_symbol_2)).data[p_save] = ((*(tint_symbol_2)).data[p_save] * 2u);
i = (i + 1u); i = (i + 1u);
} }
continue; continue;
} }
(*(tint_symbol_1)).data[p_save] = 0u; (*(tint_symbol_2)).data[p_save] = 0u;
{ {
(*(tint_symbol_1)).data[p_save] = ((*(tint_symbol_1)).data[p_save] * 2u); (*(tint_symbol_2)).data[p_save] = ((*(tint_symbol_2)).data[p_save] * 2u);
i = (i + 1u); i = (i + 1u);
} }
} }

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 43 ; Bound: 51
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -13,6 +13,9 @@
OpMemberName %Buf 0 "count" OpMemberName %Buf 0 "count"
OpMemberName %Buf 1 "data" OpMemberName %Buf 1 "data"
OpName %b "b" OpName %b "b"
OpName %tint_mod "tint_mod"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %main "main" OpName %main "main"
OpName %i "i" OpName %i "i"
OpDecorate %b_block Block OpDecorate %b_block Block
@ -29,55 +32,65 @@
%b_block = OpTypeStruct %Buf %b_block = OpTypeStruct %Buf
%_ptr_StorageBuffer_b_block = OpTypePointer StorageBuffer %b_block %_ptr_StorageBuffer_b_block = OpTypePointer StorageBuffer %b_block
%b = OpVariable %_ptr_StorageBuffer_b_block StorageBuffer %b = OpVariable %_ptr_StorageBuffer_b_block StorageBuffer
%8 = OpTypeFunction %uint %uint %uint
%14 = OpConstantNull %uint
%bool = OpTypeBool
%uint_1 = OpConstant %uint 1
%void = OpTypeVoid %void = OpTypeVoid
%8 = OpTypeFunction %void %19 = OpTypeFunction %void
%12 = OpConstantNull %uint
%_ptr_Function_uint = OpTypePointer Function %uint %_ptr_Function_uint = OpTypePointer Function %uint
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
%bool = OpTypeBool
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%uint_1 = OpConstant %uint 1 %tint_mod = OpFunction %uint None %8
%main = OpFunction %void None %8 %lhs = OpFunctionParameter %uint
%11 = OpLabel %rhs = OpFunctionParameter %uint
%i = OpVariable %_ptr_Function_uint Function %12 %12 = OpLabel
OpStore %i %12 %15 = OpIEqual %bool %rhs %14
OpBranch %15 %13 = OpSelect %uint %15 %uint_1 %rhs
%15 = OpLabel %18 = OpUMod %uint %lhs %13
OpLoopMerge %16 %17 None OpReturnValue %18
OpBranch %18 OpFunctionEnd
%18 = OpLabel %main = OpFunction %void None %19
%19 = OpLoad %uint %i %22 = OpLabel
%22 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_0 %i = OpVariable %_ptr_Function_uint Function %14
%23 = OpLoad %uint %22 OpStore %i %14
%24 = OpUGreaterThanEqual %bool %19 %23 OpBranch %25
OpSelectionMerge %26 None %25 = OpLabel
OpBranchConditional %24 %27 %26 OpLoopMerge %26 %27 None
%27 = OpLabel OpBranch %28
OpBranch %16 %28 = OpLabel
%26 = OpLabel
%28 = OpLoad %uint %i
%29 = OpLoad %uint %i %29 = OpLoad %uint %i
%31 = OpUMod %uint %29 %uint_2 %32 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_0
%32 = OpIEqual %bool %31 %12 %33 = OpLoad %uint %32
OpSelectionMerge %33 None %34 = OpUGreaterThanEqual %bool %29 %33
OpBranchConditional %32 %34 %33 OpSelectionMerge %35 None
%34 = OpLabel OpBranchConditional %34 %36 %35
OpBranch %17 %36 = OpLabel
%33 = OpLabel OpBranch %26
%36 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 %35 = OpLabel
OpStore %36 %12 %37 = OpLoad %uint %i
OpBranch %17 %39 = OpLoad %uint %i
%17 = OpLabel %38 = OpFunctionCall %uint %tint_mod %39 %uint_2
%37 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 %41 = OpIEqual %bool %38 %14
%38 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 OpSelectionMerge %42 None
%39 = OpLoad %uint %38 OpBranchConditional %41 %43 %42
%40 = OpIMul %uint %39 %uint_2 %43 = OpLabel
OpStore %37 %40 OpBranch %27
%41 = OpLoad %uint %i %42 = OpLabel
%42 = OpIAdd %uint %41 %uint_1 %44 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37
OpStore %i %42 OpStore %44 %14
OpBranch %15 OpBranch %27
%16 = OpLabel %27 = OpLabel
%45 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37
%46 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37
%47 = OpLoad %uint %46
%48 = OpIMul %uint %47 %uint_2
OpStore %45 %48
%49 = OpLoad %uint %i
%50 = OpIAdd %uint %49 %uint_1
OpStore %i %50
OpBranch %25
%26 = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,3 +1,7 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
ByteAddressBuffer firstMatrix : register(t0, space0); ByteAddressBuffer firstMatrix : register(t0, space0);
ByteAddressBuffer secondMatrix : register(t1, space0); ByteAddressBuffer secondMatrix : register(t1, space0);
RWByteAddressBuffer resultMatrix : register(u2, space0); RWByteAddressBuffer resultMatrix : register(u2, space0);
@ -63,7 +67,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
const uint tileCol = (local_id.x * 4u); const uint tileCol = (local_id.x * 4u);
const uint globalRow = (global_id.y * 4u); const uint globalRow = (global_id.y * 4u);
const uint globalCol = (global_id.x * 4u); const uint globalCol = (global_id.x * 4u);
const uint numTiles = (((uniforms[0].y - 1u) / 64u) + 1u); const uint tint_symbol_2 = tint_div((uniforms[0].y - 1u), 64u);
const uint numTiles = (tint_symbol_2 + 1u);
float acc[16] = (float[16])0; float acc[16] = (float[16])0;
float ACached = 0.0f; float ACached = 0.0f;
float BCached[4] = (float[4])0; float BCached[4] = (float[4])0;
@ -84,8 +89,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
const uint inputRow = (tileRow + innerRow); const uint inputRow = (tileRow + innerRow);
const uint inputCol = (tileColA + innerCol); const uint inputCol = (tileColA + innerCol);
const float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); const float tint_symbol_3 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
mm_Asub[inputRow][inputCol] = tint_symbol_2; mm_Asub[inputRow][inputCol] = tint_symbol_3;
} }
} }
} }
@ -96,8 +101,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
const uint inputRow = (tileRowB + innerRow); const uint inputRow = (tileRowB + innerRow);
const uint inputCol = (tileCol + innerCol); const uint inputCol = (tileCol + innerCol);
const float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); const float tint_symbol_4 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
mm_Bsub[innerCol][inputCol] = tint_symbol_3; mm_Bsub[innerCol][inputCol] = tint_symbol_4;
} }
} }
} }

View File

@ -1,3 +1,7 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
ByteAddressBuffer firstMatrix : register(t0, space0); ByteAddressBuffer firstMatrix : register(t0, space0);
ByteAddressBuffer secondMatrix : register(t1, space0); ByteAddressBuffer secondMatrix : register(t1, space0);
RWByteAddressBuffer resultMatrix : register(u2, space0); RWByteAddressBuffer resultMatrix : register(u2, space0);
@ -63,7 +67,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
const uint tileCol = (local_id.x * 4u); const uint tileCol = (local_id.x * 4u);
const uint globalRow = (global_id.y * 4u); const uint globalRow = (global_id.y * 4u);
const uint globalCol = (global_id.x * 4u); const uint globalCol = (global_id.x * 4u);
const uint numTiles = (((uniforms[0].y - 1u) / 64u) + 1u); const uint tint_symbol_2 = tint_div((uniforms[0].y - 1u), 64u);
const uint numTiles = (tint_symbol_2 + 1u);
float acc[16] = (float[16])0; float acc[16] = (float[16])0;
float ACached = 0.0f; float ACached = 0.0f;
float BCached[4] = (float[4])0; float BCached[4] = (float[4])0;
@ -84,8 +89,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
const uint inputRow = (tileRow + innerRow); const uint inputRow = (tileRow + innerRow);
const uint inputCol = (tileColA + innerCol); const uint inputCol = (tileColA + innerCol);
const float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); const float tint_symbol_3 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
mm_Asub[inputRow][inputCol] = tint_symbol_2; mm_Asub[inputRow][inputCol] = tint_symbol_3;
} }
} }
} }
@ -96,8 +101,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
const uint inputRow = (tileRowB + innerRow); const uint inputRow = (tileRowB + innerRow);
const uint inputCol = (tileCol + innerCol); const uint inputCol = (tileCol + innerCol);
const float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); const float tint_symbol_4 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
mm_Bsub[innerCol][inputCol] = tint_symbol_3; mm_Bsub[innerCol][inputCol] = tint_symbol_4;
} }
} }
} }

View File

@ -1,5 +1,9 @@
#version 310 es #version 310 es
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
struct Uniforms { struct Uniforms {
uint dimAOuter; uint dimAOuter;
uint dimInner; uint dimInner;
@ -74,7 +78,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) {
uint tileCol = (local_id.x * 4u); uint tileCol = (local_id.x * 4u);
uint globalRow = (global_id.y * 4u); uint globalRow = (global_id.y * 4u);
uint globalCol = (global_id.x * 4u); uint globalCol = (global_id.x * 4u);
uint numTiles = (((uniforms.inner.dimInner - 1u) / 64u) + 1u); uint tint_symbol_1 = tint_div((uniforms.inner.dimInner - 1u), 64u);
uint numTiles = (tint_symbol_1 + 1u);
float acc[16] = float[16](0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); float acc[16] = float[16](0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
float ACached = 0.0f; float ACached = 0.0f;
float BCached[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f); float BCached[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f);
@ -95,8 +100,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
uint inputRow = (tileRow + innerRow); uint inputRow = (tileRow + innerRow);
uint inputCol = (tileColA + innerCol); uint inputCol = (tileColA + innerCol);
float tint_symbol_1 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
mm_Asub[inputRow][inputCol] = tint_symbol_1; mm_Asub[inputRow][inputCol] = tint_symbol_2;
} }
} }
} }
@ -107,8 +112,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) {
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
uint inputRow = (tileRowB + innerRow); uint inputRow = (tileRowB + innerRow);
uint inputCol = (tileCol + innerCol); uint inputCol = (tileCol + innerCol);
float tint_symbol_2 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
mm_Bsub[innerCol][inputCol] = tint_symbol_2; mm_Bsub[innerCol][inputCol] = tint_symbol_3;
} }
} }
} }

View File

@ -14,6 +14,10 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
struct Uniforms { struct Uniforms {
/* 0x0000 */ uint dimAOuter; /* 0x0000 */ uint dimAOuter;
/* 0x0004 */ uint dimInner; /* 0x0004 */ uint dimInner;
@ -24,42 +28,43 @@ struct Matrix {
/* 0x0000 */ tint_array<float, 1> numbers; /* 0x0000 */ tint_array<float, 1> numbers;
}; };
float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_3, const device Matrix* const tint_symbol_4) { float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_4, const device Matrix* const tint_symbol_5) {
if (((row < (*(tint_symbol_3)).dimAOuter) && (col < (*(tint_symbol_3)).dimInner))) { if (((row < (*(tint_symbol_4)).dimAOuter) && (col < (*(tint_symbol_4)).dimInner))) {
float const result = (*(tint_symbol_4)).numbers[((row * (*(tint_symbol_3)).dimInner) + col)]; float const result = (*(tint_symbol_5)).numbers[((row * (*(tint_symbol_4)).dimInner) + col)];
return result; return result;
} }
return 0.0f; return 0.0f;
} }
float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_5, const device Matrix* const tint_symbol_6) { float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_6, const device Matrix* const tint_symbol_7) {
if (((row < (*(tint_symbol_5)).dimInner) && (col < (*(tint_symbol_5)).dimBOuter))) { if (((row < (*(tint_symbol_6)).dimInner) && (col < (*(tint_symbol_6)).dimBOuter))) {
float const result = (*(tint_symbol_6)).numbers[((row * (*(tint_symbol_5)).dimBOuter) + col)]; float const result = (*(tint_symbol_7)).numbers[((row * (*(tint_symbol_6)).dimBOuter) + col)];
return result; return result;
} }
return 0.0f; return 0.0f;
} }
void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_7, device Matrix* const tint_symbol_8) { void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_8, device Matrix* const tint_symbol_9) {
if (((row < (*(tint_symbol_7)).dimAOuter) && (col < (*(tint_symbol_7)).dimBOuter))) { if (((row < (*(tint_symbol_8)).dimAOuter) && (col < (*(tint_symbol_8)).dimBOuter))) {
uint const index = (col + (row * (*(tint_symbol_7)).dimBOuter)); uint const index = (col + (row * (*(tint_symbol_8)).dimBOuter));
(*(tint_symbol_8)).numbers[index] = value; (*(tint_symbol_9)).numbers[index] = value;
} }
} }
void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_9, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_10, const constant Uniforms* const tint_symbol_11, const device Matrix* const tint_symbol_12, const device Matrix* const tint_symbol_13, device Matrix* const tint_symbol_14) { void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_10, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_11, const constant Uniforms* const tint_symbol_12, const device Matrix* const tint_symbol_13, const device Matrix* const tint_symbol_14, device Matrix* const tint_symbol_15) {
for(uint idx = local_invocation_index; (idx < 4096u); idx = (idx + 256u)) { for(uint idx = local_invocation_index; (idx < 4096u); idx = (idx + 256u)) {
uint const i = (idx / 64u); uint const i = (idx / 64u);
uint const i_1 = (idx % 64u); uint const i_1 = (idx % 64u);
(*(tint_symbol_9))[i][i_1] = 0.0f;
(*(tint_symbol_10))[i][i_1] = 0.0f; (*(tint_symbol_10))[i][i_1] = 0.0f;
(*(tint_symbol_11))[i][i_1] = 0.0f;
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
uint const tileRow = (local_id[1] * 4u); uint const tileRow = (local_id[1] * 4u);
uint const tileCol = (local_id[0] * 4u); uint const tileCol = (local_id[0] * 4u);
uint const globalRow = (global_id[1] * 4u); uint const globalRow = (global_id[1] * 4u);
uint const globalCol = (global_id[0] * 4u); uint const globalCol = (global_id[0] * 4u);
uint const numTiles = ((((*(tint_symbol_11)).dimInner - 1u) / 64u) + 1u); uint const tint_symbol_1 = tint_div(((*(tint_symbol_12)).dimInner - 1u), 64u);
uint const numTiles = (tint_symbol_1 + 1u);
tint_array<float, 16> acc = {}; tint_array<float, 16> acc = {};
float ACached = 0.0f; float ACached = 0.0f;
tint_array<float, 4> BCached = {}; tint_array<float, 4> BCached = {};
@ -75,25 +80,25 @@ void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_in
for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
uint const inputRow = (tileRow + innerRow); uint const inputRow = (tileRow + innerRow);
uint const inputCol = (tileColA + innerCol); uint const inputCol = (tileColA + innerCol);
float const tint_symbol_1 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_11, tint_symbol_12); float const tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_12, tint_symbol_13);
(*(tint_symbol_9))[inputRow][inputCol] = tint_symbol_1; (*(tint_symbol_10))[inputRow][inputCol] = tint_symbol_2;
} }
} }
for(uint innerRow = 0u; (innerRow < RowPerThreadB); innerRow = (innerRow + 1u)) { for(uint innerRow = 0u; (innerRow < RowPerThreadB); innerRow = (innerRow + 1u)) {
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
uint const inputRow = (tileRowB + innerRow); uint const inputRow = (tileRowB + innerRow);
uint const inputCol = (tileCol + innerCol); uint const inputCol = (tileCol + innerCol);
float const tint_symbol_2 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_11, tint_symbol_13); float const tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_12, tint_symbol_14);
(*(tint_symbol_10))[innerCol][inputCol] = tint_symbol_2; (*(tint_symbol_11))[innerCol][inputCol] = tint_symbol_3;
} }
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
for(uint k = 0u; (k < 64u); k = (k + 1u)) { for(uint k = 0u; (k < 64u); k = (k + 1u)) {
for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) { for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) {
BCached[inner] = (*(tint_symbol_10))[k][(tileCol + inner)]; BCached[inner] = (*(tint_symbol_11))[k][(tileCol + inner)];
} }
for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) { for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
ACached = (*(tint_symbol_9))[(tileRow + innerRow)][k]; ACached = (*(tint_symbol_10))[(tileRow + innerRow)][k];
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
uint const index = ((innerRow * 4u) + innerCol); uint const index = ((innerRow * 4u) + innerCol);
acc[index] = (acc[index] + (ACached * BCached[innerCol])); acc[index] = (acc[index] + (ACached * BCached[innerCol]));
@ -105,15 +110,15 @@ void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_in
for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) { for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
uint const index = ((innerRow * 4u) + innerCol); uint const index = ((innerRow * 4u) + innerCol);
mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_symbol_11, tint_symbol_14); mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_symbol_12, tint_symbol_15);
} }
} }
} }
kernel void tint_symbol(const constant Uniforms* tint_symbol_17 [[buffer(0)]], const device Matrix* tint_symbol_18 [[buffer(2)]], const device Matrix* tint_symbol_19 [[buffer(3)]], device Matrix* tint_symbol_20 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) { kernel void tint_symbol(const constant Uniforms* tint_symbol_18 [[buffer(0)]], const device Matrix* tint_symbol_19 [[buffer(2)]], const device Matrix* tint_symbol_20 [[buffer(3)]], device Matrix* tint_symbol_21 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_15;
threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_16; threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_16;
tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_15), &(tint_symbol_16), tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20); threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_17;
tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_16), &(tint_symbol_17), tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21);
return; return;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,7 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
SamplerState samp : register(s0, space0); SamplerState samp : register(s0, space0);
cbuffer cbuffer_params : register(b1, space0) { cbuffer cbuffer_params : register(b1, space0) {
uint4 params[1]; uint4 params[1];
@ -25,7 +29,7 @@ void main_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_invocatio
} }
} }
GroupMemoryBarrierWithGroupSync(); GroupMemoryBarrierWithGroupSync();
const uint filterOffset = ((params[0].x - 1u) / 2u); const uint filterOffset = tint_div((params[0].x - 1u), 2u);
int3 tint_tmp; int3 tint_tmp;
inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z); inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z);
const uint2 dims = tint_tmp.xy; const uint2 dims = tint_tmp.xy;

View File

@ -1,3 +1,7 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
SamplerState samp : register(s0, space0); SamplerState samp : register(s0, space0);
cbuffer cbuffer_params : register(b1, space0) { cbuffer cbuffer_params : register(b1, space0) {
uint4 params[1]; uint4 params[1];
@ -25,7 +29,7 @@ void main_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_invocatio
} }
} }
GroupMemoryBarrierWithGroupSync(); GroupMemoryBarrierWithGroupSync();
const uint filterOffset = ((params[0].x - 1u) / 2u); const uint filterOffset = tint_div((params[0].x - 1u), 2u);
int3 tint_tmp; int3 tint_tmp;
inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z); inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z);
const uint2 dims = tint_tmp.xy; const uint2 dims = tint_tmp.xy;

View File

@ -1,5 +1,9 @@
#version 310 es #version 310 es
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
struct Params { struct Params {
uint filterDim; uint filterDim;
uint blockDim; uint blockDim;
@ -36,7 +40,7 @@ void tint_symbol(uvec3 WorkGroupID, uvec3 LocalInvocationID, uint local_invocati
} }
} }
barrier(); barrier();
uint filterOffset = ((params.inner.filterDim - 1u) / 2u); uint filterOffset = tint_div((params.inner.filterDim - 1u), 2u);
uvec2 dims = uvec2(textureSize(inputTex_1, 0)); uvec2 dims = uvec2(textureSize(inputTex_1, 0));
uvec2 baseIndex = (((WorkGroupID.xy * uvec2(params.inner.blockDim, 4u)) + (LocalInvocationID.xy * uvec2(4u, 1u))) - uvec2(filterOffset, 0u)); uvec2 baseIndex = (((WorkGroupID.xy * uvec2(params.inner.blockDim, 4u)) + (LocalInvocationID.xy * uvec2(4u, 1u))) - uvec2(filterOffset, 0u));
{ {

View File

@ -14,6 +14,10 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
struct Params { struct Params {
/* 0x0000 */ uint filterDim; /* 0x0000 */ uint filterDim;
/* 0x0004 */ uint blockDim; /* 0x0004 */ uint blockDim;
@ -30,7 +34,7 @@ void tint_symbol_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_in
(*(tint_symbol_1))[i_1][i_2] = float3(0.0f); (*(tint_symbol_1))[i_1][i_2] = float3(0.0f);
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
uint const filterOffset = (((*(tint_symbol_2)).filterDim - 1u) / 2u); uint const filterOffset = tint_div(((*(tint_symbol_2)).filterDim - 1u), 2u);
uint2 const dims = uint2(tint_symbol_3.get_width(0), tint_symbol_3.get_height(0)); uint2 const dims = uint2(tint_symbol_3.get_width(0), tint_symbol_3.get_height(0));
uint2 const baseIndex = (((uint3(WorkGroupID).xy * uint2((*(tint_symbol_2)).blockDim, 4u)) + (uint3(LocalInvocationID).xy * uint2(4u, 1u))) - uint2(filterOffset, 0u)); uint2 const baseIndex = (((uint3(WorkGroupID).xy * uint2((*(tint_symbol_2)).blockDim, 4u)) + (uint3(LocalInvocationID).xy * uint2(4u, 1u))) - uint2(filterOffset, 0u));
for(uint r = 0u; (r < 4u); r = (r + 1u)) { for(uint r = 0u; (r < 4u); r = (r + 1u)) {

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 253 ; Bound: 261
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpCapability ImageQuery OpCapability ImageQuery
@ -26,6 +26,9 @@
OpMemberName %Flip 0 "value" OpMemberName %Flip 0 "value"
OpName %flip "flip" OpName %flip "flip"
OpName %tile "tile" OpName %tile "tile"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %main_inner "main_inner" OpName %main_inner "main_inner"
OpName %WorkGroupID "WorkGroupID" OpName %WorkGroupID "WorkGroupID"
OpName %LocalInvocationID "LocalInvocationID" OpName %LocalInvocationID "LocalInvocationID"
@ -98,311 +101,321 @@
%_arr__arr_v3float_uint_256_uint_4 = OpTypeArray %_arr_v3float_uint_256 %uint_4 %_arr__arr_v3float_uint_256_uint_4 = OpTypeArray %_arr_v3float_uint_256 %uint_4
%_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 = OpTypePointer Workgroup %_arr__arr_v3float_uint_256_uint_4 %_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 = OpTypePointer Workgroup %_arr__arr_v3float_uint_256_uint_4
%tile = OpVariable %_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 Workgroup %tile = OpVariable %_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 Workgroup
%void = OpTypeVoid %33 = OpTypeFunction %uint %uint %uint
%33 = OpTypeFunction %void %v3uint %v3uint %uint %39 = OpConstantNull %uint
%_ptr_Function_uint = OpTypePointer Function %uint
%42 = OpConstantNull %uint
%uint_1024 = OpConstant %uint 1024
%bool = OpTypeBool %bool = OpTypeBool
%uint_1 = OpConstant %uint 1
%void = OpTypeVoid
%44 = OpTypeFunction %void %v3uint %v3uint %uint
%_ptr_Function_uint = OpTypePointer Function %uint
%uint_1024 = OpConstant %uint 1024
%_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
%60 = OpConstantNull %v3float %69 = OpConstantNull %v3float
%uint_64 = OpConstant %uint 64 %uint_64 = OpConstant %uint 64
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264 %uint_264 = OpConstant %uint 264
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%_ptr_Uniform_uint = OpTypePointer Uniform %uint %_ptr_Uniform_uint = OpTypePointer Uniform %uint
%uint_1 = OpConstant %uint 1
%v2uint = OpTypeVector %uint 2 %v2uint = OpTypeVector %uint 2
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%78 = OpConstantNull %int %86 = OpConstantNull %int
%85 = OpConstantComposite %v2uint %uint_4 %uint_1 %93 = OpConstantComposite %v2uint %uint_4 %uint_1
%_ptr_Function_v2uint = OpTypePointer Function %v2uint %_ptr_Function_v2uint = OpTypePointer Function %v2uint
%116 = OpConstantNull %v2uint %124 = OpConstantNull %v2uint
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%134 = OpTypeSampledImage %17 %142 = OpTypeSampledImage %17
%v2float = OpTypeVector %float 2 %v2float = OpTypeVector %float 2
%float_0_25 = OpConstant %float 0.25 %float_0_25 = OpConstant %float 0.25
%140 = OpConstantComposite %v2float %float_0_25 %float_0_25 %148 = OpConstantComposite %v2float %float_0_25 %float_0_25
%144 = OpConstantNull %float %152 = OpConstantNull %float
%v2bool = OpTypeVector %bool 2 %v2bool = OpTypeVector %bool 2
%_ptr_Function_v3float = OpTypePointer Function %v3float %_ptr_Function_v3float = OpTypePointer Function %v3float
%float_1 = OpConstant %float 1 %float_1 = OpConstant %float 1
%246 = OpTypeFunction %void %254 = OpTypeFunction %void
%main_inner = OpFunction %void None %33 %tint_div = OpFunction %uint None %33
%lhs = OpFunctionParameter %uint
%rhs = OpFunctionParameter %uint
%37 = OpLabel
%40 = OpIEqual %bool %rhs %39
%38 = OpSelect %uint %40 %uint_1 %rhs
%43 = OpUDiv %uint %lhs %38
OpReturnValue %43
OpFunctionEnd
%main_inner = OpFunction %void None %44
%WorkGroupID = OpFunctionParameter %v3uint %WorkGroupID = OpFunctionParameter %v3uint
%LocalInvocationID = OpFunctionParameter %v3uint %LocalInvocationID = OpFunctionParameter %v3uint
%local_invocation_index = OpFunctionParameter %uint %local_invocation_index = OpFunctionParameter %uint
%39 = OpLabel %50 = OpLabel
%idx = OpVariable %_ptr_Function_uint Function %42 %idx = OpVariable %_ptr_Function_uint Function %39
%r = OpVariable %_ptr_Function_uint Function %42 %r = OpVariable %_ptr_Function_uint Function %39
%c = OpVariable %_ptr_Function_uint Function %42 %c = OpVariable %_ptr_Function_uint Function %39
%loadIndex = OpVariable %_ptr_Function_v2uint Function %116 %loadIndex = OpVariable %_ptr_Function_v2uint Function %124
%r_0 = OpVariable %_ptr_Function_uint Function %42 %r_0 = OpVariable %_ptr_Function_uint Function %39
%c_0 = OpVariable %_ptr_Function_uint Function %42 %c_0 = OpVariable %_ptr_Function_uint Function %39
%writeIndex = OpVariable %_ptr_Function_v2uint Function %116 %writeIndex = OpVariable %_ptr_Function_v2uint Function %124
%acc = OpVariable %_ptr_Function_v3float Function %60 %acc = OpVariable %_ptr_Function_v3float Function %69
%f = OpVariable %_ptr_Function_uint Function %42 %f = OpVariable %_ptr_Function_uint Function %39
%i = OpVariable %_ptr_Function_uint Function %42 %i = OpVariable %_ptr_Function_uint Function %39
OpStore %idx %local_invocation_index OpStore %idx %local_invocation_index
OpBranch %43 OpBranch %53
%43 = OpLabel
OpLoopMerge %44 %45 None
OpBranch %46
%46 = OpLabel
%48 = OpLoad %uint %idx
%50 = OpULessThan %bool %48 %uint_1024
%47 = OpLogicalNot %bool %50
OpSelectionMerge %52 None
OpBranchConditional %47 %53 %52
%53 = OpLabel %53 = OpLabel
OpBranch %44 OpLoopMerge %54 %55 None
%52 = OpLabel OpBranch %56
%54 = OpLoad %uint %idx %56 = OpLabel
%55 = OpUDiv %uint %54 %uint_256 %58 = OpLoad %uint %idx
%56 = OpLoad %uint %idx %60 = OpULessThan %bool %58 %uint_1024
%57 = OpUMod %uint %56 %uint_256 %57 = OpLogicalNot %bool %60
%59 = OpAccessChain %_ptr_Workgroup_v3float %tile %55 %57 OpSelectionMerge %61 None
OpStore %59 %60 OpBranchConditional %57 %62 %61
OpBranch %45 %62 = OpLabel
%45 = OpLabel OpBranch %54
%61 = OpLoad %uint %idx %61 = OpLabel
%63 = OpIAdd %uint %61 %uint_64 %63 = OpLoad %uint %idx
OpStore %idx %63 %64 = OpUDiv %uint %63 %uint_256
OpBranch %43 %65 = OpLoad %uint %idx
%44 = OpLabel %66 = OpUMod %uint %65 %uint_256
%68 = OpAccessChain %_ptr_Workgroup_v3float %tile %64 %66
OpStore %68 %69
OpBranch %55
%55 = OpLabel
%70 = OpLoad %uint %idx
%72 = OpIAdd %uint %70 %uint_64
OpStore %idx %72
OpBranch %53
%54 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
%69 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 %79 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0
%70 = OpLoad %uint %69 %80 = OpLoad %uint %79
%72 = OpISub %uint %70 %uint_1 %81 = OpISub %uint %80 %uint_1
%73 = OpUDiv %uint %72 %uint_2 %76 = OpFunctionCall %uint %tint_div %81 %uint_2
%76 = OpLoad %17 %inputTex %84 = OpLoad %17 %inputTex
%74 = OpImageQuerySizeLod %v2uint %76 %78 %82 = OpImageQuerySizeLod %v2uint %84 %86
%79 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1 %87 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1
%80 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_1 %88 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_1
%81 = OpLoad %uint %80 %89 = OpLoad %uint %88
%82 = OpCompositeConstruct %v2uint %81 %uint_4 %90 = OpCompositeConstruct %v2uint %89 %uint_4
%83 = OpIMul %v2uint %79 %82 %91 = OpIMul %v2uint %87 %90
%84 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1 %92 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1
%86 = OpIMul %v2uint %84 %85 %94 = OpIMul %v2uint %92 %93
%87 = OpIAdd %v2uint %83 %86 %95 = OpIAdd %v2uint %91 %94
%88 = OpCompositeConstruct %v2uint %73 %42 %96 = OpCompositeConstruct %v2uint %76 %39
%89 = OpISub %v2uint %87 %88 %97 = OpISub %v2uint %95 %96
OpStore %r %42 OpStore %r %39
OpBranch %91 OpBranch %99
%91 = OpLabel
OpLoopMerge %92 %93 None
OpBranch %94
%94 = OpLabel
%96 = OpLoad %uint %r
%97 = OpULessThan %bool %96 %uint_4
%95 = OpLogicalNot %bool %97
OpSelectionMerge %98 None
OpBranchConditional %95 %99 %98
%99 = OpLabel %99 = OpLabel
OpBranch %92 OpLoopMerge %100 %101 None
%98 = OpLabel OpBranch %102
OpStore %c %42 %102 = OpLabel
%104 = OpLoad %uint %r
%105 = OpULessThan %bool %104 %uint_4
%103 = OpLogicalNot %bool %105
OpSelectionMerge %106 None
OpBranchConditional %103 %107 %106
%107 = OpLabel
OpBranch %100
%106 = OpLabel
OpStore %c %39
OpBranch %109
%109 = OpLabel
OpLoopMerge %110 %111 None
OpBranch %112
%112 = OpLabel
%114 = OpLoad %uint %c
%115 = OpULessThan %bool %114 %uint_4
%113 = OpLogicalNot %bool %115
OpSelectionMerge %116 None
OpBranchConditional %113 %117 %116
%117 = OpLabel
OpBranch %110
%116 = OpLabel
%118 = OpLoad %uint %c
%119 = OpLoad %uint %r
%120 = OpCompositeConstruct %v2uint %118 %119
%121 = OpIAdd %v2uint %97 %120
OpStore %loadIndex %121
%125 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0
%126 = OpLoad %uint %125
%127 = OpINotEqual %bool %126 %39
OpSelectionMerge %128 None
OpBranchConditional %127 %129 %128
%129 = OpLabel
%130 = OpLoad %v2uint %loadIndex
%131 = OpVectorShuffle %v2uint %130 %130 1 0
OpStore %loadIndex %131
OpBranch %128
%128 = OpLabel
%132 = OpLoad %uint %r
%133 = OpCompositeExtract %uint %LocalInvocationID 0
%134 = OpIMul %uint %uint_4 %133
%135 = OpLoad %uint %c
%136 = OpIAdd %uint %134 %135
%137 = OpAccessChain %_ptr_Workgroup_v3float %tile %132 %136
%140 = OpLoad %10 %samp
%141 = OpLoad %17 %inputTex
%143 = OpSampledImage %142 %141 %140
%146 = OpLoad %v2uint %loadIndex
%144 = OpConvertUToF %v2float %146
%149 = OpFAdd %v2float %144 %148
%150 = OpConvertUToF %v2float %82
%151 = OpFDiv %v2float %149 %150
%138 = OpImageSampleExplicitLod %v4float %143 %151 Lod %152
%153 = OpVectorShuffle %v3float %138 %138 0 1 2
OpStore %137 %153
OpBranch %111
%111 = OpLabel
%154 = OpLoad %uint %c
%155 = OpIAdd %uint %154 %uint_1
OpStore %c %155
OpBranch %109
%110 = OpLabel
OpBranch %101 OpBranch %101
%101 = OpLabel %101 = OpLabel
OpLoopMerge %102 %103 None %156 = OpLoad %uint %r
OpBranch %104 %157 = OpIAdd %uint %156 %uint_1
%104 = OpLabel OpStore %r %157
%106 = OpLoad %uint %c OpBranch %99
%107 = OpULessThan %bool %106 %uint_4 %100 = OpLabel
%105 = OpLogicalNot %bool %107
OpSelectionMerge %108 None
OpBranchConditional %105 %109 %108
%109 = OpLabel
OpBranch %102
%108 = OpLabel
%110 = OpLoad %uint %c
%111 = OpLoad %uint %r
%112 = OpCompositeConstruct %v2uint %110 %111
%113 = OpIAdd %v2uint %89 %112
OpStore %loadIndex %113
%117 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0
%118 = OpLoad %uint %117
%119 = OpINotEqual %bool %118 %42
OpSelectionMerge %120 None
OpBranchConditional %119 %121 %120
%121 = OpLabel
%122 = OpLoad %v2uint %loadIndex
%123 = OpVectorShuffle %v2uint %122 %122 1 0
OpStore %loadIndex %123
OpBranch %120
%120 = OpLabel
%124 = OpLoad %uint %r
%125 = OpCompositeExtract %uint %LocalInvocationID 0
%126 = OpIMul %uint %uint_4 %125
%127 = OpLoad %uint %c
%128 = OpIAdd %uint %126 %127
%129 = OpAccessChain %_ptr_Workgroup_v3float %tile %124 %128
%132 = OpLoad %10 %samp
%133 = OpLoad %17 %inputTex
%135 = OpSampledImage %134 %133 %132
%138 = OpLoad %v2uint %loadIndex
%136 = OpConvertUToF %v2float %138
%141 = OpFAdd %v2float %136 %140
%142 = OpConvertUToF %v2float %74
%143 = OpFDiv %v2float %141 %142
%130 = OpImageSampleExplicitLod %v4float %135 %143 Lod %144
%145 = OpVectorShuffle %v3float %130 %130 0 1 2
OpStore %129 %145
OpBranch %103
%103 = OpLabel
%146 = OpLoad %uint %c
%147 = OpIAdd %uint %146 %uint_1
OpStore %c %147
OpBranch %101
%102 = OpLabel
OpBranch %93
%93 = OpLabel
%148 = OpLoad %uint %r
%149 = OpIAdd %uint %148 %uint_1
OpStore %r %149
OpBranch %91
%92 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %r_0 %42 OpStore %r_0 %39
OpBranch %152 OpBranch %160
%152 = OpLabel
OpLoopMerge %153 %154 None
OpBranch %155
%155 = OpLabel
%157 = OpLoad %uint %r_0
%158 = OpULessThan %bool %157 %uint_4
%156 = OpLogicalNot %bool %158
OpSelectionMerge %159 None
OpBranchConditional %156 %160 %159
%160 = OpLabel %160 = OpLabel
OpBranch %153 OpLoopMerge %161 %162 None
%159 = OpLabel
OpStore %c_0 %42
OpBranch %162
%162 = OpLabel
OpLoopMerge %163 %164 None
OpBranch %165
%165 = OpLabel
%167 = OpLoad %uint %c_0
%168 = OpULessThan %bool %167 %uint_4
%166 = OpLogicalNot %bool %168
OpSelectionMerge %169 None
OpBranchConditional %166 %170 %169
%170 = OpLabel
OpBranch %163 OpBranch %163
%169 = OpLabel %163 = OpLabel
%171 = OpLoad %uint %c_0 %165 = OpLoad %uint %r_0
%172 = OpLoad %uint %r_0 %166 = OpULessThan %bool %165 %uint_4
%173 = OpCompositeConstruct %v2uint %171 %172 %164 = OpLogicalNot %bool %166
%174 = OpIAdd %v2uint %89 %173 OpSelectionMerge %167 None
OpStore %writeIndex %174 OpBranchConditional %164 %168 %167
%176 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0 %168 = OpLabel
%177 = OpLoad %uint %176 OpBranch %161
%178 = OpINotEqual %bool %177 %42 %167 = OpLabel
OpSelectionMerge %179 None OpStore %c_0 %39
OpBranchConditional %178 %180 %179 OpBranch %170
%180 = OpLabel %170 = OpLabel
%181 = OpLoad %v2uint %writeIndex OpLoopMerge %171 %172 None
%182 = OpVectorShuffle %v2uint %181 %181 1 0 OpBranch %173
%173 = OpLabel
%175 = OpLoad %uint %c_0
%176 = OpULessThan %bool %175 %uint_4
%174 = OpLogicalNot %bool %176
OpSelectionMerge %177 None
OpBranchConditional %174 %178 %177
%178 = OpLabel
OpBranch %171
%177 = OpLabel
%179 = OpLoad %uint %c_0
%180 = OpLoad %uint %r_0
%181 = OpCompositeConstruct %v2uint %179 %180
%182 = OpIAdd %v2uint %97 %181
OpStore %writeIndex %182 OpStore %writeIndex %182
OpBranch %179 %184 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0
%179 = OpLabel %185 = OpLoad %uint %184
%183 = OpCompositeExtract %uint %LocalInvocationID 0 %186 = OpINotEqual %bool %185 %39
%184 = OpIMul %uint %uint_4 %183 OpSelectionMerge %187 None
%185 = OpLoad %uint %c_0 OpBranchConditional %186 %188 %187
%186 = OpIAdd %uint %184 %185
%187 = OpUGreaterThanEqual %bool %186 %73
OpSelectionMerge %188 None
OpBranchConditional %187 %189 %188
%189 = OpLabel
%190 = OpISub %uint %uint_256 %73
%191 = OpULessThan %bool %186 %190
OpBranch %188
%188 = OpLabel %188 = OpLabel
%192 = OpPhi %bool %187 %179 %191 %189 %189 = OpLoad %v2uint %writeIndex
OpSelectionMerge %193 None %190 = OpVectorShuffle %v2uint %189 %189 1 0
OpBranchConditional %192 %194 %193 OpStore %writeIndex %190
%194 = OpLabel OpBranch %187
%196 = OpLoad %v2uint %writeIndex %187 = OpLabel
%197 = OpULessThan %v2bool %196 %74 %191 = OpCompositeExtract %uint %LocalInvocationID 0
%195 = OpAll %bool %197 %192 = OpIMul %uint %uint_4 %191
OpBranch %193 %193 = OpLoad %uint %c_0
%193 = OpLabel %194 = OpIAdd %uint %192 %193
%199 = OpPhi %bool %192 %188 %195 %194 %195 = OpUGreaterThanEqual %bool %194 %76
OpSelectionMerge %200 None OpSelectionMerge %196 None
OpBranchConditional %199 %201 %200 OpBranchConditional %195 %197 %196
%197 = OpLabel
%198 = OpISub %uint %uint_256 %76
%199 = OpULessThan %bool %194 %198
OpBranch %196
%196 = OpLabel
%200 = OpPhi %bool %195 %187 %199 %197
OpSelectionMerge %201 None
OpBranchConditional %200 %202 %201
%202 = OpLabel
%204 = OpLoad %v2uint %writeIndex
%205 = OpULessThan %v2bool %204 %82
%203 = OpAll %bool %205
OpBranch %201
%201 = OpLabel %201 = OpLabel
OpStore %acc %60 %207 = OpPhi %bool %200 %196 %203 %202
OpStore %f %42 OpSelectionMerge %208 None
OpBranch %205 OpBranchConditional %207 %209 %208
%205 = OpLabel %209 = OpLabel
OpLoopMerge %206 %207 None OpStore %acc %69
OpStore %f %39
OpBranch %213
%213 = OpLabel
OpLoopMerge %214 %215 None
OpBranch %216
%216 = OpLabel
%218 = OpLoad %uint %f
%219 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0
%220 = OpLoad %uint %219
%221 = OpULessThan %bool %218 %220
%217 = OpLogicalNot %bool %221
OpSelectionMerge %222 None
OpBranchConditional %217 %223 %222
%223 = OpLabel
OpBranch %214
%222 = OpLabel
%224 = OpLoad %uint %f
%225 = OpIAdd %uint %194 %224
%226 = OpISub %uint %225 %76
OpStore %i %226
%228 = OpLoad %v3float %acc
%231 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0
%232 = OpLoad %uint %231
%230 = OpConvertUToF %float %232
%233 = OpFDiv %float %float_1 %230
%234 = OpLoad %uint %r_0
%235 = OpLoad %uint %i
%236 = OpAccessChain %_ptr_Workgroup_v3float %tile %234 %235
%237 = OpLoad %v3float %236
%238 = OpVectorTimesScalar %v3float %237 %233
%239 = OpFAdd %v3float %228 %238
OpStore %acc %239
OpBranch %215
%215 = OpLabel
%240 = OpLoad %uint %f
%241 = OpIAdd %uint %240 %uint_1
OpStore %f %241
OpBranch %213
%214 = OpLabel
%243 = OpLoad %21 %outputTex
%244 = OpLoad %v2uint %writeIndex
%245 = OpLoad %v3float %acc
%246 = OpCompositeExtract %float %245 0
%247 = OpCompositeExtract %float %245 1
%248 = OpCompositeExtract %float %245 2
%249 = OpCompositeConstruct %v4float %246 %247 %248 %float_1
OpImageWrite %243 %244 %249
OpBranch %208 OpBranch %208
%208 = OpLabel %208 = OpLabel
%210 = OpLoad %uint %f OpBranch %172
%211 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 %172 = OpLabel
%212 = OpLoad %uint %211 %250 = OpLoad %uint %c_0
%213 = OpULessThan %bool %210 %212 %251 = OpIAdd %uint %250 %uint_1
%209 = OpLogicalNot %bool %213 OpStore %c_0 %251
OpSelectionMerge %214 None OpBranch %170
OpBranchConditional %209 %215 %214 %171 = OpLabel
%215 = OpLabel
OpBranch %206
%214 = OpLabel
%216 = OpLoad %uint %f
%217 = OpIAdd %uint %186 %216
%218 = OpISub %uint %217 %73
OpStore %i %218
%220 = OpLoad %v3float %acc
%223 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0
%224 = OpLoad %uint %223
%222 = OpConvertUToF %float %224
%225 = OpFDiv %float %float_1 %222
%226 = OpLoad %uint %r_0
%227 = OpLoad %uint %i
%228 = OpAccessChain %_ptr_Workgroup_v3float %tile %226 %227
%229 = OpLoad %v3float %228
%230 = OpVectorTimesScalar %v3float %229 %225
%231 = OpFAdd %v3float %220 %230
OpStore %acc %231
OpBranch %207
%207 = OpLabel
%232 = OpLoad %uint %f
%233 = OpIAdd %uint %232 %uint_1
OpStore %f %233
OpBranch %205
%206 = OpLabel
%235 = OpLoad %21 %outputTex
%236 = OpLoad %v2uint %writeIndex
%237 = OpLoad %v3float %acc
%238 = OpCompositeExtract %float %237 0
%239 = OpCompositeExtract %float %237 1
%240 = OpCompositeExtract %float %237 2
%241 = OpCompositeConstruct %v4float %238 %239 %240 %float_1
OpImageWrite %235 %236 %241
OpBranch %200
%200 = OpLabel
OpBranch %164
%164 = OpLabel
%242 = OpLoad %uint %c_0
%243 = OpIAdd %uint %242 %uint_1
OpStore %c_0 %243
OpBranch %162 OpBranch %162
%163 = OpLabel %162 = OpLabel
OpBranch %154 %252 = OpLoad %uint %r_0
%154 = OpLabel %253 = OpIAdd %uint %252 %uint_1
%244 = OpLoad %uint %r_0 OpStore %r_0 %253
%245 = OpIAdd %uint %244 %uint_1 OpBranch %160
OpStore %r_0 %245 %161 = OpLabel
OpBranch %152
%153 = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %void None %246 %main = OpFunction %void None %254
%248 = OpLabel %256 = OpLabel
%250 = OpLoad %v3uint %WorkGroupID_1 %258 = OpLoad %v3uint %WorkGroupID_1
%251 = OpLoad %v3uint %LocalInvocationID_1 %259 = OpLoad %v3uint %LocalInvocationID_1
%252 = OpLoad %uint %local_invocation_index_1 %260 = OpLoad %uint %local_invocation_index_1
%249 = OpFunctionCall %void %main_inner %250 %251 %252 %257 = OpFunctionCall %void %main_inner %258 %259 %260
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,3 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
static uint local_invocation_index_1 = 0u; static uint local_invocation_index_1 = 0u;
groupshared uint wg[3][2][1]; groupshared uint wg[3][2][1];
@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) {
const uint x_31 = idx; const uint x_31 = idx;
const uint x_33 = idx; const uint x_33 = idx;
const uint x_35 = idx; const uint x_35 = idx;
const uint tint_symbol_2 = tint_div(x_31, 2u);
const uint tint_symbol_3 = tint_mod(x_33, 2u);
const uint tint_symbol_4 = tint_mod(x_35, 1u);
uint atomic_result = 0u; uint atomic_result = 0u;
InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result);
{ {
const uint x_42 = idx; const uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -1,3 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
static uint local_invocation_index_1 = 0u; static uint local_invocation_index_1 = 0u;
groupshared uint wg[3][2][1]; groupshared uint wg[3][2][1];
@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) {
const uint x_31 = idx; const uint x_31 = idx;
const uint x_33 = idx; const uint x_33 = idx;
const uint x_35 = idx; const uint x_35 = idx;
const uint tint_symbol_2 = tint_div(x_31, 2u);
const uint tint_symbol_3 = tint_mod(x_33, 2u);
const uint tint_symbol_4 = tint_mod(x_35, 1u);
uint atomic_result = 0u; uint atomic_result = 0u;
InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result);
{ {
const uint x_42 = idx; const uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -1,5 +1,13 @@
#version 310 es #version 310 es
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
uint local_invocation_index_1 = 0u; uint local_invocation_index_1 = 0u;
shared uint wg[3][2][1]; shared uint wg[3][2][1];
void compute_main_inner(uint local_invocation_index) { void compute_main_inner(uint local_invocation_index) {
@ -13,7 +21,10 @@ void compute_main_inner(uint local_invocation_index) {
uint x_31 = idx; uint x_31 = idx;
uint x_33 = idx; uint x_33 = idx;
uint x_35 = idx; uint x_35 = idx;
atomicExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u); uint tint_symbol = tint_div(x_31, 2u);
uint tint_symbol_1 = tint_mod(x_33, 2u);
uint tint_symbol_2 = tint_mod(x_35, 1u);
atomicExchange(wg[tint_symbol][tint_symbol_1][tint_symbol_2], 0u);
{ {
uint x_42 = idx; uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -14,7 +14,15 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) { uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % select(rhs, 1u, (rhs == 0u)));
}
void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3) {
uint idx = 0u; uint idx = 0u;
idx = local_invocation_index; idx = local_invocation_index;
while (true) { while (true) {
@ -25,39 +33,42 @@ void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint
uint const x_31 = idx; uint const x_31 = idx;
uint const x_33 = idx; uint const x_33 = idx;
uint const x_35 = idx; uint const x_35 = idx;
atomic_store_explicit(&((*(tint_symbol))[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)]), 0u, memory_order_relaxed); uint const tint_symbol = tint_div(x_31, 2u);
uint const tint_symbol_1 = tint_mod(x_33, 2u);
uint const tint_symbol_2 = tint_mod(x_35, 1u);
atomic_store_explicit(&((*(tint_symbol_3))[tint_symbol][tint_symbol_1][tint_symbol_2]), 0u, memory_order_relaxed);
{ {
uint const x_42 = idx; uint const x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);
} }
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed); atomic_store_explicit(&((*(tint_symbol_3))[2][1][0]), 1u, memory_order_relaxed);
return; return;
} }
void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_2) { void compute_main_1(thread uint* const tint_symbol_4, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_5) {
uint const x_57 = *(tint_symbol_1); uint const x_57 = *(tint_symbol_4);
compute_main_inner(x_57, tint_symbol_2); compute_main_inner(x_57, tint_symbol_5);
return; return;
} }
void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) { void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_6, thread uint* const tint_symbol_7) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) { for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
uint const i = (idx_1 / 2u); uint const i = (idx_1 / 2u);
uint const i_1 = (idx_1 % 2u); uint const i_1 = (idx_1 % 2u);
uint const i_2 = (idx_1 % 1u); uint const i_2 = (idx_1 % 1u);
atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed); atomic_store_explicit(&((*(tint_symbol_6))[i][i_1][i_2]), 0u, memory_order_relaxed);
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param; *(tint_symbol_7) = local_invocation_index_1_param;
compute_main_1(tint_symbol_4, tint_symbol_3); compute_main_1(tint_symbol_7, tint_symbol_6);
} }
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) { kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_5; threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_8;
thread uint tint_symbol_6 = 0u; thread uint tint_symbol_9 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6)); compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_8), &(tint_symbol_9));
return; return;
} }

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 90 ; Bound: 105
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -10,6 +10,12 @@
OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1" OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1"
OpName %local_invocation_index_1 "local_invocation_index_1" OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %wg "wg" OpName %wg "wg"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %tint_mod "tint_mod"
OpName %lhs_0 "lhs"
OpName %rhs_0 "rhs"
OpName %compute_main_inner "compute_main_inner" OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index" OpName %local_invocation_index "local_invocation_index"
OpName %idx "idx" OpName %idx "idx"
@ -36,105 +42,124 @@
%_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3 %_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3
%_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3 %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3
%wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup
%15 = OpTypeFunction %uint %uint %uint
%bool = OpTypeBool
%void = OpTypeVoid %void = OpTypeVoid
%15 = OpTypeFunction %void %uint %31 = OpTypeFunction %void %uint
%_ptr_Function_uint = OpTypePointer Function %uint %_ptr_Function_uint = OpTypePointer Function %uint
%uint_6 = OpConstant %uint 6 %uint_6 = OpConstant %uint 6
%bool = OpTypeBool
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
%uint_264 = OpConstant %uint 264 %uint_264 = OpConstant %uint 264
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%53 = OpConstantNull %int %68 = OpConstantNull %int
%55 = OpTypeFunction %void %70 = OpTypeFunction %void
%compute_main_inner = OpFunction %void None %15 %tint_div = OpFunction %uint None %15
%local_invocation_index = OpFunctionParameter %uint %lhs = OpFunctionParameter %uint
%rhs = OpFunctionParameter %uint
%19 = OpLabel %19 = OpLabel
%21 = OpIEqual %bool %rhs %6
%20 = OpSelect %uint %21 %uint_1 %rhs
%23 = OpUDiv %uint %lhs %20
OpReturnValue %23
OpFunctionEnd
%tint_mod = OpFunction %uint None %15
%lhs_0 = OpFunctionParameter %uint
%rhs_0 = OpFunctionParameter %uint
%27 = OpLabel
%29 = OpIEqual %bool %rhs_0 %6
%28 = OpSelect %uint %29 %uint_1 %rhs_0
%30 = OpUMod %uint %lhs_0 %28
OpReturnValue %30
OpFunctionEnd
%compute_main_inner = OpFunction %void None %31
%local_invocation_index = OpFunctionParameter %uint
%35 = OpLabel
%idx = OpVariable %_ptr_Function_uint Function %6 %idx = OpVariable %_ptr_Function_uint Function %6
OpStore %idx %6 OpStore %idx %6
OpStore %idx %local_invocation_index OpStore %idx %local_invocation_index
OpBranch %22 OpBranch %38
%22 = OpLabel %38 = OpLabel
OpLoopMerge %23 %24 None OpLoopMerge %39 %40 None
OpBranch %25 OpBranch %41
%25 = OpLabel %41 = OpLabel
%26 = OpLoad %uint %idx %42 = OpLoad %uint %idx
%29 = OpULessThan %bool %26 %uint_6 %45 = OpULessThan %bool %42 %uint_6
%27 = OpLogicalNot %bool %29 %43 = OpLogicalNot %bool %45
OpSelectionMerge %31 None OpSelectionMerge %46 None
OpBranchConditional %27 %32 %31 OpBranchConditional %43 %47 %46
%32 = OpLabel %47 = OpLabel
OpBranch %23 OpBranch %39
%31 = OpLabel %46 = OpLabel
%33 = OpLoad %uint %idx %48 = OpLoad %uint %idx
%34 = OpLoad %uint %idx %49 = OpLoad %uint %idx
%35 = OpLoad %uint %idx %50 = OpLoad %uint %idx
%39 = OpUDiv %uint %33 %uint_2 %51 = OpFunctionCall %uint %tint_div %48 %uint_2
%40 = OpUMod %uint %34 %uint_2 %52 = OpFunctionCall %uint %tint_mod %49 %uint_2
%41 = OpUMod %uint %35 %uint_1 %53 = OpFunctionCall %uint %tint_mod %50 %uint_1
%43 = OpAccessChain %_ptr_Workgroup_uint %wg %39 %40 %41 %58 = OpAccessChain %_ptr_Workgroup_uint %wg %51 %52 %53
OpAtomicStore %43 %uint_2 %uint_0 %6 OpAtomicStore %58 %uint_2 %uint_0 %6
OpBranch %24 OpBranch %40
%24 = OpLabel %40 = OpLabel
%44 = OpLoad %uint %idx %59 = OpLoad %uint %idx
%45 = OpIAdd %uint %44 %uint_1 %60 = OpIAdd %uint %59 %uint_1
OpStore %idx %45 OpStore %idx %60
OpBranch %22 OpBranch %38
%23 = OpLabel %39 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
%54 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %53 %69 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %68
OpAtomicStore %54 %uint_2 %uint_0 %uint_1 OpAtomicStore %69 %uint_2 %uint_0 %uint_1
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main_1 = OpFunction %void None %55 %compute_main_1 = OpFunction %void None %70
%57 = OpLabel %72 = OpLabel
%58 = OpLoad %uint %local_invocation_index_1 %73 = OpLoad %uint %local_invocation_index_1
%59 = OpFunctionCall %void %compute_main_inner %58 %74 = OpFunctionCall %void %compute_main_inner %73
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %15 %compute_main_inner_1 = OpFunction %void None %31
%local_invocation_index_1_param = OpFunctionParameter %uint %local_invocation_index_1_param = OpFunctionParameter %uint
%62 = OpLabel %77 = OpLabel
%idx_1 = OpVariable %_ptr_Function_uint Function %6 %idx_1 = OpVariable %_ptr_Function_uint Function %6
OpStore %idx_1 %local_invocation_index_1_param OpStore %idx_1 %local_invocation_index_1_param
OpBranch %64 OpBranch %79
%64 = OpLabel %79 = OpLabel
OpLoopMerge %65 %66 None OpLoopMerge %80 %81 None
OpBranch %67 OpBranch %82
%67 = OpLabel %82 = OpLabel
%69 = OpLoad %uint %idx_1 %84 = OpLoad %uint %idx_1
%70 = OpULessThan %bool %69 %uint_6 %85 = OpULessThan %bool %84 %uint_6
%68 = OpLogicalNot %bool %70 %83 = OpLogicalNot %bool %85
OpSelectionMerge %71 None OpSelectionMerge %86 None
OpBranchConditional %68 %72 %71 OpBranchConditional %83 %87 %86
%72 = OpLabel %87 = OpLabel
OpBranch %65 OpBranch %80
%71 = OpLabel %86 = OpLabel
%73 = OpLoad %uint %idx_1 %88 = OpLoad %uint %idx_1
%74 = OpUDiv %uint %73 %uint_2 %89 = OpUDiv %uint %88 %uint_2
%75 = OpLoad %uint %idx_1 %90 = OpLoad %uint %idx_1
%76 = OpUMod %uint %75 %uint_2 %91 = OpUMod %uint %90 %uint_2
%77 = OpLoad %uint %idx_1 %92 = OpLoad %uint %idx_1
%78 = OpUMod %uint %77 %uint_1 %93 = OpUMod %uint %92 %uint_1
%81 = OpAccessChain %_ptr_Workgroup_uint %wg %74 %76 %78 %96 = OpAccessChain %_ptr_Workgroup_uint %wg %89 %91 %93
OpAtomicStore %81 %uint_2 %uint_0 %6 OpAtomicStore %96 %uint_2 %uint_0 %6
OpBranch %66 OpBranch %81
%66 = OpLabel %81 = OpLabel
%82 = OpLoad %uint %idx_1 %97 = OpLoad %uint %idx_1
%83 = OpIAdd %uint %82 %uint_1 %98 = OpIAdd %uint %97 %uint_1
OpStore %idx_1 %83 OpStore %idx_1 %98
OpBranch %64 OpBranch %79
%65 = OpLabel %80 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param OpStore %local_invocation_index_1 %local_invocation_index_1_param
%85 = OpFunctionCall %void %compute_main_1 %100 = OpFunctionCall %void %compute_main_1
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main = OpFunction %void None %55 %compute_main = OpFunction %void None %70
%87 = OpLabel %102 = OpLabel
%89 = OpLoad %uint %local_invocation_index_1_param_1 %104 = OpLoad %uint %local_invocation_index_1_param_1
%88 = OpFunctionCall %void %compute_main_inner_1 %89 %103 = OpFunctionCall %void %compute_main_inner_1 %104
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,3 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
static uint local_invocation_index_1 = 0u; static uint local_invocation_index_1 = 0u;
groupshared uint wg[3][2][1]; groupshared uint wg[3][2][1];
@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) {
const uint x_31 = idx; const uint x_31 = idx;
const uint x_33 = idx; const uint x_33 = idx;
const uint x_35 = idx; const uint x_35 = idx;
const uint tint_symbol_2 = tint_div(x_31, 2u);
const uint tint_symbol_3 = tint_mod(x_33, 2u);
const uint tint_symbol_4 = tint_mod(x_35, 1u);
uint atomic_result = 0u; uint atomic_result = 0u;
InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result);
{ {
const uint x_42 = idx; const uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -1,3 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
static uint local_invocation_index_1 = 0u; static uint local_invocation_index_1 = 0u;
groupshared uint wg[3][2][1]; groupshared uint wg[3][2][1];
@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) {
const uint x_31 = idx; const uint x_31 = idx;
const uint x_33 = idx; const uint x_33 = idx;
const uint x_35 = idx; const uint x_35 = idx;
const uint tint_symbol_2 = tint_div(x_31, 2u);
const uint tint_symbol_3 = tint_mod(x_33, 2u);
const uint tint_symbol_4 = tint_mod(x_35, 1u);
uint atomic_result = 0u; uint atomic_result = 0u;
InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result);
{ {
const uint x_42 = idx; const uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -1,5 +1,13 @@
#version 310 es #version 310 es
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % ((rhs == 0u) ? 1u : rhs));
}
uint local_invocation_index_1 = 0u; uint local_invocation_index_1 = 0u;
shared uint wg[3][2][1]; shared uint wg[3][2][1];
void compute_main_inner(uint local_invocation_index) { void compute_main_inner(uint local_invocation_index) {
@ -13,7 +21,10 @@ void compute_main_inner(uint local_invocation_index) {
uint x_31 = idx; uint x_31 = idx;
uint x_33 = idx; uint x_33 = idx;
uint x_35 = idx; uint x_35 = idx;
atomicExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u); uint tint_symbol = tint_div(x_31, 2u);
uint tint_symbol_1 = tint_mod(x_33, 2u);
uint tint_symbol_2 = tint_mod(x_35, 1u);
atomicExchange(wg[tint_symbol][tint_symbol_1][tint_symbol_2], 0u);
{ {
uint x_42 = idx; uint x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);

View File

@ -14,7 +14,15 @@ struct tint_array {
T elements[N]; T elements[N];
}; };
void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) { uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
uint tint_mod(uint lhs, uint rhs) {
return (lhs % select(rhs, 1u, (rhs == 0u)));
}
void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3) {
uint idx = 0u; uint idx = 0u;
idx = local_invocation_index; idx = local_invocation_index;
while (true) { while (true) {
@ -25,39 +33,42 @@ void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint
uint const x_31 = idx; uint const x_31 = idx;
uint const x_33 = idx; uint const x_33 = idx;
uint const x_35 = idx; uint const x_35 = idx;
atomic_store_explicit(&((*(tint_symbol))[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)]), 0u, memory_order_relaxed); uint const tint_symbol = tint_div(x_31, 2u);
uint const tint_symbol_1 = tint_mod(x_33, 2u);
uint const tint_symbol_2 = tint_mod(x_35, 1u);
atomic_store_explicit(&((*(tint_symbol_3))[tint_symbol][tint_symbol_1][tint_symbol_2]), 0u, memory_order_relaxed);
{ {
uint const x_42 = idx; uint const x_42 = idx;
idx = (x_42 + 1u); idx = (x_42 + 1u);
} }
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed); atomic_store_explicit(&((*(tint_symbol_3))[2][1][0]), 1u, memory_order_relaxed);
return; return;
} }
void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_2) { void compute_main_1(thread uint* const tint_symbol_4, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_5) {
uint const x_57 = *(tint_symbol_1); uint const x_57 = *(tint_symbol_4);
compute_main_inner(x_57, tint_symbol_2); compute_main_inner(x_57, tint_symbol_5);
return; return;
} }
void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) { void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_6, thread uint* const tint_symbol_7) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) { for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
uint const i = (idx_1 / 2u); uint const i = (idx_1 / 2u);
uint const i_1 = (idx_1 % 2u); uint const i_1 = (idx_1 % 2u);
uint const i_2 = (idx_1 % 1u); uint const i_2 = (idx_1 % 1u);
atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed); atomic_store_explicit(&((*(tint_symbol_6))[i][i_1][i_2]), 0u, memory_order_relaxed);
} }
threadgroup_barrier(mem_flags::mem_threadgroup); threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param; *(tint_symbol_7) = local_invocation_index_1_param;
compute_main_1(tint_symbol_4, tint_symbol_3); compute_main_1(tint_symbol_7, tint_symbol_6);
} }
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) { kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_5; threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_8;
thread uint tint_symbol_6 = 0u; thread uint tint_symbol_9 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6)); compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_8), &(tint_symbol_9));
return; return;
} }

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 90 ; Bound: 105
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -10,6 +10,12 @@
OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1" OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1"
OpName %local_invocation_index_1 "local_invocation_index_1" OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %wg "wg" OpName %wg "wg"
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %tint_mod "tint_mod"
OpName %lhs_0 "lhs"
OpName %rhs_0 "rhs"
OpName %compute_main_inner "compute_main_inner" OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index" OpName %local_invocation_index "local_invocation_index"
OpName %idx "idx" OpName %idx "idx"
@ -36,105 +42,124 @@
%_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3 %_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3
%_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3 %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3
%wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup
%15 = OpTypeFunction %uint %uint %uint
%bool = OpTypeBool
%void = OpTypeVoid %void = OpTypeVoid
%15 = OpTypeFunction %void %uint %31 = OpTypeFunction %void %uint
%_ptr_Function_uint = OpTypePointer Function %uint %_ptr_Function_uint = OpTypePointer Function %uint
%uint_6 = OpConstant %uint 6 %uint_6 = OpConstant %uint 6
%bool = OpTypeBool
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
%uint_264 = OpConstant %uint 264 %uint_264 = OpConstant %uint 264
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%53 = OpConstantNull %int %68 = OpConstantNull %int
%55 = OpTypeFunction %void %70 = OpTypeFunction %void
%compute_main_inner = OpFunction %void None %15 %tint_div = OpFunction %uint None %15
%local_invocation_index = OpFunctionParameter %uint %lhs = OpFunctionParameter %uint
%rhs = OpFunctionParameter %uint
%19 = OpLabel %19 = OpLabel
%21 = OpIEqual %bool %rhs %6
%20 = OpSelect %uint %21 %uint_1 %rhs
%23 = OpUDiv %uint %lhs %20
OpReturnValue %23
OpFunctionEnd
%tint_mod = OpFunction %uint None %15
%lhs_0 = OpFunctionParameter %uint
%rhs_0 = OpFunctionParameter %uint
%27 = OpLabel
%29 = OpIEqual %bool %rhs_0 %6
%28 = OpSelect %uint %29 %uint_1 %rhs_0
%30 = OpUMod %uint %lhs_0 %28
OpReturnValue %30
OpFunctionEnd
%compute_main_inner = OpFunction %void None %31
%local_invocation_index = OpFunctionParameter %uint
%35 = OpLabel
%idx = OpVariable %_ptr_Function_uint Function %6 %idx = OpVariable %_ptr_Function_uint Function %6
OpStore %idx %6 OpStore %idx %6
OpStore %idx %local_invocation_index OpStore %idx %local_invocation_index
OpBranch %22 OpBranch %38
%22 = OpLabel %38 = OpLabel
OpLoopMerge %23 %24 None OpLoopMerge %39 %40 None
OpBranch %25 OpBranch %41
%25 = OpLabel %41 = OpLabel
%26 = OpLoad %uint %idx %42 = OpLoad %uint %idx
%29 = OpULessThan %bool %26 %uint_6 %45 = OpULessThan %bool %42 %uint_6
%27 = OpLogicalNot %bool %29 %43 = OpLogicalNot %bool %45
OpSelectionMerge %31 None OpSelectionMerge %46 None
OpBranchConditional %27 %32 %31 OpBranchConditional %43 %47 %46
%32 = OpLabel %47 = OpLabel
OpBranch %23 OpBranch %39
%31 = OpLabel %46 = OpLabel
%33 = OpLoad %uint %idx %48 = OpLoad %uint %idx
%34 = OpLoad %uint %idx %49 = OpLoad %uint %idx
%35 = OpLoad %uint %idx %50 = OpLoad %uint %idx
%39 = OpUDiv %uint %33 %uint_2 %51 = OpFunctionCall %uint %tint_div %48 %uint_2
%40 = OpUMod %uint %34 %uint_2 %52 = OpFunctionCall %uint %tint_mod %49 %uint_2
%41 = OpUMod %uint %35 %uint_1 %53 = OpFunctionCall %uint %tint_mod %50 %uint_1
%43 = OpAccessChain %_ptr_Workgroup_uint %wg %39 %40 %41 %58 = OpAccessChain %_ptr_Workgroup_uint %wg %51 %52 %53
OpAtomicStore %43 %uint_2 %uint_0 %6 OpAtomicStore %58 %uint_2 %uint_0 %6
OpBranch %24 OpBranch %40
%24 = OpLabel %40 = OpLabel
%44 = OpLoad %uint %idx %59 = OpLoad %uint %idx
%45 = OpIAdd %uint %44 %uint_1 %60 = OpIAdd %uint %59 %uint_1
OpStore %idx %45 OpStore %idx %60
OpBranch %22 OpBranch %38
%23 = OpLabel %39 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
%54 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %53 %69 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %68
OpAtomicStore %54 %uint_2 %uint_0 %uint_1 OpAtomicStore %69 %uint_2 %uint_0 %uint_1
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main_1 = OpFunction %void None %55 %compute_main_1 = OpFunction %void None %70
%57 = OpLabel %72 = OpLabel
%58 = OpLoad %uint %local_invocation_index_1 %73 = OpLoad %uint %local_invocation_index_1
%59 = OpFunctionCall %void %compute_main_inner %58 %74 = OpFunctionCall %void %compute_main_inner %73
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %15 %compute_main_inner_1 = OpFunction %void None %31
%local_invocation_index_1_param = OpFunctionParameter %uint %local_invocation_index_1_param = OpFunctionParameter %uint
%62 = OpLabel %77 = OpLabel
%idx_1 = OpVariable %_ptr_Function_uint Function %6 %idx_1 = OpVariable %_ptr_Function_uint Function %6
OpStore %idx_1 %local_invocation_index_1_param OpStore %idx_1 %local_invocation_index_1_param
OpBranch %64 OpBranch %79
%64 = OpLabel %79 = OpLabel
OpLoopMerge %65 %66 None OpLoopMerge %80 %81 None
OpBranch %67 OpBranch %82
%67 = OpLabel %82 = OpLabel
%69 = OpLoad %uint %idx_1 %84 = OpLoad %uint %idx_1
%70 = OpULessThan %bool %69 %uint_6 %85 = OpULessThan %bool %84 %uint_6
%68 = OpLogicalNot %bool %70 %83 = OpLogicalNot %bool %85
OpSelectionMerge %71 None OpSelectionMerge %86 None
OpBranchConditional %68 %72 %71 OpBranchConditional %83 %87 %86
%72 = OpLabel %87 = OpLabel
OpBranch %65 OpBranch %80
%71 = OpLabel %86 = OpLabel
%73 = OpLoad %uint %idx_1 %88 = OpLoad %uint %idx_1
%74 = OpUDiv %uint %73 %uint_2 %89 = OpUDiv %uint %88 %uint_2
%75 = OpLoad %uint %idx_1 %90 = OpLoad %uint %idx_1
%76 = OpUMod %uint %75 %uint_2 %91 = OpUMod %uint %90 %uint_2
%77 = OpLoad %uint %idx_1 %92 = OpLoad %uint %idx_1
%78 = OpUMod %uint %77 %uint_1 %93 = OpUMod %uint %92 %uint_1
%81 = OpAccessChain %_ptr_Workgroup_uint %wg %74 %76 %78 %96 = OpAccessChain %_ptr_Workgroup_uint %wg %89 %91 %93
OpAtomicStore %81 %uint_2 %uint_0 %6 OpAtomicStore %96 %uint_2 %uint_0 %6
OpBranch %66 OpBranch %81
%66 = OpLabel %81 = OpLabel
%82 = OpLoad %uint %idx_1 %97 = OpLoad %uint %idx_1
%83 = OpIAdd %uint %82 %uint_1 %98 = OpIAdd %uint %97 %uint_1
OpStore %idx_1 %83 OpStore %idx_1 %98
OpBranch %64 OpBranch %79
%65 = OpLabel %80 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264 OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param OpStore %local_invocation_index_1 %local_invocation_index_1_param
%85 = OpFunctionCall %void %compute_main_1 %100 = OpFunctionCall %void %compute_main_1
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%compute_main = OpFunction %void None %55 %compute_main = OpFunction %void None %70
%87 = OpLabel %102 = OpLabel
%89 = OpLoad %uint %local_invocation_index_1_param_1 %104 = OpLoad %uint %local_invocation_index_1_param_1
%88 = OpFunctionCall %void %compute_main_inner_1 %89 %103 = OpFunctionCall %void %compute_main_inner_1 %104
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 2; const int b = 2;
const int r = (a / (b == 0 ? 1 : b)); const int r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 2; const int b = 2;
const int r = (a / (b == 0 ? 1 : b)); const int r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
int tint_div(int lhs, int rhs) {
return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs));
}
void f() { void f() {
int a = 1; int a = 1;
int b = 2; int b = 2;
int r = (a / b); int r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int tint_div(int lhs, int rhs) {
return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))));
}
kernel void f() { kernel void f() {
int const a = 1; int const a = 1;
int const b = 2; int const b = 2;
int const r = (a / b); int const r = tint_div(a, b);
return; return;
} }

View File

@ -1,20 +1,41 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 9 ; Bound: 25
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%1 = OpTypeFunction %int %int %int
%8 = OpConstantNull %int
%bool = OpTypeBool
%int_n2147483648 = OpConstant %int -2147483648
%int_n1 = OpConstant %int -1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%void = OpTypeVoid
%19 = OpTypeFunction %void
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%f = OpFunction %void None %1 %tint_div = OpFunction %int None %1
%4 = OpLabel %lhs = OpFunctionParameter %int
%8 = OpSDiv %int %int_1 %int_2 %rhs = OpFunctionParameter %int
%6 = OpLabel
%9 = OpIEqual %bool %rhs %8
%12 = OpIEqual %bool %lhs %int_n2147483648
%14 = OpIEqual %bool %rhs %int_n1
%15 = OpLogicalAnd %bool %12 %14
%16 = OpLogicalOr %bool %9 %15
%7 = OpSelect %int %16 %int_1 %rhs
%18 = OpSDiv %int %lhs %7
OpReturnValue %18
OpFunctionEnd
%f = OpFunction %void None %19
%22 = OpLabel
%24 = OpFunctionCall %int %tint_div %int_1 %int_2
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint a = 1u; const uint a = 1u;
const uint b = 2u; const uint b = 2u;
const uint r = (a / (b == 0u ? 1u : b)); const uint r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint a = 1u; const uint a = 1u;
const uint b = 2u; const uint b = 2u;
const uint r = (a / (b == 0u ? 1u : b)); const uint r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
void f() { void f() {
uint a = 1u; uint a = 1u;
uint b = 2u; uint b = 2u;
uint r = (a / b); uint r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
uint tint_div(uint lhs, uint rhs) {
return (lhs / select(rhs, 1u, (rhs == 0u)));
}
kernel void f() { kernel void f() {
uint const a = 1u; uint const a = 1u;
uint const b = 2u; uint const b = 2u;
uint const r = (a / b); uint const r = tint_div(a, b);
return; return;
} }

View File

@ -1,20 +1,35 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 9 ; Bound: 19
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%1 = OpTypeFunction %uint %uint %uint
%8 = OpConstantNull %uint
%bool = OpTypeBool
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%void = OpTypeVoid
%13 = OpTypeFunction %void
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%f = OpFunction %void None %1 %tint_div = OpFunction %uint None %1
%4 = OpLabel %lhs = OpFunctionParameter %uint
%8 = OpUDiv %uint %uint_1 %uint_2 %rhs = OpFunctionParameter %uint
%6 = OpLabel
%9 = OpIEqual %bool %rhs %8
%7 = OpSelect %uint %9 %uint_1 %rhs
%12 = OpUDiv %uint %lhs %7
OpReturnValue %12
OpFunctionEnd
%f = OpFunction %void None %13
%16 = OpLabel
%18 = OpFunctionCall %uint %tint_div %uint_1 %uint_2
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,12 @@
int3 tint_div(int lhs, int3 rhs) {
const int3 l = int3((lhs).xxx);
return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 4; const int a = 4;
const int3 b = int3(1, 2, 3); const int3 b = int3(1, 2, 3);
const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,12 @@
int3 tint_div(int lhs, int3 rhs) {
const int3 l = int3((lhs).xxx);
return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 4; const int a = 4;
const int3 b = int3(1, 2, 3); const int3 b = int3(1, 2, 3);
const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,14 @@
#version 310 es #version 310 es
ivec3 tint_div(int lhs, ivec3 rhs) {
ivec3 l = ivec3(lhs);
return (l / mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))));
}
void f() { void f() {
int a = 4; int a = 4;
ivec3 b = ivec3(1, 2, 3); ivec3 b = ivec3(1, 2, 3);
ivec3 r = (a / b); ivec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,15 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int3 tint_div(int lhs, int3 rhs) {
int3 const l = int3(lhs);
return (l / select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1))))));
}
kernel void f() { kernel void f() {
int const a = 4; int const a = 4;
int3 const b = int3(1, 2, 3); int3 const b = int3(1, 2, 3);
int3 const r = (a / b); int3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,28 +1,50 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 17 ; Bound: 34
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_4 = OpConstant %int 4
%v3int = OpTypeVector %int 3 %v3int = OpTypeVector %int 3
%1 = OpTypeFunction %v3int %int %v3int
%10 = OpConstantNull %v3int
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%int_n2147483648 = OpConstant %int -2147483648
%15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648
%int_n1 = OpConstant %int -1
%18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%void = OpTypeVoid
%25 = OpTypeFunction %void
%int_4 = OpConstant %int 4
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3 %int_3 = OpConstant %int 3
%11 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %32 = OpConstantComposite %v3int %int_1 %int_2 %int_3
%_ptr_Function_v3int = OpTypePointer Function %v3int %tint_div = OpFunction %v3int None %1
%15 = OpConstantNull %v3int %lhs = OpFunctionParameter %int
%f = OpFunction %void None %1 %rhs = OpFunctionParameter %v3int
%4 = OpLabel %7 = OpLabel
%13 = OpVariable %_ptr_Function_v3int Function %15 %8 = OpCompositeConstruct %v3int %lhs %lhs %lhs
%16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 %11 = OpIEqual %v3bool %rhs %10
%12 = OpSDiv %v3int %16 %11 %16 = OpIEqual %v3bool %8 %15
%19 = OpIEqual %v3bool %rhs %18
%20 = OpLogicalAnd %v3bool %16 %19
%21 = OpLogicalOr %v3bool %11 %20
%9 = OpSelect %v3int %21 %23 %rhs
%24 = OpSDiv %v3int %8 %9
OpReturnValue %24
OpFunctionEnd
%f = OpFunction %void None %25
%28 = OpLabel
%33 = OpFunctionCall %v3int %tint_div %int_4 %32
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,12 @@
uint3 tint_div(uint lhs, uint3 rhs) {
const uint3 l = uint3((lhs).xxx);
return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint a = 4u; const uint a = 4u;
const uint3 b = uint3(1u, 2u, 3u); const uint3 b = uint3(1u, 2u, 3u);
const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,12 @@
uint3 tint_div(uint lhs, uint3 rhs) {
const uint3 l = uint3((lhs).xxx);
return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint a = 4u; const uint a = 4u;
const uint3 b = uint3(1u, 2u, 3u); const uint3 b = uint3(1u, 2u, 3u);
const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,14 @@
#version 310 es #version 310 es
uvec3 tint_div(uint lhs, uvec3 rhs) {
uvec3 l = uvec3(lhs);
return (l / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u))));
}
void f() { void f() {
uint a = 4u; uint a = 4u;
uvec3 b = uvec3(1u, 2u, 3u); uvec3 b = uvec3(1u, 2u, 3u);
uvec3 r = (a / b); uvec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,15 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
uint3 tint_div(uint lhs, uint3 rhs) {
uint3 const l = uint3(lhs);
return (l / select(rhs, uint3(1u), (rhs == uint3(0u))));
}
kernel void f() { kernel void f() {
uint const a = 4u; uint const a = 4u;
uint3 const b = uint3(1u, 2u, 3u); uint3 const b = uint3(1u, 2u, 3u);
uint3 const r = (a / b); uint3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,28 +1,42 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 17 ; Bound: 26
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%v3uint = OpTypeVector %uint 3 %v3uint = OpTypeVector %uint 3
%1 = OpTypeFunction %v3uint %uint %v3uint
%10 = OpConstantNull %v3uint
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%void = OpTypeVoid
%17 = OpTypeFunction %void
%uint_4 = OpConstant %uint 4
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%uint_3 = OpConstant %uint 3 %uint_3 = OpConstant %uint 3
%11 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %24 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
%_ptr_Function_v3uint = OpTypePointer Function %v3uint %tint_div = OpFunction %v3uint None %1
%15 = OpConstantNull %v3uint %lhs = OpFunctionParameter %uint
%f = OpFunction %void None %1 %rhs = OpFunctionParameter %v3uint
%4 = OpLabel %7 = OpLabel
%13 = OpVariable %_ptr_Function_v3uint Function %15 %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs
%16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 %11 = OpIEqual %v3bool %rhs %10
%12 = OpUDiv %v3uint %16 %11 %9 = OpSelect %v3uint %11 %15 %rhs
%16 = OpUDiv %v3uint %8 %9
OpReturnValue %16
OpFunctionEnd
%f = OpFunction %void None %17
%20 = OpLabel
%25 = OpFunctionCall %v3uint %tint_div %uint_4 %24
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,12 @@
int3 tint_div(int3 lhs, int rhs) {
const int3 r = int3((rhs).xxx);
return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int3 a = int3(1, 2, 3); const int3 a = int3(1, 2, 3);
const int b = 4; const int b = 4;
const int3 r = (a / (b == 0 ? 1 : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,12 @@
int3 tint_div(int3 lhs, int rhs) {
const int3 r = int3((rhs).xxx);
return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int3 a = int3(1, 2, 3); const int3 a = int3(1, 2, 3);
const int b = 4; const int b = 4;
const int3 r = (a / (b == 0 ? 1 : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,14 @@
#version 310 es #version 310 es
ivec3 tint_div(ivec3 lhs, int rhs) {
ivec3 r = ivec3(rhs);
return (lhs / mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1))))))));
}
void f() { void f() {
ivec3 a = ivec3(1, 2, 3); ivec3 a = ivec3(1, 2, 3);
int b = 4; int b = 4;
ivec3 r = (a / b); ivec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,15 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int3 tint_div(int3 lhs, int rhs) {
int3 const r = int3(rhs);
return (lhs / select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1))))));
}
kernel void f() { kernel void f() {
int3 const a = int3(1, 2, 3); int3 const a = int3(1, 2, 3);
int const b = 4; int const b = 4;
int3 const r = (a / b); int3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,28 +1,50 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 17 ; Bound: 34
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%v3int = OpTypeVector %int 3 %v3int = OpTypeVector %int 3
%1 = OpTypeFunction %v3int %v3int %int
%10 = OpConstantNull %v3int
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%int_n2147483648 = OpConstant %int -2147483648
%15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648
%int_n1 = OpConstant %int -1
%18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%void = OpTypeVoid
%25 = OpTypeFunction %void
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3 %int_3 = OpConstant %int 3
%10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3
%int_4 = OpConstant %int 4 %int_4 = OpConstant %int 4
%_ptr_Function_v3int = OpTypePointer Function %v3int %tint_div = OpFunction %v3int None %1
%15 = OpConstantNull %v3int %lhs = OpFunctionParameter %v3int
%f = OpFunction %void None %1 %rhs = OpFunctionParameter %int
%4 = OpLabel %7 = OpLabel
%13 = OpVariable %_ptr_Function_v3int Function %15 %8 = OpCompositeConstruct %v3int %rhs %rhs %rhs
%16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 %11 = OpIEqual %v3bool %8 %10
%12 = OpSDiv %v3int %10 %16 %16 = OpIEqual %v3bool %lhs %15
%19 = OpIEqual %v3bool %8 %18
%20 = OpLogicalAnd %v3bool %16 %19
%21 = OpLogicalOr %v3bool %11 %20
%9 = OpSelect %v3int %21 %23 %8
%24 = OpSDiv %v3int %lhs %9
OpReturnValue %24
OpFunctionEnd
%f = OpFunction %void None %25
%28 = OpLabel
%33 = OpFunctionCall %v3int %tint_div %31 %int_4
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,12 @@
uint3 tint_div(uint3 lhs, uint rhs) {
const uint3 r = uint3((rhs).xxx);
return (lhs / ((r == (0u).xxx) ? (1u).xxx : r));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint3 a = uint3(1u, 2u, 3u); const uint3 a = uint3(1u, 2u, 3u);
const uint b = 4u; const uint b = 4u;
const uint3 r = (a / (b == 0u ? 1u : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,12 @@
uint3 tint_div(uint3 lhs, uint rhs) {
const uint3 r = uint3((rhs).xxx);
return (lhs / ((r == (0u).xxx) ? (1u).xxx : r));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint3 a = uint3(1u, 2u, 3u); const uint3 a = uint3(1u, 2u, 3u);
const uint b = 4u; const uint b = 4u;
const uint3 r = (a / (b == 0u ? 1u : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,14 @@
#version 310 es #version 310 es
uvec3 tint_div(uvec3 lhs, uint rhs) {
uvec3 r = uvec3(rhs);
return (lhs / mix(r, uvec3(1u), equal(r, uvec3(0u))));
}
void f() { void f() {
uvec3 a = uvec3(1u, 2u, 3u); uvec3 a = uvec3(1u, 2u, 3u);
uint b = 4u; uint b = 4u;
uvec3 r = (a / b); uvec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,15 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
uint3 tint_div(uint3 lhs, uint rhs) {
uint3 const r = uint3(rhs);
return (lhs / select(r, uint3(1u), (r == uint3(0u))));
}
kernel void f() { kernel void f() {
uint3 const a = uint3(1u, 2u, 3u); uint3 const a = uint3(1u, 2u, 3u);
uint const b = 4u; uint const b = 4u;
uint3 const r = (a / b); uint3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,28 +1,42 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 17 ; Bound: 26
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3 %v3uint = OpTypeVector %uint 3
%1 = OpTypeFunction %v3uint %v3uint %uint
%10 = OpConstantNull %v3uint
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%void = OpTypeVoid
%17 = OpTypeFunction %void
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%uint_3 = OpConstant %uint 3 %uint_3 = OpConstant %uint 3
%10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
%uint_4 = OpConstant %uint 4 %uint_4 = OpConstant %uint 4
%_ptr_Function_v3uint = OpTypePointer Function %v3uint %tint_div = OpFunction %v3uint None %1
%15 = OpConstantNull %v3uint %lhs = OpFunctionParameter %v3uint
%f = OpFunction %void None %1 %rhs = OpFunctionParameter %uint
%4 = OpLabel %7 = OpLabel
%13 = OpVariable %_ptr_Function_v3uint Function %15 %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs
%16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 %11 = OpIEqual %v3bool %8 %10
%12 = OpUDiv %v3uint %10 %16 %9 = OpSelect %v3uint %11 %15 %8
%16 = OpUDiv %v3uint %lhs %9
OpReturnValue %16
OpFunctionEnd
%f = OpFunction %void None %17
%20 = OpLabel
%25 = OpFunctionCall %v3uint %tint_div %23 %uint_4
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
int3 tint_div(int3 lhs, int3 rhs) {
return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int3 a = int3(1, 2, 3); const int3 a = int3(1, 2, 3);
const int3 b = int3(4, 5, 6); const int3 b = int3(4, 5, 6);
const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
int3 tint_div(int3 lhs, int3 rhs) {
return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int3 a = int3(1, 2, 3); const int3 a = int3(1, 2, 3);
const int3 b = int3(4, 5, 6); const int3 b = int3(4, 5, 6);
const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); const int3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
ivec3 tint_div(ivec3 lhs, ivec3 rhs) {
return (lhs / mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))));
}
void f() { void f() {
ivec3 a = ivec3(1, 2, 3); ivec3 a = ivec3(1, 2, 3);
ivec3 b = ivec3(4, 5, 6); ivec3 b = ivec3(4, 5, 6);
ivec3 r = (a / b); ivec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int3 tint_div(int3 lhs, int3 rhs) {
return (lhs / select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1))))));
}
kernel void f() { kernel void f() {
int3 const a = int3(1, 2, 3); int3 const a = int3(1, 2, 3);
int3 const b = int3(4, 5, 6); int3 const b = int3(4, 5, 6);
int3 const r = (a / b); int3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,27 +1,52 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 16 ; Bound: 36
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%v3int = OpTypeVector %int 3 %v3int = OpTypeVector %int 3
%1 = OpTypeFunction %v3int %v3int %v3int
%9 = OpConstantNull %v3int
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%int_n2147483648 = OpConstant %int -2147483648
%14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648
%int_n1 = OpConstant %int -1
%17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%void = OpTypeVoid
%24 = OpTypeFunction %void
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3 %int_3 = OpConstant %int 3
%10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3
%int_4 = OpConstant %int 4 %int_4 = OpConstant %int 4
%int_5 = OpConstant %int 5 %int_5 = OpConstant %int 5
%int_6 = OpConstant %int 6 %int_6 = OpConstant %int 6
%14 = OpConstantComposite %v3int %int_4 %int_5 %int_6 %34 = OpConstantComposite %v3int %int_4 %int_5 %int_6
%f = OpFunction %void None %1 %tint_div = OpFunction %v3int None %1
%4 = OpLabel %lhs = OpFunctionParameter %v3int
%15 = OpSDiv %v3int %10 %14 %rhs = OpFunctionParameter %v3int
%7 = OpLabel
%10 = OpIEqual %v3bool %rhs %9
%15 = OpIEqual %v3bool %lhs %14
%18 = OpIEqual %v3bool %rhs %17
%19 = OpLogicalAnd %v3bool %15 %18
%20 = OpLogicalOr %v3bool %10 %19
%8 = OpSelect %v3int %20 %22 %rhs
%23 = OpSDiv %v3int %lhs %8
OpReturnValue %23
OpFunctionEnd
%f = OpFunction %void None %24
%27 = OpLabel
%35 = OpFunctionCall %v3int %tint_div %30 %34
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
uint3 tint_div(uint3 lhs, uint3 rhs) {
return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint3 a = uint3(1u, 2u, 3u); const uint3 a = uint3(1u, 2u, 3u);
const uint3 b = uint3(4u, 5u, 6u); const uint3 b = uint3(4u, 5u, 6u);
const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
uint3 tint_div(uint3 lhs, uint3 rhs) {
return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint3 a = uint3(1u, 2u, 3u); const uint3 a = uint3(1u, 2u, 3u);
const uint3 b = uint3(4u, 5u, 6u); const uint3 b = uint3(4u, 5u, 6u);
const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); const uint3 r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
uvec3 tint_div(uvec3 lhs, uvec3 rhs) {
return (lhs / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u))));
}
void f() { void f() {
uvec3 a = uvec3(1u, 2u, 3u); uvec3 a = uvec3(1u, 2u, 3u);
uvec3 b = uvec3(4u, 5u, 6u); uvec3 b = uvec3(4u, 5u, 6u);
uvec3 r = (a / b); uvec3 r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
uint3 tint_div(uint3 lhs, uint3 rhs) {
return (lhs / select(rhs, uint3(1u), (rhs == uint3(0u))));
}
kernel void f() { kernel void f() {
uint3 const a = uint3(1u, 2u, 3u); uint3 const a = uint3(1u, 2u, 3u);
uint3 const b = uint3(4u, 5u, 6u); uint3 const b = uint3(4u, 5u, 6u);
uint3 const r = (a / b); uint3 const r = tint_div(a, b);
return; return;
} }

View File

@ -1,27 +1,44 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 16 ; Bound: 28
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3 %v3uint = OpTypeVector %uint 3
%1 = OpTypeFunction %v3uint %v3uint %v3uint
%9 = OpConstantNull %v3uint
%bool = OpTypeBool
%v3bool = OpTypeVector %bool 3
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%void = OpTypeVoid
%16 = OpTypeFunction %void
%uint_2 = OpConstant %uint 2 %uint_2 = OpConstant %uint 2
%uint_3 = OpConstant %uint 3 %uint_3 = OpConstant %uint 3
%10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
%uint_4 = OpConstant %uint 4 %uint_4 = OpConstant %uint 4
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%uint_6 = OpConstant %uint 6 %uint_6 = OpConstant %uint 6
%14 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6 %26 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6
%f = OpFunction %void None %1 %tint_div = OpFunction %v3uint None %1
%4 = OpLabel %lhs = OpFunctionParameter %v3uint
%15 = OpUDiv %v3uint %10 %14 %rhs = OpFunctionParameter %v3uint
%7 = OpLabel
%10 = OpIEqual %v3bool %rhs %9
%8 = OpSelect %v3uint %10 %14 %rhs
%15 = OpUDiv %v3uint %lhs %8
OpReturnValue %15
OpFunctionEnd
%f = OpFunction %void None %16
%19 = OpLabel
%27 = OpFunctionCall %v3uint %tint_div %22 %26
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 0; const int b = 0;
const int r = (a / (b == 0 ? 1 : b)); const int r = tint_div(a, b);
return; return;
} }

View File

@ -1,7 +1,11 @@
int tint_div(int lhs, int rhs) {
return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const int a = 1; const int a = 1;
const int b = 0; const int b = 0;
const int r = (a / (b == 0 ? 1 : b)); const int r = tint_div(a, b);
return; return;
} }

View File

@ -1,9 +1,13 @@
#version 310 es #version 310 es
int tint_div(int lhs, int rhs) {
return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs));
}
void f() { void f() {
int a = 1; int a = 1;
int b = 0; int b = 0;
int r = (a / b); int r = tint_div(a, b);
} }
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,10 +1,14 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
int tint_div(int lhs, int rhs) {
return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))));
}
kernel void f() { kernel void f() {
int const a = 1; int const a = 1;
int const b = 0; int const b = 0;
int const r = (a / b); int const r = tint_div(a, b);
return; return;
} }

View File

@ -1,20 +1,40 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 9 ; Bound: 24
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %f "f" OpEntryPoint GLCompute %f "f"
OpExecutionMode %f LocalSize 1 1 1 OpExecutionMode %f LocalSize 1 1 1
OpName %tint_div "tint_div"
OpName %lhs "lhs"
OpName %rhs "rhs"
OpName %f "f" OpName %f "f"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%1 = OpTypeFunction %int %int %int
%8 = OpConstantNull %int
%bool = OpTypeBool
%int_n2147483648 = OpConstant %int -2147483648
%int_n1 = OpConstant %int -1
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%7 = OpConstantNull %int %void = OpTypeVoid
%f = OpFunction %void None %1 %19 = OpTypeFunction %void
%4 = OpLabel %tint_div = OpFunction %int None %1
%8 = OpSDiv %int %int_1 %7 %lhs = OpFunctionParameter %int
%rhs = OpFunctionParameter %int
%6 = OpLabel
%9 = OpIEqual %bool %rhs %8
%12 = OpIEqual %bool %lhs %int_n2147483648
%14 = OpIEqual %bool %rhs %int_n1
%15 = OpLogicalAnd %bool %12 %14
%16 = OpLogicalOr %bool %9 %15
%7 = OpSelect %int %16 %int_1 %rhs
%18 = OpSDiv %int %lhs %7
OpReturnValue %18
OpFunctionEnd
%f = OpFunction %void None %19
%22 = OpLabel
%23 = OpFunctionCall %int %tint_div %int_1 %8
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -1,7 +1,11 @@
uint tint_div(uint lhs, uint rhs) {
return (lhs / ((rhs == 0u) ? 1u : rhs));
}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void f() { void f() {
const uint a = 1u; const uint a = 1u;
const uint b = 0u; const uint b = 0u;
const uint r = (a / (b == 0u ? 1u : b)); const uint r = tint_div(a, b);
return; return;
} }

Some files were not shown because too many files have changed in this diff Show More