Commit 27c08917 by Jamie Madill

Cache active attribute lists in VertexDataManager.

This saves us re-creating vector memory every iteration, and allows us to iterate over much smaller lists of attributes. In the future it could allow us to update the cache more efficiently with state change updates. BUG=angleproject:959 Change-Id: Ie8ae7a31726468dc2184165380f1f3e5e0152936 Reviewed-on: https://chromium-review.googlesource.com/277284Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3d72cc79
...@@ -83,6 +83,10 @@ VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) ...@@ -83,6 +83,10 @@ VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
{ {
ERR("Failed to allocate the streaming vertex buffer."); ERR("Failed to allocate the streaming vertex buffer.");
} }
// TODO(jmadill): use context caps
mActiveEnabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
mActiveDisabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
} }
VertexDataManager::~VertexDataManager() VertexDataManager::~VertexDataManager()
...@@ -94,21 +98,17 @@ void VertexDataManager::hintUnmapAllResources(const std::vector<gl::VertexAttrib ...@@ -94,21 +98,17 @@ void VertexDataManager::hintUnmapAllResources(const std::vector<gl::VertexAttrib
{ {
mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); mStreamingBuffer->getVertexBuffer()->hintUnmapResource();
for (size_t i = 0; i < vertexAttributes.size(); i++) for (const TranslatedAttribute *translated : mActiveEnabledAttributes)
{
const gl::VertexAttribute &attrib = vertexAttributes[i];
if (attrib.enabled)
{ {
gl::Buffer *buffer = attrib.buffer.get(); gl::Buffer *buffer = translated->attribute->buffer.get();
BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL; BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL; StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : nullptr;
if (staticBuffer) if (staticBuffer)
{ {
staticBuffer->getVertexBuffer()->hintUnmapResource(); staticBuffer->getVertexBuffer()->hintUnmapResource();
} }
} }
}
for (auto &currentValue : mCurrentValueCache) for (auto &currentValue : mCurrentValueCache)
{ {
...@@ -127,9 +127,14 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta ...@@ -127,9 +127,14 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL."); return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
} }
// Compute active enabled and active disable attributes, for speed.
// TODO(jmadill): don't recompute if there was no state change
const gl::VertexArray *vertexArray = state.getVertexArray(); const gl::VertexArray *vertexArray = state.getVertexArray();
const std::vector<gl::VertexAttribute> &vertexAttributes = vertexArray->getVertexAttributes(); const std::vector<gl::VertexAttribute> &vertexAttributes = vertexArray->getVertexAttributes();
mActiveEnabledAttributes.clear();
mActiveDisabledAttributes.clear();
for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
{ {
translated[attribIndex].active = (state.getProgram()->getSemanticIndex(attribIndex) != -1); translated[attribIndex].active = (state.getProgram()->getSemanticIndex(attribIndex) != -1);
...@@ -142,34 +147,33 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta ...@@ -142,34 +147,33 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
if (vertexAttributes[attribIndex].enabled) if (vertexAttributes[attribIndex].enabled)
{ {
mActiveEnabledAttributes.push_back(&translated[attribIndex]);
// Also invalidate static buffers that don't contain matching attributes // Also invalidate static buffers that don't contain matching attributes
invalidateMatchingStaticData(vertexAttributes[attribIndex], invalidateMatchingStaticData(vertexAttributes[attribIndex],
state.getVertexAttribCurrentValue(attribIndex)); state.getVertexAttribCurrentValue(attribIndex));
} }
else
{
mActiveDisabledAttributes.push_back(attribIndex);
}
} }
} }
// Reserve the required space in the buffers // Reserve the required space in the buffers
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (const TranslatedAttribute *translated : mActiveEnabledAttributes)
{ {
if (translated[i].active && translated[i].attribute->enabled) gl::Error error = reserveSpaceForAttrib(*translated, count, instances);
{
gl::Error error = reserveSpaceForAttrib(translated[i], count, instances);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
} }
}
// Perform the vertex data translations // Perform the vertex data translations
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (TranslatedAttribute *translated : mActiveEnabledAttributes)
{
if (translated[i].active)
{ {
if (translated[i].attribute->enabled) gl::Error error = storeAttribute(translated, start, count, instances);
{
gl::Error error = storeAttribute(&translated[i], start, count, instances);
if (error.isError()) if (error.isError())
{ {
...@@ -177,40 +181,36 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta ...@@ -177,40 +181,36 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
return error; return error;
} }
} }
else
for (size_t attribIndex : mActiveDisabledAttributes)
{ {
if (mCurrentValueCache[i].buffer == nullptr) if (mCurrentValueCache[attribIndex].buffer == nullptr)
{ {
mCurrentValueCache[i].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE); mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
} }
gl::Error error = storeCurrentValue(state.getVertexAttribCurrentValue(i), gl::Error error = storeCurrentValue(state.getVertexAttribCurrentValue(attribIndex),
&translated[i], &translated[attribIndex],
&mCurrentValueCache[i]); &mCurrentValueCache[attribIndex]);
if (error.isError()) if (error.isError())
{ {
hintUnmapAllResources(vertexAttributes); hintUnmapAllResources(vertexAttributes);
return error; return error;
} }
} }
}
}
// Hint to unmap all the resources // Hint to unmap all the resources
hintUnmapAllResources(vertexAttributes); hintUnmapAllResources(vertexAttributes);
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (const TranslatedAttribute *translated : mActiveEnabledAttributes)
{
const gl::VertexAttribute &curAttrib = vertexAttributes[i];
if (translated[i].active && curAttrib.enabled)
{ {
gl::Buffer *buffer = curAttrib.buffer.get(); gl::Buffer *buffer = translated->attribute->buffer.get();
if (buffer) if (buffer)
{ {
BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer); BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib)); size_t typeSize = ComputeVertexAttributeTypeSize(*translated->attribute);
} bufferD3D->promoteStaticUsage(count * typeSize);
} }
} }
...@@ -401,6 +401,7 @@ gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValu ...@@ -401,6 +401,7 @@ gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValu
if (cachedState->data != currentValue) if (cachedState->data != currentValue)
{ {
const gl::VertexAttribute &attrib = *translated->attribute; const gl::VertexAttribute &attrib = *translated->attribute;
gl::Error error = cachedState->buffer->reserveVertexSpace(attrib, 1, 0); gl::Error error = cachedState->buffer->reserveVertexSpace(attrib, 1, 0);
if (error.isError()) if (error.isError())
{ {
......
...@@ -88,6 +88,10 @@ class VertexDataManager : angle::NonCopyable ...@@ -88,6 +88,10 @@ class VertexDataManager : angle::NonCopyable
StreamingVertexBufferInterface *mStreamingBuffer; StreamingVertexBufferInterface *mStreamingBuffer;
std::vector<CurrentValueState> mCurrentValueCache; std::vector<CurrentValueState> mCurrentValueCache;
// Cache variables
std::vector<TranslatedAttribute *> mActiveEnabledAttributes;
std::vector<size_t> mActiveDisabledAttributes;
}; };
} }
......
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