Reland ExternalTexture Gamma/Gamut Correction
Adds configurable gamma and gamut correction in Tint's external texture
transform. Adds constants in Dawn to perform correct conversion from
BT.709 to sRGB.
Bug: dawn:1082
Change-Id: I68b7ad7ccec29977c637a0a0d4f526cd47fe73d4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88367
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index a5a2134..34df013 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -51,6 +51,9 @@
/// as input into the transform.
const NewBindingPoints* new_binding_points;
+ /// Symbol for the GammaTransferParams
+ Symbol gamma_transfer_struct_sym;
+
/// Symbol for the ExternalTextureParams struct
Symbol params_struct_sym;
@@ -60,6 +63,9 @@
/// Symbol for the textureSampleExternal function
Symbol texture_sample_external_sym;
+ /// Symbol for the gammaCorrection function
+ Symbol gamma_correction_sym;
+
/// Storage for new bindings that have been created corresponding to an
/// original texture_external binding.
std::unordered_map<const sem::Variable*, NewBindingSymbols>
@@ -96,7 +102,7 @@
// If we find a texture_external binding, we know we must emit the
// ExternalTextureParams struct.
if (!params_struct_sym.IsValid()) {
- createExtTexParamsStruct();
+ createExtTexParamsStructs();
}
// The binding points for the newly introduced bindings must have been
@@ -158,7 +164,7 @@
// If we find a texture_external, we must ensure the
// ExternalTextureParams struct exists.
if (!params_struct_sym.IsValid()) {
- createExtTexParamsStruct();
+ createExtTexParamsStructs();
}
// When a texture_external is found, we insert all components
// the texture_external into the parameter list. We must also place
@@ -236,15 +242,68 @@
});
}
- /// Creates the ExternalTextureParams struct.
- void createExtTexParamsStruct() {
- ast::StructMemberList member_list = {
+ /// Creates the parameter structs associated with the transform.
+ void createExtTexParamsStructs() {
+ // Create GammaTransferParams struct.
+ ast::StructMemberList gamma_transfer_member_list = {
+ b.Member("G", b.ty.f32()), b.Member("A", b.ty.f32()),
+ b.Member("B", b.ty.f32()), b.Member("C", b.ty.f32()),
+ b.Member("D", b.ty.f32()), b.Member("E", b.ty.f32()),
+ b.Member("F", b.ty.f32()), b.Member("padding", b.ty.u32())};
+
+ gamma_transfer_struct_sym = b.Symbols().New("GammaTransferParams");
+
+ b.Structure(gamma_transfer_struct_sym, gamma_transfer_member_list);
+
+ // Create ExternalTextureParams struct.
+ ast::StructMemberList ext_tex_params_member_list = {
b.Member("numPlanes", b.ty.u32()),
- b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4(b.ty.f32()))};
+ b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4(b.ty.f32())),
+ b.Member("gammaDecodeParams", b.ty.type_name("GammaTransferParams")),
+ b.Member("gammaEncodeParams", b.ty.type_name("GammaTransferParams")),
+ b.Member("gamutConversionMatrix", b.ty.mat3x3(b.ty.f32()))};
params_struct_sym = b.Symbols().New("ExternalTextureParams");
- b.Structure(params_struct_sym, member_list);
+ b.Structure(params_struct_sym, ext_tex_params_member_list);
+ }
+
+ /// Creates the gammaCorrection function if needed and returns a call
+ /// expression to it.
+ void createGammaCorrectionFn() {
+ using f32 = ProgramBuilder::f32;
+ ast::VariableList varList = {
+ b.Param("v", b.ty.vec3<f32>()),
+ b.Param("params", b.ty.type_name(gamma_transfer_struct_sym))};
+
+ ast::StatementList statementList = {
+ // let cond = abs(v) < vec3(params.D);
+ b.Decl(b.Let("cond", nullptr,
+ b.LessThan(b.Call("abs", "v"),
+ b.vec3<f32>(b.MemberAccessor("params", "D"))))),
+ // let t = sign(v) * ((params.C * abs(v)) + params.F);
+ b.Decl(b.Let("t", nullptr,
+ b.Mul(b.Call("sign", "v"),
+ b.Add(b.Mul(b.MemberAccessor("params", "C"),
+ b.Call("abs", "v")),
+ b.MemberAccessor("params", "F"))))),
+ // let f = (sign(v) * pow(((params.A * abs(v)) + params.B),
+ // vec3(params.G))) + params.E;
+ b.Decl(b.Let(
+ "f", nullptr,
+ b.Mul(b.Call("sign", "v"),
+ b.Add(b.Call("pow",
+ b.Add(b.Mul(b.MemberAccessor("params", "A"),
+ b.Call("abs", "v")),
+ b.MemberAccessor("params", "B")),
+ b.vec3<f32>(b.MemberAccessor("params", "G"))),
+ b.MemberAccessor("params", "E"))))),
+ // return select(f, t, cond);
+ b.Return(b.Call("select", "f", "t", "cond"))};
+
+ gamma_correction_sym = b.Symbols().New("gammaCorrection");
+
+ b.Func(gamma_correction_sym, varList, b.ty.vec3<f32>(), statementList, {});
}
/// Constructs a StatementList containing all the statements making up the
@@ -297,6 +356,18 @@
b.MemberAccessor(plane_1_call, "rg"), 1.0f),
b.MemberAccessor(
"params", "yuvToRgbConversionMatrix"))))),
+ // color = gammaConversion(color, gammaDecodeParams);
+ b.Assign("color",
+ b.Call("gammaCorrection", "color",
+ b.MemberAccessor("params", "gammaDecodeParams"))),
+ // color = (params.gamutConversionMatrix * color);
+ b.Assign("color",
+ b.Mul(b.MemberAccessor("params", "gamutConversionMatrix"),
+ "color")),
+ // color = gammaConversion(color, gammaEncodeParams);
+ b.Assign("color",
+ b.Call("gammaCorrection", "color",
+ b.MemberAccessor("params", "gammaEncodeParams"))),
// return vec4<f32>(color, 1.0f);
b.Return(b.vec4<f32>("color", 1.0f))};
}
@@ -318,6 +389,12 @@
<< expr->args.size() << " parameters";
}
+ // TextureSampleExternal calls the gammaCorrection function, so ensure it
+ // exists.
+ if (!gamma_correction_sym.IsValid()) {
+ createGammaCorrectionFn();
+ }
+
if (!texture_sample_external_sym.IsValid()) {
texture_sample_external_sym = b.Symbols().New("textureSampleExternal");
@@ -362,6 +439,12 @@
<< expr->args.size() << " parameters";
}
+ // TextureLoadExternal calls the gammaCorrection function, so ensure it
+ // exists.
+ if (!gamma_correction_sym.IsValid()) {
+ createGammaCorrectionFn();
+ }
+
if (!texture_load_external_sym.IsValid()) {
texture_load_external_sym = b.Symbols().New("textureLoadExternal");
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index df3b837..77448a7 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -106,9 +106,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -146,9 +160,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -185,9 +213,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -198,6 +240,13 @@
@group(0) @binding(1) var ext_tex : texture_2d<f32>;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -205,6 +254,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -234,15 +286,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -250,6 +323,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -282,9 +358,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -293,6 +383,13 @@
@group(0) @binding(0) var ext_tex : texture_2d<f32>;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -300,6 +397,9 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -328,15 +428,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(2) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -344,6 +465,9 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -376,9 +500,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -389,6 +527,13 @@
@group(0) @binding(1) var ext_tex : texture_2d<f32>;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -396,6 +541,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -406,6 +554,9 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -436,15 +587,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -452,6 +624,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -462,6 +637,9 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -498,9 +676,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(4) var ext_tex_plane_1 : texture_2d<f32>;
@@ -529,6 +721,13 @@
@group(1) @binding(0) var ext_tex_3 : texture_2d<f32>;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -536,6 +735,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -575,15 +777,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -591,6 +814,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -635,9 +861,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -649,6 +889,13 @@
f(ext_tex, ext_tex_plane_1, ext_tex_params, smp);
}
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -656,6 +903,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -694,15 +944,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -710,6 +981,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -755,9 +1029,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
@@ -768,6 +1056,13 @@
@group(0) @binding(6) var<uniform> ext_tex_params_1 : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -775,6 +1070,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -826,9 +1124,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
@@ -844,6 +1156,13 @@
f(ext_tex, ext_tex_plane_1, ext_tex_params, smp, ext_tex2, ext_tex_plane_1_1, ext_tex_params_1);
}
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -851,6 +1170,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -897,15 +1219,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -913,6 +1256,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -965,15 +1311,36 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@group(0) @binding(3) var<uniform> ext_tex_params : ExternalTextureParams;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -981,6 +1348,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -1021,9 +1391,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
fn f(ext_tex : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams) -> vec2<i32> {
@@ -1057,9 +1441,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1068,6 +1466,13 @@
type ET = texture_external;
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -1075,6 +1480,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}
@@ -1119,9 +1527,23 @@
)";
auto* expect = R"(
+struct GammaTransferParams {
+ G : f32,
+ A : f32,
+ B : f32,
+ C : f32,
+ D : f32,
+ E : f32,
+ F : f32,
+ padding : u32,
+}
+
struct ExternalTextureParams {
numPlanes : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
+ gammaDecodeParams : GammaTransferParams,
+ gammaEncodeParams : GammaTransferParams,
+ gamutConversionMatrix : mat3x3<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1133,6 +1555,13 @@
f(ext_tex, ext_tex_plane_1, ext_tex_params, smp);
}
+fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
+ let cond = (abs(v) < vec3<f32>(params.D));
+ let t = (sign(v) * ((params.C * abs(v)) + params.F));
+ let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3<f32>(params.G)) + params.E));
+ return select(f, t, cond);
+}
+
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
var color : vec3<f32>;
if ((params.numPlanes == 1u)) {
@@ -1140,6 +1569,9 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix);
}
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
return vec4<f32>(color, 1.0);
}