ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_robustness / draw-vbo-bounds.c
blob022b23dc63cda568e553d0390e2bc440c6bd9e49
1 /*
2 * Copyright (C) 2011 VMware, Inc.
3 * Copyright (C) 2010 Marek Olšák <maraeo@gmail.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
24 * Authors:
25 * Jose Fonseca <jfonseca@vmware.com>
26 * Based on code from Marek Olšák <maraeo@gmail.com>
29 /* Test whether out-of-bounds vertex buffer object cause termination.
31 * Note that the original ARB_vertex_buffer_object extension explicitly states
32 * program termination is allowed when out-of-bounds vertex buffer object
33 * fetches occur. The ARB_robustness extension does provides an enable to
34 * guarantee that out-of-bounds buffer object accesses by the GPU will have
35 * deterministic behavior and preclude application instability or termination
36 * due to an incorrect buffer access. But regardless of ARB_robustness
37 * extension support it is a good idea not to crash. For example, viewperf
38 * doesn't properly detect NV_primitive_restart and emits 0xffffffff indices
39 * which can result in crashes.
41 * TODO:
42 * - test more vertex/element formats
43 * - add test for out-of-bound index buffer object access
44 * - add test non-aligned offsets
45 * - provide a command line option to actually enable ARB_robustness
48 #include "piglit-util-gl.h"
50 PIGLIT_GL_TEST_CONFIG_BEGIN
52 config.supports_gl_compat_version = 10;
54 config.window_width = 320;
55 config.window_height = 320;
56 config.window_visual = PIGLIT_GL_VISUAL_RGB;
57 config.khr_no_error_support = PIGLIT_NO_ERRORS;
59 PIGLIT_GL_TEST_CONFIG_END
61 void piglit_init(int argc, char **argv)
63 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
65 piglit_require_gl_version(15);
67 glShadeModel(GL_FLAT);
68 glClearColor(0.2, 0.2, 0.2, 1.0);
71 static void
72 random_vertices(GLsizei offset, GLsizei stride, GLsizei count)
74 GLsizei element_size = 2 * sizeof(GLfloat);
75 GLsizei size;
76 GLubyte *vertices;
77 GLsizei i;
79 if (stride == 0) {
80 stride = element_size;
83 size = offset + (count - 1)*stride + element_size;
85 assert(offset % sizeof(GLfloat) == 0);
86 assert(stride % sizeof(GLfloat) == 0);
88 glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
89 assert(glGetError() == GL_NO_ERROR);
91 vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
92 assert(vertices);
93 if (!vertices) {
94 return;
97 for (i = 0; i < count; ++i) {
98 GLfloat *vertex = (GLfloat *)(vertices + offset + i*stride);
99 vertex[0] = (rand() % 1000) * .001;
100 vertex[1] = (rand() % 1000) * .001;
103 glUnmapBuffer(GL_ARRAY_BUFFER);
106 static void
107 random_ushort_indices(GLsizei offset, GLsizei count, GLuint min_index, GLuint max_index)
109 GLushort *indices;
110 GLsizei size = offset + count*sizeof(*indices);
111 GLsizei i;
113 glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
114 assert(glGetError() == GL_NO_ERROR);
116 indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
117 assert(indices);
118 if (!indices) {
119 return;
122 assert(offset % sizeof(*indices) == 0);
123 for (i = 0; i < count; ++i) {
124 GLushort *index = indices + offset / sizeof *indices + i;
125 *index = min_index + rand() % (max_index - min_index + 1);
128 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
131 static void test(void)
133 GLsizei vertex_offset;
134 GLsizei vertex_stride;
135 GLsizei vertex_count;
136 GLuint vertex_buffer;
138 GLsizei index_offset;
139 GLsizei index_count;
140 GLuint max_index;
141 GLuint min_index;
142 GLuint index_buffer;
144 vertex_offset = (rand() % 0xff) * sizeof(GLfloat);
145 vertex_stride = (rand() % 0xf) * sizeof(GLfloat);
146 vertex_count = 1 + rand() % 0xffff;
148 index_offset = (rand() % 0xff) * sizeof(GLushort);
149 index_count = 1 + rand() % 0xffff;
150 min_index = rand() % vertex_count;
151 max_index = min_index + rand() % (vertex_count - min_index);
153 if (!piglit_automatic) {
154 fprintf(stdout, "vertex_offset = %i\n", vertex_offset);
155 fprintf(stdout, "vertex_stride = %i\n", vertex_stride);
156 fprintf(stdout, "vertex_count = %i\n", vertex_count);
157 fprintf(stdout, "index_offset = %i\n", index_offset);
158 fprintf(stdout, "index_count = %i\n", index_count);
159 fprintf(stdout, "min_index = %u\n", min_index);
160 fprintf(stdout, "max_index = %u\n", max_index);
161 fprintf(stdout, "\n");
162 fflush(stdout);
165 glGenBuffers(1, &vertex_buffer);
166 glGenBuffers(1, &index_buffer);
167 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
168 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
170 random_vertices(vertex_offset, vertex_stride, vertex_count);
172 if (0) {
173 /* Generate valid indices only */
174 random_ushort_indices(index_offset, index_count, min_index, max_index);
175 } else {
176 /* Generate out-of-range indices */
177 random_ushort_indices(index_offset, index_count, 0, 2*vertex_count - 1);
180 glVertexPointer(2, GL_FLOAT, vertex_stride, (const void*)(intptr_t)vertex_offset);
181 glDrawRangeElements(GL_TRIANGLES,
182 min_index,
183 max_index,
184 index_count,
185 GL_UNSIGNED_SHORT,
186 (const void*)(intptr_t)index_offset);
187 assert(glGetError() == GL_NO_ERROR);
189 /* Call glFinish to prevent the draw from being batched, delaying the cpu crash / gpu crash
190 * to much later. */
191 glFinish();
193 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
194 glBindBuffer(GL_ARRAY_BUFFER, 0);
195 glDeleteBuffers(1, &index_buffer);
196 glDeleteBuffers(1, &vertex_buffer);
199 enum piglit_result
200 piglit_display(void)
202 unsigned i;
204 glClear(GL_COLOR_BUFFER_BIT);
205 glEnableClientState(GL_VERTEX_ARRAY);
207 for (i = 0; i < 1000; ++i) {
208 test();
209 assert(glGetError() == GL_NO_ERROR);
212 glFinish();
214 return PIGLIT_PASS;