Skip to content
Snippets Groups Projects
Commit 79a49e30 authored by Keith Whitwell's avatar Keith Whitwell
Browse files

Fix several more display list glitches.

Get 'loopback' replay of display lists working.
parent f1582dbe
No related branches found
No related tags found
No related merge requests found
......@@ -68,8 +68,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "dlist.h"
#include "context.h"
#include "dlist.h"
#include "enums.h"
#include "macros.h"
#include "api_validate.h"
#include "api_arrayelt.h"
......@@ -89,10 +90,12 @@ static GLuint _save_copy_vertices( GLcontext *ctx,
GLuint sz = tnl->save.vertex_size;
GLfloat *src = node->buffer + prim->start * sz;
GLfloat *dst = tnl->save.copied.buffer;
GLenum mode = prim->mode & PRIM_MODE_MASK;
GLuint ovf, i;
switch( mode )
if (prim->mode & PRIM_END)
return 0;
switch( prim->mode & PRIM_MODE_MASK )
{
case GL_POINTS:
return 0;
......@@ -197,11 +200,6 @@ static void _save_compile_vertex_list( GLcontext *ctx )
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_vertex_list *node;
if (tnl->save.initial_counter == tnl->save.counter) {
_save_reset_counters( ctx );
return;
}
/* Allocate space for this structure in the display list currently
* being compiled.
*/
......@@ -226,6 +224,9 @@ static void _save_compile_vertex_list( GLcontext *ctx )
node->vertex_store->refcount++;
node->prim_store->refcount++;
assert(node->attrsz[_TNL_ATTRIB_POS] != 0);
tnl->save.vertex_store->used += tnl->save.vertex_size * node->count;
tnl->save.prim_store->used += node->prim_count;
......@@ -298,13 +299,6 @@ static void _save_wrap_buffers( GLcontext *ctx )
/* Called only when buffers are wrapped as the result of filling the
* vertex_store struct.
*
* -- what about when be wraps?
* -- Don't need to copy vertices or emit fake begin/ends
* -- Just call _save_compile_vertex_list()
* -- what about vertex upgrades?
* -- Same logic, but want to do more before emitting vertices in new
* format.
*/
static void _save_wrap_filled_vertex( GLcontext *ctx )
{
......@@ -392,8 +386,8 @@ static void _save_upgrade_vertex( GLcontext *ctx,
/* Store the current run of vertices, and emit a GL_END. Emit a
* BEGIN in the new buffer.
*/
_save_wrap_buffers( ctx );
if (tnl->save.initial_counter != tnl->save.counter)
_save_wrap_buffers( ctx );
/* Do a COPY_TO_CURRENT to ensure back-copying works for the case
* when the attribute already exists in the vertex and is having
......@@ -401,7 +395,6 @@ static void _save_upgrade_vertex( GLcontext *ctx,
*/
_save_copy_to_current( ctx );
/* Fix up sizes:
*/
oldsz = tnl->save.attrsz[attr];
......@@ -1103,17 +1096,21 @@ static void _save_CallList( GLuint l )
static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
int i = tnl->save.prim_count++;
assert(i < tnl->save.prim_max);
tnl->save.prim[i].mode = mode | PRIM_BEGIN;
tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
tnl->save.prim[i].count = 0;
if (1) {
int i = tnl->save.prim_count++;
_mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
assert(i < tnl->save.prim_max);
tnl->save.prim[i].mode = mode | PRIM_BEGIN;
tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
tnl->save.prim[i].count = 0;
ctx->Driver.SaveNeedFlush = 1;
return GL_TRUE;
_mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
ctx->Driver.SaveNeedFlush = 1;
return GL_TRUE;
}
else
return GL_FALSE;
}
......@@ -1277,11 +1274,34 @@ static void _save_vtxfmt_init( GLcontext *ctx )
}
void _tnl_SaveFlushVertices( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLint i;
/* Noop when we are actually active:
*/
if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
return;
if (tnl->save.initial_counter != tnl->save.counter ||
tnl->save.prim_count)
_save_compile_vertex_list( ctx );
save_init_attrfv( tnl );
for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
tnl->save.attrsz[i] = 0;
tnl->save.vertex_size = 0;
ctx->Driver.SaveNeedFlush = 0;
}
void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
assert(tnl->save.vertex_size == 0);
GLuint i;
if (!tnl->save.prim_store)
tnl->save.prim_store = alloc_prim_store( ctx );
......@@ -1291,6 +1311,14 @@ void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
tnl->save.vbptr = tnl->save.vertex_store->buffer;
}
save_init_attrfv( tnl );
for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
tnl->save.attrsz[i] = 0;
tnl->save.vertex_size = 0;
ctx->Driver.SaveNeedFlush = 0;
_save_reset_counters( ctx );
}
......@@ -1308,28 +1336,6 @@ void _tnl_EndCallList( GLcontext *ctx )
{
}
/* Called when
*/
void _tnl_SaveFlushVertices( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLint i;
if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
return;
_save_compile_vertex_list( ctx );
save_init_attrfv( tnl );
for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
tnl->save.attrsz[i] = 0;
tnl->save.vertex_size = 0;
ctx->Driver.SaveNeedFlush = 0;
}
static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
{
......@@ -1346,10 +1352,23 @@ static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
static void _tnl_print_vertex_list( GLcontext *ctx, void *data )
{
struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
GLuint i;
_mesa_debug(ctx, "TNL-VERTEX-LIST, %u vertices %d primitives\n",
_mesa_debug(0, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
node->count,
node->prim_count);
node->prim_count,
node->vertex_size);
for (i = 0 ; i < node->prim_count ; i++) {
struct tnl_prim *prim = &node->prim[i];
_mesa_debug(0, " prim %d: %s %d..%d %s %s\n",
i,
_mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
prim->start,
prim->start + prim->count,
(prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
(prim->mode & PRIM_END) ? "END" : "(wrap)");
}
}
......@@ -1383,14 +1402,6 @@ void _tnl_save_init( GLcontext *ctx )
struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
GLuint i;
save_init_attrfv( tnl );
for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
tnl->save.attrsz[i] = 0;
tnl->save.vertex_size = 0;
_save_vtxfmt_init( ctx );
for (i = 0; i < _TNL_ATTRIB_MAX; i++)
_mesa_vector4f_init( &tmp->Attribs[i], 0, 0);
......@@ -1404,6 +1415,7 @@ void _tnl_save_init( GLcontext *ctx )
ctx->Driver.NotifySaveBegin = _save_NotifyBegin;
_save_vtxfmt_init( ctx );
_save_current_init( ctx );
}
......
......@@ -28,6 +28,7 @@
*/
#include "context.h"
#include "enums.h"
#include "glapi.h"
#include "imports.h"
#include "macros.h"
......@@ -175,10 +176,10 @@ struct loopback_attr {
void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
{
struct loopback_attr la[32];
struct loopback_attr la[_TNL_ATTRIB_MAX];
GLuint i, nr = 0;
for (i = 1 ; i <= _TNL_ATTRIB_TEX7 ; i++) {
for (i = 0 ; i <= _TNL_ATTRIB_TEX7 ; i++) {
if (list->attrsz[i]) {
la[nr].target = i;
la[nr].sz = list->attrsz[i];
......@@ -212,32 +213,20 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
nr++;
}
/* Must be last
*/
if (list->attrsz[_TNL_ATTRIB_POS]) {
la[nr].target = _TNL_ATTRIB_POS;
la[nr].sz = list->attrsz[_TNL_ATTRIB_POS];
la[nr].func = vert_attrfunc[list->attrsz[0]-1];
nr++;
}
else {
fprintf(stderr, "No pos attrib???\n");
return;
}
/* Don't emit ends and begins on wrapped primitives. Don't replay
* wrapped vertices. If we get here, it's probably because the the
* precalculated wrapping is wrong.
*/
for (i = 0 ; i < list->prim_count ; i++) {
GLint begin = list->prim[i].start;
GLint end = begin + list->prim[i].count;
struct tnl_prim *prim = &list->prim[i];
GLint begin = prim->start;
GLint end = begin + prim->count;
GLfloat *data;
GLint j, k;
if (list->prim[i].mode & PRIM_BEGIN)
glBegin( list->prim[i].mode & PRIM_MODE_MASK );
else {
if (prim->mode & PRIM_BEGIN) {
glBegin( prim->mode & PRIM_MODE_MASK );
} else {
assert(i == 0);
assert(begin == 0);
begin += list->wrap_count;
......@@ -246,14 +235,22 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
data = list->buffer + begin * list->vertex_size;
for (j = begin ; j < end ; j++) {
for (k = 0 ; k < nr ; k++) {
la[k].func( la[k].target, data );
data += la[k].sz;
GLfloat *tmp = data + la[0].sz;
for (k = 1 ; k < nr ; k++) {
la[k].func( la[k].target, tmp );
tmp += la[k].sz;
}
/* Fire the vertex
*/
la[0].func( VERT_ATTRIB_POS, data );
data = tmp;
}
if (list->prim[i].mode & PRIM_END)
if (prim->mode & PRIM_END) {
glEnd();
}
else {
assert (i == list->prim_count-1);
}
......
......@@ -30,6 +30,8 @@
#include "context.h"
#include "imports.h"
#include "mtypes.h"
#include "macros.h"
#include "light.h"
#include "state.h"
#include "t_pipeline.h"
#include "t_save_api.h"
......@@ -114,6 +116,49 @@ static void _tnl_bind_vertex_list( GLcontext *ctx,
}
}
static void _playback_copy_to_current( GLcontext *ctx,
struct tnl_vertex_list *node )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLfloat *data;
GLuint i;
if (node->count)
data = node->buffer + (node->count-1) * node->vertex_size;
else
data = node->buffer;
for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
if (node->attrsz[i]) {
ASSIGN_4V(tnl->vtx.current[i], 0, 0, 0, 1);
COPY_SZ_4V(tnl->vtx.current[i], node->attrsz[i], data);
data += node->attrsz[i];
}
}
/* Edgeflag requires special treatment:
*/
if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
ctx->Current.EdgeFlag = (data[0] == 1.0);
}
/* Colormaterial -- this kindof sucks.
*/
if (ctx->Light.ColorMaterialEnabled) {
_mesa_update_color_material( ctx,
ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
}
/* CurrentExecPrimitive
*/
if (node->prim_count) {
GLenum mode = node->prim[node->prim_count - 1].mode;
if (mode & PRIM_END)
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
else
ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK);
}
}
/**
......@@ -126,25 +171,39 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
FLUSH_CURRENT(ctx, 0);
if (!node->prim_count || !node->count)
return;
if (node->prim_count) {
if (ctx->NewState)
_mesa_update_state( ctx );
/* Degenerate case: list is called inside begin/end pair.
*/
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
(node->prim[0].mode & PRIM_BEGIN)) {
_mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
_tnl_loopback_vertex_list( ctx, data );
return;
}
else if (1) {
_tnl_loopback_vertex_list( ctx, data );
return;
}
if (ctx->NewState)
_mesa_update_state( ctx );
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
_tnl_bind_vertex_list( ctx, node );
_tnl_bind_vertex_list( ctx, node );
/* Invalidate all stored data before and after run:
*/
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
tnl->Driver.RunPipeline( ctx );
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
/* Invalidate all stored data before and after run:
*/
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
tnl->Driver.RunPipeline( ctx );
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
}
/* Copy to current?
*/
_playback_copy_to_current( ctx, node );
}
......
......@@ -173,8 +173,6 @@ static GLboolean run_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage
GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
GLuint idx;
/* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */
/* Make sure we can talk about position x,y and z:
*
* FIXME!
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment