Add option to support EXT_draw_buffers with NV_draw_buffers
After this patch, it is possible to set a flag to change
EXT_draw_buffers extension directives to NV_draw_buffers in ESSL.
This enables users of ANGLE to emulate EXT_draw_buffers by using
NV_draw_buffers in combination with GLES3.0.
Change-Id: I5dacdbd6cd0d0362424ea3791557342c42efd4bd
Reviewed-on: https://chromium-review.googlesource.com/219941
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index b7989f5..10a89dc 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -246,6 +246,12 @@
int EXT_frag_depth;
int EXT_shader_texture_lod;
+ // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
+ // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
+ // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
+ // function. This applies to Tegra K1 devices.
+ int NV_draw_buffers;
+
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
int FragmentPrecisionHigh;
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 368cd2a..8e1743d 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -360,7 +360,8 @@
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
- << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
+ << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
+ << ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
builtInResourcesString = strstream.str();
}
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index 20ce716..e0ed5f5 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -201,6 +201,8 @@
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
+ resources->NV_draw_buffers = 0;
+
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
diff --git a/src/compiler/translator/TranslatorESSL.cpp b/src/compiler/translator/TranslatorESSL.cpp
index 5b99fea..df6266b 100644
--- a/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/compiler/translator/TranslatorESSL.cpp
@@ -37,8 +37,13 @@
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) {
- sink << "#extension " << iter->first << " : "
- << getBehaviorString(iter->second) << "\n";
+ if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
+ sink << "#extension GL_NV_draw_buffers : "
+ << getBehaviorString(iter->second) << "\n";
+ } else {
+ sink << "#extension " << iter->first << " : "
+ << getBehaviorString(iter->second) << "\n";
+ }
}
}
}
diff --git a/tests/compiler_tests/NV_draw_buffers_test.cpp b/tests/compiler_tests/NV_draw_buffers_test.cpp
new file mode 100644
index 0000000..68ef5ea
--- /dev/null
+++ b/tests/compiler_tests/NV_draw_buffers_test.cpp
@@ -0,0 +1,60 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// NV_draw_buffers_test.cpp:
+// Test for NV_draw_buffers setting
+//
+
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/TranslatorESSL.h"
+
+class NVDrawBuffersTest : public testing::Test
+{
+ public:
+ NVDrawBuffersTest() {}
+
+ protected:
+ virtual void SetUp()
+ {
+ ShBuiltInResources resources;
+ ShInitBuiltInResources(&resources);
+ resources.MaxDrawBuffers = 8;
+ resources.EXT_draw_buffers = 1;
+ resources.NV_draw_buffers = 1;
+
+ mTranslator = new TranslatorESSL(GL_FRAGMENT_SHADER, SH_GLES2_SPEC);
+ ASSERT_TRUE(mTranslator->Init(resources));
+ }
+
+ virtual void TearDown()
+ {
+ delete mTranslator;
+ }
+
+ TranslatorESSL *mTranslator;
+};
+
+TEST_F(NVDrawBuffersTest, NVDrawBuffers)
+{
+ const std::string &shaderString =
+ "#extension GL_EXT_draw_buffers : require\n"
+ "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragData[0] = vec4(1.0);\n"
+ " gl_FragData[1] = vec4(0.0);\n"
+ "}\n";
+
+ const char *shaderStrings[] = { shaderString.c_str() };
+ ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_OBJECT_CODE));
+
+ TInfoSink& infoSink = mTranslator->getInfoSink();
+ std::string objCode(infoSink.obj.c_str());
+ size_t nv_draw_buffers_ind = objCode.find("GL_NV_draw_buffers");
+ EXPECT_NE(std::string::npos, nv_draw_buffers_ind);
+ size_t ext_draw_buffers_ind = objCode.find("GL_EXT_draw_buffers");
+ EXPECT_EQ(std::string::npos, ext_draw_buffers_ind);
+};