/* * Copyright © 2009 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 vp-max-array.c * Validate creation of a single maximally sized parameter array. * * \author Ian Romanick */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_RGB; PIGLIT_GL_TEST_CONFIG_END static const char template_header[] = "!!ARBvp1.0\n" "OPTION ARB_position_invariant;\n" "PARAM colors[%d] = {\n" ; static const char template_footer[] = " };\n" "MOV result.color, colors[0];\n" "END\n" ; static const char max_native_template_footer[] = " };\n" "ADDRESS a;\n" "ARL a.x, vertex.position.x;\n" "MOV result.color, colors[a.x];\n" "END\n" ; static const char max_local_template[] = "!!ARBvp1.0\n" "OPTION ARB_position_invariant;\n" "PARAM colors[96] = {\n" " program.%s[0..48],\n" " program.%s[%d..%d]\n" " };\n" "ADDRESS a;\n" "ARL a.x, vertex.position.x;\n" "MOV result.color, colors[a.x];\n" "END\n" ; enum piglit_result piglit_display(void) { return PIGLIT_PASS; } bool query_and_require_limit(GLenum pname, GLint *param, GLint minimum_maximum) { glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, pname, param); if (*param < minimum_maximum) { fprintf(stderr, "%s: Expected at least %d, got %d\n", piglit_get_gl_enum_name(pname), minimum_maximum, *param); return false; } return true; } void piglit_init(int argc, char **argv) { GLint max_parameters; GLint max_native_parameters; GLint max_local_parameters; GLint max_env_parameters; char *shader_source; bool pass = true; size_t len; int offset; unsigned i; (void) argc; (void) argv; piglit_require_vertex_program(); /* First, query all of the limits. */ pass = query_and_require_limit(GL_MAX_PROGRAM_PARAMETERS_ARB, & max_parameters, 96) && pass; pass = query_and_require_limit(GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, & max_native_parameters, 96) && pass; pass = query_and_require_limit(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, & max_local_parameters, 96) && pass; pass = query_and_require_limit(GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, & max_env_parameters, 96) && pass; if (!pass) { piglit_report_result(PIGLIT_FAIL); } /* Allocate a buffer big enough to hold any program that this test * might generate. */ len = sizeof(template_header) + sizeof(template_footer) + sizeof(max_native_template_footer) + (80 * max_parameters) + 1; shader_source = malloc(len); if (shader_source == NULL) piglit_report_result(PIGLIT_FAIL); /* Generate a program that uses the full parameter space using an * array of constants. Since only one parameter is statically used, * this exercises GL_MAX_PROGRAM_PARAMETERS_ARB and *not* * GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB. */ offset = snprintf(shader_source, len, template_header, max_parameters); for (i = 0; i < max_parameters; i++) { int comma = (i < (max_parameters - 1)) ? ',' : ' '; int used = snprintf(& shader_source[offset], len - offset, "\t\t{ %.1f, %.1f, %.1f, %.1f }%c\n", (float) i, (float) i + 0.2, (float) i + 0.4, (float) i + 0.6, comma); offset += used; } memcpy(& shader_source[offset], template_footer, sizeof(template_footer)); (void) piglit_compile_program(GL_VERTEX_PROGRAM_ARB, shader_source); /* Generate a program that uses the full native parameter space using * an array of constants. The array is accessed indirectly, so the * assembler cannot know which elements may be used. As a result, it * has to upload all of them. This exercises * GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB. */ offset = snprintf(shader_source, len, template_header, max_native_parameters); for (i = 0; i < max_native_parameters; i++) { int comma = (i < (max_native_parameters - 1)) ? ',' : ' '; int used = snprintf(& shader_source[offset], len - offset, "\t\t{ %.1f, %.1f, %.1f, %.1f }%c\n", (float) i, (float) i + 0.2, (float) i + 0.4, (float) i + 0.6, comma); offset += used; } memcpy(& shader_source[offset], max_native_template_footer, sizeof(max_native_template_footer)); (void) piglit_compile_program(GL_VERTEX_PROGRAM_ARB, shader_source); /* Generate a program that uses as much of the local parameter space * as possible. This basically tries to hit both ends of the * program.local array without making assumptions about the relative * amount of parameter space. We only assume that the * minimum-maximums of 96 are respected by the GL implementation. */ snprintf(shader_source, len, max_local_template, "local", "local", max_local_parameters - 47, max_local_parameters - 1); (void) piglit_compile_program(GL_VERTEX_PROGRAM_ARB, shader_source); /* Generate a program that uses as much of the env parameter space * as possible. This basically tries to hit both ends of the * program.env array without making assumptions about the relative * amount of parameter space. We only assume that the * minimum-maximums of 96 are respected by the GL implementation. */ snprintf(shader_source, len, max_local_template, "env", "env", max_env_parameters - 47, max_env_parameters - 1); (void) piglit_compile_program(GL_VERTEX_PROGRAM_ARB, shader_source); }