1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009 VMware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
32 * All vertex buffers should be in an unmapped state when we're about
33 * to draw. This debug function checks that.
36 check_buffers_are_unmapped(const struct gl_client_array
**inputs
)
41 for (i
= 0; i
< VBO_ATTRIB_MAX
; i
++) {
43 struct gl_buffer_object
*obj
= inputs
[i
]->BufferObj
;
44 assert(!_mesa_bufferobj_mapped(obj
));
53 * A debug function that may be called from other parts of Mesa as
54 * needed during debugging.
57 vbo_check_buffers_are_unmapped(struct gl_context
*ctx
)
59 struct vbo_context
*vbo
= vbo_context(ctx
);
60 struct vbo_exec_context
*exec
= &vbo
->exec
;
61 /* check the current vertex arrays */
62 check_buffers_are_unmapped(exec
->array
.inputs
);
63 /* check the current glBegin/glVertex/glEnd-style VBO */
64 assert(!_mesa_bufferobj_mapped(exec
->vtx
.bufferobj
));
68 vbo_sizeof_ib_type(GLenum type
)
72 return sizeof(GLuint
);
73 case GL_UNSIGNED_SHORT
:
74 return sizeof(GLushort
);
75 case GL_UNSIGNED_BYTE
:
76 return sizeof(GLubyte
);
78 assert(!"unsupported index data type");
79 /* In case assert is turned off */
86 * Compute min and max elements by scanning the index buffer for
87 * glDraw[Range]Elements() calls.
88 * If primitive restart is enabled, we need to ignore restart
89 * indexes when computing min/max.
92 vbo_get_minmax_index(struct gl_context
*ctx
,
93 const struct _mesa_prim
*prim
,
94 const struct _mesa_index_buffer
*ib
,
95 GLuint
*min_index
, GLuint
*max_index
)
97 const GLuint count
= prim
->count
;
101 if (_mesa_is_bufferobj(ib
->obj
)) {
102 indices
= ctx
->Driver
.MapBufferRange(ctx
, (GLsizeiptr
) ib
->ptr
,
103 count
* vbo_sizeof_ib_type(ib
->type
),
104 GL_MAP_READ_BIT
, ib
->obj
);
110 case GL_UNSIGNED_INT
: {
111 const GLuint
*ui_indices
= (const GLuint
*)indices
;
114 for (i
= 0; i
< count
; i
++) {
115 if (ui_indices
[i
] > max_ui
) max_ui
= ui_indices
[i
];
116 if (ui_indices
[i
] < min_ui
) min_ui
= ui_indices
[i
];
122 case GL_UNSIGNED_SHORT
: {
123 const GLushort
*us_indices
= (const GLushort
*)indices
;
126 for (i
= 0; i
< count
; i
++) {
127 if (us_indices
[i
] > max_us
) max_us
= us_indices
[i
];
128 if (us_indices
[i
] < min_us
) min_us
= us_indices
[i
];
134 case GL_UNSIGNED_BYTE
: {
135 const GLubyte
*ub_indices
= (const GLubyte
*)indices
;
138 for (i
= 0; i
< count
; i
++) {
139 if (ub_indices
[i
] > max_ub
) max_ub
= ub_indices
[i
];
140 if (ub_indices
[i
] < min_ub
) min_ub
= ub_indices
[i
];
151 if (_mesa_is_bufferobj(ib
->obj
)) {
152 ctx
->Driver
.UnmapBuffer(ctx
, ib
->obj
);
158 * Check array data, looking for NaNs, etc.
161 check_draw_arrays_data(struct gl_context
*ctx
, GLint start
, GLsizei count
)
168 * Print info/data for glDrawArrays(), for debugging.
171 print_draw_arrays(struct gl_context
*ctx
,
172 GLenum mode
, GLint start
, GLsizei count
)
174 struct vbo_context
*vbo
= vbo_context(ctx
);
175 struct vbo_exec_context
*exec
= &vbo
->exec
;
178 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
181 for (i
= 0; i
< 32; i
++) {
182 struct gl_buffer_object
*bufObj
= exec
->array
.inputs
[i
]->BufferObj
;
183 GLuint bufName
= bufObj
->Name
;
184 GLint stride
= exec
->array
.inputs
[i
]->Stride
;
185 printf("attr %2d: size %d stride %d enabled %d "
186 "ptr %p Bufobj %u\n",
188 exec
->array
.inputs
[i
]->Size
,
190 /*exec->array.inputs[i]->Enabled,*/
191 ctx
->Array
.VertexAttrib
[VERT_ATTRIB(i
)].Enabled
,
192 exec
->array
.inputs
[i
]->Ptr
,
196 GLubyte
*p
= ctx
->Driver
.MapBufferRange(ctx
, 0, bufObj
->Size
,
197 GL_MAP_READ_BIT
, bufObj
);
198 int offset
= (int) (GLintptr
) exec
->array
.inputs
[i
]->Ptr
;
199 float *f
= (float *) (p
+ offset
);
202 int n
= (count
* stride
) / 4;
205 printf(" Data at offset %d:\n", offset
);
206 for (i
= 0; i
< n
; i
++) {
207 printf(" float[%d] = 0x%08x %f\n", i
, k
[i
], f
[i
]);
209 ctx
->Driver
.UnmapBuffer(ctx
, bufObj
);
216 * Set the vbo->exec->inputs[] pointers to point to the enabled
217 * vertex arrays. This depends on the current vertex program/shader
218 * being executed because of whether or not generic vertex arrays
219 * alias the conventional vertex arrays.
220 * For arrays that aren't enabled, we set the input[attrib] pointer
221 * to point at a zero-stride current value "array".
224 recalculate_input_bindings(struct gl_context
*ctx
)
226 struct vbo_context
*vbo
= vbo_context(ctx
);
227 struct vbo_exec_context
*exec
= &vbo
->exec
;
228 struct gl_client_array
*vertexAttrib
= ctx
->Array
.VertexAttrib
;
229 const struct gl_client_array
**inputs
= &exec
->array
.inputs
[0];
230 GLbitfield64 const_inputs
= 0x0;
233 for (i
= 0; i
< VBO_ATTRIB_MAX
; i
++) {
234 if ((i
< VERT_ATTRIB_MAX
) && (vertexAttrib
[VERT_ATTRIB(i
)].Enabled
))
235 inputs
[i
] = &vertexAttrib
[VERT_ATTRIB(i
)];
237 inputs
[i
] = &vbo
->currval
[i
];
238 const_inputs
|= VERT_BIT(i
);
242 ctx
->NewState
|= _NEW_ARRAY
;
247 * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
248 * These will point to the arrays to actually use for drawing. Some will
249 * be user-provided arrays, other will be zero-stride const-valued arrays.
250 * Note that this might set the _NEW_ARRAY dirty flag so state validation
251 * must be done after this call.
254 vbo_bind_arrays(struct gl_context
*ctx
)
256 if (!ctx
->Array
.RebindArrays
) {
260 recalculate_input_bindings(ctx
);
261 ctx
->Array
.RebindArrays
= GL_FALSE
;
266 * Helper function called by the other DrawArrays() functions below.
267 * This is where we handle primitive restart for drawing non-indexed
268 * arrays. If primitive restart is enabled, it typically means
269 * splitting one DrawArrays() into two.
272 vbo_draw_arrays(struct gl_context
*ctx
, GLenum mode
, GLint start
,
273 GLsizei count
, GLuint numInstances
)
275 struct vbo_context
*vbo
= vbo_context(ctx
);
276 struct vbo_exec_context
*exec
= &vbo
->exec
;
277 struct _mesa_prim prim
[2];
279 vbo_bind_arrays(ctx
);
281 vbo_draw_method(exec
, DRAW_ARRAYS
);
283 /* Again... because we may have changed the bitmask of per-vertex varying
284 * attributes. If we regenerate the fixed-function vertex program now
285 * we may be able to prune down the number of vertex attributes which we
286 * need in the shader.
289 _mesa_update_state(ctx
);
291 /* init most fields to zero */
292 memset(prim
, 0, sizeof(prim
));
296 prim
[0].num_instances
= numInstances
;
298 /* no prim restart */
299 prim
[0].start
= start
;
300 prim
[0].count
= count
;
302 check_buffers_are_unmapped(exec
->array
.inputs
);
303 vbo
->draw_prims(ctx
, exec
->array
.inputs
, prim
, 1, NULL
,
304 GL_TRUE
, start
, start
+ count
- 1);
310 * Called from glDrawArrays when in immediate mode (not display list mode).
312 static void GLAPIENTRY
313 vbo_exec_DrawArrays(GLenum mode
, GLint start
, GLsizei count
)
315 GET_CURRENT_CONTEXT(ctx
);
317 if (MESA_VERBOSE
& VERBOSE_DRAW
)
318 _mesa_debug(ctx
, "glDrawArrays(%s, %d, %d)\n",
319 _mesa_lookup_enum_by_nr(mode
), start
, count
);
321 if (!_mesa_validate_DrawArrays( ctx
, mode
, start
, count
))
324 FLUSH_CURRENT( ctx
, 0 );
326 if (!_mesa_valid_to_render(ctx
, "glDrawArrays")) {
331 check_draw_arrays_data(ctx
, start
, count
);
333 vbo_draw_arrays(ctx
, mode
, start
, count
, 1);
336 print_draw_arrays(ctx
, mode
, start
, count
);
341 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
346 dump_element_buffer(struct gl_context
*ctx
, GLenum type
)
349 ctx
->Driver
.MapBufferRange(ctx
, 0,
350 ctx
->Array
.ArrayObj
->ElementArrayBufferObj
->Size
,
352 ctx
->Array
.ArrayObj
->ElementArrayBufferObj
);
354 case GL_UNSIGNED_BYTE
:
356 const GLubyte
*us
= (const GLubyte
*) map
;
358 for (i
= 0; i
< ctx
->Array
.ArrayObj
->ElementArrayBufferObj
->Size
; i
++) {
359 printf("%02x ", us
[i
]);
366 case GL_UNSIGNED_SHORT
:
368 const GLushort
*us
= (const GLushort
*) map
;
370 for (i
= 0; i
< ctx
->Array
.ArrayObj
->ElementArrayBufferObj
->Size
/ 2; i
++) {
371 printf("%04x ", us
[i
]);
378 case GL_UNSIGNED_INT
:
380 const GLuint
*us
= (const GLuint
*) map
;
382 for (i
= 0; i
< ctx
->Array
.ArrayObj
->ElementArrayBufferObj
->Size
/ 4; i
++) {
383 printf("%08x ", us
[i
]);
394 ctx
->Driver
.UnmapBuffer(ctx
, ctx
->Array
.ArrayObj
->ElementArrayBufferObj
);
400 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
401 * Do the rendering for a glDrawElements or glDrawRangeElements call after
402 * we've validated buffer bounds, etc.
405 vbo_validated_drawrangeelements(struct gl_context
*ctx
, GLenum mode
,
406 GLboolean index_bounds_valid
,
407 GLuint start
, GLuint end
,
408 GLsizei count
, GLenum type
,
409 const GLvoid
*indices
, GLint numInstances
)
411 struct vbo_context
*vbo
= vbo_context(ctx
);
412 struct vbo_exec_context
*exec
= &vbo
->exec
;
413 struct _mesa_index_buffer ib
;
414 struct _mesa_prim prim
[1];
416 FLUSH_CURRENT( ctx
, 0 );
418 if (!_mesa_valid_to_render(ctx
, "glDraw[Range]Elements")) {
422 vbo_bind_arrays( ctx
);
424 vbo_draw_method(exec
, DRAW_ARRAYS
);
426 /* check for dirty state again */
428 _mesa_update_state( ctx
);
432 ib
.obj
= ctx
->Array
.ElementArrayBufferObj
;
441 prim
[0].count
= count
;
443 prim
[0].num_instances
= numInstances
;
445 /* Need to give special consideration to rendering a range of
446 * indices starting somewhere above zero. Typically the
447 * application is issuing multiple DrawRangeElements() to draw
448 * successive primitives layed out linearly in the vertex arrays.
449 * Unless the vertex arrays are all in a VBO (or locked as with
450 * CVA), the OpenGL semantics imply that we need to re-read or
451 * re-upload the vertex data on each draw call.
453 * In the case of hardware tnl, we want to avoid starting the
454 * upload at zero, as it will mean every draw call uploads an
455 * increasing amount of not-used vertex data. Worse - in the
456 * software tnl module, all those vertices might be transformed and
457 * lit but never rendered.
459 * If we just upload or transform the vertices in start..end,
460 * however, the indices will be incorrect.
462 * At this level, we don't know exactly what the requirements of
463 * the backend are going to be, though it will likely boil down to
466 * 1) Do nothing, everything is in a VBO and is processed once
469 * 2) Adjust the indices and vertex arrays so that start becomes
472 * Rather than doing anything here, I'll provide a helper function
473 * for the latter case elsewhere.
476 check_buffers_are_unmapped(exec
->array
.inputs
);
477 vbo
->draw_prims( ctx
, exec
->array
.inputs
, prim
, 1, &ib
,
478 index_bounds_valid
, start
, end
);
483 * Called by glDrawElements() in immediate mode.
485 static void GLAPIENTRY
486 vbo_exec_DrawElements(GLenum mode
, GLsizei count
, GLenum type
,
487 const GLvoid
*indices
)
489 GET_CURRENT_CONTEXT(ctx
);
491 if (MESA_VERBOSE
& VERBOSE_DRAW
)
492 _mesa_debug(ctx
, "glDrawElements(%s, %u, %s, %p)\n",
493 _mesa_lookup_enum_by_nr(mode
), count
,
494 _mesa_lookup_enum_by_nr(type
), indices
);
496 if (!_mesa_validate_DrawElements( ctx
, mode
, count
, type
, indices
))
499 vbo_validated_drawrangeelements(ctx
, mode
, GL_FALSE
, ~0, ~0,
500 count
, type
, indices
, 1);
505 * Plug in the immediate-mode vertex array drawing commands into the
506 * givven vbo_exec_context object.
509 vbo_exec_array_init( struct vbo_exec_context
*exec
)
511 exec
->vtxfmt
.DrawArrays
= vbo_exec_DrawArrays
;
512 exec
->vtxfmt
.DrawElements
= vbo_exec_DrawElements
;
517 vbo_exec_array_destroy( struct vbo_exec_context
*exec
)
525 * The following functions are only used for OpenGL ES 1/2 support.
526 * And some aren't even supported (yet) in ES 1/2.
531 _mesa_DrawArrays(GLenum mode
, GLint first
, GLsizei count
)
533 vbo_exec_DrawArrays(mode
, first
, count
);
538 _mesa_DrawElements(GLenum mode
, GLsizei count
, GLenum type
,
539 const GLvoid
*indices
)
541 vbo_exec_DrawElements(mode
, count
, type
, indices
);