llvmpipe: Fix lp_test_format on 32bit OSes.
[mesa.git] / src / gallium / drivers / i965 / brw_sf.c
index 90513245ee84258adbc0080f5dde1eeabaece81f..5abf3848ab4e6d7865c505e5215845443cbb7946 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
   
+#include "pipe/p_state.h"
 
-#include "main/glheader.h"
-#include "main/macros.h"
-#include "main/enums.h"
-
-#include "intel_batchbuffer.h"
-
+#include "brw_batchbuffer.h"
 #include "brw_defines.h"
 #include "brw_context.h"
+#include "brw_pipe_rast.h"
 #include "brw_eu.h"
-#include "brw_util.h"
 #include "brw_sf.h"
 #include "brw_state.h"
 
-static void compile_sf_prog( struct brw_context *brw,
-                            struct brw_sf_prog_key *key )
+static enum pipe_error compile_sf_prog( struct brw_context *brw,
+                                        struct brw_sf_prog_key *key,
+                                        struct brw_winsys_buffer **bo_out )
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   enum pipe_error ret;
    struct brw_sf_compile c;
    const GLuint *program;
    GLuint program_size;
-   GLuint i, idx;
 
    memset(&c, 0, sizeof(c));
 
@@ -59,141 +55,161 @@ static void compile_sf_prog( struct brw_context *brw,
    brw_init_compile(brw, &c.func);
 
    c.key = *key;
-   c.nr_attrs = util_count_bits(c.key.attrs);
+   c.nr_attrs = c.key.nr_attrs;
    c.nr_attr_regs = (c.nr_attrs+1)/2;
-   c.nr_setup_attrs = util_count_bits(c.key.attrs & DO_SETUP_BITS);
+   c.nr_setup_attrs = c.key.nr_attrs;
    c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
 
    c.prog_data.urb_read_length = c.nr_attr_regs;
    c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
 
-   /* Construct map from attribute number to position in the vertex.
+   /* Special case when there are no attributes to setup.
+    *
+    * XXX: should be able to set nr_setup_attrs to nr_attrs-1 -- but
+    * breaks vp-tris.c
     */
-   for (i = idx = 0; i < VERT_RESULT_MAX; i++) 
-      if (c.key.attrs & (1<<i)) {
-        c.attr_to_idx[i] = idx;
-        c.idx_to_attr[idx] = i;
-        if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) {
-            c.point_attrs[i].CoordReplace = 
-               ctx->Point.CoordReplace[i - VERT_RESULT_TEX0];
-        }
-         else {
-            c.point_attrs[i].CoordReplace = GL_FALSE;
-         }
-        idx++;
+   if (c.nr_attrs - 1 == 0) {
+      c.nr_verts = 0;
+      brw_emit_null_setup( &c );
+   }
+   else {
+      /* Which primitive?  Or all three? 
+       */
+      switch (key->primitive) {
+      case SF_TRIANGLES:
+         c.nr_verts = 3;
+         brw_emit_tri_setup( &c, GL_TRUE );
+         break;
+      case SF_LINES:
+         c.nr_verts = 2;
+         brw_emit_line_setup( &c, GL_TRUE );
+         break;
+      case SF_POINTS:
+         c.nr_verts = 1;
+         if (key->do_point_sprite)
+            brw_emit_point_sprite_setup( &c, GL_TRUE );
+         else
+            brw_emit_point_setup( &c, GL_TRUE );
+         break;
+      case SF_UNFILLED_TRIS:
+         c.nr_verts = 3;
+         brw_emit_anyprim_setup( &c );
+         break;
+      default:
+         assert(0);
+         return PIPE_ERROR_BAD_INPUT;
       }
-   
-   /* Which primitive?  Or all three? 
-    */
-   switch (key->primitive) {
-   case SF_TRIANGLES:
-      c.nr_verts = 3;
-      brw_emit_tri_setup( &c, GL_TRUE );
-      break;
-   case SF_LINES:
-      c.nr_verts = 2;
-      brw_emit_line_setup( &c, GL_TRUE );
-      break;
-   case SF_POINTS:
-      c.nr_verts = 1;
-      if (key->do_point_sprite)
-         brw_emit_point_sprite_setup( &c, GL_TRUE );
-      else
-         brw_emit_point_setup( &c, GL_TRUE );
-      break;
-   case SF_UNFILLED_TRIS:
-      c.nr_verts = 3;
-      brw_emit_anyprim_setup( &c );
-      break;
-   default:
-      assert(0);
-      return;
    }
 
    /* get the program
     */
-   program = brw_get_program(&c.func, &program_size);
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
 
    /* Upload
     */
-   dri_bo_unreference(brw->sf.prog_bo);
-   brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG,
-                                      &c.key, sizeof(c.key),
-                                      NULL, 0,
-                                      program, program_size,
-                                      &c.prog_data,
-                                      &brw->sf.prog_data );
+   ret = brw_upload_cache( &brw->cache, BRW_SF_PROG,
+                           &c.key, sizeof(c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->sf.prog_data,
+                           bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
 }
 
 /* Calculate interpolants for triangle and line rasterization.
  */
-static void upload_sf_prog(struct brw_context *brw)
+static enum pipe_error upload_sf_prog(struct brw_context *brw)
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   const struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
+   const struct pipe_rasterizer_state *rast = &brw->curr.rast->templ;
    struct brw_sf_prog_key key;
+   enum pipe_error ret;
+   unsigned i;
 
    memset(&key, 0, sizeof(key));
 
    /* Populate the key, noting state dependencies:
     */
-   /* CACHE_NEW_VS_PROG */
-   key.attrs = brw->vs.prog_data->outputs_written; 
+
+   /* XXX: Add one to account for the position input.
+    */
+   /* PIPE_NEW_FRAGMENT_SIGNATURE */
+   key.nr_attrs = sig->nr_inputs + 1;
+
+
+   /* XXX: why is position required to be linear?  why do we care
+    * about it at all?
+    */
+   key.linear_attrs = 1;        /* position -- but why? */
+
+   for (i = 0; i < sig->nr_inputs; i++) {
+      switch (sig->input[i].interp) {
+      case TGSI_INTERPOLATE_CONSTANT:
+         break;
+      case TGSI_INTERPOLATE_LINEAR:
+         key.linear_attrs |= 1 << (i+1);
+         break;
+      case TGSI_INTERPOLATE_PERSPECTIVE:
+         key.persp_attrs |= 1 << (i+1);
+         break;
+      }
+   }
 
    /* BRW_NEW_REDUCED_PRIMITIVE */
-   switch (brw->intel.reduced_primitive) {
-   case GL_TRIANGLES: 
-      /* NOTE: We just use the edgeflag attribute as an indicator that
-       * unfilled triangles are active.  We don't actually do the
-       * edgeflag testing here, it is already done in the clip
-       * program.
+   switch (brw->reduced_primitive) {
+   case PIPE_PRIM_TRIANGLES: 
+      /* PIPE_NEW_RAST
        */
-      if (key.attrs & (1<<VERT_RESULT_EDGE))
+      if (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
+         rast->fill_back != PIPE_POLYGON_MODE_FILL)
         key.primitive = SF_UNFILLED_TRIS;
       else
         key.primitive = SF_TRIANGLES;
       break;
-   case GL_LINES: 
+   case PIPE_PRIM_LINES: 
       key.primitive = SF_LINES; 
       break;
-   case GL_POINTS: 
+   case PIPE_PRIM_POINTS: 
       key.primitive = SF_POINTS; 
       break;
    }
 
-   key.do_point_sprite = ctx->Point.PointSprite;
-   key.SpriteOrigin = ctx->Point.SpriteOrigin;
-   /* _NEW_LIGHT */
-   key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
-   key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
-
-   /* _NEW_HINT */
-   key.linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
+   key.do_point_sprite = rast->sprite_coord_enable ? 1 : 0;
+   key.sprite_origin_lower_left = (rast->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
+   key.point_coord_replace_attrs = rast->sprite_coord_enable;
+   key.do_flat_shading = rast->flatshade;
+   key.do_twoside_color = rast->light_twoside;
 
-   /* _NEW_POLYGON */
    if (key.do_twoside_color) {
-      /* If we're rendering to a FBO, we have to invert the polygon
-       * face orientation, just as we invert the viewport in
-       * sf_unit_create_from_key().  ctx->DrawBuffer->Name will be
-       * nonzero if we're rendering to such an FBO.
-       */
-      key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0);
+      key.frontface_ccw = rast->front_ccw;
    }
 
-   dri_bo_unreference(brw->sf.prog_bo);
-   brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG,
-                                     &key, sizeof(key),
-                                     NULL, 0,
-                                     &brw->sf.prog_data);
-   if (brw->sf.prog_bo == NULL)
-      compile_sf_prog( brw, &key );
+   if (brw_search_cache(&brw->cache, BRW_SF_PROG,
+                        &key, sizeof(key),
+                        NULL, 0,
+                        &brw->sf.prog_data,
+                        &brw->sf.prog_bo))
+      return PIPE_OK;
+
+   ret = compile_sf_prog( brw, &key, &brw->sf.prog_bo );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
 }
 
 
 const struct brw_tracked_state brw_sf_prog = {
    .dirty = {
-      .mesa  = (_NEW_HINT | _NEW_LIGHT | _NEW_POLYGON | _NEW_POINT),
+      .mesa  = (PIPE_NEW_RAST | PIPE_NEW_FRAGMENT_SIGNATURE),
       .brw   = (BRW_NEW_REDUCED_PRIMITIVE),
-      .cache = CACHE_NEW_VS_PROG
+      .cache = 0
    },
    .prepare = upload_sf_prog
 };