*
**************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
+/*
+ * This file implements the st_draw_vbo() function which is called from
+ * Mesa's VBO module. All point/line/triangle rendering is done through
+ * this function whether the user called glBegin/End, glDrawArrays,
+ * glDrawElements, glEvalMesh, or glCalList, etc.
+ *
+ * We basically convert the VBO's vertex attribute/array information into
+ * Gallium vertex state, bind the vertex buffer objects and call
+ * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays().
+ *
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
#include "main/imports.h"
#include "main/image.h"
* Return a PIPE_FORMAT_x for the given GL datatype and size.
*/
GLuint
-st_pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized)
+st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
+ GLboolean normalized)
{
assert((type >= GL_BYTE && type <= GL_DOUBLE) ||
type == GL_FIXED);
assert(size >= 1);
assert(size <= 4);
+ assert(format == GL_RGBA || format == GL_BGRA);
+
+ if (format == GL_BGRA) {
+ /* this is an odd-ball case */
+ assert(type == GL_UNSIGNED_BYTE);
+ assert(normalized);
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ }
if (normalized) {
switch (type) {
struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
ubyte *map;
- if (!stobj)
+ if (!stobj || stobj->Base.Name == 0) {
+ /* edge flags are not in a VBO */
return NULL;
+ }
vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32));
if (!vec)
const GLubyte **low, const GLubyte **high)
{
const GLubyte *low_addr = NULL;
+ const GLubyte *high_addr = NULL;
GLuint attr;
- GLint stride;
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
+ const GLint stride = arrays[mesaAttr]->StrideB;
const GLubyte *start = arrays[mesaAttr]->Ptr;
- stride = arrays[mesaAttr]->StrideB;
+ const unsigned sz = (arrays[mesaAttr]->Size *
+ _mesa_sizeof_type(arrays[mesaAttr]->Type));
+ const GLubyte *end = start + (max_index * stride) + sz;
+
if (attr == 0) {
low_addr = start;
+ high_addr = end;
}
else {
low_addr = MIN2(low_addr, start);
+ high_addr = MAX2(high_addr, end);
}
}
*low = low_addr;
- *high = low_addr + (max_index + 1) * stride;
+ *high = high_addr;
}
}
else {
vbuffer->buffer = NULL;
- pipe_buffer_reference(pipe->screen, &vbuffer->buffer, stobj->buffer);
- vbuffer->buffer_offset = (unsigned) low;
+ pipe_buffer_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer_offset = pointer_to_offset(low);
}
vbuffer->stride = stride; /* in bytes */
vbuffer->max_index = max_index;
velements[attr].src_format =
st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
}
/*printf("stobj %u = %p\n", attr, (void*) stobj);*/
vbuffer[attr].buffer = NULL;
- pipe_buffer_reference(pipe->screen, &vbuffer[attr].buffer, stobj->buffer);
- vbuffer[attr].buffer_offset = (unsigned) arrays[mesaAttr]->Ptr;
+ pipe_buffer_reference(&vbuffer[attr].buffer, stobj->buffer);
+ vbuffer[attr].buffer_offset = pointer_to_offset(arrays[mesaAttr]->Ptr);
velements[attr].src_offset = 0;
}
else {
velements[attr].src_format
= st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
}
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
unsigned num_vbuffers, num_velements;
GLboolean userSpace;
+ /* Gallium probably doesn't want this in some cases. */
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &ctx->st->vp->state;
+ vs = &ctx->st->vp_varient->state;
#if 0
if (MESA_VERBOSE & VERBOSE_GLSL) {
check_uniforms(ctx);
}
+#else
+ (void) check_uniforms;
#endif
/*
if (bufobj && bufobj->Name) {
/* elements/indexes are in a real VBO */
struct st_buffer_object *stobj = st_buffer_object(bufobj);
- pipe_buffer_reference(pipe->screen, &indexBuf, stobj->buffer);
- indexOffset = (unsigned) ib->ptr / indexSize;
+ pipe_buffer_reference(&indexBuf, stobj->buffer);
+ indexOffset = pointer_to_offset(ib->ptr) / indexSize;
}
else {
/* element/indicies are in user space memory */
}
}
- pipe_buffer_reference(pipe->screen, &indexBuf, NULL);
+ pipe_buffer_reference(&indexBuf, NULL);
}
else {
/* non-indexed */
/* unreference buffers (frees wrapped user-space buffer objects) */
for (attr = 0; attr < num_vbuffers; attr++) {
- pipe_buffer_reference(pipe->screen, &vbuffer[attr].buffer, NULL);
+ pipe_buffer_reference(&vbuffer[attr].buffer, NULL);
assert(!vbuffer[attr].buffer);
}