Add tests for GL_EXT_debug_marker

This adds simple support check, randomized, and invalid usage tests for
GL_EXT_debug_marker to the ES2 test module.

Android framework requires GL_EXT_debug_marker extension so tests will
fail on Android unless the extension is supported. On other platforms
the usual convention of reporting NotSupported is followed.

Bug: 21333653
Bug: 18315793
Change-Id: Id73c64e091533564698c736fcdbe24e216481354
diff --git a/Android.mk b/Android.mk
index 5ff953e..9c27830 100644
--- a/Android.mk
+++ b/Android.mk
@@ -304,6 +304,7 @@
 	modules/gles2/functional/es2fBufferWriteTests.cpp \
 	modules/gles2/functional/es2fClippingTests.cpp \
 	modules/gles2/functional/es2fColorClearTest.cpp \
+	modules/gles2/functional/es2fDebugMarkerTests.cpp \
 	modules/gles2/functional/es2fDefaultVertexAttributeTests.cpp \
 	modules/gles2/functional/es2fDepthRangeTests.cpp \
 	modules/gles2/functional/es2fDepthStencilClearTests.cpp \
diff --git a/android/cts/master/com.drawelements.deqp.gles2.xml b/android/cts/master/com.drawelements.deqp.gles2.xml
index cf393cd..e9ad551 100644
--- a/android/cts/master/com.drawelements.deqp.gles2.xml
+++ b/android/cts/master/com.drawelements.deqp.gles2.xml
@@ -43421,6 +43421,14 @@
 					</TestCase>
 				</TestSuite>
 			</TestSuite>
+			<TestCase name="debug_marker">
+				<Test name="supported">
+					<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+				</Test>
+				<Test name="random">
+					<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+				</Test>
+			</TestCase>
 		</TestSuite>
 	</TestSuite>
 </TestPackage>
diff --git a/android/cts/master/gles2-master.txt b/android/cts/master/gles2-master.txt
index 91c556a..fa38349 100644
--- a/android/cts/master/gles2-master.txt
+++ b/android/cts/master/gles2-master.txt
@@ -14103,3 +14103,5 @@
 dEQP-GLES2.functional.lifetime.attach.deleted_input.shader_program
 dEQP-GLES2.functional.lifetime.attach.deleted_output.texture_framebuffer
 dEQP-GLES2.functional.lifetime.attach.deleted_output.renderbuffer_framebuffer
+dEQP-GLES2.functional.debug_marker.supported
+dEQP-GLES2.functional.debug_marker.random
diff --git a/android/cts/master/src/gles2-failures.txt b/android/cts/master/src/gles2-failures.txt
index 7771e66..74c0b72 100644
--- a/android/cts/master/src/gles2-failures.txt
+++ b/android/cts/master/src/gles2-failures.txt
@@ -108,6 +108,7 @@
 dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_pos_y_pos_z_and_pos_x_neg_y_neg_z
 dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_neg_y_pos_z_and_neg_x_pos_y_neg_z
 dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_pos_y_pos_z_and_neg_x_neg_y_neg_z
+dEQP-GLES2.functional.debug_marker.invalid
 dEQP-GLES2.functional.depth_stencil_clear.depth_scissored_masked
 dEQP-GLES2.functional.depth_stencil_clear.depth_stencil_masked
 dEQP-GLES2.functional.depth_stencil_clear.depth_stencil_scissored_masked
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index d95b415..d5829e4 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -2374,6 +2374,13 @@
 	m_gl.hint(target, mode);
 }
 
+void CallLogWrapper::glInsertEventMarkerEXT (glw::GLsizei length, const glw::GLchar *marker)
+{
+	if (m_enableLog)
+		m_log << TestLog::Message << "glInsertEventMarkerEXT(" << length << ", " << getStringStr(marker) << ");" << TestLog::EndMessage;
+	m_gl.insertEventMarkerEXT(length, marker);
+}
+
 void CallLogWrapper::glInvalidateBufferData (glw::GLuint buffer)
 {
 	if (m_enableLog)
@@ -2876,6 +2883,13 @@
 	m_gl.popDebugGroup();
 }
 
+void CallLogWrapper::glPopGroupMarkerEXT (void)
+{
+	if (m_enableLog)
+		m_log << TestLog::Message << "glPopGroupMarkerEXT(" << ");" << TestLog::EndMessage;
+	m_gl.popGroupMarkerEXT();
+}
+
 void CallLogWrapper::glPrimitiveBoundingBoxEXT (glw::GLfloat minX, glw::GLfloat minY, glw::GLfloat minZ, glw::GLfloat minW, glw::GLfloat maxX, glw::GLfloat maxY, glw::GLfloat maxZ, glw::GLfloat maxW)
 {
 	if (m_enableLog)
@@ -3268,6 +3282,13 @@
 	m_gl.pushDebugGroup(source, id, length, message);
 }
 
+void CallLogWrapper::glPushGroupMarkerEXT (glw::GLsizei length, const glw::GLchar *marker)
+{
+	if (m_enableLog)
+		m_log << TestLog::Message << "glPushGroupMarkerEXT(" << length << ", " << getStringStr(marker) << ");" << TestLog::EndMessage;
+	m_gl.pushGroupMarkerEXT(length, marker);
+}
+
 void CallLogWrapper::glQueryCounter (glw::GLuint id, glw::GLenum target)
 {
 	if (m_enableLog)
diff --git a/framework/opengl/gluCallLogWrapperApi.inl b/framework/opengl/gluCallLogWrapperApi.inl
index c18ffaa..55505f1 100644
--- a/framework/opengl/gluCallLogWrapperApi.inl
+++ b/framework/opengl/gluCallLogWrapperApi.inl
@@ -317,6 +317,7 @@
 void					glGetnUniformiv									(glw::GLuint program, glw::GLint location, glw::GLsizei bufSize, glw::GLint *params);
 void					glGetnUniformuiv								(glw::GLuint program, glw::GLint location, glw::GLsizei bufSize, glw::GLuint *params);
 void					glHint											(glw::GLenum target, glw::GLenum mode);
+void					glInsertEventMarkerEXT							(glw::GLsizei length, const glw::GLchar *marker);
 void					glInvalidateBufferData							(glw::GLuint buffer);
 void					glInvalidateBufferSubData						(glw::GLuint buffer, glw::GLintptr offset, glw::GLsizeiptr length);
 void					glInvalidateFramebuffer							(glw::GLenum target, glw::GLsizei numAttachments, const glw::GLenum *attachments);
@@ -381,6 +382,7 @@
 void					glPolygonMode									(glw::GLenum face, glw::GLenum mode);
 void					glPolygonOffset									(glw::GLfloat factor, glw::GLfloat units);
 void					glPopDebugGroup									(void);
+void					glPopGroupMarkerEXT								(void);
 void					glPrimitiveBoundingBoxEXT						(glw::GLfloat minX, glw::GLfloat minY, glw::GLfloat minZ, glw::GLfloat minW, glw::GLfloat maxX, glw::GLfloat maxY, glw::GLfloat maxZ, glw::GLfloat maxW);
 void					glPrimitiveRestartIndex							(glw::GLuint index);
 void					glProgramBinary									(glw::GLuint program, glw::GLenum binaryFormat, const void *binary, glw::GLsizei length);
@@ -437,6 +439,7 @@
 void					glProgramUniformMatrix4x3fv						(glw::GLuint program, glw::GLint location, glw::GLsizei count, glw::GLboolean transpose, const glw::GLfloat *value);
 void					glProvokingVertex								(glw::GLenum mode);
 void					glPushDebugGroup								(glw::GLenum source, glw::GLuint id, glw::GLsizei length, const glw::GLchar *message);
+void					glPushGroupMarkerEXT							(glw::GLsizei length, const glw::GLchar *marker);
 void					glQueryCounter									(glw::GLuint id, glw::GLenum target);
 void					glReadBuffer									(glw::GLenum src);
 void					glReadPixels									(glw::GLint x, glw::GLint y, glw::GLsizei width, glw::GLsizei height, glw::GLenum format, glw::GLenum type, void *pixels);
diff --git a/framework/opengl/wrapper/glwApi.inl b/framework/opengl/wrapper/glwApi.inl
index ef33442..7ed1be9 100644
--- a/framework/opengl/wrapper/glwApi.inl
+++ b/framework/opengl/wrapper/glwApi.inl
@@ -317,6 +317,7 @@
 #define			glGetnUniformiv									glwGetnUniformiv
 #define			glGetnUniformuiv								glwGetnUniformuiv
 #define			glHint											glwHint
+#define			glInsertEventMarkerEXT							glwInsertEventMarkerEXT
 #define			glInvalidateBufferData							glwInvalidateBufferData
 #define			glInvalidateBufferSubData						glwInvalidateBufferSubData
 #define			glInvalidateFramebuffer							glwInvalidateFramebuffer
@@ -381,6 +382,7 @@
 #define			glPolygonMode									glwPolygonMode
 #define			glPolygonOffset									glwPolygonOffset
 #define			glPopDebugGroup									glwPopDebugGroup
+#define			glPopGroupMarkerEXT								glwPopGroupMarkerEXT
 #define			glPrimitiveBoundingBoxEXT						glwPrimitiveBoundingBoxEXT
 #define			glPrimitiveRestartIndex							glwPrimitiveRestartIndex
 #define			glProgramBinary									glwProgramBinary
@@ -437,6 +439,7 @@
 #define			glProgramUniformMatrix4x3fv						glwProgramUniformMatrix4x3fv
 #define			glProvokingVertex								glwProvokingVertex
 #define			glPushDebugGroup								glwPushDebugGroup
+#define			glPushGroupMarkerEXT							glwPushGroupMarkerEXT
 #define			glQueryCounter									glwQueryCounter
 #define			glReadBuffer									glwReadBuffer
 #define			glReadPixels									glwReadPixels
@@ -974,6 +977,7 @@
 void			glwGetnUniformiv								(GLuint program, GLint location, GLsizei bufSize, GLint *params);
 void			glwGetnUniformuiv								(GLuint program, GLint location, GLsizei bufSize, GLuint *params);
 void			glwHint											(GLenum target, GLenum mode);
+void			glwInsertEventMarkerEXT							(GLsizei length, const GLchar *marker);
 void			glwInvalidateBufferData							(GLuint buffer);
 void			glwInvalidateBufferSubData						(GLuint buffer, GLintptr offset, GLsizeiptr length);
 void			glwInvalidateFramebuffer						(GLenum target, GLsizei numAttachments, const GLenum *attachments);
@@ -1038,6 +1042,7 @@
 void			glwPolygonMode									(GLenum face, GLenum mode);
 void			glwPolygonOffset								(GLfloat factor, GLfloat units);
 void			glwPopDebugGroup								();
+void			glwPopGroupMarkerEXT							();
 void			glwPrimitiveBoundingBoxEXT						(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
 void			glwPrimitiveRestartIndex						(GLuint index);
 void			glwProgramBinary								(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
@@ -1094,6 +1099,7 @@
 void			glwProgramUniformMatrix4x3fv					(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 void			glwProvokingVertex								(GLenum mode);
 void			glwPushDebugGroup								(GLenum source, GLuint id, GLsizei length, const GLchar *message);
+void			glwPushGroupMarkerEXT							(GLsizei length, const GLchar *marker);
 void			glwQueryCounter									(GLuint id, GLenum target);
 void			glwReadBuffer									(GLenum src);
 void			glwReadPixels									(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
diff --git a/framework/opengl/wrapper/glwFunctionTypes.inl b/framework/opengl/wrapper/glwFunctionTypes.inl
index 707a13a..bf36b65 100644
--- a/framework/opengl/wrapper/glwFunctionTypes.inl
+++ b/framework/opengl/wrapper/glwFunctionTypes.inl
@@ -317,6 +317,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glGetnUniformivFunc)									(GLuint program, GLint location, GLsizei bufSize, GLint *params);
 typedef GLW_APICALL void			(GLW_APIENTRY* glGetnUniformuivFunc)								(GLuint program, GLint location, GLsizei bufSize, GLuint *params);
 typedef GLW_APICALL void			(GLW_APIENTRY* glHintFunc)											(GLenum target, GLenum mode);
+typedef GLW_APICALL void			(GLW_APIENTRY* glInsertEventMarkerEXTFunc)							(GLsizei length, const GLchar *marker);
 typedef GLW_APICALL void			(GLW_APIENTRY* glInvalidateBufferDataFunc)							(GLuint buffer);
 typedef GLW_APICALL void			(GLW_APIENTRY* glInvalidateBufferSubDataFunc)						(GLuint buffer, GLintptr offset, GLsizeiptr length);
 typedef GLW_APICALL void			(GLW_APIENTRY* glInvalidateFramebufferFunc)							(GLenum target, GLsizei numAttachments, const GLenum *attachments);
@@ -381,6 +382,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glPolygonModeFunc)									(GLenum face, GLenum mode);
 typedef GLW_APICALL void			(GLW_APIENTRY* glPolygonOffsetFunc)									(GLfloat factor, GLfloat units);
 typedef GLW_APICALL void			(GLW_APIENTRY* glPopDebugGroupFunc)									(void);
+typedef GLW_APICALL void			(GLW_APIENTRY* glPopGroupMarkerEXTFunc)								(void);
 typedef GLW_APICALL void			(GLW_APIENTRY* glPrimitiveBoundingBoxEXTFunc)						(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
 typedef GLW_APICALL void			(GLW_APIENTRY* glPrimitiveRestartIndexFunc)							(GLuint index);
 typedef GLW_APICALL void			(GLW_APIENTRY* glProgramBinaryFunc)									(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
@@ -437,6 +439,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glProgramUniformMatrix4x3fvFunc)						(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef GLW_APICALL void			(GLW_APIENTRY* glProvokingVertexFunc)								(GLenum mode);
 typedef GLW_APICALL void			(GLW_APIENTRY* glPushDebugGroupFunc)								(GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef GLW_APICALL void			(GLW_APIENTRY* glPushGroupMarkerEXTFunc)							(GLsizei length, const GLchar *marker);
 typedef GLW_APICALL void			(GLW_APIENTRY* glQueryCounterFunc)									(GLuint id, GLenum target);
 typedef GLW_APICALL void			(GLW_APIENTRY* glReadBufferFunc)									(GLenum src);
 typedef GLW_APICALL void			(GLW_APIENTRY* glReadPixelsFunc)									(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
diff --git a/framework/opengl/wrapper/glwFunctions.inl b/framework/opengl/wrapper/glwFunctions.inl
index 7717c89..2f34d9c 100644
--- a/framework/opengl/wrapper/glwFunctions.inl
+++ b/framework/opengl/wrapper/glwFunctions.inl
@@ -317,6 +317,7 @@
 glGetnUniformivFunc									getnUniformiv;
 glGetnUniformuivFunc								getnUniformuiv;
 glHintFunc											hint;
+glInsertEventMarkerEXTFunc							insertEventMarkerEXT;
 glInvalidateBufferDataFunc							invalidateBufferData;
 glInvalidateBufferSubDataFunc						invalidateBufferSubData;
 glInvalidateFramebufferFunc							invalidateFramebuffer;
@@ -381,6 +382,7 @@
 glPolygonModeFunc									polygonMode;
 glPolygonOffsetFunc									polygonOffset;
 glPopDebugGroupFunc									popDebugGroup;
+glPopGroupMarkerEXTFunc								popGroupMarkerEXT;
 glPrimitiveBoundingBoxEXTFunc						primitiveBoundingBoxEXT;
 glPrimitiveRestartIndexFunc							primitiveRestartIndex;
 glProgramBinaryFunc									programBinary;
@@ -437,6 +439,7 @@
 glProgramUniformMatrix4x3fvFunc						programUniformMatrix4x3fv;
 glProvokingVertexFunc								provokingVertex;
 glPushDebugGroupFunc								pushDebugGroup;
+glPushGroupMarkerEXTFunc							pushGroupMarkerEXT;
 glQueryCounterFunc									queryCounter;
 glReadBufferFunc									readBuffer;
 glReadPixelsFunc									readPixels;
diff --git a/framework/opengl/wrapper/glwImpl.inl b/framework/opengl/wrapper/glwImpl.inl
index 52cf3aa..8ddbc99 100644
--- a/framework/opengl/wrapper/glwImpl.inl
+++ b/framework/opengl/wrapper/glwImpl.inl
@@ -2516,6 +2516,14 @@
 	gl->hint(target, mode);
 }
 
+void glwInsertEventMarkerEXT (GLsizei length, const GLchar *marker)
+{
+	const glw::Functions* gl = glw::getCurrentThreadFunctions();
+	if (!gl)
+		return;
+	gl->insertEventMarkerEXT(length, marker);
+}
+
 void glwInvalidateBufferData (GLuint buffer)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
@@ -3028,6 +3036,14 @@
 	gl->popDebugGroup();
 }
 
+void glwPopGroupMarkerEXT (void)
+{
+	const glw::Functions* gl = glw::getCurrentThreadFunctions();
+	if (!gl)
+		return;
+	gl->popGroupMarkerEXT();
+}
+
 void glwPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
@@ -3476,6 +3492,14 @@
 	gl->pushDebugGroup(source, id, length, message);
 }
 
+void glwPushGroupMarkerEXT (GLsizei length, const GLchar *marker)
+{
+	const glw::Functions* gl = glw::getCurrentThreadFunctions();
+	if (!gl)
+		return;
+	gl->pushGroupMarkerEXT(length, marker);
+}
+
 void glwQueryCounter (GLuint id, GLenum target)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
diff --git a/framework/opengl/wrapper/glwInitExtES.inl b/framework/opengl/wrapper/glwInitExtES.inl
index 61026e5..13b6c6d 100644
--- a/framework/opengl/wrapper/glwInitExtES.inl
+++ b/framework/opengl/wrapper/glwInitExtES.inl
@@ -89,3 +89,10 @@
 	gl->texParameterIiv			= (glTexParameterIivFunc)			loader->get("glTexParameterIivEXT");
 	gl->texParameterIuiv		= (glTexParameterIuivFunc)			loader->get("glTexParameterIuivEXT");
 }
+
+if (de::contains(extSet, "GL_EXT_debug_marker"))
+{
+	gl->insertEventMarkerEXT	= (glInsertEventMarkerEXTFunc)	loader->get("glInsertEventMarkerEXT");
+	gl->popGroupMarkerEXT		= (glPopGroupMarkerEXTFunc)		loader->get("glPopGroupMarkerEXT");
+	gl->pushGroupMarkerEXT		= (glPushGroupMarkerEXTFunc)	loader->get("glPushGroupMarkerEXT");
+}
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index 60c4a71..09144e8 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -2554,6 +2554,13 @@
 
 }
 
+GLW_APICALL void GLW_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker)
+{
+	DE_UNREF(length);
+	DE_UNREF(marker);
+
+}
+
 GLW_APICALL void GLW_APIENTRY glInvalidateBufferData (GLuint buffer)
 {
 	DE_UNREF(buffer);
@@ -3045,6 +3052,11 @@
 
 }
 
+GLW_APICALL void GLW_APIENTRY glPopGroupMarkerEXT (void)
+{
+
+}
+
 GLW_APICALL void GLW_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)
 {
 	DE_UNREF(minX);
@@ -3572,6 +3584,13 @@
 
 }
 
+GLW_APICALL void GLW_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker)
+{
+	DE_UNREF(length);
+	DE_UNREF(marker);
+
+}
+
 GLW_APICALL void GLW_APIENTRY glQueryCounter (GLuint id, GLenum target)
 {
 	DE_UNREF(id);
diff --git a/framework/platform/null/tcuNullRenderContextInitFuncs.inl b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
index cba6f59..b7610b7 100644
--- a/framework/platform/null/tcuNullRenderContextInitFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
@@ -317,6 +317,7 @@
 gl->getnUniformiv								= glGetnUniformiv;
 gl->getnUniformuiv								= glGetnUniformuiv;
 gl->hint										= glHint;
+gl->insertEventMarkerEXT						= glInsertEventMarkerEXT;
 gl->invalidateBufferData						= glInvalidateBufferData;
 gl->invalidateBufferSubData						= glInvalidateBufferSubData;
 gl->invalidateFramebuffer						= glInvalidateFramebuffer;
@@ -381,6 +382,7 @@
 gl->polygonMode									= glPolygonMode;
 gl->polygonOffset								= glPolygonOffset;
 gl->popDebugGroup								= glPopDebugGroup;
+gl->popGroupMarkerEXT							= glPopGroupMarkerEXT;
 gl->primitiveBoundingBoxEXT						= glPrimitiveBoundingBoxEXT;
 gl->primitiveRestartIndex						= glPrimitiveRestartIndex;
 gl->programBinary								= glProgramBinary;
@@ -437,6 +439,7 @@
 gl->programUniformMatrix4x3fv					= glProgramUniformMatrix4x3fv;
 gl->provokingVertex								= glProvokingVertex;
 gl->pushDebugGroup								= glPushDebugGroup;
+gl->pushGroupMarkerEXT							= glPushGroupMarkerEXT;
 gl->queryCounter								= glQueryCounter;
 gl->readBuffer									= glReadBuffer;
 gl->readPixels									= glReadPixels;
diff --git a/modules/gles2/functional/CMakeLists.txt b/modules/gles2/functional/CMakeLists.txt
index 4119bd4..d10d0f8 100644
--- a/modules/gles2/functional/CMakeLists.txt
+++ b/modules/gles2/functional/CMakeLists.txt
@@ -159,6 +159,8 @@
 	es2fFlushFinishTests.hpp
 	es2fShaderFragDataTests.cpp
 	es2fShaderFragDataTests.hpp
+	es2fDebugMarkerTests.cpp
+	es2fDebugMarkerTests.hpp
 	)
 
 add_library(deqp-gles2-functional STATIC ${DEQP_GLES2_FUNCTIONAL_SRCS})
diff --git a/modules/gles2/functional/es2fDebugMarkerTests.cpp b/modules/gles2/functional/es2fDebugMarkerTests.cpp
new file mode 100644
index 0000000..9012914
--- /dev/null
+++ b/modules/gles2/functional/es2fDebugMarkerTests.cpp
@@ -0,0 +1,209 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 2.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GL_EXT_debug_marker tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es2fDebugMarkerTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluRenderContext.hpp"
+#include "glwFunctions.hpp"
+#include "glwEnums.hpp"
+#include "tcuTestLog.hpp"
+#include "deRandom.hpp"
+#include "deUniquePtr.hpp"
+
+namespace deqp
+{
+namespace gles2
+{
+namespace Functional
+{
+
+namespace
+{
+
+using std::vector;
+using tcu::TestLog;
+
+void checkSupport (const glu::ContextInfo& ctxInfo)
+{
+	if (!ctxInfo.isExtensionSupported("GL_EXT_debug_marker"))
+	{
+#if (DE_OS == DE_OS_ANDROID)
+		TCU_THROW(TestError, "Support for GL_EXT_debug_marker is mandatory on Android");
+#else
+		TCU_THROW(NotSupportedError, "GL_EXT_debug_marker is not supported");
+#endif
+	}
+	// else no exception thrown
+}
+
+class IsSupportedCase : public TestCase
+{
+public:
+	IsSupportedCase (Context& context)
+		: TestCase(context, "supported", "Is GL_EXT_debug_marker supported")
+	{
+	}
+
+	IterateResult iterate (void)
+	{
+		checkSupport(m_context.getContextInfo());
+		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "GL_EXT_debug_marker is supported");
+		return STOP;
+	}
+};
+
+void getSimpleRndString (vector<char>& dst, de::Random& rnd, int maxLen)
+{
+	const char s_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -_";
+
+	dst.resize(rnd.getInt(0, (int)maxLen));
+
+	for (size_t ndx = 0; ndx < dst.size(); ndx++)
+		dst[ndx] = rnd.choose<char>(DE_ARRAY_BEGIN(s_chars), DE_ARRAY_END(s_chars));
+}
+
+void getComplexRndString (vector<char>& dst, de::Random& rnd, int maxLen)
+{
+	dst.resize(rnd.getInt(0, (int)maxLen));
+
+	for (size_t ndx = 0; ndx < dst.size(); ndx++)
+		dst[ndx] = (char)rnd.getUint8();
+}
+
+enum CallType
+{
+	CALL_TYPE_PUSH_GROUP	= 0,
+	CALL_TYPE_POP_GROUP,
+	CALL_TYPE_INSERT_MARKER,
+
+	CALL_TYPE_LAST
+};
+
+class RandomCase : public TestCase
+{
+public:
+	RandomCase (Context& context)
+		: TestCase(context, "random", "Random GL_EXT_debug_marker usage")
+	{
+	}
+
+	void init (void)
+	{
+		checkSupport(m_context.getContextInfo());
+	}
+
+	IterateResult iterate (void)
+	{
+		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
+		const int				numIters	= 1000;
+		const int				maxMsgLen	= 4096;
+		de::Random				rnd			(0xaf829c0);
+
+		for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
+		{
+			const CallType		callType	= CallType(rnd.getInt(0, CALL_TYPE_LAST-1));
+
+			if (callType == CALL_TYPE_PUSH_GROUP || callType == CALL_TYPE_INSERT_MARKER)
+			{
+				const bool		nullTerminate	= rnd.getBool();
+				const bool		passLength		= rnd.getBool();
+				const bool		complexMsg		= rnd.getBool();
+				vector<char>	message;
+
+				if (complexMsg)
+					getComplexRndString(message, rnd, maxMsgLen);
+				else
+					getSimpleRndString(message, rnd, maxMsgLen);
+
+				if (nullTerminate)
+					message.push_back(char(0));
+
+				{
+					const glw::GLsizei	length	= passLength ? glw::GLsizei(nullTerminate ? message.size()-1 : message.size()) : 0;
+
+					if (callType == CALL_TYPE_PUSH_GROUP)
+						gl.pushGroupMarkerEXT(length, &message[0]);
+					else
+						gl.insertEventMarkerEXT(length, &message[0]);
+				}
+			}
+			else
+				gl.popGroupMarkerEXT();
+		}
+
+		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");
+
+		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
+		return STOP;
+	}
+};
+
+class InvalidCase : public TestCase
+{
+public:
+	InvalidCase (Context& context)
+		: TestCase(context, "invalid", "Invalid GL_EXT_debug_marker usage")
+	{
+	}
+
+	void init (void)
+	{
+		checkSupport(m_context.getContextInfo());
+	}
+
+	IterateResult iterate (void)
+	{
+		const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
+
+		m_testCtx.getLog() << TestLog::Message << "Note: GL_EXT_debug_marker calls must not report an error even if invalid arguments are supplied." << TestLog::EndMessage;
+
+		gl.pushGroupMarkerEXT(-1, "foo");
+		gl.insertEventMarkerEXT(-1, "foo");
+		gl.pushGroupMarkerEXT(0, DE_NULL);
+		gl.insertEventMarkerEXT(0, DE_NULL);
+		gl.pushGroupMarkerEXT(-1, DE_NULL);
+		gl.insertEventMarkerEXT(-1, DE_NULL);
+
+		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");
+
+		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
+		return STOP;
+	}
+};
+
+} // anonymous
+
+tcu::TestCaseGroup* createDebugMarkerTests (Context& context)
+{
+	de::MovePtr<tcu::TestCaseGroup>	debugMarkerGroup	(new tcu::TestCaseGroup(context.getTestContext(), "debug_marker", "GL_EXT_debug_marker tests"));
+
+	debugMarkerGroup->addChild(new IsSupportedCase	(context));
+	debugMarkerGroup->addChild(new RandomCase		(context));
+	debugMarkerGroup->addChild(new InvalidCase		(context));
+
+	return debugMarkerGroup.release();
+}
+
+} // Functional
+} // gles2
+} // deqp
diff --git a/modules/gles2/functional/es2fDebugMarkerTests.hpp b/modules/gles2/functional/es2fDebugMarkerTests.hpp
new file mode 100644
index 0000000..0daa505
--- /dev/null
+++ b/modules/gles2/functional/es2fDebugMarkerTests.hpp
@@ -0,0 +1,42 @@
+#ifndef _ES2FDEBUGMARKERTESTS_HPP
+#define _ES2FDEBUGMARKERTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 2.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GL_EXT_debug_marker tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes2TestCase.hpp"
+
+namespace deqp
+{
+namespace gles2
+{
+namespace Functional
+{
+
+tcu::TestCaseGroup*		createDebugMarkerTests		(Context& context);
+
+} // Functional
+} // gles2
+} // deqp
+
+#endif // _ES2FDEBUGMARKERTESTS_HPP
diff --git a/modules/gles2/functional/es2fFunctionalTests.cpp b/modules/gles2/functional/es2fFunctionalTests.cpp
index af34ef4..97620cb 100644
--- a/modules/gles2/functional/es2fFunctionalTests.cpp
+++ b/modules/gles2/functional/es2fFunctionalTests.cpp
@@ -98,6 +98,7 @@
 #include "es2fShaderStateQueryTests.hpp"
 
 #include "es2fReadPixelsTests.hpp"
+#include "es2fDebugMarkerTests.hpp"
 
 namespace deqp
 {
@@ -332,6 +333,7 @@
 	addChild(new FlushFinishTests			(m_context));
 	addChild(new DefaultVertexAttributeTests(m_context));
 	addChild(createLifetimeTests			(m_context));
+	addChild(createDebugMarkerTests			(m_context));
 }
 
 } // Functional
diff --git a/scripts/opengl/src_util.py b/scripts/opengl/src_util.py
index 7d960b2..b3f1b90 100644
--- a/scripts/opengl/src_util.py
+++ b/scripts/opengl/src_util.py
@@ -64,6 +64,7 @@
 	'GL_EXT_texture_border_clamp',
 	'GL_EXT_texture_sRGB_R8',
 	'GL_EXT_texture_sRGB_RG8',
+	'GL_EXT_debug_marker',
 ]
 
 def getGLRegistry ():