From: Ian Romanick <[email protected]> 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 <[email protected]> --- tests/all.py | 2 +- .../arb_separate_shader_objects/CMakeLists.gl.txt | 1 + .../spec/arb_separate_shader_objects/api-errors.c | 349 +++++++++++++++++++++ 3 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 tests/spec/arb_separate_shader_objects/api-errors.c diff --git a/tests/all.py b/tests/all.py index 7648bb7..5230cb8 100644 --- a/tests/all.py +++ b/tests/all.py @@ -1808,7 +1808,7 @@ arb_separate_shader_objects['400 combinations by location'] = plain_test('arb_se arb_separate_shader_objects['400 combinations by name'] = plain_test('arb_separate_shader_object-400-combinations -fbo') arb_separate_shader_objects['active sampler conflict'] = concurrent_test('arb_separate_shader_object-active-sampler-conflict') arb_separate_shader_objects['dlist'] = concurrent_test('arb_separate_shader_object-dlist') -arb_separate_shader_objects['uniform namespace is per-program'] = concurrent_test('arb_separate_shader_object-uniform-namespace') +arb_separate_shader_objects['misc. API error checks'] = concurrent_test('arb_separate_shader_object-api-errors') # Group ARB_sampler_objects arb_sampler_objects = {} diff --git a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt index 43440bc..b049e3e 100644 --- a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt +++ b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt @@ -12,6 +12,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-dlist dlist.c sso-common.c) piglit_add_executable (arb_separate_shader_object-GetProgramPipelineiv GetProgramPipelineiv.c) piglit_add_executable (arb_separate_shader_object-IsProgramPipeline IsProgramPipeline.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..9b4b30e --- /dev/null +++ b/tests/spec/arb_separate_shader_objects/api-errors.c @@ -0,0 +1,349 @@ +/* + * 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-common.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." + * + * Note that this should *not* generate an error or fail to link! See + * the glsl-link-empty-prog-01 and glsl-link-empty-prog-02 tests for + * more information. + */ + glLinkProgram(prog); + + 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(source, 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; +} -- 1.8.1.4 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
