summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2015-01-20 10:21:10 -0800
committerIan Romanick <ian.d.romanick@intel.com>2019-06-26 08:31:49 -0700
commit904645808e9fd5a9003e198670af92f274575a0d (patch)
tree1eb63bd98821935fcc6f7f60a1e7f4561e0fa146
parent6d132bebe6adbf1e92b806a6dbf2963ea3b9a4a1 (diff)
arb_vertex_program: Verify that unsupported functions generate errorsHEADmaster
Once upon a time, Mesa accidentally enabled GL_ARB_vertex_program in Core Profile. We fixed that, but continued to export the functions. We eventually fixed that too. It turns out that, especially in the piglit framework, it's really hard to verify that a function is not there. The piglit framework will detect that a function is being called that is not supported by the implementation, and it will print a friendly message. We don't want that. We want to call the function specifically because we know it's not supported. As a result, glXGetProcAddress has to be used directly. Using glXGetProcAddress poses two problems. First, it can either return NULL or it can return a pointer to a dispatch trampoile function. Some closed-source libGL implementations will return NULL for functions that they and the associated drivers have never heard of. The open-source libGL implementations will never return NULL because the application might later load a new driver that supports the requested function. Try glXGetProcAddress((const GLubyte *)"glHamsandwich") on your favorite libGL. Second, the trampoline function may or may not call a valid function. Depending on the driver and the libGL the dispatch table entry used by the trampoline function may: 1. Point at garbage. 2. Point at a default function that always sets GL_INVALID_OPERATION. 3. Point at a real implementation of the function that may or may not set GL_INVALID_OPERATION. The only way to determine which you've got is by calling the trampoline function. In case #1, this will result in some signal (probably either SIGSEGV or SIGILL) that leads to program termination. By the definition of the GL spec, this is actually success, so crashing is not a good way to reflect that. To deal with this a combination of signal and sigsetjmp are used. For each function to be tested, 1. Call glXGetProcAddress on the function. If glXGetProcAddress returns NULL, the function passes. 2. Set signal handlers for every reasonable signal that calling outer space might generate. The signal handler will siglongjmp back to the caller. 3. Use sigsetjmp to set the location to which the signal handler should return. 4. Call the function. If GL_INVALID_OPERATION is set, the function passes. If the signal handler is invoked, the call to glGetError will never happen. If any other condition is set, the function fails. This particular test only calls a subset of the GL_ARB_vertex_program functions. The remaining functions require that a valid vertex program be bound. If all the functions included in this test are successful, either the functions would be too (with possible false positives) or an api-errors test should detect their failures. Either way, I didn't see much point in trying them. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Tested-by: Albert Freeman <albertwdfreeman@gmail.com> Reviewed-by: Albert Freeman <albertwdfreeman@gmail.com>
-rw-r--r--tests/opengl.py1
-rw-r--r--tests/spec/arb_vertex_program/CMakeLists.gl.txt4
-rw-r--r--tests/spec/arb_vertex_program/unsupported.c111
3 files changed, 116 insertions, 0 deletions
diff --git a/tests/opengl.py b/tests/opengl.py
index 4c963a301..397b5f40e 100644
--- a/tests/opengl.py
+++ b/tests/opengl.py
@@ -2758,6 +2758,7 @@ with profile.test_list.group_manager(
g(['vp-address-04'], run_concurrent=False)
g(['vp-bad-program'], run_concurrent=False)
g(['vp-max-array'], run_concurrent=False)
+ g(['arb_vertex_program-unsupported'], 'unsupported')
with profile.test_list.group_manager(
PiglitGLTest,
diff --git a/tests/spec/arb_vertex_program/CMakeLists.gl.txt b/tests/spec/arb_vertex_program/CMakeLists.gl.txt
index d52b56511..f906d2950 100644
--- a/tests/spec/arb_vertex_program/CMakeLists.gl.txt
+++ b/tests/spec/arb_vertex_program/CMakeLists.gl.txt
@@ -8,6 +8,10 @@ link_libraries (
${OPENGL_gl_LIBRARY}
)
+IF(PIGLIT_BUILD_GLX_TESTS)
+piglit_add_executable (arb_vertex_program-unsupported unsupported.c)
+ENDIF(PIGLIT_BUILD_GLX_TESTS)
+
piglit_add_executable (arb_vertex_program-get-limits-without-fp get-limits-without-fp.c)
piglit_add_executable (arb_vertex_program-getenv4d-with-error getenv4d-with-error.c)
piglit_add_executable (arb_vertex_program-getlocal4d-with-error getlocal4d-with-error.c)
diff --git a/tests/spec/arb_vertex_program/unsupported.c b/tests/spec/arb_vertex_program/unsupported.c
new file mode 100644
index 000000000..f2cf039a7
--- /dev/null
+++ b/tests/spec/arb_vertex_program/unsupported.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2015 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 unsupported.c
+ * Verify that GL_INVALID_OPERATION is generated in core profile context that
+ * doesn't advertise the GL_ARB_vertex_program extension.
+ */
+#include "piglit-util-gl.h"
+#include <GL/glx.h>
+#include <signal.h>
+#include <setjmp.h>
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 31;
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char source[] =
+ "!!ARBvp1.0\n"
+ "MOV result.position, vertex.position;\n"
+ "END\n"
+ ;
+
+static sigjmp_buf env;
+
+static void
+handler(int s)
+{
+ siglongjmp(env, s);
+}
+
+#define ATTEMPT_FUNCTION(type, name, parameters) \
+ do { \
+ type proc = (type) \
+ glXGetProcAddress((const GLubyte *) # name ); \
+ \
+ printf("%s...\n", # name); \
+ if (proc == NULL) { \
+ printf(" GetProcAddress returned NULL.\n"); \
+ } else { \
+ int s = sigsetjmp(env, true); \
+ if (s == 0) { \
+ printf(" Calling...\n"); \
+ proc parameters ; \
+ pass = piglit_check_gl_error(GL_INVALID_OPERATION) \
+ && pass; \
+ } else { \
+ printf(" Got signal %d.\n", s); \
+ } \
+ } \
+ } while (false)
+
+void
+piglit_init(int argc, char **argv)
+{
+ bool pass = true;
+ GLuint prog = 0;
+
+ piglit_require_not_extension("GL_ARB_vertex_program");
+ piglit_require_not_extension("GL_ARB_fragment_program");
+
+ signal(SIGSEGV, handler);
+ signal(SIGILL, handler);
+ signal(SIGFPE, handler);
+ signal(SIGBUS, handler);
+
+ ATTEMPT_FUNCTION(PFNGLGENPROGRAMSARBPROC, glGenProgramsARB,
+ (1, &prog));
+ ATTEMPT_FUNCTION(PFNGLBINDPROGRAMARBPROC, glBindProgramARB,
+ (GL_VERTEX_PROGRAM_ARB, 1));
+ ATTEMPT_FUNCTION(PFNGLPROGRAMSTRINGARBPROC, glProgramStringARB,
+ (GL_VERTEX_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(source),
+ source));
+ ATTEMPT_FUNCTION(PFNGLDELETEPROGRAMSARBPROC, glDeleteProgramsARB,
+ (1, &prog));
+ ATTEMPT_FUNCTION(PFNGLISPROGRAMARBPROC, glIsProgramARB,
+ (prog));
+
+ piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ return PIGLIT_FAIL;
+}