Store multiple vertex executables in the program binary.
With dynamic vertex conversion the GPU, we will have different input
layouts resulting in different executables. This patch adds a way
of mapping the input layouts to vertex executables.
BUG=angle:560
Change-Id: Ie36f2f8ac2dfcb96f562af577d31f57d6d89b447
Reviewed-on: https://chromium-review.googlesource.com/185192
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index c94f944..6b91d91 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -2407,9 +2407,14 @@
}
// Applies the shaders and shader constants to the Direct3D 9 device
-void Context::applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard)
+void Context::applyShaders(ProgramBinary *programBinary)
{
- mRenderer->applyShaders(programBinary, rasterizerDiscard);
+ const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes();
+
+ VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues);
+
+ mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, inputLayout);
programBinary->applyUniforms();
}
@@ -2879,7 +2884,7 @@
return gl::error(err);
}
- applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
+ applyShaders(programBinary);
applyTextures(programBinary);
if (!applyUniformBuffers())
@@ -2942,7 +2947,7 @@
return gl::error(err);
}
- applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
+ applyShaders(programBinary);
applyTextures(programBinary);
if (!applyUniformBuffers())
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 9026377..391ea63 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -453,7 +453,7 @@
bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode);
- void applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard);
+ void applyShaders(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary, SamplerType type);
bool applyUniformBuffers();
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index a3e600b..a5d6a46 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -50,6 +50,23 @@
return subscript;
}
+void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
+{
+ for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
+ VertexFormat *defaultFormat = &inputLayout[attributeIndex];
+
+ if (shaderAttr.type != GL_NONE)
+ {
+ defaultFormat->mType = UniformComponentType(shaderAttr.type);
+ defaultFormat->mNormalized = false;
+ defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
+ defaultFormat->mComponents = UniformComponentCount(shaderAttr.type);
+ }
+ }
+}
+
}
VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -57,14 +74,38 @@
{
}
+ProgramBinary::VertexExecutable::VertexExecutable(rx::Renderer *const renderer,
+ const VertexFormat inputLayout[],
+ rx::ShaderExecutable *shaderExecutable)
+ : mShaderExecutable(shaderExecutable)
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ mInputs[attributeIndex] = inputLayout[attributeIndex];
+ }
+}
+
+bool ProgramBinary::VertexExecutable::matchesInputLayout(const VertexFormat attributes[]) const
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (mInputs[attributeIndex] != attributes[attributeIndex])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::Renderer *renderer)
: RefCountObject(0),
mRenderer(renderer),
mDynamicHLSL(NULL),
+ mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
mPixelExecutable(NULL),
- mVertexExecutable(NULL),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
@@ -95,9 +136,14 @@
ProgramBinary::~ProgramBinary()
{
- SafeDelete(mPixelExecutable);
- SafeDelete(mVertexExecutable);
+ while (!mVertexExecutables.empty())
+ {
+ delete mVertexExecutables.back();
+ mVertexExecutables.pop_back();
+ }
+
SafeDelete(mGeometryExecutable);
+ SafeDelete(mPixelExecutable);
while (!mUniforms.empty())
{
@@ -136,9 +182,32 @@
return mPixelExecutable;
}
-rx::ShaderExecutable *ProgramBinary::getVertexExecutable() const
+rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
{
- return mVertexExecutable;
+ for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
+ {
+ if (mVertexExecutables[executableIndex]->matchesInputLayout(inputLayout))
+ {
+ return mVertexExecutables[executableIndex]->shaderExecutable();
+ }
+ }
+
+ // Generate new vertex executable
+ InfoLog tempInfoLog;
+ rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, mVertexHLSL.c_str(), rx::SHADER_VERTEX, mVertexWorkarounds);
+
+ if (!vertexExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, vertexExecutable));
+ }
+
+ return vertexExecutable;
}
rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
@@ -1091,15 +1160,73 @@
stream.read(&mUniformIndex[i].index);
}
+ stream.read(&mVertexHLSL);
+ stream.read(&mVertexWorkarounds);
+
+ unsigned int vertexShaderCount;
+ stream.read(&vertexShaderCount);
+
+ for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
+ {
+ VertexFormat vertexInputs[gl::MAX_VERTEX_ATTRIBS];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ VertexFormat *vertexInput = &vertexInputs[inputIndex];
+ stream.read(&vertexInput->mType);
+ stream.read(&vertexInput->mNormalized);
+ stream.read(&vertexInput->mComponents);
+ stream.read(&vertexInput->mPureInteger);
+ }
+
+ unsigned int vertexShaderSize;
+ stream.read(&vertexShaderSize);
+
+ const char *vertexShaderFunction = (const char*) binary + stream.offset();
+
+ rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+ vertexShaderSize, rx::SHADER_VERTEX);
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create vertex shader.");
+ return false;
+ }
+
+ mVertexExecutables.push_back(new VertexExecutable(mRenderer, vertexInputs, shaderExecutable));
+
+ stream.skip(vertexShaderSize);
+ }
+
unsigned int pixelShaderSize;
stream.read(&pixelShaderSize);
- unsigned int vertexShaderSize;
- stream.read(&vertexShaderSize);
+ const char *pixelShaderFunction = (const char*) binary + stream.offset();
+ mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
+ pixelShaderSize, rx::SHADER_PIXEL);
+ if (!mPixelExecutable)
+ {
+ infoLog.append("Could not create pixel shader.");
+ return false;
+ }
+ stream.skip(pixelShaderSize);
unsigned int geometryShaderSize;
stream.read(&geometryShaderSize);
+ if (geometryShaderSize > 0)
+ {
+ const char *geometryShaderFunction = (const char*) binary + stream.offset();
+ mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
+ geometryShaderSize, rx::SHADER_GEOMETRY);
+ if (!mGeometryExecutable)
+ {
+ infoLog.append("Could not create geometry shader.");
+ SafeDelete(mPixelExecutable);
+ return false;
+ }
+ stream.skip(geometryShaderSize);
+ }
+
const char *ptr = (const char*) binary + stream.offset();
const GUID *binaryIdentifier = (const GUID *) ptr;
@@ -1112,52 +1239,6 @@
return false;
}
- const char *pixelShaderFunction = ptr;
- ptr += pixelShaderSize;
-
- const char *vertexShaderFunction = ptr;
- ptr += vertexShaderSize;
-
- const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL;
- ptr += geometryShaderSize;
-
- mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
- pixelShaderSize, rx::SHADER_PIXEL);
- if (!mPixelExecutable)
- {
- infoLog.append("Could not create pixel shader.");
- return false;
- }
-
- mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
- vertexShaderSize, rx::SHADER_VERTEX);
- if (!mVertexExecutable)
- {
- infoLog.append("Could not create vertex shader.");
- delete mPixelExecutable;
- mPixelExecutable = NULL;
- return false;
- }
-
- if (geometryShaderFunction != NULL && geometryShaderSize > 0)
- {
- mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY);
- if (!mGeometryExecutable)
- {
- infoLog.append("Could not create geometry shader.");
- delete mPixelExecutable;
- mPixelExecutable = NULL;
- delete mVertexExecutable;
- mVertexExecutable = NULL;
- return false;
- }
- }
- else
- {
- mGeometryExecutable = NULL;
- }
-
initializeUniformStorage();
return true;
@@ -1200,7 +1281,7 @@
stream.write(mShaderVersion);
stream.write(mUniforms.size());
- for (unsigned int uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
const Uniform &uniform = *mUniforms[uniformIndex];
@@ -1222,7 +1303,7 @@
}
stream.write(mUniformBlocks.size());
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
{
const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
@@ -1241,28 +1322,60 @@
}
stream.write(mUniformIndex.size());
- for (unsigned int i = 0; i < mUniformIndex.size(); ++i)
+ for (size_t i = 0; i < mUniformIndex.size(); ++i)
{
stream.write(mUniformIndex[i].name);
stream.write(mUniformIndex[i].element);
stream.write(mUniformIndex[i].index);
}
+ stream.write(mVertexHLSL);
+ stream.write(mVertexWorkarounds);
+
+ UINT vertexShadersTotalSize = 0;
+
+ stream.write(mVertexExecutables.size());
+ for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
+ {
+ VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
+ stream.write(vertexInput.mType);
+ stream.write(vertexInput.mNormalized);
+ stream.write(vertexInput.mComponents);
+ stream.write(vertexInput.mPureInteger);
+ }
+
+ UINT vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
+ stream.write(vertexShaderSize);
+
+ unsigned char *vertexBlob = static_cast<unsigned char *>(vertexExecutable->shaderExecutable()->getFunction());
+ stream.write(vertexBlob, vertexShaderSize);
+ }
+
UINT pixelShaderSize = mPixelExecutable->getLength();
stream.write(pixelShaderSize);
- UINT vertexShaderSize = mVertexExecutable->getLength();
- stream.write(vertexShaderSize);
+ unsigned char *pixelBlob = static_cast<unsigned char *>(mPixelExecutable->getFunction());
+ stream.write(pixelBlob, pixelShaderSize);
UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
stream.write(geometryShaderSize);
+ if (mGeometryExecutable != NULL && geometryShaderSize > 0)
+ {
+ unsigned char *geometryBlob = static_cast<unsigned char *>(mGeometryExecutable->getFunction());
+ stream.write(geometryBlob, geometryShaderSize);
+ }
+
GUID identifier = mRenderer->getAdapterIdentifier();
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
- GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize;
+ GLsizei totalLength = streamLength + sizeof(GUID);
if (totalLength > bufSize)
{
if (length)
@@ -1283,18 +1396,6 @@
memcpy(ptr, &identifier, sizeof(GUID));
ptr += sizeof(GUID);
- memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize);
- ptr += pixelShaderSize;
-
- memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize);
- ptr += vertexShaderSize;
-
- if (mGeometryExecutable != NULL && geometryShaderSize > 0)
- {
- memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize);
- ptr += geometryShaderSize;
- }
-
ASSERT(ptr - totalLength == binary);
}
@@ -1334,7 +1435,8 @@
mShaderVersion = vertexShader->getShaderVersion();
std::string pixelHLSL = fragmentShader->getHLSL();
- std::string vertexHLSL = vertexShader->getHLSL();
+ mVertexHLSL = vertexShader->getHLSL();
+ mVertexWorkarounds = vertexShader->getD3DWorkarounds();
// Map the varyings to the register file
const sh::ShaderVariable *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL};
@@ -1351,7 +1453,8 @@
}
mUsesPointSize = vertexShader->usesPointSize();
- if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader, &mOutputVariables))
+ if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, pixelHLSL, mVertexHLSL,
+ fragmentShader, vertexShader, &mOutputVariables))
{
return false;
}
@@ -1383,8 +1486,11 @@
if (success)
{
- mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, vertexShader->getD3DWorkarounds());
- mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, vertexShader->getD3DWorkarounds());
+ VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
+ GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout);
+
+ rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
+ mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, fragmentShader->getD3DWorkarounds());
if (usesGeometryShader())
{
@@ -1392,17 +1498,19 @@
mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY, rx::ANGLE_D3D_WORKAROUND_NONE);
}
- if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ if (!defaultVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
{
infoLog.append("Failed to create D3D shaders.");
success = false;
- delete mVertexExecutable;
- mVertexExecutable = NULL;
- delete mPixelExecutable;
- mPixelExecutable = NULL;
- delete mGeometryExecutable;
- mGeometryExecutable = NULL;
+ while (!mVertexExecutables.empty())
+ {
+ delete mVertexExecutables.back();
+ mVertexExecutables.pop_back();
+ }
+
+ SafeDelete(mGeometryExecutable);
+ SafeDelete(mPixelExecutable);
}
}
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 54f9920..808f387 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -25,6 +25,7 @@
#include "libGLESv2/Uniform.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Constants.h"
+#include "libGLESv2/renderer/VertexDataManager.h"
namespace rx
{
@@ -65,7 +66,7 @@
~ProgramBinary();
rx::ShaderExecutable *getPixelExecutable() const;
- rx::ShaderExecutable *getVertexExecutable() const;
+ rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]);
rx::ShaderExecutable *getGeometryExecutable() const;
GLuint getAttributeLocation(const char *name);
@@ -185,12 +186,30 @@
static TextureType getTextureType(GLenum samplerType, InfoLog &infoLog);
+ class VertexExecutable
+ {
+ public:
+ VertexExecutable(rx::Renderer *const renderer,
+ const VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+ rx::ShaderExecutable *shaderExecutable);
+ bool matchesInputLayout(const VertexFormat attributes[gl::MAX_VERTEX_ATTRIBS]) const;
+
+ const VertexFormat *inputs() const { return mInputs; }
+ rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
+ rx::ShaderExecutable *mShaderExecutable;
+ };
+
rx::Renderer *const mRenderer;
DynamicHLSL *mDynamicHLSL;
- rx::ShaderExecutable *mPixelExecutable;
- rx::ShaderExecutable *mVertexExecutable;
+ std::string mVertexHLSL;
+ rx::D3DWorkaroundType mVertexWorkarounds;
+ std::vector<VertexExecutable *> mVertexExecutables;
rx::ShaderExecutable *mGeometryExecutable;
+ rx::ShaderExecutable *mPixelExecutable;
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 61cb0fe..fa14806 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -130,7 +130,7 @@
bool ignoreViewport) = 0;
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
- virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard) = 0;
+ virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]) = 0;
virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
diff --git a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
index b88a54f..5962862 100644
--- a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
@@ -22,6 +22,21 @@
namespace rx
{
+static 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++)
+ {
+ const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex];
+
+ if (translatedAttributes[attributeIndex].active)
+ {
+ inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute,
+ translatedAttribute.currentValueType);
+ }
+ }
+}
+
const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
@@ -135,7 +150,9 @@
}
else
{
- ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
+ gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
+ GetInputLayout(attributes, shaderInputLayout);
+ ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout));
D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
for (unsigned int j = 0; j < ilKey.elementCount; ++j)
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index a4037f6..31d31c4 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -1403,9 +1403,9 @@
}
}
-void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
+void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[])
{
- ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+ ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index 69e04ab..2f7d403 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -75,7 +75,7 @@
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
- virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard);
+ virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]);
virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index d857c01..2e7c083 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -30,6 +30,7 @@
#include "libGLESv2/renderer/d3d9/BufferStorage9.h"
#include "libGLESv2/renderer/d3d9/Query9.h"
#include "libGLESv2/renderer/d3d9/Fence9.h"
+#include "libGLESv2/angletypes.h"
#include "libEGL/Display.h"
@@ -1722,11 +1723,11 @@
}
}
-void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
+void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[])
{
ASSERT(!rasterizerDiscard);
- ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+ ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d9/Renderer9.h
index c665006..78e70cc 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.h
@@ -58,17 +58,6 @@
IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
-#if 0
- void *createTexture2D();
- void *createTextureCube();
- void *createQuery();
- void *createIndexBuffer();
- void *createVertexbuffer();
-
- // state setup
- void applyShaders();
- void applyConstants();
-#endif
virtual void generateSwizzle(gl::Texture *texture);
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
@@ -86,7 +75,7 @@
bool ignoreViewport);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
- virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard);
+ virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]);
virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],