Commit eb99436e by Brandon Jones

Moving Shader Executables into ProgramD3D

BUG=angle:731 Change-Id: I677fc9773914307184bcdd9ab7ac564956d77f6a Reviewed-on: https://chromium-review.googlesource.com/219814Tested-by: 's avatarBrandon Jones <bajones@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent eeb1f537
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdint.h>
namespace gl namespace gl
{ {
...@@ -26,7 +27,7 @@ class BinaryInputStream ...@@ -26,7 +27,7 @@ class BinaryInputStream
{ {
mError = false; mError = false;
mOffset = 0; mOffset = 0;
mData = static_cast<const char*>(data); mData = static_cast<const uint8_t*>(data);
mLength = length; mLength = length;
} }
...@@ -85,7 +86,7 @@ class BinaryInputStream ...@@ -85,7 +86,7 @@ class BinaryInputStream
return; return;
} }
v->assign(mData + mOffset, length); v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
mOffset += length; mOffset += length;
} }
...@@ -115,11 +116,16 @@ class BinaryInputStream ...@@ -115,11 +116,16 @@ class BinaryInputStream
return mOffset == mLength; return mOffset == mLength;
} }
const uint8_t *data()
{
return mData;
}
private: private:
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream); DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
bool mError; bool mError;
size_t mOffset; size_t mOffset;
const char *mData; const uint8_t *mData;
size_t mLength; size_t mLength;
template <typename T> template <typename T>
......
...@@ -80,42 +80,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name) ...@@ -80,42 +80,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
return subscript; 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) bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
{ {
return var.isRowMajorLayout; return var.isRowMajorLayout;
...@@ -133,47 +97,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element ...@@ -133,47 +97,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element
{ {
} }
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() LinkedVarying::LinkedVarying()
{ {
} }
...@@ -189,7 +112,6 @@ unsigned int ProgramBinary::mCurrentSerial = 1; ...@@ -189,7 +112,6 @@ unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl) ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0), : RefCountObject(0),
mProgram(impl), mProgram(impl),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0), mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0), mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true), mDirtySamplerMapping(true),
...@@ -220,93 +142,6 @@ unsigned int ProgramBinary::issueSerial() ...@@ -220,93 +142,6 @@ unsigned int ProgramBinary::issueSerial()
return mCurrentSerial++; 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) GLuint ProgramBinary::getAttributeLocation(const char *name)
{ {
if (name) if (name)
...@@ -497,17 +332,17 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const ...@@ -497,17 +332,17 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const
size_t ProgramBinary::getTransformFeedbackVaryingCount() const size_t ProgramBinary::getTransformFeedbackVaryingCount() const
{ {
return mTransformFeedbackLinkedVaryings.size(); return mProgram->getTransformFeedbackLinkedVaryings().size();
} }
const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
{ {
return mTransformFeedbackLinkedVaryings[idx]; return mProgram->getTransformFeedbackLinkedVaryings()[idx];
} }
GLenum ProgramBinary::getTransformFeedbackBufferMode() const GLenum ProgramBinary::getTransformFeedbackBufferMode() const
{ {
return mTransformFeedbackBufferMode; return mProgram->getTransformFeedbackBufferMode();
} }
template <typename T> template <typename T>
...@@ -1064,8 +899,8 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina ...@@ -1064,8 +899,8 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
{ {
stream.readInt(&mLinkedAttribute[i].type); stream.readInt(&mLinkedAttribute[i].type);
stream.readString(&mLinkedAttribute[i].name); stream.readString(&mLinkedAttribute[i].name);
stream.readInt(&mShaderAttributes[i].type); stream.readInt(&mProgram->getShaderAttributes()[i].type);
stream.readString(&mShaderAttributes[i].name); stream.readString(&mProgram->getShaderAttributes()[i].name);
stream.readInt(&mSemanticIndex[i]); stream.readInt(&mSemanticIndex[i]);
} }
...@@ -1170,102 +1005,6 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina ...@@ -1170,102 +1005,6 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
stream.readInt(&mUniformIndex[uniformIndexIndex].index); 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)) if (!mProgram->load(infoLog, &stream))
{ {
return false; return false;
...@@ -1296,8 +1035,8 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL ...@@ -1296,8 +1035,8 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
{ {
stream.writeInt(mLinkedAttribute[i].type); stream.writeInt(mLinkedAttribute[i].type);
stream.writeString(mLinkedAttribute[i].name); stream.writeString(mLinkedAttribute[i].name);
stream.writeInt(mShaderAttributes[i].type); stream.writeInt(mProgram->getShaderAttributes()[i].type);
stream.writeString(mShaderAttributes[i].name); stream.writeString(mProgram->getShaderAttributes()[i].name);
stream.writeInt(mSemanticIndex[i]); stream.writeInt(mSemanticIndex[i]);
} }
...@@ -1369,69 +1108,6 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL ...@@ -1369,69 +1108,6 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
stream.writeInt(mUniformIndex[i].index); 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 (!mProgram->save(&stream))
{ {
if (length) if (length)
...@@ -1506,14 +1182,13 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin ...@@ -1506,14 +1182,13 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
mSamplersPS.resize(caps.maxTextureImageUnits); mSamplersPS.resize(caps.maxTextureImageUnits);
mSamplersVS.resize(caps.maxVertexTextureImageUnits); mSamplersVS.resize(caps.maxVertexTextureImageUnits);
mTransformFeedbackBufferMode = transformFeedbackBufferMode;
rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
int registers; int registers;
std::vector<LinkedVarying> linkedVaryings; std::vector<LinkedVarying> linkedVaryings;
if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables)) if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
&registers, &linkedVaryings, &mOutputVariables, caps))
{ {
return false; return false;
} }
...@@ -1546,29 +1221,16 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin ...@@ -1546,29 +1221,16 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
} }
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps)) transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
{ {
success = false; success = false;
} }
if (success) if (success)
{ {
VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS]; // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout); if (!mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers))
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))
{ {
infoLog.append("Failed to create D3D shaders."); infoLog.append("Failed to create D3D shaders.");
success = false; success = false;
...@@ -1596,7 +1258,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at ...@@ -1596,7 +1258,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; 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 if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
{ {
...@@ -2678,13 +2340,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA ...@@ -2678,13 +2340,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
void ProgramBinary::reset() void ProgramBinary::reset()
{ {
SafeDeleteContainer(mVertexExecutables);
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
mSamplersPS.clear(); mSamplersPS.clear();
mSamplersVS.clear(); mSamplersVS.clear();
......
...@@ -101,11 +101,6 @@ class ProgramBinary : public RefCountObject ...@@ -101,11 +101,6 @@ class ProgramBinary : public RefCountObject
rx::ProgramImpl *getImplementation() { return mProgram; } rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { 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); GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex); int getSemanticIndex(int attributeIndex);
...@@ -250,56 +245,12 @@ class ProgramBinary : public RefCountObject ...@@ -250,56 +245,12 @@ class ProgramBinary : public RefCountObject
template <typename T> template <typename T>
void getUniformv(GLint location, T *params, GLenum uniformType); 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; rx::ProgramImpl *mProgram;
std::vector<VertexExecutable *> mVertexExecutables;
std::vector<PixelExecutable *> mPixelExecutables;
rx::ShaderExecutable *mGeometryExecutable;
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS];
int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
GLenum mTransformFeedbackBufferMode;
std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
std::vector<Sampler> mSamplersPS; std::vector<Sampler> mSamplersPS;
std::vector<Sampler> mSamplersVS; std::vector<Sampler> mSamplersVS;
GLuint mUsedVertexSamplerRange; GLuint mUsedVertexSamplerRange;
......
...@@ -25,37 +25,23 @@ class ProgramImpl ...@@ -25,37 +25,23 @@ class ProgramImpl
public: public:
virtual ~ProgramImpl() { } virtual ~ProgramImpl() { }
virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0;
virtual bool usesPointSize() const = 0; virtual bool usesPointSize() const = 0;
virtual bool usesGeometryShader() const = 0;
virtual int getShaderVersion() 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 GLenum getBinaryFormat() = 0;
virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual bool save(gl::BinaryOutputStream *stream) = 0; virtual bool save(gl::BinaryOutputStream *stream) = 0;
virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, virtual bool compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, int registers) = 0;
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 link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, int *registers, const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
gl::VariableLocation> *outputVariables) = 0; std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps) = 0;
virtual void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const = 0;
virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0; virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "libGLESv2/renderer/d3d/ProgramD3D.h" #include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Program.h" #include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/Renderer.h"
...@@ -20,18 +22,101 @@ ...@@ -20,18 +22,101 @@
namespace rx 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(), : ProgramImpl(),
mRenderer(renderer), mRenderer(renderer),
mDynamicHLSL(NULL), mDynamicHLSL(NULL),
mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), mGeometryExecutable(NULL),
mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
mUsesPointSize(false), mUsesPointSize(false),
mVertexUniformStorage(NULL), mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL), mFragmentUniformStorage(NULL),
mShaderVersion(100) mShaderVersion(100)
{ {
mDynamicHLSL = new rx::DynamicHLSL(renderer); mDynamicHLSL = new DynamicHLSL(renderer);
} }
ProgramD3D::~ProgramD3D() ProgramD3D::~ProgramD3D()
...@@ -52,11 +137,6 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl) ...@@ -52,11 +137,6 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
return static_cast<const ProgramD3D*>(impl); return static_cast<const ProgramD3D*>(impl);
} }
bool ProgramD3D::usesPointSize() const
{
return mUsesPointSize;
}
bool ProgramD3D::usesPointSpriteEmulation() const bool ProgramD3D::usesPointSpriteEmulation() const
{ {
return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
...@@ -71,6 +151,21 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -71,6 +151,21 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{ {
stream->readInt(&mShaderVersion); 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->readString(&mVertexHLSL);
stream->readInt(&mVertexWorkarounds); stream->readInt(&mVertexWorkarounds);
stream->readString(&mPixelHLSL); stream->readString(&mPixelHLSL);
...@@ -88,6 +183,91 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -88,6 +183,91 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); 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}; GUID binaryIdentifier = {0};
stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID)); stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
...@@ -105,6 +285,20 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -105,6 +285,20 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream)
{ {
stream->writeInt(mShaderVersion); 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->writeString(mVertexHLSL);
stream->writeInt(mVertexWorkarounds); stream->writeInt(mVertexWorkarounds);
stream->writeString(mPixelHLSL); stream->writeString(mPixelHLSL);
...@@ -112,85 +306,201 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -112,85 +306,201 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeInt(mUsesFragDepth); stream->writeInt(mUsesFragDepth);
stream->writeInt(mUsesPointSize); stream->writeInt(mUsesPointSize);
const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey; const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
stream->writeInt(pixelShaderKey.size()); stream->writeInt(pixelShaderKey.size());
for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++) 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->writeInt(variable.type);
stream->writeString(variable.name); stream->writeString(variable.name);
stream->writeString(variable.source); stream->writeString(variable.source);
stream->writeInt(variable.outputIndex); 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(); GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID)); stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
return true; return true;
} }
ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, ShaderExecutable *ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo)
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
bool separatedOutputBuffers)
{ {
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, std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
outputSignature); outputSignature);
// Generate new pixel executable // Generate new pixel executable
ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL, rx::SHADER_PIXEL, gl::InfoLog tempInfoLog;
transformFeedbackLinkedVaryings, separatedOutputBuffers, ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mPixelWorkarounds); 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; return pixelExecutable;
} }
ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog, ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
const sh::Attribute shaderAttributes[],
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
bool separatedOutputBuffers)
{ {
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 // 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 // Generate new vertex executable
ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL, gl::InfoLog tempInfoLog;
rx::SHADER_VERTEX, ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL,
transformFeedbackLinkedVaryings, separatedOutputBuffers, SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mVertexWorkarounds); 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; return vertexExecutable;
} }
ShaderExecutable *ProgramD3D::getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, bool ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, int registers)
bool separatedOutputBuffers, int registers)
{ {
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->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, std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
rx::SHADER_GEOMETRY, transformFeedbackLinkedVaryings, ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
separatedOutputBuffers, rx::ANGLE_D3D_WORKAROUND_NONE);
return geometryExecutable; if (usesGeometryShader())
} {
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
ShaderExecutable *ProgramD3D::loadExecutable(const void *function, size_t length, rx::ShaderType type, mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL,
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
bool separatedOutputBuffers) (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
{ ANGLE_D3D_WORKAROUND_NONE);
return mRenderer->loadExecutable(function, length, type, transformFeedbackLinkedVaryings, separatedOutputBuffers); }
return (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
} }
bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, int *registers, const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables) 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()); ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
mTransformFeedbackBufferMode = transformFeedbackBufferMode;
mPixelHLSL = fragmentShaderD3D->getTranslatedSource(); mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds(); mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
...@@ -200,7 +510,7 @@ bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shad ...@@ -200,7 +510,7 @@ bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shad
mShaderVersion = vertexShaderD3D->getShaderVersion(); mShaderVersion = vertexShaderD3D->getShaderVersion();
// Map the varyings to the register file // Map the varyings to the register file
rx::VaryingPacking packing = { NULL }; VaryingPacking packing = { NULL };
*registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings); *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings);
if (*registers < 0) if (*registers < 0)
...@@ -352,12 +662,19 @@ unsigned int ProgramD3D::getReservedUniformVectors(GLenum shader) ...@@ -352,12 +662,19 @@ unsigned int ProgramD3D::getReservedUniformVectors(GLenum shader)
void ProgramD3D::reset() void ProgramD3D::reset()
{ {
SafeDeleteContainer(mVertexExecutables);
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
mVertexHLSL.clear(); mVertexHLSL.clear();
mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mShaderVersion = 100; mShaderVersion = 100;
mPixelHLSL.clear(); mPixelHLSL.clear();
mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mUsesFragDepth = false; mUsesFragDepth = false;
mPixelShaderKey.clear(); mPixelShaderKey.clear();
mUsesPointSize = false; mUsesPointSize = false;
......
...@@ -37,8 +37,11 @@ class ProgramD3D : public ProgramImpl ...@@ -37,8 +37,11 @@ class ProgramD3D : public ProgramImpl
const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; } const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
int getShaderVersion() const { return mShaderVersion; } 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 usesPointSpriteEmulation() const;
bool usesGeometryShader() const; bool usesGeometryShader() const;
...@@ -46,24 +49,18 @@ class ProgramD3D : public ProgramImpl ...@@ -46,24 +49,18 @@ class ProgramD3D : public ProgramImpl
bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
bool save(gl::BinaryOutputStream *stream); bool save(gl::BinaryOutputStream *stream);
ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, ShaderExecutable *getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo);
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
bool separatedOutputBuffers); ShaderExecutable *getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]);
ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
const sh::Attribute shaderAttributes[], bool compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, int registers);
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);
bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, int *registers, const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables); 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; void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
...@@ -83,9 +80,49 @@ class ProgramD3D : public ProgramImpl ...@@ -83,9 +80,49 @@ class ProgramD3D : public ProgramImpl
private: private:
DISALLOW_COPY_AND_ASSIGN(ProgramD3D); 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; Renderer *mRenderer;
DynamicHLSL *mDynamicHLSL; DynamicHLSL *mDynamicHLSL;
std::vector<VertexExecutable *> mVertexExecutables;
std::vector<PixelExecutable *> mPixelExecutables;
rx::ShaderExecutable *mGeometryExecutable;
std::string mVertexHLSL; std::string mVertexHLSL;
rx::D3DWorkaroundType mVertexWorkarounds; rx::D3DWorkaroundType mVertexWorkarounds;
...@@ -99,6 +136,11 @@ class ProgramD3D : public ProgramImpl ...@@ -99,6 +136,11 @@ class ProgramD3D : public ProgramImpl
UniformStorage *mVertexUniformStorage; UniformStorage *mVertexUniformStorage;
UniformStorage *mFragmentUniformStorage; UniformStorage *mFragmentUniformStorage;
GLenum mTransformFeedbackBufferMode;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS];
int mShaderVersion; int mShaderVersion;
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h" #include "libGLESv2/VertexAttribute.h"
...@@ -137,7 +138,8 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl ...@@ -137,7 +138,8 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
{ {
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout); 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]; D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
for (unsigned int j = 0; j < ilKey.elementCount; ++j) for (unsigned int j = 0; j < ilKey.elementCount; ++j)
......
...@@ -1329,9 +1329,10 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * ...@@ -1329,9 +1329,10 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive) bool rasterizerDiscard, bool transformFeedbackActive)
{ {
ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); ShaderExecutable *vertexExe = programD3D->getVertexExecutableForInputLayout(inputLayout);
ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); ShaderExecutable *pixelExe = programD3D->getPixelExecutableForFramebuffer(framebuffer);
ShaderExecutable *geometryExe = programD3D->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
......
...@@ -1670,8 +1670,9 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve ...@@ -1670,8 +1670,9 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
ASSERT(!transformFeedbackActive); ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard); ASSERT(!rasterizerDiscard);
ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); ShaderExecutable *vertexExe = programD3D->getVertexExecutableForInputLayout(inputLayout);
ShaderExecutable *pixelExe = programD3D->getPixelExecutableForFramebuffer(framebuffer);
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);
......
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