Commit 3cf12ce6 by Geoff Lang

Implement the instanced draw calls in RendererGL.

BUG=angleproject:1136 Change-Id: I1167365618bdc3ca37ac0f4c60809de32c7a9d78 Reviewed-on: https://chromium-review.googlesource.com/295733Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 5b49bb83
...@@ -52,4 +52,23 @@ size_t ComputeVertexAttributeStride(const VertexAttribute& attrib) ...@@ -52,4 +52,23 @@ size_t ComputeVertexAttributeStride(const VertexAttribute& attrib)
return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib); return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib);
} }
size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib,
size_t drawCount,
size_t instanceCount)
{
// For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
//
// A vertex attribute with a positive divisor loads one instanced vertex for every set of
// non-instanced vertices, and the instanced vertex index advances once every "mDivisor"
// instances.
if (instanceCount > 0 && attrib.divisor > 0)
{
// When instanceDrawCount is not a multiple attrib.divisor, the division must round up.
// For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced
// vertices.
return (instanceCount + attrib.divisor - 1u) / attrib.divisor;
}
return drawCount;
}
} }
...@@ -44,6 +44,9 @@ T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pnam ...@@ -44,6 +44,9 @@ T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pnam
size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib); size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib);
size_t ComputeVertexAttributeStride(const VertexAttribute& attrib); size_t ComputeVertexAttributeStride(const VertexAttribute& attrib);
size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib,
size_t drawCount,
size_t instanceCount);
struct VertexAttribCurrentValueData struct VertexAttribCurrentValueData
{ {
......
...@@ -41,22 +41,6 @@ static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size ...@@ -41,22 +41,6 @@ static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size
stride; stride;
} }
static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int vertexDrawCount, int instanceDrawCount)
{
// For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
//
// A vertex attribute with a positive divisor loads one instanced vertex for every set of
// non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
if (instanceDrawCount > 0 && attrib.divisor > 0)
{
// When instanceDrawCount is not a multiple attrib.divisor, the division must round up.
// For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced vertices.
return (instanceDrawCount + attrib.divisor - 1) / attrib.divisor;
}
return vertexDrawCount;
}
VertexDataManager::CurrentValueState::CurrentValueState() VertexDataManager::CurrentValueState::CurrentValueState()
: buffer(nullptr), : buffer(nullptr),
offset(0) offset(0)
...@@ -278,12 +262,13 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr ...@@ -278,12 +262,13 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr
} }
else else
{ {
int totalCount = StreamingBufferElementCount(attrib, count, instances); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
ASSERT(!bufferImpl || ASSERT(!bufferImpl ||
ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize())) >= ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize())) >=
totalCount); totalCount);
gl::Error error = mStreamingBuffer->reserveVertexSpace(attrib, totalCount, instances); gl::Error error = mStreamingBuffer->reserveVertexSpace(
attrib, static_cast<GLsizei>(totalCount), instances);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -388,20 +373,16 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -388,20 +373,16 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
} }
else else
{ {
int totalCount = StreamingBufferElementCount(attrib, count, instances); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
error = mStreamingBuffer->storeVertexAttributes(attrib, error = mStreamingBuffer->storeVertexAttributes(
translated->currentValueType, attrib, translated->currentValueType, firstVertexIndex,
firstVertexIndex, static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData);
totalCount,
instances,
&streamOffset,
sourceData);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -71,7 +71,6 @@ static void AssignGLExtensionEntryPoint(const std::vector<std::string> &extensio ...@@ -71,7 +71,6 @@ static void AssignGLExtensionEntryPoint(const std::vector<std::string> &extensio
{ {
if (std::find(extensions.begin(), extensions.end(), requiredExtension) == extensions.end()) if (std::find(extensions.begin(), extensions.end(), requiredExtension) == extensions.end())
{ {
*outFunction = nullptr;
return; return;
} }
} }
...@@ -798,6 +797,8 @@ void FunctionsGL::initialize() ...@@ -798,6 +797,8 @@ void FunctionsGL::initialize()
profile = 0; profile = 0;
} }
// clang-format off
// Load extensions // Load extensions
// Even though extensions are written against specific versions of GL, many drivers expose the extensions // Even though extensions are written against specific versions of GL, many drivers expose the extensions
// in even older versions. Always try loading the extensions regardless of GL version. // in even older versions. Always try loading the extensions regardless of GL version.
...@@ -880,6 +881,17 @@ void FunctionsGL::initialize() ...@@ -880,6 +881,17 @@ void FunctionsGL::initialize()
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glDepthRangef"), &depthRangef); AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glDepthRangef"), &depthRangef);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glClearDepthf"), &clearDepthf); AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glClearDepthf"), &clearDepthf);
// GL_ARB_instanced_arrays
AssignGLExtensionEntryPoint(extensions, "GL_ARB_instanced_arrays", loadProcAddress("glVertexAttribDivisorARB"), &vertexAttribDivisor);
// GL_EXT_draw_instanced
AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawArraysInstancedEXT"), &drawArraysInstanced);
AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawElementsInstancedEXT"), &drawElementsInstanced);
// GL_ARB_draw_instanced
AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawArraysInstancedARB"), &drawArraysInstanced);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawElementsInstancedARB"), &drawElementsInstanced);
// 1.0 // 1.0
if (isAtLeastGL(gl::Version(1, 0))) if (isAtLeastGL(gl::Version(1, 0)))
{ {
...@@ -1622,6 +1634,8 @@ void FunctionsGL::initialize() ...@@ -1622,6 +1634,8 @@ void FunctionsGL::initialize()
AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffer"), &vertexArrayVertexBuffer); AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffer"), &vertexArrayVertexBuffer);
AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffers"), &vertexArrayVertexBuffers); AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffers"), &vertexArrayVertexBuffers);
} }
// clang-format on
} }
bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
......
...@@ -131,7 +131,7 @@ gl::Error RendererGL::finish() ...@@ -131,7 +131,7 @@ gl::Error RendererGL::finish()
gl::Error RendererGL::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) gl::Error RendererGL::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count)
{ {
gl::Error error = mStateManager->setDrawArraysState(data, first, count); gl::Error error = mStateManager->setDrawArraysState(data, first, count, 0);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -151,7 +151,17 @@ gl::Error RendererGL::drawArraysInstanced(const gl::Data &data, ...@@ -151,7 +151,17 @@ gl::Error RendererGL::drawArraysInstanced(const gl::Data &data,
GLsizei count, GLsizei count,
GLsizei instanceCount) GLsizei instanceCount)
{ {
UNIMPLEMENTED(); gl::Error error = mStateManager->setDrawArraysState(data, first, count, instanceCount);
if (error.isError())
{
return error;
}
if (!mSkipDrawCalls)
{
mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
}
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -163,7 +173,8 @@ gl::Error RendererGL::drawElements(const gl::Data &data, ...@@ -163,7 +173,8 @@ gl::Error RendererGL::drawElements(const gl::Data &data,
const gl::RangeUI &indexRange) const gl::RangeUI &indexRange)
{ {
const GLvoid *drawIndexPointer = nullptr; const GLvoid *drawIndexPointer = nullptr;
gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, &drawIndexPointer); gl::Error error =
mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -185,7 +196,19 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Data &data, ...@@ -185,7 +196,19 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Data &data,
GLsizei instances, GLsizei instances,
const gl::RangeUI &indexRange) const gl::RangeUI &indexRange)
{ {
UNIMPLEMENTED(); const GLvoid *drawIndexPointer = nullptr;
gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances,
&drawIndexPointer);
if (error.isError())
{
return error;
}
if (!mSkipDrawCalls)
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances);
}
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -401,7 +401,10 @@ void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer) ...@@ -401,7 +401,10 @@ void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
} }
} }
gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, GLsizei count) gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data,
GLint first,
GLsizei count,
GLsizei instanceCount)
{ {
const gl::State &state = *data.state; const gl::State &state = *data.state;
...@@ -410,8 +413,8 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, ...@@ -410,8 +413,8 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first,
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 = gl::Error error = vaoGL->syncDrawArraysState(program->getActiveAttribLocationsMask(), first,
vaoGL->syncDrawArraysState(program->getActiveAttribLocationsMask(), first, count); count, instanceCount);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -422,7 +425,11 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, ...@@ -422,7 +425,11 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first,
return setGenericDrawState(data); return setGenericDrawState(data);
} }
gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei count, GLenum type, const GLvoid *indices, gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei instanceCount,
const GLvoid **outIndices) const GLvoid **outIndices)
{ {
const gl::State &state = *data.state; const gl::State &state = *data.state;
...@@ -433,7 +440,7 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou ...@@ -433,7 +440,7 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
gl::Error error = vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count, gl::Error error = vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count,
type, indices, outIndices); type, indices, instanceCount, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -105,8 +105,15 @@ class StateManagerGL final : angle::NonCopyable ...@@ -105,8 +105,15 @@ class StateManagerGL final : angle::NonCopyable
void setPixelPackState(const gl::PixelPackState &pack); void setPixelPackState(const gl::PixelPackState &pack);
void setPixelPackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels); void setPixelPackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels);
gl::Error setDrawArraysState(const gl::Data &data, GLint first, GLsizei count); gl::Error setDrawArraysState(const gl::Data &data,
gl::Error setDrawElementsState(const gl::Data &data, GLsizei count, GLenum type, const GLvoid *indices, GLint first,
GLsizei count,
GLsizei instanceCount);
gl::Error setDrawElementsState(const gl::Data &data,
GLsizei count,
GLenum type,
const GLvoid *indices,
GLsizei instanceCount,
const GLvoid **outIndices); const GLvoid **outIndices);
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
......
...@@ -77,18 +77,21 @@ VertexArrayGL::~VertexArrayGL() ...@@ -77,18 +77,21 @@ VertexArrayGL::~VertexArrayGL()
gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAttributesMask,
GLint first, GLint first,
GLsizei count) const GLsizei count,
GLsizei instanceCount) const
{ {
return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, nullptr); return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, instanceCount,
nullptr);
} }
gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeAttributesMask,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount,
const GLvoid **outIndices) const const GLvoid **outIndices) const
{ {
return syncDrawState(activeAttributesMask, 0, count, type, indices, outIndices); return syncDrawState(activeAttributesMask, 0, count, type, indices, instanceCount, outIndices);
} }
gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask,
...@@ -96,6 +99,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -96,6 +99,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount,
const GLvoid **outIndices) const const GLvoid **outIndices) const
{ {
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
...@@ -123,7 +127,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -123,7 +127,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
if (attributesNeedStreaming) if (attributesNeedStreaming)
{ {
Error error = streamAttributes(activeAttributesMask, indexRange); Error error = streamAttributes(activeAttributesMask, instanceCount, indexRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -213,6 +217,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -213,6 +217,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
} }
void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
GLsizei instanceCount,
const gl::RangeUI &indexRange, const gl::RangeUI &indexRange,
size_t *outStreamingDataSize, size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const size_t *outMaxAttributeDataSize) const
...@@ -228,26 +233,28 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act ...@@ -228,26 +233,28 @@ 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 streamedVertexCount = indexRange.end - indexRange.start + 1; 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 += typeSize * streamedVertexCount; *outStreamingDataSize +=
typeSize * ComputeVertexAttributeElementCount(attrib, 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,
const gl::RangeUI &indexRange) const const gl::RangeUI &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;
size_t maxAttributeDataSize = 0; size_t maxAttributeDataSize = 0;
computeStreamingAttributeSizes(activeAttributesMask, indexRange, &streamingDataSize, computeStreamingAttributeSizes(activeAttributesMask, instanceCount, indexRange,
&maxAttributeDataSize); &streamingDataSize, &maxAttributeDataSize);
if (streamingDataSize == 0) if (streamingDataSize == 0)
{ {
...@@ -282,7 +289,7 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -282,7 +289,7 @@ 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 streamedVertexCount = indexRange.end - indexRange.start + 1; 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 :
...@@ -291,6 +298,9 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -291,6 +298,9 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
const auto &attrib = attribs[idx]; const auto &attrib = attribs[idx];
ASSERT(AttributeNeedsStreaming(attrib)); ASSERT(AttributeNeedsStreaming(attrib));
const size_t streamedVertexCount =
ComputeVertexAttributeElementCount(attrib, 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);
......
...@@ -25,11 +25,13 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -25,11 +25,13 @@ class VertexArrayGL : public VertexArrayImpl
gl::Error syncDrawArraysState(const gl::AttributesMask &activeAttributesMask, gl::Error syncDrawArraysState(const gl::AttributesMask &activeAttributesMask,
GLint first, GLint first,
GLsizei count) const; GLsizei count,
GLsizei instanceCount) const;
gl::Error syncDrawElementsState(const gl::AttributesMask &activeAttributesMask, gl::Error syncDrawElementsState(const gl::AttributesMask &activeAttributesMask,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount,
const GLvoid **outIndices) const; const GLvoid **outIndices) const;
GLuint getVertexArrayID() const; GLuint getVertexArrayID() const;
...@@ -43,6 +45,7 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -43,6 +45,7 @@ class VertexArrayGL : public VertexArrayImpl
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const GLvoid *indices, const GLvoid *indices,
GLsizei instanceCount,
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
...@@ -52,12 +55,14 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -52,12 +55,14 @@ class VertexArrayGL : public VertexArrayImpl
// 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,
const gl::RangeUI &indexRange, const gl::RangeUI &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,
const gl::RangeUI &indexRange) const; const gl::RangeUI &indexRange) const;
void updateNeedsStreaming(size_t attribIndex); void updateNeedsStreaming(size_t attribIndex);
......
...@@ -532,6 +532,12 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM ...@@ -532,6 +532,12 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_frag_depth"); functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_frag_depth");
extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") || extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_fbo_render_mipmap"); functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
extensions->instancedArrays = functions->isAtLeastGL(gl::Version(3, 1)) ||
(functions->hasGLExtension("GL_ARB_instanced_arrays") &&
(functions->hasGLExtension("GL_ARB_draw_instanced") ||
functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
functions->isAtLeastGLES(gl::Version(3, 0)) ||
functions->hasGLESExtension("GL_EXT_instanced_arrays");
} }
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds) void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
......
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