Commit 6f5444da by Jamie Madill Committed by Commit Bot

Remove HasIndexRange.

This is superseded by the DrawCallParams class. Instead of storing the context, we also return an error from the index range resolution. Bug: angleproject:2389 Change-Id: I9e7d58f006f51872eb3b52cbb9efbee16fff7ef6 Reviewed-on: https://chromium-review.googlesource.com/960570 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 1c08cbb3
...@@ -1250,7 +1250,7 @@ class Context final : angle::NonCopyable ...@@ -1250,7 +1250,7 @@ class Context final : angle::NonCopyable
// Caches entry point parameters and values re-used between layers. // Caches entry point parameters and values re-used between layers.
mutable const ParamTypeInfo *mSavedArgsType; mutable const ParamTypeInfo *mSavedArgsType;
static constexpr size_t kParamsBufferSize = 64u; static constexpr size_t kParamsBufferSize = 128u;
mutable std::array<uint8_t, kParamsBufferSize> mParamsBuffer; mutable std::array<uint8_t, kParamsBufferSize> mParamsBuffer;
std::unique_ptr<rx::ContextImpl> mImplementation; std::unique_ptr<rx::ContextImpl> mImplementation;
......
...@@ -18,53 +18,7 @@ namespace gl ...@@ -18,53 +18,7 @@ namespace gl
// static // static
constexpr ParamTypeInfo ParamsBase::TypeInfo; constexpr ParamTypeInfo ParamsBase::TypeInfo;
constexpr ParamTypeInfo HasIndexRange::TypeInfo; constexpr ParamTypeInfo DrawCallParams::TypeInfo;
// HasIndexRange implementation.
HasIndexRange::HasIndexRange()
: ParamsBase(nullptr), mContext(nullptr), mCount(0), mType(GL_NONE), mIndices(nullptr)
{
}
HasIndexRange::HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices)
: ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices)
{
}
const Optional<IndexRange> &HasIndexRange::getIndexRange() const
{
if (mIndexRange.valid() || !mContext)
{
return mIndexRange;
}
const State &state = mContext->getGLState();
const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (elementArrayBuffer)
{
uintptr_t offset = reinterpret_cast<uintptr_t>(mIndices);
IndexRange indexRange;
Error error =
elementArrayBuffer->getIndexRange(mContext, mType, static_cast<size_t>(offset), mCount,
state.isPrimitiveRestartEnabled(), &indexRange);
if (error.isError())
{
mContext->handleError(error);
return mIndexRange;
}
mIndexRange = indexRange;
}
else
{
mIndexRange = ComputeIndexRange(mType, mIndices, mCount, state.isPrimitiveRestartEnabled());
}
return mIndexRange;
}
// DrawCallParams implementation. // DrawCallParams implementation.
// Called by DrawArrays. // Called by DrawArrays.
...@@ -73,7 +27,6 @@ DrawCallParams::DrawCallParams(GLenum mode, ...@@ -73,7 +27,6 @@ DrawCallParams::DrawCallParams(GLenum mode,
GLsizei vertexCount, GLsizei vertexCount,
GLsizei instances) GLsizei instances)
: mMode(mode), : mMode(mode),
mHasIndexRange(nullptr),
mFirstVertex(firstVertex), mFirstVertex(firstVertex),
mVertexCount(vertexCount), mVertexCount(vertexCount),
mIndexCount(0), mIndexCount(0),
...@@ -87,14 +40,12 @@ DrawCallParams::DrawCallParams(GLenum mode, ...@@ -87,14 +40,12 @@ DrawCallParams::DrawCallParams(GLenum mode,
// Called by DrawElements. // Called by DrawElements.
DrawCallParams::DrawCallParams(GLenum mode, DrawCallParams::DrawCallParams(GLenum mode,
const HasIndexRange &hasIndexRange,
GLint indexCount, GLint indexCount,
GLenum type, GLenum type,
const void *indices, const void *indices,
GLint baseVertex, GLint baseVertex,
GLsizei instances) GLsizei instances)
: mMode(mode), : mMode(mode),
mHasIndexRange(&hasIndexRange),
mFirstVertex(0), mFirstVertex(0),
mVertexCount(0), mVertexCount(0),
mIndexCount(indexCount), mIndexCount(indexCount),
...@@ -109,7 +60,6 @@ DrawCallParams::DrawCallParams(GLenum mode, ...@@ -109,7 +60,6 @@ DrawCallParams::DrawCallParams(GLenum mode,
// Called by DrawArraysIndirect. // Called by DrawArraysIndirect.
DrawCallParams::DrawCallParams(GLenum mode, const void *indirect) DrawCallParams::DrawCallParams(GLenum mode, const void *indirect)
: mMode(mode), : mMode(mode),
mHasIndexRange(nullptr),
mFirstVertex(0), mFirstVertex(0),
mVertexCount(0), mVertexCount(0),
mIndexCount(0), mIndexCount(0),
...@@ -124,7 +74,6 @@ DrawCallParams::DrawCallParams(GLenum mode, const void *indirect) ...@@ -124,7 +74,6 @@ DrawCallParams::DrawCallParams(GLenum mode, const void *indirect)
// Called by DrawElementsIndirect. // Called by DrawElementsIndirect.
DrawCallParams::DrawCallParams(GLenum mode, GLenum type, const void *indirect) DrawCallParams::DrawCallParams(GLenum mode, GLenum type, const void *indirect)
: mMode(mode), : mMode(mode),
mHasIndexRange(nullptr),
mFirstVertex(0), mFirstVertex(0),
mVertexCount(0), mVertexCount(0),
mIndexCount(0), mIndexCount(0),
...@@ -147,13 +96,13 @@ GLint DrawCallParams::firstVertex() const ...@@ -147,13 +96,13 @@ GLint DrawCallParams::firstVertex() const
// path". In these cases the index range is not resolved. If the first vertex is not zero, // path". In these cases the index range is not resolved. If the first vertex is not zero,
// however, then it must be because the index range is resolved. This only applies to the // however, then it must be because the index range is resolved. This only applies to the
// D3D11 back-end currently. // D3D11 back-end currently.
ASSERT(mFirstVertex == 0 || mHasIndexRange == nullptr); ASSERT(mFirstVertex == 0 || (!isDrawElements() || mIndexRange.valid()));
return mFirstVertex; return mFirstVertex;
} }
GLsizei DrawCallParams::vertexCount() const GLsizei DrawCallParams::vertexCount() const
{ {
ASSERT(!mHasIndexRange); ASSERT(!isDrawElements() || mIndexRange.valid());
return mVertexCount; return mVertexCount;
} }
...@@ -194,19 +143,44 @@ bool DrawCallParams::isDrawElements() const ...@@ -194,19 +143,44 @@ bool DrawCallParams::isDrawElements() const
return (mType != GL_NONE); return (mType != GL_NONE);
} }
void DrawCallParams::ensureIndexRangeResolved() const Error DrawCallParams::ensureIndexRangeResolved(const Context *context) const
{ {
if (mHasIndexRange == nullptr) if (mIndexRange.valid() || !isDrawElements())
{
return NoError();
}
const State &state = context->getGLState();
const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (elementArrayBuffer)
{ {
return; uintptr_t offset = reinterpret_cast<uintptr_t>(mIndices);
IndexRange indexRange;
ANGLE_TRY(elementArrayBuffer->getIndexRange(context, mType, static_cast<size_t>(offset),
mIndexCount, state.isPrimitiveRestartEnabled(),
&indexRange));
mIndexRange = indexRange;
}
else
{
mIndexRange =
ComputeIndexRange(mType, mIndices, mIndexCount, state.isPrimitiveRestartEnabled());
} }
// This call will resolve the index range. const IndexRange &indexRange = mIndexRange.value();
const gl::IndexRange &indexRange = mHasIndexRange->getIndexRange().value(); mFirstVertex = mBaseVertex + static_cast<GLint>(indexRange.start);
mVertexCount = static_cast<GLsizei>(indexRange.vertexCount());
mFirstVertex = mBaseVertex + static_cast<GLint>(indexRange.start); return NoError();
mVertexCount = static_cast<GLsizei>(indexRange.vertexCount()); }
mHasIndexRange = nullptr;
const IndexRange &DrawCallParams::getIndexRange() const
{
ASSERT(isDrawElements() && mIndexRange.valid());
return mIndexRange.value();
} }
} // namespace gl } // namespace gl
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common/Optional.h" #include "common/Optional.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/mathutil.h" #include "common/mathutil.h"
#include "libANGLE/Error.h"
#include "libANGLE/entry_points_enum_autogen.h" #include "libANGLE/entry_points_enum_autogen.h"
namespace gl namespace gl
...@@ -68,28 +69,6 @@ ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT. ...@@ -68,28 +69,6 @@ ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT.
new (objBuffer) EntryPointParamType<EP>(args...); new (objBuffer) EntryPointParamType<EP>(args...);
} }
class HasIndexRange : public ParamsBase
{
public:
// Dummy placeholder that can't generate an index range.
HasIndexRange();
HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices);
template <EntryPoint EP, typename... ArgsT>
static void Factory(HasIndexRange *objBuffer, ArgsT... args);
const Optional<IndexRange> &getIndexRange() const;
ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase);
private:
Context *mContext;
GLsizei mCount;
GLenum mType;
const GLvoid *mIndices;
mutable Optional<IndexRange> mIndexRange;
};
// Helper class that encompasses draw call parameters. It uses the HasIndexRange // Helper class that encompasses draw call parameters. It uses the HasIndexRange
// helper class to only pull index range info lazily to prevent unnecessary readback. // 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 // It is also used when syncing state for the VertexArray implementation, since the
...@@ -102,7 +81,6 @@ class DrawCallParams final : angle::NonCopyable ...@@ -102,7 +81,6 @@ class DrawCallParams final : angle::NonCopyable
// Called by DrawElements. // Called by DrawElements.
DrawCallParams(GLenum mode, DrawCallParams(GLenum mode,
const HasIndexRange &hasIndexRange,
GLint indexCount, GLint indexCount,
GLenum type, GLenum type,
const void *indices, const void *indices,
...@@ -115,11 +93,11 @@ class DrawCallParams final : angle::NonCopyable ...@@ -115,11 +93,11 @@ class DrawCallParams final : angle::NonCopyable
// Called by DrawElementsIndirect. // Called by DrawElementsIndirect.
DrawCallParams(GLenum mode, GLenum type, const void *indirect); DrawCallParams(GLenum mode, GLenum type, const void *indirect);
// It should be possible to also use an overload to handle the 'slow' indirect draw path.
// TODO(jmadill): Indirect draw slow path overload.
GLenum mode() const; GLenum mode() const;
// This value is the sum of 'baseVertex' and the first indexed vertex for DrawElements calls.
GLint firstVertex() const; GLint firstVertex() const;
GLsizei vertexCount() const; GLsizei vertexCount() const;
GLsizei indexCount() const; GLsizei indexCount() const;
GLint baseVertex() const; GLint baseVertex() const;
...@@ -128,12 +106,20 @@ class DrawCallParams final : angle::NonCopyable ...@@ -128,12 +106,20 @@ class DrawCallParams final : angle::NonCopyable
GLsizei instances() const; GLsizei instances() const;
const void *indirect() const; const void *indirect() const;
void ensureIndexRangeResolved() const; Error ensureIndexRangeResolved(const Context *context) const;
bool isDrawElements() const; bool isDrawElements() const;
// ensureIndexRangeResolved must be called first.
const IndexRange &getIndexRange() const;
template <EntryPoint EP, typename... ArgsT>
static void Factory(DrawCallParams *objBuffer, ArgsT... args);
ANGLE_PARAM_TYPE_INFO(DrawCallParams, ParamsBase);
private: private:
GLenum mMode; GLenum mMode;
mutable const HasIndexRange *mHasIndexRange; mutable Optional<IndexRange> mIndexRange;
mutable GLint mFirstVertex; mutable GLint mFirstVertex;
mutable GLsizei mVertexCount; mutable GLsizei mVertexCount;
GLint mIndexCount; GLint mIndexCount;
...@@ -157,59 +143,118 @@ template<> struct EntryPointParam<EntryPoint::NAME> \ ...@@ -157,59 +143,118 @@ template<> struct EntryPointParam<EntryPoint::NAME> \
\ \
template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__) template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__)
ANGLE_ENTRY_POINT_FUNC(DrawArrays,
DrawCallParams,
DrawCallParams *objBuffer,
Context *context,
GLenum 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,
GLenum 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,
GLenum 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,
GLenum mode,
const void *indirect)
{
return ParamsBase::Factory<EntryPoint::DrawArraysIndirect>(objBuffer, mode, indirect);
}
ANGLE_ENTRY_POINT_FUNC(DrawElementsIndirect,
DrawCallParams,
DrawCallParams *objBuffer,
Context *context,
GLenum mode,
GLenum type,
const void *indirect)
{
return ParamsBase::Factory<EntryPoint::DrawElementsIndirect>(objBuffer, mode, type, indirect);
}
ANGLE_ENTRY_POINT_FUNC(DrawElements, ANGLE_ENTRY_POINT_FUNC(DrawElements,
HasIndexRange, DrawCallParams,
HasIndexRange *objBuffer, DrawCallParams *objBuffer,
Context *context, Context *context,
GLenum /*mode*/, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices) const void *indices)
{ {
return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, context, count, type, indices); return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, mode, count, type, indices, 0,
0);
} }
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced, ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,
HasIndexRange, DrawCallParams,
HasIndexRange *objBuffer, DrawCallParams *objBuffer,
Context *context, Context *context,
GLenum /*mode*/, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices, const void *indices,
GLsizei /*instanceCount*/) GLsizei instanceCount)
{ {
return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, context, count, type, return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, mode, count, type,
indices); indices, 0, instanceCount);
} }
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE, ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,
HasIndexRange, DrawCallParams,
HasIndexRange *objBuffer, DrawCallParams *objBuffer,
Context *context, Context *context,
GLenum /*mode*/, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices, const void *indices,
GLsizei /*instanceCount*/) GLsizei instanceCount)
{ {
return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, context, count, return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, mode, count, type,
type, indices); indices, 0, instanceCount);
} }
ANGLE_ENTRY_POINT_FUNC(DrawRangeElements, ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,
HasIndexRange, DrawCallParams,
HasIndexRange *objBuffer, DrawCallParams *objBuffer,
Context *context, Context *context,
GLenum /*mode*/, GLenum mode,
GLuint /*start*/, GLuint /*start*/,
GLuint /*end*/, GLuint /*end*/,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices) const void *indices)
{ {
return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, context, count, type, return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, mode, count, type, indices,
indices); 0, 0);
} }
#undef ANGLE_ENTRY_POINT_FUNC #undef ANGLE_ENTRY_POINT_FUNC
......
...@@ -299,22 +299,26 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, ...@@ -299,22 +299,26 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
return gl::NoError(); return gl::NoError();
} }
GLenum GetIndexTranslationDestType(GLenum srcType, gl::Error GetIndexTranslationDestType(const gl::Context *context,
const gl::HasIndexRange &lazyIndexRange, const gl::DrawCallParams &drawCallParams,
bool usePrimitiveRestartWorkaround) bool usePrimitiveRestartWorkaround,
GLenum *destTypeOut)
{ {
// Avoid D3D11's primitive restart index value // Avoid D3D11's primitive restart index value
// see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
if (usePrimitiveRestartWorkaround) if (usePrimitiveRestartWorkaround)
{ {
const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value(); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType)) const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type()))
{ {
return GL_UNSIGNED_INT; *destTypeOut = GL_UNSIGNED_INT;
return gl::NoError();
} }
} }
return (srcType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; *destTypeOut = (drawCallParams.type() == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
return gl::NoError();
} }
} // namespace rx } // namespace rx
...@@ -94,9 +94,10 @@ class IndexDataManager : angle::NonCopyable ...@@ -94,9 +94,10 @@ class IndexDataManager : angle::NonCopyable
std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt; std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt;
}; };
GLenum GetIndexTranslationDestType(GLenum srcType, gl::Error GetIndexTranslationDestType(const gl::Context *context,
const gl::HasIndexRange &lazyIndexRange, const gl::DrawCallParams &drawCallParams,
bool usePrimitiveRestartWorkaround); bool usePrimitiveRestartWorkaround,
GLenum *destTypeOut);
bool IsOffsetAligned(GLenum elementType, unsigned int offset); bool IsOffsetAligned(GLenum elementType, unsigned int offset);
......
...@@ -441,7 +441,7 @@ gl::Error InputLayoutCache::createInputLayout( ...@@ -441,7 +441,7 @@ gl::Error InputLayoutCache::createInputLayout(
GLsizei numIndicesPerInstance = 0; GLsizei numIndicesPerInstance = 0;
if (drawCallParams.instances() > 0) if (drawCallParams.instances() > 0)
{ {
// This may trigger an evaluation of the index range. // This requires that the index range is resolved.
numIndicesPerInstance = drawCallParams.vertexCount(); numIndicesPerInstance = drawCallParams.vertexCount();
} }
......
...@@ -1510,7 +1510,7 @@ gl::Error Renderer11::drawArrays(const gl::Context *context, ...@@ -1510,7 +1510,7 @@ gl::Error Renderer11::drawArrays(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
gl::DrawCallParams drawCallParams(mode, startVertex, count, instances); const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams));
if (glState.isTransformFeedbackActiveUnpaused()) if (glState.isTransformFeedbackActiveUnpaused())
...@@ -1642,15 +1642,13 @@ gl::Error Renderer11::drawElements(const gl::Context *context, ...@@ -1642,15 +1642,13 @@ gl::Error Renderer11::drawElements(const gl::Context *context,
// API validation layer. // API validation layer.
ASSERT(!glState.isTransformFeedbackActiveUnpaused()); ASSERT(!glState.isTransformFeedbackActiveUnpaused());
const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>(); const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
gl::DrawCallParams drawCallParams(mode, lazyIndexRange, count, type, indices, 0, instances);
bool usePrimitiveRestartWorkaround = bool usePrimitiveRestartWorkaround =
UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type); UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type);
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, ANGLE_TRY(
usePrimitiveRestartWorkaround)); mStateManager.applyIndexBuffer(context, drawCallParams, usePrimitiveRestartWorkaround));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams));
int startVertex = static_cast<int>(drawCallParams.firstVertex()); int startVertex = static_cast<int>(drawCallParams.firstVertex());
...@@ -1795,10 +1793,10 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, ...@@ -1795,10 +1793,10 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type)) if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type))
{ {
ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, gl::HasIndexRange(),
usePrimitiveRestartWorkaround));
gl::DrawCallParams drawCallParams(mode, type, indirect); gl::DrawCallParams drawCallParams(mode, type, indirect);
ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams));
ANGLE_TRY(
mStateManager.applyIndexBuffer(context, drawCallParams, usePrimitiveRestartWorkaround));
ID3D11Buffer *buffer = nullptr; ID3D11Buffer *buffer = nullptr;
ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer); ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer);
mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast<unsigned int>(offset)); mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast<unsigned int>(offset));
...@@ -1816,26 +1814,23 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, ...@@ -1816,26 +1814,23 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
GLuint firstIndex = cmd->firstIndex; GLuint firstIndex = cmd->firstIndex;
GLint baseVertex = cmd->baseVertex; GLint baseVertex = cmd->baseVertex;
// TODO(jmadill): Fix const cast.
const gl::Type &typeInfo = gl::GetTypeInfo(type); const gl::Type &typeInfo = gl::GetTypeInfo(type);
const void *indices = const void *indices =
reinterpret_cast<const void *>(static_cast<uintptr_t>(firstIndex * typeInfo.bytes)); reinterpret_cast<const void *>(static_cast<uintptr_t>(firstIndex * typeInfo.bytes));
gl::HasIndexRange lazyIndexRange(const_cast<gl::Context *>(context), count, type, indices);
gl::DrawCallParams drawCallParams(mode, lazyIndexRange, count, type, indices, baseVertex, gl::DrawCallParams drawCallParams(mode, count, type, indices, baseVertex, instances);
instances);
// We must explicitly resolve the index range for the slow-path indirect drawElements to make // 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 // sure we are using the correct 'baseVertex'. This parameter does not exist for the direct
// drawElements. // drawElements.
drawCallParams.ensureIndexRangeResolved(); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, ANGLE_TRY(
usePrimitiveRestartWorkaround)); mStateManager.applyIndexBuffer(context, drawCallParams, usePrimitiveRestartWorkaround));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, drawCallParams));
int baseVertexLocation = -static_cast<int>(lazyIndexRange.getIndexRange().value().start); int baseVertexLocation = -static_cast<int>(drawCallParams.getIndexRange().start);
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
{ {
......
...@@ -2730,20 +2730,19 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context, ...@@ -2730,20 +2730,19 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
} }
gl::Error StateManager11::applyIndexBuffer(const gl::Context *context, gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
const void *indices, const gl::DrawCallParams &params,
GLsizei count,
GLenum type,
const gl::HasIndexRange &lazyIndexRange,
bool usePrimitiveRestartWorkaround) bool usePrimitiveRestartWorkaround)
{ {
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
gl::VertexArray *vao = glState.getVertexArray(); gl::VertexArray *vao = glState.getVertexArray();
VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao); VertexArray11 *vao11 = GetImplAs<VertexArray11>(vao);
GLenum destElementType = GLenum destElementType = GL_NONE;
GetIndexTranslationDestType(type, lazyIndexRange, usePrimitiveRestartWorkaround); ANGLE_TRY(GetIndexTranslationDestType(context, params, usePrimitiveRestartWorkaround,
&destElementType));
if (!vao11->updateElementArrayStorage(context, type, destElementType, indices) && if (!vao11->updateElementArrayStorage(context, params.type(), destElementType,
params.indices()) &&
!mIndexBufferIsDirty) !mIndexBufferIsDirty)
{ {
// No streaming or index buffer application necessary. // No streaming or index buffer application necessary.
...@@ -2753,8 +2752,9 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context, ...@@ -2753,8 +2752,9 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo(); TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo();
ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, destElementType, count, ANGLE_TRY(mIndexDataManager.prepareIndexData(context, params.type(), destElementType,
elementArrayBuffer, indices, indexInfo)); params.indexCount(), elementArrayBuffer,
params.indices(), indexInfo));
ID3D11Buffer *buffer = nullptr; ID3D11Buffer *buffer = nullptr;
DXGI_FORMAT bufferFormat = DXGI_FORMAT bufferFormat =
......
...@@ -242,10 +242,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -242,10 +242,7 @@ class StateManager11 final : angle::NonCopyable
const gl::DrawCallParams &drawCallParams); const gl::DrawCallParams &drawCallParams);
gl::Error applyIndexBuffer(const gl::Context *context, gl::Error applyIndexBuffer(const gl::Context *context,
const void *indices, const gl::DrawCallParams &drawCallParams,
GLsizei count,
GLenum type,
const gl::HasIndexRange &lazyIndexRange,
bool usePrimitiveRestartWorkaround); bool usePrimitiveRestartWorkaround);
void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
......
...@@ -315,7 +315,7 @@ gl::Error VertexArray11::updateDirtyAndDynamicAttribs(const gl::Context *context ...@@ -315,7 +315,7 @@ gl::Error VertexArray11::updateDirtyAndDynamicAttribs(const gl::Context *context
if (mDynamicAttribsMask.any()) if (mDynamicAttribsMask.any())
{ {
drawCallParams.ensureIndexRangeResolved(); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
if (activeDynamicAttribs.none()) if (activeDynamicAttribs.none())
......
...@@ -1317,11 +1317,12 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Context *context, ...@@ -1317,11 +1317,12 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Context *context,
GLenum type, GLenum type,
TranslatedIndexData *indexInfo) TranslatedIndexData *indexInfo)
{ {
gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::VertexArray *vao = context->getGLState().getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>(); const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false); GLenum dstType = GL_NONE;
ANGLE_TRY(GetIndexTranslationDestType(context, drawCallParams, false, &dstType));
ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer, ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer,
indices, indexInfo)); indices, indexInfo));
...@@ -1396,8 +1397,10 @@ gl::Error Renderer9::drawElementsImpl(const gl::Context *context, ...@@ -1396,8 +1397,10 @@ gl::Error Renderer9::drawElementsImpl(const gl::Context *context,
ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo)); ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo));
const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>(); const auto &drawCallParams = context->getParams<gl::DrawCallParams>();
const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value(); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
size_t vertexCount = indexRange.vertexCount(); size_t vertexCount = indexRange.vertexCount();
ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start), ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start),
static_cast<GLsizei>(vertexCount), instances, &indexInfo)); static_cast<GLsizei>(vertexCount), instances, &indexInfo));
......
...@@ -2944,31 +2944,27 @@ bool ValidateDrawElementsCommon(Context *context, ...@@ -2944,31 +2944,27 @@ bool ValidateDrawElementsCommon(Context *context,
else else
{ {
// Use the parameter buffer to retrieve and cache the index range. // Use the parameter buffer to retrieve and cache the index range.
const auto &params = context->getParams<HasIndexRange>(); const DrawCallParams &params = context->getParams<DrawCallParams>();
const auto &indexRangeOpt = params.getIndexRange(); ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
if (!indexRangeOpt.valid()) const IndexRange &indexRange = params.getIndexRange();
{
// Unexpected error.
return false;
}
// If we use an index greater than our maximum supported index range, return an error. // If we use an index greater than our maximum supported index range, return an error.
// The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
// return an error if possible here. // return an error if possible here.
if (static_cast<GLuint64>(indexRangeOpt.value().end) >= context->getCaps().maxElementIndex) if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
{ {
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement); ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement);
return false; return false;
} }
if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRangeOpt.value().end), if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end),
static_cast<GLint>(indexRangeOpt.value().vertexCount()))) static_cast<GLint>(indexRange.vertexCount())))
{ {
return false; return false;
} }
// No op if there are no real indices in the index data (all are primitive restart). // No op if there are no real indices in the index data (all are primitive restart).
return (indexRangeOpt.value().vertexIndexCount > 0); return (indexRange.vertexIndexCount > 0);
} }
return true; return true;
......
...@@ -1284,15 +1284,12 @@ bool ValidateDrawRangeElements(Context *context, ...@@ -1284,15 +1284,12 @@ bool ValidateDrawRangeElements(Context *context,
} }
// Use the parameter buffer to retrieve and cache the index range. // Use the parameter buffer to retrieve and cache the index range.
const auto &params = context->getParams<HasIndexRange>(); const DrawCallParams &params = context->getParams<DrawCallParams>();
const auto &indexRangeOpt = params.getIndexRange(); ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
if (!indexRangeOpt.valid())
{ const IndexRange &indexRange = params.getIndexRange();
// Unexpected error.
return false;
}
if (indexRangeOpt.value().end > end || indexRangeOpt.value().start < start) if (indexRange.end > end || indexRange.start < start)
{ {
// GL spec says that behavior in this case is undefined - generating an error is fine. // GL spec says that behavior in this case is undefined - generating an error is fine.
context->handleError(InvalidOperation() << "Indices are out of the start, end range."); context->handleError(InvalidOperation() << "Indices are out of the start, end range.");
......
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