[Piglit] [PATCH] sso: Add several misc API error tests

Timothy Arceri timothy.arceri at collabora.com
Tue Jan 26 17:27:04 PST 2016


From: Ian Romanick <ian.d.romanick at intel.com>

V3: rebased, fix variable copy & paste error, update the
relink_program_created_by_glCreateShaderProgram() test to check
for linking error when in core profile and no error in compat
(Timothy).

v2: Add missing extension check for GL_ARB_transform_feedback2.  Use
configure_transform_feedback_object utility function.  Use
CreateShaderProgram_with_xfb utility function.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Timothy Arceri <timothy.arceri at collabora.com>
---
 tests/all.py                                       |   1 +
 .../arb_separate_shader_objects/CMakeLists.gl.txt  |   1 +
 .../spec/arb_separate_shader_objects/api-errors.c  | 352 +++++++++++++++++++++
 3 files changed, 354 insertions(+)
 create mode 100644 tests/spec/arb_separate_shader_objects/api-errors.c

diff --git a/tests/all.py b/tests/all.py
index 33b49f2..2c16c69 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -2193,6 +2193,7 @@ with profile.group_manager(
       'mix-and-match-tcs-tes'),
     g(['arb_separate_shader_object-mixed_explicit_and_non_explicit_locations'],
       'Mixed explicit and non-explicit locations')
+    g(['arb_separate_shader_object-api-errors'], 'misc. API error checks')
     g(['arb_separate_shader_object-rendezvous_by_location', '-fbo'],
       'Rendezvous by location', run_concurrent=False)
     g(['arb_separate_shader_object-rendezvous_by_location-5-stages'],
diff --git a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt
index 572157e..f5512bd 100644
--- a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt
+++ b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt
@@ -11,6 +11,7 @@ link_libraries (
 piglit_add_executable (arb_separate_shader_object-400-combinations 400-combinations.c sso-common.c)
 piglit_add_executable (arb_separate_shader_object-active-sampler-conflict active-sampler-conflict.c)
 piglit_add_executable (arb_separate_shader_object-ActiveShaderProgram-invalid-program ActiveShaderProgram-invalid-program.c sso-common.c)
+piglit_add_executable (arb_separate_shader_object-api-errors api-errors.c sso-common.c)
 piglit_add_executable (arb_separate_shader_object-compat-builtins compat-builtins.c)
 piglit_add_executable (arb_separate_shader_object-dlist dlist.c sso-common.c)
 piglit_add_executable (arb_separate_shader_object-explicit_locations_and_transform_feedback explicit_locations_and_transform_feedback.c)
diff --git a/tests/spec/arb_separate_shader_objects/api-errors.c b/tests/spec/arb_separate_shader_objects/api-errors.c
new file mode 100644
index 0000000..1d6069e
--- /dev/null
+++ b/tests/spec/arb_separate_shader_objects/api-errors.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * \file api-errors.c
+ * Verify miscelaneous API error conditions from the specification.
+ */
+#include "piglit-util-gl.h"
+#include "sso-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+	config.supports_gl_core_version = 31;
+
+	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static bool
+relink_program_created_by_glCreateShaderProgram(void)
+{
+	static const char *code = "void main() { gl_Position = vec4(0); }";
+	GLuint prog = 0;
+	GLuint vs = 0;
+	bool pass = true;
+
+	prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1,
+				      (const GLchar * const*) &code);
+	if (!piglit_link_check_status(prog)) {
+		pass = false;
+		goto done;
+	}
+
+	if (!piglit_check_gl_error(0)) {
+		pass = false;
+		goto done;
+	}
+
+	/* Issue #14 of the GL_ARB_separate_shader_objects spec says:
+	 *
+	 *     "14. Should glLinkProgram work to re-link a shader created with
+	 *          glCreateShaderProgram?
+	 *
+	 *          RESOLVED: NO because the shader created by
+	 *          glCreateShaderProgram is detached and deleted as part of
+	 *          the glCreateShaderProgram sequence.  This means if you
+	 *          call glLinkProgram on a program returned from
+	 *          glCreateShaderProgram, you'll find the re-link fails
+	 *          because no shader object is attached.
+	 *
+	 *          An application is free to attach one or more new shader
+	 *          objects to the program and then relink would work.
+	 *
+	 *          This is fine because re-linking isn't necessary/expected."
+	 */
+	glLinkProgram(prog);
+
+	if (piglit_is_core_profile) {
+		if (piglit_link_check_status(prog)) {
+			printf("Relinking program without any shaders "
+			       "attached succeeded, but it should have "
+			       "failed.\n");
+			pass = false;
+		}
+	} else if (!piglit_link_check_status(prog)) {
+		printf("Relinking program without any shaders attached "
+		       "failed, but it should have succeeded.\n");
+		pass = false;
+	}
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, code);
+	if (vs == 0) {
+		pass = false;
+		goto done;
+	}
+
+	glAttachShader(prog, vs);
+
+	glLinkProgram(prog);
+
+	if (!piglit_link_check_status(prog)) {
+		printf("Relinking program after reattaching a vertex shader "
+		       "failed, but it should have succeeded.\n");
+		pass = false;
+	}
+
+	pass = piglit_check_gl_error(0) && pass;
+
+ done:
+	glDeleteProgram(prog);
+	glDeleteShader(vs);
+
+	piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+				     "relink a program created by "
+				     "glCreateShaderProgramv");
+	return pass;
+}
+
+static bool
+glUseProgramStages_for_a_missing_stage(void)
+{
+	static const char *vs_code = "void main() { gl_Position = vec4(0); }";
+	static const char *fs_code = "void main() { }";
+
+	GLuint vs_prog = 0;
+	GLuint fs_prog = 0;
+	GLuint prog;
+	GLuint pipe = 0;
+	bool pass = true;
+
+	vs_prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1,
+					 (const GLchar * const*) &vs_code);
+	fs_prog = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1,
+					 (const GLchar * const*) &fs_code);
+
+	glGenProgramPipelines(1, &pipe);
+	glBindProgramPipeline(pipe);
+	glUseProgramStages(pipe, GL_VERTEX_SHADER_BIT, vs_prog);
+	glUseProgramStages(pipe, GL_FRAGMENT_SHADER_BIT, fs_prog);
+
+	/* Sanity check.
+	 */
+	glGetProgramPipelineiv(pipe, GL_FRAGMENT_SHADER, (GLint *) &prog);
+	if (prog != fs_prog) {
+		printf("Sanity check failed - fragment shader program "
+		       "mismatch.\n");
+		pass = false;
+	}
+
+	glGetProgramPipelineiv(pipe, GL_VERTEX_SHADER, (GLint *) &prog);
+	if (prog != vs_prog) {
+		printf("Sanity check failed - vertex shader program "
+		       "mismatch.\n");
+		pass = false;
+	}
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	/* Issue #7 of the GL_ARB_separate_shader_objects spec says:
+	 *
+	 *     "7.  What happens if you have a program object current for a
+	 *          shader stage, but the program object doesn't contain an
+	 *          executable for that stage?
+	 *
+	 *          RESOLVED: This is not an error; instead it is as though
+	 *          there were no program bound to that stage.  We have two
+	 *          different notions for programs bound to shader stages.  A
+	 *          program is "current" for a stage if it bound to that stage
+	 *          in the active program pipeline object.  A program is
+	 *          "active" for a stage if it is current and it has an
+	 *          executable for this stage.  In this case, the program
+	 *          would be current but not active.
+	 *
+	 *          When no program is active for a stage, the stage will be
+	 *          replaced with fixed functionality logic (compatibility
+	 *          profile vertex and fragment), disabled (tessellation
+	 *          control and evaluation, geometry), or have undefined
+	 *          results (core profile vertex and fragment).
+	 *
+	 *          Support for programs that are current but not active is
+	 *          intentional behavior.  Consider an example where an
+	 *          application wants to use two different types of separate
+	 *          program object -- one for all types of vertex processing
+	 *          and a second for fragment processing.  Some of the vertex
+	 *          pipe programs might include tessellation or geometry
+	 *          shaders; others might only include a vertex shader.  With
+	 *          this configuration, the application can use code like the
+	 *          following:
+	 *
+	 *            #define GL_ALL_VERTEX_PIPE_SHADER_BITS	\
+	 *                (GL_VERTEX_SHADER_BIT             |	\
+	 *                 GL_TESS_CONTROL_SHADER_BIT       |	\
+	 *                 GL_TESS_EVALUATION_SHADER_BIT    |	\
+	 *                 GL_GEOMETRY_SHADER_BIT)
+	 *
+	 *            glUseProgramStages(pipeline,
+	 *                               GL_ALL_VERTEX_PIPE_SHADER_BITS,
+	 *                               vertex_pipe_program);
+	 *            glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT,
+	 *                               fragment_pipe_program);
+	 *
+	 *        Such code wouldn't have to determine if
+	 *        <vertex_pipe_program> has tessellation or geometry shaders.
+	 *        Instead, it simply sets all possible bits, which removes the
+	 *        old program from all non-fragment stages.  For stages not
+	 *        present in the new program, the program will be current but
+	 *        not active, and it will be as though no program were bound
+	 *        to such stages."
+	 *
+	 * Further, the body of the spec says:
+	 *
+	 *     "If UseProgramStages is called with <program> set to zero or
+	 *     with a program object that contains no executable code for a
+	 *     given stages, it is as if the pipeline object has no
+	 *     programmable stage configured for the indicated shader stages."
+	 *
+	 * This indicated to me that the "program == 0" and "program doesn't
+	 * have the specified stage" cases should both cause
+	 * glGetProgramPipelineiv to return zero for the GL_*_SHADER query.
+	 */
+	glUseProgramStages(pipe, GL_FRAGMENT_SHADER_BIT, vs_prog);
+
+	glGetProgramPipelineiv(pipe, GL_FRAGMENT_SHADER, (GLint *) &prog);
+	if (prog != 0) {
+		printf("Using a program that lacks a particular stage for that "
+		       "stage did not cause the stage to use program 0.\n");
+		pass = false;
+	}
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+				     "glUseProgramStages of a program that "
+				     "lacks a specified stage");
+
+	return pass;
+}
+
+static bool
+glActiveShaderProgram_while_transform_feedback_is_active(void)
+{
+	static const char *vs_code = "void main() { gl_Position = vec4(0); }";
+	static const char *fs_code = "void main() { }";
+
+	GLuint vs_prog = 0;
+	GLuint fs_prog = 0;
+	GLuint pipe = 0;
+	GLuint xfb = 0;
+	GLuint buf = 0;
+	bool pass = true;
+	static const char *varyings[] = {"gl_Position"};
+
+	if (!CreateShaderProgram_with_xfb(vs_code, varyings, 1, &vs_prog)) {
+		pass = false;
+		goto done;
+	}
+
+	fs_prog = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1,
+					 (const GLchar * const*) &fs_code);
+
+	glGenProgramPipelines(1, &pipe);
+	glBindProgramPipeline(pipe);
+	glUseProgramStages(pipe, GL_VERTEX_SHADER_BIT, vs_prog);
+	glUseProgramStages(pipe, GL_FRAGMENT_SHADER_BIT, fs_prog);
+
+	configure_transform_feedback_object(&xfb, &buf);
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	glBeginTransformFeedback(GL_TRIANGLES);
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	/* Issue #6b of the GL_ARB_separate_shader_objects spec says:
+	 *
+	 *     "6b. Should the active program be allowed to changed within
+	 *          transform feedback mode?
+	 *
+	 *          RESOLVED:  Yes.
+	 *
+	 *          The active program simply allows uniforms to be changed
+	 *          but doesn't actually change how the graphics pipeline
+	 *          itself is configured or what programs are used for vertex,
+	 *          geometry, and fragment processing."
+	 */
+	glActiveShaderProgram(pipe, vs_prog);
+	glActiveShaderProgram(pipe, fs_prog);
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	glEndTransformFeedback();
+
+	pass = piglit_check_gl_error(0) && pass;
+
+ done:
+	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
+	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+
+	glDeleteTransformFeedbacks(1, &xfb);
+	glDeleteBuffers(1, &buf);
+	glDeleteProgram(vs_prog);
+	glDeleteProgram(fs_prog);
+
+	pass = piglit_check_gl_error(0) && pass;
+
+	piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+				     "glActiveShaderProgram while transform "
+				     "feedback is active");
+
+	return pass;
+}
+
+static bool
+glBindProgramPipeline_while_transform_feedback_is_active(void)
+{
+	/* This is already covered by the "bind_pipeline" mode of the
+	 * ext_transform_feedback-api-errors test.
+	 */
+	return true;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	bool pass = true;
+
+	piglit_require_vertex_shader();
+	piglit_require_fragment_shader();
+	piglit_require_extension("GL_ARB_separate_shader_objects");
+
+	pass = relink_program_created_by_glCreateShaderProgram() && pass;
+	pass = glUseProgramStages_for_a_missing_stage() && pass;
+
+	if (piglit_is_extension_supported("GL_ARB_transform_feedback2")) {
+		pass = glActiveShaderProgram_while_transform_feedback_is_active()
+			&& pass;
+		pass = glBindProgramPipeline_while_transform_feedback_is_active()
+			&& pass;
+	}
+
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
-- 
2.5.0



More information about the Piglit mailing list