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