Inline Context::DrawArrays and Context::BindBuffer.

This reduces the call depth of both of these two hotspots.
Reduces time spent in the CPU overhead benchmarks by about 10%.

Bug: angleproject:2966
Change-Id: I5052e56dcc1dfb80274326a7f0891fafba7d6655
Reviewed-on: https://chromium-review.googlesource.com/c/1392389
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Markus Tavenrath <matavenrath@nvidia.com>
This commit is contained in:
Jamie Madill 2018-12-29 16:04:05 -05:00 коммит произвёл Commit Bot
Родитель 9f088621eb
Коммит 60a50cfcb8
3 изменённых файлов: 60 добавлений и 60 удалений

Просмотреть файл

@ -130,17 +130,6 @@ angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLen
} }
} }
ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
GLsizei count,
GLsizei instanceCount)
{
if (context->getStateCache().isTransformFeedbackActiveUnpaused())
{
TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
transformFeedback->onVerticesDrawn(context, count, instanceCount);
}
}
// Attribute map queries. // Attribute map queries.
EGLint GetClientMajorVersion(const egl::AttributeMap &attribs) EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
{ {
@ -254,20 +243,6 @@ void LimitCap(CapT *cap, MaxT maximum)
*cap = std::min(*cap, static_cast<CapT>(maximum)); *cap = std::min(*cap, static_cast<CapT>(maximum));
} }
constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
{PrimitiveMode::Points, 1},
{PrimitiveMode::Lines, 2},
{PrimitiveMode::LineLoop, 2},
{PrimitiveMode::LineStrip, 2},
{PrimitiveMode::Triangles, 3},
{PrimitiveMode::TriangleStrip, 3},
{PrimitiveMode::TriangleFan, 3},
{PrimitiveMode::LinesAdjacency, 2},
{PrimitiveMode::LineStripAdjacency, 2},
{PrimitiveMode::TrianglesAdjacency, 3},
{PrimitiveMode::TriangleStripAdjacency, 3},
}};
// The rest default to false. // The rest default to false.
constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1> constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
kValidBasicDrawModes = {{ kValidBasicDrawModes = {{
@ -2201,19 +2176,6 @@ void Context::texParameterIuivRobust(TextureType target,
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
{
// No-op if count draws no primitives for given mode
if (noopDraw(mode, count))
{
return;
}
ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
MarkTransformFeedbackBufferUsage(this, count, 1);
}
void Context::drawArraysInstanced(PrimitiveMode mode, void Context::drawArraysInstanced(PrimitiveMode mode,
GLint first, GLint first,
GLsizei count, GLsizei count,
@ -3478,14 +3440,6 @@ void Context::initWorkarounds()
} }
} }
// Return true if the draw is a no-op, else return false.
// A no-op draw occurs if the count of vertices is less than the minimum required to
// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
bool Context::noopDraw(PrimitiveMode mode, GLsizei count)
{
return count < kMinimumPrimitiveCounts[mode];
}
bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount)
{ {
return (instanceCount == 0) || noopDraw(mode, count); return (instanceCount == 0) || noopDraw(mode, count);
@ -5107,13 +5061,6 @@ void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *nam
programObject->bindAttributeLocation(index, name); programObject->bindAttributeLocation(index, name);
} }
void Context::bindBuffer(BufferBinding target, GLuint buffer)
{
Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
mGLState.setBufferBinding(this, target, bufferObject);
mStateCache.onBufferBindingChange(this);
}
void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer) void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer)
{ {
bindBufferRange(target, index, buffer, 0, 0); bindBufferRange(target, index, buffer, 0, 0);
@ -8319,12 +8266,6 @@ void StateCache::onUniformBufferStateChange(Context *context)
updateBasicDrawStatesError(); updateBasicDrawStatesError();
} }
void StateCache::onBufferBindingChange(Context *context)
{
updateBasicDrawStatesError();
updateBasicDrawElementsError();
}
void StateCache::setValidDrawModes(bool pointsOK, void StateCache::setValidDrawModes(bool pointsOK,
bool linesOK, bool linesOK,
bool trisOK, bool trisOK,

Просмотреть файл

@ -1,5 +1,5 @@
// //
// Copyright (c) 2018 The ANGLE Project Authors. All rights reserved. // Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
@ -21,6 +21,38 @@
namespace gl namespace gl
{ {
constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
{PrimitiveMode::Points, 1},
{PrimitiveMode::Lines, 2},
{PrimitiveMode::LineLoop, 2},
{PrimitiveMode::LineStrip, 2},
{PrimitiveMode::Triangles, 3},
{PrimitiveMode::TriangleStrip, 3},
{PrimitiveMode::TriangleFan, 3},
{PrimitiveMode::LinesAdjacency, 2},
{PrimitiveMode::LineStripAdjacency, 2},
{PrimitiveMode::TrianglesAdjacency, 3},
{PrimitiveMode::TriangleStripAdjacency, 3},
}};
ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
GLsizei count,
GLsizei instanceCount)
{
if (context->getStateCache().isTransformFeedbackActiveUnpaused())
{
TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
transformFeedback->onVerticesDrawn(context, count, instanceCount);
}
}
// Return true if the draw is a no-op, else return false.
// A no-op draw occurs if the count of vertices is less than the minimum required to
// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count)
{
return count < kMinimumPrimitiveCounts[mode];
}
ANGLE_INLINE angle::Result Context::syncDirtyBits() ANGLE_INLINE angle::Result Context::syncDirtyBits()
{ {
@ -56,6 +88,19 @@ ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
return syncDirtyBits(); return syncDirtyBits();
} }
ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
{
// No-op if count draws no primitives for given mode
if (noopDraw(mode, count))
{
return;
}
ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
MarkTransformFeedbackBufferUsage(this, count, 1);
}
ANGLE_INLINE void Context::drawElements(PrimitiveMode mode, ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
GLsizei count, GLsizei count,
DrawElementsType type, DrawElementsType type,
@ -71,6 +116,19 @@ ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices)); ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
} }
ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
{
updateBasicDrawStatesError();
updateBasicDrawElementsError();
}
ANGLE_INLINE void Context::bindBuffer(BufferBinding target, GLuint buffer)
{
Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
mGLState.setBufferBinding(this, target, bufferObject);
mStateCache.onBufferBindingChange(this);
}
} // namespace gl } // namespace gl
#endif // LIBANGLE_CONTEXT_INL_H_ #endif // LIBANGLE_CONTEXT_INL_H_

Просмотреть файл

@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/ResourceManager.h" #include "libANGLE/ResourceManager.h"
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"