Sort the elements of the D3D11 input layouts before we store them in the cache.

This prevents a D3D11 error complaining that the input layout uses a different ordering of the vertex elements than the vertex shader. TRAC #22561 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1931 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 4f4215f7
...@@ -19,7 +19,10 @@ ...@@ -19,7 +19,10 @@
#include "libGLESv2/Shader.h" #include "libGLESv2/Shader.h"
#include "libGLESv2/Program.h" #include "libGLESv2/Program.h"
#include <string> #include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/VertexDataManager.h"
#include <algorithm>
#undef near #undef near
#undef far #undef far
...@@ -2485,4 +2488,47 @@ ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textur ...@@ -2485,4 +2488,47 @@ ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textur
{ {
} }
struct AttributeSorter
{
AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
: originalIndices(semanticIndices)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
indices[i] = i;
}
std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this);
}
bool operator()(int a, int b)
{
return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b];
}
int indices[MAX_VERTEX_ATTRIBS];
const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
};
void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
{
AttributeSorter sorter(mSemanticIndex);
int oldIndices[MAX_VERTEX_ATTRIBS];
rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
oldIndices[i] = mSemanticIndex[i];
oldTranslatedAttributes[i] = attributes[i];
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
int oldIndex = sorter.indices[i];
sortedSemanticIndices[i] = oldIndices[oldIndex];
attributes[i] = oldTranslatedAttributes[oldIndex];
}
}
} }
...@@ -28,6 +28,7 @@ namespace rx ...@@ -28,6 +28,7 @@ namespace rx
{ {
class ShaderExecutable; class ShaderExecutable;
class Renderer; class Renderer;
struct TranslatedAttribute;
} }
namespace gl namespace gl
...@@ -113,6 +114,8 @@ class ProgramBinary : public RefCountObject ...@@ -113,6 +114,8 @@ class ProgramBinary : public RefCountObject
unsigned int getSerial() const; unsigned int getSerial() const;
void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
static std::string decorateAttribute(const std::string &name); // Prepend an underscore static std::string decorateAttribute(const std::string &name); // Prepend an underscore
private: private:
......
...@@ -51,6 +51,9 @@ void InputLayoutCache::clear() ...@@ -51,6 +51,9 @@ void InputLayoutCache::clear()
GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
gl::ProgramBinary *programBinary) gl::ProgramBinary *programBinary)
{ {
int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
if (!mDevice || !mDeviceContext) if (!mDevice || !mDeviceContext)
{ {
ERR("InputLayoutCache is not initialized."); ERR("InputLayoutCache is not initialized.");
...@@ -75,7 +78,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M ...@@ -75,7 +78,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
ilKey.elements[ilKey.elementCount].SemanticName = semanticName; ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
ilKey.elements[ilKey.elementCount].SemanticIndex = programBinary->getSemanticIndex(i); ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
ilKey.elements[ilKey.elementCount].InputSlot = i; ilKey.elements[ilKey.elementCount].InputSlot = i;
ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0; ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
......
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