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
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.
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.
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);
72 random_vertices(GLsizei offset
, GLsizei stride
, GLsizei count
)
74 GLsizei element_size
= 2 * sizeof(GLfloat
);
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
);
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
);
107 random_ushort_indices(GLsizei offset
, GLsizei count
, GLuint min_index
, GLuint max_index
)
110 GLsizei size
= offset
+ count
*sizeof(*indices
);
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
);
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
;
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");
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
);
173 /* Generate valid indices only */
174 random_ushort_indices(index_offset
, index_count
, min_index
, max_index
);
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
,
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
193 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
194 glBindBuffer(GL_ARRAY_BUFFER
, 0);
195 glDeleteBuffers(1, &index_buffer
);
196 glDeleteBuffers(1, &vertex_buffer
);
204 glClear(GL_COLOR_BUFFER_BIT
);
205 glEnableClientState(GL_VERTEX_ARRAY
);
207 for (i
= 0; i
< 1000; ++i
) {
209 assert(glGetError() == GL_NO_ERROR
);