Commit b5560486 by shrekshao Committed by Commit Bot

BaseInstance VertexAttribDivisor fix

Add tests not using gl_InstanceID/gl_BaseInstance but set vertexAttribDivisor which implicitly reference base instance value. Add fixes and workarounds based on this change. Bug: chromium:891861, angleproject:3402 Change-Id: I2d93c181029f4ca1741f244363568096964d6b19 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1779350 Commit-Queue: Shrek Shao <shrekshao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3a2e01ed
......@@ -268,7 +268,7 @@ angle::Result Context11::drawArrays(const gl::Context *context,
ASSERT(count > 0);
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0));
return mRenderer->drawArrays(context, mode, first, count, 0);
return mRenderer->drawArrays(context, mode, first, count, 0, 0);
}
angle::Result Context11::drawArraysInstanced(const gl::Context *context,
......@@ -280,7 +280,7 @@ angle::Result Context11::drawArraysInstanced(const gl::Context *context,
ASSERT(count > 0);
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, instanceCount, 0));
return mRenderer->drawArrays(context, mode, first, count, instanceCount);
return mRenderer->drawArrays(context, mode, first, count, instanceCount, 0);
}
angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *context,
......@@ -290,7 +290,10 @@ angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *cont
GLsizei instanceCount,
GLuint baseInstance)
{
return drawArraysInstanced(context, mode, first, count, instanceCount);
ASSERT(count > 0);
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, instanceCount, 0));
return mRenderer->drawArrays(context, mode, first, count, instanceCount, baseInstance);
}
ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *context,
......@@ -380,7 +383,8 @@ angle::Result Context11::drawArraysIndirect(const gl::Context *context,
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, cmd->first, cmd->count,
gl::DrawElementsType::InvalidEnum,
nullptr, cmd->instanceCount, 0));
return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount);
return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount,
cmd->baseInstance);
}
else
{
......
......@@ -1476,7 +1476,8 @@ angle::Result Renderer11::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
GLsizei vertexCount,
GLsizei instanceCount)
GLsizei instanceCount,
GLuint baseInstance)
{
if (mStateManager.getCullEverything())
{
......@@ -1520,7 +1521,7 @@ angle::Result Renderer11::drawArrays(const gl::Context *context,
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
if (adjustedInstanceCount == 0)
{
mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance);
return angle::Result::Continue;
}
......@@ -1534,7 +1535,7 @@ angle::Result Renderer11::drawArrays(const gl::Context *context,
{
ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(
context, firstVertex, i));
mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, 0);
mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance);
}
// This required by updateVertexOffsets... above but is outside of the loop for
......@@ -1554,7 +1555,7 @@ angle::Result Renderer11::drawArrays(const gl::Context *context,
}
else
{
mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, 0);
mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, baseInstance);
}
return angle::Result::Continue;
}
......
......@@ -410,7 +410,8 @@ class Renderer11 : public RendererD3D
gl::PrimitiveMode mode,
GLint firstVertex,
GLsizei vertexCount,
GLsizei instanceCount);
GLsizei instanceCount,
GLuint baseInstance);
angle::Result drawElements(const gl::Context *context,
gl::PrimitiveMode mode,
GLint startVertex,
......
......@@ -294,6 +294,82 @@ angle::Result ContextGL::drawArraysInstanced(const gl::Context *context,
return angle::Result::Continue;
}
gl::AttributesMask ContextGL::updateAttributesForBaseInstance(const gl::Program *program,
GLuint baseInstance)
{
gl::AttributesMask attribToUpdateMask;
if (baseInstance != 0)
{
const FunctionsGL *functions = getFunctions();
const auto &attribs = mState.getVertexArray()->getVertexAttributes();
const auto &bindings = mState.getVertexArray()->getVertexBindings();
for (GLuint attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
{
const gl::VertexAttribute &attrib = attribs[attribIndex];
const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
if (program->isAttribLocationActive(attribIndex) && binding.getDivisor() != 0)
{
attribToUpdateMask.set(attribIndex);
const char *p = static_cast<const char *>(attrib.pointer);
const size_t sourceStride = gl::ComputeVertexAttributeStride(attrib, binding);
const void *newPointer = p + sourceStride * baseInstance;
const BufferGL *buffer = GetImplAs<BufferGL>(binding.getBuffer().get());
// We often stream data from scratch buffers when client side data is being used
// and that information is in VertexArrayGL.
// Assert that the buffer is non-null because this case isn't handled.
ASSERT(buffer);
getStateManager()->bindBuffer(gl::BufferBinding::Array, buffer->getBufferID());
if (attrib.format->isPureInt())
{
functions->vertexAttribIPointer(attribIndex, attrib.format->channelCount,
gl::ToGLenum(attrib.format->vertexAttribType),
attrib.vertexAttribArrayStride, newPointer);
}
else
{
functions->vertexAttribPointer(attribIndex, attrib.format->channelCount,
gl::ToGLenum(attrib.format->vertexAttribType),
attrib.format->isNorm(),
attrib.vertexAttribArrayStride, newPointer);
}
}
}
}
return attribToUpdateMask;
}
void ContextGL::resetUpdatedAttributes(gl::AttributesMask attribMask)
{
const FunctionsGL *functions = getFunctions();
for (size_t attribIndex : attribMask)
{
const gl::VertexAttribute &attrib =
mState.getVertexArray()->getVertexAttributes()[attribIndex];
const gl::VertexBinding &binding =
(mState.getVertexArray()->getVertexBindings())[attrib.bindingIndex];
getStateManager()->bindBuffer(
gl::BufferBinding::Array,
GetImplAs<BufferGL>(binding.getBuffer().get())->getBufferID());
if (attrib.format->isPureInt())
{
functions->vertexAttribIPointer(static_cast<GLuint>(attribIndex),
attrib.format->channelCount,
gl::ToGLenum(attrib.format->vertexAttribType),
attrib.vertexAttribArrayStride, attrib.pointer);
}
else
{
functions->vertexAttribPointer(
static_cast<GLuint>(attribIndex), attrib.format->channelCount,
gl::ToGLenum(attrib.format->vertexAttribType), attrib.format->isNorm(),
attrib.vertexAttribArrayStride, attrib.pointer);
}
}
}
angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *context,
gl::PrimitiveMode mode,
GLint first,
......@@ -301,7 +377,39 @@ angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *cont
GLsizei instanceCount,
GLuint baseInstance)
{
return drawArraysInstanced(context, mode, first, count, instanceCount);
GLsizei adjustedInstanceCount = instanceCount;
const gl::Program *program = context->getState().getProgram();
if (program->usesMultiview())
{
adjustedInstanceCount *= program->getNumViews();
}
ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
const FunctionsGL *functions = getFunctions();
if (functions->drawArraysInstancedBaseInstance)
{
// GL 4.2+ or GL_EXT_base_instance
functions->drawArraysInstancedBaseInstance(ToGLenum(mode), first, count,
adjustedInstanceCount, baseInstance);
}
else
{
// GL 3.3+ or GLES 3.2+
// TODO(http://anglebug.com/3910): This is a temporary solution by setting and resetting
// pointer offset calling vertexAttribPointer Will refactor stateCache and pass baseInstance
// to setDrawArraysState to set pointer offset
gl::AttributesMask attribToResetMask =
updateAttributesForBaseInstance(program, baseInstance);
functions->drawArraysInstanced(ToGLenum(mode), first, count, adjustedInstanceCount);
resetUpdatedAttributes(attribToResetMask);
}
return angle::Result::Continue;
}
angle::Result ContextGL::drawElements(const gl::Context *context,
......@@ -373,10 +481,26 @@ angle::Result ContextGL::drawElementsInstancedBaseVertexBaseInstance(const gl::C
const FunctionsGL *functions = getFunctions();
// GLES 3.2+ or GL 3.2+
// or GL_OES_draw_elements_base_vertex / GL_EXT_draw_elements_base_vertex
functions->drawElementsInstancedBaseVertex(ToGLenum(mode), count, ToGLenum(type),
drawIndexPointer, adjustedInstanceCount, baseVertex);
if (functions->drawElementsInstancedBaseVertexBaseInstance)
{
// GL 4.2+ or GL_EXT_base_instance
functions->drawElementsInstancedBaseVertexBaseInstance(
ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, adjustedInstanceCount,
baseVertex, baseInstance);
}
else
{
// GL 3.3+ or GLES 3.2+
// TODO(http://anglebug.com/3910): same as above
gl::AttributesMask attribToResetMask =
updateAttributesForBaseInstance(program, baseInstance);
functions->drawElementsInstancedBaseVertex(ToGLenum(mode), count, ToGLenum(type),
drawIndexPointer, adjustedInstanceCount,
baseVertex);
resetUpdatedAttributes(attribToResetMask);
}
return angle::Result::Continue;
}
......
......@@ -255,6 +255,10 @@ class ContextGL : public ContextImpl
GLsizei instanceCount,
const void **outIndices);
gl::AttributesMask updateAttributesForBaseInstance(const gl::Program *program,
GLuint baseInstance);
void resetUpdatedAttributes(gl::AttributesMask attribMask);
protected:
std::shared_ptr<RendererGL> mRenderer;
};
......
......@@ -133,6 +133,10 @@ class DrawBaseVertexBaseInstanceTest
mRegularIndices[oi + j] = mIndices[j] + ov;
}
}
std::iota(mInstancedArrayId.begin(), mInstancedArrayId.end(), 0.0f);
std::reverse_copy(mInstancedArrayId.begin(), mInstancedArrayId.end(),
mInstancedArrayColorId.begin());
}
void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }
......@@ -147,7 +151,7 @@ class DrawBaseVertexBaseInstanceTest
return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;
}
std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw)
std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw, bool divisorTest)
{
// Each color channel is to test the value of
// R: gl_InstanceID and gl_BaseInstance
......@@ -162,18 +166,24 @@ class DrawBaseVertexBaseInstanceTest
<< "#define kCountY " << kCountY << "\n"
<< R"(
in vec2 vPosition;
)" << (useBaseInstanceBuiltin() ? "" : "in float vInstanceID;\n")
<< (!divisorTest ? "" : "in float vInstanceColorID;\n") << R"(
out vec4 color;
void main()
{
const float xStep = 1.0 / float(kCountX);
const float yStep = 1.0 / float(kCountY);
float x_id = float(gl_InstanceID)"
<< (useBaseInstanceBuiltin() ? " + gl_BaseInstance" : "") << R"();
float x_id = )"
<< (useBaseInstanceBuiltin() ? " float(gl_InstanceID + gl_BaseInstance);"
: "vInstanceID;")
<< "float x_color = "
<< (divisorTest ? "xStep * (vInstanceColorID + 1.0f);" : " 1.0 - xStep * x_id;")
<< R"(
float y_id = floor(float(gl_VertexID) / )"
<< (isDrawArrays ? "6.0" : "4.0") << R"( + 0.01);
color = vec4(
1.0 - xStep * x_id,
x_color,
1.0 - yStep * y_id,
)" << (useBaseVertexBuiltin() ? "1.0 - yStep * float(gl_BaseVertex) / 4.0" : "1.0")
<< R"(,
......@@ -201,14 +211,22 @@ void main()
})";
}
void setupProgram(GLProgram &program, bool isDrawArrays = true, bool isMultiDraw = false)
void setupProgram(GLProgram &program,
bool isDrawArrays = true,
bool isMultiDraw = false,
bool isDivisorTest = false)
{
program.makeRaster(vertexShaderSource300(isDrawArrays, isMultiDraw).c_str(),
program.makeRaster(vertexShaderSource300(isDrawArrays, isMultiDraw, isDivisorTest).c_str(),
fragmentShaderSource300().c_str());
EXPECT_GL_NO_ERROR();
ASSERT_TRUE(program.valid());
glUseProgram(program.get());
mPositionLoc = glGetAttribLocation(program.get(), "vPosition");
if (!useBaseInstanceBuiltin())
{
mInstanceIDLoc = glGetAttribLocation(program.get(), "vInstanceID");
mInstanceColorIDLoc = glGetAttribLocation(program.get(), "vInstanceColorID");
}
}
void setupNonIndexedBuffers(GLBuffer &vertexBuffer)
......@@ -233,6 +251,24 @@ void main()
ASSERT_GL_NO_ERROR();
}
void setupInstanceIDBuffer(GLBuffer &instanceIDBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),
mInstancedArrayId.data(), GL_STATIC_DRAW);
ASSERT_GL_NO_ERROR();
}
void setupInstanceColorIDBuffer(GLBuffer &instanceIDBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),
mInstancedArrayColorId.data(), GL_STATIC_DRAW);
ASSERT_GL_NO_ERROR();
}
void setupRegularIndexedBuffer(GLBuffer &indexBuffer)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
......@@ -242,53 +278,37 @@ void main()
ASSERT_GL_NO_ERROR();
}
void doDrawCommons()
void setupPositionVertexAttribPointer()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(mPositionLoc);
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
}
void doVertexAttribDivisor(GLint location, GLuint divisor)
void setupInstanceIDVertexAttribPointer(GLuint instanceIDLoc)
{
if (getClientMajorVersion() <= 2)
{
ASSERT_TRUE(IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
glVertexAttribDivisorANGLE(location, divisor);
}
else
{
glVertexAttribDivisor(location, divisor);
}
glEnableVertexAttribArray(instanceIDLoc);
glVertexAttribPointer(instanceIDLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribDivisor(instanceIDLoc, 1);
}
void doDrawArraysInstancedBaseInstance()
{
doDrawCommons();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const uint32_t countPerDraw = kCountY * 6;
if (useBaseInstanceBuiltin())
{
for (uint32_t i = 0; i < kCountX; i += 2)
{
glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, 2, i);
}
}
else
for (uint32_t i = 0; i < kCountX; i += 2)
{
glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, kCountX, 0);
glDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, 0, countPerDraw, 2, i);
}
}
void doMultiDrawArraysInstancedBaseInstance()
{
doDrawCommons();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const uint32_t countPerDraw = kCountY * 6;
if (useBaseInstanceBuiltin())
{
const GLsizei drawCount = kCountX;
const std::vector<GLsizei> counts(drawCount, countPerDraw);
const std::vector<GLsizei> firsts(drawCount, 0);
......@@ -301,43 +321,22 @@ void main()
glMultiDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, drawCount, counts.data(),
instanceCounts.data(), firsts.data(),
baseInstances.data());
}
else
{
const GLsizei drawCount = 1;
const std::vector<GLsizei> counts(drawCount, countPerDraw);
const std::vector<GLsizei> firsts(drawCount, 0);
const std::vector<GLsizei> instanceCounts(drawCount, kCountX);
const std::vector<GLuint> baseInstances(drawCount, 0);
glMultiDrawArraysInstancedBaseInstanceANGLE(GL_TRIANGLES, drawCount, counts.data(),
instanceCounts.data(), firsts.data(),
baseInstances.data());
}
}
void doDrawElementsInstancedBaseVertexBaseInstance()
{
doDrawCommons();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const uint32_t countPerDraw = 6;
for (uint32_t v = 0; v < kCountY; v++)
{
if (useBaseInstanceBuiltin())
{
for (uint32_t i = 0; i < kCountX; i += 2)
{
glDrawElementsInstancedBaseVertexBaseInstanceANGLE(
GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), 2, v * 4, i);
}
}
else
{
glDrawElementsInstancedBaseVertexBaseInstanceANGLE(
GL_TRIANGLES, countPerDraw, GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)), kCountX, v * 4, 0);
}
}
}
......@@ -345,63 +344,42 @@ void main()
// BaseInstance are reset to zero
void doDrawArraysBaseInstanceReset()
{
doDrawCommons();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6 * kCountY);
}
void doDrawElementsBaseVertexBaseInstanceReset()
{
doDrawCommons();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6 * kCountY, GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(0)));
}
void doMultiDrawElementsInstancedBaseVertexBaseInstance()
{
doDrawCommons();
if (useBaseInstanceBuiltin())
{
const GLsizei drawCount = kCountX * kCountY / 2;
const std::vector<GLsizei> counts(drawCount, 6);
const std::vector<GLsizei> instanceCounts(drawCount, 2);
const std::vector<GLvoid *> indices(drawCount, 0);
std::vector<GLint> baseVertices(drawCount);
std::vector<GLuint> baseInstances(drawCount);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLsizei b = 0;
for (uint32_t v = 0; v < kCountY; v++)
{
for (uint32_t i = 0; i < kCountX; i += 2)
{
baseVertices[b] = v * 4;
baseInstances[b] = i;
b++;
}
}
const GLsizei drawCount = kCountX * kCountY / 2;
const std::vector<GLsizei> counts(drawCount, 6);
const std::vector<GLsizei> instanceCounts(drawCount, 2);
const std::vector<GLvoid *> indices(drawCount, 0);
std::vector<GLint> baseVertices(drawCount);
std::vector<GLuint> baseInstances(drawCount);
glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
GL_TRIANGLES, GL_UNSIGNED_SHORT, drawCount, counts.data(), instanceCounts.data(),
indices.data(), baseVertices.data(), baseInstances.data());
}
else
GLsizei b = 0;
for (uint32_t v = 0; v < kCountY; v++)
{
const GLsizei drawCount = kCountY;
const std::vector<GLsizei> counts(drawCount, 6);
const std::vector<GLsizei> instanceCounts(drawCount, kCountX);
const std::vector<GLvoid *> indices(drawCount, 0);
std::vector<GLint> baseVertices(drawCount);
const std::vector<GLuint> baseInstances(drawCount, 0);
for (uint32_t v = 0; v < drawCount; v++)
for (uint32_t i = 0; i < kCountX; i += 2)
{
baseVertices[v] = v * 4;
baseVertices[b] = v * 4;
baseInstances[b] = i;
b++;
}
glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
GL_TRIANGLES, GL_UNSIGNED_SHORT, drawCount, counts.data(), instanceCounts.data(),
indices.data(), baseVertices.data(), baseInstances.data());
}
glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
GL_TRIANGLES, GL_UNSIGNED_SHORT, drawCount, counts.data(), instanceCounts.data(),
indices.data(), baseVertices.data(), baseInstances.data());
}
void checkDrawResult(bool hasBaseVertex, bool oneColumn = false)
......@@ -474,9 +452,14 @@ void main()
std::vector<GLushort> mIndices;
std::vector<GLfloat> mVertices;
std::vector<GLfloat> mNonIndexedVertices;
// Used when gl_BaseInstance is not used
std::array<GLfloat, kCountX> mInstancedArrayId;
std::array<GLfloat, kCountX> mInstancedArrayColorId;
// Used for regular draw calls without base vertex base instance
std::vector<GLushort> mRegularIndices;
GLint mPositionLoc;
GLuint mInstanceIDLoc;
GLuint mInstanceColorIDLoc;
};
// Tests that compile a program with the extension succeeds
......@@ -493,6 +476,58 @@ TEST_P(DrawBaseVertexBaseInstanceTest, CanCompile)
setupProgram(p3, false, true);
}
// Tests if baseInstance works properly with instanced array with non-zero divisor
TEST_P(DrawBaseVertexBaseInstanceTest, BaseInstanceDivisor)
{
ANGLE_SKIP_TEST_IF(!requestExtensions());
ANGLE_SKIP_TEST_IF(useBaseInstanceBuiltin());
GLProgram program;
setupProgram(program, true, false, true);
GLBuffer nonIndexedVertexBuffer;
setupNonIndexedBuffers(nonIndexedVertexBuffer);
setupPositionVertexAttribPointer();
GLBuffer instanceIDBuffer;
GLBuffer instanceColorIDBuffer;
setupInstanceIDBuffer(instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
setupInstanceColorIDBuffer(instanceColorIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
doDrawArraysInstancedBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(false);
doDrawArraysBaseInstanceReset();
EXPECT_GL_NO_ERROR();
checkDrawResult(false, true);
GLProgram programIndexed;
setupProgram(programIndexed, false, false, true);
GLBuffer indexBuffer;
GLBuffer vertexBuffer;
setupIndexedBuffers(vertexBuffer, indexBuffer);
setupPositionVertexAttribPointer();
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
glBindBuffer(GL_ARRAY_BUFFER, instanceColorIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceColorIDLoc);
doDrawElementsInstancedBaseVertexBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(true);
setupRegularIndexedBuffer(indexBuffer);
doDrawElementsBaseVertexBaseInstanceReset();
EXPECT_GL_NO_ERROR();
checkDrawResult(false, true);
}
// Tests basic functionality of glDrawArraysInstancedBaseInstance
TEST_P(DrawBaseVertexBaseInstanceTest, DrawArraysInstancedBaseInstance)
{
......@@ -513,10 +548,21 @@ TEST_P(DrawBaseVertexBaseInstanceTest, DrawArraysInstancedBaseInstance)
}
ANGLE_SKIP_TEST_IF(!requestExtensions());
GLBuffer vertexBuffer;
setupNonIndexedBuffers(vertexBuffer);
GLProgram program;
setupProgram(program, true);
GLBuffer vertexBuffer;
setupNonIndexedBuffers(vertexBuffer);
setupPositionVertexAttribPointer();
GLBuffer instanceIDBuffer;
if (!useBaseInstanceBuiltin())
{
setupInstanceIDBuffer(instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
}
doDrawArraysInstancedBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(false);
......@@ -538,10 +584,21 @@ TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)
}
ANGLE_SKIP_TEST_IF(!requestExtensions());
GLBuffer vertexBuffer;
setupNonIndexedBuffers(vertexBuffer);
GLProgram program;
setupProgram(program, true, true);
GLBuffer vertexBuffer;
setupNonIndexedBuffers(vertexBuffer);
setupPositionVertexAttribPointer();
GLBuffer instanceIDBuffer;
if (!useBaseInstanceBuiltin())
{
setupInstanceIDBuffer(instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
}
doMultiDrawArraysInstancedBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(false);
......@@ -554,11 +611,22 @@ TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)
TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstance)
{
ANGLE_SKIP_TEST_IF(!requestExtensions());
GLProgram program;
setupProgram(program, false);
GLBuffer indexBuffer;
GLBuffer vertexBuffer;
setupIndexedBuffers(vertexBuffer, indexBuffer);
GLProgram program;
setupProgram(program, false);
setupPositionVertexAttribPointer();
GLBuffer instanceIDBuffer;
if (!useBaseInstanceBuiltin())
{
setupInstanceIDBuffer(instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
}
doDrawElementsInstancedBaseVertexBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(true);
......@@ -573,11 +641,22 @@ TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstan
TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawElementsInstancedBaseVertexBaseInstance)
{
ANGLE_SKIP_TEST_IF(!requestExtensions());
GLProgram program;
setupProgram(program, false, true);
GLBuffer indexBuffer;
GLBuffer vertexBuffer;
setupIndexedBuffers(vertexBuffer, indexBuffer);
GLProgram program;
setupProgram(program, false, true);
setupPositionVertexAttribPointer();
GLBuffer instanceIDBuffer;
if (!useBaseInstanceBuiltin())
{
setupInstanceIDBuffer(instanceIDBuffer);
setupInstanceIDVertexAttribPointer(mInstanceIDLoc);
}
doMultiDrawElementsInstancedBaseVertexBaseInstance();
EXPECT_GL_NO_ERROR();
checkDrawResult(true);
......
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