Skip Gamma and Gamut conversions for BT.709->SRGB

This introduces a new field 'doYuvToRgbConversionOnly' in
ExternalTextureParams to have the WGSL only do yuv->rgb conversion for
better performance. User studies shows that users don't really care
about the Gamma difference between 2.4 and 2.2.
https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/color_space.cc;l=1022;drc=a1dbb594a6741a400db35fe3678e77bad2504ea4

Bug: dawn:1082
Bug: dawn:1466
Change-Id: I61c0fe65c5969d8a61c267c202c8dd64c259ed8a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92901
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp
index 0dfa963..978fb9e 100644
--- a/src/dawn/native/ExternalTexture.cpp
+++ b/src/dawn/native/ExternalTexture.cpp
@@ -152,6 +152,8 @@
     ExternalTextureParams params;
     params.numPlanes = descriptor->plane1 == nullptr ? 1 : 2;
 
+    params.doYuvToRgbConversionOnly = descriptor->doYuvToRgbConversionOnly ? 1 : 0;
+
     // YUV-to-RGB conversion is performed by multiplying the source YUV values with a 4x3 matrix
     // passed from Chromium. The matrix was originally sourced from /skia/src/core/SkYUVMath.cpp.
     // This matrix is only used in multiplanar scenarios.
diff --git a/src/dawn/native/ExternalTexture.h b/src/dawn/native/ExternalTexture.h
index 50f3b89..509a7ee 100644
--- a/src/dawn/native/ExternalTexture.h
+++ b/src/dawn/native/ExternalTexture.h
@@ -28,7 +28,9 @@
 
 struct ExternalTextureParams {
     uint32_t numPlanes;
-    std::array<uint32_t, 3> padding;
+    // TODO(crbug.com/dawn/1466): Only go as few steps as necessary.
+    uint32_t doYuvToRgbConversionOnly;
+    std::array<uint32_t, 2> padding;
     std::array<float, 12> yuvToRgbConversionMatrix;
     std::array<float, 8> gammaDecodingParams = {};
     std::array<float, 8> gammaEncodingParams = {};
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 8b85573..cf5a5a6 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -251,6 +251,7 @@
         // Create ExternalTextureParams struct.
         ast::StructMemberList ext_tex_params_member_list = {
             b.Member("numPlanes", b.ty.u32()),
+            b.Member("doYuvToRgbConversionOnly", b.ty.u32()),
             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")),
@@ -340,14 +341,20 @@
                               b.Mul(b.vec4<f32>(b.MemberAccessor(plane_0_call, "r"),
                                                 b.MemberAccessor(plane_1_call, "rg"), 1_f),
                                     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"))),
+            // if (params.doYuvToRgbConversionOnly == 0u)
+            b.If(b.create<ast::BinaryExpression>(
+                     ast::BinaryOp::kEqual, b.MemberAccessor("params", "doYuvToRgbConversionOnly"),
+                     b.Expr(0_u)),
+                 b.Block(
+                     // 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.f);
             b.Return(b.vec4<f32>("color", 1_f))};
     }
diff --git a/src/tint/transform/multiplanar_external_texture.h b/src/tint/transform/multiplanar_external_texture.h
index 88cbc981..fcb5156 100644
--- a/src/tint/transform/multiplanar_external_texture.h
+++ b/src/tint/transform/multiplanar_external_texture.h
@@ -46,7 +46,10 @@
 /// textureSampleLevel that contain a texture_external parameter will be
 /// transformed into a newly generated version of the function, which can
 /// perform the desired operation on a single RGBA plane or on seperate Y and UV
-/// planes.
+/// planes, and do colorspace conversions including yuv->rgb conversion, gamma
+/// decoding, gamut conversion, and gamma encoding steps. Specifically
+// for BT.709 to SRGB conversion, it takes the fast path only doing the yuv->rgb
+// step and skipping all other steps.
 class MultiplanarExternalTexture : public Castable<MultiplanarExternalTexture, Transform> {
   public:
     /// BindingsMap is a map where the key is the binding location of a
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index 63d12f1..79f9fdd 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -118,6 +118,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -172,6 +173,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -225,6 +227,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -253,9 +256,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -298,6 +303,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -322,9 +328,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -370,6 +378,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -396,9 +405,11 @@
   } else {
     color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -440,6 +451,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -464,9 +476,11 @@
   } else {
     color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -512,6 +526,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -540,9 +555,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -553,9 +570,11 @@
   } else {
     color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -599,6 +618,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -623,9 +643,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -636,9 +658,11 @@
   } else {
     color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -688,6 +712,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -734,9 +759,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -788,6 +815,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -812,9 +840,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -870,6 +900,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -899,9 +930,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -952,6 +985,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -976,9 +1010,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1036,6 +1072,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1064,9 +1101,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1129,6 +1168,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1162,9 +1202,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1223,6 +1265,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1247,9 +1290,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1313,6 +1358,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1337,9 +1383,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1391,6 +1439,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1441,6 +1490,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1467,9 +1517,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }
 
@@ -1526,6 +1578,7 @@
 
 struct ExternalTextureParams {
   numPlanes : u32,
+  doYuvToRgbConversionOnly : u32,
   yuvToRgbConversionMatrix : mat3x4<f32>,
   gammaDecodeParams : GammaTransferParams,
   gammaEncodeParams : GammaTransferParams,
@@ -1555,9 +1608,11 @@
   } else {
     color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
   }
-  color = gammaCorrection(color, params.gammaDecodeParams);
-  color = (params.gamutConversionMatrix * color);
-  color = gammaCorrection(color, params.gammaEncodeParams);
+  if ((params.doYuvToRgbConversionOnly == 0u)) {
+    color = gammaCorrection(color, params.gammaDecodeParams);
+    color = (params.gamutConversionMatrix * color);
+    color = gammaCorrection(color, params.gammaEncodeParams);
+  }
   return vec4<f32>(color, 1.0f);
 }