Commit bfe31c42 by Jamie Madill Committed by Commit Bot

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: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 8edb7188
......@@ -139,6 +139,12 @@ const char *GetGenericErrorMessage(GLenum error);
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
......
......@@ -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
......@@ -70,107 +70,8 @@ ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT.
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<> struct EntryPointParam<EntryPoint::NAME> \
\
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>
......
......@@ -303,7 +303,9 @@ angle::Result IndexDataManager::getStreamingIndexBuffer(const gl::Context *conte
}
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 @@ angle::Result GetIndexTranslationDestType(const gl::Context *context,
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();
}
......
......@@ -97,7 +97,9 @@ class IndexDataManager : angle::NonCopyable
};
angle::Result GetIndexTranslationDestType(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
GLsizei indexCount,
GLenum indexType,
const void *indices,
bool usePrimitiveRestartWorkaround,
GLenum *destTypeOut);
......
......@@ -248,10 +248,10 @@ angle::Result Context11::drawArrays(const gl::Context *context,
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 @@ angle::Result Context11::drawArraysInstanced(const gl::Context *context,
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 @@ ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *contex
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 @@ angle::Result Context11::drawArraysIndirect(const gl::Context *context,
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 @@ angle::Result Context11::drawElementsIndirect(const gl::Context *context,
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::Result Context11::drawElementsIndirect(const gl::Context *context,
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);
}
}
......
......@@ -120,7 +120,9 @@ angle::Result InputLayoutCache::getInputLayout(
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 @@ angle::Result InputLayoutCache::getInputLayout(
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 @@ angle::Result InputLayoutCache::getInputLayout(
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::Result InputLayoutCache::getInputLayout(
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 @@ angle::Result InputLayoutCache::createInputLayout(
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 @@ angle::Result InputLayoutCache::createInputLayout(
// 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;
......
......@@ -93,7 +93,9 @@ class InputLayoutCache : angle::NonCopyable
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 @@ class InputLayoutCache : angle::NonCopyable
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.
......
......@@ -1447,7 +1447,11 @@ angle::Result Renderer11::drawWithGeometryShaderAndTransformFeedback(Context11 *
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 @@ angle::Result Renderer11::drawArrays(const gl::Context *context, const gl::DrawC
}
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 @@ angle::Result Renderer11::drawArrays(const gl::Context *context, const gl::DrawC
// 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::drawArrays(const gl::Context *context, const gl::DrawC
}
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 @@ angle::Result Renderer11::drawElements(const gl::Context *context,
// 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 @@ angle::Result Renderer11::drawElements(const gl::Context *context,
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 @@ angle::Result Renderer11::drawElements(const gl::Context *context,
// 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 @@ angle::Result Renderer11::drawElements(const gl::Context *context,
// 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 @@ angle::Result Renderer11::drawElements(const gl::Context *context,
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 @@ angle::Result Renderer11::drawArraysIndirect(const gl::Context *context,
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 @@ angle::Result Renderer11::drawArraysIndirect(const gl::Context *context,
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 @@ angle::Result Renderer11::drawElementsIndirect(const gl::Context *context,
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));
......
......@@ -399,13 +399,20 @@ class Renderer11 : public RendererD3D
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;
......
......@@ -1258,11 +1258,11 @@ angle::Result StateManager11::syncDepthStencilState(const gl::Context *context)
}
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 @@ void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT str
}
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 @@ angle::Result StateManager11::updateState(const gl::Context *context,
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 @@ angle::Result StateManager11::updateState(const gl::Context *context,
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 @@ angle::Result StateManager11::updateState(const gl::Context *context,
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 @@ angle::Result StateManager11::updateState(const gl::Context *context,
// 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::Result StateManager11::updateState(const gl::Context *context,
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 @@ angle::Result StateManager11::syncProgramForCompute(const gl::Context *context)
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 @@ angle::Result StateManager11::syncVertexBuffersAndInputLayout(
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 @@ angle::Result StateManager11::applyVertexBuffers(const gl::Context *context,
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::applyVertexBuffers(const gl::Context *context,
}
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 @@ angle::Result StateManager11::applyIndexBuffer(const gl::Context *context,
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 =
......
......@@ -212,8 +212,13 @@ class StateManager11 final : angle::NonCopyable
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 @@ class StateManager11 final : angle::NonCopyable
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 @@ class StateManager11 final : angle::NonCopyable
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 @@ class StateManager11 final : angle::NonCopyable
// 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
{
......
......@@ -125,7 +125,12 @@ angle::Result VertexArray11::syncState(const gl::Context *context,
}
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 @@ angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
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::syncStateForDraw(const gl::Context *context,
}
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::updateDirtyAttribs(const gl::Context *context,
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 @@ angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
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 @@ angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
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);
......
......@@ -26,7 +26,7 @@ class VertexArray11 : public VertexArrayImpl
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 @@ class VertexArray11 : public VertexArrayImpl
// 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 @@ class VertexArray11 : public VertexArrayImpl
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;
......
......@@ -1304,10 +1304,9 @@ angle::Result Renderer9::applyIndexBuffer(const gl::Context *context,
{
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));
......
......@@ -197,21 +197,31 @@ class ContextVk : public ContextImpl, public vk::Context
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 @@ class ContextVk : public ContextImpl, public vk::Context
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;
......
......@@ -131,10 +131,9 @@ angle::Result SyncDefaultUniformBlock(ContextVk *contextVk,
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 @@ void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
}
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 @@ void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
}
angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
// Can probably use better dirty bits here.
......
......@@ -97,7 +97,7 @@ class ProgramVk : public ProgramImpl
// 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 @@ class ProgramVk : public ProgramImpl
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
angle::Result updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
// For testing only.
......
......@@ -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 @@ void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
}
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 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
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 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
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::updateClientAttribs(const gl::Context *context,
}
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 @@ angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
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 @@ angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
}
// 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::handleLineLoop(ContextVk *contextVk,
}
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 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
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));
......
......@@ -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 @@ class VertexArrayVk : public VertexArrayImpl
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 @@ class VertexArrayVk : public VertexArrayImpl
}
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
......
......@@ -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(RendererVk *renderer)
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++)
{
......
......@@ -340,7 +340,8 @@ class LineLoopHelper final : angle::NonCopyable
~LineLoopHelper();
angle::Result getIndexBufferForDrawArrays(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams,
uint32_t clampedVertexCount,
GLint firstVertex,
VkBuffer *bufferHandleOut,
VkDeviceSize *offsetOut);
......
......@@ -39,7 +39,6 @@ class Display;
namespace gl
{
struct Box;
class DrawCallParams;
struct Extents;
struct RasterizerState;
struct Rectangle;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment