Commit a56467e0 by Jamie Madill Committed by Commit Bot

VertexArray: Use switch macro for faster iteration.

Has a small but noticeable impact on performance on a microbenchmark. Seems to improve a synthetic score by about 1%. Should have a very small improvement in real-world performance. Note that the odd formatting is an idiosyncrasy of clang-format. Bug: angleproject:2389 Change-Id: I888bf101c6d8b80a0fbafdb9c5a84205c9c8fee6 Reviewed-on: https://chromium-review.googlesource.com/962963Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 6d5af92b
...@@ -13,6 +13,17 @@ ...@@ -13,6 +13,17 @@
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
// This is a helper X macro for iterating over all dirty attribs/bindings. Useful for dirty bits.
static_assert(gl::MAX_VERTEX_ATTRIBS == 16, "Invalid max vertex attribs");
static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS == 16, "Invalid max vertex bindings");
#define ANGLE_VERTEX_INDEX_CASES(FUNC) \
FUNC(0) \
FUNC(1) \
FUNC(2) \
FUNC(3) \
FUNC(4) \
FUNC(5) FUNC(6) FUNC(7) FUNC(8) FUNC(9) FUNC(10) FUNC(11) FUNC(12) FUNC(13) FUNC(14) FUNC(15)
namespace rx namespace rx
{ {
class ContextImpl; class ContextImpl;
......
...@@ -37,6 +37,29 @@ void VertexArray11::destroy(const gl::Context *context) ...@@ -37,6 +37,29 @@ void VertexArray11::destroy(const gl::Context *context)
{ {
} }
#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
ASSERT(INDEX == mState.getBindingIndexFromAttribIndex(INDEX)); \
updateVertexAttribStorage(stateManager, dirtyBit, INDEX); \
invalidateVertexBuffer = true; \
break;
#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
ASSERT(INDEX == mState.getBindingIndexFromAttribIndex(INDEX)); \
updateVertexAttribStorage(stateManager, dirtyBit, INDEX); \
invalidateVertexBuffer = true; \
break;
#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
if (mAttributeStorageTypes[INDEX] == VertexStorageType::STATIC) \
{ \
invalidateVertexBuffer = true; \
mAttribsToTranslate.set(INDEX); \
} \
break;
gl::Error VertexArray11::syncState(const gl::Context *context, gl::Error VertexArray11::syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits, const gl::VertexArray::DirtyBits &dirtyBits,
const gl::VertexArray::DirtyAttribBitsArray &attribBits, const gl::VertexArray::DirtyAttribBitsArray &attribBits,
...@@ -68,29 +91,13 @@ gl::Error VertexArray11::syncState(const gl::Context *context, ...@@ -68,29 +91,13 @@ gl::Error VertexArray11::syncState(const gl::Context *context,
break; break;
} }
ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
default: default:
{ UNREACHABLE();
size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
// TODO(jiawei.shao@intel.com): Vertex Attrib Bindings
ASSERT(index == mState.getBindingIndexFromAttribIndex(index));
if (dirtyBit < gl::VertexArray::DIRTY_BIT_BINDING_MAX)
{
updateVertexAttribStorage(stateManager, dirtyBit, index);
}
else
{
ASSERT(dirtyBit >= gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 &&
dirtyBit < gl::VertexArray::DIRTY_BIT_BUFFER_DATA_MAX);
if (mAttributeStorageTypes[index] == VertexStorageType::STATIC)
{
mAttribsToTranslate.set(index);
}
}
invalidateVertexBuffer = true;
break; break;
}
} }
} }
......
...@@ -701,6 +701,20 @@ void VertexArrayGL::syncDirtyBinding(const gl::Context *context, ...@@ -701,6 +701,20 @@ void VertexArrayGL::syncDirtyBinding(const gl::Context *context,
} }
} }
#define ANGLE_DIRTY_ATTRIB_FUNC(INDEX) \
case VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
syncDirtyAttrib(context, INDEX, attribBits[INDEX]); \
break;
#define ANGLE_DIRTY_BINDING_FUNC(INDEX) \
case VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
syncDirtyBinding(context, INDEX, bindingBits[INDEX]); \
break;
#define ANGLE_DIRTY_BUFFER_DATA_FUNC(INDEX) \
case VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
break;
gl::Error VertexArrayGL::syncState(const gl::Context *context, gl::Error VertexArrayGL::syncState(const gl::Context *context,
const VertexArray::DirtyBits &dirtyBits, const VertexArray::DirtyBits &dirtyBits,
const gl::VertexArray::DirtyAttribBitsArray &attribBits, const gl::VertexArray::DirtyAttribBitsArray &attribBits,
...@@ -719,26 +733,13 @@ gl::Error VertexArrayGL::syncState(const gl::Context *context, ...@@ -719,26 +733,13 @@ gl::Error VertexArrayGL::syncState(const gl::Context *context,
case VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA: case VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
break; break;
ANGLE_VERTEX_INDEX_CASES(ANGLE_DIRTY_ATTRIB_FUNC);
ANGLE_VERTEX_INDEX_CASES(ANGLE_DIRTY_BINDING_FUNC);
ANGLE_VERTEX_INDEX_CASES(ANGLE_DIRTY_BUFFER_DATA_FUNC);
default: default:
{ UNREACHABLE();
ASSERT(dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0);
size_t index = VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
if (dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX)
{
syncDirtyAttrib(context, index, attribBits[index]);
}
else if (dirtyBit < VertexArray::DIRTY_BIT_BINDING_MAX)
{
ASSERT(dirtyBit >= VertexArray::DIRTY_BIT_BINDING_0);
syncDirtyBinding(context, index, bindingBits[index]);
}
else
{
ASSERT(dirtyBit >= VertexArray::DIRTY_BIT_BUFFER_DATA_0 &&
dirtyBit < VertexArray::DIRTY_BIT_BUFFER_DATA_MAX);
}
break; break;
}
} }
} }
......
...@@ -144,6 +144,22 @@ gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer, ...@@ -144,6 +144,22 @@ gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer,
return gl::NoError(); return gl::NoError();
} }
#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
syncDirtyAttrib(attribs[INDEX], bindings[attribs[INDEX].bindingIndex], INDEX); \
invalidatePipeline = true; \
break;
#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
syncDirtyAttrib(attribs[INDEX], bindings[attribs[INDEX].bindingIndex], INDEX); \
invalidatePipeline = true; \
break;
#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
break;
gl::Error VertexArrayVk::syncState(const gl::Context *context, gl::Error VertexArrayVk::syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits, const gl::VertexArray::DirtyBits &dirtyBits,
const gl::VertexArray::DirtyAttribBitsArray &attribBits, const gl::VertexArray::DirtyAttribBitsArray &attribBits,
...@@ -192,46 +208,13 @@ gl::Error VertexArrayVk::syncState(const gl::Context *context, ...@@ -192,46 +208,13 @@ gl::Error VertexArrayVk::syncState(const gl::Context *context,
mDirtyLineLoopTranslation = true; mDirtyLineLoopTranslation = true;
break; break;
default: ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
{ ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit); ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
// Invalidate the input description for pipelines.
mDirtyPackedInputs.set(attribIndex);
const auto &attrib = attribs[attribIndex]; default:
const auto &binding = bindings[attrib.bindingIndex]; UNREACHABLE();
if (attrib.enabled)
{
gl::Buffer *bufferGL = binding.getBuffer().get();
if (bufferGL)
{
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentArrayBufferResources[attribIndex] = bufferVk;
mCurrentArrayBufferHandles[attribIndex] =
bufferVk->getVkBuffer().getHandle();
mClientMemoryAttribs.reset(attribIndex);
}
else
{
mCurrentArrayBufferResources[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
mClientMemoryAttribs.set(attribIndex);
}
// TODO(jmadill): Offset handling. Assume zero for now.
mCurrentArrayBufferOffsets[attribIndex] = 0;
}
else
{
mClientMemoryAttribs.reset(attribIndex);
UNIMPLEMENTED();
}
invalidatePipeline = true;
break; break;
}
} }
} }
...@@ -244,6 +227,40 @@ gl::Error VertexArrayVk::syncState(const gl::Context *context, ...@@ -244,6 +227,40 @@ gl::Error VertexArrayVk::syncState(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
void VertexArrayVk::syncDirtyAttrib(const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex)
{
// Invalidate the input description for pipelines.
mDirtyPackedInputs.set(attribIndex);
if (attrib.enabled)
{
gl::Buffer *bufferGL = binding.getBuffer().get();
if (bufferGL)
{
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentArrayBufferResources[attribIndex] = bufferVk;
mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
mClientMemoryAttribs.reset(attribIndex);
}
else
{
mCurrentArrayBufferResources[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
mClientMemoryAttribs.set(attribIndex);
}
// TODO(jmadill): Offset handling. Assume zero for now.
mCurrentArrayBufferOffsets[attribIndex] = 0;
}
else
{
mClientMemoryAttribs.reset(attribIndex);
UNIMPLEMENTED();
}
}
const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
{ {
return mCurrentArrayBufferHandles; return mCurrentArrayBufferHandles;
......
...@@ -99,6 +99,10 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -99,6 +99,10 @@ class VertexArrayVk : public VertexArrayImpl
vk::CommandGraphNode *drawNode, vk::CommandGraphNode *drawNode,
bool newCommandBuffer); bool newCommandBuffer);
void syncDirtyAttrib(const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex);
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles; gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets; gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<vk::CommandGraphResource *> mCurrentArrayBufferResources; gl::AttribArray<vk::CommandGraphResource *> mCurrentArrayBufferResources;
...@@ -113,7 +117,7 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -113,7 +117,7 @@ class VertexArrayVk : public VertexArrayImpl
vk::VertexInputAttributes mPackedInputAttributes; vk::VertexInputAttributes mPackedInputAttributes;
// Which attributes need to be copied from client memory. // Which attributes need to be copied from client memory.
// TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/2389 // TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/1391
gl::AttributesMask mClientMemoryAttribs; gl::AttributesMask mClientMemoryAttribs;
vk::DynamicBuffer mDynamicVertexData; vk::DynamicBuffer mDynamicVertexData;
......
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