summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp115
1 files changed, 76 insertions, 39 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index 14e6c94ca4..bcd04b7157 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
@@ -1165,7 +1165,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
bool usesFragColor = fragmentShader->mUsesFragColor;
bool usesFragData = fragmentShader->mUsesFragData;
- if (usesMRT && usesFragColor && usesFragData)
+ if (usesFragColor && usesFragData)
{
infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
return false;
@@ -1177,6 +1177,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0);
+ // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor
+ const bool broadcast = fragmentShader->mUsesFragColor;
+ const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1);
+
if (registersNeeded > maxVaryingVectors)
{
infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
@@ -1221,8 +1225,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
-
- const unsigned int renderTargetCount = usesMRT ? mRenderer->getMaxRenderTargets() : 1;
+ std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
// special varyings that use reserved registers
int reservedRegisterIndex = registers;
@@ -1472,9 +1475,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
"struct PS_OUTPUT\n"
"{\n";
- for (unsigned int i = 0; i < renderTargetCount; i++)
+ for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
+ {
+ pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
+ }
+
+ if (fragmentShader->mUsesFragDepth)
{
- pixelHLSL += " float4 gl_Color" + str(i) + " : " + targetSemantic + str(i) + ";\n";
+ pixelHLSL += " float gl_Depth : " + depthSemantic + ";\n";
}
pixelHLSL += "};\n"
@@ -1583,11 +1591,16 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
"\n"
" PS_OUTPUT output;\n";
- for (unsigned int i = 0; i < renderTargetCount; i++)
+ for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
{
- unsigned int sourceColor = fragmentShader->mUsesFragData ? i : 0;
+ unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
+
+ pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
+ }
- pixelHLSL += " output.gl_Color" + str(i) + " = gl_Color[" + str(sourceColor) + "];\n";
+ if (fragmentShader->mUsesFragDepth)
+ {
+ pixelHLSL += " output.gl_Depth = gl_Depth;\n";
}
pixelHLSL += "\n"
@@ -1617,6 +1630,14 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
return false;
}
+ int compileFlags = 0;
+ stream.read(&compileFlags);
+ if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ {
+ infoLog.append("Mismatched compilation flags.");
+ return false;
+ }
+
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
stream.read(&mLinkedAttribute[i].type);
@@ -1626,6 +1647,8 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.read(&mSemanticIndex[i]);
}
+ initAttributesByLayout();
+
for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
{
stream.read(&mSamplersPS[i].active);
@@ -1769,6 +1792,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.write(GL_PROGRAM_BINARY_ANGLE);
stream.write(VERSION_DWORD);
+ stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
@@ -1917,36 +1941,48 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
}
bool success = true;
- mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX);
- mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL);
- if (usesGeometryShader())
+ if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
{
- std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader);
- mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY);
+ success = false;
}
- if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms()))
{
- infoLog.append("Failed to create D3D shaders.");
success = false;
-
- delete mVertexExecutable;
- mVertexExecutable = NULL;
- delete mPixelExecutable;
- mPixelExecutable = NULL;
- delete mGeometryExecutable;
- mGeometryExecutable = NULL;
}
- if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
+ // special case for gl_DepthRange, the only built-in uniform (also a struct)
+ if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange)
{
- success = false;
+ mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0));
+ mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0));
+ mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0));
}
- if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms()))
+ if (success)
{
- success = false;
+ mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX);
+ mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL);
+
+ if (usesGeometryShader())
+ {
+ std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader);
+ mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY);
+ }
+
+ if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ {
+ infoLog.append("Failed to create D3D shaders.");
+ success = false;
+
+ delete mVertexExecutable;
+ mVertexExecutable = NULL;
+ delete mPixelExecutable;
+ mPixelExecutable = NULL;
+ delete mGeometryExecutable;
+ mGeometryExecutable = NULL;
+ }
}
return success;
@@ -2019,6 +2055,8 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
}
}
+ initAttributesByLayout();
+
return true;
}
@@ -2545,12 +2583,6 @@ struct AttributeSorter
AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
: originalIndices(semanticIndices)
{
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- indices[i] = i;
- }
-
- std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this);
}
bool operator()(int a, int b)
@@ -2558,27 +2590,32 @@ struct AttributeSorter
return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b];
}
- int indices[MAX_VERTEX_ATTRIBS];
const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
};
-void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
+void ProgramBinary::initAttributesByLayout()
{
- AttributeSorter sorter(mSemanticIndex);
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributesByLayout[i] = i;
+ }
+
+ std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
+}
- int oldIndices[MAX_VERTEX_ATTRIBS];
+void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
+{
rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- oldIndices[i] = mSemanticIndex[i];
oldTranslatedAttributes[i] = attributes[i];
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- int oldIndex = sorter.indices[i];
- sortedSemanticIndices[i] = oldIndices[oldIndex];
+ int oldIndex = mAttributesByLayout[i];
+ sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
attributes[i] = oldTranslatedAttributes[oldIndex];
}
}