Commit 3edfe034 by Geoff Lang

Support primitive restart in RendererGL.

Store index ranges in a new struct that tracks how many real indices were seen. Update index caching to key on primitive restart being enabled and update index counting functions to skip primitive restart indicies when needed. Passes dEQP-GLES3.functional.primitive_restart.* Change-Id: Id1e25a5adcdcd4e998836e8ff6679c64be4c3066 Reviewed-on: https://chromium-review.googlesource.com/297770 Tryjob-Request: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 8f68be8b
...@@ -541,6 +541,26 @@ struct Range ...@@ -541,6 +541,26 @@ struct Range
typedef Range<int> RangeI; typedef Range<int> RangeI;
typedef Range<unsigned int> RangeUI; typedef Range<unsigned int> RangeUI;
struct IndexRange
{
IndexRange() : IndexRange(0, 0, 0) {}
IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_)
: start(start_), end(end_), vertexIndexCount(vertexIndexCount_)
{
ASSERT(start <= end);
}
// Number of vertices in the range.
size_t vertexCount() const { return (end - start) + 1; }
// Inclusive range of indices that are not primitive restart
size_t start;
size_t end;
// Number of non-primitive restart indices
size_t vertexIndexCount;
};
// First, both normalized floating-point values are converted into 16-bit integer values. // First, both normalized floating-point values are converted into 16-bit integer values.
// Then, the results are packed into the returned 32-bit unsigned integer. // Then, the results are packed into the returned 32-bit unsigned integer.
// The first float value will be written to the least significant bits of the output; // The first float value will be written to the least significant bits of the output;
......
...@@ -19,6 +19,78 @@ ...@@ -19,6 +19,78 @@
# include <windows.graphics.display.h> # include <windows.graphics.display.h>
#endif #endif
namespace
{
template <class IndexType>
gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
size_t count,
bool primitiveRestartEnabled,
GLuint primitiveRestartIndex)
{
ASSERT(count > 0);
IndexType minIndex = 0;
IndexType maxIndex = 0;
size_t nonPrimitiveRestartIndices = 0;
if (primitiveRestartEnabled)
{
// Find the first non-primitive restart index to initialize the min and max values
size_t i = 0;
for (; i < count; i++)
{
if (indices[i] != primitiveRestartIndex)
{
minIndex = indices[i];
maxIndex = indices[i];
nonPrimitiveRestartIndices++;
break;
}
}
// Loop over the rest of the indices
for (; i < count; i++)
{
if (indices[i] != primitiveRestartIndex)
{
if (minIndex > indices[i])
{
minIndex = indices[i];
}
if (maxIndex < indices[i])
{
maxIndex = indices[i];
}
nonPrimitiveRestartIndices++;
}
}
}
else
{
minIndex = indices[0];
maxIndex = indices[0];
nonPrimitiveRestartIndices = count;
for (size_t i = 1; i < count; i++)
{
if (minIndex > indices[i])
{
minIndex = indices[i];
}
if (maxIndex < indices[i])
{
maxIndex = indices[i];
}
}
}
return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
nonPrimitiveRestartIndices);
}
} // anonymous namespace
namespace gl namespace gl
{ {
...@@ -399,30 +471,44 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index) ...@@ -399,30 +471,44 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index)
return FirstCubeMapTextureTarget + static_cast<GLenum>(index); return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
} }
template <class IndexType> IndexRange ComputeIndexRange(GLenum indexType,
static RangeUI ComputeTypedIndexRange(const IndexType *indices, GLsizei count) const GLvoid *indices,
size_t count,
bool primitiveRestartEnabled)
{ {
ASSERT(count > 0); switch (indexType)
IndexType minIndex = indices[0];
IndexType maxIndex = indices[0];
for (GLsizei i = 1; i < count; i++)
{ {
if (minIndex > indices[i]) minIndex = indices[i]; case GL_UNSIGNED_BYTE:
if (maxIndex < indices[i]) maxIndex = indices[i]; return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
case GL_UNSIGNED_SHORT:
return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
case GL_UNSIGNED_INT:
return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
default:
UNREACHABLE();
return IndexRange();
} }
return RangeUI(static_cast<GLuint>(minIndex), static_cast<GLuint>(maxIndex));
} }
RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count) GLuint GetPrimitiveRestartIndex(GLenum indexType)
{ {
switch (indexType) switch (indexType)
{ {
case GL_UNSIGNED_BYTE: return ComputeTypedIndexRange(static_cast<const GLubyte*>(indices), count); case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT: return ComputeTypedIndexRange(static_cast<const GLushort*>(indices), count); return 0xFF;
case GL_UNSIGNED_INT: return ComputeTypedIndexRange(static_cast<const GLuint*>(indices), count); case GL_UNSIGNED_SHORT:
default: UNREACHABLE(); return RangeUI(0, 0); return 0xFFFF;
case GL_UNSIGNED_INT:
return 0xFFFFFFFF;
default:
UNREACHABLE();
return 0;
} }
} }
......
...@@ -50,7 +50,15 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index); ...@@ -50,7 +50,15 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index);
// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid. // set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
std::string ParseUniformName(const std::string &name, size_t *outSubscript); std::string ParseUniformName(const std::string &name, size_t *outSubscript);
RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count); // Find the range of index values in the provided indices pointer. Primitive restart indices are
// only counted in the range if primitive restart is disabled.
IndexRange ComputeIndexRange(GLenum indexType,
const GLvoid *indices,
size_t count,
bool primitiveRestartEnabled);
// Get the primitive restart index value for the given index type.
GLuint GetPrimitiveRestartIndex(GLenum indexType);
bool IsTriangleMode(GLenum drawMode); bool IsTriangleMode(GLenum drawMode);
......
...@@ -160,22 +160,24 @@ void Buffer::onPixelUnpack() ...@@ -160,22 +160,24 @@ void Buffer::onPixelUnpack()
mIndexRangeCache.clear(); mIndexRangeCache.clear();
} }
Error Buffer::getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) const Error Buffer::getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
IndexRange *outRange) const
{ {
if (mIndexRangeCache.findRange(type, static_cast<unsigned int>(offset), if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange))
static_cast<GLsizei>(count), outRange))
{ {
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
Error error = mBuffer->getIndexRange(type, offset, count, outRange); Error error = mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
mIndexRangeCache.addRange(type, static_cast<unsigned int>(offset), static_cast<GLsizei>(count), mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange);
*outRange);
return Error(GL_NO_ERROR); return Error(GL_NO_ERROR);
} }
......
...@@ -41,7 +41,11 @@ class Buffer : public RefCountObject ...@@ -41,7 +41,11 @@ class Buffer : public RefCountObject
void onTransformFeedback(); void onTransformFeedback();
void onPixelUnpack(); void onPixelUnpack();
Error getIndexRange(GLenum type, size_t offset, size_t count, RangeUI *outRange) const; Error getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
IndexRange *outRange) const;
GLenum getUsage() const { return mUsage; } GLenum getUsage() const { return mUsage; }
GLbitfield getAccessFlags() const { return mAccessFlags; } GLbitfield getAccessFlags() const { return mAccessFlags; }
......
...@@ -1301,7 +1301,7 @@ Error Context::drawElements(GLenum mode, ...@@ -1301,7 +1301,7 @@ Error Context::drawElements(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const RangeUI &indexRange) const IndexRange &indexRange)
{ {
syncRendererState(); syncRendererState();
return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange); return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
...@@ -1312,7 +1312,7 @@ Error Context::drawElementsInstanced(GLenum mode, ...@@ -1312,7 +1312,7 @@ Error Context::drawElementsInstanced(GLenum mode,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const RangeUI &indexRange) const IndexRange &indexRange)
{ {
syncRendererState(); syncRendererState();
return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances, return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
...@@ -1325,7 +1325,7 @@ Error Context::drawRangeElements(GLenum mode, ...@@ -1325,7 +1325,7 @@ Error Context::drawRangeElements(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const RangeUI &indexRange) const IndexRange &indexRange)
{ {
syncRendererState(); syncRendererState();
return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices, return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
......
...@@ -171,20 +171,20 @@ class Context final : angle::NonCopyable ...@@ -171,20 +171,20 @@ class Context final : angle::NonCopyable
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const RangeUI &indexRange); const IndexRange &indexRange);
Error drawElementsInstanced(GLenum mode, Error drawElementsInstanced(GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const RangeUI &indexRange); const IndexRange &indexRange);
Error drawRangeElements(GLenum mode, Error drawRangeElements(GLenum mode,
GLuint start, GLuint start,
GLuint end, GLuint end,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const RangeUI &indexRange); const IndexRange &indexRange);
Error flush(); Error flush();
Error finish(); Error finish();
......
...@@ -15,37 +15,22 @@ ...@@ -15,37 +15,22 @@
namespace gl namespace gl
{ {
void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range) void IndexRangeCache::addRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
const IndexRange &range)
{ {
mIndexRangeCache[IndexRange(type, offset, count)] = range; mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = range;
} }
void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size) bool IndexRangeCache::findRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
IndexRange *outRange) const
{ {
unsigned int invalidateStart = offset; auto i = mIndexRangeCache.find(IndexRangeKey(type, offset, count, primitiveRestartEnabled));
unsigned int invalidateEnd = offset + size;
IndexRangeMap::iterator i = mIndexRangeCache.begin();
while (i != mIndexRangeCache.end())
{
unsigned int rangeStart = i->first.offset;
unsigned int rangeEnd = i->first.offset + (GetTypeInfo(i->first.type).bytes * i->first.count);
if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
{
++i;
}
else
{
mIndexRangeCache.erase(i++);
}
}
}
bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
RangeUI *outRange) const
{
IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
if (i != mIndexRangeCache.end()) if (i != mIndexRangeCache.end())
{ {
if (outRange) if (outRange)
...@@ -58,34 +43,71 @@ bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, ...@@ -58,34 +43,71 @@ bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
{ {
if (outRange) if (outRange)
{ {
*outRange = RangeUI(0, 0); *outRange = IndexRange();
} }
return false; return false;
} }
} }
void IndexRangeCache::invalidateRange(size_t offset, size_t size)
{
size_t invalidateStart = offset;
size_t invalidateEnd = offset + size;
auto i = mIndexRangeCache.begin();
while (i != mIndexRangeCache.end())
{
size_t rangeStart = i->first.offset;
size_t rangeEnd = i->first.offset + (GetTypeInfo(i->first.type).bytes * i->first.count);
if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
{
++i;
}
else
{
mIndexRangeCache.erase(i++);
}
}
}
void IndexRangeCache::clear() void IndexRangeCache::clear()
{ {
mIndexRangeCache.clear(); mIndexRangeCache.clear();
} }
IndexRangeCache::IndexRange::IndexRange() IndexRangeCache::IndexRangeKey::IndexRangeKey()
: IndexRangeCache::IndexRange(GL_NONE, 0, 0) : IndexRangeCache::IndexRangeKey(GL_NONE, 0, 0, false)
{ {
} }
IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c) IndexRangeCache::IndexRangeKey::IndexRangeKey(GLenum type_,
: type(typ), size_t offset_,
offset(static_cast<unsigned int>(off)), size_t count_,
count(c) bool primitiveRestartEnabled_)
: type(type_), offset(offset_), count(count_), primitiveRestartEnabled(primitiveRestartEnabled_)
{ {
} }
bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const bool IndexRangeCache::IndexRangeKey::operator<(const IndexRangeKey &rhs) const
{ {
if (type != rhs.type) return type < rhs.type; if (type != rhs.type)
if (offset != rhs.offset) return offset < rhs.offset; {
return count < rhs.count; return type < rhs.type;
}
if (offset != rhs.offset)
{
return offset < rhs.offset;
}
if (count != rhs.count)
{
return count < rhs.count;
}
if (primitiveRestartEnabled != rhs.primitiveRestartEnabled)
{
return primitiveRestartEnabled;
}
return false;
} }
} }
...@@ -23,26 +23,35 @@ namespace gl ...@@ -23,26 +23,35 @@ namespace gl
class IndexRangeCache class IndexRangeCache
{ {
public: public:
void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range); void addRange(GLenum type,
bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut) const; size_t offset,
size_t count,
void invalidateRange(unsigned int offset, unsigned int size); bool primitiveRestartEnabled,
const IndexRange &range);
bool findRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
IndexRange *outRange) const;
void invalidateRange(size_t offset, size_t size);
void clear(); void clear();
private: private:
struct IndexRange struct IndexRangeKey
{ {
GLenum type; IndexRangeKey();
unsigned int offset; IndexRangeKey(GLenum type, size_t offset, size_t count, bool primitiveRestart);
GLsizei count;
IndexRange(); bool operator<(const IndexRangeKey &rhs) const;
IndexRange(GLenum type, intptr_t offset, GLsizei count);
bool operator<(const IndexRange& rhs) const; GLenum type;
size_t offset;
size_t count;
bool primitiveRestartEnabled;
}; };
typedef std::map<IndexRange, RangeUI> IndexRangeMap; typedef std::map<IndexRangeKey, IndexRange> IndexRangeMap;
IndexRangeMap mIndexRangeCache; IndexRangeMap mIndexRangeCache;
}; };
......
...@@ -30,7 +30,11 @@ class BufferImpl : angle::NonCopyable ...@@ -30,7 +30,11 @@ class BufferImpl : angle::NonCopyable
virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
virtual gl::Error unmap(GLboolean *result) = 0; virtual gl::Error unmap(GLboolean *result) = 0;
virtual gl::Error getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) = 0; virtual gl::Error getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange) = 0;
}; };
} }
......
...@@ -28,7 +28,7 @@ class MockBufferImpl : public BufferImpl ...@@ -28,7 +28,7 @@ class MockBufferImpl : public BufferImpl
MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **)); MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **));
MOCK_METHOD1(unmap, gl::Error(GLboolean *result)); MOCK_METHOD1(unmap, gl::Error(GLboolean *result));
MOCK_METHOD4(getIndexRange, gl::Error(GLenum, size_t, size_t, gl::RangeUI *)); MOCK_METHOD5(getIndexRange, gl::Error(GLenum, size_t, size_t, bool, gl::IndexRange *));
MOCK_METHOD0(destructor, void()); MOCK_METHOD0(destructor, void());
}; };
......
...@@ -58,14 +58,14 @@ class Renderer : public ImplFactory ...@@ -58,14 +58,14 @@ class Renderer : public ImplFactory
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) = 0; const gl::IndexRange &indexRange) = 0;
virtual gl::Error drawElementsInstanced(const gl::Data &data, virtual gl::Error drawElementsInstanced(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) = 0; const gl::IndexRange &indexRange) = 0;
virtual gl::Error drawRangeElements(const gl::Data &data, virtual gl::Error drawRangeElements(const gl::Data &data,
GLenum mode, GLenum mode,
GLuint start, GLuint start,
...@@ -73,7 +73,7 @@ class Renderer : public ImplFactory ...@@ -73,7 +73,7 @@ class Renderer : public ImplFactory
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) = 0; const gl::IndexRange &indexRange) = 0;
// lost device // lost device
//TODO(jmadill): investigate if this stuff is necessary in GL //TODO(jmadill): investigate if this stuff is necessary in GL
......
...@@ -107,7 +107,11 @@ void BufferD3D::promoteStaticUsage(int dataSize) ...@@ -107,7 +107,11 @@ void BufferD3D::promoteStaticUsage(int dataSize)
} }
} }
gl::Error BufferD3D::getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) gl::Error BufferD3D::getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange)
{ {
const uint8_t *data = nullptr; const uint8_t *data = nullptr;
gl::Error error = getData(&data); gl::Error error = getData(&data);
...@@ -116,7 +120,7 @@ gl::Error BufferD3D::getIndexRange(GLenum type, size_t offset, size_t count, gl: ...@@ -116,7 +120,7 @@ gl::Error BufferD3D::getIndexRange(GLenum type, size_t offset, size_t count, gl:
return error; return error;
} }
*outRange = gl::ComputeIndexRange(type, data + offset, static_cast<GLsizei>(count)); *outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -46,7 +46,11 @@ class BufferD3D : public BufferImpl ...@@ -46,7 +46,11 @@ class BufferD3D : public BufferImpl
void invalidateStaticData(); void invalidateStaticData();
void promoteStaticUsage(int dataSize); void promoteStaticUsage(int dataSize);
gl::Error getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) override; gl::Error getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange) override;
protected: protected:
void updateSerial(); void updateSerial();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "common/utilities.h"
#include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/BufferD3D.h"
#include "libANGLE/renderer/d3d/IndexBuffer.h" #include "libANGLE/renderer/d3d/IndexBuffer.h"
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
...@@ -123,9 +124,11 @@ gl::Error IndexDataManager::prepareIndexData(GLenum srcType, GLsizei count, gl:: ...@@ -123,9 +124,11 @@ gl::Error IndexDataManager::prepareIndexData(GLenum srcType, GLsizei count, gl::
{ {
// 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
bool hasPrimitiveRestartIndex =
translated->indexRange.vertexIndexCount < static_cast<size_t>(count) ||
translated->indexRange.end == gl::GetPrimitiveRestartIndex(srcType);
bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 && bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 &&
translated->indexRange.end == 0xFFFF && hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_SHORT;
srcType == GL_UNSIGNED_SHORT;
const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) ? const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) ?
GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
......
...@@ -38,7 +38,7 @@ class RendererD3D; ...@@ -38,7 +38,7 @@ class RendererD3D;
struct TranslatedIndexData struct TranslatedIndexData
{ {
gl::RangeUI indexRange; gl::IndexRange indexRange;
unsigned int startIndex; unsigned int startIndex;
unsigned int startOffset; // In bytes unsigned int startOffset; // In bytes
......
...@@ -86,7 +86,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data, ...@@ -86,7 +86,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
return genericDrawElements(data, mode, count, type, indices, 0, indexRange); return genericDrawElements(data, mode, count, type, indices, 0, indexRange);
} }
...@@ -97,7 +97,7 @@ gl::Error RendererD3D::drawElementsInstanced(const gl::Data &data, ...@@ -97,7 +97,7 @@ gl::Error RendererD3D::drawElementsInstanced(const gl::Data &data,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
return genericDrawElements(data, mode, count, type, indices, instances, indexRange); return genericDrawElements(data, mode, count, type, indices, instances, indexRange);
} }
...@@ -109,7 +109,7 @@ gl::Error RendererD3D::drawRangeElements(const gl::Data &data, ...@@ -109,7 +109,7 @@ gl::Error RendererD3D::drawRangeElements(const gl::Data &data,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
return genericDrawElements(data, mode, count, type, indices, 0, indexRange); return genericDrawElements(data, mode, count, type, indices, 0, indexRange);
} }
...@@ -120,7 +120,7 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data, ...@@ -120,7 +120,7 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
if (data.state->isPrimitiveRestartEnabled()) if (data.state->isPrimitiveRestartEnabled())
{ {
...@@ -175,8 +175,9 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data, ...@@ -175,8 +175,9 @@ gl::Error RendererD3D::genericDrawElements(const gl::Data &data,
// layer. // layer.
ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
GLsizei vertexCount = indexInfo.indexRange.length() + 1; size_t vertexCount = indexInfo.indexRange.vertexCount();
error = applyVertexBuffer(*data.state, mode, indexInfo.indexRange.start, vertexCount, instances, &sourceIndexInfo); error = applyVertexBuffer(*data.state, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
static_cast<GLsizei>(vertexCount), instances, &sourceIndexInfo);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -109,14 +109,14 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -109,14 +109,14 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
gl::Error drawElementsInstanced(const gl::Data &data, gl::Error drawElementsInstanced(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
gl::Error drawRangeElements(const gl::Data &data, gl::Error drawRangeElements(const gl::Data &data,
GLenum mode, GLenum mode,
GLuint start, GLuint start,
...@@ -124,7 +124,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -124,7 +124,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
bool isDeviceLost() const override; bool isDeviceLost() const override;
std::string getVendorString() const override; std::string getVendorString() const override;
...@@ -270,7 +270,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -270,7 +270,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange); const gl::IndexRange &indexRange);
virtual gl::Error drawArraysImpl(const gl::Data &data, virtual gl::Error drawArraysImpl(const gl::Data &data,
GLenum mode, GLenum mode,
......
...@@ -1549,10 +1549,12 @@ gl::Error Renderer9::drawElementsImpl(GLenum mode, ...@@ -1549,10 +1549,12 @@ gl::Error Renderer9::drawElementsImpl(GLenum mode,
} }
else else
{ {
size_t vertexCount = indexInfo.indexRange.vertexCount();
for (int i = 0; i < mRepeatDraw; i++) for (int i = 0; i < mRepeatDraw; i++)
{ {
GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1; mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex,
mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); static_cast<UINT>(vertexCount), indexInfo.startIndex,
mPrimitiveCount);
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -101,13 +101,17 @@ gl::Error BufferGL::unmap(GLboolean *result) ...@@ -101,13 +101,17 @@ gl::Error BufferGL::unmap(GLboolean *result)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error BufferGL::getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) gl::Error BufferGL::getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange)
{ {
ASSERT(!mIsMapped); ASSERT(!mIsMapped);
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
const uint8_t *bufferData = reinterpret_cast<uint8_t*>(mFunctions->mapBuffer(DestBufferOperationTarget, GL_READ_ONLY)); const uint8_t *bufferData = reinterpret_cast<uint8_t*>(mFunctions->mapBuffer(DestBufferOperationTarget, GL_READ_ONLY));
*outRange = gl::ComputeIndexRange(type, bufferData + offset, static_cast<GLsizei>(count)); *outRange = gl::ComputeIndexRange(type, bufferData + offset, count, primitiveRestartEnabled);
mFunctions->unmapBuffer(DestBufferOperationTarget); mFunctions->unmapBuffer(DestBufferOperationTarget);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
......
...@@ -30,7 +30,11 @@ class BufferGL : public BufferImpl ...@@ -30,7 +30,11 @@ class BufferGL : public BufferImpl
gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
gl::Error unmap(GLboolean *result) override; gl::Error unmap(GLboolean *result) override;
gl::Error getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) override; gl::Error getIndexRange(GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange) override;
GLuint getBufferID() const; GLuint getBufferID() const;
......
...@@ -170,7 +170,7 @@ gl::Error RendererGL::drawElements(const gl::Data &data, ...@@ -170,7 +170,7 @@ gl::Error RendererGL::drawElements(const gl::Data &data,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
const GLvoid *drawIndexPointer = nullptr; const GLvoid *drawIndexPointer = nullptr;
gl::Error error = gl::Error error =
...@@ -194,7 +194,7 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Data &data, ...@@ -194,7 +194,7 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Data &data,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
const GLvoid *drawIndexPointer = nullptr; const GLvoid *drawIndexPointer = nullptr;
gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances, gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances,
...@@ -219,7 +219,7 @@ gl::Error RendererGL::drawRangeElements(const gl::Data &data, ...@@ -219,7 +219,7 @@ gl::Error RendererGL::drawRangeElements(const gl::Data &data,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) const gl::IndexRange &indexRange)
{ {
const GLvoid *drawIndexPointer = nullptr; const GLvoid *drawIndexPointer = nullptr;
gl::Error error = gl::Error error =
......
...@@ -40,14 +40,14 @@ class RendererGL : public Renderer ...@@ -40,14 +40,14 @@ class RendererGL : public Renderer
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
gl::Error drawElementsInstanced(const gl::Data &data, gl::Error drawElementsInstanced(const gl::Data &data,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
gl::Error drawRangeElements(const gl::Data &data, gl::Error drawRangeElements(const gl::Data &data,
GLenum mode, GLenum mode,
GLuint start, GLuint start,
...@@ -55,7 +55,7 @@ class RendererGL : public Renderer ...@@ -55,7 +55,7 @@ class RendererGL : public Renderer
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
const gl::RangeUI &indexRange) override; const gl::IndexRange &indexRange) override;
// Shader creation // Shader creation
CompilerImpl *createCompiler(const gl::Data &data) override; CompilerImpl *createCompiler(const gl::Data &data) override;
......
...@@ -448,8 +448,9 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, ...@@ -448,8 +448,9 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data,
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
gl::Error error = vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count, gl::Error error =
type, indices, instanceCount, outIndices); vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count, type, indices,
instanceCount, state.isPrimitiveRestartEnabled(), outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -80,7 +80,7 @@ gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAtt ...@@ -80,7 +80,7 @@ gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAtt
GLsizei count, GLsizei count,
GLsizei instanceCount) const GLsizei instanceCount) const
{ {
return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, instanceCount, return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, instanceCount, false,
nullptr); nullptr);
} }
...@@ -89,9 +89,11 @@ gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeA ...@@ -89,9 +89,11 @@ gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeA
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount, GLsizei instanceCount,
bool primitiveRestartEnabled,
const GLvoid **outIndices) const const GLvoid **outIndices) const
{ {
return syncDrawState(activeAttributesMask, 0, count, type, indices, instanceCount, outIndices); return syncDrawState(activeAttributesMask, 0, count, type, indices, instanceCount,
primitiveRestartEnabled, outIndices);
} }
gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask,
...@@ -100,6 +102,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -100,6 +102,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount, GLsizei instanceCount,
bool primitiveRestartEnabled,
const GLvoid **outIndices) const const GLvoid **outIndices) const
{ {
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
...@@ -108,11 +111,11 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -108,11 +111,11 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
bool attributesNeedStreaming = mAttributesNeedStreaming.any(); bool attributesNeedStreaming = mAttributesNeedStreaming.any();
// Determine if an index buffer needs to be streamed and the range of vertices that need to be copied // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied
RangeUI indexRange(0, 0); IndexRange indexRange;
if (type != GL_NONE) if (type != GL_NONE)
{ {
Error error = Error error = syncIndexData(count, type, indices, primitiveRestartEnabled,
syncIndexData(count, type, indices, attributesNeedStreaming, &indexRange, outIndices); attributesNeedStreaming, &indexRange, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -140,8 +143,9 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -140,8 +143,9 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
Error VertexArrayGL::syncIndexData(GLsizei count, Error VertexArrayGL::syncIndexData(GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
bool primitiveRestartEnabled,
bool attributesNeedStreaming, bool attributesNeedStreaming,
RangeUI *outIndexRange, IndexRange *outIndexRange,
const GLvoid **outIndices) const const GLvoid **outIndices) const
{ {
ASSERT(outIndices); ASSERT(outIndices);
...@@ -163,7 +167,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -163,7 +167,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
{ {
ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices); ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices);
Error error = mData.getElementArrayBuffer()->getIndexRange( Error error = mData.getElementArrayBuffer()->getIndexRange(
type, static_cast<size_t>(elementArrayBufferOffset), count, outIndexRange); type, elementArrayBufferOffset, count, primitiveRestartEnabled, outIndexRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -181,7 +185,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -181,7 +185,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
// Only compute the index range if the attributes also need to be streamed // Only compute the index range if the attributes also need to be streamed
if (attributesNeedStreaming) if (attributesNeedStreaming)
{ {
*outIndexRange = ComputeIndexRange(type, indices, count); *outIndexRange = ComputeIndexRange(type, indices, count, primitiveRestartEnabled);
} }
// Allocate the streaming element array buffer // Allocate the streaming element array buffer
...@@ -218,7 +222,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -218,7 +222,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
GLsizei instanceCount, GLsizei instanceCount,
const gl::RangeUI &indexRange, const gl::IndexRange &indexRange,
size_t *outStreamingDataSize, size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const size_t *outMaxAttributeDataSize) const
{ {
...@@ -233,21 +237,19 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act ...@@ -233,21 +237,19 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act
const auto &attrib = attribs[idx]; const auto &attrib = attribs[idx];
ASSERT(AttributeNeedsStreaming(attrib)); ASSERT(AttributeNeedsStreaming(attrib));
const size_t vertexCount = indexRange.end - indexRange.start + 1;
// If streaming is going to be required, compute the size of the required buffer // If streaming is going to be required, compute the size of the required buffer
// and how much slack space at the beginning of the buffer will be required by determining // and how much slack space at the beginning of the buffer will be required by determining
// the attribute with the largest data size. // the attribute with the largest data size.
size_t typeSize = ComputeVertexAttributeTypeSize(attrib); size_t typeSize = ComputeVertexAttributeTypeSize(attrib);
*outStreamingDataSize += *outStreamingDataSize += typeSize * ComputeVertexAttributeElementCount(
typeSize * ComputeVertexAttributeElementCount(attrib, vertexCount, instanceCount); attrib, indexRange.vertexCount(), instanceCount);
*outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize); *outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize);
} }
} }
gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask,
GLsizei instanceCount, GLsizei instanceCount,
const gl::RangeUI &indexRange) const const gl::IndexRange &indexRange) const
{ {
// Sync the vertex attribute state and track what data needs to be streamed // Sync the vertex attribute state and track what data needs to be streamed
size_t streamingDataSize = 0; size_t streamingDataSize = 0;
...@@ -289,8 +291,6 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -289,8 +291,6 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
uint8_t *bufferPointer = reinterpret_cast<uint8_t*>(mFunctions->mapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); uint8_t *bufferPointer = reinterpret_cast<uint8_t*>(mFunctions->mapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
size_t curBufferOffset = bufferEmptySpace; size_t curBufferOffset = bufferEmptySpace;
const size_t vertexCount = indexRange.end - indexRange.start + 1;
const auto &attribs = mData.getVertexAttributes(); const auto &attribs = mData.getVertexAttributes();
for (unsigned int idx : for (unsigned int idx :
angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask)) angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
...@@ -299,7 +299,7 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -299,7 +299,7 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
ASSERT(AttributeNeedsStreaming(attrib)); ASSERT(AttributeNeedsStreaming(attrib));
const size_t streamedVertexCount = const size_t streamedVertexCount =
ComputeVertexAttributeElementCount(attrib, vertexCount, instanceCount); ComputeVertexAttributeElementCount(attrib, indexRange.vertexCount(), instanceCount);
const size_t sourceStride = ComputeVertexAttributeStride(attrib); const size_t sourceStride = ComputeVertexAttributeStride(attrib);
const size_t destStride = ComputeVertexAttributeTypeSize(attrib); const size_t destStride = ComputeVertexAttributeTypeSize(attrib);
......
...@@ -32,6 +32,7 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -32,6 +32,7 @@ class VertexArrayGL : public VertexArrayImpl
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount, GLsizei instanceCount,
bool primitiveRestartEnabled,
const GLvoid **outIndices) const; const GLvoid **outIndices) const;
GLuint getVertexArrayID() const; GLuint getVertexArrayID() const;
...@@ -46,24 +47,30 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -46,24 +47,30 @@ class VertexArrayGL : public VertexArrayImpl
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount, GLsizei instanceCount,
bool primitiveRestartEnabled,
const GLvoid **outIndices) const; const GLvoid **outIndices) const;
// Apply index data, only sets outIndexRange if attributesNeedStreaming is true // Apply index data, only sets outIndexRange if attributesNeedStreaming is true
gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming, gl::Error syncIndexData(GLsizei count,
gl::RangeUI *outIndexRange, const GLvoid **outIndices) const; GLenum type,
const GLvoid *indices,
bool primitiveRestartEnabled,
bool attributesNeedStreaming,
gl::IndexRange *outIndexRange,
const GLvoid **outIndices) const;
// Returns the amount of space needed to stream all attributes that need streaming // Returns the amount of space needed to stream all attributes that need streaming
// and the data size of the largest attribute // and the data size of the largest attribute
void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
GLsizei instanceCount, GLsizei instanceCount,
const gl::RangeUI &indexRange, const gl::IndexRange &indexRange,
size_t *outStreamingDataSize, size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const; size_t *outMaxAttributeDataSize) const;
// Stream attributes that have client data // Stream attributes that have client data
gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask, gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask,
GLsizei instanceCount, GLsizei instanceCount,
const gl::RangeUI &indexRange) const; const gl::IndexRange &indexRange) const;
void updateNeedsStreaming(size_t attribIndex); void updateNeedsStreaming(size_t attribIndex);
void updateAttribEnabled(size_t attribIndex); void updateAttribEnabled(size_t attribIndex);
......
...@@ -1642,8 +1642,13 @@ bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first ...@@ -1642,8 +1642,13 @@ bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first
return ValidateDrawArraysInstanced(context, mode, first, count, primcount); return ValidateDrawArraysInstanced(context, mode, first, count, primcount);
} }
bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElements(Context *context,
const GLvoid *indices, GLsizei primcount, RangeUI *indexRangeOut) GLenum mode,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei primcount,
IndexRange *indexRangeOut)
{ {
switch (type) switch (type)
{ {
...@@ -1728,7 +1733,9 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t ...@@ -1728,7 +1733,9 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
if (elementArrayBuffer) if (elementArrayBuffer)
{ {
uintptr_t offset = reinterpret_cast<uintptr_t>(indices); uintptr_t offset = reinterpret_cast<uintptr_t>(indices);
Error error = elementArrayBuffer->getIndexRange(type, static_cast<size_t>(offset), count, indexRangeOut); Error error =
elementArrayBuffer->getIndexRange(type, static_cast<size_t>(offset), count,
state.isPrimitiveRestartEnabled(), indexRangeOut);
if (error.isError()) if (error.isError())
{ {
context->recordError(error); context->recordError(error);
...@@ -1737,7 +1744,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t ...@@ -1737,7 +1744,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
} }
else else
{ {
*indexRangeOut = ComputeIndexRange(type, indices, count); *indexRangeOut = ComputeIndexRange(type, indices, count, state.isPrimitiveRestartEnabled());
} }
if (!ValidateDrawAttribs(context, primcount, static_cast<GLsizei>(indexRangeOut->end))) if (!ValidateDrawAttribs(context, primcount, static_cast<GLsizei>(indexRangeOut->end)))
...@@ -1745,13 +1752,17 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t ...@@ -1745,13 +1752,17 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
return false; return false;
} }
return true; // No op if there are no real indices in the index data (all are primitive restart).
return (indexRangeOut->vertexIndexCount > 0);
} }
bool ValidateDrawElementsInstanced(Context *context, bool ValidateDrawElementsInstanced(Context *context,
GLenum mode, GLsizei count, GLenum type, GLenum mode,
const GLvoid *indices, GLsizei primcount, GLsizei count,
RangeUI *indexRangeOut) GLenum type,
const GLvoid *indices,
GLsizei primcount,
IndexRange *indexRangeOut)
{ {
if (primcount < 0) if (primcount < 0)
{ {
...@@ -1768,8 +1779,13 @@ bool ValidateDrawElementsInstanced(Context *context, ...@@ -1768,8 +1779,13 @@ bool ValidateDrawElementsInstanced(Context *context,
return (primcount > 0); return (primcount > 0);
} }
bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElementsInstancedANGLE(Context *context,
const GLvoid *indices, GLsizei primcount, RangeUI *indexRangeOut) GLenum mode,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei primcount,
IndexRange *indexRangeOut)
{ {
if (!ValidateDrawInstancedANGLE(context)) if (!ValidateDrawInstancedANGLE(context))
{ {
......
...@@ -87,13 +87,28 @@ bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei coun ...@@ -87,13 +87,28 @@ bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei coun
bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElements(Context *context,
const GLvoid *indices, GLsizei primcount, RangeUI *indexRangeOut); GLenum mode,
GLsizei count,
bool ValidateDrawElementsInstanced(Context *context, GLenum mode, GLsizei count, GLenum type, GLenum type,
const GLvoid *indices, GLsizei primcount, RangeUI *indexRangeOut); const GLvoid *indices,
bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, GLsizei primcount,
const GLvoid *indices, GLsizei primcount, RangeUI *indexRangeOut); IndexRange *indexRangeOut);
bool ValidateDrawElementsInstanced(Context *context,
GLenum mode,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei primcount,
IndexRange *indexRangeOut);
bool ValidateDrawElementsInstancedANGLE(Context *context,
GLenum mode,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei primcount,
IndexRange *indexRangeOut);
bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level); GLuint texture, GLint level);
......
...@@ -1184,7 +1184,7 @@ void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLv ...@@ -1184,7 +1184,7 @@ void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
RangeUI indexRange; IndexRange indexRange;
if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
{ {
return; return;
......
...@@ -117,7 +117,7 @@ void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t ...@@ -117,7 +117,7 @@ void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
RangeUI indexRange; IndexRange indexRange;
if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange)) if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
{ {
return; return;
......
...@@ -59,7 +59,7 @@ void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize ...@@ -59,7 +59,7 @@ void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize
return; return;
} }
RangeUI indexRange; IndexRange indexRange;
if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
{ {
return; return;
...@@ -2264,7 +2264,7 @@ void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, ...@@ -2264,7 +2264,7 @@ void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
return; return;
} }
RangeUI indexRange; IndexRange indexRange;
if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange)) if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange))
{ {
return; return;
......
...@@ -157,7 +157,8 @@ void IndexDataManagerPerfTest::step(float dt, double totalTime) ...@@ -157,7 +157,8 @@ void IndexDataManagerPerfTest::step(float dt, double totalTime)
rx::SourceIndexData sourceIndexData; rx::SourceIndexData sourceIndexData;
for (unsigned int iteration = 0; iteration < 100; ++iteration) for (unsigned int iteration = 0; iteration < 100; ++iteration)
{ {
mIndexBuffer.getIndexRange(GL_UNSIGNED_SHORT, 0, mIndexCount, &translatedIndexData.indexRange); mIndexBuffer.getIndexRange(GL_UNSIGNED_SHORT, 0, mIndexCount, false,
&translatedIndexData.indexRange);
mIndexDataManager.prepareIndexData(GL_UNSIGNED_SHORT, mIndexCount, &mIndexBuffer, nullptr, &translatedIndexData, &sourceIndexData); mIndexDataManager.prepareIndexData(GL_UNSIGNED_SHORT, mIndexCount, &mIndexBuffer, nullptr, &translatedIndexData, &sourceIndexData);
} }
......
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