brw_sf_emit.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
00003  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
00004  develop this 3D driver.
00005 
00006  Permission is hereby granted, free of charge, to any person obtaining
00007  a copy of this software and associated documentation files (the
00008  "Software"), to deal in the Software without restriction, including
00009  without limitation the rights to use, copy, modify, merge, publish,
00010  distribute, sublicense, and/or sell copies of the Software, and to
00011  permit persons to whom the Software is furnished to do so, subject to
00012  the following conditions:
00013 
00014  The above copyright notice and this permission notice (including the
00015  next paragraph) shall be included in all copies or substantial
00016  portions of the Software.
00017 
00018  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
00022  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026  **********************************************************************/
00027  /*
00028   * Authors:
00029   *   Keith Whitwell <keith@tungstengraphics.com>
00030   */
00031 
00032 
00033 #include "brw_defines.h"
00034 #include "brw_context.h"
00035 #include "brw_eu.h"
00036 #include "brw_util.h"
00037 #include "brw_sf.h"
00038 
00039 
00040 
00041 /***********************************************************************
00042  * Triangle setup.
00043  */
00044 
00045 
00046 static void alloc_regs( struct brw_sf_compile *c )
00047 {
00048    unsigned reg, i;
00049 
00050    /* Values computed by fixed function unit:
00051     */
00052    c->pv  = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD);
00053    c->det = brw_vec1_grf(1, 2);
00054    c->dx0 = brw_vec1_grf(1, 3);
00055    c->dx2 = brw_vec1_grf(1, 4);
00056    c->dy0 = brw_vec1_grf(1, 5);
00057    c->dy2 = brw_vec1_grf(1, 6);
00058 
00059    /* z and 1/w passed in seperately:
00060     */
00061    c->z[0]     = brw_vec1_grf(2, 0);
00062    c->inv_w[0] = brw_vec1_grf(2, 1);
00063    c->z[1]     = brw_vec1_grf(2, 2);
00064    c->inv_w[1] = brw_vec1_grf(2, 3);
00065    c->z[2]     = brw_vec1_grf(2, 4);
00066    c->inv_w[2] = brw_vec1_grf(2, 5);
00067 
00068    /* The vertices:
00069     */
00070    reg = 3;
00071    for (i = 0; i < c->nr_verts; i++) {
00072       c->vert[i] = brw_vec8_grf(reg, 0);
00073       reg += c->nr_attr_regs;
00074    }
00075 
00076    /* Temporaries, allocated after last vertex reg.
00077     */
00078    c->inv_det = brw_vec1_grf(reg, 0);  reg++;
00079    c->a1_sub_a0 = brw_vec8_grf(reg, 0);  reg++;
00080    c->a2_sub_a0 = brw_vec8_grf(reg, 0);  reg++;
00081    c->tmp = brw_vec8_grf(reg, 0);  reg++;
00082 
00083    /* Note grf allocation:
00084     */
00085    c->prog_data.total_grf = reg;
00086 
00087 
00088    /* Outputs of this program - interpolation coefficients for
00089     * rasterization:
00090     */
00091    c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0);
00092    c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0);
00093    c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0);
00094 }
00095 
00096 
00097 static void copy_z_inv_w( struct brw_sf_compile *c )
00098 {
00099    struct brw_compile *p = &c->func;
00100    unsigned i;
00101 
00102    brw_push_insn_state(p);
00103 
00104    /* Copy both scalars with a single MOV:
00105     */
00106    for (i = 0; i < c->nr_verts; i++)
00107       brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i]));
00108 
00109    brw_pop_insn_state(p);
00110 }
00111 
00112 
00113 static void invert_det( struct brw_sf_compile *c)
00114 {
00115    brw_math(&c->func,
00116             c->inv_det,
00117             BRW_MATH_FUNCTION_INV,
00118             BRW_MATH_SATURATE_NONE,
00119             0,
00120             c->det,
00121             BRW_MATH_DATA_SCALAR,
00122             BRW_MATH_PRECISION_FULL);
00123 
00124 }
00125 
00126 #define NON_PERPECTIVE_ATTRS  (FRAG_BIT_WPOS | \
00127                                FRAG_BIT_COL0 | \
00128                                FRAG_BIT_COL1)
00129 
00130 static boolean calculate_masks( struct brw_sf_compile *c,
00131                                   unsigned reg,
00132                                   ushort *pc,
00133                                   ushort *pc_persp,
00134                                   ushort *pc_linear)
00135 {
00136    boolean is_last_attr = (reg == c->nr_setup_regs - 1);
00137    unsigned persp_mask = c->key.persp_mask;
00138    unsigned linear_mask = c->key.linear_mask;
00139 
00140    debug_printf("persp_mask: %x\n", persp_mask);
00141    debug_printf("linear_mask: %x\n", linear_mask);
00142 
00143    *pc_persp = 0;
00144    *pc_linear = 0;
00145    *pc = 0xf;
00146 
00147    if (persp_mask & (1 << (reg*2)))
00148       *pc_persp = 0xf;
00149 
00150    if (linear_mask & (1 << (reg*2)))
00151       *pc_linear = 0xf;
00152 
00153    /* Maybe only processs one attribute on the final round:
00154     */
00155    if (reg*2+1 < c->nr_setup_attrs) {
00156       *pc |= 0xf0;
00157 
00158       if (persp_mask & (1 << (reg*2+1)))
00159          *pc_persp |= 0xf0;
00160 
00161       if (linear_mask & (1 << (reg*2+1)))
00162          *pc_linear |= 0xf0;
00163    }
00164 
00165    debug_printf("pc: %x\n", *pc);
00166    debug_printf("pc_persp: %x\n", *pc_persp);
00167    debug_printf("pc_linear: %x\n", *pc_linear);
00168    
00169 
00170    return is_last_attr;
00171 }
00172 
00173 
00174 
00175 void brw_emit_tri_setup( struct brw_sf_compile *c )
00176 {
00177    struct brw_compile *p = &c->func;
00178    unsigned i;
00179 
00180    debug_printf("%s START ==============\n", __FUNCTION__);
00181 
00182    c->nr_verts = 3;
00183    alloc_regs(c);
00184    invert_det(c);
00185    copy_z_inv_w(c);
00186 
00187 
00188    for (i = 0; i < c->nr_setup_regs; i++)
00189    {
00190       /* Pair of incoming attributes:
00191        */
00192       struct brw_reg a0 = offset(c->vert[0], i);
00193       struct brw_reg a1 = offset(c->vert[1], i);
00194       struct brw_reg a2 = offset(c->vert[2], i);
00195       ushort pc = 0, pc_persp = 0, pc_linear = 0;
00196       boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
00197 
00198       if (pc_persp)
00199       {
00200          brw_set_predicate_control_flag_value(p, pc_persp);
00201          brw_MUL(p, a0, a0, c->inv_w[0]);
00202          brw_MUL(p, a1, a1, c->inv_w[1]);
00203          brw_MUL(p, a2, a2, c->inv_w[2]);
00204       }
00205 
00206 
00207       /* Calculate coefficients for interpolated values:
00208        */
00209       if (pc_linear)
00210       {
00211          brw_set_predicate_control_flag_value(p, pc_linear);
00212 
00213          brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
00214          brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
00215 
00216          /* calculate dA/dx
00217           */
00218          brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
00219          brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
00220          brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
00221 
00222          /* calculate dA/dy
00223           */
00224          brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
00225          brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
00226          brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
00227       }
00228 
00229       {
00230          brw_set_predicate_control_flag_value(p, pc);
00231          /* start point for interpolation
00232           */
00233          brw_MOV(p, c->m3C0, a0);
00234 
00235          /* Copy m0..m3 to URB.  m0 is implicitly copied from r0 in
00236           * the send instruction:
00237           */
00238          brw_urb_WRITE(p,
00239                        brw_null_reg(),
00240                        0,
00241                        brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
00242                        0,       /* allocate */
00243                        1,       /* used */
00244                        4,       /* msg len */
00245                        0,       /* response len */
00246                        last,    /* eot */
00247                        last,    /* writes complete */
00248                        i*4,     /* offset */
00249                        BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
00250       }
00251    }
00252 
00253    debug_printf("%s DONE ==============\n", __FUNCTION__);
00254 
00255 }
00256 
00257 
00258 
00259 void brw_emit_line_setup( struct brw_sf_compile *c )
00260 {
00261    struct brw_compile *p = &c->func;
00262    unsigned i;
00263 
00264 
00265    c->nr_verts = 2;
00266    alloc_regs(c);
00267    invert_det(c);
00268    copy_z_inv_w(c);
00269 
00270    for (i = 0; i < c->nr_setup_regs; i++)
00271    {
00272       /* Pair of incoming attributes:
00273        */
00274       struct brw_reg a0 = offset(c->vert[0], i);
00275       struct brw_reg a1 = offset(c->vert[1], i);
00276       ushort pc, pc_persp, pc_linear;
00277       boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
00278 
00279       if (pc_persp)
00280       {
00281          brw_set_predicate_control_flag_value(p, pc_persp);
00282          brw_MUL(p, a0, a0, c->inv_w[0]);
00283          brw_MUL(p, a1, a1, c->inv_w[1]);
00284       }
00285 
00286       /* Calculate coefficients for position, color:
00287        */
00288       if (pc_linear) {
00289          brw_set_predicate_control_flag_value(p, pc_linear);
00290 
00291          brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
00292 
00293          brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
00294          brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
00295 
00296          brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
00297          brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
00298       }
00299 
00300       {
00301          brw_set_predicate_control_flag_value(p, pc);
00302 
00303          /* start point for interpolation
00304           */
00305          brw_MOV(p, c->m3C0, a0);
00306 
00307          /* Copy m0..m3 to URB.
00308           */
00309          brw_urb_WRITE(p,
00310                        brw_null_reg(),
00311                        0,
00312                        brw_vec8_grf(0, 0),
00313                        0,       /* allocate */
00314                        1,       /* used */
00315                        4,       /* msg len */
00316                        0,       /* response len */
00317                        last,    /* eot */
00318                        last,    /* writes complete */
00319                        i*4,     /* urb destination offset */
00320                        BRW_URB_SWIZZLE_TRANSPOSE);
00321       }
00322    }
00323 }
00324 
00325 
00326 /* Points setup - several simplifications as all attributes are
00327  * constant across the face of the point (point sprites excluded!)
00328  */
00329 void brw_emit_point_setup( struct brw_sf_compile *c )
00330 {
00331    struct brw_compile *p = &c->func;
00332    unsigned i;
00333 
00334    c->nr_verts = 1;
00335    alloc_regs(c);
00336    copy_z_inv_w(c);
00337 
00338    brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
00339    brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
00340 
00341    for (i = 0; i < c->nr_setup_regs; i++)
00342    {
00343       struct brw_reg a0 = offset(c->vert[0], i);
00344       ushort pc, pc_persp, pc_linear;
00345       boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
00346 
00347       if (pc_persp)
00348       {
00349          /* This seems odd as the values are all constant, but the
00350           * fragment shader will be expecting it:
00351           */
00352          brw_set_predicate_control_flag_value(p, pc_persp);
00353          brw_MUL(p, a0, a0, c->inv_w[0]);
00354       }
00355 
00356 
00357       /* The delta values are always zero, just send the starting
00358        * coordinate.  Again, this is to fit in with the interpolation
00359        * code in the fragment shader.
00360        */
00361       {
00362          brw_set_predicate_control_flag_value(p, pc);
00363 
00364          brw_MOV(p, c->m3C0, a0); /* constant value */
00365 
00366          /* Copy m0..m3 to URB.
00367           */
00368          brw_urb_WRITE(p,
00369                        brw_null_reg(),
00370                        0,
00371                        brw_vec8_grf(0, 0),
00372                        0,       /* allocate */
00373                        1,       /* used */
00374                        4,       /* msg len */
00375                        0,       /* response len */
00376                        last,    /* eot */
00377                        last,    /* writes complete */
00378                        i*4,     /* urb destination offset */
00379                        BRW_URB_SWIZZLE_TRANSPOSE);
00380       }
00381    }
00382 }

Generated on Tue Sep 29 06:25:16 2009 for Gallium3D by  doxygen 1.5.4