egl: Handle dri configs with floating point pixel data
[mesa.git] / src / mesa / tnl_dd / t_dd_dmatmp.h
index f55cfe87bd6c2a3182ee9a959202db596ea4f152..56fa1a382f7bbda13c0e6d67357c57c5fd3bce50 100644 (file)
@@ -24,7 +24,7 @@
  * Authors:
  *    Keith Whitwell <keithw@vmware.com>
  */
-
+#include <stdbool.h>
 
 /**
  * \file t_dd_dmatmp.h
@@ -52,8 +52,8 @@
 /*                  Render whole begin/end objects                    */
 /**********************************************************************/
 
-static __inline void *TAG(emit_verts)( struct gl_context *ctx, GLuint start, 
-                                    GLuint count, void *buf )
+static inline void *TAG(emit_verts)(struct gl_context *ctx, GLuint start,
+                                    GLuint count, void *buf)
 {
    return EMIT_VERTS(ctx, start, count, buf);
 }
@@ -62,32 +62,31 @@ static __inline void *TAG(emit_verts)( struct gl_context *ctx, GLuint start,
  *                    Render non-indexed primitives.
  ***********************************************************************/
 
-static void TAG(render_points_verts)( struct gl_context *ctx,
-                                     GLuint start,
-                                     GLuint count,
-                                     GLuint flags )
+static void TAG(render_points_verts)(struct gl_context *ctx,
+                                     GLuint start,
+                                     GLuint count,
+                                     GLuint flags)
 {
    if (HAVE_POINTS) {
       LOCAL_VARS;
-      int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-      int currentsz;
+      const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+      unsigned currentsz;
       GLuint j, nr;
 
-      INIT( GL_POINTS );
+      INIT(GL_POINTS);
 
       currentsz = GET_CURRENT_VB_MAX_VERTS();
       if (currentsz < 8)
-        currentsz = dmasz;
+         currentsz = dmasz;
 
       for (j = 0; j < count; j += nr) {
-        nr = MIN2( currentsz, count - j );
+         nr = MIN2(currentsz, count - j);
          TAG(emit_verts)(ctx, start + j, nr, ALLOC_VERTS(nr));
-        currentsz = dmasz;
+         currentsz = dmasz;
       }
-
    } else {
-      fprintf(stderr, "%s - cannot draw primitive\n", __func__);
-      return;
+      unreachable("Cannot draw primitive; validate_render should have "
+                  "prevented this");
    }
 }
 
@@ -97,8 +96,8 @@ static void TAG(render_lines_verts)(struct gl_context *ctx,
                                     GLuint flags)
 {
    LOCAL_VARS;
-   int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-   int currentsz;
+   const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS() & ~1;
+   unsigned currentsz;
    GLuint j, nr;
 
    INIT(GL_LINES);
@@ -108,7 +107,6 @@ static void TAG(render_lines_verts)(struct gl_context *ctx,
    count -= count & 1;
    currentsz = GET_CURRENT_VB_MAX_VERTS();
    currentsz -= currentsz & 1;
-   dmasz -= dmasz & 1;
 
    if (currentsz < 8)
       currentsz = dmasz;
@@ -127,8 +125,8 @@ static void TAG(render_line_strip_verts)(struct gl_context *ctx,
                                          GLuint flags)
 {
    LOCAL_VARS;
-   int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-   int currentsz;
+   const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+   unsigned currentsz;
    GLuint j, nr;
 
    INIT(GL_LINE_STRIP);
@@ -153,8 +151,8 @@ static void TAG(render_line_loop_verts)(struct gl_context *ctx,
                                         GLuint flags)
 {
    LOCAL_VARS;
-   int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-   int currentsz;
+   const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS() - 1;
+   unsigned currentsz;
    GLuint j, nr;
 
    INIT(GL_LINE_STRIP);
@@ -165,7 +163,6 @@ static void TAG(render_line_loop_verts)(struct gl_context *ctx,
     */
    currentsz = GET_CURRENT_VB_MAX_VERTS();
    currentsz--;
-   dmasz--;
 
    if (currentsz < 8)
       currentsz = dmasz;
@@ -199,19 +196,19 @@ static void TAG(render_line_loop_verts)(struct gl_context *ctx,
 }
 
 
-static void TAG(render_triangles_verts)( struct gl_context *ctx,
-                                        GLuint start,
-                                        GLuint count,
-                                        GLuint flags )
+static void TAG(render_triangles_verts)(struct gl_context *ctx,
+                                        GLuint start,
+                                        GLuint count,
+                                        GLuint flags)
 {
    LOCAL_VARS;
-   int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
-   int currentsz;
+   const unsigned dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 3) * 3;
+   unsigned currentsz;
    GLuint j, nr;
 
    INIT(GL_TRIANGLES);
 
-   currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
+   currentsz = (GET_CURRENT_VB_MAX_VERTS() / 3) * 3;
 
    /* Emit whole number of tris in total.  dmasz is already a multiple
     * of 3.
@@ -222,7 +219,7 @@ static void TAG(render_triangles_verts)( struct gl_context *ctx,
       currentsz = dmasz;
 
    for (j = 0; j < count; j += nr) {
-      nr = MIN2( currentsz, count - j );
+      nr = MIN2(currentsz, count - j);
       TAG(emit_verts)(ctx, start + j, nr, ALLOC_VERTS(nr));
       currentsz = dmasz;
    }
@@ -237,8 +234,8 @@ static void TAG(render_tri_strip_verts)(struct gl_context *ctx,
 {
    LOCAL_VARS;
    GLuint j, nr;
-   int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-   int currentsz;
+   const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS() & ~1;
+   unsigned currentsz;
 
    INIT(GL_TRIANGLE_STRIP);
 
@@ -249,7 +246,6 @@ static void TAG(render_tri_strip_verts)(struct gl_context *ctx,
 
    /* From here on emit even numbers of tris when wrapping over buffers:
     */
-   dmasz -= (dmasz & 1);
    currentsz -= (currentsz & 1);
 
    for (j = 0; j + 2 < count; j += nr - 2) {
@@ -268,8 +264,8 @@ static void TAG(render_tri_fan_verts)(struct gl_context *ctx,
 {
    LOCAL_VARS;
    GLuint j, nr;
-   int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-   int currentsz;
+   const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+   unsigned currentsz;
 
    INIT(GL_TRIANGLE_FAN);
 
@@ -291,62 +287,55 @@ static void TAG(render_tri_fan_verts)(struct gl_context *ctx,
 }
 
 
-static void TAG(render_poly_verts)( struct gl_context *ctx,
-                                   GLuint start,
-                                   GLuint count,
-                                   GLuint flags )
+static void TAG(render_poly_verts)(struct gl_context *ctx,
+                                   GLuint start,
+                                   GLuint count,
+                                   GLuint flags)
 {
    if (HAVE_POLYGONS) {
       LOCAL_VARS;
       GLuint j, nr;
-      int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-      int currentsz;
+      const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+      unsigned currentsz;
 
       INIT(GL_POLYGON);
 
       currentsz = GET_CURRENT_VB_MAX_VERTS();
       if (currentsz < 8) {
-        currentsz = dmasz;
+         currentsz = dmasz;
       }
 
-      for (j = 1 ; j + 1 < count ; j += nr - 2 ) {
-        void *tmp;
-        nr = MIN2( currentsz, count - j + 1 );
-        tmp = ALLOC_VERTS( nr );
-        tmp = TAG(emit_verts)( ctx, start, 1, tmp );
+      for (j = 1; j + 1 < count; j += nr - 2) {
+         void *tmp;
+         nr = MIN2(currentsz, count - j + 1);
+         tmp = ALLOC_VERTS(nr);
+         tmp = TAG(emit_verts)(ctx, start, 1, tmp);
          tmp = TAG(emit_verts)(ctx, start + j, nr - 1, tmp);
-        (void) tmp;
-        currentsz = dmasz;
+         (void) tmp;
+         currentsz = dmasz;
       }
 
       FLUSH();
-   }
-   else if (ctx->Light.ShadeModel == GL_SMOOTH) {
+   } else if (ctx->Light.ShadeModel == GL_SMOOTH ||
+              ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION) {
       TAG(render_tri_fan_verts)( ctx, start, count, flags );
    } else {
-      fprintf(stderr, "%s - cannot draw primitive\n", __func__);
-      return;
+      unreachable("Cannot draw primitive; validate_render should have "
+                  "prevented this");
    }
 }
 
-static void TAG(render_quad_strip_verts)( struct gl_context *ctx,
-                                         GLuint start,
-                                         GLuint count,
-                                         GLuint flags )
+static void TAG(render_quad_strip_verts)(struct gl_context *ctx,
+                                         GLuint start,
+                                         GLuint count,
+                                         GLuint flags)
 {
    GLuint j, nr;
 
-   if (ctx->Light.ShadeModel == GL_FLAT &&
-       TNL_CONTEXT(ctx)->vb.AttribPtr[_TNL_ATTRIB_COLOR0]->stride) {
-        /* Vertices won't fit in a single buffer or elts not
-         * available - should never happen.
-         */
-        fprintf(stderr, "%s - cannot draw primitive\n", __func__);
-        return;
-   } else {
+   if (ctx->Light.ShadeModel == GL_SMOOTH) {
       LOCAL_VARS;
-      int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
-      int currentsz;
+      const unsigned dmasz = GET_SUBSEQUENT_VB_MAX_VERTS() & ~1;
+      unsigned currentsz;
 
       /* Emit smooth-shaded quadstrips as tristrips:
        */
@@ -355,21 +344,23 @@ static void TAG(render_quad_strip_verts)( struct gl_context *ctx,
 
       /* Emit whole number of quads in total, and in each buffer.
        */
-      dmasz -= dmasz & 1;
       currentsz = GET_CURRENT_VB_MAX_VERTS();
       currentsz -= currentsz & 1;
       count -= count & 1;
 
       if (currentsz < 8)
-        currentsz = dmasz;
+         currentsz = dmasz;
 
       for (j = 0; j + 3 < count; j += nr - 2) {
          nr = MIN2(currentsz, count - j);
          TAG(emit_verts)(ctx, start + j, nr, ALLOC_VERTS(nr));
-        currentsz = dmasz;
+         currentsz = dmasz;
       }
 
       FLUSH();
+   } else {
+      unreachable("Cannot draw primitive; validate_render should have "
+                  "prevented this");
    }
 }
 
@@ -379,44 +370,48 @@ static void TAG(render_quads_verts)(struct gl_context *ctx,
                                     GLuint count,
                                     GLuint flags)
 {
-   /* Emit whole number of quads in total. */
-   count -= count & 3;
-
-   {
-      /* Hardware doesn't have a quad primitive type -- try to
-       * simulate it using triangle primitive.  This is a win for
-       * gears, but is it useful in the broader world?
-       */
+   if (ctx->Light.ShadeModel == GL_SMOOTH ||
+       ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
       LOCAL_VARS;
       GLuint j;
 
+      /* Emit whole number of quads in total. */
+      count -= count & 3;
+
+      /* Hardware doesn't have a quad primitive type -- try to simulate it using
+       * triangle primitive.  This is a win for gears, but is it useful in the
+       * broader world?
+       */
       INIT(GL_TRIANGLES);
 
       for (j = 0; j + 3 < count; j += 4) {
-        void *tmp = ALLOC_VERTS( 6 );
-        /* Send v0, v1, v3
-         */
-        tmp = EMIT_VERTS(ctx, start + j,     2, tmp);
-        tmp = EMIT_VERTS(ctx, start + j + 3, 1, tmp);
-        /* Send v1, v2, v3
-         */
-        tmp = EMIT_VERTS(ctx, start + j + 1, 3, tmp);
-        (void) tmp;
+         void *tmp = ALLOC_VERTS(6);
+         /* Send v0, v1, v3
+          */
+         tmp = EMIT_VERTS(ctx, start + j,     2, tmp);
+         tmp = EMIT_VERTS(ctx, start + j + 3, 1, tmp);
+         /* Send v1, v2, v3
+          */
+         tmp = EMIT_VERTS(ctx, start + j + 1, 3, tmp);
+         (void) tmp;
       }
+   } else {
+      unreachable("Cannot draw primitive");
    }
 }
 
-static void TAG(render_noop)( struct gl_context *ctx,
-                             GLuint start,
-                             GLuint count,
-                             GLuint flags )
+static void TAG(render_noop)(struct gl_context *ctx,
+                             GLuint start,
+                             GLuint count,
+                             GLuint flags)
 {
+   (void) ctx;
+   (void) start;
+   (void) count;
+   (void) flags;
 }
 
-
-
-
-static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
+static const tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
 {
    TAG(render_points_verts),
    TAG(render_lines_verts),
@@ -434,65 +429,60 @@ static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
 /* Pre-check the primitives in the VB to prevent the need for
  * fallbacks later on.
  */
-static GLboolean TAG(validate_render)( struct gl_context *ctx,
-                                      struct vertex_buffer *VB )
+static bool TAG(validate_render)(struct gl_context *ctx,
+                                 struct vertex_buffer *VB)
 {
    GLint i;
 
    if (VB->ClipOrMask & ~CLIP_CULL_BIT)
-      return GL_FALSE;
+      return false;
 
    if (VB->Elts)
-      return GL_FALSE;
+      return false;
 
    for (i = 0 ; i < VB->PrimitiveCount ; i++) {
       GLuint prim = VB->Primitive[i].mode;
       GLuint count = VB->Primitive[i].count;
-      GLboolean ok = GL_FALSE;
+      bool ok = false;
 
       if (!count)
-        continue;
+         continue;
 
       switch (prim & PRIM_MODE_MASK) {
       case GL_POINTS:
-        ok = HAVE_POINTS;
-        break;
+         ok = HAVE_POINTS;
+         break;
       case GL_LINES:
       case GL_LINE_STRIP:
       case GL_LINE_LOOP:
-        ok = !ctx->Line.StippleFlag;
-        break;
+         ok = !ctx->Line.StippleFlag;
+         break;
       case GL_TRIANGLES:
       case GL_TRIANGLE_STRIP:
       case GL_TRIANGLE_FAN:
-        ok = GL_TRUE;
-        break;
+         ok = true;
+         break;
       case GL_POLYGON:
-         ok = (HAVE_POLYGONS) || ctx->Light.ShadeModel == GL_SMOOTH;
-        break;
+         ok = (HAVE_POLYGONS) || ctx->Light.ShadeModel == GL_SMOOTH ||
+              ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION;
+         break;
       case GL_QUAD_STRIP:
-        if (VB->Elts) {
-           ok = GL_TRUE;
-        } else if (ctx->Light.ShadeModel == GL_FLAT &&
-                   VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0) {
-              ok = GL_FALSE;
-        }
-        else 
-           ok = GL_TRUE;
-        break;
+         ok = VB->Elts || ctx->Light.ShadeModel == GL_SMOOTH;
+         break;
       case GL_QUADS:
-           ok = GL_TRUE; /* flatshading is ok. */
-        break;
+         ok = ctx->Light.ShadeModel == GL_SMOOTH ||
+              ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION;
+         break;
       default:
-        break;
+         break;
       }
       
       if (!ok) {
-/*      fprintf(stderr, "not ok %s\n", _mesa_enum_to_string(prim & PRIM_MODE_MASK)); */
-        return GL_FALSE;
+/*          fprintf(stderr, "not ok %s\n", _mesa_enum_to_string(prim & PRIM_MODE_MASK)); */
+         return false;
       }
    }
 
-   return GL_TRUE;
+   return true;
 }