Commit 476682e6 by Jamie Madill

Use std::vector for TranslatedAttribs.

This allows us to cache a std::vector between calls, and avoids us calling allocation/constructors for locals, which saves us some time. It also allows us to use the vector's size to limit the range of attribs we look at. BUG=angleproject:959 Change-Id: I799ed6c92fa8fca96e92e235b125a11d2d551aab Reviewed-on: https://chromium-review.googlesource.com/277286Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 46565a42
......@@ -2018,15 +2018,15 @@ void ProgramD3D::initAttributesByLayout()
std::sort(&mAttributesByLayout[0], &mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
}
void ProgramD3D::sortAttributesByLayout(const rx::TranslatedAttribute unsortedAttributes[gl::MAX_VERTEX_ATTRIBS],
void ProgramD3D::sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
for (size_t attribIndex = 0; attribIndex < unsortedAttributes.size(); ++attribIndex)
{
int oldIndex = mAttributesByLayout[i];
sortedSemanticIndicesOut[i] = mSemanticIndex[oldIndex];
sortedAttributesOut[i] = &unsortedAttributes[oldIndex];
int oldIndex = mAttributesByLayout[attribIndex];
sortedSemanticIndicesOut[attribIndex] = mSemanticIndex[oldIndex];
sortedAttributesOut[attribIndex] = &unsortedAttributes[oldIndex];
}
}
......
......@@ -127,7 +127,7 @@ class ProgramD3D : public ProgramImpl
unsigned int getSerial() const;
void initAttributesByLayout();
void sortAttributesByLayout(const rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
......
......@@ -13,6 +13,7 @@
#include "common/MemoryBuffer.h"
#include "libANGLE/Data.h"
#include "libANGLE/renderer/Renderer.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h"
#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
......@@ -212,6 +213,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
gl::DebugAnnotator *mAnnotator;
std::vector<TranslatedAttribute> mTranslatedAttribCache;
private:
//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
......
......@@ -119,8 +119,11 @@ void VertexDataManager::hintUnmapAllResources(const std::vector<gl::VertexAttrib
}
}
gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count,
TranslatedAttribute *translated, GLsizei instances)
gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
GLint start,
GLsizei count,
std::vector<TranslatedAttribute> *translatedAttribs,
GLsizei instances)
{
if (!mStreamingBuffer)
{
......@@ -135,20 +138,26 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
mActiveEnabledAttributes.clear();
mActiveDisabledAttributes.clear();
translatedAttribs->clear();
for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
{
translated[attribIndex].active = (semanticIndexes[attribIndex] != -1);
if (translated[attribIndex].active)
if (semanticIndexes[attribIndex] != -1)
{
// Resize automatically puts in empty attribs
translatedAttribs->resize(attribIndex + 1);
TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
// Record the attribute now
translated[attribIndex].attribute = &vertexAttributes[attribIndex];
translated[attribIndex].currentValueType = state.getVertexAttribCurrentValue(attribIndex).Type;
translated[attribIndex].divisor = vertexAttributes[attribIndex].divisor;
translated->active = true;
translated->attribute = &vertexAttributes[attribIndex];
translated->currentValueType = state.getVertexAttribCurrentValue(attribIndex).Type;
translated->divisor = vertexAttributes[attribIndex].divisor;
if (vertexAttributes[attribIndex].enabled)
{
mActiveEnabledAttributes.push_back(&translated[attribIndex]);
mActiveEnabledAttributes.push_back(translated);
// Also invalidate static buffers that don't contain matching attributes
invalidateMatchingStaticData(vertexAttributes[attribIndex],
......@@ -191,7 +200,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
}
gl::Error error = storeCurrentValue(state.getVertexAttribCurrentValue(attribIndex),
&translated[attribIndex],
&(*translatedAttribs)[attribIndex],
&mCurrentValueCache[attribIndex]);
if (error.isError())
{
......
......@@ -30,9 +30,18 @@ class VertexBuffer;
struct TranslatedAttribute
{
TranslatedAttribute() : active(false), attribute(NULL), currentValueType(GL_NONE),
offset(0), stride(0), vertexBuffer(NULL), storage(NULL),
serial(0), divisor(0) {};
TranslatedAttribute()
: active(false),
attribute(NULL),
currentValueType(GL_NONE),
offset(0),
stride(0),
vertexBuffer(NULL),
storage(NULL),
serial(0),
divisor(0)
{}
bool active;
const gl::VertexAttribute *attribute;
......@@ -52,8 +61,11 @@ class VertexDataManager : angle::NonCopyable
VertexDataManager(BufferFactoryD3D *factory);
virtual ~VertexDataManager();
gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count,
TranslatedAttribute *outAttribs, GLsizei instances);
gl::Error prepareVertexData(const gl::State &state,
GLint start,
GLsizei count,
std::vector<TranslatedAttribute> *translatedAttribs,
GLsizei instances);
private:
struct CurrentValueState
......
......@@ -26,9 +26,10 @@ namespace
{
void GetInputLayout(const TranslatedAttribute *translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
size_t attributeCount,
gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
{
for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
for (size_t attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex)
{
const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex];
......@@ -96,7 +97,7 @@ void InputLayoutCache::markDirty()
}
}
gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute unsortedAttributes[gl::MAX_VERTEX_ATTRIBS],
gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttribute> &unsortedAttributes,
GLenum mode, gl::Program *program)
{
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
......@@ -120,7 +121,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute unsortedAttri
unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS;
unsigned int nextAvailableInputSlot = 0;
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
for (unsigned int i = 0; i < unsortedAttributes.size(); i++)
{
if (sortedAttributes[i]->active)
{
......@@ -223,7 +224,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute unsortedAttri
else
{
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(sortedAttributes, shaderInputLayout);
GetInputLayout(sortedAttributes, unsortedAttributes.size(), shaderInputLayout);
ShaderExecutableD3D *shader = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr);
......@@ -284,18 +285,20 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute unsortedAttri
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
ID3D11Buffer *buffer = NULL;
UINT vertexStride = 0;
UINT vertexOffset = 0;
if (sortedAttributes[i]->active)
if (i < unsortedAttributes.size() && sortedAttributes[i]->active)
{
VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(sortedAttributes[i]->vertexBuffer);
Buffer11 *bufferStorage = sortedAttributes[i]->storage ? GetAs<Buffer11>(sortedAttributes[i]->storage) : NULL;
buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
: vertexBuffer->getBuffer();
}
UINT vertexStride = sortedAttributes[i]->stride;
UINT vertexOffset = sortedAttributes[i]->offset;
vertexStride = sortedAttributes[i]->stride;
vertexOffset = sortedAttributes[i]->offset;
}
if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] ||
vertexOffset != mCurrentVertexOffsets[i])
......
......@@ -38,7 +38,7 @@ class InputLayoutCache : angle::NonCopyable
void clear();
void markDirty();
gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
gl::Error applyVertexBuffers(const std::vector<TranslatedAttribute> &attributes,
GLenum mode, gl::Program *program);
private:
......
......@@ -651,6 +651,9 @@ void Renderer11::initializeDevice()
angleFeatureLevel,
NUM_ANGLE_FEATURE_LEVELS);
// TODO(jmadill): use context caps, and place in common D3D location
mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
double elapsedTimeSeconds = ANGLEPlatformCurrent()->currentTime() - startTimeSeconds;
int initializeDeviceMS = static_cast<int>(elapsedTimeSeconds * 1000);
ANGLE_HISTOGRAM_TIMES("GPU.ANGLE.Renderer11InitializeDeviceMS", initializeDeviceMS);
......@@ -1514,14 +1517,13 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError())
{
return error;
}
return mInputLayoutCache.applyVertexBuffers(attributes, mode, state.getProgram());
return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram());
}
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
......
......@@ -369,6 +369,9 @@ void Renderer9::initializeDevice()
ASSERT(!mVertexDataManager && !mIndexDataManager);
mVertexDataManager = new VertexDataManager(this);
mIndexDataManager = new IndexDataManager(this, getRendererClass());
// TODO(jmadill): use context caps, and place in common D3D location
mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
......@@ -1415,14 +1418,13 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError())
{
return error;
}
return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw);
return mVertexDeclarationCache.applyDeclaration(mDevice, mTranslatedAttribCache, state.getProgram(), instances, &mRepeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
......
......@@ -40,16 +40,23 @@ VertexDeclarationCache::~VertexDeclarationCache()
}
}
gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw)
gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device,
const std::vector<TranslatedAttribute> &attributes,
gl::Program *program,
GLsizei instances,
GLsizei *repeatDraw)
{
ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size());
*repeatDraw = 1;
int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
const size_t invalidAttribIndex = attributes.size();
size_t indexedAttribute = invalidAttribIndex;
size_t instancedAttribute = invalidAttribIndex;
if (instances == 0)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i)
for (size_t i = 0; i < attributes.size(); ++i)
{
if (attributes[i].divisor != 0)
{
......@@ -64,26 +71,26 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra
if (instances > 0)
{
// Find an indexed attribute to be mapped to D3D stream 0
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
for (size_t i = 0; i < attributes.size(); i++)
{
if (attributes[i].active)
{
if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0)
if (indexedAttribute == invalidAttribIndex && attributes[i].divisor == 0)
{
indexedAttribute = i;
}
else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0)
else if (instancedAttribute == invalidAttribIndex && attributes[i].divisor != 0)
{
instancedAttribute = i;
}
if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS)
if (indexedAttribute != invalidAttribIndex && instancedAttribute != invalidAttribIndex)
break; // Found both an indexed and instanced attribute
}
}
// The validation layer checks that there is at least one active attribute with a zero divisor as per
// the GL_ANGLE_instanced_arrays spec.
ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS);
ASSERT(indexedAttribute != invalidAttribIndex);
}
D3DCAPS9 caps;
......@@ -92,7 +99,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra
D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
for (size_t i = 0; i < attributes.size(); i++)
{
if (attributes[i].active)
{
......@@ -104,7 +111,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra
if (instances > 0)
{
// Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
if (instancedAttribute == invalidAttribIndex)
{
*repeatDraw = instances;
}
......@@ -160,7 +167,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra
}
}
if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
if (instances == 0 || instancedAttribute == invalidAttribIndex)
{
if (mInstancingEnabled)
{
......
......@@ -27,7 +27,11 @@ class VertexDeclarationCache
VertexDeclarationCache();
~VertexDeclarationCache();
gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw);
gl::Error applyDeclaration(IDirect3DDevice9 *device,
const std::vector<TranslatedAttribute> &attributes,
gl::Program *program,
GLsizei instances,
GLsizei *repeatDraw);
void markStateDirty();
......
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