/* * Copyright © 2012 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 get-buffer-state.c * * Test that "Get" functions can be used to query the state of * transform feedback buffers. */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB; config.khr_no_error_support = PIGLIT_NO_ERRORS; PIGLIT_GL_TEST_CONFIG_END #define XFB_BUFFER_SIZE 12 enum test_mode { MAIN, INDEXED, }; static struct test_desc { const char *name; enum test_mode mode; GLenum param; } tests[] = { /* name mode param */ { "main_binding", MAIN, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING }, { "indexed_binding", INDEXED, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING }, { "buffer_start", INDEXED, GL_TRANSFORM_FEEDBACK_BUFFER_START }, { "buffer_size", INDEXED, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE }, }; static GLboolean check_integer(const struct test_desc *test, GLenum param, GLint expected) { GLint get_result; const char *param_string = piglit_get_gl_enum_name(param); if (test->mode == MAIN && test->param == param) { glGetIntegerv(param, &get_result); if (get_result != expected) { printf("%s == %i, expected %i\n", param_string, get_result, expected); return GL_FALSE; } } return GL_TRUE; } static GLboolean check_indexed(const struct test_desc *test, GLenum param, GLuint index, GLint expected) { GLint get_result; const char *param_string = piglit_get_gl_enum_name(param); if (test->mode == INDEXED && test->param == param) { glGetIntegeri_v(param, index, &get_result); if (get_result != expected) { printf("%s[%u] == %i, expected %i\n", param_string, index, get_result, expected); return GL_FALSE; } } return GL_TRUE; } static GLboolean do_test(const struct test_desc *test) { GLuint *bufs; GLboolean pass = GL_TRUE; GLint max_separate_attribs; float initial_xfb_buffer_contents[XFB_BUFFER_SIZE]; int i; glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs); printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n", max_separate_attribs); bufs = malloc(max_separate_attribs * sizeof(GLuint)); glGenBuffers(max_separate_attribs, bufs); memset(initial_xfb_buffer_contents, 0, sizeof(initial_xfb_buffer_contents)); /* Main GL_TRANSFORM_FEEDBACK_BUFFER_BINDING should still be * set to its default value. */ pass = check_integer(test, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) && pass; /* Set up buffers. */ for (i = 0; i < max_separate_attribs; ++i) { printf("BindBuffer(TRANSFORM_FEEDBACK_BUFFER, %u)\n", bufs[i]); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]); pass = check_integer(test, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, bufs[i]) && pass; glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buffer_contents), initial_xfb_buffer_contents, GL_STREAM_READ); } /* Indexed bindings should still be set to their default values. */ for (i = 0; i < max_separate_attribs; ++i) { pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, 0) && pass; pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, 0) && pass; pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, 0) && pass; } /* Bind buffers, setting various offsets and sizes. */ for (i = 0; i < max_separate_attribs; ++i) { int offset = 4 * (i % 4); int size = 4 * ((i % 3) + 1); printf("BindBufferRange(TRANSFORM_FEEDBACK_BUFFER, %i, %u, %i, %i)\n", i, bufs[i], offset, size); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bufs[i], offset, size); pass = check_integer(test, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, bufs[i]) && pass; } /* Check indexed bindings. */ for (i = 0; i < max_separate_attribs; ++i) { int offset = 4 * (i % 4); int size = 4 * ((i % 3) + 1); pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, bufs[i]) && pass; pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, offset) && pass; pass = check_indexed(test, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, size) && pass; } return pass; } void print_usage_and_exit(const char *prog_name) { int i; printf("Usage: %s \n" " where is one of:\n", prog_name); for (i = 0; i < ARRAY_SIZE(tests); ++i) printf(" %s\n", tests[i].name); exit(0); } const struct test_desc * find_matching_test(const char *prog_name, const char *test_name) { int i; for (i = 0; i < ARRAY_SIZE(tests); ++i) { if (strcmp(tests[i].name, test_name) == 0) return &tests[i]; } print_usage_and_exit(prog_name); return NULL; /* won't actually be reached */ } void piglit_init(int argc, char **argv) { const struct test_desc *test; /* Parse params. */ if (argc != 2) print_usage_and_exit(argv[0]); test = find_matching_test(argv[0], argv[1]); piglit_require_GLSL(); piglit_require_transform_feedback(); piglit_report_result(do_test(test) ? PIGLIT_PASS : PIGLIT_FAIL); } enum piglit_result piglit_display(void) { /* Should never be reached */ return PIGLIT_FAIL; }