util: simplify util_pstipple_create_fragment_shader() params
[mesa.git] / src / gallium / drivers / softpipe / sp_setup.c
index b82594ca2a5433482255e7ffa1e8530433777dae..6704015112b8eda5607f6530c668343d9b675c60 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -28,7 +28,7 @@
 /**
  * \brief  Primitive rasterization/rendering (points, lines, triangles)
  *
- * \author  Keith Whitwell <keith@tungstengraphics.com>
+ * \author  Keith Whitwell <keithw@vmware.com>
  * \author  Brian Paul
  */
 
@@ -92,6 +92,7 @@ struct setup_context {
    int facing;
 
    float pixel_offset;
+   unsigned max_layer;
 
    struct quad_header quad[MAX_QUADS];
    struct quad_header *quad_ptrs[MAX_QUADS];
@@ -163,6 +164,10 @@ clip_emit_quad(struct setup_context *setup, struct quad_header *quad)
    if (quad->inout.mask) {
       struct softpipe_context *sp = setup->softpipe;
 
+#if DEBUG_FRAGS
+      setup->numFragsEmitted += util_bitcount(quad->inout.mask);
+#endif
+
       sp->quad.first->run( sp->quad.first, &quad, 1 );
    }
 }
@@ -234,6 +239,9 @@ flush_spans(struct setup_context *setup)
                setup->quad[q].inout.mask = quadmask;
                setup->quad_ptrs[q] = &setup->quad[q];
                q++;
+#if DEBUG_FRAGS
+               setup->numFragsEmitted += util_bitcount(quadmask);
+#endif
             }
             mask0 >>= 2;
             mask1 >>= 2;
@@ -387,7 +395,7 @@ setup_sort_vertices(struct setup_context *setup,
     *  - pixel center (0.5, 0.5) for GL, or
     *  - assume (0.0, 0.0) for other APIs.
     */
-   if (setup->softpipe->rasterizer->gl_rasterization_rules) {
+   if (setup->softpipe->rasterizer->half_pixel_center) {
       setup->pixel_offset = 0.5f;
    } else {
       setup->pixel_offset = 0.0f;
@@ -504,14 +512,6 @@ tri_linear_coeff(struct setup_context *setup,
    coef->a0[i] = (v[0] -
                   (dadx * (setup->vmin[0][0] - setup->pixel_offset) +
                    dady * (setup->vmin[0][1] - setup->pixel_offset)));
-
-   /*
-   debug_printf("attr[%d].%c: %f dx:%f dy:%f\n",
-               slot, "xyzw"[i],
-               setup->coef[slot].a0[i],
-               setup->coef[slot].dadx[i],
-               setup->coef[slot].dady[i]);
-   */
 }
 
 
@@ -542,13 +542,6 @@ tri_persp_coeff(struct setup_context *setup,
    float dadx = a * setup->oneoverarea;
    float dady = b * setup->oneoverarea;
 
-   /*
-   debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i,
-               setup->vmin[vertSlot][i],
-               setup->vmid[vertSlot][i],
-                       setup->vmax[vertSlot][i]
-          );
-   */
    assert(i <= 3);
 
    coef->dadx[i] = dadx;
@@ -569,17 +562,21 @@ static void
 setup_fragcoord_coeff(struct setup_context *setup, uint slot)
 {
    const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
+   boolean origin_lower_left =
+         fsInfo->properties[TGSI_PROPERTY_FS_COORD_ORIGIN];
+   boolean pixel_center_integer =
+         fsInfo->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER];
 
    /*X*/
-   setup->coef[slot].a0[0] = fsInfo->pixel_center_integer ? 0.0 : 0.5;
-   setup->coef[slot].dadx[0] = 1.0;
-   setup->coef[slot].dady[0] = 0.0;
+   setup->coef[slot].a0[0] = pixel_center_integer ? 0.0f : 0.5f;
+   setup->coef[slot].dadx[0] = 1.0f;
+   setup->coef[slot].dady[0] = 0.0f;
    /*Y*/
    setup->coef[slot].a0[1] =
-                  (fsInfo->origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0)
-                  + (fsInfo->pixel_center_integer ? 0.0 : 0.5);
-   setup->coef[slot].dadx[1] = 0.0;
-   setup->coef[slot].dady[1] = fsInfo->origin_lower_left ? -1.0 : 1.0;
+                  (origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0)
+                  + (pixel_center_integer ? 0.0f : 0.5f);
+   setup->coef[slot].dadx[1] = 0.0f;
+   setup->coef[slot].dady[1] = origin_lower_left ? -1.0f : 1.0f;
    /*Z*/
    setup->coef[slot].a0[2] = setup->posCoef.a0[2];
    setup->coef[slot].dadx[2] = setup->posCoef.dadx[2];
@@ -625,11 +622,11 @@ setup_tri_coefficients(struct setup_context *setup)
 
       switch (vinfo->attrib[fragSlot].interp_mode) {
       case INTERP_CONSTANT:
-         for (j = 0; j < NUM_CHANNELS; j++)
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
          break;
       case INTERP_LINEAR:
-         for (j = 0; j < NUM_CHANNELS; j++) {
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
             tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                        setup->vmid[vertSlot][j],
                                        setup->vmax[vertSlot][j],
@@ -639,7 +636,7 @@ setup_tri_coefficients(struct setup_context *setup)
          }
          break;
       case INTERP_PERSPECTIVE:
-         for (j = 0; j < NUM_CHANNELS; j++) {
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
             tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                        setup->vmid[vertSlot][j],
                                        setup->vmax[vertSlot][j],
@@ -661,6 +658,16 @@ setup_tri_coefficients(struct setup_context *setup)
          setup->coef[fragSlot].dadx[0] = 0.0;
          setup->coef[fragSlot].dady[0] = 0.0;
       }
+
+      if (0) {
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
+            debug_printf("attr[%d].%c: a0:%f dx:%f dy:%f\n",
+                         fragSlot, "xyzw"[j],
+                         setup->coef[fragSlot].a0[j],
+                         setup->coef[fragSlot].dadx[j],
+                         setup->coef[fragSlot].dady[j]);
+         }
+      }
    }
 }
 
@@ -799,7 +806,7 @@ sp_setup_tri(struct setup_context *setup,
              const float (*v2)[4])
 {
    float det;
-
+   uint layer = 0;
 #if DEBUG_VERTS
    debug_printf("Setup triangle:\n");
    print_vertex(setup, v0);
@@ -807,7 +814,7 @@ sp_setup_tri(struct setup_context *setup,
    print_vertex(setup, v2);
 #endif
 
-   if (setup->softpipe->no_rast)
+   if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
       return;
    
    det = calc_det(v0, v1, v2);
@@ -832,6 +839,11 @@ sp_setup_tri(struct setup_context *setup,
    setup->span.right[0] = 0;
    setup->span.right[1] = 0;
    /*   setup->span.z_mode = tri_z_mode( setup->ctx ); */
+   if (setup->softpipe->layer_slot > 0) {
+      layer = *(unsigned *)v1[setup->softpipe->layer_slot];
+      layer = MIN2(layer, setup->max_layer);
+   }
+   setup->quad[0].input.layer = layer;
 
    /*   init_constant_attribs( setup ); */
 
@@ -850,6 +862,10 @@ sp_setup_tri(struct setup_context *setup,
 
    flush_spans( setup );
 
+   if (setup->softpipe->active_statistics_queries) {
+      setup->softpipe->pipeline_statistics.c_primitives++;
+   }
+
 #if DEBUG_FRAGS
    printf("Tri: %u frags emitted, %u written\n",
           setup->numFragsEmitted,
@@ -981,11 +997,11 @@ setup_line_coefficients(struct setup_context *setup,
 
       switch (vinfo->attrib[fragSlot].interp_mode) {
       case INTERP_CONSTANT:
-         for (j = 0; j < NUM_CHANNELS; j++)
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
          break;
       case INTERP_LINEAR:
-         for (j = 0; j < NUM_CHANNELS; j++) {
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
             line_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                         setup->vmax[vertSlot][j],
                                         fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
@@ -994,7 +1010,7 @@ setup_line_coefficients(struct setup_context *setup,
          }
          break;
       case INTERP_PERSPECTIVE:
-         for (j = 0; j < NUM_CHANNELS; j++) {
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
             line_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                         setup->vmax[vertSlot][j],
                                         fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
@@ -1066,6 +1082,7 @@ sp_setup_line(struct setup_context *setup,
    int dx = x1 - x0;
    int dy = y1 - y0;
    int xstep, ystep;
+   uint layer = 0;
 
 #if DEBUG_VERTS
    debug_printf("Setup line:\n");
@@ -1073,7 +1090,7 @@ sp_setup_line(struct setup_context *setup,
    print_vertex(setup, v1);
 #endif
 
-   if (setup->softpipe->no_rast)
+   if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
       return;
 
    if (dx == 0 && dy == 0)
@@ -1109,6 +1126,11 @@ sp_setup_line(struct setup_context *setup,
 
    setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1;
    setup->quad[0].inout.mask = 0x0;
+   if (setup->softpipe->layer_slot > 0) {
+      layer = *(unsigned *)v1[setup->softpipe->layer_slot];
+      layer = MIN2(layer, setup->max_layer);
+   }
+   setup->quad[0].input.layer = layer;
 
    /* XXX temporary: set coverage to 1.0 so the line appears
     * if AA mode happens to be enabled.
@@ -1200,17 +1222,23 @@ sp_setup_point(struct setup_context *setup,
    const float y = v0[0][1];
    const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
    uint fragSlot;
-
+   uint layer = 0;
 #if DEBUG_VERTS
    debug_printf("Setup point:\n");
    print_vertex(setup, v0);
 #endif
 
-   if (softpipe->no_rast)
+   if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
       return;
 
    assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS);
 
+   if (setup->softpipe->layer_slot > 0) {
+      layer = *(unsigned *)v0[setup->softpipe->layer_slot];
+      layer = MIN2(layer, setup->max_layer);
+   }
+   setup->quad[0].input.layer = layer;
+
    /* For points, all interpolants are constant-valued.
     * However, for point sprites, we'll need to setup texcoords appropriately.
     * XXX: which coefficients are the texcoords???
@@ -1241,11 +1269,11 @@ sp_setup_point(struct setup_context *setup,
       case INTERP_CONSTANT:
          /* fall-through */
       case INTERP_LINEAR:
-         for (j = 0; j < NUM_CHANNELS; j++)
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
          break;
       case INTERP_PERSPECTIVE:
-         for (j = 0; j < NUM_CHANNELS; j++)
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
             point_persp_coeff(setup, setup->vprovoke,
                               &setup->coef[fragSlot], vertSlot, j);
          break;
@@ -1395,14 +1423,32 @@ void
 sp_setup_prepare(struct setup_context *setup)
 {
    struct softpipe_context *sp = setup->softpipe;
-
+   int i;
+   unsigned max_layer = ~0;
    if (sp->dirty) {
-      softpipe_update_derived(sp);
+      softpipe_update_derived(sp, sp->reduced_api_prim);
    }
 
    /* Note: nr_attrs is only used for debugging (vertex printing) */
    setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);
 
+   /*
+    * Determine how many layers the fb has (used for clamping layer value).
+    * OpenGL (but not d3d10) permits different amount of layers per rt, however
+    * results are undefined if layer exceeds the amount of layers of ANY
+    * attachment hence don't need separate per cbuf and zsbuf max.
+    */
+   for (i = 0; i < setup->softpipe->framebuffer.nr_cbufs; i++) {
+      struct pipe_surface *cbuf = setup->softpipe->framebuffer.cbufs[i];
+      if (cbuf) {
+         max_layer = MIN2(max_layer,
+                          cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
+
+      }
+   }
+
+   setup->max_layer = max_layer;
+
    sp->quad.first->begin( sp->quad.first );
 
    if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&