diff --git a/src/transform/multiplanar_external_texture.cc b/src/transform/multiplanar_external_texture.cc
index 599f593..a3cfcc7 100644
--- a/src/transform/multiplanar_external_texture.cc
+++ b/src/transform/multiplanar_external_texture.cc
@@ -20,6 +20,7 @@
 #include "src/ast/function.h"
 #include "src/program_builder.h"
 #include "src/sem/call.h"
+#include "src/sem/function.h"
 #include "src/sem/variable.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture);
@@ -33,15 +34,26 @@
 /// This struct stores symbols for new bindings created as a result of
 /// transforming a texture_external instance.
 struct NewBindingSymbols {
-  Symbol ext_tex_params_binding_sym;
-  Symbol ext_tex_plane_1_binding_sym;
+  Symbol params;
+  Symbol plane_0;
+  Symbol plane_1;
 };
 }  // namespace
 
 /// State holds the current transform state
 struct MultiplanarExternalTexture::State {
+  /// The clone context.
+  CloneContext& ctx;
+
+  /// ProgramBuilder for the context
+  ProgramBuilder& b;
+
+  /// Desination binding locations for the expanded texture_external provided as
+  /// input into the transform.
+  const NewBindingPoints* new_binding_points;
+
   /// Symbol for the ExternalTextureParams struct
-  Symbol external_texture_params_struct_sym;
+  Symbol params_struct_sym;
 
   /// Symbol for the textureLoadExternal function
   Symbol texture_load_external_sym;
@@ -52,6 +64,337 @@
   /// Storage for new bindings that have been created corresponding to an
   /// original texture_external binding.
   std::unordered_map<Symbol, NewBindingSymbols> new_binding_symbols;
+
+  /// Constructor
+  /// @param context the clone
+  /// @param newBindingPoints the input destination binding locations for the
+  /// expanded texture_external
+  State(CloneContext& context, const NewBindingPoints* newBindingPoints)
+      : ctx(context), b(*context.dst), new_binding_points(newBindingPoints) {}
+
+  /// Processes the module
+  void Process() {
+    auto& sem = ctx.src->Sem();
+
+    // For each texture_external binding, we replace it with a texture_2d<f32>
+    // binding and create two additional bindings (one texture_2d<f32> to
+    // represent the secondary plane and one uniform buffer for the
+    // ExternalTextureParams struct).
+    ctx.ReplaceAll([&](const ast::Variable* var) -> const ast::Variable* {
+      if (!::tint::Is<ast::ExternalTexture>(var->type)) {
+        return nullptr;
+      }
+
+      // If the decorations are empty, then this must be a texture_external
+      // passed as a function parameter. These variables are transformed
+      // elsewhere.
+      if (var->decorations.empty()) {
+        return nullptr;
+      }
+
+      // If we find a texture_external binding, we know we must emit the
+      // ExternalTextureParams struct.
+      if (!params_struct_sym.IsValid()) {
+        createExtTexParamsStruct();
+      }
+
+      // The binding points for the newly introduced bindings must have been
+      // provided to this transform. We fetch the new binding points by
+      // providing the original texture_external binding points into the
+      // passed map.
+      BindingPoint bp = {var->BindingPoint().group->value,
+                         var->BindingPoint().binding->value};
+
+      BindingsMap::const_iterator it =
+          new_binding_points->bindings_map.find(bp);
+      if (it == new_binding_points->bindings_map.end()) {
+        b.Diagnostics().add_error(
+            diag::System::Transform,
+            "missing new binding points for texture_external at binding {" +
+                std::to_string(bp.group) + "," + std::to_string(bp.binding) +
+                "}");
+        return nullptr;
+      }
+
+      BindingPoints bps = it->second;
+
+      // Symbols for the newly created bindings must be saved so they can be
+      // passed as parameters later. These are placed in a map and keyed by
+      // the source symbol associated with the texture_external binding that
+      // corresponds with the new destination bindings.
+      // NewBindingSymbols new_binding_syms;
+      auto& syms = new_binding_symbols[var->symbol];
+      syms.plane_0 = ctx.Clone(var->symbol);
+      syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
+      b.Global(syms.plane_1,
+               b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+               b.GroupAndBinding(bps.plane_1.group, bps.plane_1.binding));
+      syms.params = b.Symbols().New("ext_tex_params");
+      b.Global(syms.params, b.ty.type_name("ExternalTextureParams"),
+               ast::StorageClass::kUniform,
+               b.GroupAndBinding(bps.params.group, bps.params.binding));
+
+      // Replace the original texture_external binding with a texture_2d<f32>
+      // binding.
+      ast::DecorationList cloned_decorations = ctx.Clone(var->decorations);
+      const ast::Expression* cloned_constructor = ctx.Clone(var->constructor);
+
+      return b.Var(syms.plane_0,
+                   b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+                   cloned_constructor, cloned_decorations);
+    });
+
+    // Transform the original textureLoad and textureSampleLevel calls into
+    // textureLoadExternal and textureSampleExternal calls.
+    ctx.ReplaceAll(
+        [&](const ast::CallExpression* expr) -> const ast::CallExpression* {
+          auto* intrinsic = sem.Get(expr)->Target()->As<sem::Intrinsic>();
+
+          if (intrinsic && !intrinsic->Parameters().empty() &&
+              intrinsic->Parameters()[0]->Type()->Is<sem::ExternalTexture>() &&
+              intrinsic->Type() != sem::IntrinsicType::kTextureDimensions) {
+            auto it = new_binding_symbols.find(
+                expr->args[0]->As<ast::IdentifierExpression>()->symbol);
+            if (it == new_binding_symbols.end()) {
+              // If valid new binding locations were not provided earlier, we
+              // would have been unable to create these symbols. An error
+              // message was emitted earlier, so just return early to avoid
+              // internal compiler errors and retain a clean error message.
+              return nullptr;
+            }
+            auto& syms = it->second;
+
+            if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad) {
+              return createTexLdExt(expr, syms);
+            }
+
+            if (intrinsic->Type() == sem::IntrinsicType::kTextureSampleLevel) {
+              return createTexSmpExt(expr, syms);
+            }
+
+          } else if (sem.Get(expr)->Target()->Is<sem::Function>()) {
+            // The call expression may be to a user-defined function that
+            // contains a texture_external parameter. These need to be expanded
+            // out to multiple plane textures and the texture parameters
+            // structure.
+            for (const ast::Expression* arg : expr->args) {
+              if (auto* id_expr = arg->As<ast::IdentifierExpression>()) {
+                // Check if a parameter is a texture_external by trying to find
+                // it in the transform state.
+                auto it = new_binding_symbols.find(id_expr->symbol);
+                if (it != new_binding_symbols.end()) {
+                  auto& syms = it->second;
+                  // When we find a texture_external, we must unpack it into its
+                  // components.
+                  ctx.Replace(id_expr, b.Expr(syms.plane_0));
+                  ctx.InsertAfter(expr->args, id_expr, b.Expr(syms.plane_1));
+                  ctx.InsertAfter(expr->args, id_expr, b.Expr(syms.params));
+                }
+              }
+            }
+          }
+
+          return nullptr;
+        });
+
+    // We must update all the texture_external parameters for user declared
+    // functions.
+    ctx.ReplaceAll([&](const ast::Function* fn) -> const ast::Function* {
+      for (const ast::Variable* param : fn->params) {
+        if (::tint::Is<ast::ExternalTexture>(param->type)) {
+          // If we find a texture_external, we must ensure the
+          // ExternalTextureParams struct exists.
+          if (!params_struct_sym.IsValid()) {
+            createExtTexParamsStruct();
+          }
+          // When a texture_external is found, we insert all components
+          // the texture_external into the parameter list. We must also place
+          // the new symbols into the transform state so they can be used when
+          // transforming function calls.
+          auto& syms = new_binding_symbols[param->symbol];
+          syms.plane_0 = ctx.Clone(param->symbol);
+          syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
+          syms.params = b.Symbols().New("ext_tex_params");
+          auto tex2d_f32 = [&] {
+            return b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32());
+          };
+          ctx.Replace(param, b.Param(syms.plane_0, tex2d_f32()));
+          ctx.InsertAfter(fn->params, param,
+                          b.Param(syms.plane_1, tex2d_f32()));
+          ctx.InsertAfter(
+              fn->params, param,
+              b.Param(syms.params, b.ty.type_name(params_struct_sym)));
+        }
+      }
+      // Clone the function. This will use the Replace() and InsertAfter() calls
+      // above.
+      return nullptr;
+    });
+  }
+
+  /// Creates the ExternalTextureParams struct.
+  void createExtTexParamsStruct() {
+    ast::StructMemberList member_list = {
+        b.Member("numPlanes", b.ty.u32()), b.Member("vr", b.ty.f32()),
+        b.Member("ug", b.ty.f32()), b.Member("vg", b.ty.f32()),
+        b.Member("ub", b.ty.f32())};
+
+    params_struct_sym = b.Symbols().New("ExternalTextureParams");
+
+    b.Structure(params_struct_sym, member_list,
+                ast::DecorationList{b.StructBlock()});
+  }
+
+  /// Constructs a StatementList containing all the statements making up the
+  /// bodies of the textureSampleExternal and textureLoadExternal functions.
+  /// @param callType determines which function body to generate
+  /// @returns a statement list that makes of the body of the chosen function
+  ast::StatementList createTexFnExtStatementList(sem::IntrinsicType callType) {
+    using f32 = ProgramBuilder::f32;
+    const ast::CallExpression* single_plane_call;
+    const ast::CallExpression* plane_0_call;
+    const ast::CallExpression* plane_1_call;
+    if (callType == sem::IntrinsicType::kTextureSampleLevel) {
+      // textureSampleLevel(plane0, smp, coord.xy, 0.0);
+      single_plane_call =
+          b.Call("textureSampleLevel", "plane0", "smp", "coord", 0.0f);
+      // textureSampleLevel(plane0, smp, coord.xy, 0.0);
+      plane_0_call =
+          b.Call("textureSampleLevel", "plane0", "smp", "coord", 0.0f);
+      // textureSampleLevel(plane1, smp, coord.xy, 0.0);
+      plane_1_call =
+          b.Call("textureSampleLevel", "plane1", "smp", "coord", 0.0f);
+    } else if (callType == sem::IntrinsicType::kTextureLoad) {
+      // textureLoad(plane0, coords.xy, 0);
+      single_plane_call = b.Call("textureLoad", "plane0", "coord", 0);
+      // textureLoad(plane0, coords.xy, 0);
+      plane_0_call = b.Call("textureLoad", "plane0", "coord", 0);
+      // textureLoad(plane1, coords.xy, 0);
+      plane_1_call = b.Call("textureLoad", "plane1", "coord", 0);
+    }
+
+    return {
+        // if (params.numPlanes == 1u) {
+        //    return singlePlaneCall
+        // }
+        b.If(b.create<ast::BinaryExpression>(
+                 ast::BinaryOp::kEqual, b.MemberAccessor("params", "numPlanes"),
+                 b.Expr(1u)),
+             b.Block(b.Return(single_plane_call))),
+        // let y = plane0Call.r - 0.0625;
+        b.Decl(b.Const("y", nullptr,
+                       b.Sub(b.MemberAccessor(plane_0_call, "r"), 0.0625f))),
+        // let uv = plane1Call.rg - 0.5;
+        b.Decl(b.Const("uv", nullptr,
+                       b.Sub(b.MemberAccessor(plane_1_call, "rg"), 0.5f))),
+        // let u = uv.x;
+        b.Decl(b.Const("u", nullptr, b.MemberAccessor("uv", "x"))),
+        // let v = uv.y;
+        b.Decl(b.Const("v", nullptr, b.MemberAccessor("uv", "y"))),
+        // let r = 1.164 * y + params.vr * v;
+        b.Decl(b.Const("r", nullptr,
+                       b.Add(b.Mul(1.164f, "y"),
+                             b.Mul(b.MemberAccessor("params", "vr"), "v")))),
+        // let g = 1.164 * y - params.ug * u - params.vg * v;
+        b.Decl(
+            b.Const("g", nullptr,
+                    b.Sub(b.Sub(b.Mul(1.164f, "y"),
+                                b.Mul(b.MemberAccessor("params", "ug"), "u")),
+                          b.Mul(b.MemberAccessor("params", "vg"), "v")))),
+        // let b = 1.164 * y + params.ub * u;
+        b.Decl(b.Const("b", nullptr,
+                       b.Add(b.Mul(1.164f, "y"),
+                             b.Mul(b.MemberAccessor("params", "ub"), "u")))),
+        // return vec4<f32>(r, g, b, 1.0);
+        b.Return(b.vec4<f32>("r", "g", "b", 1.0f)),
+    };
+  }
+
+  /// Creates the textureSampleExternal function if needed and returns a call
+  /// expression to it.
+  /// @param expr the call expression being transformed
+  /// @param syms the expanded symbols to be used in the new call
+  /// @returns a call expression to textureSampleExternal
+  const ast::CallExpression* createTexSmpExt(const ast::CallExpression* expr,
+                                             NewBindingSymbols syms) {
+    ast::ExpressionList params;
+    const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]);
+
+    if (expr->args.size() != 3) {
+      TINT_ICE(Transform, b.Diagnostics())
+          << "expected textureSampleLevel call with a "
+             "texture_external to have 3 parameters, found "
+          << expr->args.size() << " parameters";
+    }
+
+    if (!texture_sample_external_sym.IsValid()) {
+      texture_sample_external_sym = b.Symbols().New("textureSampleExternal");
+
+      // Emit the textureSampleExternal function.
+      ast::VariableList varList = {
+          b.Param("plane0",
+                  b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
+          b.Param("plane1",
+                  b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
+          b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
+          b.Param("coord", b.ty.vec2(b.ty.f32())),
+          b.Param("params", b.ty.type_name(params_struct_sym))};
+
+      ast::StatementList statementList =
+          createTexFnExtStatementList(sem::IntrinsicType::kTextureSampleLevel);
+
+      b.Func(texture_sample_external_sym, varList, b.ty.vec4(b.ty.f32()),
+             statementList, {});
+    }
+
+    const ast::IdentifierExpression* exp = b.Expr(texture_sample_external_sym);
+    params = {plane_0_binding_param, b.Expr(syms.plane_1),
+              ctx.Clone(expr->args[1]), ctx.Clone(expr->args[2]),
+              b.Expr(syms.params)};
+    return b.Call(exp, params);
+  }
+
+  /// Creates the textureLoadExternal function if needed and returns a call
+  /// expression to it.
+  /// @param expr the call expression being transformed
+  /// @param syms the expanded symbols to be used in the new call
+  /// @returns a call expression to textureLoadExternal
+  const ast::CallExpression* createTexLdExt(const ast::CallExpression* expr,
+                                            NewBindingSymbols syms) {
+    ast::ExpressionList params;
+    const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]);
+
+    if (expr->args.size() != 2) {
+      TINT_ICE(Transform, b.Diagnostics())
+          << "expected textureLoad call with a texture_external "
+             "to have 2 parameters, found "
+          << expr->args.size() << " parameters";
+    }
+
+    if (!texture_load_external_sym.IsValid()) {
+      texture_load_external_sym = b.Symbols().New("textureLoadExternal");
+
+      // Emit the textureLoadExternal function.
+      ast::VariableList var_list = {
+          b.Param("plane0",
+                  b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
+          b.Param("plane1",
+                  b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
+          b.Param("coord", b.ty.vec2(b.ty.i32())),
+          b.Param("params", b.ty.type_name(params_struct_sym))};
+
+      ast::StatementList statement_list =
+          createTexFnExtStatementList(sem::IntrinsicType::kTextureLoad);
+
+      b.Func(texture_load_external_sym, var_list, b.ty.vec4(b.ty.f32()),
+             statement_list, {});
+    }
+
+    const ast::IdentifierExpression* exp = b.Expr(texture_load_external_sym);
+    params = {plane_0_binding_param, b.Expr(syms.plane_1),
+              ctx.Clone(expr->args[1]), b.Expr(syms.params)};
+    return b.Call(exp, params);
+  }
 };
 
 MultiplanarExternalTexture::NewBindingPoints::NewBindingPoints(
@@ -72,285 +415,21 @@
 void MultiplanarExternalTexture::Run(CloneContext& ctx,
                                      const DataMap& inputs,
                                      DataMap&) {
-  State state;
-  auto& b = *ctx.dst;
-
   auto* new_binding_points = inputs.Get<NewBindingPoints>();
 
   if (!new_binding_points) {
-    b.Diagnostics().add_error(
+    ctx.dst->Diagnostics().add_error(
         diag::System::Transform,
         "missing new binding point data for " + std::string(TypeInfo().name));
     return;
   }
 
-  auto& sem = ctx.src->Sem();
+  State state(ctx, new_binding_points);
 
-  // For each texture_external binding, we replace it with a texture_2d<f32>
-  // binding and create two additional bindings (one texture_2d<f32> to
-  // represent the secondary plane and one uniform buffer for the
-  // ExternalTextureParams struct).
-  ctx.ReplaceAll([&](const ast::Variable* var) -> const ast::Variable* {
-    if (!::tint::Is<ast::ExternalTexture>(var->type)) {
-      return nullptr;
-    }
-
-    // If the decorations are empty, then this must be a texture_external being
-    // passed as a function parameter. We need to unpack this into multiple
-    // parameters - but this hasn't been implemented so produce an error.
-    if (var->decorations.empty()) {
-      b.Diagnostics().add_error(
-          diag::System::Transform,
-          "transforming a texture_external passed as a user-defined function "
-          "parameter has not been implemented.");
-      return nullptr;
-    }
-
-    // If we find a texture_external binding, we know we must emit the
-    // ExternalTextureParams struct.
-    if (!state.external_texture_params_struct_sym.IsValid()) {
-      ast::StructMemberList member_list = {
-          b.Member("numPlanes", b.ty.u32()), b.Member("vr", b.ty.f32()),
-          b.Member("ug", b.ty.f32()), b.Member("vg", b.ty.f32()),
-          b.Member("ub", b.ty.f32())};
-
-      state.external_texture_params_struct_sym =
-          b.Symbols().New("ExternalTextureParams");
-
-      b.Structure(state.external_texture_params_struct_sym, member_list,
-                  ast::DecorationList{b.StructBlock()});
-    }
-
-    // The binding points for the newly introduced bindings must have been
-    // provided to this transform. We fetch the new binding points by
-    // providing the original texture_external binding points into the
-    // passed map.
-    BindingPoint bp = {var->BindingPoint().group->value,
-                       var->BindingPoint().binding->value};
-    BindingPoints bps;
-    BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp);
-    if (it == new_binding_points->bindings_map.end()) {
-      b.Diagnostics().add_error(
-          diag::System::Transform,
-          "missing new binding points for texture_external at binding {" +
-              std::to_string(bp.group) + "," + std::to_string(bp.binding) +
-              "}");
-      return nullptr;
-    } else {
-      bps = it->second;
-    }
-
-    // Symbols for the newly created bindings must be saved so they can be
-    // passed as parameters later. These are placed in a map and keyed by
-    // the symbol associated with the texture_external binding that
-    // corresponds with the new bindings.
-    NewBindingSymbols new_binding_syms;
-    new_binding_syms.ext_tex_plane_1_binding_sym =
-        b.Symbols().New("ext_tex_plane_1");
-    b.Global(new_binding_syms.ext_tex_plane_1_binding_sym,
-             b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
-             b.GroupAndBinding(bps.plane_1.group, bps.plane_1.binding));
-
-    new_binding_syms.ext_tex_params_binding_sym =
-        b.Symbols().New("ext_tex_params");
-    b.Global(new_binding_syms.ext_tex_params_binding_sym,
-             b.ty.type_name("ExternalTextureParams"),
-             ast::StorageClass::kUniform,
-             b.GroupAndBinding(bps.params.group, bps.params.binding));
-
-    // Replace the original texture_external binding with a texture_2d<f32>
-    // binding.
-    auto cloned_sym = ctx.Clone(var->symbol);
-    ast::DecorationList cloned_decorations = ctx.Clone(var->decorations);
-    const ast::Expression* cloned_constructor = ctx.Clone(var->constructor);
-    state.new_binding_symbols[cloned_sym] = new_binding_syms;
-
-    return b.Var(cloned_sym,
-                 b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
-                 cloned_constructor, cloned_decorations);
-  });
-
-  // Transform the original textureLoad and textureSampleLevel calls into
-  // textureLoadExternal and textureSampleExternal calls.
-  ctx.ReplaceAll([&](const ast::CallExpression* expr)
-                     -> const ast::CallExpression* {
-    auto* intrinsic = sem.Get(expr)->Target()->As<sem::Intrinsic>();
-
-    if (!intrinsic ||
-        !intrinsic->Parameters()[0]->Type()->Is<sem::ExternalTexture>() ||
-        intrinsic->Parameters().empty() ||
-        intrinsic->Type() == sem::IntrinsicType::kTextureDimensions) {
-      return nullptr;
-    }
-
-    const ast::Expression* ext_tex_plane_0_binding_param =
-        ctx.Clone(expr->args[0]);
-
-    // Lookup the symbols for the new bindings using the symbol from the
-    // original texture_external.
-    Symbol ext_tex_plane_1_binding_sym =
-        state
-            .new_binding_symbols[ext_tex_plane_0_binding_param
-                                     ->As<ast::IdentifierExpression>()
-                                     ->symbol]
-            .ext_tex_plane_1_binding_sym;
-    Symbol ext_tex_params_binding_sym =
-        state
-            .new_binding_symbols[ext_tex_plane_0_binding_param
-                                     ->As<ast::IdentifierExpression>()
-                                     ->symbol]
-            .ext_tex_params_binding_sym;
-
-    // If valid new binding locations were not provided earlier, we would
-    // have been unable to create these symbols. An error message was
-    // emitted earlier, so just return early to avoid internal compiler
-    // errors and retain a clean error message.
-    if (!ext_tex_plane_1_binding_sym.IsValid() ||
-        !ext_tex_params_binding_sym.IsValid()) {
-      return nullptr;
-    }
-
-    ast::IdentifierExpression* exp;
-    ast::ExpressionList params;
-
-    if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad) {
-      if (expr->args.size() != 2) {
-        TINT_ICE(Transform, b.Diagnostics())
-            << "expected textureLoad call with a texture_external "
-               "to "
-               "have 2 parameters, found "
-            << expr->args.size() << " parameters";
-      }
-
-      if (!state.texture_load_external_sym.IsValid()) {
-        state.texture_load_external_sym =
-            b.Symbols().New("textureLoadExternal");
-
-        // Emit the textureLoadExternal function.
-        ast::VariableList var_list = {
-            b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d,
-                                                   b.ty.f32())),
-            b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d,
-                                                   b.ty.f32())),
-            b.Param("coord", b.ty.vec2(b.ty.i32())),
-            b.Param("params",
-                    b.ty.type_name(state.external_texture_params_struct_sym))};
-
-        ast::StatementList statement_list =
-            createTexFnExtStatementList(b, sem::IntrinsicType::kTextureLoad);
-
-        b.Func(state.texture_load_external_sym, var_list, b.ty.vec4(b.ty.f32()),
-               statement_list, {});
-      }
-
-      exp =
-          b.create<ast::IdentifierExpression>(state.texture_load_external_sym);
-      params = {ext_tex_plane_0_binding_param,
-                b.Expr(ext_tex_plane_1_binding_sym), ctx.Clone(expr->args[1]),
-                b.Expr(ext_tex_params_binding_sym)};
-    } else if (intrinsic->Type() == sem::IntrinsicType::kTextureSampleLevel) {
-      if (expr->args.size() != 3) {
-        TINT_ICE(Transform, b.Diagnostics())
-            << "expected textureSampleLevel call with a "
-               "texture_external to have 3 parameters, found "
-            << expr->args.size() << " parameters";
-      }
-
-      if (!state.texture_sample_external_sym.IsValid()) {
-        state.texture_sample_external_sym =
-            b.Symbols().New("textureSampleExternal");
-
-        // Emit the textureSampleExternal function.
-        ast::VariableList varList = {
-            b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d,
-                                                   b.ty.f32())),
-            b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d,
-                                                   b.ty.f32())),
-            b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
-            b.Param("coord", b.ty.vec2(b.ty.f32())),
-            b.Param("params",
-                    b.ty.type_name(state.external_texture_params_struct_sym))};
-
-        ast::StatementList statementList = createTexFnExtStatementList(
-            b, sem::IntrinsicType::kTextureSampleLevel);
-
-        b.Func(state.texture_sample_external_sym, varList,
-               b.ty.vec4(b.ty.f32()), statementList, {});
-      }
-      exp = b.create<ast::IdentifierExpression>(
-          state.texture_sample_external_sym);
-      params = {ext_tex_plane_0_binding_param,
-                b.Expr(ext_tex_plane_1_binding_sym), ctx.Clone(expr->args[1]),
-                ctx.Clone(expr->args[2]), b.Expr(ext_tex_params_binding_sym)};
-    }
-
-    return b.Call(exp, params);
-  });
+  state.Process();
 
   ctx.Clone();
 }
 
-// Constructs a StatementList containing all the statements making up the bodies
-// of the textureSampleExternal and textureLoadExternal functions.
-ast::StatementList MultiplanarExternalTexture::createTexFnExtStatementList(
-    ProgramBuilder& b,
-    sem::IntrinsicType callType) {
-  using f32 = ProgramBuilder::f32;
-  const ast::CallExpression* single_plane_call;
-  const ast::CallExpression* plane_0_call;
-  const ast::CallExpression* plane_1_call;
-  if (callType == sem::IntrinsicType::kTextureSampleLevel) {
-    // textureSampleLevel(plane0, smp, coord.xy, 0.0);
-    single_plane_call =
-        b.Call("textureSampleLevel", "plane0", "smp", "coord", 0.0f);
-    // textureSampleLevel(plane0, smp, coord.xy, 0.0);
-    plane_0_call = b.Call("textureSampleLevel", "plane0", "smp", "coord", 0.0f);
-    // textureSampleLevel(plane1, smp, coord.xy, 0.0);
-    plane_1_call = b.Call("textureSampleLevel", "plane1", "smp", "coord", 0.0f);
-  } else if (callType == sem::IntrinsicType::kTextureLoad) {
-    // textureLoad(plane0, coords.xy, 0);
-    single_plane_call = b.Call("textureLoad", "plane0", "coord", 0);
-    // textureLoad(plane0, coords.xy, 0);
-    plane_0_call = b.Call("textureLoad", "plane0", "coord", 0);
-    // textureLoad(plane1, coords.xy, 0);
-    plane_1_call = b.Call("textureLoad", "plane1", "coord", 0);
-  }
-
-  return {
-      // if (params.numPlanes == 1u) {
-      //    return singlePlaneCall
-      // }
-      b.If(b.create<ast::BinaryExpression>(
-               ast::BinaryOp::kEqual, b.MemberAccessor("params", "numPlanes"),
-               b.Expr(1u)),
-           b.Block(b.Return(single_plane_call))),
-      // let y = plane0Call.r - 0.0625;
-      b.Decl(b.Const("y", nullptr,
-                     b.Sub(b.MemberAccessor(plane_0_call, "r"), 0.0625f))),
-      // let uv = plane1Call.rg - 0.5;
-      b.Decl(b.Const("uv", nullptr,
-                     b.Sub(b.MemberAccessor(plane_1_call, "rg"), 0.5f))),
-      // let u = uv.x;
-      b.Decl(b.Const("u", nullptr, b.MemberAccessor("uv", "x"))),
-      // let v = uv.y;
-      b.Decl(b.Const("v", nullptr, b.MemberAccessor("uv", "y"))),
-      // let r = 1.164 * y + params.vr * v;
-      b.Decl(b.Const("r", nullptr,
-                     b.Add(b.Mul(1.164f, "y"),
-                           b.Mul(b.MemberAccessor("params", "vr"), "v")))),
-      // let g = 1.164 * y - params.ug * u - params.vg * v;
-      b.Decl(b.Const("g", nullptr,
-                     b.Sub(b.Sub(b.Mul(1.164f, "y"),
-                                 b.Mul(b.MemberAccessor("params", "ug"), "u")),
-                           b.Mul(b.MemberAccessor("params", "vg"), "v")))),
-      // let b = 1.164 * y + params.ub * u;
-      b.Decl(b.Const("b", nullptr,
-                     b.Add(b.Mul(1.164f, "y"),
-                           b.Mul(b.MemberAccessor("params", "ub"), "u")))),
-      // return vec4<f32>(r, g, b, 1.0);
-      b.Return(b.vec4<f32>("r", "g", "b", 1.0f)),
-  };
-}
-
 }  // namespace transform
 }  // namespace tint
diff --git a/src/transform/multiplanar_external_texture.h b/src/transform/multiplanar_external_texture.h
index 718dd3a..ad1e61b 100644
--- a/src/transform/multiplanar_external_texture.h
+++ b/src/transform/multiplanar_external_texture.h
@@ -86,17 +86,6 @@
   /// @param inputs optional extra transform-specific input data
   /// @param outputs optional extra transform-specific output data
   void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override;
-
-  /// Creates the statement list for the TextureSampleExternal and
-  /// TextureLoadExternal functions.
-  /// @param b a reference to the ProgramBuilder associated with the destination
-  /// context
-  /// @param callType determines the kind of param list to emit (either
-  /// textureLoad or textureSampleLevel)
-  /// @returns a statement list that is used to create the TextureSampleExternal
-  /// and TextureLoadExternal functions.
-  ast::StatementList createTexFnExtStatementList(ProgramBuilder& b,
-                                                 sem::IntrinsicType callType);
 };
 
 }  // namespace transform
diff --git a/src/transform/multiplanar_external_texture_test.cc b/src/transform/multiplanar_external_texture_test.cc
index 489a437..488df7a 100644
--- a/src/transform/multiplanar_external_texture_test.cc
+++ b/src/transform/multiplanar_external_texture_test.cc
@@ -379,21 +379,278 @@
 TEST_F(MultiplanarExternalTextureTest, ExternalTexturePassedAsParam) {
   auto* src = R"(
 fn f(t : texture_external, s : sampler) {
-      textureSampleLevel(t, s, vec2<f32>(1.0, 2.0));
-  }
+  textureSampleLevel(t, s, vec2<f32>(1.0, 2.0));
+}
 
-  [[group(0), binding(0)]] var ext_tex : texture_external;
-  [[group(0), binding(1)]] var smp : sampler;
+[[group(0), binding(0)]] var ext_tex : texture_external;
+[[group(0), binding(1)]] var smp : sampler;
 
-  [[stage(fragment)]]
-  fn main() {
-      f(ext_tex, smp);
-  }
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, smp);
+}
 )";
 
-  auto* expect =
-      "error: transforming a texture_external passed as a user-defined "
-      "function parameter has not been implemented.";
+  auto* expect = R"(
+[[block]]
+struct ExternalTextureParams {
+  numPlanes : u32;
+  vr : f32;
+  ug : f32;
+  vg : f32;
+  ub : f32;
+};
+
+fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+  if ((params.numPlanes == 1u)) {
+    return textureSampleLevel(plane0, smp, coord, 0.0);
+  }
+  let y = (textureSampleLevel(plane0, smp, coord, 0.0).r - 0.0625);
+  let uv = (textureSampleLevel(plane1, smp, coord, 0.0).rg - 0.5);
+  let u = uv.x;
+  let v = uv.y;
+  let r = ((1.164000034 * y) + (params.vr * v));
+  let g = (((1.164000034 * y) - (params.ug * u)) - (params.vg * v));
+  let b = ((1.164000034 * y) + (params.ub * u));
+  return vec4<f32>(r, g, b, 1.0);
+}
+
+fn f(t : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams, s : sampler) {
+  textureSampleExternal(t, ext_tex_plane_1, s, vec2<f32>(1.0, 2.0), ext_tex_params);
+}
+
+[[group(0), binding(2)]] var ext_tex_plane_1_1 : texture_2d<f32>;
+
+[[group(0), binding(3)]] var<uniform> ext_tex_params_1 : ExternalTextureParams;
+
+[[group(0), binding(0)]] var ext_tex : texture_2d<f32>;
+
+[[group(0), binding(1)]] var smp : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, ext_tex_plane_1_1, ext_tex_params_1, smp);
+}
+)";
+  DataMap data;
+  data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+      MultiplanarExternalTexture::BindingsMap{
+          {{0, 0}, {{0, 2}, {0, 3}}},
+      });
+  auto got = Run<MultiplanarExternalTexture>(src, data);
+  EXPECT_EQ(expect, str(got));
+}
+
+// Tests that the texture_external passed as a parameter not in the first
+// position produces the correct output.
+TEST_F(MultiplanarExternalTextureTest, ExternalTexturePassedAsSecondParam) {
+  auto* src = R"(
+fn f(s : sampler, t : texture_external) {
+  textureSampleLevel(t, s, vec2<f32>(1.0, 2.0));
+}
+
+[[group(0), binding(0)]] var ext_tex : texture_external;
+[[group(0), binding(1)]] var smp : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  f(smp, ext_tex);
+}
+)";
+
+  auto* expect = R"(
+[[block]]
+struct ExternalTextureParams {
+  numPlanes : u32;
+  vr : f32;
+  ug : f32;
+  vg : f32;
+  ub : f32;
+};
+
+fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+  if ((params.numPlanes == 1u)) {
+    return textureSampleLevel(plane0, smp, coord, 0.0);
+  }
+  let y = (textureSampleLevel(plane0, smp, coord, 0.0).r - 0.0625);
+  let uv = (textureSampleLevel(plane1, smp, coord, 0.0).rg - 0.5);
+  let u = uv.x;
+  let v = uv.y;
+  let r = ((1.164000034 * y) + (params.vr * v));
+  let g = (((1.164000034 * y) - (params.ug * u)) - (params.vg * v));
+  let b = ((1.164000034 * y) + (params.ub * u));
+  return vec4<f32>(r, g, b, 1.0);
+}
+
+fn f(s : sampler, t : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams) {
+  textureSampleExternal(t, ext_tex_plane_1, s, vec2<f32>(1.0, 2.0), ext_tex_params);
+}
+
+[[group(0), binding(2)]] var ext_tex_plane_1_1 : texture_2d<f32>;
+
+[[group(0), binding(3)]] var<uniform> ext_tex_params_1 : ExternalTextureParams;
+
+[[group(0), binding(0)]] var ext_tex : texture_2d<f32>;
+
+[[group(0), binding(1)]] var smp : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  f(smp, ext_tex, ext_tex_plane_1_1, ext_tex_params_1);
+}
+)";
+  DataMap data;
+  data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+      MultiplanarExternalTexture::BindingsMap{
+          {{0, 0}, {{0, 2}, {0, 3}}},
+      });
+  auto got = Run<MultiplanarExternalTexture>(src, data);
+  EXPECT_EQ(expect, str(got));
+}
+
+// Tests that multiple texture_external params passed to a function produces the
+// correct output.
+TEST_F(MultiplanarExternalTextureTest, ExternalTexturePassedAsParamMultiple) {
+  auto* src = R"(
+fn f(t : texture_external, s : sampler, t2 : texture_external) {
+  textureSampleLevel(t, s, vec2<f32>(1.0, 2.0));
+  textureSampleLevel(t2, s, vec2<f32>(1.0, 2.0));
+}
+
+[[group(0), binding(0)]] var ext_tex : texture_external;
+[[group(0), binding(1)]] var smp : sampler;
+[[group(0), binding(2)]] var ext_tex2 : texture_external;
+
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, smp, ext_tex2);
+}
+)";
+
+  auto* expect = R"(
+[[block]]
+struct ExternalTextureParams {
+  numPlanes : u32;
+  vr : f32;
+  ug : f32;
+  vg : f32;
+  ub : f32;
+};
+
+fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+  if ((params.numPlanes == 1u)) {
+    return textureSampleLevel(plane0, smp, coord, 0.0);
+  }
+  let y = (textureSampleLevel(plane0, smp, coord, 0.0).r - 0.0625);
+  let uv = (textureSampleLevel(plane1, smp, coord, 0.0).rg - 0.5);
+  let u = uv.x;
+  let v = uv.y;
+  let r = ((1.164000034 * y) + (params.vr * v));
+  let g = (((1.164000034 * y) - (params.ug * u)) - (params.vg * v));
+  let b = ((1.164000034 * y) + (params.ub * u));
+  return vec4<f32>(r, g, b, 1.0);
+}
+
+fn f(t : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams, s : sampler, t2 : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams) {
+  textureSampleExternal(t, ext_tex_plane_1, s, vec2<f32>(1.0, 2.0), ext_tex_params);
+  textureSampleExternal(t2, ext_tex_plane_1_1, s, vec2<f32>(1.0, 2.0), ext_tex_params_1);
+}
+
+[[group(0), binding(3)]] var ext_tex_plane_1_2 : texture_2d<f32>;
+
+[[group(0), binding(4)]] var<uniform> ext_tex_params_2 : ExternalTextureParams;
+
+[[group(0), binding(0)]] var ext_tex : texture_2d<f32>;
+
+[[group(0), binding(1)]] var smp : sampler;
+
+[[group(0), binding(5)]] var ext_tex_plane_1_3 : texture_2d<f32>;
+
+[[group(0), binding(6)]] var<uniform> ext_tex_params_3 : ExternalTextureParams;
+
+[[group(0), binding(2)]] var ext_tex2 : texture_2d<f32>;
+
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, ext_tex_plane_1_2, ext_tex_params_2, smp, ext_tex2, ext_tex_plane_1_3, ext_tex_params_3);
+}
+)";
+  DataMap data;
+  data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+      MultiplanarExternalTexture::BindingsMap{
+          {{0, 0}, {{0, 3}, {0, 4}}},
+          {{0, 2}, {{0, 5}, {0, 6}}},
+      });
+  auto got = Run<MultiplanarExternalTexture>(src, data);
+  EXPECT_EQ(expect, str(got));
+}
+
+// Tests that the texture_external passed to as a parameter to multiple
+// functions produces the correct output.
+TEST_F(MultiplanarExternalTextureTest, ExternalTexturePassedAsParamNested) {
+  auto* src = R"(
+fn nested(t : texture_external, s : sampler) {
+  textureSampleLevel(t, s, vec2<f32>(1.0, 2.0));
+}
+
+fn f(t : texture_external, s : sampler) {
+  nested(t, s);
+}
+
+[[group(0), binding(0)]] var ext_tex : texture_external;
+[[group(0), binding(1)]] var smp : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, smp);
+}
+)";
+
+  auto* expect = R"(
+[[block]]
+struct ExternalTextureParams {
+  numPlanes : u32;
+  vr : f32;
+  ug : f32;
+  vg : f32;
+  ub : f32;
+};
+
+fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+  if ((params.numPlanes == 1u)) {
+    return textureSampleLevel(plane0, smp, coord, 0.0);
+  }
+  let y = (textureSampleLevel(plane0, smp, coord, 0.0).r - 0.0625);
+  let uv = (textureSampleLevel(plane1, smp, coord, 0.0).rg - 0.5);
+  let u = uv.x;
+  let v = uv.y;
+  let r = ((1.164000034 * y) + (params.vr * v));
+  let g = (((1.164000034 * y) - (params.ug * u)) - (params.vg * v));
+  let b = ((1.164000034 * y) + (params.ub * u));
+  return vec4<f32>(r, g, b, 1.0);
+}
+
+fn nested(t : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams, s : sampler) {
+  textureSampleExternal(t, ext_tex_plane_1, s, vec2<f32>(1.0, 2.0), ext_tex_params);
+}
+
+fn f(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) {
+  nested(t, ext_tex_plane_1_1, ext_tex_params_1, s);
+}
+
+[[group(0), binding(2)]] var ext_tex_plane_1_2 : texture_2d<f32>;
+
+[[group(0), binding(3)]] var<uniform> ext_tex_params_2 : ExternalTextureParams;
+
+[[group(0), binding(0)]] var ext_tex : texture_2d<f32>;
+
+[[group(0), binding(1)]] var smp : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  f(ext_tex, ext_tex_plane_1_2, ext_tex_params_2, smp);
+}
+)";
   DataMap data;
   data.Add<MultiplanarExternalTexture::NewBindingPoints>(
       MultiplanarExternalTexture::BindingsMap{
