-/* $Id: t_array_api.c,v 1.14 2001/05/11 08:11:31 keithw Exp $ */
+/* $Id: t_array_api.c,v 1.15 2001/05/11 15:53:06 keithw Exp $ */
/*
* Mesa 3-D graphics library
static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start,
GLsizei count )
{
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
/* Need to produce immediate structs, either for compiling or
* because the array range is too large to process in a single
* VB. In GL_EXECUTE mode, this introduces two redundant
*/
#if 1
if (_tnl_hard_begin( ctx, mode )) {
- GLint j;
- for (j = 0 ; j < count ; ) {
+ GLint i;
+ for (i = 0 ; i < count ; ) {
struct immediate *IM = TNL_CURRENT_IM(ctx);
- GLuint nr = MIN2( IMM_MAXDATA - IM->Start, (GLuint) (count - j) );
- GLuint sf = IM->Flag[IM->Start];
-
- _tnl_fill_immediate_drawarrays( ctx, IM, j, j+nr );
+ GLuint start = IM->Start;
+ GLuint nr = MIN2( IMM_MAXDATA - start, (GLuint) (count - i) );
- if (j == 0) IM->Flag[IM->Start] |= sf;
+ _tnl_fill_immediate_drawarrays( ctx, IM, i, i+nr );
- IM->Count = IM->Start + nr;
- j += nr;
+ IM->Count = start + nr;
+ i += nr;
- if (j == count)
+ if (i == count)
_tnl_end( ctx );
_tnl_flush_immediate( IM );
static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count,
const GLuint *indices)
{
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
#if 1
/* Optimized code that fakes the effect of calling
* _tnl_array_element for each index in the list.
*/
if (_tnl_hard_begin( ctx, mode )) {
GLint i, j;
- for (j = 0 ; j < count ; ) {
+ for (i = 0 ; i < count ; ) {
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint start = IM->Start;
- GLint nr = MIN2( (GLint) (IMM_MAXDATA - start), count - j ) + start;
+ GLint end = MIN2( IMM_MAXDATA, (count - i) + start);
GLuint sf = IM->Flag[start];
IM->FlushElt = IM->ArrayEltFlush;
- for (i = start ; i < nr ; i++) {
- IM->Elt[i] = (GLuint) *indices++;
- IM->Flag[i] = VERT_ELT;
+ for (j = start ; j < end ; j++) {
+ IM->Elt[j] = (GLuint) *indices++;
+ IM->Flag[j] = VERT_ELT;
}
- if (j == 0) IM->Flag[start] |= sf;
+ IM->Flag[start] |= (sf & IM->ArrayEltFlags);
+ IM->Count = end;
+ i += end - start;
- IM->Count = nr;
- j += nr - start;
-
- if (j == count)
+ if (i == count)
_tnl_end( ctx );
_tnl_flush_immediate( IM );
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
/* Check arguments, etc.
*/
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
/* fprintf(stderr, "start %d count %d min %d modulo %d skip %d\n", */
/* start, count, minimum, modulo, skip); */
+
+ bufsz -= bufsz % modulo;
+ bufsz -= minimum;
+
for (j = start + minimum ; j < count ; j += nr + skip ) {
nr = MIN2( bufsz, count - j );
- nr -= nr % modulo;
/* fprintf(stderr, "%d..%d\n", j - minimum, j+nr); */
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint *ui_indices;
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
/* Check arguments, etc.
*/
if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint *ui_indices;
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
/* Check arguments, etc.
*/
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
-/* $Id: t_imm_api.c,v 1.13 2001/05/11 08:11:31 keithw Exp $ */
+/* $Id: t_imm_api.c,v 1.14 2001/05/11 15:53:06 keithw Exp $ */
/*
* Mesa 3-D graphics library
}
+
+
+/* Note the ctx argument. This function called only by _tnl_Begin,
+ * _tnl_save_Begin and _tnl_hard_begin() in this file.
+ */
static void
_tnl_begin( GLcontext *ctx, GLenum p )
{
}
+void
+_tnl_save_Begin( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (mode > GL_POLYGON) {
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" );
+ return;
+ }
+
+ _tnl_begin( ctx, mode );
+
+ /* Update save_primitive now.
+ */
+ if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
+ ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
+ ctx->Driver.CurrentSavePrimitive = mode;
+}
static void
_tnl_Begin( GLenum mode )
_tnl_begin(ctx, mode);
- /* If compiling update SavePrimitive now.
- *
- * In compile_and_exec mode, exec_primitive will be updated when
- * the cassette is finished.
- *
- * If not compiling, update exec_primitive now.
+ /* Update exec_primitive now.
*/
- if (ctx->CompileFlag) {
- if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
- ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
- else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
- ctx->Driver.CurrentSavePrimitive = mode;
- }
- else if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
-/* fprintf(stderr, "setting cep %x in %s\n", mode, __FUNCTION__); */
+ ASSERT (!ctx->CompileFlag);
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
ctx->Driver.CurrentExecPrimitive = mode;
}
}
+/* Function which allows operations like 'glRectf' to decompose to a
+ * begin/end object and vertices without worrying about what happens
+ * with display lists.
+ */
GLboolean
_tnl_hard_begin( GLcontext *ctx, GLenum p )
{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
- GLuint count, last;
-
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- /* If not compiling, treat as a normal begin().
- */
if (!ctx->CompileFlag) {
- _tnl_begin( ctx, p );
-
- /* Set this for the duration:
+ /* If not compiling, treat as a normal begin().
*/
+ _tnl_begin( ctx, p );
+ ASSERT(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END);
ctx->Driver.CurrentExecPrimitive = p;
-/* fprintf(stderr, "setting cep %x in %s\n", */
-/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */
return GL_TRUE;
}
-
- if (IM->Count > IMM_MAXDATA-8) {
- _tnl_flush_immediate( IM );
- IM = TNL_CURRENT_IM(ctx);
- }
-
- switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
- case VERT_BEGIN_0|VERT_BEGIN_1:
- /* This is an immediate known to be inside a begin/end object.
- */
- IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
- return GL_FALSE;
-
- case VERT_BEGIN_0:
- case VERT_BEGIN_1:
- /* This is a display-list immediate in an unknown begin/end
- * state. Assert it is empty and conviert it to a 'hard' one.
- */
- ASSERT (IM->SavedBeginState == 0);
-
- /* Push current beginstate, to be restored later. Don't worry
- * about raising errors.
+ else {
+ /* Otherwise, need to do special processing to preserve the
+ * condition that these vertices will only be replayed outside
+ * future begin/end objects.
*/
- IM->SavedBeginState = IM->BeginState;
+ struct immediate *IM = TNL_CURRENT_IM(ctx);
- /* FALLTHROUGH */
- case 0:
- /* Unless we have fallen through, this is an immediate known to
- * be outside begin/end objects.
- */
-
- IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
-
-
- count = IM->Count;
- last = IM->LastPrimitive;
-
- IM->Flag[count] |= VERT_BEGIN;
- IM->Primitive[count] = p | PRIM_BEGIN;
- IM->PrimitiveLength[last] = count - last;
- IM->LastPrimitive = count;
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
- ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
+ if (IM->Count > IMM_MAXDATA-8) {
+ _tnl_flush_immediate( IM );
+ IM = TNL_CURRENT_IM(ctx);
+ }
- /* This is necessary as this immediate will not be flushed in
- * _tnl_end() -- we leave it active, hoping to pick up more
- * vertices before the next state change.
+ /* A lot depends on the degree to which the display list has
+ * constrained the possible begin/end states at this point:
*/
- ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
-
- return GL_TRUE;
-
- default:
- ASSERT (0);
- return GL_TRUE;
+ switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
+ case VERT_BEGIN_0|VERT_BEGIN_1:
+ /* This is an immediate known to be inside a begin/end object.
+ */
+ ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
+ IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
+ return GL_FALSE;
+
+ case VERT_BEGIN_0:
+ case VERT_BEGIN_1:
+ /* This is a display-list immediate in an unknown begin/end
+ * state. Assert it is empty and convert it to a 'hard' one.
+ */
+ ASSERT(IM->SavedBeginState == 0);
+ ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
+
+ /* Push current beginstate, to be restored later. Don't worry
+ * about raising errors.
+ */
+ IM->SavedBeginState = IM->BeginState;
+
+ /* FALLTHROUGH */
+
+ case 0:
+ /* Unless we have fallen through, this is an immediate known to
+ * be outside begin/end objects.
+ */
+ ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
+ ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
+ ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
+
+ IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
+ IM->Flag[IM->Count] |= VERT_BEGIN;
+ IM->Primitive[IM->Count] = p | PRIM_BEGIN;
+ IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
+ IM->LastPrimitive = IM->Count;
+
+ /* This is necessary as this immediate will not be flushed in
+ * _tnl_end() -- we leave it active, hoping to pick up more
+ * vertices before the next state change.
+ */
+ ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
+ return GL_TRUE;
+
+ default:
+ ASSERT (0);
+ return GL_TRUE;
+ }
}
}
-/* Need to do this to get the correct begin/end error behaviour from
- * functions like ColorPointerEXT which are still active in
- * SAVE_AND_EXEC modes.
- */
-void
-_tnl_save_Begin( GLenum mode )
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (mode > GL_POLYGON) {
- _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
-
- if (ctx->ExecuteFlag) {
- /* Preserve vtxfmt invarient:
- */
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- /* Slot in geomexec: No need to call setdispatch as we know
- * CurrentDispatch is Save.
- */
- ASSERT(ctx->CurrentDispatch == ctx->Save);
- }
-
- _tnl_begin( ctx, mode );
-}
-
if (!ctx->CompileFlag) {
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
-/* fprintf(stderr, "setting cep %x in %s\n", */
-/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */
}
/* You can set this flag to get the old 'flush_vb on glEnd()'
/* Execute a glRectf() function. _tnl_hard_begin() ensures the check
* on outside_begin_end is executed even in compiled lists. These
- * vertices can now participate in the same VB as regular ones, even
- * in most display lists.
+ * vertices can now participate in the same immediate as regular ones,
+ * even in most display lists.
*/
static void
_tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )