diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp index 7b3ae850f1..f9e7044024 100644 --- a/src/dawn/native/ExternalTexture.cpp +++ b/src/dawn/native/ExternalTexture.cpp @@ -150,16 +150,38 @@ namespace dawn::native { ExternalTextureParams params; params.numPlanes = descriptor->plane1 == nullptr ? 1 : 2; + // TODO(dawn:1082): Make this field configurable from outside of Dawn. + // Conversion matrix for BT.709 limited range. Columns 1, 2 and 3 are copied + // directly from the corresponding matrix in SkYUVMath.cpp. Column 4 is the range + // bias (for RGB) found in column 5 of the same SkYUVMath.cpp matrix. + params.yuvToRgbConversionMatrix = {1.164384f, 0.0f, 1.792741f, -0.972945f, + 1.164384f, -0.213249f, -0.532909f, 0.301483f, + 1.164384f, 2.112402f, 0.0f, -1.133402f}; + + // TODO(dawn:1082): Make this field configurable from outside of Dawn. + // Use an identity matrix when converting BT.709 to sRGB because they shared the + // same primaries. + params.gamutConversionMatrix = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; + switch (descriptor->colorSpace) { - case wgpu::PredefinedColorSpace::Srgb: - // Conversion matrix for BT.709 limited range. Columns 1, 2 and 3 are copied - // directly from the corresponding matrix in SkYUVMath.cpp. Column 4 is the range - // bias (for RGB) found in column 5 of the same SkYUVMath.cpp matrix. - params.yuvToRgbConversion = {1.164384f, 0.0f, 1.792741f, -0.972945f, - 1.164384f, -0.213249f, -0.532909f, 0.301483f, - 1.164384f, 2.112402f, 0.0f, -1.133402f}; - break; case wgpu::PredefinedColorSpace::Undefined: + // Undefined color space should eventually produce an error. For now, these + // constants will effectively perform no gamma correction so tests can continue + // passing. + params.gammaDecodingParams = {1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0}; + params.gammaEncodingParams = {1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0}; + break; + case wgpu::PredefinedColorSpace::Srgb: + // TODO(dawn:1082): Make this field configurable from outside of Dawn. + // These are the inverted parameters as specified by Rec. ITU-R BT.1886 for BT.709 + params.gammaDecodingParams = {2.2, 1.0 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, + 0.0, 0.0}; + + // Constants for sRGB transfer function pulled from + // https://en.wikipedia.org/wiki/SRGB + params.gammaEncodingParams = { + 1 / 2.4, 1.137119 /*1.055^2.4*/, 0.0, 12.92, 0.0031308, -0.055, 0.0}; break; } diff --git a/src/dawn/native/ExternalTexture.h b/src/dawn/native/ExternalTexture.h index e752ca5234..86b688655a 100644 --- a/src/dawn/native/ExternalTexture.h +++ b/src/dawn/native/ExternalTexture.h @@ -26,10 +26,24 @@ namespace dawn::native { class TextureViewBase; + struct GammaTransferParams { + float G = 0.0; + float A = 0.0; + float B = 0.0; + float C = 0.0; + float D = 0.0; + float E = 0.0; + float F = 0.0; + uint32_t padding = 0; + }; + struct ExternalTextureParams { uint32_t numPlanes; std::array padding; - std::array yuvToRgbConversion; + std::array yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodingParams = {}; + GammaTransferParams gammaEncodingParams = {}; + std::array gamutConversionMatrix = {}; }; MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device, diff --git a/src/dawn/tests/end2end/ExternalTextureTests.cpp b/src/dawn/tests/end2end/ExternalTextureTests.cpp index 80cf6ce632..afe28f8afc 100644 --- a/src/dawn/tests/end2end/ExternalTextureTests.cpp +++ b/src/dawn/tests/end2end/ExternalTextureTests.cpp @@ -191,10 +191,15 @@ TEST_P(ExternalTextureTests, SampleMultiplanarExternalTexture) { RGBA8 rgba; }; - std::array expectations = {{{0.0, .5, .5, RGBA8::kBlack}, - {0.2126, 0.4172, 1.0, RGBA8::kRed}, - {0.7152, 0.1402, 0.0175, RGBA8::kGreen}, - {0.0722, 1.0, 0.4937, RGBA8::kBlue}}}; + // Conversion expectations for BT.709 YUV source and sRGB destination. + std::array expectations = { + {{0.0, .5, .5, RGBA8::kBlack}, + {0.2126, 0.4172, 1.0, RGBA8::kRed}, + {0.7152, 0.1402, 0.0175, RGBA8::kGreen}, + {0.0722, 1.0, 0.4937, RGBA8::kBlue}, + {0.6382, 0.3232, 0.6644, {246, 169, 90, 255}}, + {0.5423, 0.5323, 0.4222, {120, 162, 169, 255}}, + {0.2345, 0.4383, 0.6342, {126, 53, 33, 255}}}}; for (ConversionExpectation expectation : expectations) { // Initialize the texture planes with YUV data diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc index a5a2134bc3..34df0139ce 100644 --- a/src/tint/transform/multiplanar_external_texture.cc +++ b/src/tint/transform/multiplanar_external_texture.cc @@ -51,6 +51,9 @@ struct MultiplanarExternalTexture::State { /// 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 @@ struct MultiplanarExternalTexture::State { /// 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 @@ -96,7 +102,7 @@ struct MultiplanarExternalTexture::State { // 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 @@ struct MultiplanarExternalTexture::State { // 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 @@ struct MultiplanarExternalTexture::State { }); } - /// 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()), + 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(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(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(), statementList, {}); } /// Constructs a StatementList containing all the statements making up the @@ -297,6 +356,18 @@ struct MultiplanarExternalTexture::State { 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(color, 1.0f); b.Return(b.vec4("color", 1.0f))}; } @@ -318,6 +389,12 @@ struct MultiplanarExternalTexture::State { << 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 @@ struct MultiplanarExternalTexture::State { << 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 df3b837420..77448a7e5a 100644 --- a/src/tint/transform/multiplanar_external_texture_test.cc +++ b/src/tint/transform/multiplanar_external_texture_test.cc @@ -106,9 +106,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(1) var ext_tex_plane_1 : texture_2d; @@ -146,9 +160,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(1) var ext_tex_plane_1 : texture_2d; @@ -185,9 +213,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @@ -198,6 +240,13 @@ struct ExternalTextureParams { @group(0) @binding(1) var ext_tex : texture_2d; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -205,6 +254,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -234,15 +286,36 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -250,6 +323,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -282,9 +358,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(1) var ext_tex_plane_1 : texture_2d; @@ -293,6 +383,13 @@ struct ExternalTextureParams { @group(0) @binding(0) var ext_tex : texture_2d; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -300,6 +397,9 @@ fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord } else { color = (vec4(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(color, 1.0); } @@ -328,15 +428,36 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(1) var ext_tex_plane_1 : texture_2d; @group(0) @binding(2) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -344,6 +465,9 @@ fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord } else { color = (vec4(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(color, 1.0); } @@ -376,9 +500,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @@ -389,6 +527,13 @@ struct ExternalTextureParams { @group(0) @binding(1) var ext_tex : texture_2d; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -396,6 +541,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -406,6 +554,9 @@ fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord } else { color = (vec4(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(color, 1.0); } @@ -436,15 +587,36 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -452,6 +624,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -462,6 +637,9 @@ fn textureLoadExternal(plane0 : texture_2d, plane1 : texture_2d, coord } else { color = (vec4(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(color, 1.0); } @@ -498,9 +676,23 @@ fn main(@builtin(position) coord : vec4) -> @location(0) vec4 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(4) var ext_tex_plane_1 : texture_2d; @@ -529,6 +721,13 @@ struct ExternalTextureParams { @group(1) @binding(0) var ext_tex_3 : texture_2d; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -536,6 +735,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -575,15 +777,36 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -591,6 +814,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -635,9 +861,23 @@ fn f(t : texture_external, s : sampler) { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @@ -649,6 +889,13 @@ fn main() { f(ext_tex, ext_tex_plane_1, ext_tex_params, smp); } +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -656,6 +903,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -694,15 +944,36 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -710,6 +981,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -755,9 +1029,23 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(3) var ext_tex_plane_1 : texture_2d; @@ -768,6 +1056,13 @@ struct ExternalTextureParams { @group(0) @binding(6) var ext_tex_params_1 : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -775,6 +1070,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -826,9 +1124,23 @@ fn f(t : texture_external, s : sampler, t2 : texture_external) { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(3) var ext_tex_plane_1 : texture_2d; @@ -844,6 +1156,13 @@ fn main() { 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, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -851,6 +1170,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -897,15 +1219,36 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -913,6 +1256,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -965,15 +1311,36 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @group(0) @binding(3) var ext_tex_params : ExternalTextureParams; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -981,6 +1348,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -1021,9 +1391,23 @@ fn f(ext_tex : texture_external) -> vec2 { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } fn f(ext_tex : texture_2d, ext_tex_plane_1 : texture_2d, ext_tex_params : ExternalTextureParams) -> vec2 { @@ -1057,9 +1441,23 @@ fn main() { )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @@ -1068,6 +1466,13 @@ struct ExternalTextureParams { type ET = texture_external; +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -1075,6 +1480,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } @@ -1119,9 +1527,23 @@ type ET = texture_external; )"; 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, + gammaDecodeParams : GammaTransferParams, + gammaEncodeParams : GammaTransferParams, + gamutConversionMatrix : mat3x3, } @group(0) @binding(2) var ext_tex_plane_1 : texture_2d; @@ -1133,6 +1555,13 @@ fn main() { f(ext_tex, ext_tex_plane_1, ext_tex_params, smp); } +fn gammaCorrection(v : vec3, params : GammaTransferParams) -> vec3 { + let cond = (abs(v) < vec3(params.D)); + let t = (sign(v) * ((params.C * abs(v)) + params.F)); + let f = (sign(v) * (pow(((params.A * abs(v)) + params.B), vec3(params.G)) + params.E)); + return select(f, t, cond); +} + fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp : sampler, coord : vec2, params : ExternalTextureParams) -> vec4 { var color : vec3; if ((params.numPlanes == 1u)) { @@ -1140,6 +1569,9 @@ fn textureSampleExternal(plane0 : texture_2d, plane1 : texture_2d, smp } else { color = (vec4(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(color, 1.0); } diff --git a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.glsl b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.glsl index ee6f776719..a1cf7d7a3d 100644 --- a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.glsl +++ b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.glsl @@ -1,13 +1,30 @@ #version 310 es +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; + struct ExternalTextureParams { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; }; layout(binding = 2) uniform ExternalTextureParams_1 { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; } ext_tex_params; uniform highp sampler2D arg_0_1; @@ -31,14 +48,31 @@ void main() { #version 310 es precision mediump float; +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; + struct ExternalTextureParams { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; }; layout(binding = 2) uniform ExternalTextureParams_1 { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; } ext_tex_params; uniform highp sampler2D arg_0_1; @@ -56,14 +90,31 @@ void main() { } #version 310 es +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; + struct ExternalTextureParams { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; }; layout(binding = 2) uniform ExternalTextureParams_1 { uint numPlanes; mat3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + mat3 gamutConversionMatrix; } ext_tex_params; uniform highp sampler2D arg_0_1; diff --git a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.hlsl b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.hlsl index 78d6e702e3..108fe85c73 100644 --- a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.hlsl +++ b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.hlsl @@ -1,6 +1,6 @@ Texture2D ext_tex_plane_1 : register(t1, space1); cbuffer cbuffer_ext_tex_params : register(b2, space1) { - uint4 ext_tex_params[4]; + uint4 ext_tex_params[11]; }; Texture2D arg_0 : register(t0, space1); diff --git a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.msl b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.msl index 6a4127b55d..1d4eb711ca 100644 --- a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.msl +++ b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.msl @@ -1,9 +1,23 @@ #include using namespace metal; +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; + struct ExternalTextureParams { uint numPlanes; float3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + float3x3 gamutConversionMatrix; }; void textureDimensions_ba1481(texture2d tint_symbol_1) { diff --git a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.spvasm b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.spvasm index 9ff8d5a864..c0f550a47f 100644 --- a/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/textureDimensions/ba1481.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 44 +; Bound: 47 ; Schema: 0 OpCapability Shader OpCapability ImageQuery @@ -17,6 +17,18 @@ OpName %ExternalTextureParams "ExternalTextureParams" OpMemberName %ExternalTextureParams 0 "numPlanes" OpMemberName %ExternalTextureParams 1 "yuvToRgbConversionMatrix" + OpMemberName %ExternalTextureParams 2 "gammaDecodeParams" + OpName %GammaTransferParams "GammaTransferParams" + OpMemberName %GammaTransferParams 0 "G" + OpMemberName %GammaTransferParams 1 "A" + OpMemberName %GammaTransferParams 2 "B" + OpMemberName %GammaTransferParams 3 "C" + OpMemberName %GammaTransferParams 4 "D" + OpMemberName %GammaTransferParams 5 "E" + OpMemberName %GammaTransferParams 6 "F" + OpMemberName %GammaTransferParams 7 "padding" + OpMemberName %ExternalTextureParams 3 "gammaEncodeParams" + OpMemberName %ExternalTextureParams 4 "gamutConversionMatrix" OpName %ext_tex_params "ext_tex_params" OpName %arg_0 "arg_0" OpName %textureDimensions_ba1481 "textureDimensions_ba1481" @@ -34,6 +46,19 @@ OpMemberDecorate %ExternalTextureParams 1 Offset 16 OpMemberDecorate %ExternalTextureParams 1 ColMajor OpMemberDecorate %ExternalTextureParams 1 MatrixStride 16 + OpMemberDecorate %ExternalTextureParams 2 Offset 64 + OpMemberDecorate %GammaTransferParams 0 Offset 0 + OpMemberDecorate %GammaTransferParams 1 Offset 4 + OpMemberDecorate %GammaTransferParams 2 Offset 8 + OpMemberDecorate %GammaTransferParams 3 Offset 12 + OpMemberDecorate %GammaTransferParams 4 Offset 16 + OpMemberDecorate %GammaTransferParams 5 Offset 20 + OpMemberDecorate %GammaTransferParams 6 Offset 24 + OpMemberDecorate %GammaTransferParams 7 Offset 28 + OpMemberDecorate %ExternalTextureParams 3 Offset 96 + OpMemberDecorate %ExternalTextureParams 4 Offset 128 + OpMemberDecorate %ExternalTextureParams 4 ColMajor + OpMemberDecorate %ExternalTextureParams 4 MatrixStride 16 OpDecorate %ext_tex_params NonWritable OpDecorate %ext_tex_params DescriptorSet 1 OpDecorate %ext_tex_params Binding 2 @@ -52,46 +77,49 @@ %ext_tex_plane_1 = OpVariable %_ptr_UniformConstant_11 UniformConstant %uint = OpTypeInt 32 0 %mat3v4float = OpTypeMatrix %v4float 3 -%ExternalTextureParams = OpTypeStruct %uint %mat3v4float +%GammaTransferParams = OpTypeStruct %float %float %float %float %float %float %float %uint + %v3float = OpTypeVector %float 3 +%mat3v3float = OpTypeMatrix %v3float 3 +%ExternalTextureParams = OpTypeStruct %uint %mat3v4float %GammaTransferParams %GammaTransferParams %mat3v3float %_ptr_Uniform_ExternalTextureParams = OpTypePointer Uniform %ExternalTextureParams %ext_tex_params = OpVariable %_ptr_Uniform_ExternalTextureParams Uniform %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant %void = OpTypeVoid - %18 = OpTypeFunction %void + %21 = OpTypeFunction %void %int = OpTypeInt 32 1 %v2int = OpTypeVector %int 2 %int_0 = OpConstant %int 0 %_ptr_Function_v2int = OpTypePointer Function %v2int - %29 = OpConstantNull %v2int - %30 = OpTypeFunction %v4float + %32 = OpConstantNull %v2int + %33 = OpTypeFunction %v4float %float_1 = OpConstant %float 1 -%textureDimensions_ba1481 = OpFunction %void None %18 - %21 = OpLabel - %res = OpVariable %_ptr_Function_v2int Function %29 - %25 = OpLoad %11 %arg_0 - %22 = OpImageQuerySizeLod %v2int %25 %int_0 - OpStore %res %22 +%textureDimensions_ba1481 = OpFunction %void None %21 + %24 = OpLabel + %res = OpVariable %_ptr_Function_v2int Function %32 + %28 = OpLoad %11 %arg_0 + %25 = OpImageQuerySizeLod %v2int %28 %int_0 + OpStore %res %25 OpReturn OpFunctionEnd -%vertex_main_inner = OpFunction %v4float None %30 - %32 = OpLabel - %33 = OpFunctionCall %void %textureDimensions_ba1481 +%vertex_main_inner = OpFunction %v4float None %33 + %35 = OpLabel + %36 = OpFunctionCall %void %textureDimensions_ba1481 OpReturnValue %5 OpFunctionEnd -%vertex_main = OpFunction %void None %18 - %35 = OpLabel - %36 = OpFunctionCall %v4float %vertex_main_inner - OpStore %value %36 +%vertex_main = OpFunction %void None %21 + %38 = OpLabel + %39 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %39 OpStore %vertex_point_size %float_1 OpReturn OpFunctionEnd -%fragment_main = OpFunction %void None %18 - %39 = OpLabel - %40 = OpFunctionCall %void %textureDimensions_ba1481 - OpReturn - OpFunctionEnd -%compute_main = OpFunction %void None %18 +%fragment_main = OpFunction %void None %21 %42 = OpLabel %43 = OpFunctionCall %void %textureDimensions_ba1481 OpReturn OpFunctionEnd +%compute_main = OpFunction %void None %21 + %45 = OpLabel + %46 = OpFunctionCall %void %textureDimensions_ba1481 + OpReturn + OpFunctionEnd diff --git a/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.hlsl b/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.hlsl index f1d67e8536..d48102670c 100644 --- a/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.hlsl +++ b/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.hlsl @@ -1,14 +1,34 @@ +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; struct ExternalTextureParams { uint numPlanes; float3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + float3x3 gamutConversionMatrix; }; Texture2D ext_tex_plane_1 : register(t1, space1); cbuffer cbuffer_ext_tex_params : register(b2, space1) { - uint4 ext_tex_params[4]; + uint4 ext_tex_params[11]; }; Texture2D arg_0 : register(t0, space1); +float3 gammaCorrection(float3 v, GammaTransferParams params) { + const bool3 cond = (abs(v) < float3((params.D).xxx)); + const float3 t = (sign(v) * ((params.C * abs(v)) + params.F)); + const float3 f = (sign(v) * (pow(((params.A * abs(v)) + params.B), float3((params.G).xxx)) + params.E)); + return (cond ? t : f); +} + float4 textureLoadExternal(Texture2D plane0, Texture2D plane1, int2 coord, ExternalTextureParams params) { float3 color = float3(0.0f, 0.0f, 0.0f); if ((params.numPlanes == 1u)) { @@ -16,20 +36,43 @@ float4 textureLoadExternal(Texture2D plane0, Texture2D plane1, i } else { color = mul(params.yuvToRgbConversionMatrix, float4(plane0.Load(int3(coord, 0)).r, plane1.Load(int3(coord, 0)).rg, 1.0f)); } + color = gammaCorrection(color, params.gammaDecodeParams); + color = mul(color, params.gamutConversionMatrix); + color = gammaCorrection(color, params.gammaEncodeParams); return float4(color, 1.0f); } -float3x4 tint_symbol_3(uint4 buffer[4], uint offset) { +float3x4 tint_symbol_3(uint4 buffer[11], uint offset) { const uint scalar_offset = ((offset + 0u)) / 4; const uint scalar_offset_1 = ((offset + 16u)) / 4; const uint scalar_offset_2 = ((offset + 32u)) / 4; return float3x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4])); } -ExternalTextureParams tint_symbol_1(uint4 buffer[4], uint offset) { +GammaTransferParams tint_symbol_5(uint4 buffer[11], uint offset) { const uint scalar_offset_3 = ((offset + 0u)) / 4; - const ExternalTextureParams tint_symbol_5 = {buffer[scalar_offset_3 / 4][scalar_offset_3 % 4], tint_symbol_3(buffer, (offset + 16u))}; - return tint_symbol_5; + const uint scalar_offset_4 = ((offset + 4u)) / 4; + const uint scalar_offset_5 = ((offset + 8u)) / 4; + const uint scalar_offset_6 = ((offset + 12u)) / 4; + const uint scalar_offset_7 = ((offset + 16u)) / 4; + const uint scalar_offset_8 = ((offset + 20u)) / 4; + const uint scalar_offset_9 = ((offset + 24u)) / 4; + const uint scalar_offset_10 = ((offset + 28u)) / 4; + const GammaTransferParams tint_symbol_9 = {asfloat(buffer[scalar_offset_3 / 4][scalar_offset_3 % 4]), asfloat(buffer[scalar_offset_4 / 4][scalar_offset_4 % 4]), asfloat(buffer[scalar_offset_5 / 4][scalar_offset_5 % 4]), asfloat(buffer[scalar_offset_6 / 4][scalar_offset_6 % 4]), asfloat(buffer[scalar_offset_7 / 4][scalar_offset_7 % 4]), asfloat(buffer[scalar_offset_8 / 4][scalar_offset_8 % 4]), asfloat(buffer[scalar_offset_9 / 4][scalar_offset_9 % 4]), buffer[scalar_offset_10 / 4][scalar_offset_10 % 4]}; + return tint_symbol_9; +} + +float3x3 tint_symbol_7(uint4 buffer[11], uint offset) { + const uint scalar_offset_11 = ((offset + 0u)) / 4; + const uint scalar_offset_12 = ((offset + 16u)) / 4; + const uint scalar_offset_13 = ((offset + 32u)) / 4; + return float3x3(asfloat(buffer[scalar_offset_11 / 4].xyz), asfloat(buffer[scalar_offset_12 / 4].xyz), asfloat(buffer[scalar_offset_13 / 4].xyz)); +} + +ExternalTextureParams tint_symbol_1(uint4 buffer[11], uint offset) { + const uint scalar_offset_14 = ((offset + 0u)) / 4; + const ExternalTextureParams tint_symbol_10 = {buffer[scalar_offset_14 / 4][scalar_offset_14 % 4], tint_symbol_3(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 64u)), tint_symbol_5(buffer, (offset + 96u)), tint_symbol_7(buffer, (offset + 128u))}; + return tint_symbol_10; } void textureLoad_8acf41() { diff --git a/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.msl b/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.msl index 2cf34bc854..d7ae7960ef 100644 --- a/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.msl +++ b/test/tint/builtins/gen/textureLoad/8acf41.wgsl.expected.msl @@ -1,12 +1,33 @@ #include using namespace metal; +struct GammaTransferParams { + /* 0x0000 */ float G; + /* 0x0004 */ float A; + /* 0x0008 */ float B; + /* 0x000c */ float C; + /* 0x0010 */ float D; + /* 0x0014 */ float E; + /* 0x0018 */ float F; + /* 0x001c */ uint padding; +}; + struct ExternalTextureParams { /* 0x0000 */ uint numPlanes; /* 0x0004 */ int8_t tint_pad[12]; /* 0x0010 */ float3x4 yuvToRgbConversionMatrix; + /* 0x0040 */ GammaTransferParams gammaDecodeParams; + /* 0x0060 */ GammaTransferParams gammaEncodeParams; + /* 0x0080 */ float3x3 gamutConversionMatrix; }; +float3 gammaCorrection(float3 v, GammaTransferParams params) { + bool3 const cond = (fabs(v) < float3(params.D)); + float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F)); + float3 const f = (sign(v) * (pow(((params.A * fabs(v)) + params.B), float3(params.G)) + params.E)); + return select(f, t, cond); +} + float4 textureLoadExternal(texture2d plane0, texture2d plane1, int2 coord, ExternalTextureParams params) { float3 color = 0.0f; if ((params.numPlanes == 1u)) { @@ -14,6 +35,9 @@ float4 textureLoadExternal(texture2d plane0, texture2d ext_tex_plane_1 : register(t2, space1); cbuffer cbuffer_ext_tex_params : register(b3, space1) { - uint4 ext_tex_params[4]; + uint4 ext_tex_params[11]; }; Texture2D arg_0 : register(t0, space1); SamplerState arg_1 : register(s1, space1); +float3 gammaCorrection(float3 v, GammaTransferParams params) { + const bool3 cond = (abs(v) < float3((params.D).xxx)); + const float3 t = (sign(v) * ((params.C * abs(v)) + params.F)); + const float3 f = (sign(v) * (pow(((params.A * abs(v)) + params.B), float3((params.G).xxx)) + params.E)); + return (cond ? t : f); +} + float4 textureSampleExternal(Texture2D plane0, Texture2D plane1, SamplerState smp, float2 coord, ExternalTextureParams params) { float3 color = float3(0.0f, 0.0f, 0.0f); if ((params.numPlanes == 1u)) { @@ -17,20 +37,43 @@ float4 textureSampleExternal(Texture2D plane0, Texture2D plane1, } else { color = mul(params.yuvToRgbConversionMatrix, float4(plane0.SampleLevel(smp, coord, 0.0f).r, plane1.SampleLevel(smp, coord, 0.0f).rg, 1.0f)); } + color = gammaCorrection(color, params.gammaDecodeParams); + color = mul(color, params.gamutConversionMatrix); + color = gammaCorrection(color, params.gammaEncodeParams); return float4(color, 1.0f); } -float3x4 tint_symbol_3(uint4 buffer[4], uint offset) { +float3x4 tint_symbol_3(uint4 buffer[11], uint offset) { const uint scalar_offset = ((offset + 0u)) / 4; const uint scalar_offset_1 = ((offset + 16u)) / 4; const uint scalar_offset_2 = ((offset + 32u)) / 4; return float3x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4])); } -ExternalTextureParams tint_symbol_1(uint4 buffer[4], uint offset) { +GammaTransferParams tint_symbol_5(uint4 buffer[11], uint offset) { const uint scalar_offset_3 = ((offset + 0u)) / 4; - const ExternalTextureParams tint_symbol_5 = {buffer[scalar_offset_3 / 4][scalar_offset_3 % 4], tint_symbol_3(buffer, (offset + 16u))}; - return tint_symbol_5; + const uint scalar_offset_4 = ((offset + 4u)) / 4; + const uint scalar_offset_5 = ((offset + 8u)) / 4; + const uint scalar_offset_6 = ((offset + 12u)) / 4; + const uint scalar_offset_7 = ((offset + 16u)) / 4; + const uint scalar_offset_8 = ((offset + 20u)) / 4; + const uint scalar_offset_9 = ((offset + 24u)) / 4; + const uint scalar_offset_10 = ((offset + 28u)) / 4; + const GammaTransferParams tint_symbol_9 = {asfloat(buffer[scalar_offset_3 / 4][scalar_offset_3 % 4]), asfloat(buffer[scalar_offset_4 / 4][scalar_offset_4 % 4]), asfloat(buffer[scalar_offset_5 / 4][scalar_offset_5 % 4]), asfloat(buffer[scalar_offset_6 / 4][scalar_offset_6 % 4]), asfloat(buffer[scalar_offset_7 / 4][scalar_offset_7 % 4]), asfloat(buffer[scalar_offset_8 / 4][scalar_offset_8 % 4]), asfloat(buffer[scalar_offset_9 / 4][scalar_offset_9 % 4]), buffer[scalar_offset_10 / 4][scalar_offset_10 % 4]}; + return tint_symbol_9; +} + +float3x3 tint_symbol_7(uint4 buffer[11], uint offset) { + const uint scalar_offset_11 = ((offset + 0u)) / 4; + const uint scalar_offset_12 = ((offset + 16u)) / 4; + const uint scalar_offset_13 = ((offset + 32u)) / 4; + return float3x3(asfloat(buffer[scalar_offset_11 / 4].xyz), asfloat(buffer[scalar_offset_12 / 4].xyz), asfloat(buffer[scalar_offset_13 / 4].xyz)); +} + +ExternalTextureParams tint_symbol_1(uint4 buffer[11], uint offset) { + const uint scalar_offset_14 = ((offset + 0u)) / 4; + const ExternalTextureParams tint_symbol_10 = {buffer[scalar_offset_14 / 4][scalar_offset_14 % 4], tint_symbol_3(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 64u)), tint_symbol_5(buffer, (offset + 96u)), tint_symbol_7(buffer, (offset + 128u))}; + return tint_symbol_10; } void textureSampleLevel_979816() { diff --git a/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.msl b/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.msl index 2a297dff0d..abe1cccfd6 100644 --- a/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.msl +++ b/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.msl @@ -1,12 +1,33 @@ #include using namespace metal; +struct GammaTransferParams { + /* 0x0000 */ float G; + /* 0x0004 */ float A; + /* 0x0008 */ float B; + /* 0x000c */ float C; + /* 0x0010 */ float D; + /* 0x0014 */ float E; + /* 0x0018 */ float F; + /* 0x001c */ uint padding; +}; + struct ExternalTextureParams { /* 0x0000 */ uint numPlanes; /* 0x0004 */ int8_t tint_pad[12]; /* 0x0010 */ float3x4 yuvToRgbConversionMatrix; + /* 0x0040 */ GammaTransferParams gammaDecodeParams; + /* 0x0060 */ GammaTransferParams gammaEncodeParams; + /* 0x0080 */ float3x3 gamutConversionMatrix; }; +float3 gammaCorrection(float3 v, GammaTransferParams params) { + bool3 const cond = (fabs(v) < float3(params.D)); + float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F)); + float3 const f = (sign(v) * (pow(((params.A * fabs(v)) + params.B), float3(params.G)) + params.E)); + return select(f, t, cond); +} + float4 textureSampleExternal(texture2d plane0, texture2d plane1, sampler smp, float2 coord, ExternalTextureParams params) { float3 color = 0.0f; if ((params.numPlanes == 1u)) { @@ -14,6 +35,9 @@ float4 textureSampleExternal(texture2d plane0, texture2d< } else { color = (float4(plane0.sample(smp, coord, level(0.0f))[0], float4(plane1.sample(smp, coord, level(0.0f))).rg, 1.0f) * params.yuvToRgbConversionMatrix); } + color = gammaCorrection(color, params.gammaDecodeParams); + color = (params.gamutConversionMatrix * color); + color = gammaCorrection(color, params.gammaEncodeParams); return float4(color, 1.0f); } diff --git a/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.spvasm b/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.spvasm index ae6490cca0..ebf64411fe 100644 --- a/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/textureSampleLevel/979816.wgsl.expected.spvasm @@ -1,9 +1,10 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 88 +; Bound: 136 ; Schema: 0 OpCapability Shader + %30 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size OpEntryPoint Fragment %fragment_main "fragment_main" @@ -16,15 +17,30 @@ OpName %ExternalTextureParams "ExternalTextureParams" OpMemberName %ExternalTextureParams 0 "numPlanes" OpMemberName %ExternalTextureParams 1 "yuvToRgbConversionMatrix" + OpMemberName %ExternalTextureParams 2 "gammaDecodeParams" + OpName %GammaTransferParams "GammaTransferParams" + OpMemberName %GammaTransferParams 0 "G" + OpMemberName %GammaTransferParams 1 "A" + OpMemberName %GammaTransferParams 2 "B" + OpMemberName %GammaTransferParams 3 "C" + OpMemberName %GammaTransferParams 4 "D" + OpMemberName %GammaTransferParams 5 "E" + OpMemberName %GammaTransferParams 6 "F" + OpMemberName %GammaTransferParams 7 "padding" + OpMemberName %ExternalTextureParams 3 "gammaEncodeParams" + OpMemberName %ExternalTextureParams 4 "gamutConversionMatrix" OpName %ext_tex_params "ext_tex_params" OpName %arg_0 "arg_0" OpName %arg_1 "arg_1" + OpName %gammaCorrection "gammaCorrection" + OpName %v "v" + OpName %params "params" OpName %textureSampleExternal "textureSampleExternal" OpName %plane0 "plane0" OpName %plane1 "plane1" OpName %smp "smp" OpName %coord "coord" - OpName %params "params" + OpName %params_0 "params" OpName %color "color" OpName %textureSampleLevel_979816 "textureSampleLevel_979816" OpName %res "res" @@ -41,6 +57,19 @@ OpMemberDecorate %ExternalTextureParams 1 Offset 16 OpMemberDecorate %ExternalTextureParams 1 ColMajor OpMemberDecorate %ExternalTextureParams 1 MatrixStride 16 + OpMemberDecorate %ExternalTextureParams 2 Offset 64 + OpMemberDecorate %GammaTransferParams 0 Offset 0 + OpMemberDecorate %GammaTransferParams 1 Offset 4 + OpMemberDecorate %GammaTransferParams 2 Offset 8 + OpMemberDecorate %GammaTransferParams 3 Offset 12 + OpMemberDecorate %GammaTransferParams 4 Offset 16 + OpMemberDecorate %GammaTransferParams 5 Offset 20 + OpMemberDecorate %GammaTransferParams 6 Offset 24 + OpMemberDecorate %GammaTransferParams 7 Offset 28 + OpMemberDecorate %ExternalTextureParams 3 Offset 96 + OpMemberDecorate %ExternalTextureParams 4 Offset 128 + OpMemberDecorate %ExternalTextureParams 4 ColMajor + OpMemberDecorate %ExternalTextureParams 4 MatrixStride 16 OpDecorate %ext_tex_params NonWritable OpDecorate %ext_tex_params DescriptorSet 1 OpDecorate %ext_tex_params Binding 3 @@ -61,98 +90,150 @@ %ext_tex_plane_1 = OpVariable %_ptr_UniformConstant_11 UniformConstant %uint = OpTypeInt 32 0 %mat3v4float = OpTypeMatrix %v4float 3 -%ExternalTextureParams = OpTypeStruct %uint %mat3v4float +%GammaTransferParams = OpTypeStruct %float %float %float %float %float %float %float %uint + %v3float = OpTypeVector %float 3 +%mat3v3float = OpTypeMatrix %v3float 3 +%ExternalTextureParams = OpTypeStruct %uint %mat3v4float %GammaTransferParams %GammaTransferParams %mat3v3float %_ptr_Uniform_ExternalTextureParams = OpTypePointer Uniform %ExternalTextureParams %ext_tex_params = OpVariable %_ptr_Uniform_ExternalTextureParams Uniform %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant - %20 = OpTypeSampler -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %arg_1 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %v2float = OpTypeVector %float 2 - %21 = OpTypeFunction %v4float %11 %11 %20 %v2float %ExternalTextureParams - %v3float = OpTypeVector %float 3 -%_ptr_Function_v3float = OpTypePointer Function %v3float - %33 = OpConstantNull %v3float - %uint_1 = OpConstant %uint 1 + %23 = OpTypeSampler +%_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23 + %arg_1 = OpVariable %_ptr_UniformConstant_23 UniformConstant + %24 = OpTypeFunction %v3float %v3float %GammaTransferParams %bool = OpTypeBool - %42 = OpTypeSampledImage %11 + %v3bool = OpTypeVector %bool 3 +%_ptr_Function_v3float = OpTypePointer Function %v3float + %44 = OpConstantNull %v3float + %v2float = OpTypeVector %float 2 + %64 = OpTypeFunction %v4float %11 %11 %23 %v2float %ExternalTextureParams + %uint_1 = OpConstant %uint 1 + %81 = OpTypeSampledImage %11 %float_0 = OpConstant %float 0 %float_1 = OpConstant %float 1 %void = OpTypeVoid - %63 = OpTypeFunction %void - %71 = OpConstantNull %v2float + %111 = OpTypeFunction %void + %119 = OpConstantNull %v2float %_ptr_Function_v4float = OpTypePointer Function %v4float - %75 = OpTypeFunction %v4float -%textureSampleExternal = OpFunction %v4float None %21 + %123 = OpTypeFunction %v4float +%gammaCorrection = OpFunction %v3float None %24 + %v = OpFunctionParameter %v3float + %params = OpFunctionParameter %GammaTransferParams + %28 = OpLabel + %42 = OpVariable %_ptr_Function_v3float Function %44 + %54 = OpVariable %_ptr_Function_v3float Function %44 + %60 = OpVariable %_ptr_Function_v3float Function %44 + %29 = OpExtInst %v3float %30 FAbs %v + %31 = OpCompositeExtract %float %params 4 + %32 = OpCompositeConstruct %v3float %31 %31 %31 + %33 = OpFOrdLessThan %v3bool %29 %32 + %36 = OpExtInst %v3float %30 FSign %v + %37 = OpCompositeExtract %float %params 3 + %38 = OpExtInst %v3float %30 FAbs %v + %39 = OpVectorTimesScalar %v3float %38 %37 + %40 = OpCompositeExtract %float %params 6 + %45 = OpCompositeConstruct %v3float %40 %40 %40 + %41 = OpFAdd %v3float %39 %45 + %46 = OpFMul %v3float %36 %41 + %47 = OpExtInst %v3float %30 FSign %v + %49 = OpCompositeExtract %float %params 1 + %50 = OpExtInst %v3float %30 FAbs %v + %51 = OpVectorTimesScalar %v3float %50 %49 + %52 = OpCompositeExtract %float %params 2 + %55 = OpCompositeConstruct %v3float %52 %52 %52 + %53 = OpFAdd %v3float %51 %55 + %56 = OpCompositeExtract %float %params 0 + %57 = OpCompositeConstruct %v3float %56 %56 %56 + %48 = OpExtInst %v3float %30 Pow %53 %57 + %58 = OpCompositeExtract %float %params 5 + %61 = OpCompositeConstruct %v3float %58 %58 %58 + %59 = OpFAdd %v3float %48 %61 + %62 = OpFMul %v3float %47 %59 + %63 = OpSelect %v3float %33 %46 %62 + OpReturnValue %63 + OpFunctionEnd +%textureSampleExternal = OpFunction %v4float None %64 %plane0 = OpFunctionParameter %11 %plane1 = OpFunctionParameter %11 - %smp = OpFunctionParameter %20 + %smp = OpFunctionParameter %23 %coord = OpFunctionParameter %v2float - %params = OpFunctionParameter %ExternalTextureParams - %29 = OpLabel - %color = OpVariable %_ptr_Function_v3float Function %33 - %34 = OpCompositeExtract %uint %params 0 - %36 = OpIEqual %bool %34 %uint_1 - OpSelectionMerge %38 None - OpBranchConditional %36 %39 %40 - %39 = OpLabel - %43 = OpSampledImage %42 %plane0 %smp - %41 = OpImageSampleExplicitLod %v4float %43 %coord Lod %float_0 - %45 = OpVectorShuffle %v3float %41 %41 0 1 2 - OpStore %color %45 - OpBranch %38 - %40 = OpLabel - %47 = OpSampledImage %42 %plane0 %smp - %46 = OpImageSampleExplicitLod %v4float %47 %coord Lod %float_0 - %48 = OpCompositeExtract %float %46 0 - %50 = OpSampledImage %42 %plane1 %smp - %49 = OpImageSampleExplicitLod %v4float %50 %coord Lod %float_0 - %51 = OpVectorShuffle %v2float %49 %49 0 1 - %52 = OpCompositeExtract %float %51 0 - %53 = OpCompositeExtract %float %51 1 - %55 = OpCompositeConstruct %v4float %48 %52 %53 %float_1 - %56 = OpCompositeExtract %mat3v4float %params 1 - %57 = OpVectorTimesMatrix %v3float %55 %56 - OpStore %color %57 - OpBranch %38 - %38 = OpLabel - %58 = OpLoad %v3float %color - %59 = OpCompositeExtract %float %58 0 - %60 = OpCompositeExtract %float %58 1 - %61 = OpCompositeExtract %float %58 2 - %62 = OpCompositeConstruct %v4float %59 %60 %61 %float_1 - OpReturnValue %62 + %params_0 = OpFunctionParameter %ExternalTextureParams + %72 = OpLabel + %color = OpVariable %_ptr_Function_v3float Function %44 + %74 = OpCompositeExtract %uint %params_0 0 + %76 = OpIEqual %bool %74 %uint_1 + OpSelectionMerge %77 None + OpBranchConditional %76 %78 %79 + %78 = OpLabel + %82 = OpSampledImage %81 %plane0 %smp + %80 = OpImageSampleExplicitLod %v4float %82 %coord Lod %float_0 + %84 = OpVectorShuffle %v3float %80 %80 0 1 2 + OpStore %color %84 + OpBranch %77 + %79 = OpLabel + %86 = OpSampledImage %81 %plane0 %smp + %85 = OpImageSampleExplicitLod %v4float %86 %coord Lod %float_0 + %87 = OpCompositeExtract %float %85 0 + %89 = OpSampledImage %81 %plane1 %smp + %88 = OpImageSampleExplicitLod %v4float %89 %coord Lod %float_0 + %90 = OpVectorShuffle %v2float %88 %88 0 1 + %91 = OpCompositeExtract %float %90 0 + %92 = OpCompositeExtract %float %90 1 + %94 = OpCompositeConstruct %v4float %87 %91 %92 %float_1 + %95 = OpCompositeExtract %mat3v4float %params_0 1 + %96 = OpVectorTimesMatrix %v3float %94 %95 + OpStore %color %96 + OpBranch %77 + %77 = OpLabel + %98 = OpLoad %v3float %color + %99 = OpCompositeExtract %GammaTransferParams %params_0 2 + %97 = OpFunctionCall %v3float %gammaCorrection %98 %99 + OpStore %color %97 + %100 = OpCompositeExtract %mat3v3float %params_0 4 + %101 = OpLoad %v3float %color + %102 = OpMatrixTimesVector %v3float %100 %101 + OpStore %color %102 + %104 = OpLoad %v3float %color + %105 = OpCompositeExtract %GammaTransferParams %params_0 3 + %103 = OpFunctionCall %v3float %gammaCorrection %104 %105 + OpStore %color %103 + %106 = OpLoad %v3float %color + %107 = OpCompositeExtract %float %106 0 + %108 = OpCompositeExtract %float %106 1 + %109 = OpCompositeExtract %float %106 2 + %110 = OpCompositeConstruct %v4float %107 %108 %109 %float_1 + OpReturnValue %110 OpFunctionEnd -%textureSampleLevel_979816 = OpFunction %void None %63 - %66 = OpLabel +%textureSampleLevel_979816 = OpFunction %void None %111 + %114 = OpLabel %res = OpVariable %_ptr_Function_v4float Function %5 - %68 = OpLoad %11 %arg_0 - %69 = OpLoad %11 %ext_tex_plane_1 - %70 = OpLoad %20 %arg_1 - %72 = OpLoad %ExternalTextureParams %ext_tex_params - %67 = OpFunctionCall %v4float %textureSampleExternal %68 %69 %70 %71 %72 - OpStore %res %67 + %116 = OpLoad %11 %arg_0 + %117 = OpLoad %11 %ext_tex_plane_1 + %118 = OpLoad %23 %arg_1 + %120 = OpLoad %ExternalTextureParams %ext_tex_params + %115 = OpFunctionCall %v4float %textureSampleExternal %116 %117 %118 %119 %120 + OpStore %res %115 OpReturn OpFunctionEnd -%vertex_main_inner = OpFunction %v4float None %75 - %77 = OpLabel - %78 = OpFunctionCall %void %textureSampleLevel_979816 +%vertex_main_inner = OpFunction %v4float None %123 + %125 = OpLabel + %126 = OpFunctionCall %void %textureSampleLevel_979816 OpReturnValue %5 OpFunctionEnd -%vertex_main = OpFunction %void None %63 - %80 = OpLabel - %81 = OpFunctionCall %v4float %vertex_main_inner - OpStore %value %81 +%vertex_main = OpFunction %void None %111 + %128 = OpLabel + %129 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %129 OpStore %vertex_point_size %float_1 OpReturn OpFunctionEnd -%fragment_main = OpFunction %void None %63 - %83 = OpLabel - %84 = OpFunctionCall %void %textureSampleLevel_979816 +%fragment_main = OpFunction %void None %111 + %131 = OpLabel + %132 = OpFunctionCall %void %textureSampleLevel_979816 OpReturn OpFunctionEnd -%compute_main = OpFunction %void None %63 - %86 = OpLabel - %87 = OpFunctionCall %void %textureSampleLevel_979816 +%compute_main = OpFunction %void None %111 + %134 = OpLabel + %135 = OpFunctionCall %void %textureSampleLevel_979816 OpReturn OpFunctionEnd diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.hlsl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.hlsl index e82139276d..2fb9dfebde 100644 --- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.hlsl +++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.hlsl @@ -1,14 +1,34 @@ +struct GammaTransferParams { + float G; + float A; + float B; + float C; + float D; + float E; + float F; + uint padding; +}; struct ExternalTextureParams { uint numPlanes; float3x4 yuvToRgbConversionMatrix; + GammaTransferParams gammaDecodeParams; + GammaTransferParams gammaEncodeParams; + float3x3 gamutConversionMatrix; }; Texture2D ext_tex_plane_1 : register(t1, space1); cbuffer cbuffer_ext_tex_params : register(b2, space1) { - uint4 ext_tex_params[4]; + uint4 ext_tex_params[11]; }; Texture2D arg_0 : register(t0, space1); +float3 gammaCorrection(float3 v, GammaTransferParams params) { + const bool3 cond = (abs(v) < float3((params.D).xxx)); + const float3 t = (sign(v) * ((params.C * abs(v)) + params.F)); + const float3 f = (sign(v) * (pow(((params.A * abs(v)) + params.B), float3((params.G).xxx)) + params.E)); + return (cond ? t : f); +} + float4 textureLoadExternal(Texture2D plane0, Texture2D plane1, int2 coord, ExternalTextureParams params) { float3 color = float3(0.0f, 0.0f, 0.0f); if ((params.numPlanes == 1u)) { @@ -16,6 +36,9 @@ float4 textureLoadExternal(Texture2D plane0, Texture2D plane1, i } else { color = mul(params.yuvToRgbConversionMatrix, float4(plane0.Load(int3(coord, 0)).r, plane1.Load(int3(coord, 0)).rg, 1.0f)); } + color = gammaCorrection(color, params.gammaDecodeParams); + color = mul(color, params.gamutConversionMatrix); + color = gammaCorrection(color, params.gammaEncodeParams); return float4(color, 1.0f); } @@ -23,17 +46,37 @@ float4 textureLoad2d(Texture2D tint_symbol, Texture2D ext_tex_pl return textureLoadExternal(tint_symbol, ext_tex_plane_1_1, coords, ext_tex_params_1); } -float3x4 tint_symbol_4(uint4 buffer[4], uint offset) { +float3x4 tint_symbol_4(uint4 buffer[11], uint offset) { const uint scalar_offset = ((offset + 0u)) / 4; const uint scalar_offset_1 = ((offset + 16u)) / 4; const uint scalar_offset_2 = ((offset + 32u)) / 4; return float3x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4])); } -ExternalTextureParams tint_symbol_2(uint4 buffer[4], uint offset) { +GammaTransferParams tint_symbol_6(uint4 buffer[11], uint offset) { const uint scalar_offset_3 = ((offset + 0u)) / 4; - const ExternalTextureParams tint_symbol_6 = {buffer[scalar_offset_3 / 4][scalar_offset_3 % 4], tint_symbol_4(buffer, (offset + 16u))}; - return tint_symbol_6; + const uint scalar_offset_4 = ((offset + 4u)) / 4; + const uint scalar_offset_5 = ((offset + 8u)) / 4; + const uint scalar_offset_6 = ((offset + 12u)) / 4; + const uint scalar_offset_7 = ((offset + 16u)) / 4; + const uint scalar_offset_8 = ((offset + 20u)) / 4; + const uint scalar_offset_9 = ((offset + 24u)) / 4; + const uint scalar_offset_10 = ((offset + 28u)) / 4; + const GammaTransferParams tint_symbol_10 = {asfloat(buffer[scalar_offset_3 / 4][scalar_offset_3 % 4]), asfloat(buffer[scalar_offset_4 / 4][scalar_offset_4 % 4]), asfloat(buffer[scalar_offset_5 / 4][scalar_offset_5 % 4]), asfloat(buffer[scalar_offset_6 / 4][scalar_offset_6 % 4]), asfloat(buffer[scalar_offset_7 / 4][scalar_offset_7 % 4]), asfloat(buffer[scalar_offset_8 / 4][scalar_offset_8 % 4]), asfloat(buffer[scalar_offset_9 / 4][scalar_offset_9 % 4]), buffer[scalar_offset_10 / 4][scalar_offset_10 % 4]}; + return tint_symbol_10; +} + +float3x3 tint_symbol_8(uint4 buffer[11], uint offset) { + const uint scalar_offset_11 = ((offset + 0u)) / 4; + const uint scalar_offset_12 = ((offset + 16u)) / 4; + const uint scalar_offset_13 = ((offset + 32u)) / 4; + return float3x3(asfloat(buffer[scalar_offset_11 / 4].xyz), asfloat(buffer[scalar_offset_12 / 4].xyz), asfloat(buffer[scalar_offset_13 / 4].xyz)); +} + +ExternalTextureParams tint_symbol_2(uint4 buffer[11], uint offset) { + const uint scalar_offset_14 = ((offset + 0u)) / 4; + const ExternalTextureParams tint_symbol_11 = {buffer[scalar_offset_14 / 4][scalar_offset_14 % 4], tint_symbol_4(buffer, (offset + 16u)), tint_symbol_6(buffer, (offset + 64u)), tint_symbol_6(buffer, (offset + 96u)), tint_symbol_8(buffer, (offset + 128u))}; + return tint_symbol_11; } void doTextureLoad() { diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl index bc167c9abd..c1e9dd6cc1 100644 --- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl +++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl @@ -1,12 +1,33 @@ #include using namespace metal; +struct GammaTransferParams { + /* 0x0000 */ float G; + /* 0x0004 */ float A; + /* 0x0008 */ float B; + /* 0x000c */ float C; + /* 0x0010 */ float D; + /* 0x0014 */ float E; + /* 0x0018 */ float F; + /* 0x001c */ uint padding; +}; + struct ExternalTextureParams { /* 0x0000 */ uint numPlanes; /* 0x0004 */ int8_t tint_pad[12]; /* 0x0010 */ float3x4 yuvToRgbConversionMatrix; + /* 0x0040 */ GammaTransferParams gammaDecodeParams; + /* 0x0060 */ GammaTransferParams gammaEncodeParams; + /* 0x0080 */ float3x3 gamutConversionMatrix; }; +float3 gammaCorrection(float3 v, GammaTransferParams params) { + bool3 const cond = (fabs(v) < float3(params.D)); + float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F)); + float3 const f = (sign(v) * (pow(((params.A * fabs(v)) + params.B), float3(params.G)) + params.E)); + return select(f, t, cond); +} + float4 textureLoadExternal(texture2d plane0, texture2d plane1, int2 coord, ExternalTextureParams params) { float3 color = 0.0f; if ((params.numPlanes == 1u)) { @@ -14,6 +35,9 @@ float4 textureLoadExternal(texture2d plane0, texture2d