Commit 03fd0356 by Jamie Madill Committed by Commit Bot

D3D11: Push index range computation deeper.

If we can make the index range computation happen as late as possible, we won't have to check it during the fastest draw call paths. This change makes it easier to skip re-computing some index range checks by only checking it in one place in IndexDataManager, and by making it a lazy check; the check is never evaluated if the primitive restart workaround is not enabled. Future work can also push the index range computation for vertex info later, so we only evaluate it in the cases where we need it. BUG=angleproject:2229 Change-Id: Ic55fac9e23fd35a119ddff475355a43095d2e3e9 Reviewed-on: https://chromium-review.googlesource.com/764675 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c7965001
...@@ -20,9 +20,14 @@ namespace gl ...@@ -20,9 +20,14 @@ namespace gl
constexpr ParamTypeInfo ParamsBase::TypeInfo; constexpr ParamTypeInfo ParamsBase::TypeInfo;
constexpr ParamTypeInfo HasIndexRange::TypeInfo; constexpr ParamTypeInfo HasIndexRange::TypeInfo;
HasIndexRange::HasIndexRange()
: ParamsBase(nullptr), mContext(nullptr), mCount(0), mType(GL_NONE), mIndices(nullptr)
{
}
const Optional<IndexRange> &HasIndexRange::getIndexRange() const const Optional<IndexRange> &HasIndexRange::getIndexRange() const
{ {
if (mIndexRange.valid()) if (mIndexRange.valid() || !mContext)
{ {
return mIndexRange; return mIndexRange;
} }
......
...@@ -71,6 +71,8 @@ ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT. ...@@ -71,6 +71,8 @@ ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT.
class HasIndexRange : public ParamsBase class HasIndexRange : public ParamsBase
{ {
public: public:
// Dummy placeholder that can't generate an index range.
HasIndexRange();
HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices) HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices)
: ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices) : ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices)
{ {
......
...@@ -280,13 +280,14 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, ...@@ -280,13 +280,14 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
} }
GLenum GetIndexTranslationDestType(GLenum srcType, GLenum GetIndexTranslationDestType(GLenum srcType,
const gl::IndexRange &indexRange, const gl::HasIndexRange &lazyIndexRange,
bool usePrimitiveRestartWorkaround) bool usePrimitiveRestartWorkaround)
{ {
// 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();
if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType)) if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType))
{ {
return GL_UNSIGNED_INT; return GL_UNSIGNED_INT;
......
...@@ -50,7 +50,6 @@ struct SourceIndexData ...@@ -50,7 +50,6 @@ struct SourceIndexData
struct TranslatedIndexData struct TranslatedIndexData
{ {
gl::IndexRange indexRange;
unsigned int startIndex; unsigned int startIndex;
unsigned int startOffset; // In bytes unsigned int startOffset; // In bytes
...@@ -96,7 +95,7 @@ class IndexDataManager : angle::NonCopyable ...@@ -96,7 +95,7 @@ class IndexDataManager : angle::NonCopyable
}; };
GLenum GetIndexTranslationDestType(GLenum srcType, GLenum GetIndexTranslationDestType(GLenum srcType,
const gl::IndexRange &indexRange, const gl::HasIndexRange &lazyIndexRange,
bool usePrimitiveRestartWorkaround); bool usePrimitiveRestartWorkaround);
} // namespace rx } // namespace rx
......
...@@ -1647,10 +1647,13 @@ gl::Error Renderer11::drawElements(const gl::Context *context, ...@@ -1647,10 +1647,13 @@ gl::Error Renderer11::drawElements(const gl::Context *context,
const gl::Program *program = glState.getProgram(); const gl::Program *program = glState.getProgram();
GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances); GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>();
if (!DrawCallNeedsTranslation(context, mode) && if (!DrawCallNeedsTranslation(context, mode) &&
!UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type)) !UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type))
{ {
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo)); ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange,
&indexInfo));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
if (adjustedInstanceCount > 0) if (adjustedInstanceCount > 0)
...@@ -1664,15 +1667,16 @@ gl::Error Renderer11::drawElements(const gl::Context *context, ...@@ -1664,15 +1667,16 @@ gl::Error Renderer11::drawElements(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
indexInfo.indexRange = context->getParams<gl::HasIndexRange>().getIndexRange().value(); ANGLE_TRY(
mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, &indexInfo));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo)); const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
size_t vertexCount = indexInfo.indexRange.vertexCount(); size_t vertexCount = indexRange.vertexCount();
ANGLE_TRY(mStateManager.applyVertexBuffer( ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start),
context, mode, static_cast<GLsizei>(indexInfo.indexRange.start), static_cast<GLsizei>(vertexCount), instances,
static_cast<GLsizei>(vertexCount), instances, &indexInfo)); &indexInfo));
int startVertex = static_cast<int>(indexInfo.indexRange.start); int startVertex = static_cast<int>(indexRange.start);
int baseVertex = -startVertex; int baseVertex = -startVertex;
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
...@@ -1723,7 +1727,7 @@ gl::Error Renderer11::drawElements(const gl::Context *context, ...@@ -1723,7 +1727,7 @@ gl::Error Renderer11::drawElements(const gl::Context *context,
// efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each
// batch of points. An offset into the instanced data buffer is calculated and applied on each // batch of points. An offset into the instanced data buffer is calculated and applied on each
// iteration to ensure all instances are rendered correctly. // iteration to ensure all instances are rendered correctly.
GLsizei elementsToRender = static_cast<GLsizei>(indexInfo.indexRange.vertexCount()); GLsizei elementsToRender = static_cast<GLsizei>(indexRange.vertexCount());
// Each instance being rendered requires the inputlayout cache to reapply buffers and offsets. // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets.
for (GLsizei i = 0; i < instances; i++) for (GLsizei i = 0; i < instances; i++)
...@@ -1806,7 +1810,8 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, ...@@ -1806,7 +1810,8 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
TranslatedIndexData indexInfo; TranslatedIndexData indexInfo;
if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type)) if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type))
{ {
ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, &indexInfo)); ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, gl::HasIndexRange(),
&indexInfo));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
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);
...@@ -1820,23 +1825,20 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, ...@@ -1820,23 +1825,20 @@ gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
const gl::DrawElementsIndirectCommand *cmd = const gl::DrawElementsIndirectCommand *cmd =
reinterpret_cast<const gl::DrawElementsIndirectCommand *>(bufferData + offset); reinterpret_cast<const gl::DrawElementsIndirectCommand *>(bufferData + offset);
GLuint count = cmd->count; GLsizei count = cmd->count;
GLuint instances = cmd->primCount; GLuint instances = cmd->primCount;
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);
uint8_t *indices = static_cast<uint8_t *>(0) + firstIndex * typeInfo.bytes; const void *indices = reinterpret_cast<const void *>(firstIndex * typeInfo.bytes);
gl::HasIndexRange lazyIndexRange(const_cast<gl::Context *>(context), count, type, indices);
gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer().get(); ANGLE_TRY(
ASSERT(elementArrayBuffer); mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, &indexInfo));
gl::IndexRange indexRange;
ANGLE_TRY(elementArrayBuffer->getIndexRange(context, type, reinterpret_cast<size_t>(indices),
count, glState.isPrimitiveRestartEnabled(),
&indexRange));
indexInfo.indexRange = indexRange; const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo));
size_t vertexCount = indexRange.vertexCount(); size_t vertexCount = indexRange.vertexCount();
ANGLE_TRY(mStateManager.applyVertexBuffer( ANGLE_TRY(mStateManager.applyVertexBuffer(
context, mode, static_cast<GLsizei>(indexRange.start) + baseVertex, context, mode, static_cast<GLsizei>(indexRange.start) + baseVertex,
......
...@@ -2559,6 +2559,7 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context, ...@@ -2559,6 +2559,7 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
const void *indices, const void *indices,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const gl::HasIndexRange &lazyIndexRange,
TranslatedIndexData *indexInfo) TranslatedIndexData *indexInfo)
{ {
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
...@@ -2569,7 +2570,7 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context, ...@@ -2569,7 +2570,7 @@ gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type); UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type);
GLenum dstType = GLenum dstType =
GetIndexTranslationDestType(type, indexInfo->indexRange, usePrimitiveRestartWorkaround); GetIndexTranslationDestType(type, lazyIndexRange, usePrimitiveRestartWorkaround);
ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, dstType, count, elementArrayBuffer, ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, dstType, count, elementArrayBuffer,
indices, indexInfo)); indices, indexInfo));
......
...@@ -245,6 +245,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -245,6 +245,7 @@ class StateManager11 final : angle::NonCopyable
const void *indices, const void *indices,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const gl::HasIndexRange &lazyIndexRange,
TranslatedIndexData *indexInfo); TranslatedIndexData *indexInfo);
bool setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); bool setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
......
...@@ -1342,8 +1342,9 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Context *context, ...@@ -1342,8 +1342,9 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Context *context,
{ {
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>();
GLenum dstType = GetIndexTranslationDestType(type, indexInfo->indexRange, false); GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false);
ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer, ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer,
indices, indexInfo)); indices, indexInfo));
...@@ -1415,17 +1416,18 @@ gl::Error Renderer9::drawElementsImpl(const gl::Context *context, ...@@ -1415,17 +1416,18 @@ gl::Error Renderer9::drawElementsImpl(const gl::Context *context,
GLsizei instances) GLsizei instances)
{ {
TranslatedIndexData indexInfo; TranslatedIndexData indexInfo;
const gl::IndexRange &indexRange =
context->getParams<gl::HasIndexRange>().getIndexRange().value();
indexInfo.indexRange = indexRange;
ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo)); ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo));
size_t vertexCount = indexInfo.indexRange.vertexCount();
ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexInfo.indexRange.start), const auto &lazyIndexRange = context->getParams<gl::HasIndexRange>();
const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
size_t vertexCount = indexRange.vertexCount();
ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start),
static_cast<GLsizei>(vertexCount), instances, &indexInfo)); static_cast<GLsizei>(vertexCount), instances, &indexInfo));
startScene(); startScene();
int minIndex = static_cast<int>(indexInfo.indexRange.start); int minIndex = static_cast<int>(indexRange.start);
gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::VertexArray *vao = context->getGLState().getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
......
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