Commit e6124500 by shrekshao Committed by Commit Bot

Fix baseVertex and baseInstance with streaming attributes

baseInstance: Fixed by adding the intial offset to each copy for streaming attributes baseVertex: make sure mShaderConstants.onFirstVertexChange takes in correct firstVertex value for dynamic attribs (where firstVertex passed to StateManager11::updateState already include baseVertex) Bug: chromium:1078330, angleproject:3402 Change-Id: I289c4e3733fdf6f78af8c3adee84112c05a5abce Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2227022Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Shrek Shao <shrekshao@google.com>
parent 7f7d046b
......@@ -141,6 +141,7 @@ class BufferFactoryD3D : angle::NonCopyable
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *bytesRequiredOut) const = 0;
};
......
......@@ -96,11 +96,12 @@ angle::Result VertexBufferInterface::getSpaceRequired(const gl::Context *context
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *spaceInBytesOut) const
{
unsigned int spaceRequired = 0;
ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
&spaceRequired));
baseInstance, &spaceRequired));
// Align to 16-byte boundary
unsigned int alignedSpaceRequired = roundUpPow2(spaceRequired, 16u);
......@@ -171,11 +172,13 @@ angle::Result StreamingVertexBufferInterface::storeDynamicAttribute(
GLint start,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *outStreamOffset,
const uint8_t *sourceData)
{
unsigned int spaceRequired = 0;
ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, &spaceRequired));
ANGLE_TRY(
getSpaceRequired(context, attrib, binding, count, instances, baseInstance, &spaceRequired));
// Protect against integer overflow
angle::CheckedNumeric<unsigned int> checkedPosition(mWritePosition);
......@@ -184,8 +187,19 @@ angle::Result StreamingVertexBufferInterface::storeDynamicAttribute(
mReservedSpace = 0;
size_t adjustedCount = count;
GLuint divisor = binding.getDivisor();
if (instances != 0 && divisor != 0)
{
// The attribute is an instanced attribute and it's an draw instance call
// Extra number of elements are copied at the beginning to make sure
// the driver is referencing the correct data with non-zero baseInstance
adjustedCount += UnsignedCeilDivide(baseInstance, divisor);
}
ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, currentValueType,
start, count, instances, mWritePosition,
start, adjustedCount, instances, mWritePosition,
sourceData));
if (outStreamOffset)
......@@ -202,11 +216,12 @@ angle::Result StreamingVertexBufferInterface::reserveVertexSpace(const gl::Conte
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances)
GLsizei instances,
GLuint baseInstance)
{
unsigned int requiredSpace = 0;
ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
&requiredSpace));
baseInstance, &requiredSpace));
// Align to 16-byte boundary
auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u);
......@@ -277,7 +292,7 @@ angle::Result StaticVertexBufferInterface::storeStaticAttribute(const gl::Contex
const uint8_t *sourceData)
{
unsigned int spaceRequired = 0;
ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, &spaceRequired));
ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, 0, &spaceRequired));
ANGLE_TRY(setBufferSize(context, spaceRequired));
ASSERT(attrib.enabled);
......
......@@ -102,6 +102,7 @@ class VertexBufferInterface : angle::NonCopyable
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *spaceInBytesOut) const;
BufferFactoryD3D *const mFactory;
VertexBuffer *mVertexBuffer;
......@@ -124,6 +125,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface
GLint start,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *outStreamOffset,
const uint8_t *sourceData);
......@@ -131,7 +133,8 @@ class StreamingVertexBufferInterface : public VertexBufferInterface
const gl::VertexAttribute &attribute,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances);
GLsizei instances,
GLuint baseInstance);
private:
angle::Result reserveSpace(const gl::Context *context, unsigned int size);
......
......@@ -114,7 +114,7 @@ bool DirectStoragePossible(const gl::Context *context,
{
unsigned int elementSize = 0;
angle::Result error =
factory->getVertexSpaceRequired(context, attrib, binding, 1, 0, &elementSize);
factory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &elementSize);
ASSERT(error == angle::Result::Continue);
alignment = std::min<size_t>(elementSize, 4);
}
......@@ -312,8 +312,9 @@ angle::Result VertexDataManager::prepareVertexData(
return angle::Result::Continue;
}
// prepareVertexData is only called by Renderer9 which don't support baseInstance
ANGLE_TRY(storeDynamicAttribs(context, translatedAttribs, mDynamicAttribsMaskCache, start,
count, instances));
count, instances, 0u));
PromoteDynamicAttribs(context, *translatedAttribs, mDynamicAttribsMaskCache, count);
......@@ -370,7 +371,7 @@ angle::Result VertexDataManager::StoreStaticAttrib(const gl::Context *context,
unsigned int streamOffset = 0;
translated->storage = nullptr;
ANGLE_TRY(bufferD3D->getFactory()->getVertexSpaceRequired(context, attrib, binding, 1, 0,
ANGLE_TRY(bufferD3D->getFactory()->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0,
&translated->stride));
auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib, binding);
......@@ -418,7 +419,8 @@ angle::Result VertexDataManager::storeDynamicAttribs(
const gl::AttributesMask &dynamicAttribsMask,
GLint start,
size_t count,
GLsizei instances)
GLsizei instances,
GLuint baseInstance)
{
// Instantiating this class will ensure the streaming buffer is never left mapped.
class StreamingBufferUnmapper final : NonCopyable
......@@ -442,14 +444,16 @@ angle::Result VertexDataManager::storeDynamicAttribs(
for (auto attribIndex : dynamicAttribsMask)
{
const auto &dynamicAttrib = (*translatedAttribs)[attribIndex];
ANGLE_TRY(reserveSpaceForAttrib(context, dynamicAttrib, start, count, instances));
ANGLE_TRY(
reserveSpaceForAttrib(context, dynamicAttrib, start, count, instances, baseInstance));
}
// Store dynamic attributes
for (auto attribIndex : dynamicAttribsMask)
{
auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
ANGLE_TRY(storeDynamicAttrib(context, dynamicAttrib, start, count, instances));
ANGLE_TRY(
storeDynamicAttrib(context, dynamicAttrib, start, count, instances, baseInstance));
}
return angle::Result::Continue;
......@@ -482,7 +486,8 @@ angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *contex
const TranslatedAttribute &translatedAttrib,
GLint start,
size_t count,
GLsizei instances)
GLsizei instances,
GLuint baseInstance)
{
ASSERT(translatedAttrib.attribute && translatedAttrib.binding);
const auto &attrib = *translatedAttrib.attribute;
......@@ -502,7 +507,9 @@ angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *contex
{
// Vertices do not apply the 'start' offset when the divisor is non-zero even when doing
// a non-instanced draw call
GLint firstVertexIndex = binding.getDivisor() > 0 ? 0 : start;
GLint firstVertexIndex = binding.getDivisor() > 0
? UnsignedCeilDivide(baseInstance, binding.getDivisor())
: start;
int64_t maxVertexCount =
static_cast<int64_t>(firstVertexIndex) + static_cast<int64_t>(totalCount);
......@@ -513,14 +520,16 @@ angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *contex
maxByte <= static_cast<int64_t>(bufferD3D->getSize()),
"Vertex buffer is not big enough for the draw call.", GL_INVALID_OPERATION);
}
return mStreamingBuffer.reserveVertexSpace(context, attrib, binding, totalCount, instances);
return mStreamingBuffer.reserveVertexSpace(context, attrib, binding, totalCount, instances,
baseInstance);
}
angle::Result VertexDataManager::storeDynamicAttrib(const gl::Context *context,
TranslatedAttribute *translated,
GLint start,
size_t count,
GLsizei instances)
GLsizei instances,
GLuint baseInstance)
{
ASSERT(translated->attribute && translated->binding);
const auto &attrib = *translated->attribute;
......@@ -533,7 +542,8 @@ angle::Result VertexDataManager::storeDynamicAttrib(const gl::Context *context,
BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
// Instanced vertices do not apply the 'start' offset
GLint firstVertexIndex = (binding.getDivisor() > 0 ? 0 : start);
GLint firstVertexIndex =
(binding.getDivisor() > 0 ? UnsignedCeilDivide(baseInstance, binding.getDivisor()) : start);
// Compute source data pointer
const uint8_t *sourceData = nullptr;
......@@ -554,14 +564,14 @@ angle::Result VertexDataManager::storeDynamicAttrib(const gl::Context *context,
translated->storage = nullptr;
ANGLE_TRY(
mFactory->getVertexSpaceRequired(context, attrib, binding, 1, 0, &translated->stride));
mFactory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &translated->stride));
size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count,
static_cast<size_t>(instances));
ANGLE_TRY(mStreamingBuffer.storeDynamicAttribute(
context, attrib, binding, translated->currentValueType, firstVertexIndex,
static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData));
static_cast<GLsizei>(totalCount), instances, baseInstance, &streamOffset, sourceData));
VertexBuffer *vertexBuffer = mStreamingBuffer.getVertexBuffer();
......@@ -593,13 +603,13 @@ angle::Result VertexDataManager::storeCurrentValue(
const auto &attrib = *translated->attribute;
const auto &binding = *translated->binding;
ANGLE_TRY(buffer.reserveVertexSpace(context, attrib, binding, 1, 0));
ANGLE_TRY(buffer.reserveVertexSpace(context, attrib, binding, 1, 0, 0));
const uint8_t *sourceData =
reinterpret_cast<const uint8_t *>(currentValue.Values.FloatValues);
unsigned int streamOffset;
ANGLE_TRY(buffer.storeDynamicAttribute(context, attrib, binding, currentValue.Type, 0, 1, 0,
&streamOffset, sourceData));
0, &streamOffset, sourceData));
buffer.getVertexBuffer()->hintUnmapResource();
......
......@@ -111,7 +111,8 @@ class VertexDataManager : angle::NonCopyable
const gl::AttributesMask &dynamicAttribsMask,
GLint start,
size_t count,
GLsizei instances);
GLsizei instances,
GLuint baseInstance);
// Promote static usage of dynamic buffers.
static void PromoteDynamicAttribs(const gl::Context *context,
......@@ -140,13 +141,15 @@ class VertexDataManager : angle::NonCopyable
const TranslatedAttribute &translatedAttrib,
GLint start,
size_t count,
GLsizei instances);
GLsizei instances,
GLuint baseInstance);
angle::Result storeDynamicAttrib(const gl::Context *context,
TranslatedAttribute *translated,
GLint start,
size_t count,
GLsizei instances);
GLsizei instances,
GLuint baseInstance);
BufferFactoryD3D *const mFactory;
......
......@@ -264,7 +264,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));
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0));
return mRenderer->drawArrays(context, mode, first, count, 0, 0);
}
......@@ -275,8 +275,9 @@ angle::Result Context11::drawArraysInstanced(const gl::Context *context,
GLsizei instanceCount)
{
ASSERT(count > 0);
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, instanceCount, 0));
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
gl::DrawElementsType::InvalidEnum, nullptr,
instanceCount, 0, 0));
return mRenderer->drawArrays(context, mode, first, count, instanceCount, 0);
}
......@@ -288,8 +289,9 @@ angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *cont
GLuint baseInstance)
{
ASSERT(count > 0);
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, instanceCount, 0));
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
gl::DrawElementsType::InvalidEnum, nullptr,
instanceCount, 0, baseInstance));
return mRenderer->drawArrays(context, mode, first, count, instanceCount, baseInstance);
}
......@@ -312,15 +314,17 @@ ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *contex
GLint startVertex;
ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, baseVertex,
&startVertex));
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, startVertex, indexCount, indexType, indices, instanceCount, baseVertex));
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, startVertex, indexCount,
indexType, indices, instanceCount,
baseVertex, baseInstance));
return mRenderer->drawElements(context, mode, startVertex, indexCount, indexType, indices,
instanceCount, baseVertex, baseInstance);
}
else
{
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, indexCount, indexType,
indices, instanceCount, baseVertex));
indices, instanceCount, baseVertex,
baseInstance));
return mRenderer->drawElements(context, mode, 0, indexCount, indexType, indices,
instanceCount, baseVertex, baseInstance);
}
......@@ -413,14 +417,14 @@ 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));
nullptr, cmd->instanceCount, 0, 0));
return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount,
cmd->baseInstance);
}
else
{
ANGLE_TRY(mRenderer->getStateManager()->updateState(
context, mode, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0));
context, mode, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0));
return mRenderer->drawArraysIndirect(context, indirect);
}
}
......@@ -453,14 +457,14 @@ angle::Result Context11::drawElementsIndirect(const gl::Context *context,
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, startVertex, cmd->count,
type, indices, cmd->primCount,
cmd->baseVertex));
cmd->baseVertex, cmd->baseInstance));
return mRenderer->drawElements(context, mode, static_cast<GLint>(indexRange.start),
cmd->count, type, indices, cmd->primCount, 0, 0);
}
else
{
ANGLE_TRY(
mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0, 0));
mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0, 0, 0));
return mRenderer->drawElementsIndirect(context, indirect);
}
}
......
......@@ -3843,6 +3843,7 @@ angle::Result Renderer11::getVertexSpaceRequired(const gl::Context *context,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *bytesRequiredOut) const
{
if (!attrib.enabled)
......@@ -3861,7 +3862,8 @@ angle::Result Renderer11::getVertexSpaceRequired(const gl::Context *context,
else
{
// Round up to divisor, if possible
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), divisor);
elementCount =
UnsignedCeilDivide(static_cast<unsigned int>(instances + baseInstance), divisor);
}
ASSERT(elementCount > 0);
......
......@@ -374,6 +374,7 @@ class Renderer11 : public RendererD3D
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *bytesRequiredOut) const override;
angle::Result readFromAttachment(const gl::Context *context,
......
......@@ -541,9 +541,10 @@ void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
}
// Update the ShaderConstants with a new first vertex and return whether the update dirties them.
ANGLE_INLINE bool ShaderConstants11::onFirstVertexChange(GLint firstVertex, GLint baseVertex)
ANGLE_INLINE bool ShaderConstants11::onFirstVertexChange(GLint firstVertex)
{
uint32_t newFirstVertex = static_cast<uint32_t>(firstVertex + baseVertex);
// firstVertex should already include baseVertex, if any.
uint32_t newFirstVertex = static_cast<uint32_t>(firstVertex);
bool firstVertexDirty = (mVertex.firstVertex != newFirstVertex);
if (firstVertexDirty)
......@@ -2167,7 +2168,8 @@ angle::Result StateManager11::updateState(const gl::Context *context,
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
GLsizei instanceCount,
GLint baseVertex)
GLint baseVertex,
GLuint baseInstance)
{
const gl::State &glState = context->getState();
......@@ -2211,7 +2213,7 @@ angle::Result StateManager11::updateState(const gl::Context *context,
ANGLE_TRY(mVertexArray11->syncStateForDraw(context, firstVertex, vertexOrIndexCount,
indexTypeOrInvalid, indices, instanceCount,
baseVertex));
baseVertex, baseInstance));
// Changes in the draw call can affect the vertex buffer translations.
if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != firstVertex)
......@@ -2223,7 +2225,18 @@ angle::Result StateManager11::updateState(const gl::Context *context,
// The ShaderConstants only need to be updated when the program uses vertexID
if (mProgramD3D->usesVertexID())
{
if (mShaderConstants.onFirstVertexChange(firstVertex, baseVertex))
GLint firstVertexOnChange = firstVertex + baseVertex;
ASSERT(mVertexArray11);
if (mVertexArray11->hasActiveDynamicAttrib(context) &&
indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
{
// drawElements with Dynamic attribute
// the firstVertex is already including baseVertex when
// doing ComputeStartVertex
firstVertexOnChange = firstVertex;
}
if (mShaderConstants.onFirstVertexChange(firstVertexOnChange))
{
mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
}
......
......@@ -44,7 +44,7 @@ class ShaderConstants11 : angle::NonCopyable
const D3D11_VIEWPORT &dxViewport,
bool is9_3,
bool presentPathFast);
bool onFirstVertexChange(GLint firstVertex, GLint baseVertex);
bool onFirstVertexChange(GLint firstVertex);
void onImageLayerChange(gl::ShaderType shaderType, unsigned int imageIndex, int layer);
void onSamplerChange(gl::ShaderType shaderType,
unsigned int samplerIndex,
......@@ -239,7 +239,8 @@ class StateManager11 final : angle::NonCopyable
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
GLsizei instanceCount,
GLint baseVertex);
GLint baseVertex,
GLuint baseInstance);
void setShaderResourceShared(gl::ShaderType shaderType,
UINT resourceSlot,
......
......@@ -127,7 +127,8 @@ angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
GLsizei instances,
GLint baseVertex)
GLint baseVertex,
GLuint baseInstance)
{
Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
StateManager11 *stateManager = renderer->getStateManager();
......@@ -159,7 +160,8 @@ angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
{
ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(),
firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
indices, instances, baseVertex, activeDynamicAttribs));
indices, instances, baseVertex, baseInstance,
activeDynamicAttribs));
stateManager->invalidateInputLayout();
}
}
......@@ -292,6 +294,7 @@ angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
const void *indices,
GLsizei instances,
GLint baseVertex,
GLuint baseInstance,
const gl::AttributesMask &activeDynamicAttribs)
{
const auto &glState = context->getState();
......@@ -315,8 +318,9 @@ angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
}
ANGLE_TRY(vertexDataManager->storeDynamicAttribs(
context, &mTranslatedAttribs, activeDynamicAttribs, startVertex, vertexCount, instances));
ANGLE_TRY(vertexDataManager->storeDynamicAttribs(context, &mTranslatedAttribs,
activeDynamicAttribs, startVertex, vertexCount,
instances, baseInstance));
VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
vertexCount);
......
......@@ -39,7 +39,8 @@ class VertexArray11 : public VertexArrayImpl
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
GLsizei instances,
GLint baseVertex);
GLint baseVertex,
GLuint baseInstance);
// This will check the dynamic attribs mask.
bool hasActiveDynamicAttrib(const gl::Context *context);
......@@ -72,6 +73,7 @@ class VertexArray11 : public VertexArrayImpl
const void *indices,
GLsizei instances,
GLint baseVertex,
GLuint baseInstance,
const gl::AttributesMask &activeDynamicAttribs);
angle::Result updateElementArrayStorage(const gl::Context *context,
......
......@@ -2976,6 +2976,7 @@ angle::Result Renderer9::getVertexSpaceRequired(const gl::Context *context,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *bytesRequiredOut) const
{
if (!attrib.enabled)
......
......@@ -374,6 +374,7 @@ class Renderer9 : public RendererD3D
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
GLuint baseInstance,
unsigned int *bytesRequiredOut) const override;
angle::Result copyToRenderTarget(const gl::Context *context,
......
......@@ -78,7 +78,7 @@ angle::Result VertexBuffer9::storeVertexAttributes(const gl::Context *context,
unsigned int mapSize = 0;
ANGLE_TRY(
mRenderer->getVertexSpaceRequired(context, attrib, binding, count, instances, &mapSize));
mRenderer->getVertexSpaceRequired(context, attrib, binding, count, instances, 0, &mapSize));
HRESULT result =
mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void **>(&mapPtr), lockFlags);
......
......@@ -63,8 +63,14 @@ enum class BaseInstanceOption
UseBaseInstance
};
using DrawBaseVertexBaseInstanceTestParams =
std::tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption>;
enum class BufferDataUsageOption
{
StaticDraw,
DynamicDraw
};
using DrawBaseVertexBaseInstanceTestParams = std::
tuple<angle::PlatformParameters, BaseVertexOption, BaseInstanceOption, BufferDataUsageOption>;
struct PrintToStringParamName
{
......@@ -72,7 +78,9 @@ struct PrintToStringParamName
const ::testing::TestParamInfo<DrawBaseVertexBaseInstanceTestParams> &info) const
{
::std::stringstream ss;
ss << (std::get<2>(info.param) == BaseInstanceOption::UseBaseInstance ? "UseBaseInstance_"
ss << (std::get<3>(info.param) == BufferDataUsageOption::StaticDraw ? "StaticDraw_"
: "DynamicDraw_")
<< (std::get<2>(info.param) == BaseInstanceOption::UseBaseInstance ? "UseBaseInstance_"
: "")
<< (std::get<1>(info.param) == BaseVertexOption::UseBaseVertex ? "UseBaseVertex_" : "")
<< std::get<0>(info.param);
......@@ -151,6 +159,12 @@ class DrawBaseVertexBaseInstanceTest
return std::get<2>(GetParam()) == BaseInstanceOption::UseBaseInstance;
}
GLenum getBufferDataUsage() const
{
return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW
: GL_DYNAMIC_DRAW;
}
std::string vertexShaderSource300(bool isDrawArrays, bool isMultiDraw, bool divisorTest)
{
// Each color channel is to test the value of
......@@ -179,8 +193,8 @@ void main()
<< "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);
float y_id = float(gl_VertexID / )"
<< (isDrawArrays ? "6" : "4") << R"();
color = vec4(
x_color,
......@@ -233,7 +247,7 @@ void main()
{
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),
mNonIndexedVertices.data(), GL_STATIC_DRAW);
mNonIndexedVertices.data(), getBufferDataUsage());
ASSERT_GL_NO_ERROR();
}
......@@ -242,11 +256,11 @@ void main()
{
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
GL_STATIC_DRAW);
getBufferDataUsage());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
GL_STATIC_DRAW);
getBufferDataUsage());
ASSERT_GL_NO_ERROR();
}
......@@ -255,7 +269,7 @@ void main()
{
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayId.size(),
mInstancedArrayId.data(), GL_STATIC_DRAW);
mInstancedArrayId.data(), getBufferDataUsage());
ASSERT_GL_NO_ERROR();
}
......@@ -264,7 +278,7 @@ void main()
{
glBindBuffer(GL_ARRAY_BUFFER, instanceIDBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mInstancedArrayColorId.size(),
mInstancedArrayColorId.data(), GL_STATIC_DRAW);
mInstancedArrayColorId.data(), getBufferDataUsage());
ASSERT_GL_NO_ERROR();
}
......@@ -273,7 +287,7 @@ void main()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mRegularIndices.size(),
mRegularIndices.data(), GL_STATIC_DRAW);
mRegularIndices.data(), getBufferDataUsage());
ASSERT_GL_NO_ERROR();
}
......@@ -584,6 +598,7 @@ TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawArraysInstancedBaseInstance)
}
ANGLE_SKIP_TEST_IF(!requestExtensions());
ANGLE_SKIP_TEST_IF(getBufferDataUsage() == GL_DYNAMIC_DRAW);
GLProgram program;
setupProgram(program, true, true);
......@@ -641,6 +656,7 @@ TEST_P(DrawBaseVertexBaseInstanceTest, DrawElementsInstancedBaseVertexBaseInstan
TEST_P(DrawBaseVertexBaseInstanceTest, MultiDrawElementsInstancedBaseVertexBaseInstance)
{
ANGLE_SKIP_TEST_IF(!requestExtensions());
ANGLE_SKIP_TEST_IF(getBufferDataUsage() == GL_DYNAMIC_DRAW);
GLProgram program;
setupProgram(program, false, true);
......@@ -680,7 +696,8 @@ INSTANTIATE_TEST_SUITE_P(
testing::Combine(
testing::ValuesIn(::angle::FilterTestParams(platforms, ArraySize(platforms))),
testing::Values(BaseVertexOption::NoBaseVertex, BaseVertexOption::UseBaseVertex),
testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance)),
testing::Values(BaseInstanceOption::NoBaseInstance, BaseInstanceOption::UseBaseInstance),
testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw)),
PrintToStringParamName());
} // namespace
......@@ -56,12 +56,13 @@ class MockBufferFactoryD3D : public rx::BufferFactoryD3D
MOCK_METHOD0(createVertexBuffer, rx::VertexBuffer *());
MOCK_CONST_METHOD1(getVertexConversionType, rx::VertexConversionType(angle::FormatID));
MOCK_CONST_METHOD1(getVertexComponentType, GLenum(angle::FormatID));
MOCK_CONST_METHOD6(getVertexSpaceRequired,
MOCK_CONST_METHOD7(getVertexSpaceRequired,
angle::Result(const gl::Context *,
const gl::VertexAttribute &,
const gl::VertexBinding &,
size_t,
GLsizei,
GLuint,
unsigned int *));
// Dependency injection
......
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