summaryrefslogtreecommitdiffstats
path: root/src/mesa/vbo/vbo_save_loopback.c
diff options
context:
space:
mode:
authorMathias Fröhlich <[email protected]>2018-02-25 18:01:07 +0100
committerMathias Fröhlich <[email protected]>2018-03-01 04:06:23 +0100
commit08aa0d9bf49ea74f84b19cd11a0f0ace7ce7211a (patch)
tree67df4045c3e6722cff79e2784b5aaa10ee3c5849 /src/mesa/vbo/vbo_save_loopback.c
parentf7178d677ca6a072455ff45b328b1078175a93b6 (diff)
vbo: Implement vbo_loopback_vertex_list in terms of the VAO.
Use the information already present in the VAO to replay a display list node using immediate mode draw commands. Use a hand full of helper methods that will be useful for the next patches also. v2: Insert asserts, constify local variables. Reviewed-by: Brian Paul <[email protected]> Signed-off-by: Mathias Fröhlich <[email protected]>
Diffstat (limited to 'src/mesa/vbo/vbo_save_loopback.c')
-rw-r--r--src/mesa/vbo/vbo_save_loopback.c119
1 files changed, 77 insertions, 42 deletions
diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c
index 43d458a7c0a..f1a93d6e434 100644
--- a/src/mesa/vbo/vbo_save_loopback.c
+++ b/src/mesa/vbo/vbo_save_loopback.c
@@ -81,8 +81,8 @@ static attr_func vert_attrfunc[4] = {
struct loopback_attr {
- GLint index;
- GLint sz;
+ enum vbo_attrib index;
+ GLuint offset;
attr_func func;
};
@@ -94,17 +94,15 @@ struct loopback_attr {
*/
static void
loopback_prim(struct gl_context *ctx,
- const GLfloat *buffer,
+ const GLubyte *buffer,
const struct _mesa_prim *prim,
GLuint wrap_count,
- GLuint vertex_size,
+ GLuint stride,
const struct loopback_attr *la, GLuint nr)
{
- GLint start = prim->start;
- GLint end = start + prim->count;
- const GLfloat *data;
- GLint j;
- GLuint k;
+ GLuint start = prim->start;
+ const GLuint end = start + prim->count;
+ const GLubyte *data;
if (0)
printf("loopback prim %s(%s,%s) verts %d..%d vsize %d\n",
@@ -112,7 +110,7 @@ loopback_prim(struct gl_context *ctx,
prim->begin ? "begin" : "..",
prim->end ? "end" : "..",
start, end,
- vertex_size);
+ stride);
if (prim->begin) {
CALL_Begin(GET_DISPATCH(), (prim->mode));
@@ -121,20 +119,13 @@ loopback_prim(struct gl_context *ctx,
start += wrap_count;
}
- data = buffer + start * vertex_size;
+ data = buffer + start * stride;
- for (j = start; j < end; j++) {
- const GLfloat *tmp = data + la[0].sz;
+ for (GLuint j = start; j < end; j++) {
+ for (GLuint k = 0; k < nr; k++)
+ la[k].func(ctx, la[k].index, (const GLfloat *)(data + la[k].offset));
- for (k = 1; k < nr; k++) {
- la[k].func(ctx, la[k].index, tmp);
- tmp += la[k].sz;
- }
-
- /* Fire the vertex
- */
- la[0].func(ctx, VBO_ATTRIB_POS, data);
- data = tmp;
+ data += stride;
}
if (prim->end) {
@@ -167,36 +158,80 @@ loopback_weak_prim(struct gl_context *ctx,
}
+static inline void
+append_attr(GLuint *nr, struct loopback_attr la[], int i, int shift,
+ const struct gl_vertex_array_object *vao)
+{
+ la[*nr].index = shift + i;
+ la[*nr].offset = vao->VertexAttrib[i].RelativeOffset;
+ la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Size - 1];
+ (*nr)++;
+}
+
+
void
-vbo_loopback_vertex_list(struct gl_context *ctx,
- const GLfloat *buffer,
- const GLubyte *attrsz,
- const struct _mesa_prim *prim,
- GLuint prim_count,
- GLuint wrap_count,
- GLuint vertex_size)
+_vbo_loopback_vertex_list(struct gl_context *ctx,
+ const struct vbo_save_vertex_list* node)
{
struct loopback_attr la[VBO_ATTRIB_MAX];
- GLuint i, nr = 0;
+ GLuint nr = 0;
/* All Legacy, NV, ARB and Material attributes are routed through
* the NV attributes entrypoints:
*/
- for (i = 0; i < VBO_ATTRIB_MAX; i++) {
- if (attrsz[i]) {
- la[nr].index = i;
- la[nr].sz = attrsz[i];
- la[nr].func = vert_attrfunc[attrsz[i]-1];
- nr++;
- }
+ const struct gl_vertex_array_object *vao = node->VAO[VP_MODE_FF];
+ GLbitfield mask = vao->_Enabled & VERT_BIT_MAT_ALL;
+ while (mask) {
+ const int i = u_bit_scan(&mask);
+ append_attr(&nr, la, i, VBO_MATERIAL_SHIFT, vao);
+ }
+
+ vao = node->VAO[VP_MODE_SHADER];
+ mask = vao->_Enabled & ~(VERT_BIT_POS | VERT_BIT_GENERIC0);
+ while (mask) {
+ const int i = u_bit_scan(&mask);
+ append_attr(&nr, la, i, 0, vao);
+ }
+
+ /* The last in the list should be the vertex provoking attribute */
+ if (vao->_Enabled & VERT_BIT_GENERIC0) {
+ append_attr(&nr, la, VERT_ATTRIB_GENERIC0, 0, vao);
+ } else if (vao->_Enabled & VERT_BIT_POS) {
+ append_attr(&nr, la, VERT_ATTRIB_POS, 0, vao);
+ }
+
+ const GLuint wrap_count = node->wrap_count;
+ const GLuint stride = _vbo_save_get_stride(node);
+ const GLubyte *buffer = NULL;
+ if (0 < nr) {
+ /* Compute the minimal offset into the vertex buffer object */
+ GLuint offset = ~0u;
+ for (GLuint i = 0; i < nr; ++i)
+ offset = MIN2(offset, la[i].offset);
+ for (GLuint i = 0; i < nr; ++i)
+ la[i].offset -= offset;
+
+ /* Get the mapped base pointer, assert sufficient mapping */
+ struct gl_buffer_object *bufferobj = vao->BufferBinding[0].BufferObj;
+ assert(bufferobj && bufferobj->Mappings[MAP_INTERNAL].Pointer);
+ buffer = bufferobj->Mappings[MAP_INTERNAL].Pointer;
+ assert(bufferobj->Mappings[MAP_INTERNAL].Offset
+ <= vao->BufferBinding[0].Offset + offset
+ + stride*(_vbo_save_get_min_index(node) + wrap_count));
+ buffer += vao->BufferBinding[0].Offset + offset
+ - bufferobj->Mappings[MAP_INTERNAL].Offset;
+ assert(stride*(_vbo_save_get_vertex_count(node) - wrap_count)
+ <= bufferobj->Mappings[MAP_INTERNAL].Length);
}
- for (i = 0; i < prim_count; i++) {
- if ((prim[i].mode & VBO_SAVE_PRIM_WEAK) &&
- _mesa_inside_begin_end(ctx)) {
- loopback_weak_prim(ctx, &prim[i]);
+ /* Replay the primitives */
+ const struct _mesa_prim *prims = node->prims;
+ const GLuint prim_count = node->prim_count;
+ for (GLuint i = 0; i < prim_count; i++) {
+ if ((prims[i].mode & VBO_SAVE_PRIM_WEAK) && _mesa_inside_begin_end(ctx)) {
+ loopback_weak_prim(ctx, &prims[i]);
} else {
- loopback_prim(ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr);
+ loopback_prim(ctx, buffer, &prims[i], wrap_count, stride, la, nr);
}
}
}