Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / dri / r200 / r200_swtcl.c
index 83e70b586d7f7b00c4c9544e67f00e46c347a619..38864162cede8637cfe68d7da83d59a2e66423f6 100644 (file)
@@ -39,11 +39,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/image.h"
 #include "main/imports.h"
 #include "main/macros.h"
+#include "main/simple_list.h"
 
 #include "swrast/s_context.h"
 #include "swrast/s_fog.h"
 #include "swrast_setup/swrast_setup.h"
-#include "math/m_translate.h"
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
@@ -75,7 +75,7 @@ do {                                                                  \
    rmesa->radeon.swtcl.vertex_attr_count++;                                    \
 } while (0)
 
-static void r200SetVertexFormat( GLcontext *ctx )
+static void r200SetVertexFormat( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -167,7 +167,7 @@ static void r200SetVertexFormat( GLcontext *ctx )
 
       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
         if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
-           GLuint sz = VB->TexCoordPtr[i]->size;
+           GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
 
            fmt_1 |= sz << (3 * i);
            EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 );
@@ -200,10 +200,32 @@ static void r200SetVertexFormat( GLcontext *ctx )
    }
 }
 
+static void r200_predict_emit_size( r200ContextPtr rmesa )
+{
+   if (RADEON_DEBUG & RADEON_VERTS)
+      fprintf(stderr, "%s\n", __func__);
+   const int vertex_array_size = 7;
+   const int prim_size = 3;
+   if (!rmesa->radeon.swtcl.emit_prediction) {
+      const int state_size = radeonCountStateEmitSize(&rmesa->radeon);
+      if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
+              state_size +
+              vertex_array_size + prim_size,
+              __FUNCTION__))
+        rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
+      else
+        rmesa->radeon.swtcl.emit_prediction = state_size;
+      rmesa->radeon.swtcl.emit_prediction += vertex_array_size + prim_size
+        + rmesa->radeon.cmdbuf.cs->cdw;
+   }
+}
+
 
-static void r200RenderStart( GLcontext *ctx )
+static void r200RenderStart( struct gl_context *ctx )
 {
    r200SetVertexFormat( ctx );
+   if (RADEON_DEBUG & RADEON_VERTS)
+      fprintf(stderr, "%s\n", __func__);
 }
 
 
@@ -212,7 +234,7 @@ static void r200RenderStart( GLcontext *ctx )
  * determine in advance whether or not the hardware can / should do the
  * projection divide or Mesa should do it.
  */
-void r200ChooseVertexState( GLcontext *ctx )
+void r200ChooseVertexState( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -264,31 +286,36 @@ void r200ChooseVertexState( GLcontext *ctx )
    }
 }
 
-void r200_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
+void r200_swtcl_flush(struct gl_context *ctx, uint32_t current_offset)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   rcommonEnsureCmdBufSpace(&rmesa->radeon,
-                           rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
-                           __FUNCTION__);
+   if (RADEON_DEBUG & RADEON_VERTS)
+      fprintf(stderr, "%s\n", __func__);
 
 
    radeonEmitState(&rmesa->radeon);
    r200EmitVertexAOS( rmesa,
                      rmesa->radeon.swtcl.vertex_size,
-                     rmesa->radeon.dma.current,
+                     rmesa->radeon.swtcl.bo,
                      current_offset);
 
 
    r200EmitVbufPrim( rmesa,
                     rmesa->radeon.swtcl.hw_primitive,
                     rmesa->radeon.swtcl.numverts);
+   if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
+      WARN_ONCE("Rendering was %d commands larger than predicted size."
+           " We might overflow  command buffer.\n",
+           rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
+
+   rmesa->radeon.swtcl.emit_prediction = 0;
 
 }
 
 /**************************************************************************/
 
 
-static INLINE GLuint reduced_hw_prim( GLcontext *ctx, GLuint prim)
+static INLINE GLuint reduced_hw_prim( struct gl_context *ctx, GLuint prim)
 {
    switch (prim) {
    case GL_POINTS:
@@ -309,9 +336,9 @@ static INLINE GLuint reduced_hw_prim( GLcontext *ctx, GLuint prim)
 }
 
 
-static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim );
-static void r200RenderPrimitive( GLcontext *ctx, GLenum prim );
-static void r200ResetLineStipple( GLcontext *ctx );
+static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim );
+static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim );
+static void r200ResetLineStipple( struct gl_context *ctx );
 
 /***********************************************************************
  *                    Emit primitives as inline vertices               *
@@ -329,17 +356,27 @@ static void r200ResetLineStipple( GLcontext *ctx );
 #define HAVE_POLYGONS    1
 #define HAVE_ELTS        0
 
+static void* r200_alloc_verts( r200ContextPtr rmesa, GLuint n, GLuint size)
+{
+   void *rv;
+   do {
+      r200_predict_emit_size( rmesa );
+      rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
+   } while(!rv);
+   return rv;
+}
+
 #undef LOCAL_VARS
 #undef ALLOC_VERTS
 #define CTX_ARG r200ContextPtr rmesa
 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
-#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
+#define ALLOC_VERTS( n, size ) r200_alloc_verts(rmesa, n, size)
 #define LOCAL_VARS                                             \
    r200ContextPtr rmesa = R200_CONTEXT(ctx);           \
    const char *r200verts = (char *)rmesa->radeon.swtcl.verts;
 #define VERT(x) (radeonVertex *)(r200verts + ((x) * vertsize * sizeof(int)))
 #define VERTEX radeonVertex
-#define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS))
+#define DO_DEBUG_VERTS (1 && (R200_DEBUG & RADEON_VERTS))
 
 #undef TAG
 #define TAG(x) r200_##x
@@ -383,7 +420,6 @@ static struct {
 #define DO_POINTS    1
 #define DO_FULL_QUAD 1
 
-#define HAVE_RGBA   1
 #define HAVE_SPEC   1
 #define HAVE_BACK_COLORS  0
 #define HAVE_HW_FLATSHADE 1
@@ -443,7 +479,7 @@ do {                                                        \
 
 #define LOCAL_VARS(n)                                                  \
    r200ContextPtr rmesa = R200_CONTEXT(ctx);                   \
-   GLuint color[n], spec[n];                                           \
+   GLuint color[n] = {0}, spec[n] = {0};                                               \
    GLuint coloroffset = rmesa->swtcl.coloroffset;      \
    GLuint specoffset = rmesa->swtcl.specoffset;                        \
    (void) color; (void) spec; (void) coloroffset; (void) specoffset;
@@ -532,7 +568,7 @@ static void init_rast_tab( void )
 /*                    Choose render functions                         */
 /**********************************************************************/
 
-void r200ChooseRenderState( GLcontext *ctx )
+void r200ChooseRenderState( struct gl_context *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -572,10 +608,15 @@ void r200ChooseRenderState( GLcontext *ctx )
 /**********************************************************************/
 
 
-static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim )
+static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
+   radeon_prepare_render(&rmesa->radeon);
+   if (rmesa->radeon.NewGLState)
+      r200ValidateState( ctx );
+
+
    if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
       /* need to disable perspective-correct texturing for point sprites */
       if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) {
@@ -593,7 +634,7 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim )
    }
 }
 
-static void r200RenderPrimitive( GLcontext *ctx, GLenum prim )
+static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    rmesa->radeon.swtcl.render_primitive = prim;
@@ -601,11 +642,11 @@ static void r200RenderPrimitive( GLcontext *ctx, GLenum prim )
       r200RasterPrimitive( ctx, reduced_hw_prim(ctx, prim) );
 }
 
-static void r200RenderFinish( GLcontext *ctx )
+static void r200RenderFinish( struct gl_context *ctx )
 {
 }
 
-static void r200ResetLineStipple( GLcontext *ctx )
+static void r200ResetLineStipple( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    R200_STATECHANGE( rmesa, lin );
@@ -637,7 +678,7 @@ static const char *getFallbackString(GLuint bit)
 }
 
 
-void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
+void r200Fallback( struct gl_context *ctx, GLuint bit, GLboolean mode )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -650,7 +691,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
         TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE );
         _swsetup_Wakeup( ctx );
         rmesa->radeon.swtcl.RenderIndex = ~0;
-         if (R200_DEBUG & DEBUG_FALLBACKS) {
+         if (R200_DEBUG & RADEON_FALLBACKS) {
             fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n",
                     bit, getFallbackString(bit));
          }
@@ -682,7 +723,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
            r200ChooseVertexState( ctx );
            r200ChooseRenderState( ctx );
         }
-         if (R200_DEBUG & DEBUG_FALLBACKS) {
+         if (R200_DEBUG & RADEON_FALLBACKS) {
             fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n",
                     bit, getFallbackString(bit));
          }
@@ -704,7 +745,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
  * NV_texture_rectangle).
  */
 void
-r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
+r200PointsBitmap( struct gl_context *ctx, GLint px, GLint py,
                  GLsizei width, GLsizei height,
                  const struct gl_pixelstore_attrib *unpack,
                  const GLubyte *bitmap )
@@ -879,7 +920,7 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
 /*                            Initialization.                         */
 /**********************************************************************/
 
-void r200InitSwtcl( GLcontext *ctx )
+void r200InitSwtcl( struct gl_context *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -889,6 +930,7 @@ void r200InitSwtcl( GLcontext *ctx )
       init_rast_tab();
       firsttime = 0;
    }
+   rmesa->radeon.swtcl.emit_prediction = 0;
 
    tnl->Driver.Render.Start = r200RenderStart;
    tnl->Driver.Render.Finish = r200RenderFinish;