diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp | 115 |
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]; } } |