i965/fs: Expose "urb_setup" as part of brw_wm_prog_data.
authorPaul Berry <stereotype441@gmail.com>
Tue, 3 Sep 2013 00:24:19 +0000 (17:24 -0700)
committerPaul Berry <stereotype441@gmail.com>
Mon, 16 Sep 2013 19:53:05 +0000 (12:53 -0700)
At the moment, for Gen6+, the FS assumes that all varying inputs are
delivered to it in the order in which they appear in the
gl_program::InputsRead bitfield, and the SF/SBE setup code ensures
that they are delivered in this order.

When we add support for more than 64 varying components, this will no
longer always be possible, because the Gen6+ SF/SBE stage is only
capable of performing arbitrary reorderings of 16 varying slots.

To allow extra flexibility in the ordering of FS varyings, this patch
causes the FS to advertise exactly what ordering it expects.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 108e98ca514310579ed75463f890fef2a4f92e8a..988e9fbf656d95a52b1e57770ab0beedbde969a7 100644 (file)
@@ -336,6 +336,13 @@ struct brw_wm_prog_data {
     */
    uint32_t barycentric_interp_modes;
 
+   /**
+    * Map from gl_varying_slot to the position within the FS setup data
+    * payload where the varying's attribute vertex deltas should be delivered.
+    * For varying slots that are not used by the FS, the value is -1.
+    */
+   int urb_setup[VARYING_SLOT_MAX];
+
    /* Pointers to tracked values (only valid once
     * _mesa_load_state_parameters has been called at runtime).
     *
index daa23b4ad2432a8c3ba5d56dfddc2b6660b21733..e788196aeb9400477ffc43899a5cf3c75b7b1906 100644 (file)
@@ -1004,7 +1004,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
    int location = ir->location;
    for (unsigned int i = 0; i < array_elements; i++) {
       for (unsigned int j = 0; j < type->matrix_columns; j++) {
-        if (urb_setup[location] == -1) {
+        if (c->prog_data.urb_setup[location] == -1) {
            /* If there's no incoming setup data for this slot, don't
             * emit interpolation for it.
             */
@@ -1231,7 +1231,7 @@ void
 fs_visitor::calculate_urb_setup()
 {
    for (unsigned int i = 0; i < VARYING_SLOT_MAX; i++) {
-      urb_setup[i] = -1;
+      c->prog_data.urb_setup[i] = -1;
    }
 
    int urb_next = 0;
@@ -1239,7 +1239,7 @@ fs_visitor::calculate_urb_setup()
    if (brw->gen >= 6) {
       for (unsigned int i = 0; i < VARYING_SLOT_MAX; i++) {
         if (fp->Base.InputsRead & BITFIELD64_BIT(i)) {
-           urb_setup[i] = urb_next++;
+           c->prog_data.urb_setup[i] = urb_next++;
         }
       }
    } else {
@@ -1257,7 +1257,7 @@ fs_visitor::calculate_urb_setup()
             * incremented, mapped or not.
             */
            if (_mesa_varying_slot_in_fs((gl_varying_slot) i))
-              urb_setup[i] = urb_next;
+              c->prog_data.urb_setup[i] = urb_next;
             urb_next++;
         }
       }
@@ -1269,7 +1269,7 @@ fs_visitor::calculate_urb_setup()
        * See compile_sf_prog() for more info.
        */
       if (fp->Base.InputsRead & BITFIELD64_BIT(VARYING_SLOT_PNTC))
-         urb_setup[VARYING_SLOT_PNTC] = urb_next++;
+         c->prog_data.urb_setup[VARYING_SLOT_PNTC] = urb_next++;
    }
 
    /* Each attribute is 4 setup channels, each of which is half a reg. */
index cb4ac3b455f65ae711c991a0c2389487483326fb..b77d4def80adf936b93a2d4ef4e2a3eeedec76de 100644 (file)
@@ -454,7 +454,6 @@ public:
    int first_non_payload_grf;
    /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */
    int max_grf;
-   int urb_setup[VARYING_SLOT_MAX];
 
    fs_reg *fp_temp_regs;
    fs_reg *fp_input_regs;
index d935c7b26e3fde1521cd57854a047307c98dc6aa..8b505a07cad8fcaa9f1c4ac27c7a9f5a834f66ce 100644 (file)
@@ -2171,10 +2171,10 @@ fs_visitor::emit_dummy_fs()
 struct brw_reg
 fs_visitor::interp_reg(int location, int channel)
 {
-   int regnr = urb_setup[location] * 2 + channel / 2;
+   int regnr = c->prog_data.urb_setup[location] * 2 + channel / 2;
    int stride = (channel & 1) * 4;
 
-   assert(urb_setup[location] != -1);
+   assert(c->prog_data.urb_setup[location] != -1);
 
    return brw_vec1_grf(regnr, stride);
 }