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 @@
#include <cstddef>
#include <string>
#include <vector>
#include <stdint.h>
namespace gl
{
......@@ -26,7 +27,7 @@ class BinaryInputStream
{
mError = false;
mOffset = 0;
mData = static_cast<const char*>(data);
mData = static_cast<const uint8_t*>(data);
mLength = length;
}
......@@ -85,7 +86,7 @@ class BinaryInputStream
return;
}
v->assign(mData + mOffset, length);
v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
mOffset += length;
}
......@@ -115,11 +116,16 @@ class BinaryInputStream
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>
......
......@@ -80,42 +80,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
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 @@ 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()
{
}
......@@ -189,7 +112,6 @@ unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
mProgram(impl),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true),
......@@ -220,93 +142,6 @@ unsigned int ProgramBinary::issueSerial()
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 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const
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 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
{
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 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
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 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
{
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 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
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 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
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, &registers, &linkedVaryings, &mOutputVariables))
if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
&registers, &linkedVaryings, &mOutputVariables, caps))
{
return false;
}
......@@ -1546,29 +1221,16 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
}
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 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
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::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
void ProgramBinary::reset()
{
SafeDeleteContainer(mVertexExecutables);
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
mSamplersPS.clear();
mSamplersVS.clear();
......
......@@ -101,11 +101,6 @@ class ProgramBinary : public RefCountObject
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 @@ class ProgramBinary : public RefCountObject
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;
......
......@@ -25,37 +25,23 @@ class ProgramImpl
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;
......
......@@ -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 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
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 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
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 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
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 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream)
{
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 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream)
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 @@ bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shad
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::applyUniforms(const std::vector<gl::LinkedUniform*> &unifo
}
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 @@ unsigned int ProgramD3D::getReservedUniformVectors(GLenum shader)
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;
......
......@@ -37,8 +37,11 @@ class ProgramD3D : public ProgramImpl
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 @@ class ProgramD3D : public ProgramImpl
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 @@ class ProgramD3D : public ProgramImpl
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 @@ class ProgramD3D : public ProgramImpl
UniformStorage *mVertexUniformStorage;
UniformStorage *mFragmentUniformStorage;
GLenum mTransformFeedbackBufferMode;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS];
int mShaderVersion;
};
......
......@@ -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::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
{
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)
......
......@@ -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,
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);
......
......@@ -1670,8 +1670,9 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
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);
......
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