Remove uses of DrawCallParams.

Packing and referencing this structure was causing unnecessary draw
call overhead. This improves performance on all the back-ends. Impacts
the GL back-end the most.

In total this patch series reduces overhead by up to 5%.

Bug: angleproject:2933
Change-Id: Ief416ab874e481baf960d02965978a311214a146
Reviewed-on: https://chromium-review.googlesource.com/c/1299477
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/common/utilities.h b/src/common/utilities.h
index 673e0c4..07b71bd 100644
--- a/src/common/utilities.h
+++ b/src/common/utilities.h
@@ -139,6 +139,12 @@
 
 unsigned int ElementTypeSize(GLenum elementType);
 
+template <typename T>
+T GetClampedVertexCount(size_t vertexCount)
+{
+    static constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
+    return static_cast<T>(vertexCount > kMax ? kMax : vertexCount);
+}
 }  // namespace gl
 
 namespace egl
diff --git a/src/libANGLE/params.cpp b/src/libANGLE/params.cpp
index aaa618a..608f2fe 100644
--- a/src/libANGLE/params.cpp
+++ b/src/libANGLE/params.cpp
@@ -15,75 +15,6 @@
 
 namespace gl
 {
-
 // static
 constexpr ParamTypeInfo ParamsBase::TypeInfo;
-constexpr ParamTypeInfo DrawCallParams::TypeInfo;
-
-// Called by DrawArraysIndirect.
-DrawCallParams::DrawCallParams(PrimitiveMode mode, const void *indirect)
-    : mMode(mode),
-      mFirstVertex(0),
-      mVertexCount(0),
-      mIndexCount(0),
-      mBaseVertex(0),
-      mType(GL_NONE),
-      mIndices(nullptr),
-      mInstances(0),
-      mIndirect(indirect)
-{
-}
-
-// Called by DrawElementsIndirect.
-DrawCallParams::DrawCallParams(PrimitiveMode mode, GLenum type, const void *indirect)
-    : mMode(mode),
-      mFirstVertex(0),
-      mVertexCount(0),
-      mIndexCount(0),
-      mBaseVertex(0),
-      mType(type),
-      mIndices(nullptr),
-      mInstances(0),
-      mIndirect(indirect)
-{
-}
-
-GLsizei DrawCallParams::indexCount() const
-{
-    ASSERT(isDrawElements());
-    return mIndexCount;
-}
-
-GLint DrawCallParams::baseVertex() const
-{
-    return mBaseVertex;
-}
-
-GLenum DrawCallParams::type() const
-{
-    ASSERT(isDrawElements());
-    return mType;
-}
-
-const void *DrawCallParams::indices() const
-{
-    return mIndices;
-}
-
-GLsizei DrawCallParams::instances() const
-{
-    return mInstances;
-}
-
-const void *DrawCallParams::indirect() const
-{
-    return mIndirect;
-}
-
-bool DrawCallParams::isDrawIndirect() const
-{
-    // This is a bit of a hack - it's quite possible for a direct call to have a zero count, but we
-    // assume these calls are filtered out before they make it to this code.
-    return (mIndexCount == 0 && mVertexCount == 0);
-}
 }  // namespace gl
diff --git a/src/libANGLE/params.h b/src/libANGLE/params.h
index daf1829..41698f7 100644
--- a/src/libANGLE/params.h
+++ b/src/libANGLE/params.h
@@ -70,107 +70,8 @@
     new (objBuffer) EntryPointParamType<EP>(args...);
 }
 
-// Helper class that encompasses draw call parameters. It uses the HasIndexRange
-// helper class to only pull index range info lazily to prevent unnecessary readback.
-// It is also used when syncing state for the VertexArray implementation, since the
-// vertex and index buffer updates depend on draw call parameters.
-class DrawCallParams final : angle::NonCopyable
-{
-  public:
-    // Called by DrawArrays.
-    DrawCallParams(PrimitiveMode mode, GLint firstVertex, GLsizei vertexCount, GLsizei instances)
-        : mMode(mode),
-          mFirstVertex(firstVertex),
-          mVertexCount(vertexCount),
-          mIndexCount(0),
-          mBaseVertex(0),
-          mType(GL_NONE),
-          mIndices(nullptr),
-          mInstances(instances),
-          mIndirect(nullptr)
-    {
-    }
-
-    // Called by DrawElements.
-    DrawCallParams(PrimitiveMode mode,
-                   GLint indexCount,
-                   GLenum type,
-                   const void *indices,
-                   GLint baseVertex,
-                   GLsizei instances)
-        : mMode(mode),
-          mFirstVertex(0),
-          mVertexCount(0),
-          mIndexCount(indexCount),
-          mBaseVertex(baseVertex),
-          mType(type),
-          mIndices(indices),
-          mInstances(instances),
-          mIndirect(nullptr)
-    {
-    }
-
-    // Called by DrawArraysIndirect.
-    DrawCallParams(PrimitiveMode mode, const void *indirect);
-
-    // Called by DrawElementsIndirect.
-    DrawCallParams(PrimitiveMode mode, GLenum type, const void *indirect);
-
-    PrimitiveMode mode() const { return mMode; }
-
-    // Only applies to DrawArrays.
-    GLint firstVertex() const
-    {
-        return mFirstVertex;
-    }
-
-    size_t vertexCount() const
-    {
-        return mVertexCount;
-    }
-
-    GLsizei indexCount() const;
-    GLint baseVertex() const;
-    GLenum type() const;
-    const void *indices() const;
-    GLsizei instances() const;
-    const void *indirect() const;
-
-    bool isDrawElements() const { return (mType != GL_NONE); }
-
-    bool isDrawIndirect() const;
-
-    template <typename T>
-    T getClampedVertexCount() const;
-
-    template <EntryPoint EP, typename... ArgsT>
-    static void Factory(DrawCallParams *objBuffer, ArgsT... args);
-
-    ANGLE_PARAM_TYPE_INFO(DrawCallParams, ParamsBase);
-
-  private:
-    PrimitiveMode mMode;
-    mutable GLint mFirstVertex;
-    mutable size_t mVertexCount;
-    GLint mIndexCount;
-    GLint mBaseVertex;
-    GLenum mType;
-    const void *mIndices;
-    GLsizei mInstances;
-    const void *mIndirect;
-};
-
-template <typename T>
-T DrawCallParams::getClampedVertexCount() const
-{
-    constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
-    return static_cast<T>(mVertexCount > kMax ? kMax : mVertexCount);
-}
-
 // Entry point funcs essentially re-map different entry point parameter arrays into
-// the format the parameter type class expects. For example, for HasIndexRange, for the
-// various indexed draw calls, they drop parameters that aren't useful and re-arrange
-// the rest.
+// the format the parameter type class expects.
 #define ANGLE_ENTRY_POINT_FUNC(NAME, CLASS, ...)    \
     \
 template<> struct EntryPointParam<EntryPoint::NAME> \
@@ -180,120 +81,6 @@
     \
 template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__)
 
-ANGLE_ENTRY_POINT_FUNC(DrawArrays,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLint first,
-                       GLsizei count)
-{
-    return ParamsBase::Factory<EntryPoint::DrawArrays>(objBuffer, mode, first, count, 0);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawArraysInstanced,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLint first,
-                       GLsizei count,
-                       GLsizei instanceCount)
-{
-    return ParamsBase::Factory<EntryPoint::DrawArraysInstanced>(objBuffer, mode, first, count,
-                                                                instanceCount);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawArraysInstancedANGLE,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLint first,
-                       GLsizei count,
-                       GLsizei instanceCount)
-{
-    return ParamsBase::Factory<EntryPoint::DrawArraysInstancedANGLE>(objBuffer, mode, first, count,
-                                                                     instanceCount);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawArraysIndirect,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       const void *indirect)
-{
-    return ParamsBase::Factory<EntryPoint::DrawArraysIndirect>(objBuffer, mode, indirect);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawElementsIndirect,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLenum type,
-                       const void *indirect)
-{
-    return ParamsBase::Factory<EntryPoint::DrawElementsIndirect>(objBuffer, mode, type, indirect);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawElements,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLsizei count,
-                       GLenum type,
-                       const void *indices)
-{
-    return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, mode, count, type, indices, 0,
-                                                         0);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLsizei count,
-                       GLenum type,
-                       const void *indices,
-                       GLsizei instanceCount)
-{
-    return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, mode, count, type,
-                                                                  indices, 0, instanceCount);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLsizei count,
-                       GLenum type,
-                       const void *indices,
-                       GLsizei instanceCount)
-{
-    return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, mode, count, type,
-                                                                       indices, 0, instanceCount);
-}
-
-ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,
-                       DrawCallParams,
-                       DrawCallParams *objBuffer,
-                       Context *context,
-                       PrimitiveMode mode,
-                       GLuint /*start*/,
-                       GLuint /*end*/,
-                       GLsizei count,
-                       GLenum type,
-                       const void *indices)
-{
-    return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, mode, count, type, indices,
-                                                              0, 0);
-}
-
 #undef ANGLE_ENTRY_POINT_FUNC
 
 template <EntryPoint EP>
diff --git a/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/src/libANGLE/renderer/d3d/IndexDataManager.cpp
index 2442f52..1771ce2 100644
--- a/src/libANGLE/renderer/d3d/IndexDataManager.cpp
+++ b/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -303,7 +303,9 @@
 }
 
 angle::Result GetIndexTranslationDestType(const gl::Context *context,
-                                          const gl::DrawCallParams &drawCallParams,
+                                          GLsizei indexCount,
+                                          GLenum indexType,
+                                          const void *indices,
                                           bool usePrimitiveRestartWorkaround,
                                           GLenum *destTypeOut)
 {
@@ -312,24 +314,24 @@
     if (usePrimitiveRestartWorkaround)
     {
         // Conservatively assume we need to translate the indices for draw indirect.
-        if (drawCallParams.isDrawIndirect())
+        // This is a bit of a trick. We assume the count for an indirect draw is zero.
+        if (indexCount == 0)
         {
             *destTypeOut = GL_UNSIGNED_INT;
             return angle::Result::Continue();
         }
 
         gl::IndexRange indexRange;
-        ANGLE_TRY_HANDLE(context, context->getGLState().getVertexArray()->getIndexRange(
-                                      context, drawCallParams.type(), drawCallParams.indexCount(),
-                                      drawCallParams.indices(), &indexRange));
-        if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type()))
+        ANGLE_TRY(context->getGLState().getVertexArray()->getIndexRange(
+            context, indexType, indexCount, indices, &indexRange));
+        if (indexRange.end == gl::GetPrimitiveRestartIndex(indexType))
         {
             *destTypeOut = GL_UNSIGNED_INT;
             return angle::Result::Continue();
         }
     }
 
-    *destTypeOut = (drawCallParams.type() == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+    *destTypeOut = (indexType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
     return angle::Result::Continue();
 }
 
diff --git a/src/libANGLE/renderer/d3d/IndexDataManager.h b/src/libANGLE/renderer/d3d/IndexDataManager.h
index 6425d6b..eda4fc9 100644
--- a/src/libANGLE/renderer/d3d/IndexDataManager.h
+++ b/src/libANGLE/renderer/d3d/IndexDataManager.h
@@ -97,7 +97,9 @@
 };
 
 angle::Result GetIndexTranslationDestType(const gl::Context *context,
-                                          const gl::DrawCallParams &drawCallParams,
+                                          GLsizei indexCount,
+                                          GLenum indexType,
+                                          const void *indices,
                                           bool usePrimitiveRestartWorkaround,
                                           GLenum *destTypeOut);
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
index d68ee36..ac59d78 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -248,10 +248,10 @@
                                     GLint first,
                                     GLsizei count)
 {
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-    ASSERT(!drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
-    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, first));
-    return mRenderer->drawArrays(context, drawCallParams);
+    ASSERT(count > 0);
+    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count, GL_NONE,
+                                                        nullptr, 0, 0));
+    return mRenderer->drawArrays(context, mode, first, count, 0);
 }
 
 angle::Result Context11::drawArraysInstanced(const gl::Context *context,
@@ -260,10 +260,10 @@
                                              GLsizei count,
                                              GLsizei instanceCount)
 {
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-    ASSERT(!drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
-    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, first));
-    return mRenderer->drawArrays(context, drawCallParams);
+    ASSERT(count > 0);
+    ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count, GL_NONE,
+                                                        nullptr, instanceCount, 0));
+    return mRenderer->drawArrays(context, mode, first, count, instanceCount);
 }
 
 ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *context,
@@ -273,22 +273,24 @@
                                                        const void *indices,
                                                        GLsizei instanceCount)
 {
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-    ASSERT(drawCallParams.isDrawElements() && !drawCallParams.isDrawIndirect());
+    ASSERT(indexCount > 0);
 
     if (DrawCallHasDynamicAttribs(context))
     {
         gl::IndexRange indexRange;
         ANGLE_TRY(context->getGLState().getVertexArray()->getIndexRange(
             context, indexType, indexCount, indices, &indexRange));
-        ANGLE_TRY(
-            mRenderer->getStateManager()->updateState(context, drawCallParams, indexRange.start));
-        return mRenderer->drawElements(context, drawCallParams, indexRange.start);
+        ANGLE_TRY(mRenderer->getStateManager()->updateState(
+            context, mode, indexRange.start, indexCount, indexType, indices, instanceCount, 0));
+        return mRenderer->drawElements(context, mode, indexRange.start, indexCount, indexType,
+                                       indices, instanceCount);
     }
     else
     {
-        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, 0));
-        return mRenderer->drawElements(context, drawCallParams, 0);
+        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, indexCount, indexType,
+                                                            indices, instanceCount, 0));
+        return mRenderer->drawElements(context, mode, 0, indexCount, indexType, indices,
+                                       instanceCount);
     }
 }
 
@@ -331,16 +333,15 @@
         const gl::DrawArraysIndirectCommand *cmd = nullptr;
         ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
 
-        gl::DrawCallParams drawCallParams(mode, cmd->first, cmd->count, cmd->instanceCount);
-        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, cmd->first));
-        return mRenderer->drawArrays(context, drawCallParams);
+        ANGLE_TRY(mRenderer->getStateManager()->updateState(
+            context, mode, cmd->first, cmd->count, GL_NONE, nullptr, cmd->instanceCount, 0));
+        return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount);
     }
     else
     {
-        const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-        ASSERT(!drawCallParams.isDrawElements() && drawCallParams.isDrawIndirect());
-        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, 0));
-        return mRenderer->drawArraysIndirect(context, drawCallParams);
+        ANGLE_TRY(
+            mRenderer->getStateManager()->updateState(context, mode, 0, 0, GL_NONE, nullptr, 0, 0));
+        return mRenderer->drawArraysIndirect(context, indirect);
     }
 }
 
@@ -359,9 +360,6 @@
         const void *indices      = reinterpret_cast<const void *>(
             static_cast<uintptr_t>(cmd->firstIndex * typeInfo.bytes));
 
-        gl::DrawCallParams drawCallParams(mode, cmd->count, type, indices, cmd->baseVertex,
-                                          cmd->primCount);
-
         // We must explicitly resolve the index range for the slow-path indirect drawElements to
         // make sure we are using the correct 'baseVertex'. This parameter does not exist for the
         // direct drawElements.
@@ -369,19 +367,21 @@
         ANGLE_TRY(context->getGLState().getVertexArray()->getIndexRange(context, type, cmd->count,
                                                                         indices, &indexRange));
 
-        GLint firstVertex;
-        ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange,
-                                     drawCallParams.baseVertex(), &firstVertex));
+        GLint startVertex;
+        ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, cmd->baseVertex,
+                                     &startVertex));
 
-        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, firstVertex));
-        return mRenderer->drawElements(context, drawCallParams, indexRange.start);
+        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, startVertex, cmd->count,
+                                                            type, indices, cmd->primCount,
+                                                            cmd->baseVertex));
+        return mRenderer->drawElements(context, mode, indexRange.start, cmd->count, type, indices,
+                                       cmd->primCount);
     }
     else
     {
-        const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-        ASSERT(drawCallParams.isDrawElements() && drawCallParams.isDrawIndirect());
-        ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawCallParams, 0));
-        return mRenderer->drawElementsIndirect(context, drawCallParams);
+        ANGLE_TRY(
+            mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0, 0));
+        return mRenderer->drawElementsIndirect(context, indirect);
     }
 }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 8874b41..85dc6a4 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -120,7 +120,9 @@
     const gl::State &state,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
     const AttribIndexArray &sortedSemanticIndices,
-    const gl::DrawCallParams &drawCallParams,
+    gl::PrimitiveMode mode,
+    GLsizei vertexCount,
+    GLsizei instances,
     const d3d11::InputLayout **inputLayoutOut)
 {
     gl::Program *program         = state.getProgram();
@@ -131,7 +133,7 @@
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
     bool instancedPointSpritesActive =
-        programUsesInstancedPointSprites && (drawCallParams.mode() == gl::PrimitiveMode::Points);
+        programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points);
 
     if (programUsesInstancedPointSprites)
     {
@@ -143,7 +145,7 @@
         layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE;
     }
 
-    if (drawCallParams.instances() > 0)
+    if (instances > 0)
     {
         layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE;
     }
@@ -183,8 +185,8 @@
             angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache);
 
             d3d11::InputLayout newInputLayout;
-            ANGLE_TRY(createInputLayout(context11, sortedSemanticIndices, currentAttributes,
-                                        program, drawCallParams, &newInputLayout));
+            ANGLE_TRY(createInputLayout(context11, sortedSemanticIndices, currentAttributes, mode,
+                                        vertexCount, instances, &newInputLayout));
 
             auto insertIt   = mLayoutCache.Put(layout, std::move(newInputLayout));
             *inputLayoutOut = &insertIt->second;
@@ -198,13 +200,14 @@
     Context11 *context11,
     const AttribIndexArray &sortedSemanticIndices,
     const std::vector<const TranslatedAttribute *> &currentAttributes,
-    gl::Program *program,
-    const gl::DrawCallParams &drawCallParams,
+    gl::PrimitiveMode mode,
+    GLsizei vertexCount,
+    GLsizei instances,
     d3d11::InputLayout *inputLayoutOut)
 {
-    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
     Renderer11 *renderer   = context11->getRenderer();
-    auto featureLevel      = renderer->getRenderer11DeviceCaps().featureLevel;
+    ProgramD3D *programD3D         = renderer->getStateManager()->getProgramD3D();
+    D3D_FEATURE_LEVEL featureLevel = renderer->getRenderer11DeviceCaps().featureLevel;
 
     bool programUsesInstancedPointSprites =
         programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
@@ -251,18 +254,18 @@
         // simultaneously, so a non-instanced element must exist.
 
         UINT numIndicesPerInstance = 0;
-        if (drawCallParams.instances() > 0)
+        if (instances > 0)
         {
             // This requires that the index range is resolved.
             // Note: Vertex indexes can be arbitrarily large.
-            numIndicesPerInstance = drawCallParams.getClampedVertexCount<UINT>();
+            numIndicesPerInstance = gl::clampCast<UINT>(vertexCount);
         }
 
         for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex)
         {
             // If rendering points and instanced pointsprite emulation is being used, the
             // inputClass is required to be configured as per instance data
-            if (drawCallParams.mode() == gl::PrimitiveMode::Points)
+            if (mode == gl::PrimitiveMode::Points)
             {
                 inputElements[elementIndex].InputSlotClass       = D3D11_INPUT_PER_INSTANCE_DATA;
                 inputElements[elementIndex].InstanceDataStepRate = 1;
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
index 7914667..25cfcdd 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -93,7 +93,9 @@
                                  const gl::State &state,
                                  const std::vector<const TranslatedAttribute *> &currentAttributes,
                                  const AttribIndexArray &sortedSemanticIndices,
-                                 const gl::DrawCallParams &drawCallParams,
+                                 gl::PrimitiveMode mode,
+                                 GLsizei vertexCount,
+                                 GLsizei instances,
                                  const d3d11::InputLayout **inputLayoutOut);
 
   private:
@@ -101,8 +103,9 @@
         Context11 *context11,
         const AttribIndexArray &sortedSemanticIndices,
         const std::vector<const TranslatedAttribute *> &currentAttributes,
-        gl::Program *program,
-        const gl::DrawCallParams &drawCallParams,
+        gl::PrimitiveMode mode,
+        GLsizei vertexCount,
+        GLsizei instances,
         d3d11::InputLayout *inputLayoutOut);
 
     // Starting cache size.
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index df740c4..d0a0000 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -1447,7 +1447,11 @@
     return angle::Result::Continue();
 }
 
-angle::Result Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallParams &params)
+angle::Result Renderer11::drawArrays(const gl::Context *context,
+                                     gl::PrimitiveMode mode,
+                                     GLint firstVertex,
+                                     GLsizei vertexCount,
+                                     GLsizei instanceCount)
 {
     if (mStateManager.getCullEverything())
     {
@@ -1455,25 +1459,24 @@
     }
 
     ProgramD3D *programD3D        = mStateManager.getProgramD3D();
-    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, params.instances());
+    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount);
 
     // Note: vertex indexes can be arbitrarily large.
-    UINT clampedVertexCount = params.getClampedVertexCount<UINT>();
+    UINT clampedVertexCount = gl::GetClampedVertexCount<UINT>(vertexCount);
 
     const auto &glState = context->getGLState();
     if (glState.getCurrentTransformFeedback() && glState.isTransformFeedbackActiveUnpaused())
     {
         ANGLE_TRY(markTransformFeedbackUsage(context));
 
-        if (programD3D->usesGeometryShader(params.mode()))
+        if (programD3D->usesGeometryShader(mode))
         {
-            return drawWithGeometryShaderAndTransformFeedback(GetImplAs<Context11>(context),
-                                                              params.mode(), adjustedInstanceCount,
-                                                              clampedVertexCount);
+            return drawWithGeometryShaderAndTransformFeedback(
+                GetImplAs<Context11>(context), mode, adjustedInstanceCount, clampedVertexCount);
         }
     }
 
-    switch (params.mode())
+    switch (mode)
     {
         case gl::PrimitiveMode::LineLoop:
             return drawLineLoop(context, clampedVertexCount, GL_NONE, nullptr, 0,
@@ -1502,10 +1505,10 @@
                 // calculated and applied on each iteration to ensure all instances are rendered
                 // correctly. Each instance being rendered requires the inputlayout cache to reapply
                 // buffers and offsets.
-                for (GLsizei i = 0; i < params.instances(); i++)
+                for (GLsizei i = 0; i < instanceCount; i++)
                 {
                     ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(
-                        context, params.baseVertex(), i));
+                        context, firstVertex, i));
                     mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
                 }
 
@@ -1532,8 +1535,12 @@
 }
 
 angle::Result Renderer11::drawElements(const gl::Context *context,
-                                       const gl::DrawCallParams &params,
-                                       GLint startVertex)
+                                       gl::PrimitiveMode mode,
+                                       GLint startVertex,
+                                       GLsizei indexCount,
+                                       GLenum indexType,
+                                       const void *indices,
+                                       GLsizei instanceCount)
 {
     if (mStateManager.getCullEverything())
     {
@@ -1542,7 +1549,7 @@
 
     // Transform feedback is not allowed for DrawElements, this error should have been caught at the
     // API validation layer.
-    const auto &glState = context->getGLState();
+    const gl::State &glState = context->getGLState();
     ASSERT(!glState.isTransformFeedbackActiveUnpaused());
 
     // If this draw call is coming from an indirect call, offset by the indirect call's base vertex.
@@ -1550,31 +1557,30 @@
     int baseVertex = -startVertex;
 
     const ProgramD3D *programD3D  = mStateManager.getProgramD3D();
-    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, params.instances());
+    GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount);
 
-    if (params.mode() == gl::PrimitiveMode::LineLoop)
+    if (mode == gl::PrimitiveMode::LineLoop)
     {
-        return drawLineLoop(context, params.indexCount(), params.type(), params.indices(),
-                            baseVertex, adjustedInstanceCount);
+        return drawLineLoop(context, indexCount, indexType, indices, baseVertex,
+                            adjustedInstanceCount);
     }
 
-    if (params.mode() == gl::PrimitiveMode::TriangleFan)
+    if (mode == gl::PrimitiveMode::TriangleFan)
     {
-        return drawTriangleFan(context, params.indexCount(), params.type(), params.indices(),
-                               baseVertex, adjustedInstanceCount);
+        return drawTriangleFan(context, indexCount, indexType, indices, baseVertex,
+                               adjustedInstanceCount);
     }
 
-    if (params.mode() != gl::PrimitiveMode::Points ||
-        !programD3D->usesInstancedPointSpriteEmulation())
+    if (mode != gl::PrimitiveMode::Points || !programD3D->usesInstancedPointSpriteEmulation())
     {
         if (adjustedInstanceCount == 0)
         {
-            mDeviceContext->DrawIndexed(params.indexCount(), 0, baseVertex);
+            mDeviceContext->DrawIndexed(indexCount, 0, baseVertex);
         }
         else
         {
-            mDeviceContext->DrawIndexedInstanced(params.indexCount(), adjustedInstanceCount, 0,
-                                                 baseVertex, 0);
+            mDeviceContext->DrawIndexedInstanced(indexCount, adjustedInstanceCount, 0, baseVertex,
+                                                 0);
         }
         return angle::Result::Continue();
     }
@@ -1592,9 +1598,9 @@
     // Indexed pointsprite emulation replicates data for duplicate entries found in the index
     // buffer. This is not an efficent rendering mechanism and is only used on downlevel renderers
     // that do not support geometry shaders.
-    if (params.instances() == 0)
+    if (instanceCount == 0)
     {
-        mDeviceContext->DrawIndexedInstanced(6, params.indexCount(), 0, 0, 0);
+        mDeviceContext->DrawIndexedInstanced(6, indexCount, 0, 0, 0);
         return angle::Result::Continue();
     }
 
@@ -1603,13 +1609,13 @@
     // batch of points. An offset into the instanced data buffer is calculated and applied on each
     // iteration to ensure all instances are rendered correctly.
     gl::IndexRange indexRange;
-    ANGLE_TRY(glState.getVertexArray()->getIndexRange(context, params.type(), params.indexCount(),
-                                                      params.indices(), &indexRange));
+    ANGLE_TRY(glState.getVertexArray()->getIndexRange(context, indexType, indexCount, indices,
+                                                      &indexRange));
 
     UINT clampedVertexCount = gl::clampCast<UINT>(indexRange.vertexCount());
 
     // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets.
-    for (GLsizei i = 0; i < params.instances(); i++)
+    for (GLsizei i = 0; i < instanceCount; i++)
     {
         ANGLE_TRY(
             mStateManager.updateVertexOffsetsForPointSpritesEmulation(context, startVertex, i));
@@ -1619,8 +1625,7 @@
     return angle::Result::Continue();
 }
 
-angle::Result Renderer11::drawArraysIndirect(const gl::Context *context,
-                                             const gl::DrawCallParams &params)
+angle::Result Renderer11::drawArraysIndirect(const gl::Context *context, const void *indirect)
 {
     if (mStateManager.getCullEverything())
     {
@@ -1634,7 +1639,7 @@
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
 
-    uintptr_t offset = reinterpret_cast<uintptr_t>(params.indirect());
+    uintptr_t offset = reinterpret_cast<uintptr_t>(indirect);
 
     ID3D11Buffer *buffer = nullptr;
     ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
@@ -1642,8 +1647,7 @@
     return angle::Result::Continue();
 }
 
-angle::Result Renderer11::drawElementsIndirect(const gl::Context *context,
-                                               const gl::DrawCallParams &params)
+angle::Result Renderer11::drawElementsIndirect(const gl::Context *context, const void *indirect)
 {
     if (mStateManager.getCullEverything())
     {
@@ -1656,7 +1660,7 @@
     gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
     ASSERT(drawIndirectBuffer);
     Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
-    uintptr_t offset  = reinterpret_cast<uintptr_t>(params.indirect());
+    uintptr_t offset  = reinterpret_cast<uintptr_t>(indirect);
 
     ID3D11Buffer *buffer = nullptr;
     ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index d85e028..dca91c2 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -399,13 +399,20 @@
 
     DeviceImpl *createEGLDevice() override;
 
-    angle::Result drawArrays(const gl::Context *context, const gl::DrawCallParams &params);
+    angle::Result drawArrays(const gl::Context *context,
+                             gl::PrimitiveMode mode,
+                             GLint firstVertex,
+                             GLsizei vertexCount,
+                             GLsizei instanceCount);
     angle::Result drawElements(const gl::Context *context,
-                               const gl::DrawCallParams &params,
-                               GLint startVertex);
-    angle::Result drawArraysIndirect(const gl::Context *context, const gl::DrawCallParams &params);
-    angle::Result drawElementsIndirect(const gl::Context *context,
-                                       const gl::DrawCallParams &params);
+                               gl::PrimitiveMode mode,
+                               GLint startVertex,
+                               GLsizei indexCount,
+                               GLenum indexType,
+                               const void *indices,
+                               GLsizei instanceCount);
+    angle::Result drawArraysIndirect(const gl::Context *context, const void *indirect);
+    angle::Result drawElementsIndirect(const gl::Context *context, const void *indirect);
 
     // Necessary hack for default framebuffers in D3D.
     FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
index 025fdb8..e3737e9 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -1258,11 +1258,11 @@
 }
 
 angle::Result StateManager11::syncRasterizerState(const gl::Context *context,
-                                                  const gl::DrawCallParams &drawCallParams)
+                                                  gl::PrimitiveMode mode)
 {
     // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
     gl::RasterizerState rasterState = context->getGLState().getRasterizerState();
-    rasterState.pointDrawMode       = (drawCallParams.mode() == gl::PrimitiveMode::Points);
+    rasterState.pointDrawMode       = (mode == gl::PrimitiveMode::Points);
     rasterState.multiSample         = mCurRasterState.multiSample;
 
     ID3D11RasterizerState *dxRasterState = nullptr;
@@ -2055,8 +2055,13 @@
 }
 
 angle::Result StateManager11::updateState(const gl::Context *context,
-                                          const gl::DrawCallParams &drawCallParams,
-                                          GLint firstVertex)
+                                          gl::PrimitiveMode mode,
+                                          GLint firstVertex,
+                                          GLsizei vertexOrIndexCount,
+                                          GLenum indexTypeOrNone,
+                                          const void *indices,
+                                          GLsizei instanceCount,
+                                          GLint baseVertex)
 {
     const gl::State &glState = context->getGLState();
 
@@ -2098,7 +2103,9 @@
         mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
     }
 
-    ANGLE_TRY(mVertexArray11->syncStateForDraw(context, drawCallParams));
+    ANGLE_TRY(mVertexArray11->syncStateForDraw(context, firstVertex, vertexOrIndexCount,
+                                               indexTypeOrNone, indices, instanceCount,
+                                               baseVertex));
 
     // Changes in the draw call can affect the vertex buffer translations.
     if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != firstVertex)
@@ -2107,17 +2114,17 @@
         invalidateInputLayout();
     }
 
-    if (drawCallParams.isDrawElements())
+    if (indexTypeOrNone != GL_NONE)
     {
-        ANGLE_TRY(applyIndexBuffer(context, drawCallParams));
+        ANGLE_TRY(applyIndexBuffer(context, vertexOrIndexCount, indexTypeOrNone, indices));
     }
 
-    if (mLastAppliedDrawMode != drawCallParams.mode())
+    if (mLastAppliedDrawMode != mode)
     {
-        mLastAppliedDrawMode = drawCallParams.mode();
+        mLastAppliedDrawMode = mode;
         mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
 
-        bool pointDrawMode = (drawCallParams.mode() == gl::PrimitiveMode::Points);
+        bool pointDrawMode = (mode == gl::PrimitiveMode::Points);
         if (pointDrawMode != mCurRasterState.pointDrawMode)
         {
             mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
@@ -2144,7 +2151,7 @@
                 syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
                 break;
             case DIRTY_BIT_RASTERIZER_STATE:
-                ANGLE_TRY(syncRasterizerState(context, drawCallParams));
+                ANGLE_TRY(syncRasterizerState(context, mode));
                 break;
             case DIRTY_BIT_BLEND_STATE:
                 ANGLE_TRY(syncBlendState(context, glState.getBlendState(), glState.getBlendColor(),
@@ -2174,7 +2181,7 @@
                 // TODO(jie.a.chen@intel.com): http://anglebug.com/1951
                 break;
             case DIRTY_BIT_SHADERS:
-                ANGLE_TRY(syncProgram(context, drawCallParams.mode()));
+                ANGLE_TRY(syncProgram(context, mode));
                 break;
             case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
                 ANGLE_TRY(syncCurrentValueAttribs(context, glState.getVertexAttribCurrentValues()));
@@ -2183,10 +2190,12 @@
                 ANGLE_TRY(syncTransformFeedbackBuffers(context));
                 break;
             case DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT:
-                ANGLE_TRY(syncVertexBuffersAndInputLayout(context, drawCallParams, firstVertex));
+                ANGLE_TRY(syncVertexBuffersAndInputLayout(context, mode, firstVertex,
+                                                          vertexOrIndexCount, indexTypeOrNone,
+                                                          instanceCount));
                 break;
             case DIRTY_BIT_PRIMITIVE_TOPOLOGY:
-                syncPrimitiveTopology(glState, drawCallParams.mode());
+                syncPrimitiveTopology(glState, mode);
                 break;
             default:
                 UNREACHABLE();
@@ -2799,10 +2808,12 @@
     return angle::Result::Continue();
 }
 
-angle::Result StateManager11::syncVertexBuffersAndInputLayout(
-    const gl::Context *context,
-    const gl::DrawCallParams &drawCallParams,
-    GLint firstVertex)
+angle::Result StateManager11::syncVertexBuffersAndInputLayout(const gl::Context *context,
+                                                              gl::PrimitiveMode mode,
+                                                              GLint firstVertex,
+                                                              GLsizei vertexOrIndexCount,
+                                                              GLenum indexTypeOrNone,
+                                                              GLsizei instanceCount)
 {
     const auto &vertexArrayAttribs = mVertexArray11->getTranslatedAttribs();
 
@@ -2832,24 +2843,25 @@
     const gl::State &state                = context->getGLState();
     const d3d11::InputLayout *inputLayout = nullptr;
     ANGLE_TRY(mInputLayoutCache.getInputLayout(GetImplAs<Context11>(context), state,
-                                               mCurrentAttributes, sortedSemanticIndices,
-                                               drawCallParams, &inputLayout));
+                                               mCurrentAttributes, sortedSemanticIndices, mode,
+                                               vertexOrIndexCount, instanceCount, &inputLayout));
     setInputLayoutInternal(inputLayout);
 
     // Update the applied vertex buffers.
-    ANGLE_TRY(applyVertexBuffers(context, drawCallParams, firstVertex));
+    ANGLE_TRY(applyVertexBuffers(context, mode, indexTypeOrNone, firstVertex));
 
     return angle::Result::Continue();
 }
 
 angle::Result StateManager11::applyVertexBuffers(const gl::Context *context,
-                                                 const gl::DrawCallParams &drawCallParams,
+                                                 gl::PrimitiveMode mode,
+                                                 GLenum indexTypeOrNone,
                                                  GLint firstVertex)
 {
     bool programUsesInstancedPointSprites =
         mProgramD3D->usesPointSize() && mProgramD3D->usesInstancedPointSpriteEmulation();
     bool instancedPointSpritesActive =
-        programUsesInstancedPointSprites && (drawCallParams.mode() == gl::PrimitiveMode::Points);
+        programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points);
 
     // Note that if we use instance emulation, we reserve the first buffer slot.
     size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
@@ -2876,7 +2888,7 @@
                 ASSERT(attrib.vertexBuffer.get());
                 buffer = GetAs<VertexBuffer11>(attrib.vertexBuffer.get())->getBuffer().get();
             }
-            else if (instancedPointSpritesActive && drawCallParams.isDrawElements())
+            else if (instancedPointSpritesActive && indexTypeOrNone != GL_NONE)
             {
                 ASSERT(mVertexArray11->isCachedIndexInfoValid());
                 TranslatedIndexData indexInfo = mVertexArray11->getCachedIndexInfo();
@@ -2990,7 +3002,9 @@
 }
 
 angle::Result StateManager11::applyIndexBuffer(const gl::Context *context,
-                                               const gl::DrawCallParams &params)
+                                               GLsizei indexCount,
+                                               GLenum indexType,
+                                               const void *indices)
 {
     if (!mIndexBufferIsDirty)
     {
@@ -3002,9 +3016,8 @@
     gl::Buffer *elementArrayBuffer = mVertexArray11->getState().getElementArrayBuffer();
 
     TranslatedIndexData indexInfo;
-    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, params.type(), destElementType,
-                                                 params.indexCount(), elementArrayBuffer,
-                                                 params.indices(), &indexInfo));
+    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, indexType, destElementType, indexCount,
+                                                 elementArrayBuffer, indices, &indexInfo));
 
     ID3D11Buffer *buffer = nullptr;
     DXGI_FORMAT bufferFormat =
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
index 23ad5cb..76ae14c 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -212,8 +212,13 @@
     void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset);
 
     angle::Result updateState(const gl::Context *context,
-                              const gl::DrawCallParams &drawCallParams,
-                              GLint firstVertex);
+                              gl::PrimitiveMode mode,
+                              GLint firstVertex,
+                              GLsizei vertexOrIndexCount,
+                              GLenum indexTypeOrNone,
+                              const void *indices,
+                              GLsizei instanceCount,
+                              GLint baseVertex);
 
     void setShaderResourceShared(gl::ShaderType shaderType,
                                  UINT resourceSlot,
@@ -285,8 +290,7 @@
 
     angle::Result syncDepthStencilState(const gl::Context *context);
 
-    angle::Result syncRasterizerState(const gl::Context *context,
-                                      const gl::DrawCallParams &drawCallParams);
+    angle::Result syncRasterizerState(const gl::Context *context, gl::PrimitiveMode mode);
 
     void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled);
 
@@ -361,13 +365,17 @@
 
     bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
     angle::Result syncVertexBuffersAndInputLayout(const gl::Context *context,
-                                                  const gl::DrawCallParams &vertexParams,
-                                                  GLint firstVertex);
+                                                  gl::PrimitiveMode mode,
+                                                  GLint firstVertex,
+                                                  GLsizei vertexOrIndexCount,
+                                                  GLenum indexTypeOrNone,
+                                                  GLsizei instanceCount);
 
     bool setInputLayoutInternal(const d3d11::InputLayout *inputLayout);
 
     angle::Result applyVertexBuffers(const gl::Context *context,
-                                     const gl::DrawCallParams &drawCallParams,
+                                     gl::PrimitiveMode mode,
+                                     GLenum indexTypeOrNone,
                                      GLint firstVertex);
     // TODO(jmadill): Migrate to d3d11::Buffer.
     bool queueVertexBufferChange(size_t bufferIndex,
@@ -380,7 +388,9 @@
 
     // Not handled by an internal dirty bit because it isn't synced on drawArrays calls.
     angle::Result applyIndexBuffer(const gl::Context *context,
-                                   const gl::DrawCallParams &drawCallParams);
+                                   GLsizei indexCount,
+                                   GLenum indexType,
+                                   const void *indices);
 
     enum DirtyBitType
     {
diff --git a/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp b/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
index 8921b49..7f18eea 100644
--- a/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
@@ -125,7 +125,12 @@
 }
 
 angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
-                                              const gl::DrawCallParams &drawCallParams)
+                                              GLint firstVertex,
+                                              GLsizei vertexOrIndexCount,
+                                              GLenum indexTypeOrNone,
+                                              const void *indices,
+                                              GLsizei instances,
+                                              GLint baseVertex)
 {
     Renderer11 *renderer         = GetImplAs<Context11>(context)->getRenderer();
     StateManager11 *stateManager = renderer->getStateManager();
@@ -156,24 +161,25 @@
         if (activeDynamicAttribs.any())
         {
             ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(),
-                                           drawCallParams, activeDynamicAttribs));
+                                           firstVertex, vertexOrIndexCount, indexTypeOrNone,
+                                           indices, instances, baseVertex, activeDynamicAttribs));
             stateManager->invalidateInputLayout();
         }
     }
 
-    if (drawCallParams.isDrawElements())
+    if (indexTypeOrNone != GL_NONE)
     {
         bool restartEnabled = context->getGLState().isPrimitiveRestartEnabled();
-        if (!mLastDrawElementsType.valid() ||
-            mLastDrawElementsType.value() != drawCallParams.type() ||
-            mLastDrawElementsIndices.value() != drawCallParams.indices() ||
+        if (!mLastDrawElementsType.valid() || mLastDrawElementsType.value() != indexTypeOrNone ||
+            mLastDrawElementsIndices.value() != indices ||
             mLastPrimitiveRestartEnabled.value() != restartEnabled)
         {
-            mLastDrawElementsType        = drawCallParams.type();
-            mLastDrawElementsIndices     = drawCallParams.indices();
+            mLastDrawElementsType        = indexTypeOrNone;
+            mLastDrawElementsIndices     = indices;
             mLastPrimitiveRestartEnabled = restartEnabled;
 
-            ANGLE_TRY(updateElementArrayStorage(context, drawCallParams, restartEnabled));
+            ANGLE_TRY(updateElementArrayStorage(context, vertexOrIndexCount, indexTypeOrNone,
+                                                indices, restartEnabled));
             stateManager->invalidateIndexBuffer();
         }
         else if (mCurrentElementArrayStorage == IndexStorageType::Dynamic)
@@ -186,21 +192,22 @@
 }
 
 angle::Result VertexArray11::updateElementArrayStorage(const gl::Context *context,
-                                                       const gl::DrawCallParams &drawCallParams,
+                                                       GLsizei indexCount,
+                                                       GLenum indexType,
+                                                       const void *indices,
                                                        bool restartEnabled)
 {
-    bool usePrimitiveRestartWorkaround =
-        UsePrimitiveRestartWorkaround(restartEnabled, drawCallParams.type());
+    bool usePrimitiveRestartWorkaround = UsePrimitiveRestartWorkaround(restartEnabled, indexType);
 
-    ANGLE_TRY(GetIndexTranslationDestType(context, drawCallParams, usePrimitiveRestartWorkaround,
+    ANGLE_TRY(GetIndexTranslationDestType(context, indexCount, indexType, indices,
+                                          usePrimitiveRestartWorkaround,
                                           &mCachedDestinationIndexType));
 
-    unsigned int offset =
-        static_cast<unsigned int>(reinterpret_cast<uintptr_t>(drawCallParams.indices()));
+    unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
 
     mCurrentElementArrayStorage =
-        ClassifyIndexStorage(context->getGLState(), mState.getElementArrayBuffer(),
-                             drawCallParams.type(), mCachedDestinationIndexType, offset);
+        ClassifyIndexStorage(context->getGLState(), mState.getElementArrayBuffer(), indexType,
+                             mCachedDestinationIndexType, offset);
 
     return angle::Result::Continue();
 }
@@ -282,7 +289,12 @@
 
 angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
                                                   VertexDataManager *vertexDataManager,
-                                                  const gl::DrawCallParams &drawCallParams,
+                                                  GLint firstVertex,
+                                                  GLsizei vertexOrIndexCount,
+                                                  GLenum indexTypeOrNone,
+                                                  const void *indices,
+                                                  GLsizei instances,
+                                                  GLint baseVertex,
                                                   const gl::AttributesMask &activeDynamicAttribs)
 {
     const auto &glState  = context->getGLState();
@@ -291,12 +303,8 @@
 
     GLint startVertex;
     size_t vertexCount;
-    GLsizei vertexOrIndexCount = drawCallParams.isDrawElements() ? drawCallParams.indexCount()
-                                                                 : drawCallParams.vertexCount();
-    GLenum indexTypeOrNone = drawCallParams.isDrawElements() ? drawCallParams.type() : GL_NONE;
-    ANGLE_TRY(GetVertexRangeInfo(context, drawCallParams.firstVertex(), vertexOrIndexCount,
-                                 indexTypeOrNone, drawCallParams.indices(),
-                                 drawCallParams.baseVertex(), &startVertex, &vertexCount));
+    ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrNone, indices,
+                                 baseVertex, &startVertex, &vertexCount));
 
     for (size_t dynamicAttribIndex : activeDynamicAttribs)
     {
@@ -310,9 +318,8 @@
         dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
     }
 
-    ANGLE_TRY(vertexDataManager->storeDynamicAttribs(context, &mTranslatedAttribs,
-                                                     activeDynamicAttribs, startVertex, vertexCount,
-                                                     drawCallParams.instances()));
+    ANGLE_TRY(vertexDataManager->storeDynamicAttribs(
+        context, &mTranslatedAttribs, activeDynamicAttribs, startVertex, vertexCount, instances));
 
     VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
                                              vertexCount);
diff --git a/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
index 54ccc02..8bdd617 100644
--- a/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -26,7 +26,7 @@
     void destroy(const gl::Context *context) override;
 
     // Does not apply any state updates - these are done in syncStateForDraw which as access to
-    // the DrawCallParams before a draw.
+    // the draw call parameters.
     angle::Result syncState(const gl::Context *context,
                             const gl::VertexArray::DirtyBits &dirtyBits,
                             const gl::VertexArray::DirtyAttribBitsArray &attribBits,
@@ -34,7 +34,12 @@
 
     // Applied buffer pointers are updated here.
     angle::Result syncStateForDraw(const gl::Context *context,
-                                   const gl::DrawCallParams &drawCallParams);
+                                   GLint firstVertex,
+                                   GLsizei vertexOrIndexCount,
+                                   GLenum indexTypeOrNone,
+                                   const void *indices,
+                                   GLsizei instances,
+                                   GLint baseVertex);
 
     // This will check the dynamic attribs mask.
     bool hasActiveDynamicAttrib(const gl::Context *context);
@@ -61,11 +66,18 @@
                                      const gl::AttributesMask &activeDirtyAttribs);
     angle::Result updateDynamicAttribs(const gl::Context *context,
                                        VertexDataManager *vertexDataManager,
-                                       const gl::DrawCallParams &drawCallParams,
+                                       GLint firstVertex,
+                                       GLsizei vertexOrIndexCount,
+                                       GLenum indexTypeOrNone,
+                                       const void *indices,
+                                       GLsizei instances,
+                                       GLint baseVertex,
                                        const gl::AttributesMask &activeDynamicAttribs);
 
     angle::Result updateElementArrayStorage(const gl::Context *context,
-                                            const gl::DrawCallParams &drawCallParams,
+                                            GLsizei indexCount,
+                                            GLenum indexType,
+                                            const void *indices,
                                             bool restartEnabled);
 
     std::vector<VertexStorageType> mAttributeStorageTypes;
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index ad17820..8315974 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -1304,10 +1304,9 @@
 {
     gl::VertexArray *vao                     = context->getGLState().getVertexArray();
     gl::Buffer *elementArrayBuffer           = vao->getElementArrayBuffer();
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
 
     GLenum dstType = GL_NONE;
-    ANGLE_TRY(GetIndexTranslationDestType(context, drawCallParams, false, &dstType));
+    ANGLE_TRY(GetIndexTranslationDestType(context, count, type, indices, false, &dstType));
 
     ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer,
                                                   indices, indexInfo));
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 66a6005..09573d0 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -232,7 +232,7 @@
     return mRenderer->finish(this);
 }
 
-angle::Result ContextVk::initPipeline(const gl::DrawCallParams &drawCallParams)
+angle::Result ContextVk::initPipeline()
 {
     ASSERT(!mCurrentPipeline);
 
@@ -252,7 +252,7 @@
     const vk::ShaderAndSerial *vertexShaderAndSerial   = nullptr;
     const vk::ShaderAndSerial *fragmentShaderAndSerial = nullptr;
     const vk::PipelineLayout *pipelineLayout           = nullptr;
-    ANGLE_TRY(mProgram->initShaders(this, drawCallParams, &vertexShaderAndSerial,
+    ANGLE_TRY(mProgram->initShaders(this, mCurrentDrawMode, &vertexShaderAndSerial,
                                     &fragmentShaderAndSerial, &pipelineLayout));
 
     mPipelineDesc->updateShaders(vertexShaderAndSerial->getSerial(),
@@ -266,16 +266,20 @@
 }
 
 angle::Result ContextVk::setupDraw(const gl::Context *context,
-                                   const gl::DrawCallParams &drawCallParams,
+                                   gl::PrimitiveMode mode,
+                                   GLint firstVertex,
+                                   GLsizei vertexOrIndexCount,
+                                   GLenum indexTypeOrNone,
+                                   const void *indices,
                                    DirtyBits dirtyBitMask,
                                    vk::CommandBuffer **commandBufferOut)
 {
     // Set any dirty bits that depend on draw call parameters or other objects.
-    if (drawCallParams.mode() != mCurrentDrawMode)
+    if (mode != mCurrentDrawMode)
     {
         mCurrentPipeline = nullptr;
         mDirtyBits.set(DIRTY_BIT_PIPELINE);
-        mCurrentDrawMode = drawCallParams.mode();
+        mCurrentDrawMode = mode;
     }
 
     if (!mDrawFramebuffer->appendToStartedRenderPass(mRenderer, commandBufferOut))
@@ -286,7 +290,8 @@
 
     if (context->getStateCache().hasAnyActiveClientAttrib())
     {
-        ANGLE_TRY(mVertexArray->updateClientAttribs(context, drawCallParams));
+        ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertex, vertexOrIndexCount,
+                                                    indexTypeOrNone, indices));
         mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
     }
 
@@ -305,59 +310,67 @@
     for (size_t dirtyBit : dirtyBits)
     {
         mDirtyBits.reset(dirtyBit);
-        ANGLE_TRY((this->*mDirtyBitHandlers[dirtyBit])(context, drawCallParams, *commandBufferOut));
+        ANGLE_TRY((this->*mDirtyBitHandlers[dirtyBit])(context, *commandBufferOut));
     }
 
     return angle::Result::Continue();
 }
 
 angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
-                                          const gl::DrawCallParams &drawCallParams,
+                                          gl::PrimitiveMode mode,
+                                          GLsizei indexCount,
+                                          GLenum indexType,
+                                          const void *indices,
                                           vk::CommandBuffer **commandBufferOut)
 {
-    if (drawCallParams.type() != mCurrentDrawElementsType)
+    if (indexType != mCurrentDrawElementsType)
     {
         mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
-        mCurrentDrawElementsType = drawCallParams.type();
+        mCurrentDrawElementsType = indexType;
     }
 
     const gl::Buffer *elementArrayBuffer = mVertexArray->getState().getElementArrayBuffer();
     if (!elementArrayBuffer)
     {
         mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
-        ANGLE_TRY(mVertexArray->updateIndexTranslation(this, drawCallParams));
+        ANGLE_TRY(mVertexArray->updateIndexTranslation(this, indexCount, indexType, indices));
     }
     else
     {
-        if (drawCallParams.indices() != mLastIndexBufferOffset)
+        if (indices != mLastIndexBufferOffset)
         {
             mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
-            mLastIndexBufferOffset = drawCallParams.indices();
+            mLastIndexBufferOffset = indices;
             mVertexArray->updateCurrentElementArrayBufferOffset(mLastIndexBufferOffset);
         }
 
-        if (drawCallParams.type() == GL_UNSIGNED_BYTE && mDirtyBits[DIRTY_BIT_INDEX_BUFFER])
+        if (indexType == GL_UNSIGNED_BYTE && mDirtyBits[DIRTY_BIT_INDEX_BUFFER])
         {
-            ANGLE_TRY(mVertexArray->updateIndexTranslation(this, drawCallParams));
+            ANGLE_TRY(mVertexArray->updateIndexTranslation(this, indexCount, indexType, indices));
         }
     }
 
-    return setupDraw(context, drawCallParams, mIndexedDirtyBitsMask, commandBufferOut);
+    return setupDraw(context, mode, 0, indexCount, indexType, indices, mIndexedDirtyBitsMask,
+                     commandBufferOut);
 }
 
 angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
-                                           const gl::DrawCallParams &drawCallParams,
+                                           gl::PrimitiveMode mode,
+                                           GLint firstVertex,
+                                           GLsizei vertexOrIndexCount,
+                                           GLenum indexTypeOrNone,
+                                           const void *indices,
                                            vk::CommandBuffer **commandBufferOut)
 {
-    ANGLE_TRY(mVertexArray->handleLineLoop(this, drawCallParams));
+    ANGLE_TRY(mVertexArray->handleLineLoop(this, firstVertex, vertexOrIndexCount, indexTypeOrNone,
+                                           indices));
     mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
-    mCurrentDrawElementsType =
-        drawCallParams.isDrawElements() ? drawCallParams.type() : GL_UNSIGNED_INT;
-    return setupDraw(context, drawCallParams, mIndexedDirtyBitsMask, commandBufferOut);
+    mCurrentDrawElementsType = indexTypeOrNone != GL_NONE ? indexTypeOrNone : GL_UNSIGNED_INT;
+    return setupDraw(context, mode, firstVertex, vertexOrIndexCount, indexTypeOrNone, indices,
+                     mIndexedDirtyBitsMask, commandBufferOut);
 }
 
 angle::Result ContextVk::handleDirtyDefaultAttribs(const gl::Context *context,
-                                                   const gl::DrawCallParams &drawCallParams,
                                                    vk::CommandBuffer *commandBuffer)
 {
     ASSERT(mDirtyDefaultAttribsMask.any());
@@ -372,12 +385,11 @@
 }
 
 angle::Result ContextVk::handleDirtyPipeline(const gl::Context *context,
-                                             const gl::DrawCallParams &drawCallParams,
                                              vk::CommandBuffer *commandBuffer)
 {
     if (!mCurrentPipeline)
     {
-        ANGLE_TRY(initPipeline(drawCallParams));
+        ANGLE_TRY(initPipeline());
     }
 
     commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
@@ -389,7 +401,6 @@
 }
 
 angle::Result ContextVk::handleDirtyTextures(const gl::Context *context,
-                                             const gl::DrawCallParams &drawCallParams,
                                              vk::CommandBuffer *commandBuffer)
 {
     ANGLE_TRY(updateActiveTextures(context));
@@ -411,7 +422,6 @@
 }
 
 angle::Result ContextVk::handleDirtyVertexBuffers(const gl::Context *context,
-                                                  const gl::DrawCallParams &drawCallParams,
                                                   vk::CommandBuffer *commandBuffer)
 {
     BindNonNullVertexBufferRanges(
@@ -431,7 +441,6 @@
 }
 
 angle::Result ContextVk::handleDirtyIndexBuffer(const gl::Context *context,
-                                                const gl::DrawCallParams &drawCallParams,
                                                 vk::CommandBuffer *commandBuffer)
 {
     commandBuffer->bindIndexBuffer(mVertexArray->getCurrentElementArrayBufferHandle(),
@@ -448,10 +457,9 @@
 }
 
 angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
-                                                   const gl::DrawCallParams &drawCallParams,
                                                    vk::CommandBuffer *commandBuffer)
 {
-    ANGLE_TRY(mProgram->updateDescriptorSets(this, drawCallParams, commandBuffer));
+    ANGLE_TRY(mProgram->updateDescriptorSets(this, commandBuffer));
 
     // Bind the graphics descriptor sets.
     commandBuffer->bindDescriptorSets(
@@ -465,19 +473,18 @@
                                     GLint first,
                                     GLsizei count)
 {
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-
     vk::CommandBuffer *commandBuffer = nullptr;
-    uint32_t clampedVertexCount      = drawCallParams.getClampedVertexCount<uint32_t>();
+    uint32_t clampedVertexCount      = gl::GetClampedVertexCount<uint32_t>(count);
 
     if (mode == gl::PrimitiveMode::LineLoop)
     {
-        ANGLE_TRY(setupLineLoopDraw(context, drawCallParams, &commandBuffer));
+        ANGLE_TRY(setupLineLoopDraw(context, mode, first, count, GL_NONE, nullptr, &commandBuffer));
         vk::LineLoopHelper::Draw(clampedVertexCount, commandBuffer);
     }
     else
     {
-        ANGLE_TRY(setupDraw(context, drawCallParams, mNonIndexedDirtyBitsMask, &commandBuffer));
+        ANGLE_TRY(setupDraw(context, mode, first, count, GL_NONE, nullptr, mNonIndexedDirtyBitsMask,
+                            &commandBuffer));
         commandBuffer->draw(clampedVertexCount, 1, first, 0);
     }
 
@@ -500,17 +507,15 @@
                                       GLenum type,
                                       const void *indices)
 {
-    const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
-
     vk::CommandBuffer *commandBuffer = nullptr;
     if (mode == gl::PrimitiveMode::LineLoop)
     {
-        ANGLE_TRY(setupLineLoopDraw(context, drawCallParams, &commandBuffer));
+        ANGLE_TRY(setupLineLoopDraw(context, mode, 0, count, type, indices, &commandBuffer));
         vk::LineLoopHelper::Draw(count, commandBuffer);
     }
     else
     {
-        ANGLE_TRY(setupIndexedDraw(context, drawCallParams, &commandBuffer));
+        ANGLE_TRY(setupIndexedDraw(context, mode, count, type, indices, &commandBuffer));
         commandBuffer->drawIndexed(count, 1, 0, 0, 0);
     }
 
@@ -1114,7 +1119,6 @@
 }
 
 angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context,
-                                                   const gl::DrawCallParams &drawCallParams,
                                                    vk::CommandBuffer *commandBuffer)
 {
     // Release any previously retained buffers.
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h
index 167a088..9c88260 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.h
+++ b/src/libANGLE/renderer/vulkan/ContextVk.h
@@ -197,21 +197,31 @@
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
 
     using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *,
-                                                         const gl::DrawCallParams &,
                                                          vk::CommandBuffer *commandBuffer);
 
     std::array<DirtyBitHandler, DIRTY_BIT_MAX> mDirtyBitHandlers;
 
-    angle::Result initPipeline(const gl::DrawCallParams &drawCallParams);
+    angle::Result initPipeline();
     angle::Result setupDraw(const gl::Context *context,
-                            const gl::DrawCallParams &drawCallParams,
+                            gl::PrimitiveMode mode,
+                            GLint firstVertex,
+                            GLsizei vertexOrIndexCount,
+                            GLenum indexTypeOrNone,
+                            const void *indices,
                             DirtyBits dirtyBitMask,
                             vk::CommandBuffer **commandBufferOut);
     angle::Result setupIndexedDraw(const gl::Context *context,
-                                   const gl::DrawCallParams &drawCallParams,
+                                   gl::PrimitiveMode mode,
+                                   GLsizei indexCount,
+                                   GLenum indexType,
+                                   const void *indices,
                                    vk::CommandBuffer **commandBufferOut);
     angle::Result setupLineLoopDraw(const gl::Context *context,
-                                    const gl::DrawCallParams &drawCallParams,
+                                    gl::PrimitiveMode mode,
+                                    GLint firstVertex,
+                                    GLsizei vertexOrIndexCount,
+                                    GLenum indexTypeOrNone,
+                                    const void *indices,
                                     vk::CommandBuffer **commandBufferOut);
 
     void updateScissor(const gl::State &glState) const;
@@ -225,25 +235,18 @@
     void invalidateDriverUniforms();
 
     angle::Result handleDirtyDefaultAttribs(const gl::Context *context,
-                                            const gl::DrawCallParams &drawCallParams,
                                             vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyPipeline(const gl::Context *context,
-                                      const gl::DrawCallParams &drawCallParams,
                                       vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyTextures(const gl::Context *context,
-                                      const gl::DrawCallParams &drawCallParams,
                                       vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyVertexBuffers(const gl::Context *context,
-                                           const gl::DrawCallParams &drawCallParams,
                                            vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyIndexBuffer(const gl::Context *context,
-                                         const gl::DrawCallParams &drawCallParams,
                                          vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyDriverUniforms(const gl::Context *context,
-                                            const gl::DrawCallParams &drawCallParams,
                                             vk::CommandBuffer *commandBuffer);
     angle::Result handleDirtyDescriptorSets(const gl::Context *context,
-                                            const gl::DrawCallParams &drawCallParams,
                                             vk::CommandBuffer *commandBuffer);
 
     vk::PipelineAndSerial *mCurrentPipeline;
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 2a26b97..705f634 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -131,10 +131,9 @@
     return angle::Result::Continue();
 }
 
-bool UseLineRaster(const ContextVk *contextVk, const gl::DrawCallParams &drawCallParams)
+bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
 {
-    return contextVk->getFeatures().basicGLLineRasterization &&
-           gl::IsLineMode(drawCallParams.mode());
+    return contextVk->getFeatures().basicGLLineRasterization && gl::IsLineMode(mode);
 }
 }  // anonymous namespace
 
@@ -742,12 +741,12 @@
 }
 
 angle::Result ProgramVk::initShaders(ContextVk *contextVk,
-                                     const gl::DrawCallParams &drawCallParams,
+                                     gl::PrimitiveMode mode,
                                      const vk::ShaderAndSerial **vertexShaderAndSerialOut,
                                      const vk::ShaderAndSerial **fragmentShaderAndSerialOut,
                                      const vk::PipelineLayout **pipelineLayoutOut)
 {
-    if (UseLineRaster(contextVk, drawCallParams))
+    if (UseLineRaster(contextVk, mode))
     {
         ANGLE_TRY(mLineRasterShaderInfo.getShaders(contextVk, mVertexSource, mFragmentSource, true,
                                                    vertexShaderAndSerialOut,
@@ -948,7 +947,6 @@
 }
 
 angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
-                                              const gl::DrawCallParams &drawCallParams,
                                               vk::CommandBuffer *commandBuffer)
 {
     // Can probably use better dirty bits here.
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.h b/src/libANGLE/renderer/vulkan/ProgramVk.h
index 4822c19..64b538d 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.h
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.h
@@ -97,7 +97,7 @@
 
     // Also initializes the pipeline layout, descriptor set layouts, and used descriptor ranges.
     angle::Result initShaders(ContextVk *contextVk,
-                              const gl::DrawCallParams &drawCallParams,
+                              gl::PrimitiveMode mode,
                               const vk::ShaderAndSerial **vertexShaderAndSerialOut,
                               const vk::ShaderAndSerial **fragmentShaderAndSerialOut,
                               const vk::PipelineLayout **pipelineLayoutOut);
@@ -106,7 +106,6 @@
     angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
 
     angle::Result updateDescriptorSets(ContextVk *contextVk,
-                                       const gl::DrawCallParams &drawCallParams,
                                        vk::CommandBuffer *commandBuffer);
 
     // For testing only.
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 9455035..387f9d5 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -10,7 +10,7 @@
 #include "libANGLE/renderer/vulkan/VertexArrayVk.h"
 
 #include "common/debug.h"
-
+#include "common/utilities.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/renderer/vulkan/BufferVk.h"
 #include "libANGLE/renderer/vulkan/CommandGraph.h"
@@ -431,7 +431,10 @@
 }
 
 angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
-                                                 const gl::DrawCallParams &drawCallParams)
+                                                 GLint firstVertex,
+                                                 GLsizei vertexOrIndexCount,
+                                                 GLenum indexTypeOrNone,
+                                                 const void *indices)
 {
     ContextVk *contextVk = vk::GetImpl(context);
     const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
@@ -440,12 +443,8 @@
 
     GLint startVertex;
     size_t vertexCount;
-    GLsizei vertexOrIndexCount = drawCallParams.isDrawElements() ? drawCallParams.indexCount()
-                                                                 : drawCallParams.vertexCount();
-    GLenum indexTypeOrNone = drawCallParams.isDrawElements() ? drawCallParams.type() : GL_NONE;
-    ANGLE_TRY(GetVertexRangeInfo(context, drawCallParams.firstVertex(), vertexOrIndexCount,
-                                 indexTypeOrNone, drawCallParams.indices(),
-                                 drawCallParams.baseVertex(), &startVertex, &vertexCount));
+    ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrNone, indices,
+                                 0, &startVertex, &vertexCount));
 
     mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
 
@@ -470,7 +469,7 @@
                kMaxVertexFormatAlignment);
 
         // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
-        // We allocate space for firstVertex() + vertexCount() so indexing will work.  If we
+        // We allocate space for startVertex + vertexCount so indexing will work.  If we
         // don't start at zero all the indices will be off.
         // TODO(fjhenigman): See if we can account for indices being off by adjusting the
         // offset, thus avoiding wasted memory.
@@ -484,9 +483,12 @@
 }
 
 angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
-                                            const gl::DrawCallParams &drawCallParams)
+                                            GLint firstVertex,
+                                            GLsizei vertexOrIndexCount,
+                                            GLenum indexTypeOrNone,
+                                            const void *indices)
 {
-    if (drawCallParams.isDrawElements())
+    if (indexTypeOrNone != GL_NONE)
     {
         // Handle GL_LINE_LOOP drawElements.
         if (mDirtyLineLoopTranslation)
@@ -496,19 +498,18 @@
             if (!elementArrayBuffer)
             {
                 ANGLE_TRY(mLineLoopHelper.streamIndices(
-                    contextVk, drawCallParams.type(), drawCallParams.indexCount(),
-                    reinterpret_cast<const uint8_t *>(drawCallParams.indices()),
-                    &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
+                    contextVk, indexTypeOrNone, vertexOrIndexCount,
+                    reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBufferHandle,
+                    &mCurrentElementArrayBufferOffset));
             }
             else
             {
                 // When using an element array buffer, 'indices' is an offset to the first element.
-                intptr_t offset = reinterpret_cast<intptr_t>(drawCallParams.indices());
+                intptr_t offset                = reinterpret_cast<intptr_t>(indices);
                 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
                 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
-                    contextVk, elementArrayBufferVk, drawCallParams.type(),
-                    drawCallParams.indexCount(), offset, &mCurrentElementArrayBufferHandle,
-                    &mCurrentElementArrayBufferOffset));
+                    contextVk, elementArrayBufferVk, indexTypeOrNone, vertexOrIndexCount, offset,
+                    &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
             }
         }
 
@@ -521,19 +522,18 @@
     }
 
     // Note: Vertex indexes can be arbitrarily large.
-    uint32_t clampedVertexCount = drawCallParams.getClampedVertexCount<uint32_t>();
+    uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
 
     // Handle GL_LINE_LOOP drawArrays.
-    size_t lastVertex = static_cast<size_t>(drawCallParams.firstVertex() + clampedVertexCount);
+    size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
     if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
-        mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
-        mLineLoopBufferLastIndex != lastVertex)
+        mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
     {
-        ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(contextVk, drawCallParams,
-                                                              &mCurrentElementArrayBufferHandle,
-                                                              &mCurrentElementArrayBufferOffset));
+        ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
+            contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBufferHandle,
+            &mCurrentElementArrayBufferOffset));
 
-        mLineLoopBufferFirstIndex = drawCallParams.firstVertex();
+        mLineLoopBufferFirstIndex = firstVertex;
         mLineLoopBufferLastIndex  = lastVertex;
     }
 
@@ -541,24 +541,24 @@
 }
 
 angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
-                                                    const gl::DrawCallParams &drawCallParams)
+                                                    GLsizei indexCount,
+                                                    GLenum type,
+                                                    const void *indices)
 {
-    ASSERT(drawCallParams.isDrawElements());
-    ASSERT(drawCallParams.mode() != gl::PrimitiveMode::LineLoop);
+    ASSERT(type != GL_NONE);
 
     gl::Buffer *glBuffer = mState.getElementArrayBuffer();
 
     if (!glBuffer)
     {
-        ANGLE_TRY(streamIndexData(contextVk, drawCallParams.type(), drawCallParams.indexCount(),
-                                  drawCallParams.indices(), &mDynamicIndexData));
+        ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
     }
     else
     {
         // Needed before reading buffer or we could get stale data.
         ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
 
-        ASSERT(drawCallParams.type() == GL_UNSIGNED_BYTE);
+        ASSERT(type == GL_UNSIGNED_BYTE);
         // Unsigned bytes don't have direct support in Vulkan so we have to expand the
         // memory to a GLushort.
         BufferVk *bufferVk   = vk::GetImpl(glBuffer);
@@ -566,10 +566,10 @@
         ASSERT(!glBuffer->isMapped());
         ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
         uint8_t *srcData           = static_cast<uint8_t *>(srcDataMapping);
-        intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(drawCallParams.indices());
+        intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
         srcData += offsetIntoSrcData;
 
-        ANGLE_TRY(streamIndexData(contextVk, drawCallParams.type(),
+        ANGLE_TRY(streamIndexData(contextVk, type,
                                   static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
                                   srcData, &mTranslatedByteIndexData));
 
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.h b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
index 2b828e8..57573fa 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.h
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
@@ -14,11 +14,6 @@
 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
 #include "libANGLE/renderer/vulkan/vk_helpers.h"
 
-namespace gl
-{
-class DrawCallParams;
-}  // namespace gl
-
 namespace rx
 {
 class BufferVk;
@@ -49,9 +44,16 @@
                              uint32_t offset);
 
     angle::Result updateClientAttribs(const gl::Context *context,
-                                      const gl::DrawCallParams &drawCallParams);
+                                      GLint firstVertex,
+                                      GLsizei vertexOrIndexCount,
+                                      GLenum indexTypeOrNone,
+                                      const void *indices);
 
-    angle::Result handleLineLoop(ContextVk *contextVk, const gl::DrawCallParams &drawCallParams);
+    angle::Result handleLineLoop(ContextVk *contextVk,
+                                 GLint firstVertex,
+                                 GLsizei vertexOrIndexCount,
+                                 GLenum indexTypeOrNone,
+                                 const void *indices);
 
     const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const
     {
@@ -86,7 +88,9 @@
     }
 
     angle::Result updateIndexTranslation(ContextVk *contextVk,
-                                         const gl::DrawCallParams &drawCallParams);
+                                         GLsizei indexCount,
+                                         GLenum type,
+                                         const void *indices);
 
   private:
     // This will update any dirty packed input descriptions, regardless if they're used by the
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 3a4adeb..886e654 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -7,11 +7,12 @@
 //   Helper utilitiy classes that manage Vulkan resources.
 
 #include "libANGLE/renderer/vulkan/vk_helpers.h"
-#include "libANGLE/renderer/vulkan/vk_utils.h"
 
+#include "common/utilities.h"
 #include "libANGLE/renderer/vulkan/BufferVk.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
+#include "libANGLE/renderer/vulkan/vk_utils.h"
 
 namespace rx
 {
@@ -714,22 +715,21 @@
 LineLoopHelper::~LineLoopHelper() = default;
 
 angle::Result LineLoopHelper::getIndexBufferForDrawArrays(ContextVk *contextVk,
-                                                          const gl::DrawCallParams &drawCallParams,
+                                                          uint32_t clampedVertexCount,
+                                                          GLint firstVertex,
                                                           VkBuffer *bufferHandleOut,
                                                           VkDeviceSize *offsetOut)
 {
     uint32_t *indices    = nullptr;
-    size_t allocateBytes = sizeof(uint32_t) * (drawCallParams.vertexCount() + 1);
+    size_t allocateBytes = sizeof(uint32_t) * (static_cast<size_t>(clampedVertexCount) + 1);
 
     mDynamicIndexBuffer.releaseRetainedBuffers(contextVk->getRenderer());
     ANGLE_TRY(mDynamicIndexBuffer.allocate(contextVk, allocateBytes,
                                            reinterpret_cast<uint8_t **>(&indices), bufferHandleOut,
                                            offsetOut, nullptr));
 
-    uint32_t clampedVertexCount = drawCallParams.getClampedVertexCount<uint32_t>();
-
     // Note: there could be an overflow in this addition.
-    uint32_t unsignedFirstVertex = static_cast<uint32_t>(drawCallParams.firstVertex());
+    uint32_t unsignedFirstVertex = static_cast<uint32_t>(firstVertex);
     uint32_t vertexCount         = (clampedVertexCount + unsignedFirstVertex);
     for (uint32_t vertexIndex = unsignedFirstVertex; vertexIndex < vertexCount; vertexIndex++)
     {
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index 6ec6634..6f12619 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -340,7 +340,8 @@
     ~LineLoopHelper();
 
     angle::Result getIndexBufferForDrawArrays(ContextVk *contextVk,
-                                              const gl::DrawCallParams &drawCallParams,
+                                              uint32_t clampedVertexCount,
+                                              GLint firstVertex,
                                               VkBuffer *bufferHandleOut,
                                               VkDeviceSize *offsetOut);
 
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h
index 0d1a3db..236cac5 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_utils.h
@@ -39,7 +39,6 @@
 namespace gl
 {
 struct Box;
-class DrawCallParams;
 struct Extents;
 struct RasterizerState;
 struct Rectangle;