brw_clip_line.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 #include "brw_defines.h"
00033 #include "brw_context.h"
00034 #include "brw_eu.h"
00035 #include "brw_util.h"
00036 #include "brw_clip.h"
00037 
00038 
00039 
00040 static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
00041 {
00042    unsigned i = 0,j;
00043 
00044    /* Register usage is static, precompute here:
00045     */
00046    c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
00047 
00048    if (c->key.nr_userclip) {
00049       c->reg.fixed_planes = brw_vec4_grf(i, 0);
00050       i += (6 + c->key.nr_userclip + 1) / 2;
00051 
00052       c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
00053    }
00054    else
00055       c->prog_data.curb_read_length = 0;
00056 
00057 
00058    /* Payload vertices plus space for more generated vertices:
00059     */
00060    for (j = 0; j < 4; j++) {
00061       c->reg.vertex[j] = brw_vec4_grf(i, 0);
00062       i += c->nr_regs;
00063    }
00064 
00065    c->reg.t           = brw_vec1_grf(i, 0);
00066    c->reg.t0          = brw_vec1_grf(i, 1);
00067    c->reg.t1          = brw_vec1_grf(i, 2);
00068    c->reg.planemask   = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
00069    c->reg.plane_equation = brw_vec4_grf(i, 4);
00070    i++;
00071 
00072    c->reg.dp0         = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
00073    c->reg.dp1         = brw_vec1_grf(i, 4);
00074    i++;
00075 
00076    if (!c->key.nr_userclip) {
00077       c->reg.fixed_planes = brw_vec8_grf(i, 0);
00078       i++;
00079    }
00080 
00081 
00082    c->first_tmp = i;
00083    c->last_tmp = i;
00084 
00085    c->prog_data.urb_read_length = c->nr_regs; /* ? */
00086    c->prog_data.total_grf = i;
00087 }
00088 
00089 
00090 
00091 /* Line clipping, more or less following the following algorithm:
00092  *
00093  *  for (p=0;p<MAX_PLANES;p++) {
00094  *     if (clipmask & (1 << p)) {
00095  *        float dp0 = DOTPROD( vtx0, plane[p] );
00096  *        float dp1 = DOTPROD( vtx1, plane[p] );
00097  *
00098  *        if (IS_NEGATIVE(dp1)) {
00099  *           float t = dp1 / (dp1 - dp0);
00100  *           if (t > t1) t1 = t;
00101  *        } else {
00102  *           float t = dp0 / (dp0 - dp1);
00103  *           if (t > t0) t0 = t;
00104  *        }
00105  *
00106  *        if (t0 + t1 >= 1.0)
00107  *           return;
00108  *     }
00109  *  }
00110  *
00111  *  interp( ctx, newvtx0, vtx0, vtx1, t0 );
00112  *  interp( ctx, newvtx1, vtx1, vtx0, t1 );
00113  *
00114  */
00115 static void clip_and_emit_line( struct brw_clip_compile *c )
00116 {
00117    struct brw_compile *p = &c->func;
00118    struct brw_indirect vtx0     = brw_indirect(0, 0);
00119    struct brw_indirect vtx1      = brw_indirect(1, 0);
00120    struct brw_indirect newvtx0   = brw_indirect(2, 0);
00121    struct brw_indirect newvtx1   = brw_indirect(3, 0);
00122    struct brw_indirect plane_ptr = brw_indirect(4, 0);
00123    struct brw_instruction *plane_loop;
00124    struct brw_instruction *plane_active;
00125    struct brw_instruction *is_negative;
00126    struct brw_instruction *is_neg2;
00127    struct brw_instruction *not_culled;
00128    struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
00129 
00130    brw_MOV(p, get_addr_reg(vtx0),      brw_address(c->reg.vertex[0]));
00131    brw_MOV(p, get_addr_reg(vtx1),      brw_address(c->reg.vertex[1]));
00132    brw_MOV(p, get_addr_reg(newvtx0),   brw_address(c->reg.vertex[2]));
00133    brw_MOV(p, get_addr_reg(newvtx1),   brw_address(c->reg.vertex[3]));
00134    brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
00135 
00136    /* Note: init t0, t1 together:
00137     */
00138    brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
00139 
00140    brw_clip_init_planes(c);
00141    brw_clip_init_clipmask(c);
00142 
00143    /* -ve rhw workaround */
00144    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
00145    brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
00146            brw_imm_ud(1<<20));
00147    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
00148    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00149 
00150    plane_loop = brw_DO(p, BRW_EXECUTE_1);
00151    {
00152       /* if (planemask & 1)
00153        */
00154       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
00155       brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
00156 
00157       plane_active = brw_IF(p, BRW_EXECUTE_1);
00158       {
00159          if (c->key.nr_userclip)
00160             brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
00161          else
00162             brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
00163 
00164 #if 0
00165          /* dp = DP4(vtx->position, plane)
00166           */
00167          brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
00168 
00169          /* if (IS_NEGATIVE(dp1))
00170           */
00171          brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
00172          brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
00173 #else
00174          #warning "disabled"
00175 #endif
00176          is_negative = brw_IF(p, BRW_EXECUTE_1);
00177          {
00178             brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
00179             brw_math_invert(p, c->reg.t, c->reg.t);
00180             brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
00181 
00182             brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
00183             brw_MOV(p, c->reg.t1, c->reg.t);
00184             brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00185          }
00186          is_negative = brw_ELSE(p, is_negative);
00187          {
00188             /* Coming back in.  We know that both cannot be negative
00189              * because the line would have been culled in that case.
00190              */
00191 
00192             /* If both are positive, do nothing */
00193              brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
00194              is_neg2 = brw_IF(p, BRW_EXECUTE_1);
00195              {
00196                 brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
00197                 brw_math_invert(p, c->reg.t, c->reg.t);
00198                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
00199 
00200                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
00201                 brw_MOV(p, c->reg.t0, c->reg.t);
00202                 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00203              }
00204              brw_ENDIF(p, is_neg2);
00205          }
00206          brw_ENDIF(p, is_negative);
00207       }
00208       brw_ENDIF(p, plane_active);
00209 
00210       /* plane_ptr++;
00211        */
00212       brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
00213 
00214       /* while (planemask>>=1) != 0
00215        */
00216       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
00217       brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
00218    }
00219    brw_WHILE(p, plane_loop);
00220 
00221    brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
00222    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
00223    not_culled = brw_IF(p, BRW_EXECUTE_1);
00224    {
00225       brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, FALSE);
00226       brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, FALSE);
00227 
00228       brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
00229       brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END);
00230    }
00231    brw_ENDIF(p, not_culled);
00232    brw_clip_kill_thread(c);
00233 }
00234 
00235 
00236 
00237 void brw_emit_line_clip( struct brw_clip_compile *c )
00238 {
00239    brw_clip_line_alloc_regs(c);
00240 
00241    if (c->key.do_flat_shading)
00242       brw_clip_copy_colors(c, 0, 1);
00243 
00244    clip_and_emit_line(c);
00245 }

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