Add new draw elements base vertex tests
authorJohn Richardson <john.richardson@mobica.com>
Tue, 14 Feb 2017 09:27:14 +0000 (09:27 +0000)
committerMika Isojärvi <misojarvi@google.com>
Thu, 6 Jul 2017 19:15:56 +0000 (12:15 -0700)
New tests for EXT_draw_elements_base_vertex extension
exercising the following draw calls

- DrawElementsBaseVertex()
- DrawRangeElementsBaseVertex()
- DrawElementsInstancedBaserVertex()

New test groups:
- dEQP-GLES31.functional.draw_elements_base_vertex.*

New tests:
- indices.*
- base_vertex.*
- builtin_variable.*
- points.*
- triangles.*
- triangle_fan.*
- triangle_strip.*
- lines.*
- line_strip.*
- line_loop.*

Extend dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.*
tests to include additional mapping and mismatched primitive mode
errors for base vertex draw calls.

New tests:
- *.primitive_mode_mismatch
- *.invalid_map

Change-Id: Iefc9bcddd3fe8831d2bb20f2e46d06f92daa6d6b

Android.mk
android/cts/master/gles31-master.txt
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fFunctionalTests.cpp
modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp

index e567d55..be25b8f 100644 (file)
@@ -643,6 +643,7 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fCopyImageTests.cpp \
        modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp \
        modules/gles31/functional/es31fSRGBDecodeTests.cpp \
+       modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp \
        modules/gles31/stress/es31sDrawTests.cpp \
        modules/gles31/stress/es31sStressTests.cpp \
        modules/gles31/stress/es31sTessellationGeometryInteractionTests.cpp \
index 0c5d89b..4db737f 100644 (file)
@@ -16590,6 +16590,8 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_array
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_arrays_instanced
@@ -16599,10 +16601,14 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_eleme
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.get_booleanv
@@ -17048,6 +17054,8 @@ dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_arrays_inva
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_arrays_instanced
@@ -17057,10 +17065,14 @@ dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_in
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.log.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.log.state.get_booleanv
@@ -17505,6 +17517,8 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_array
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_arrays_instanced
@@ -17514,10 +17528,14 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_eleme
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_base_vertex_invalid_map
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.get_booleanv
@@ -35570,3 +35588,117 @@ dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.conversion_gpu
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.toggled
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.multiple_textures
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.using_sampler
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.default_attribute
index 0454747..3b5bcb3 100644 (file)
@@ -183,6 +183,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fNegativeShaderStorageTests.hpp
        es31fNegativeSSBOBlockTests.cpp
        es31fNegativeSSBOBlockTests.hpp
+       es31fDrawElementsBaseVertexTests.cpp
+       es31fDrawElementsBaseVertexTests.hpp
        )
 
 add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
diff --git a/modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp
new file mode 100644 (file)
index 0000000..21ef2b9
--- /dev/null
@@ -0,0 +1,910 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 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_draw_elements_base_vertex tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fDrawElementsBaseVertexTests.hpp"
+#include "deRandom.hpp"
+#include "deStringUtil.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuVectorUtil.hpp"
+#include "sglrGLContext.hpp"
+#include "glsDrawTest.hpp"
+#include "gluStrUtil.hpp"
+#include "gluPixelTransfer.hpp"
+#include "gluContextInfo.hpp"
+
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+
+#include <string>
+#include <set>
+
+using std::vector;
+using std::string;
+using tcu::TestLog;
+
+using namespace glw;
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+enum TestIterationType
+{
+       TYPE_DRAW_COUNT,                // !< test with 1, 5, and 25 primitives
+       TYPE_INSTANCE_COUNT,    // !< test with 1, 4, and 11 instances
+
+       TYPE_LAST
+};
+
+static size_t getElementCount (gls::DrawTestSpec::Primitive primitive, size_t primitiveCount)
+{
+       switch (primitive)
+       {
+               case gls::DrawTestSpec::PRIMITIVE_POINTS:                                               return primitiveCount;
+               case gls::DrawTestSpec::PRIMITIVE_TRIANGLES:                                    return primitiveCount * 3;
+               case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:                                 return primitiveCount + 2;
+               case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:                               return primitiveCount + 2;
+               case gls::DrawTestSpec::PRIMITIVE_LINES:                                                return primitiveCount * 2;
+               case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP:                                   return primitiveCount + 1;
+               case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP:                                    return (primitiveCount==1) ? (2) : (primitiveCount);
+               case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:                              return primitiveCount * 4;
+               case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:                 return primitiveCount + 3;
+               case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:                  return primitiveCount * 6;
+               case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:             return primitiveCount * 2 + 4;
+               default:
+                       DE_ASSERT(false);
+                       return 0;
+       }
+}
+
+static void addRangeElementsToSpec (gls::DrawTestSpec& spec)
+{
+       if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
+       {
+               spec.indexMin = 0;
+               spec.indexMax = (int)getElementCount(spec.primitive, spec.primitiveCount);
+       }
+}
+
+static void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type)
+{
+       if (type == TYPE_DRAW_COUNT)
+       {
+               spec.primitiveCount = 1;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "draw count = 1");
+
+               spec.primitiveCount = 5;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "draw count = 5");
+
+               spec.primitiveCount = 25;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "draw count = 25");
+       }
+       else if (type == TYPE_INSTANCE_COUNT)
+       {
+               spec.instanceCount = 1;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "instance count = 1");
+
+               spec.instanceCount = 4;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "instance count = 4");
+
+               spec.instanceCount = 11;
+               addRangeElementsToSpec(spec);
+               test->addIteration(spec, "instance count = 11");
+       }
+       else
+               DE_ASSERT(false);
+}
+
+static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
+{
+       spec.apiType                                                    = glu::ApiType::es(3,1);
+       spec.primitive                                                  = gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
+       spec.primitiveCount                                             = 5;
+       spec.drawMethod                                                 = method;
+       spec.indexType                                                  = gls::DrawTestSpec::INDEXTYPE_LAST;
+       spec.indexPointerOffset                                 = 0;
+       spec.indexStorage                                               = gls::DrawTestSpec::STORAGE_LAST;
+       spec.first                                                              = 0;
+       spec.indexMin                                                   = 0;
+       spec.indexMax                                                   = 0;
+       spec.instanceCount                                              = 1;
+       spec.indirectOffset                                             = 0;
+
+       spec.attribs.resize(2);
+
+       spec.attribs[0].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+       spec.attribs[0].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+       spec.attribs[0].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+       spec.attribs[0].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+       spec.attribs[0].componentCount                  = 4;
+       spec.attribs[0].offset                                  = 0;
+       spec.attribs[0].stride                                  = 0;
+       spec.attribs[0].normalize                               = false;
+       spec.attribs[0].instanceDivisor                 = 0;
+       spec.attribs[0].useDefaultAttribute             = false;
+
+       spec.attribs[1].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+       spec.attribs[1].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+       spec.attribs[1].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+       spec.attribs[1].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+       spec.attribs[1].componentCount                  = 2;
+       spec.attribs[1].offset                                  = 0;
+       spec.attribs[1].stride                                  = 0;
+       spec.attribs[1].normalize                               = false;
+       spec.attribs[1].instanceDivisor                 = 0;
+       spec.attribs[1].useDefaultAttribute             = false;
+
+       addRangeElementsToSpec(spec);
+}
+
+class VertexIDCase : public TestCase
+{
+public:
+                                                                       VertexIDCase                    (Context& context, gls::DrawTestSpec::DrawMethod drawMethod);
+                                                                       ~VertexIDCase                   (void);
+
+       void                                                    init                                    (void);
+       void                                                    deinit                                  (void);
+       IterateResult                                   iterate                                 (void);
+
+       void                                                    draw                                    (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex);
+       void                                                    verifyImage                             (const tcu::Surface& image);
+
+private:
+       const glw::Functions&                   m_gl;
+       glu::ShaderProgram*                             m_program;
+       GLuint                                                  m_coordinatesBuffer;
+       GLuint                                                  m_elementsBuffer;
+       int                                                             m_iterNdx;
+       gls::DrawTestSpec::DrawMethod   m_method;
+
+       enum
+       {
+               VIEWPORT_WIDTH = 64,
+               VIEWPORT_HEIGHT = 64
+       };
+
+       enum
+       {
+               MAX_VERTICES = 2*3      //!< 2 triangles, totals 6 vertices
+       };
+};
+
+VertexIDCase::VertexIDCase (Context& context,  gls::DrawTestSpec::DrawMethod drawMethod)
+       : TestCase                              (context, "vertex_id", "gl_VertexID Test")
+       , m_gl                                  (m_context.getRenderContext().getFunctions())
+       , m_program                             (DE_NULL)
+       , m_coordinatesBuffer   (0)
+       , m_elementsBuffer              (0)
+       , m_iterNdx                             (0)
+       , m_method                              (drawMethod)
+{
+}
+
+VertexIDCase::~VertexIDCase (void)
+{
+       VertexIDCase::deinit();
+}
+
+void VertexIDCase::init (void)
+{
+       m_testCtx.getLog()      << TestLog::Message
+                                               << "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex"
+                                               << TestLog::EndMessage;
+
+       DE_ASSERT(!m_program);
+       m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
+               "#version 310 es\n"
+               "in highp vec4 a_position;\n"
+               "out mediump vec4 v_color;\n"
+               "uniform highp vec4 u_colors[8];\n"
+               "void main (void)\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "       v_color = u_colors[gl_VertexID];\n"
+               "}\n",
+
+               "#version 310 es\n"
+               "in mediump vec4 v_color;\n"
+               "layout(location = 0) out mediump vec4 o_color;\n"
+               "void main (void)\n"
+               "{\n"
+               "       o_color = v_color;\n"
+               "}\n"));
+
+       m_testCtx.getLog() << *m_program;
+
+       if (!m_program->isOk())
+       {
+               delete m_program;
+               m_program = DE_NULL;
+               TCU_FAIL("Failed to compile shader program");
+       }
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
+
+       GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
+       GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer));
+}
+
+void VertexIDCase::deinit (void)
+{
+       delete m_program;
+       m_program = DE_NULL;
+
+       if (m_elementsBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer));
+               m_elementsBuffer = 0;
+       }
+
+       if (m_coordinatesBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
+               m_coordinatesBuffer = 0;
+       }
+}
+
+void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex)
+{
+       switch (m_method)
+       {
+               case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX:
+                       GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex));
+                       break;
+
+               case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX:
+               {
+                       GLint maxElementsVertices = 0;
+                       GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices));
+                       GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex));
+                       break;
+               }
+
+               case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX:
+                               GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex));
+                               break;
+
+               default:
+                       DE_FATAL("Draw method not supported");
+       }
+}
+
+void VertexIDCase::verifyImage (const tcu::Surface& image)
+{
+       tcu::TestLog&   log                             = m_testCtx.getLog();
+       bool                    isOk                    = true;
+
+       const int               colorThreshold  = 0; // expect perfect match
+       tcu::Surface    error                   (image.getWidth(), image.getHeight());
+
+       for (int y = 0; y < image.getHeight(); y++)
+       for (int x = 0; x < image.getWidth(); x++)
+       {
+               const tcu::RGBA pixel = image.getPixel(x, y);
+               bool pixelOk = true;
+
+               // Ignore pixels not drawn with basevertex
+               if ((x < image.getWidth()* 1/4) || (x > image.getWidth()  * 3/4)
+                       || (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4))
+                       continue;
+
+               // Any pixel with !(B ~= 255) is faulty
+               if (de::abs(pixel.getBlue() - 255) > colorThreshold)
+                       pixelOk = false;
+
+               error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
+               isOk = isOk && pixelOk;
+       }
+
+       if (!isOk)
+       {
+               log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
+               log << TestLog::ImageSet("Verification result", "Result of rendering")
+                       << TestLog::Image("Result",             "Result",               image)
+                       << TestLog::Image("Error Mask", "Error mask",   error)
+                       << TestLog::EndImageSet;
+       }
+       else
+       {
+               log << TestLog::ImageSet("Verification result", "Result of rendering")
+                       << TestLog::Image("Result", "Result", image)
+                       << TestLog::EndImageSet;
+       }
+
+       if (isOk)
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+       else
+               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
+}
+
+VertexIDCase::IterateResult VertexIDCase::iterate (void)
+{
+       const GLuint                    drawCount                       = 6;
+       const GLuint                    baseVertex                      = 4;
+       const GLuint                    coordLocation           = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
+       const GLuint                    colorLocation           = m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
+
+       tcu::Surface                    surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+       const GLfloat coords[] =
+       {
+               // full viewport quad
+               -1.0f, -1.0f,
+               +1.0f, -1.0f,
+               +1.0f, +1.0f,
+               -1.0f, +1.0f,
+
+               // half viewport quad centred
+               -0.5f, -0.5f,
+               +0.5f, -0.5f,
+               +0.5f, +0.5f,
+               -0.5f, +0.5f,
+       };
+
+       const GLushort indices[] =
+       {
+               0, 1, 2, 2, 3, 0,
+       };
+
+       const GLfloat colors[] =
+       {
+               0.0f, 0.0f, 0.0f, 1.0f,
+               0.5f, 1.0f, 0.5f, 1.0f,
+               0.0f, 0.5f, 1.0f, 1.0f,
+               0.0f, 1.0f, 0.0f, 1.0f,
+
+               0.0f, 0.0f, 1.0f, 1.0f, // blue
+               0.0f, 0.0f, 1.0f, 1.0f, // blue
+               0.0f, 0.0f, 1.0f, 1.0f, // blue
+               0.0f, 0.0f, 1.0f, 1.0f, // blue
+       };
+
+       GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT));
+       GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white
+       GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
+
+       GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0]));
+
+       GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
+       GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
+       GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
+       GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
+
+       if (m_iterNdx == 0)
+       {
+               tcu::ScopedLogSection   logSection      (m_testCtx.getLog(), "Iter0", "Indices in client-side array");
+               draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex);
+       }
+
+       if (m_iterNdx == 1)
+       {
+               tcu::ScopedLogSection   logSection      (m_testCtx.getLog(), "Iter1", "Indices in element array buffer");
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW));
+               draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex);
+       }
+
+       glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess());
+       verifyImage(surface);
+
+       m_iterNdx += 1;
+
+       return (m_iterNdx < 2) ? CONTINUE : STOP;
+}
+
+class BuiltInVariableGroup : public TestCaseGroup
+{
+public:
+                                                                       BuiltInVariableGroup            (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+                                                                       ~BuiltInVariableGroup           (void);
+
+       void                                                    init                                            (void);
+
+private:
+       gls::DrawTestSpec::DrawMethod   m_method;
+};
+
+BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+       : TestCaseGroup         (context, name, descr)
+       , m_method                      (drawMethod)
+{
+}
+
+BuiltInVariableGroup::~BuiltInVariableGroup (void)
+{
+}
+
+void BuiltInVariableGroup::init (void)
+{
+       addChild(new VertexIDCase(m_context, m_method));
+}
+
+class IndexGroup : public TestCaseGroup
+{
+public:
+                                                                       IndexGroup              (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+                                                                       ~IndexGroup             (void);
+
+       void                                                    init                    (void);
+
+private:
+       gls::DrawTestSpec::DrawMethod   m_method;
+};
+
+IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+       : TestCaseGroup         (context, name, descr)
+       , m_method                      (drawMethod)
+{
+}
+
+IndexGroup::~IndexGroup (void)
+{
+}
+
+void IndexGroup::init (void)
+{
+       struct IndexTest
+       {
+               gls::DrawTestSpec::IndexType    type;
+               int                                                             offsets[3];
+       };
+
+       const IndexTest tests[] =
+       {
+               { gls::DrawTestSpec::INDEXTYPE_BYTE,    { 0, 1, -1 } },
+               { gls::DrawTestSpec::INDEXTYPE_SHORT,   { 0, 2, -1 } },
+               { gls::DrawTestSpec::INDEXTYPE_INT,             { 0, 4, -1 } },
+       };
+
+       gls::DrawTestSpec spec;
+       genBasicSpec(spec, m_method);
+
+       spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
+
+       for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
+       {
+               const IndexTest&        indexTest       = tests[testNdx];
+
+               const std::string       name            = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+               const std::string       desc            = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+               gls::DrawTest*          test            = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
+
+               spec.indexType                  = indexTest.type;
+
+               for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
+               {
+                       const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
+                       spec.indexPointerOffset = indexTest.offsets[iterationNdx];
+                       test->addIteration(spec, iterationDesc.c_str());
+               }
+
+               addChild(test);
+       }
+}
+
+class BaseVertexGroup : public TestCaseGroup
+{
+public:
+                                                                       BaseVertexGroup         (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+                                                                       ~BaseVertexGroup        (void);
+
+       void                                                    init                            (void);
+
+private:
+       gls::DrawTestSpec::DrawMethod   m_method;
+};
+
+BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+       : TestCaseGroup         (context, name, descr)
+       , m_method                      (drawMethod)
+{
+}
+
+BaseVertexGroup::~BaseVertexGroup (void)
+{
+}
+
+void BaseVertexGroup::init (void)
+{
+       struct IndexTest
+       {
+               bool                                                    positiveBase;
+               gls::DrawTestSpec::IndexType    type;
+               int                                                             baseVertex[2];
+       };
+
+       const IndexTest tests[] =
+       {
+               { true,  gls::DrawTestSpec::INDEXTYPE_BYTE,             {  1,  2 } },
+               { true,  gls::DrawTestSpec::INDEXTYPE_SHORT,    {  1,  2 } },
+               { true,  gls::DrawTestSpec::INDEXTYPE_INT,              {  1,  2 } },
+               { false, gls::DrawTestSpec::INDEXTYPE_BYTE,             { -1, -2 } },
+               { false, gls::DrawTestSpec::INDEXTYPE_SHORT,    { -1, -2 } },
+               { false, gls::DrawTestSpec::INDEXTYPE_INT,              { -1, -2 } },
+       };
+
+       gls::DrawTestSpec spec;
+       genBasicSpec(spec, m_method);
+
+       spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
+
+       for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
+       {
+               const IndexTest&        indexTest       = tests[testNdx];
+
+               const std::string       name            = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+               const std::string       desc            = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+               gls::DrawTest*          test            = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
+
+               spec.indexType                  = indexTest.type;
+
+               for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
+               {
+                       const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
+                       spec.baseVertex = indexTest.baseVertex[iterationNdx];
+                       test->addIteration(spec, iterationDesc.c_str());
+               }
+
+               addChild(test);
+       }
+}
+
+class AttributeGroup : public TestCaseGroup
+{
+public:
+                                                                       AttributeGroup  (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
+                                                                       ~AttributeGroup (void);
+
+       void                                                    init                    (void);
+
+private:
+       gls::DrawTestSpec::DrawMethod   m_method;
+       gls::DrawTestSpec::Primitive    m_primitive;
+       gls::DrawTestSpec::IndexType    m_indexType;
+       gls::DrawTestSpec::Storage              m_indexStorage;
+};
+
+AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
+       : TestCaseGroup         (context, name, descr)
+       , m_method                      (drawMethod)
+       , m_primitive           (primitive)
+       , m_indexType           (indexType)
+       , m_indexStorage        (indexStorage)
+{
+}
+
+AttributeGroup::~AttributeGroup (void)
+{
+}
+
+void AttributeGroup::init (void)
+{
+       // Single attribute
+       {
+               gls::DrawTest*          test                            = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
+               gls::DrawTestSpec       spec;
+
+               spec.apiType                                                    = glu::ApiType::es(3,1);
+               spec.primitive                                                  = m_primitive;
+               spec.primitiveCount                                             = 5;
+               spec.drawMethod                                                 = m_method;
+               spec.indexType                                                  = m_indexType;
+               spec.indexPointerOffset                                 = 0;
+               spec.indexStorage                                               = m_indexStorage;
+               spec.first                                                              = 0;
+               spec.indexMin                                                   = 0;
+               spec.indexMax                                                   = 0;
+               spec.instanceCount                                              = 1;
+               spec.indirectOffset                                             = 0;
+
+               spec.attribs.resize(1);
+
+               spec.attribs[0].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[0].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[0].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[0].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[0].componentCount                  = 2;
+               spec.attribs[0].offset                                  = 0;
+               spec.attribs[0].stride                                  = 0;
+               spec.attribs[0].normalize                               = false;
+               spec.attribs[0].instanceDivisor                 = 0;
+               spec.attribs[0].useDefaultAttribute             = false;
+
+               addTestIterations(test, spec, TYPE_DRAW_COUNT);
+
+               this->addChild(test);
+       }
+
+       // Multiple attribute
+       {
+               gls::DrawTest*          test                            = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
+               gls::DrawTestSpec       spec;
+
+               spec.apiType                                                    = glu::ApiType::es(3,1);
+               spec.primitive                                                  = m_primitive;
+               spec.primitiveCount                                             = 5;
+               spec.drawMethod                                                 = m_method;
+               spec.indexType                                                  = m_indexType;
+               spec.indexPointerOffset                                 = 0;
+               spec.indexStorage                                               = m_indexStorage;
+               spec.first                                                              = 0;
+               spec.indexMin                                                   = 0;
+               spec.indexMax                                                   = 0;
+               spec.instanceCount                                              = 1;
+               spec.indirectOffset                                             = 0;
+
+               spec.attribs.resize(2);
+
+               spec.attribs[0].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[0].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[0].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[0].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[0].componentCount                  = 4;
+               spec.attribs[0].offset                                  = 0;
+               spec.attribs[0].stride                                  = 0;
+               spec.attribs[0].normalize                               = false;
+               spec.attribs[0].instanceDivisor                 = 0;
+               spec.attribs[0].useDefaultAttribute             = false;
+
+               spec.attribs[1].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[1].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[1].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[1].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[1].componentCount                  = 2;
+               spec.attribs[1].offset                                  = 0;
+               spec.attribs[1].stride                                  = 0;
+               spec.attribs[1].normalize                               = false;
+               spec.attribs[1].instanceDivisor                 = 0;
+               spec.attribs[1].useDefaultAttribute             = false;
+
+               addTestIterations(test, spec, TYPE_DRAW_COUNT);
+
+               this->addChild(test);
+       }
+
+       // Multiple attribute, second one divided
+       {
+               gls::DrawTest*          test                                    = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
+               gls::DrawTestSpec       spec;
+
+               spec.apiType                                                            = glu::ApiType::es(3,1);
+               spec.primitive                                                          = m_primitive;
+               spec.primitiveCount                                                     = 5;
+               spec.drawMethod                                                         = m_method;
+               spec.indexType                                                          = m_indexType;
+               spec.indexPointerOffset                                         = 0;
+               spec.indexStorage                                                       = m_indexStorage;
+               spec.first                                                                      = 0;
+               spec.indexMin                                                           = 0;
+               spec.indexMax                                                           = 0;
+               spec.instanceCount                                                      = 1;
+               spec.indirectOffset                                                     = 0;
+
+               spec.attribs.resize(3);
+
+               spec.attribs[0].inputType                                       = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[0].outputType                                      = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[0].storage                                         = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[0].usage                                           = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[0].componentCount                          = 4;
+               spec.attribs[0].offset                                          = 0;
+               spec.attribs[0].stride                                          = 0;
+               spec.attribs[0].normalize                                       = false;
+               spec.attribs[0].instanceDivisor                         = 0;
+               spec.attribs[0].useDefaultAttribute                     = false;
+
+               // Add another position component so the instances wont be drawn on each other
+               spec.attribs[1].inputType                                       = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[1].outputType                                      = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[1].storage                                         = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[1].usage                                           = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[1].componentCount                          = 2;
+               spec.attribs[1].offset                                          = 0;
+               spec.attribs[1].stride                                          = 0;
+               spec.attribs[1].normalize                                       = false;
+               spec.attribs[1].instanceDivisor                         = 1;
+               spec.attribs[1].useDefaultAttribute                     = false;
+               spec.attribs[1].additionalPositionAttribute     = true;
+
+               // Instanced color
+               spec.attribs[2].inputType                                       = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[2].outputType                                      = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[2].storage                                         = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[2].usage                                           = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[2].componentCount                          = 3;
+               spec.attribs[2].offset                                          = 0;
+               spec.attribs[2].stride                                          = 0;
+               spec.attribs[2].normalize                                       = false;
+               spec.attribs[2].instanceDivisor                         = 1;
+               spec.attribs[2].useDefaultAttribute                     = false;
+
+               addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
+
+               this->addChild(test);
+       }
+
+       // Multiple attribute, second one default
+       {
+               gls::DrawTest*          test                            = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
+               gls::DrawTestSpec       spec;
+
+               spec.apiType                                                    = glu::ApiType::es(3,1);
+               spec.primitive                                                  = m_primitive;
+               spec.primitiveCount                                             = 5;
+               spec.drawMethod                                                 = m_method;
+               spec.indexType                                                  = m_indexType;
+               spec.indexPointerOffset                                 = 0;
+               spec.indexStorage                                               = m_indexStorage;
+               spec.first                                                              = 0;
+               spec.indexMin                                                   = 0;
+               spec.indexMax                                                   = 0;
+               spec.instanceCount                                              = 1;
+               spec.indirectOffset                                             = 0;
+
+               spec.attribs.resize(2);
+
+               spec.attribs[0].inputType                               = gls::DrawTestSpec::INPUTTYPE_FLOAT;
+               spec.attribs[0].outputType                              = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+               spec.attribs[0].storage                                 = gls::DrawTestSpec::STORAGE_BUFFER;
+               spec.attribs[0].usage                                   = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+               spec.attribs[0].componentCount                  = 2;
+               spec.attribs[0].offset                                  = 0;
+               spec.attribs[0].stride                                  = 0;
+               spec.attribs[0].normalize                               = false;
+               spec.attribs[0].instanceDivisor                 = 0;
+               spec.attribs[0].useDefaultAttribute             = false;
+
+               struct IOPair
+               {
+                       gls::DrawTestSpec::InputType  input;
+                       gls::DrawTestSpec::OutputType output;
+                       int                                                       componentCount;
+               } iopairs[] =
+               {
+                       { gls::DrawTestSpec::INPUTTYPE_FLOAT,            gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
+                       { gls::DrawTestSpec::INPUTTYPE_FLOAT,            gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
+                       { gls::DrawTestSpec::INPUTTYPE_INT,                      gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
+                       { gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
+               };
+
+               for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
+               {
+                       const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
+
+                       spec.attribs[1].inputType                       = iopairs[ioNdx].input;
+                       spec.attribs[1].outputType                      = iopairs[ioNdx].output;
+                       spec.attribs[1].storage                         = gls::DrawTestSpec::STORAGE_BUFFER;
+                       spec.attribs[1].usage                           = gls::DrawTestSpec::USAGE_STATIC_DRAW;
+                       spec.attribs[1].componentCount          = iopairs[ioNdx].componentCount;
+                       spec.attribs[1].offset                          = 0;
+                       spec.attribs[1].stride                          = 0;
+                       spec.attribs[1].normalize                       = false;
+                       spec.attribs[1].instanceDivisor         = 0;
+                       spec.attribs[1].useDefaultAttribute     = true;
+
+                       test->addIteration(spec, desc.c_str());
+               }
+
+               this->addChild(test);
+       }
+}
+
+class MethodGroup : public TestCaseGroup
+{
+public:
+                                                                       MethodGroup                     (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+                                                                       ~MethodGroup            (void);
+
+       void                                                    init                            (void);
+
+private:
+       gls::DrawTestSpec::DrawMethod   m_method;
+};
+
+MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+       : TestCaseGroup         (context, name, descr)
+       , m_method                      (drawMethod)
+{
+}
+
+MethodGroup::~MethodGroup (void)
+{
+}
+
+void MethodGroup::init (void)
+{
+       const bool indexed              =       (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
+                                                       ||      (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
+                                                       ||      (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX);
+
+       const gls::DrawTestSpec::Primitive primitive[] =
+       {
+               gls::DrawTestSpec::PRIMITIVE_POINTS,
+               gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
+               gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
+               gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
+               gls::DrawTestSpec::PRIMITIVE_LINES,
+               gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
+               gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
+       };
+
+       if (indexed)
+       {
+               // Index-tests
+               this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
+               this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
+               this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method));
+       }
+
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
+       {
+               const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
+               const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
+
+               this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
+       }
+}
+
+} // anonymous
+
+DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context)
+       : TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests")
+{
+}
+
+DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void)
+{
+}
+
+void DrawElementsBaseVertexTests::init (void)
+{
+       const gls::DrawTestSpec::DrawMethod basicMethods[] =
+       {
+               gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
+               gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
+               gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
+       };
+
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
+       {
+               const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
+               const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
+
+               this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
+       }
+}
+
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp
new file mode 100644 (file)
index 0000000..f3d349b
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
+#define _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 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_draw_elements_base_vertex tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+class DrawElementsBaseVertexTests : public TestCaseGroup
+{
+public:
+                                                                       DrawElementsBaseVertexTests             (Context& context);
+                                                                       ~DrawElementsBaseVertexTests    (void);
+
+       void                                                    init                                                    (void);
+
+private:
+                                                                       DrawElementsBaseVertexTests             (const DrawElementsBaseVertexTests& other);
+       DrawElementsBaseVertexTests&    operator=                                               (const DrawElementsBaseVertexTests& other);
+};
+
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
index 8e2a3c6..866fcca 100644 (file)
@@ -90,6 +90,7 @@
 #include "es31fDrawBuffersIndexedTests.hpp"
 #include "es31fDefaultVertexArrayObjectTests.hpp"
 #include "es31fSRGBDecodeTests.hpp"
+#include "es31fDrawElementsBaseVertexTests.hpp"
 
 namespace deqp
 {
@@ -355,6 +356,7 @@ void FunctionalTests::init (void)
        addChild(createDrawBuffersIndexedTests                          (m_context));
        addChild(new DefaultVertexArrayObjectTests                      (m_context));
        addChild(new SRGBTextureDecodeTests                                     (m_context));
+       addChild(new DrawElementsBaseVertexTests                        (m_context));
 }
 
 } // Functional
index 53a1414..5c282ec 100644 (file)
@@ -59,6 +59,13 @@ static const char* fragmentShaderSource              =       "${GLSL_VERSION_STRING}\n"
                                                                                                "       fragColor = vec4(0.0);\n"
                                                                                                "}\n\0";
 
+static const char* geometryShaderSource                =       "#version 320 es\n"
+                                                                                               "layout(points) in;\n"
+                                                                                               "layout(points, max_vertices = 3) out;\n"
+                                                                                               "void main (void)\n"
+                                                                                               "{\n"
+                                                                                               "}\n";
+
 void vertex_attribf (NegativeTestContext& ctx)
 {
        ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
@@ -663,8 +670,8 @@ void draw_elements_base_vertex (NegativeTestContext& ctx)
 {
        TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-       GLuint  fbo = 0;
-       GLfloat vertices[1];
+       GLuint                          fbo = 0;
+       GLfloat                         vertices[1];
 
        ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
        ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, vertices, 1);
@@ -694,6 +701,38 @@ void draw_elements_base_vertex (NegativeTestContext& ctx)
        ctx.endSection();
 }
 
+void draw_elements_base_vertex_invalid_map (NegativeTestContext& ctx)
+{
+       GLuint  buf = 0;
+       GLfloat vertices[1];
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to an enabled array or the element array and the buffer object's data store is currently mapped.");
+       ctx.glGenBuffers(1, &buf);
+       ctx.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
+       ctx.glBufferData(GL_ELEMENT_ARRAY_BUFFER, 10, 0, GL_STATIC_DRAW);
+       ctx.glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, 5, GL_MAP_READ_BIT);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, vertices, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+       ctx.glDeleteBuffers(1, &buf);
+       ctx.endSection();
+}
+
+void draw_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+       GLfloat                         vertices[1];
+       glu::ShaderProgram      program (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::GeometrySource(geometryShaderSource));
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+       ctx.glUseProgram(program.getProgram());
+       ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
 void draw_arrays_instanced (NegativeTestContext& ctx)
 {
        const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
@@ -1003,7 +1042,7 @@ void draw_elements_instanced_base_vertex (NegativeTestContext& ctx)
        GLfloat                                         vertices[1];
        map<string, string>                     args;
        args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
-       glu::ShaderProgram                      program (ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
+       glu::ShaderProgram                      program                 (ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
 
        ctx.glUseProgram(program.getProgram());
        ctx.glVertexAttribDivisor(0, 1);
@@ -1041,6 +1080,39 @@ void draw_elements_instanced_base_vertex (NegativeTestContext& ctx)
        ctx.glUseProgram(0);
 }
 
+void draw_elements_instanced_base_vertex_invalid_map (NegativeTestContext& ctx)
+{
+       GLfloat                                         vertices[1];
+       GLuint                                          buf             = 0;
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to an enabled array or the element array and the buffer object's data store is currently mapped.");
+       ctx.glGenBuffers(1, &buf);
+       ctx.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
+       ctx.glBufferData(GL_ELEMENT_ARRAY_BUFFER, 10, 0, GL_STATIC_DRAW);
+       ctx.glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, 5, GL_MAP_READ_BIT);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, vertices, 1, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+       ctx.glDeleteBuffers(1, &buf);
+       ctx.endSection();
+
+}
+
+void draw_elements_instanced_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+       GLfloat                                         vertices[1];
+       glu::ShaderProgram                      geometryProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::GeometrySource(geometryShaderSource));
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+       ctx.glUseProgram(geometryProgram.getProgram());
+       ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
 void draw_range_elements (NegativeTestContext& ctx)
 {
        const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
@@ -1291,42 +1363,80 @@ void draw_range_elements_base_vertex (NegativeTestContext& ctx)
        ctx.glUseProgram(0);
 }
 
+void draw_range_elements_base_vertex_invalid_map (NegativeTestContext& ctx)
+{
+       GLuint  buf             = 0;
+       GLfloat vertices[1];
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to an enabled array or the element array and the buffer object's data store is currently mapped.");
+       ctx.glGenBuffers(1, &buf);
+       ctx.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
+       ctx.glBufferData(GL_ELEMENT_ARRAY_BUFFER, 10, 0, GL_STATIC_DRAW);
+       ctx.glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, 5, GL_MAP_READ_BIT);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_UNSIGNED_INT, vertices, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+       ctx.glDeleteBuffers(1, &buf);
+       ctx.endSection();
+}
+
+void draw_range_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+       GLfloat                         vertices[1];
+       glu::ShaderProgram      geometryProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::GeometrySource(geometryShaderSource));
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+       ctx.glUseProgram(geometryProgram.getProgram());
+       ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, vertices, 1);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
 std::vector<FunctionContainer> getNegativeVertexArrayApiTestFunctions ()
 {
        FunctionContainer funcs[] =
        {
-               {vertex_attribf,                                                                "vertex_attribf",                                                               "Invalid glVertexAttrib{1234}f() usage"                         },
-               {vertex_attribfv,                                                               "vertex_attribfv",                                                              "Invalid glVertexAttrib{1234}fv() usage"                        },
-               {vertex_attribi4,                                                               "vertex_attribi4",                                                              "Invalid glVertexAttribI4{i|ui}f() usage"                       },
-               {vertex_attribi4v,                                                              "vertex_attribi4v",                                                             "Invalid glVertexAttribI4{i|ui}fv() usage"                      },
-               {vertex_attrib_pointer,                                                 "vertex_attrib_pointer",                                                "Invalid glVertexAttribPointer() usage"                         },
-               {vertex_attrib_i_pointer,                                               "vertex_attrib_i_pointer",                                              "Invalid glVertexAttribPointer() usage"                         },
-               {vertex_attrib_format,                                                  "vertex_attrib_format",                                                 "Invalid glVertexAttribFormat() usage"                          },
-               {vertex_attrib_i_format,                                                "vertex_attrib_i_format",                                               "Invalid glVertexAttribIFormat() usage"                         },
-               {enable_vertex_attrib_array,                                    "enable_vertex_attrib_array",                                   "Invalid glEnableVertexAttribArray() usage"                     },
-               {disable_vertex_attrib_array,                                   "disable_vertex_attrib_array",                                  "Invalid glDisableVertexAttribArray() usage"            },
-               {gen_vertex_arrays,                                                             "gen_vertex_arrays",                                                    "Invalid glGenVertexArrays() usage"                                     },
-               {bind_vertex_array,                                                             "bind_vertex_array",                                                    "Invalid glBindVertexArray() usage"                                     },
-               {delete_vertex_arrays,                                                  "delete_vertex_arrays",                                                 "Invalid glDeleteVertexArrays() usage"                          },
-               {vertex_attrib_divisor,                                                 "vertex_attrib_divisor",                                                "Invalid glVertexAttribDivisor() usage"                         },
-               {draw_arrays,                                                                   "draw_arrays",                                                                  "Invalid glDrawArrays() usage"                                          },
-               {draw_arrays_invalid_program,                                   "draw_arrays_invalid_program",                                  "Invalid glDrawArrays() usage"                                          },
-               {draw_arrays_incomplete_primitive,                              "draw_arrays_incomplete_primitive",                             "Invalid glDrawArrays() usage"                                          },
-               {draw_elements,                                                                 "draw_elements",                                                                "Invalid glDrawElements() usage"                                        },
-               {draw_elements_base_vertex,                                             "draw_elements_base_vertex",                                    "Invalid glDrawElementsBaseVertex() usage"                      },
-               {draw_elements_invalid_program,                                 "draw_elements_invalid_program",                                "Invalid glDrawElements() usage"                                        },
-               {draw_elements_incomplete_primitive,                    "draw_elements_incomplete_primitive",                   "Invalid glDrawElements() usage"                                        },
-               {draw_arrays_instanced,                                                 "draw_arrays_instanced",                                                "Invalid glDrawArraysInstanced() usage"                         },
-               {draw_arrays_instanced_invalid_program,                 "draw_arrays_instanced_invalid_program",                "Invalid glDrawArraysInstanced() usage"                         },
-               {draw_arrays_instanced_incomplete_primitive,    "draw_arrays_instanced_incomplete_primitive",   "Invalid glDrawArraysInstanced() usage"                         },
-               {draw_elements_instanced,                                               "draw_elements_instanced",                                              "Invalid glDrawElementsInstanced() usage"                       },
-               {draw_elements_instanced_invalid_program,               "draw_elements_instanced_invalid_program",              "Invalid glDrawElementsInstanced() usage"                       },
-               {draw_elements_instanced_incomplete_primitive,  "draw_elements_instanced_incomplete_primitive", "Invalid glDrawElementsInstanced() usage"                       },
-               {draw_elements_instanced_base_vertex,                   "draw_elements_instanced_base_vertex",                  "Invalid glDrawElementsInstancedBaseVertex() usage"     },
-               {draw_range_elements,                                                   "draw_range_elements",                                                  "Invalid glDrawRangeElements() usage"                           },
-               {draw_range_elements_invalid_program,                   "draw_range_elements_invalid_program",                  "Invalid glDrawRangeElements() usage"                           },
-               {draw_range_elements_incomplete_primitive,              "draw_range_elements_incomplete_primitive",             "Invalid glDrawRangeElements() usage"                           },
-               {draw_range_elements_base_vertex,                               "draw_range_elements_base_vertex",                              "Invalid glDrawRangeElementsBaseVertex() usage"         },
+               {vertex_attribf,                                                                                                "vertex_attribf",                                                                                               "Invalid glVertexAttrib{1234}f() usage"                         },
+               {vertex_attribfv,                                                                                               "vertex_attribfv",                                                                                              "Invalid glVertexAttrib{1234}fv() usage"                        },
+               {vertex_attribi4,                                                                                               "vertex_attribi4",                                                                                              "Invalid glVertexAttribI4{i|ui}f() usage"                       },
+               {vertex_attribi4v,                                                                                              "vertex_attribi4v",                                                                                             "Invalid glVertexAttribI4{i|ui}fv() usage"                      },
+               {vertex_attrib_pointer,                                                                                 "vertex_attrib_pointer",                                                                                "Invalid glVertexAttribPointer() usage"                         },
+               {vertex_attrib_i_pointer,                                                                               "vertex_attrib_i_pointer",                                                                              "Invalid glVertexAttribPointer() usage"                         },
+               {vertex_attrib_format,                                                                                  "vertex_attrib_format",                                                                                 "Invalid glVertexAttribFormat() usage"                          },
+               {vertex_attrib_i_format,                                                                                "vertex_attrib_i_format",                                                                               "Invalid glVertexAttribIFormat() usage"                         },
+               {enable_vertex_attrib_array,                                                                    "enable_vertex_attrib_array",                                                                   "Invalid glEnableVertexAttribArray() usage"                     },
+               {disable_vertex_attrib_array,                                                                   "disable_vertex_attrib_array",                                                                  "Invalid glDisableVertexAttribArray() usage"            },
+               {gen_vertex_arrays,                                                                                             "gen_vertex_arrays",                                                                                    "Invalid glGenVertexArrays() usage"                                     },
+               {bind_vertex_array,                                                                                             "bind_vertex_array",                                                                                    "Invalid glBindVertexArray() usage"                                     },
+               {delete_vertex_arrays,                                                                                  "delete_vertex_arrays",                                                                                 "Invalid glDeleteVertexArrays() usage"                          },
+               {vertex_attrib_divisor,                                                                                 "vertex_attrib_divisor",                                                                                "Invalid glVertexAttribDivisor() usage"                         },
+               {draw_arrays,                                                                                                   "draw_arrays",                                                                                                  "Invalid glDrawArrays() usage"                                          },
+               {draw_arrays_invalid_program,                                                                   "draw_arrays_invalid_program",                                                                  "Invalid glDrawArrays() usage"                                          },
+               {draw_arrays_incomplete_primitive,                                                              "draw_arrays_incomplete_primitive",                                                             "Invalid glDrawArrays() usage"                                          },
+               {draw_elements,                                                                                                 "draw_elements",                                                                                                "Invalid glDrawElements() usage"                                        },
+               {draw_elements_base_vertex,                                                                             "draw_elements_base_vertex",                                                                    "Invalid glDrawElementsBaseVertex() usage"                      },
+               {draw_elements_base_vertex_invalid_map,                                                 "draw_elements_base_vertex_invalid_map" ,                                               "Invalid glDrawElementsBaseVertex() usage"                      },
+               {draw_elements_base_vertex_primitive_mode_mismatch,                             "draw_elements_base_vertex_primitive_mode_mismatch",                    "Invalid glDrawElementsBaseVertex() usage"                      },
+               {draw_elements_invalid_program,                                                                 "draw_elements_invalid_program",                                                                "Invalid glDrawElements() usage"                                        },
+               {draw_elements_incomplete_primitive,                                                    "draw_elements_incomplete_primitive",                                                   "Invalid glDrawElements() usage"                                        },
+               {draw_arrays_instanced,                                                                                 "draw_arrays_instanced",                                                                                "Invalid glDrawArraysInstanced() usage"                         },
+               {draw_arrays_instanced_invalid_program,                                                 "draw_arrays_instanced_invalid_program",                                                "Invalid glDrawArraysInstanced() usage"                         },
+               {draw_arrays_instanced_incomplete_primitive,                                    "draw_arrays_instanced_incomplete_primitive",                                   "Invalid glDrawArraysInstanced() usage"                         },
+               {draw_elements_instanced,                                                                               "draw_elements_instanced",                                                                              "Invalid glDrawElementsInstanced() usage"                       },
+               {draw_elements_instanced_invalid_program,                                               "draw_elements_instanced_invalid_program",                                              "Invalid glDrawElementsInstanced() usage"                       },
+               {draw_elements_instanced_incomplete_primitive,                                  "draw_elements_instanced_incomplete_primitive",                                 "Invalid glDrawElementsInstanced() usage"                       },
+               {draw_elements_instanced_base_vertex,                                                   "draw_elements_instanced_base_vertex",                                                  "Invalid glDrawElementsInstancedBaseVertex() usage"     },
+               {draw_elements_instanced_base_vertex_invalid_map,                               "draw_elements_instanced_base_vertex_invalid_map",                              "Invalid glDrawElementsInstancedBaseVertex() usage"     },
+               {draw_elements_instanced_base_vertex_primitive_mode_mismatch,   "draw_elements_instanced_base_vertex_primitive_mode_mismatch",  "Invalid glDrawElementsInstancedBaseVertex() usage"     },
+               {draw_range_elements,                                                                                   "draw_range_elements",                                                                                  "Invalid glDrawRangeElements() usage"                           },
+               {draw_range_elements_invalid_program,                                                   "draw_range_elements_invalid_program",                                                  "Invalid glDrawRangeElements() usage"                           },
+               {draw_range_elements_incomplete_primitive,                                              "draw_range_elements_incomplete_primitive",                                             "Invalid glDrawRangeElements() usage"                           },
+               {draw_range_elements_base_vertex,                                                               "draw_range_elements_base_vertex",                                                              "Invalid glDrawRangeElementsBaseVertex() usage"         },
+               {draw_range_elements_base_vertex_invalid_map,                                   "draw_range_elements_base_vertex_invalid_map",                                  "Invalid glDrawRangeElementsBaseVertex() usage"         },
+               {draw_range_elements_base_vertex_primitive_mode_mismatch,               "draw_range_elements_base_vertex_primitive_mode_mismatch",              "Invalid glDrawRangeElementsBaseVertex() usage"         },
        };
 
        return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));