Commit f9327d33 by Jamie Madill

D3D11: Optimize ProgramD3D::sortAttributesByLayout.

We can use pointer math here, instead of copying values. BUG=angleproject:959 Change-Id: I3b87956224d0846c9011f5d8edb811bc5e4f2b85 Reviewed-on: https://chromium-review.googlesource.com/277119Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 9bbfdd63
...@@ -2018,21 +2018,15 @@ void ProgramD3D::initAttributesByLayout() ...@@ -2018,21 +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(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], void ProgramD3D::sortAttributesByLayout(const rx::TranslatedAttribute unsortedAttributes[gl::MAX_VERTEX_ATTRIBS],
int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const
{ {
rx::TranslatedAttribute oldTranslatedAttributes[gl::MAX_VERTEX_ATTRIBS];
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
oldTranslatedAttributes[i] = attributes[i];
}
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{ {
int oldIndex = mAttributesByLayout[i]; int oldIndex = mAttributesByLayout[i];
sortedSemanticIndices[i] = mSemanticIndex[oldIndex]; sortedSemanticIndicesOut[i] = mSemanticIndex[oldIndex];
attributes[i] = oldTranslatedAttributes[oldIndex]; sortedAttributesOut[i] = &unsortedAttributes[oldIndex];
} }
} }
......
...@@ -127,8 +127,9 @@ class ProgramD3D : public ProgramImpl ...@@ -127,8 +127,9 @@ class ProgramD3D : public ProgramImpl
unsigned int getSerial() const; unsigned int getSerial() const;
void initAttributesByLayout(); void initAttributesByLayout();
void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], void sortAttributesByLayout(const rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const; int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
private: private:
class VertexExecutable class VertexExecutable
......
...@@ -22,21 +22,26 @@ ...@@ -22,21 +22,26 @@
namespace rx namespace rx
{ {
static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS], namespace
gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) {
void GetInputLayout(const TranslatedAttribute *translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
{ {
for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex]; const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex];
if (translatedAttributes[attributeIndex].active) if (translatedAttributes[attributeIndex]->active)
{ {
inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute, inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute->attribute,
translatedAttribute.currentValueType); translatedAttribute->currentValueType);
} }
} }
} }
} // anonymous namespace
const unsigned int InputLayoutCache::kMaxInputLayouts = 1024; const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts) InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
...@@ -91,13 +96,14 @@ void InputLayoutCache::markDirty() ...@@ -91,13 +96,14 @@ void InputLayoutCache::markDirty()
} }
} }
gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute unsortedAttributes[gl::MAX_VERTEX_ATTRIBS],
GLenum mode, gl::Program *program) GLenum mode, gl::Program *program)
{ {
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
programD3D->sortAttributesByLayout(attributes, sortedSemanticIndices); const TranslatedAttribute *sortedAttributes[gl::MAX_VERTEX_ATTRIBS] = { nullptr };
programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices, sortedAttributes);
bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS); bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
...@@ -116,13 +122,13 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl ...@@ -116,13 +122,13 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{ {
if (attributes[i].active) if (sortedAttributes[i]->active)
{ {
D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; D3D11_INPUT_CLASSIFICATION inputClass = sortedAttributes[i]->divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
// If rendering points and instanced pointsprite emulation is being used, the inputClass is required to be configured as per instance data // If rendering points and instanced pointsprite emulation is being used, the inputClass is required to be configured as per instance data
inputClass = instancedPointSpritesActive ? D3D11_INPUT_PER_INSTANCE_DATA : inputClass; inputClass = instancedPointSpritesActive ? D3D11_INPUT_PER_INSTANCE_DATA : inputClass;
gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType); gl::VertexFormat vertexFormat(*sortedAttributes[i]->attribute, sortedAttributes[i]->currentValueType);
const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel); const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel);
// Record the type of the associated vertex shader vector in our key // Record the type of the associated vertex shader vector in our key
...@@ -136,7 +142,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl ...@@ -136,7 +142,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
ilKey.elements[ilKey.elementCount].desc.InputSlot = i; ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = instancedPointSpritesActive ? 1 : attributes[i].divisor; ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = instancedPointSpritesActive ? 1 : sortedAttributes[i]->divisor;
if (inputClass == D3D11_INPUT_PER_VERTEX_DATA && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS) if (inputClass == D3D11_INPUT_PER_VERTEX_DATA && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)
{ {
...@@ -217,7 +223,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl ...@@ -217,7 +223,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
else else
{ {
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout); GetInputLayout(sortedAttributes, shaderInputLayout);
ShaderExecutableD3D *shader = NULL; ShaderExecutableD3D *shader = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr); gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr);
...@@ -279,17 +285,17 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl ...@@ -279,17 +285,17 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
{ {
ID3D11Buffer *buffer = NULL; ID3D11Buffer *buffer = NULL;
if (attributes[i].active) if (sortedAttributes[i]->active)
{ {
VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(attributes[i].vertexBuffer); VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(sortedAttributes[i]->vertexBuffer);
Buffer11 *bufferStorage = attributes[i].storage ? GetAs<Buffer11>(attributes[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 = attributes[i].stride; UINT vertexStride = sortedAttributes[i]->stride;
UINT vertexOffset = attributes[i].offset; UINT vertexOffset = sortedAttributes[i]->offset;
if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] || if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] ||
vertexOffset != mCurrentVertexOffsets[i]) vertexOffset != mCurrentVertexOffsets[i])
......
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