Skip to content

Commit

Permalink
[ir] Polyfill fwidthFine for MSL and HLSL
Browse files Browse the repository at this point in the history
Compute the result using `dpdxFine` and `dpdyFine` to get the required
behavior.

Bug: 42251016
Change-Id: I30f072ca9a9e98d8575d5d74c6b89d88456de044
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/205497
Reviewed-by: Antonio Maiorano <[email protected]>
Commit-Queue: James Price <[email protected]>
  • Loading branch information
jrprice authored and Dawn LUCI CQ committed Sep 6, 2024
1 parent cca4859 commit c811e1e
Show file tree
Hide file tree
Showing 31 changed files with 218 additions and 27 deletions.
24 changes: 24 additions & 0 deletions src/tint/lang/core/ir/transform/builtin_polyfill.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ struct State {
worklist.Push(builtin);
}
break;
case core::BuiltinFn::kFwidthFine:
if (config.fwidth_fine) {
worklist.Push(builtin);
}
break;
case core::BuiltinFn::kInsertBits:
if (config.insert_bits != BuiltinPolyfillLevel::kNone) {
worklist.Push(builtin);
Expand Down Expand Up @@ -183,6 +188,9 @@ struct State {
case core::BuiltinFn::kFirstTrailingBit:
FirstTrailingBit(builtin);
break;
case core::BuiltinFn::kFwidthFine:
FwidthFine(builtin);
break;
case core::BuiltinFn::kInsertBits:
InsertBits(builtin);
break;
Expand Down Expand Up @@ -528,6 +536,22 @@ struct State {
call->Destroy();
}

/// Polyfill a `fwidthFine()` builtin call.
/// @param call the builtin call instruction
void FwidthFine(ir::CoreBuiltinCall* call) {
auto* value = call->Args()[0];
auto* type = value->Type();
b.InsertBefore(call, [&] {
auto* dpdx = b.Call(type, core::BuiltinFn::kDpdxFine, value);
auto* dpdy = b.Call(type, core::BuiltinFn::kDpdyFine, value);
auto* abs_dpdx = b.Call(type, core::BuiltinFn::kAbs, dpdx);
auto* abs_dpdy = b.Call(type, core::BuiltinFn::kAbs, dpdy);
auto* result = b.Add(type, abs_dpdx, abs_dpdy);
call->Result(0)->ReplaceAllUsesWith(result->Result(0));
});
call->Destroy();
}

/// Polyfill an `insertBits()` builtin call.
/// @param call the builtin call instruction
void InsertBits(ir::CoreBuiltinCall* call) {
Expand Down
2 changes: 2 additions & 0 deletions src/tint/lang/core/ir/transform/builtin_polyfill.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ struct BuiltinPolyfillConfig {
bool first_leading_bit = false;
/// Should `firstTrailingBit()` be polyfilled?
bool first_trailing_bit = false;
/// Should `fwidthFine()` be polyfilled?
bool fwidth_fine = false;
/// How should `insertBits()` be polyfilled?
BuiltinPolyfillLevel insert_bits = BuiltinPolyfillLevel::kNone;
/// Should `radians()` be polyfilled?
Expand Down
82 changes: 82 additions & 0 deletions src/tint/lang/core/ir/transform/builtin_polyfill_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,88 @@ TEST_F(IR_BuiltinPolyfillTest, FirstTrailingBit_Vec4I32) {
EXPECT_EQ(expect, str());
}

TEST_F(IR_BuiltinPolyfillTest, FwidthFine_NoPolyfill) {
Build(core::BuiltinFn::kFwidthFine, ty.f32(), Vector{ty.f32()});
auto* src = R"(
%foo = func(%arg:f32):f32 {
$B1: {
%result:f32 = fwidthFine %arg
ret %result
}
}
)";
auto* expect = src;

EXPECT_EQ(src, str());

BuiltinPolyfillConfig config;
config.fwidth_fine = false;
Run(BuiltinPolyfill, config);
EXPECT_EQ(expect, str());
}

TEST_F(IR_BuiltinPolyfillTest, FirstLeadingBit_F32) {
Build(core::BuiltinFn::kFwidthFine, ty.f32(), Vector{ty.f32()});
auto* src = R"(
%foo = func(%arg:f32):f32 {
$B1: {
%result:f32 = fwidthFine %arg
ret %result
}
}
)";
auto* expect = R"(
%foo = func(%arg:f32):f32 {
$B1: {
%3:f32 = dpdxFine %arg
%4:f32 = dpdyFine %arg
%5:f32 = abs %3
%6:f32 = abs %4
%7:f32 = add %5, %6
ret %7
}
}
)";

EXPECT_EQ(src, str());

BuiltinPolyfillConfig config;
config.fwidth_fine = true;
Run(BuiltinPolyfill, config);
EXPECT_EQ(expect, str());
}

TEST_F(IR_BuiltinPolyfillTest, FirstLeadingBit_Vector) {
Build(core::BuiltinFn::kFwidthFine, ty.vec4<f32>(), Vector{ty.vec4<f32>()});
auto* src = R"(
%foo = func(%arg:vec4<f32>):vec4<f32> {
$B1: {
%result:vec4<f32> = fwidthFine %arg
ret %result
}
}
)";
auto* expect = R"(
%foo = func(%arg:vec4<f32>):vec4<f32> {
$B1: {
%3:vec4<f32> = dpdxFine %arg
%4:vec4<f32> = dpdyFine %arg
%5:vec4<f32> = abs %3
%6:vec4<f32> = abs %4
%7:vec4<f32> = add %5, %6
ret %7
}
}
)";

EXPECT_EQ(src, str());

BuiltinPolyfillConfig config;
config.fwidth_fine = true;
Run(BuiltinPolyfill, config);
EXPECT_EQ(expect, str());
}

TEST_F(IR_BuiltinPolyfillTest, InsertBits_NoPolyfill) {
Build(core::BuiltinFn::kInsertBits, ty.u32(), Vector{ty.u32(), ty.u32(), ty.u32(), ty.u32()});
auto* src = R"(
Expand Down
1 change: 0 additions & 1 deletion src/tint/lang/hlsl/writer/printer/printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,6 @@ class Printer : public tint::TextGenerator {
break;
case core::BuiltinFn::kFwidth:
case core::BuiltinFn::kFwidthCoarse:
case core::BuiltinFn::kFwidthFine:
out << "fwidth";
break;
case core::BuiltinFn::kInverseSqrt:
Expand Down
2 changes: 1 addition & 1 deletion src/tint/lang/hlsl/writer/raise/raise.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
core_polyfills.extract_bits = core::ir::transform::BuiltinPolyfillLevel::kFull;
core_polyfills.first_leading_bit = true;
core_polyfills.first_trailing_bit = true;
// core_polyfills.fwidth_fine = true;
core_polyfills.fwidth_fine = true;
core_polyfills.insert_bits = core::ir::transform::BuiltinPolyfillLevel::kFull;
// core_polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;

Expand Down
1 change: 0 additions & 1 deletion src/tint/lang/msl/writer/printer/printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,6 @@ class Printer : public tint::TextGenerator {
break;
case core::BuiltinFn::kFwidth:
case core::BuiltinFn::kFwidthCoarse:
case core::BuiltinFn::kFwidthFine:
out << "fwidth";
break;
case core::BuiltinFn::kFaceForward:
Expand Down
1 change: 1 addition & 0 deletions src/tint/lang/msl/writer/raise/raise.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Result<RaiseResult> Raise(core::ir::Module& module, const Options& options) {
core_polyfills.extract_bits = core::ir::transform::BuiltinPolyfillLevel::kClampOrRangeCheck;
core_polyfills.first_leading_bit = true;
core_polyfills.first_trailing_bit = true;
core_polyfills.fwidth_fine = true;
core_polyfills.insert_bits = core::ir::transform::BuiltinPolyfillLevel::kClampOrRangeCheck;
core_polyfills.pack_unpack_4x8 = true;
core_polyfills.pack_4xu8_clamp = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float3 fwidthFine_523fdc() {
float3 res = fwidth((1.0f).xxx);
float3 v = ddx_fine((1.0f).xxx);
float3 v_1 = ddy_fine((1.0f).xxx);
float3 v_2 = abs(v);
float3 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float3 fwidthFine_523fdc() {
float3 res = fwidth((1.0f).xxx);
float3 v = ddx_fine((1.0f).xxx);
float3 v_1 = ddy_fine((1.0f).xxx);
float3 v_2 = abs(v);
float3 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ struct tint_module_vars_struct {
};

float3 fwidthFine_523fdc() {
float3 res = fwidth(float3(1.0f));
float3 const v = dfdx(float3(1.0f));
float3 const v_1 = dfdy(float3(1.0f));
float3 const v_2 = abs(v);
float3 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float4 fwidthFine_68f4ef() {
float4 res = fwidth((1.0f).xxxx);
float4 v = ddx_fine((1.0f).xxxx);
float4 v_1 = ddy_fine((1.0f).xxxx);
float4 v_2 = abs(v);
float4 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float4 fwidthFine_68f4ef() {
float4 res = fwidth((1.0f).xxxx);
float4 v = ddx_fine((1.0f).xxxx);
float4 v_1 = ddy_fine((1.0f).xxxx);
float4 v_2 = abs(v);
float4 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ struct tint_module_vars_struct {
};

float4 fwidthFine_68f4ef() {
float4 res = fwidth(float4(1.0f));
float4 const v = dfdx(float4(1.0f));
float4 const v_1 = dfdy(float4(1.0f));
float4 const v_2 = abs(v);
float4 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float fwidthFine_f1742d() {
float res = fwidth(1.0f);
float v = ddx_fine(1.0f);
float v_1 = ddy_fine(1.0f);
float v_2 = abs(v);
float res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float fwidthFine_f1742d() {
float res = fwidth(1.0f);
float v = ddx_fine(1.0f);
float v_1 = ddy_fine(1.0f);
float v_2 = abs(v);
float res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ struct tint_module_vars_struct {
};

float fwidthFine_f1742d() {
float res = fwidth(1.0f);
float const v = dfdx(1.0f);
float const v_1 = dfdy(1.0f);
float const v_2 = abs(v);
float res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float2 fwidthFine_ff6aa0() {
float2 res = fwidth((1.0f).xx);
float2 v = ddx_fine((1.0f).xx);
float2 v_1 = ddy_fine((1.0f).xx);
float2 v_2 = abs(v);
float2 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

RWByteAddressBuffer prevent_dce : register(u0);
float2 fwidthFine_ff6aa0() {
float2 res = fwidth((1.0f).xx);
float2 v = ddx_fine((1.0f).xx);
float2 v_1 = ddy_fine((1.0f).xx);
float2 v_2 = abs(v);
float2 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ struct tint_module_vars_struct {
};

float2 fwidthFine_ff6aa0() {
float2 res = fwidth(float2(1.0f));
float2 const v = dfdx(float2(1.0f));
float2 const v_1 = dfdy(float2(1.0f));
float2 const v_2 = abs(v);
float2 res = (v_2 + abs(v_1));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
RWByteAddressBuffer prevent_dce : register(u0);
float3 fwidthFine_523fdc() {
float3 arg_0 = (1.0f).xxx;
float3 res = fwidth(arg_0);
float3 v = arg_0;
float3 v_1 = ddx_fine(v);
float3 v_2 = ddy_fine(v);
float3 v_3 = abs(v_1);
float3 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
RWByteAddressBuffer prevent_dce : register(u0);
float3 fwidthFine_523fdc() {
float3 arg_0 = (1.0f).xxx;
float3 res = fwidth(arg_0);
float3 v = arg_0;
float3 v_1 = ddx_fine(v);
float3 v_2 = ddy_fine(v);
float3 v_3 = abs(v_1);
float3 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ struct tint_module_vars_struct {

float3 fwidthFine_523fdc() {
float3 arg_0 = float3(1.0f);
float3 res = fwidth(arg_0);
float3 const v = arg_0;
float3 const v_1 = dfdx(v);
float3 const v_2 = dfdy(v);
float3 const v_3 = abs(v_1);
float3 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
RWByteAddressBuffer prevent_dce : register(u0);
float4 fwidthFine_68f4ef() {
float4 arg_0 = (1.0f).xxxx;
float4 res = fwidth(arg_0);
float4 v = arg_0;
float4 v_1 = ddx_fine(v);
float4 v_2 = ddy_fine(v);
float4 v_3 = abs(v_1);
float4 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
RWByteAddressBuffer prevent_dce : register(u0);
float4 fwidthFine_68f4ef() {
float4 arg_0 = (1.0f).xxxx;
float4 res = fwidth(arg_0);
float4 v = arg_0;
float4 v_1 = ddx_fine(v);
float4 v_2 = ddy_fine(v);
float4 v_3 = abs(v_1);
float4 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ struct tint_module_vars_struct {

float4 fwidthFine_68f4ef() {
float4 arg_0 = float4(1.0f);
float4 res = fwidth(arg_0);
float4 const v = arg_0;
float4 const v_1 = dfdx(v);
float4 const v_2 = dfdy(v);
float4 const v_3 = abs(v_1);
float4 res = (v_3 + abs(v_2));
return res;
}

Expand Down
Loading

0 comments on commit c811e1e

Please sign in to comment.