aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
diff options
context:
space:
mode:
authorGravatar kkinnunen <kkinnunen@nvidia.com>2015-07-30 22:47:04 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-07-30 22:47:04 -0700
commitd94708e71e8611015cdeb4f5874a11816e40ecdc (patch)
tree46fcc208c449c0717f7e729f98b5e28fa76f07f2 /src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
parentbf49e46aca85dc1a0ec089ccaefbb33e7ed6a7d5 (diff)
Implement support for dual source blending in ES
Use EXT_blend_func_extended to implement dual source blending in OpenGL ES. The extension is the ES version of ARB_blend_func_extended. The extension provides gl_SecondaryFragColorEXT for ES 2.0 contexts. The extension provides glBindFragDataLocationIndexed to bind a custom fragment shader output to the secondary color for ES 3.0 contexts. For ES 3.1 contexts, the extension would also give "layout (location=0, index=1)" output varible layout modifier syntax, but it is not used in this patch. The extension needs #extension GL_EXT_blend_func_extended : require directive for the variables to be available in ES 2.0. For ES 3.0, the directive relaxes the rules for the amount of output variables without layout location qualifiers. OpenGL continues to use GL_ARB_blend_func_extended for dual source blending. Review URL: https://codereview.chromium.org/1266773003
Diffstat (limited to 'src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp')
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 621243f53b..a7a35e3676 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -16,7 +16,7 @@
const char* GrGLFragmentShaderBuilder::kDstTextureColorName = "_dstColor";
static const char* declared_color_output_name() { return "fsColorOut"; }
-static const char* dual_source_output_name() { return "dualSourceOut"; }
+static const char* declared_secondary_color_output_name() { return "fsSecondaryColorOut"; }
static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
SkASSERT(GrBlendEquationIsAdvanced(equation));
@@ -240,8 +240,19 @@ void GrGLFragmentShaderBuilder::enableCustomOutput() {
void GrGLFragmentShaderBuilder::enableSecondaryOutput() {
SkASSERT(!fHasSecondaryOutput);
fHasSecondaryOutput = true;
- fOutputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier,
- dual_source_output_name());
+ if (kGLES_GrGLStandard == fProgramBuilder->gpu()->ctxInfo().standard()) {
+ this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, "GL_EXT_blend_func_extended");
+ }
+
+ // If the primary output is declared, we must declare also the secondary output
+ // and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
+ // output. The condition also co-incides with the condition in whici GLES SL 2.0
+ // requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output.
+ const GrGLSLCaps& caps = *fProgramBuilder->gpu()->glCaps().glslCaps();
+ if (caps.mustDeclareFragmentShaderOutput()) {
+ fOutputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier,
+ declared_secondary_color_output_name());
+ }
}
const char* GrGLFragmentShaderBuilder::getPrimaryColorOutputName() const {
@@ -249,7 +260,9 @@ const char* GrGLFragmentShaderBuilder::getPrimaryColorOutputName() const {
}
const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const {
- return dual_source_output_name();
+ const GrGLSLCaps& caps = *fProgramBuilder->gpu()->glCaps().glslCaps();
+ return caps.mustDeclareFragmentShaderOutput() ? declared_secondary_color_output_name()
+ : "gl_SecondaryFragColorEXT";
}
bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
@@ -270,11 +283,13 @@ bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
}
void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID) {
- if (fHasCustomColorOutput && fProgramBuilder->gpu()->glCaps().bindFragDataLocationSupport()) {
+ const GrGLCaps& caps = fProgramBuilder->gpu()->glCaps();
+ if (fHasCustomColorOutput && caps.bindFragDataLocationSupport()) {
GL_CALL(BindFragDataLocation(programID, 0, declared_color_output_name()));
}
- if (fHasSecondaryOutput) {
- GL_CALL(BindFragDataLocationIndexed(programID, 0, 1, dual_source_output_name()));
+ if (fHasSecondaryOutput && caps.glslCaps()->mustDeclareFragmentShaderOutput()) {
+ GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
+ declared_secondary_color_output_name()));
}
}