2 * Copyright © 2013 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * \file map-invalidate-range.c
26 * Try to exercise some corner cases of range mapping with alignment guarantees.
28 * Under certain circumstances, many OpenGL implementations will
29 * allocate temporary storage for a mapping of a buffer object. This
30 * most commonly occurs when:
32 * 1. The buffer being mapped is being accessed by the GPU.
33 * 2. The buffer is being mapped write-only.
34 * 3. The range is mapped with invalidate (via \c GL_MAP_INVALIDATE_RANGE_BIT).
36 * Furthermore, at least some driver make different choices about the
37 * allocation of the temporary storage depending on whether or not
38 * explicit flushed (via \c GL_MAP_FLUSH_EXPLICIT_BIT) is requested.
40 * This test tries to make sure the temporary storage allocated for
41 * the mapping still provides the alignment guarantees required by
42 * GL_ARB_map_buffer_alignment. This is accomplished by starting some
43 * rendering that will use the entire buffer then immediately trying
44 * to map some portion of the buffer.
46 #include "piglit-util-gl.h"
48 PIGLIT_GL_TEST_CONFIG_BEGIN
50 config
.supports_gl_compat_version
= 15;
52 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
53 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
55 PIGLIT_GL_TEST_CONFIG_END
58 do_test(uint8_t *vertex_data
, unsigned num_verts
, int buf_size
, int map_size
,
59 int alignment
, GLbitfield access
)
64 for (offset
= 0; offset
< (buf_size
- map_size
); offset
++) {
68 glDrawArrays(GL_POINTS
, 0, num_verts
);
69 glDrawArrays(GL_POINTS
, 0, num_verts
);
70 glDrawArrays(GL_POINTS
, 0, num_verts
);
71 glDrawArrays(GL_POINTS
, 0, num_verts
);
72 glDrawArrays(GL_POINTS
, 0, num_verts
);
75 ptr
= glMapBufferRange(GL_ARRAY_BUFFER
,
80 mapping
= (uintptr_t) ptr
;
81 if ((mapping
- offset
) % alignment
!= 0) {
82 printf("Bad mapping for offset = %d, alignment = %d: "
84 offset
, alignment
, ptr
);
88 /* Invalidate throws away our data, so we have to restore the
91 memcpy(ptr
, vertex_data
+ offset
, map_size
);
93 glUnmapBuffer(GL_ARRAY_BUFFER
);
100 piglit_init(int argc
, char *argv
[])
107 uint8_t *vertex_data
;
110 piglit_require_extension("GL_ARB_map_buffer_range");
111 piglit_require_extension("GL_ARB_map_buffer_alignment");
113 glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT
, &alignment
);
115 buf_size
= MAX2(10 * alignment
, 4096);
116 map_size
= alignment
- 1;
118 vertex_data
= calloc(1, buf_size
);
120 glGenBuffers(1, &bo
);
121 glBindBuffer(GL_ARRAY_BUFFER
, bo
);
122 glBufferData(GL_ARRAY_BUFFER
, buf_size
, vertex_data
, GL_STATIC_DRAW
);
124 glVertexPointer(2, GL_FLOAT
, 0, 0);
125 glEnableClientState(GL_VERTEX_ARRAY
);
126 num_verts
= buf_size
/ (2 * sizeof(float));
128 pass
= do_test(vertex_data
, num_verts
, buf_size
, map_size
, alignment
,
130 | GL_MAP_INVALIDATE_RANGE_BIT
)
133 pass
= do_test(vertex_data
, num_verts
, buf_size
, map_size
, alignment
,
135 | GL_MAP_INVALIDATE_RANGE_BIT
136 | GL_MAP_FLUSH_EXPLICIT_BIT
)
140 glBindBuffer(GL_ARRAY_BUFFER
, 0);
141 glDeleteBuffers(1, &bo
);
143 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);