Moving Shader Executables into ProgramD3D
BUG=angle:731
Change-Id: I677fc9773914307184bcdd9ab7ac564956d77f6a
Reviewed-on: https://chromium-review.googlesource.com/219814
Tested-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/BinaryStream.h b/src/libGLESv2/BinaryStream.h
index 4d7dde0..4f7f5f2 100644
--- a/src/libGLESv2/BinaryStream.h
+++ b/src/libGLESv2/BinaryStream.h
@@ -15,6 +15,7 @@
#include <cstddef>
#include <string>
#include <vector>
+#include <stdint.h>
namespace gl
{
@@ -26,7 +27,7 @@
{
mError = false;
mOffset = 0;
- mData = static_cast<const char*>(data);
+ mData = static_cast<const uint8_t*>(data);
mLength = length;
}
@@ -85,7 +86,7 @@
return;
}
- v->assign(mData + mOffset, length);
+ v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
mOffset += length;
}
@@ -115,11 +116,16 @@
return mOffset == mLength;
}
+ const uint8_t *data()
+ {
+ return mData;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
bool mError;
size_t mOffset;
- const char *mData;
+ const uint8_t *mData;
size_t mLength;
template <typename T>
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index d7d5d94..96f78ad 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -80,42 +80,6 @@
return subscript;
}
-void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- size_t layoutIndex = 0;
- for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS);
-
- const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
-
- if (shaderAttr.type != GL_NONE)
- {
- GLenum transposedType = TransposeMatrixType(shaderAttr.type);
-
- for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++)
- {
- VertexFormat *defaultFormat = &inputLayout[layoutIndex];
-
- defaultFormat->mType = VariableComponentType(transposedType);
- defaultFormat->mNormalized = false;
- defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
- defaultFormat->mComponents = VariableColumnCount(transposedType);
- }
- }
- }
-}
-
-std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
-{
- std::vector<GLenum> defaultPixelOutput(1);
-
- ASSERT(!shaderOutputVars.empty());
- defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
-
- return defaultPixelOutput;
-}
-
bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
{
return var.isRowMajorLayout;
@@ -133,47 +97,6 @@
{
}
-ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[],
- const GLenum signature[],
- rx::ShaderExecutable *shaderExecutable)
- : mShaderExecutable(shaderExecutable)
-{
- for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- mInputs[attributeIndex] = inputLayout[attributeIndex];
- mSignature[attributeIndex] = signature[attributeIndex];
- }
-}
-
-ProgramBinary::VertexExecutable::~VertexExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
-bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
-{
- for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (mSignature[attributeIndex] != signature[attributeIndex])
- {
- return false;
- }
- }
-
- return true;
-}
-
-ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable)
- : mOutputSignature(outputSignature),
- mShaderExecutable(shaderExecutable)
-{
-}
-
-ProgramBinary::PixelExecutable::~PixelExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
LinkedVarying::LinkedVarying()
{
}
@@ -189,7 +112,6 @@
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
mProgram(impl),
- mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true),
@@ -220,93 +142,6 @@
return mCurrentSerial++;
}
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
-{
- std::vector<GLenum> outputs;
-
- const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
-
- for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
- {
- const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
-
- if (colorbuffer)
- {
- outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
- }
- else
- {
- outputs.push_back(GL_NONE);
- }
- }
-
- return getPixelExecutableForOutputLayout(outputs);
-}
-
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
-{
- for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
- {
- if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
- {
- return mPixelExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!pixelExecutable)
- {
- std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
- tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
- ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
- }
- else
- {
- mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
- }
-
- return pixelExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getInputLayoutSignature(inputLayout, signature);
-
- for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
- {
- if (mVertexExecutables[executableIndex]->matchesSignature(signature))
- {
- return mVertexExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- 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(inputLayout, signature, vertexExecutable));
- }
-
- return vertexExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
-{
- return mGeometryExecutable;
-}
-
GLuint ProgramBinary::getAttributeLocation(const char *name)
{
if (name)
@@ -497,17 +332,17 @@
size_t ProgramBinary::getTransformFeedbackVaryingCount() const
{
- return mTransformFeedbackLinkedVaryings.size();
+ return mProgram->getTransformFeedbackLinkedVaryings().size();
}
const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
{
- return mTransformFeedbackLinkedVaryings[idx];
+ return mProgram->getTransformFeedbackLinkedVaryings()[idx];
}
GLenum ProgramBinary::getTransformFeedbackBufferMode() const
{
- return mTransformFeedbackBufferMode;
+ return mProgram->getTransformFeedbackBufferMode();
}
template <typename T>
@@ -1064,8 +899,8 @@
{
stream.readInt(&mLinkedAttribute[i].type);
stream.readString(&mLinkedAttribute[i].name);
- stream.readInt(&mShaderAttributes[i].type);
- stream.readString(&mShaderAttributes[i].name);
+ stream.readInt(&mProgram->getShaderAttributes()[i].type);
+ stream.readString(&mProgram->getShaderAttributes()[i].name);
stream.readInt(&mSemanticIndex[i]);
}
@@ -1170,102 +1005,6 @@
stream.readInt(&mUniformIndex[uniformIndexIndex].index);
}
- stream.readInt(&mTransformFeedbackBufferMode);
- const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
- mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
- for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
- {
- LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
-
- stream.readString(&varying.name);
- stream.readInt(&varying.type);
- stream.readInt(&varying.size);
- stream.readString(&varying.semanticName);
- stream.readInt(&varying.semanticIndex);
- stream.readInt(&varying.semanticIndexCount);
- }
-
- const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
- for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
- {
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
-
- for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
- {
- VertexFormat *vertexInput = &inputLayout[inputIndex];
- stream.readInt(&vertexInput->mType);
- stream.readInt(&vertexInput->mNormalized);
- stream.readInt(&vertexInput->mComponents);
- stream.readBool(&vertexInput->mPureInteger);
- }
-
- unsigned int vertexShaderSize = stream.readInt<unsigned int>();
- const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mProgram->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
- vertexShaderSize, rx::SHADER_VERTEX,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
- if (!shaderExecutable)
- {
- infoLog.append("Could not create vertex shader.");
- return false;
- }
-
- // generated converted input layout
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getInputLayoutSignature(inputLayout, signature);
-
- // add new binary
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
-
- stream.skip(vertexShaderSize);
- }
-
- const size_t pixelShaderCount = stream.readInt<unsigned int>();
- for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
- {
- const size_t outputCount = stream.readInt<unsigned int>();
- std::vector<GLenum> outputs(outputCount);
- for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
- {
- stream.readInt(&outputs[outputIndex]);
- }
-
- const size_t pixelShaderSize = stream.readInt<unsigned int>();
- const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mProgram->loadExecutable(pixelShaderFunction, pixelShaderSize,
- rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!shaderExecutable)
- {
- infoLog.append("Could not create pixel shader.");
- return false;
- }
-
- // add new binary
- mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
-
- stream.skip(pixelShaderSize);
- }
-
- unsigned int geometryShaderSize = stream.readInt<unsigned int>();
-
- if (geometryShaderSize > 0)
- {
- const char *geometryShaderFunction = (const char*) binary + stream.offset();
- mGeometryExecutable = mProgram->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!mGeometryExecutable)
- {
- infoLog.append("Could not create geometry shader.");
- return false;
- }
- stream.skip(geometryShaderSize);
- }
-
if (!mProgram->load(infoLog, &stream))
{
return false;
@@ -1296,8 +1035,8 @@
{
stream.writeInt(mLinkedAttribute[i].type);
stream.writeString(mLinkedAttribute[i].name);
- stream.writeInt(mShaderAttributes[i].type);
- stream.writeString(mShaderAttributes[i].name);
+ stream.writeInt(mProgram->getShaderAttributes()[i].type);
+ stream.writeString(mProgram->getShaderAttributes()[i].name);
stream.writeInt(mSemanticIndex[i]);
}
@@ -1369,69 +1108,6 @@
stream.writeInt(mUniformIndex[i].index);
}
- stream.writeInt(mTransformFeedbackBufferMode);
- stream.writeInt(mTransformFeedbackLinkedVaryings.size());
- for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
- {
- const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
-
- stream.writeString(varying.name);
- stream.writeInt(varying.type);
- stream.writeInt(varying.size);
- stream.writeString(varying.semanticName);
- stream.writeInt(varying.semanticIndex);
- stream.writeInt(varying.semanticIndexCount);
- }
-
- stream.writeInt(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.writeInt(vertexInput.mType);
- stream.writeInt(vertexInput.mNormalized);
- stream.writeInt(vertexInput.mComponents);
- stream.writeInt(vertexInput.mPureInteger);
- }
-
- size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
- stream.writeInt(vertexShaderSize);
-
- const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(vertexBlob, vertexShaderSize);
- }
-
- stream.writeInt(mPixelExecutables.size());
- for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
- {
- PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
-
- const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
- stream.writeInt(outputs.size());
- for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
- {
- stream.writeInt(outputs[outputIndex]);
- }
-
- size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
- stream.writeInt(pixelShaderSize);
-
- const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(pixelBlob, pixelShaderSize);
- }
-
- size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
- stream.writeInt(geometryShaderSize);
-
- if (mGeometryExecutable != NULL && geometryShaderSize > 0)
- {
- const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
- stream.writeBytes(geometryBlob, geometryShaderSize);
- }
-
if (!mProgram->save(&stream))
{
if (length)
@@ -1506,14 +1182,13 @@
mSamplersPS.resize(caps.maxTextureImageUnits);
mSamplersVS.resize(caps.maxVertexTextureImageUnits);
- mTransformFeedbackBufferMode = transformFeedbackBufferMode;
-
rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
int registers;
std::vector<LinkedVarying> linkedVaryings;
- if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, ®isters, &linkedVaryings, &mOutputVariables))
+ if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
+ ®isters, &linkedVaryings, &mOutputVariables, caps))
{
return false;
}
@@ -1546,29 +1221,16 @@
}
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
+ transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
{
success = false;
}
if (success)
{
- VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
- GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
- rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
-
- std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
- rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
-
- if (mProgram->usesGeometryShader())
- {
- mGeometryExecutable = mProgram->getGeometryExecutable(infoLog, fragmentShader, vertexShader,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- registers);
- }
-
- if (!defaultVertexExecutable || !defaultPixelExecutable || (mProgram->usesGeometryShader() && !mGeometryExecutable))
+ // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
+ // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
+ if (!mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers))
{
infoLog.append("Failed to create D3D shaders.");
success = false;
@@ -1596,7 +1258,7 @@
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
- mShaderAttributes[attributeIndex] = attribute;
+ mProgram->getShaderAttributes()[attributeIndex] = attribute;
if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
{
@@ -2678,13 +2340,6 @@
void ProgramBinary::reset()
{
- SafeDeleteContainer(mVertexExecutables);
- SafeDeleteContainer(mPixelExecutables);
- SafeDelete(mGeometryExecutable);
-
- mTransformFeedbackBufferMode = GL_NONE;
- mTransformFeedbackLinkedVaryings.clear();
-
mSamplersPS.clear();
mSamplersVS.clear();
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 1c9c8c0..b3bd246 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -101,11 +101,6 @@
rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { return mProgram; }
- rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
- rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
- rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
- rx::ShaderExecutable *getGeometryExecutable() const;
-
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
@@ -250,56 +245,12 @@
template <typename T>
void getUniformv(GLint location, T *params, GLenum uniformType);
- class VertexExecutable
- {
- public:
- VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
- const GLenum signature[MAX_VERTEX_ATTRIBS],
- rx::ShaderExecutable *shaderExecutable);
- ~VertexExecutable();
-
- bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const;
-
- const VertexFormat *inputs() const { return mInputs; }
- const GLenum *signature() const { return mSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- VertexFormat mInputs[MAX_VERTEX_ATTRIBS];
- GLenum mSignature[MAX_VERTEX_ATTRIBS];
- rx::ShaderExecutable *mShaderExecutable;
- };
-
- class PixelExecutable
- {
- public:
- PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
- ~PixelExecutable();
-
- bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
-
- const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- std::vector<GLenum> mOutputSignature;
- rx::ShaderExecutable *mShaderExecutable;
- };
-
rx::ProgramImpl *mProgram;
- std::vector<VertexExecutable *> mVertexExecutables;
- std::vector<PixelExecutable *> mPixelExecutables;
- rx::ShaderExecutable *mGeometryExecutable;
-
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
- sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
- GLenum mTransformFeedbackBufferMode;
- std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
-
std::vector<Sampler> mSamplersPS;
std::vector<Sampler> mSamplersVS;
GLuint mUsedVertexSamplerRange;
diff --git a/src/libGLESv2/renderer/ProgramImpl.h b/src/libGLESv2/renderer/ProgramImpl.h
index 4d765d6..ede5c57 100644
--- a/src/libGLESv2/renderer/ProgramImpl.h
+++ b/src/libGLESv2/renderer/ProgramImpl.h
@@ -25,37 +25,23 @@
public:
virtual ~ProgramImpl() { }
- virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0;
-
virtual bool usesPointSize() const = 0;
- virtual bool usesGeometryShader() const = 0;
virtual int getShaderVersion() const = 0;
+ virtual GLenum getTransformFeedbackBufferMode() const = 0;
+ virtual std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() = 0;
+ virtual sh::Attribute *getShaderAttributes() = 0;
virtual GLenum getBinaryFormat() = 0;
virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual bool save(gl::BinaryOutputStream *stream) = 0;
- virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers) = 0;
- virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers) = 0;
- virtual rx::ShaderExecutable *getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers, int registers) = 0;
- virtual rx::ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers) = 0;
+ virtual bool compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers) = 0;
virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int,
- gl::VariableLocation> *outputVariables) = 0;
-
- virtual void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const = 0;
+ const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps) = 0;
virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
index f65a3aa..d377924 100644
--- a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -9,6 +9,8 @@
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "common/utilities.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/renderer/Renderer.h"
@@ -20,18 +22,101 @@
namespace rx
{
-ProgramD3D::ProgramD3D(rx::Renderer *renderer)
+namespace
+{
+
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+{
+ size_t layoutIndex = 0;
+ for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS);
+
+ const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
+
+ if (shaderAttr.type != GL_NONE)
+ {
+ GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
+
+ for (size_t rowIndex = 0; static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++)
+ {
+ gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex];
+
+ defaultFormat->mType = gl::VariableComponentType(transposedType);
+ defaultFormat->mNormalized = false;
+ defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
+ defaultFormat->mComponents = gl::VariableColumnCount(transposedType);
+ }
+ }
+ }
+}
+
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> &shaderOutputVars)
+{
+ std::vector<GLenum> defaultPixelOutput(1);
+
+ ASSERT(!shaderOutputVars.empty());
+ defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+ return defaultPixelOutput;
+}
+
+}
+
+ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[],
+ const GLenum signature[],
+ ShaderExecutable *shaderExecutable)
+ : mShaderExecutable(shaderExecutable)
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ mInputs[attributeIndex] = inputLayout[attributeIndex];
+ mSignature[attributeIndex] = signature[attributeIndex];
+ }
+}
+
+ProgramD3D::VertexExecutable::~VertexExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (mSignature[attributeIndex] != signature[attributeIndex])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable)
+ : mOutputSignature(outputSignature),
+ mShaderExecutable(shaderExecutable)
+{
+}
+
+ProgramD3D::PixelExecutable::~PixelExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+ProgramD3D::ProgramD3D(Renderer *renderer)
: ProgramImpl(),
mRenderer(renderer),
mDynamicHLSL(NULL),
- mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+ mGeometryExecutable(NULL),
+ mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
+ mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
mUsesPointSize(false),
mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL),
mShaderVersion(100)
{
- mDynamicHLSL = new rx::DynamicHLSL(renderer);
+ mDynamicHLSL = new DynamicHLSL(renderer);
}
ProgramD3D::~ProgramD3D()
@@ -52,11 +137,6 @@
return static_cast<const ProgramD3D*>(impl);
}
-bool ProgramD3D::usesPointSize() const
-{
- return mUsesPointSize;
-}
-
bool ProgramD3D::usesPointSpriteEmulation() const
{
return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
@@ -71,6 +151,21 @@
{
stream->readInt(&mShaderVersion);
+ stream->readInt(&mTransformFeedbackBufferMode);
+ const unsigned int transformFeedbackVaryingCount = stream->readInt<unsigned int>();
+ mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
+ for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
+ {
+ gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
+
+ stream->readString(&varying.name);
+ stream->readInt(&varying.type);
+ stream->readInt(&varying.size);
+ stream->readString(&varying.semanticName);
+ stream->readInt(&varying.semanticIndex);
+ stream->readInt(&varying.semanticIndexCount);
+ }
+
stream->readString(&mVertexHLSL);
stream->readInt(&mVertexWorkarounds);
stream->readString(&mPixelHLSL);
@@ -88,6 +183,91 @@
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
}
+ const unsigned char* binary = reinterpret_cast<const unsigned char*>(stream->data());
+
+ const unsigned int vertexShaderCount = stream->readInt<unsigned int>();
+ for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
+ {
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ gl::VertexFormat *vertexInput = &inputLayout[inputIndex];
+ stream->readInt(&vertexInput->mType);
+ stream->readInt(&vertexInput->mNormalized);
+ stream->readInt(&vertexInput->mComponents);
+ stream->readBool(&vertexInput->mPureInteger);
+ }
+
+ unsigned int vertexShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *vertexShaderFunction = binary + stream->offset();
+ ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
+ SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create vertex shader.");
+ return false;
+ }
+
+ // generated converted input layout
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ // add new binary
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
+
+ stream->skip(vertexShaderSize);
+ }
+
+ const size_t pixelShaderCount = stream->readInt<unsigned int>();
+ for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ {
+ const size_t outputCount = stream->readInt<unsigned int>();
+ std::vector<GLenum> outputs(outputCount);
+ for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
+ {
+ stream->readInt(&outputs[outputIndex]);
+ }
+
+ const size_t pixelShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *pixelShaderFunction = binary + stream->offset();
+ ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
+ SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create pixel shader.");
+ return false;
+ }
+
+ // add new binary
+ mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
+
+ stream->skip(pixelShaderSize);
+ }
+
+ unsigned int geometryShaderSize = stream->readInt<unsigned int>();
+
+ if (geometryShaderSize > 0)
+ {
+ const unsigned char *geometryShaderFunction = binary + stream->offset();
+ mGeometryExecutable = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
+ SHADER_GEOMETRY,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
+ if (!mGeometryExecutable)
+ {
+ infoLog.append("Could not create geometry shader.");
+ return false;
+ }
+ stream->skip(geometryShaderSize);
+ }
+
GUID binaryIdentifier = {0};
stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
@@ -105,6 +285,20 @@
{
stream->writeInt(mShaderVersion);
+ stream->writeInt(mTransformFeedbackBufferMode);
+ stream->writeInt(mTransformFeedbackLinkedVaryings.size());
+ for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
+ {
+ const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
+
+ stream->writeString(varying.name);
+ stream->writeInt(varying.type);
+ stream->writeInt(varying.size);
+ stream->writeString(varying.semanticName);
+ stream->writeInt(varying.semanticIndex);
+ stream->writeInt(varying.semanticIndexCount);
+ }
+
stream->writeString(mVertexHLSL);
stream->writeInt(mVertexWorkarounds);
stream->writeString(mPixelHLSL);
@@ -112,85 +306,201 @@
stream->writeInt(mUsesFragDepth);
stream->writeInt(mUsesPointSize);
- const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
+ const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
stream->writeInt(pixelShaderKey.size());
for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++)
{
- const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
+ const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
stream->writeInt(variable.type);
stream->writeString(variable.name);
stream->writeString(variable.source);
stream->writeInt(variable.outputIndex);
}
+ stream->writeInt(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 gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
+ stream->writeInt(vertexInput.mType);
+ stream->writeInt(vertexInput.mNormalized);
+ stream->writeInt(vertexInput.mComponents);
+ stream->writeInt(vertexInput.mPureInteger);
+ }
+
+ size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
+ stream->writeInt(vertexShaderSize);
+
+ const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(vertexBlob, vertexShaderSize);
+ }
+
+ stream->writeInt(mPixelExecutables.size());
+ for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
+ {
+ PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
+
+ const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
+ stream->writeInt(outputs.size());
+ for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
+ {
+ stream->writeInt(outputs[outputIndex]);
+ }
+
+ size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
+ stream->writeInt(pixelShaderSize);
+
+ const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(pixelBlob, pixelShaderSize);
+ }
+
+ size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
+ stream->writeInt(geometryShaderSize);
+
+ if (mGeometryExecutable != NULL && geometryShaderSize > 0)
+ {
+ const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
+ stream->writeBytes(geometryBlob, geometryShaderSize);
+ }
+
GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
return true;
}
-ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+ShaderExecutable *ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo)
{
+ std::vector<GLenum> outputs;
+
+ const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+ {
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
+ {
+ outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
+ }
+ else
+ {
+ outputs.push_back(GL_NONE);
+ }
+ }
+
+ return getPixelExecutableForOutputLayout(outputs);
+}
+
+ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
+{
+ for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
+ {
+ if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
+ {
+ return mPixelExecutables[executableIndex]->shaderExecutable();
+ }
+ }
+
std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
outputSignature);
// Generate new pixel executable
- ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL, rx::SHADER_PIXEL,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
- mPixelWorkarounds);
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ mPixelWorkarounds);
+
+ if (!pixelExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+ }
return pixelExecutable;
}
-ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
{
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
+ {
+ if (mVertexExecutables[executableIndex]->matchesSignature(signature))
+ {
+ return mVertexExecutables[executableIndex]->shaderExecutable();
+ }
+ }
+
// Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes);
+ std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
// Generate new vertex executable
- ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL,
- rx::SHADER_VERTEX,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL,
+ SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
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(inputLayout, signature, vertexExecutable));
+ }
return vertexExecutable;
}
-ShaderExecutable *ProgramD3D::getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers, int registers)
+bool ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
- std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+ gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS];
+ GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
+ ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
- ShaderExecutable *geometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL,
- rx::SHADER_GEOMETRY, transformFeedbackLinkedVaryings,
- separatedOutputBuffers, rx::ANGLE_D3D_WORKAROUND_NONE);
+ std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
+ ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
- return geometryExecutable;
-}
+ if (usesGeometryShader())
+ {
+ std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
-ShaderExecutable *ProgramD3D::loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
-{
- return mRenderer->loadExecutable(function, length, type, transformFeedbackLinkedVaryings, separatedOutputBuffers);
+ mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL,
+ SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ ANGLE_D3D_WORKAROUND_NONE);
+ }
+
+ return (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
}
bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables)
+ const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps)
{
- rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
- rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+ ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+ mTransformFeedbackBufferMode = transformFeedbackBufferMode;
mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
@@ -200,7 +510,7 @@
mShaderVersion = vertexShaderD3D->getShaderVersion();
// Map the varyings to the register file
- rx::VaryingPacking packing = { NULL };
+ VaryingPacking packing = { NULL };
*registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings);
if (*registers < 0)
@@ -262,7 +572,7 @@
}
gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::UniformBlock*> uniformBlocks, const std::vector<gl::Buffer*> boundBuffers,
- const gl::Caps &caps)
+ const gl::Caps &caps)
{
const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
@@ -352,12 +662,19 @@
void ProgramD3D::reset()
{
+ SafeDeleteContainer(mVertexExecutables);
+ SafeDeleteContainer(mPixelExecutables);
+ SafeDelete(mGeometryExecutable);
+
+ mTransformFeedbackBufferMode = GL_NONE;
+ mTransformFeedbackLinkedVaryings.clear();
+
mVertexHLSL.clear();
- mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mShaderVersion = 100;
mPixelHLSL.clear();
- mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mUsesFragDepth = false;
mPixelShaderKey.clear();
mUsesPointSize = false;
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/libGLESv2/renderer/d3d/ProgramD3D.h
index 0ca4643..50bdc58 100644
--- a/src/libGLESv2/renderer/d3d/ProgramD3D.h
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -37,8 +37,11 @@
const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
int getShaderVersion() const { return mShaderVersion; }
+ GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
+ std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
+ sh::Attribute *getShaderAttributes() { return mShaderAttributes; }
- bool usesPointSize() const;
+ bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const;
@@ -46,24 +49,18 @@
bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
bool save(gl::BinaryOutputStream *stream);
- ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
- ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
- ShaderExecutable *getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers, int registers);
- ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
+ ShaderExecutable *getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo);
+ ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
+ ShaderExecutable *getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]);
+ ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
+
+ bool compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers);
bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables);
+ const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps);
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
@@ -83,9 +80,49 @@
private:
DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
+ class VertexExecutable
+ {
+ public:
+ VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+ const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
+ rx::ShaderExecutable *shaderExecutable);
+ ~VertexExecutable();
+
+ bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
+
+ const gl::VertexFormat *inputs() const { return mInputs; }
+ const GLenum *signature() const { return mSignature; }
+ rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
+ GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
+ rx::ShaderExecutable *mShaderExecutable;
+ };
+
+ class PixelExecutable
+ {
+ public:
+ PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
+ ~PixelExecutable();
+
+ bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
+
+ const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
+ rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ std::vector<GLenum> mOutputSignature;
+ rx::ShaderExecutable *mShaderExecutable;
+ };
+
Renderer *mRenderer;
DynamicHLSL *mDynamicHLSL;
+ std::vector<VertexExecutable *> mVertexExecutables;
+ std::vector<PixelExecutable *> mPixelExecutables;
+ rx::ShaderExecutable *mGeometryExecutable;
+
std::string mVertexHLSL;
rx::D3DWorkaroundType mVertexWorkarounds;
@@ -99,6 +136,11 @@
UniformStorage *mVertexUniformStorage;
UniformStorage *mFragmentUniformStorage;
+ GLenum mTransformFeedbackBufferMode;
+ std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
+
+ sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS];
+
int mShaderVersion;
};
diff --git a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index b006c04..2cd7988 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -12,6 +12,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
@@ -137,7 +138,8 @@
{
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout);
- ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout));
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programD3D->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/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 990972d..fe8998f 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -1329,9 +1329,10 @@
gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
- ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ShaderExecutable *vertexExe = programD3D->getVertexExecutableForInputLayout(inputLayout);
+ ShaderExecutable *pixelExe = programD3D->getPixelExecutableForFramebuffer(framebuffer);
+ ShaderExecutable *geometryExe = programD3D->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 17cb86c..9729f51 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -1670,8 +1670,9 @@
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard);
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ShaderExecutable *vertexExe = programD3D->getVertexExecutableForInputLayout(inputLayout);
+ ShaderExecutable *pixelExe = programD3D->getPixelExecutableForFramebuffer(framebuffer);
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);