brw_clip_util.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_clip.h"
00038 
00039 
00040 
00041 
00042 
00043 static struct brw_reg get_tmp( struct brw_clip_compile *c )
00044 {
00045    struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
00046 
00047    if (++c->last_tmp > c->prog_data.total_grf)
00048       c->prog_data.total_grf = c->last_tmp;
00049 
00050    return tmp;
00051 }
00052 
00053 static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp )
00054 {
00055    if (tmp.nr == c->last_tmp-1)
00056       c->last_tmp--;
00057 }
00058 
00059 
00060 static struct brw_reg make_plane_ud(unsigned x, unsigned y, unsigned z, unsigned w)
00061 {
00062    return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x);
00063 }
00064 
00065 
00066 void brw_clip_init_planes( struct brw_clip_compile *c )
00067 {
00068    struct brw_compile *p = &c->func;
00069 
00070    if (!c->key.nr_userclip) {
00071       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0,    0, 0xff, 1));
00072       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0,    0,    1, 1));
00073       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff,    0, 1));
00074       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0,    1,    0, 1));
00075       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff,  0,    0, 1));
00076       brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1,    0,    0, 1));
00077    }
00078 }
00079 
00080 
00081 
00082 #define W 3
00083 
00084 /* Project 'pos' to screen space (or back again), overwrite with results:
00085  */
00086 static void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos )
00087 {
00088    struct brw_compile *p = &c->func;
00089 
00090    /* calc rhw
00091     */
00092    brw_math_invert(p, get_element(pos, W), get_element(pos, W));
00093 
00094    /* value.xyz *= value.rhw
00095     */
00096    brw_set_access_mode(p, BRW_ALIGN_16);
00097    brw_MUL(p, brw_writemask(pos, TGSI_WRITEMASK_XYZ), pos, brw_swizzle1(pos, W));
00098    brw_set_access_mode(p, BRW_ALIGN_1);
00099 }
00100 
00101 
00102 static void brw_clip_project_vertex( struct brw_clip_compile *c,
00103                                      struct brw_indirect vert_addr )
00104 {
00105 #if 0
00106    struct brw_compile *p = &c->func;
00107    struct brw_reg tmp = get_tmp(c);
00108 
00109    /* Fixup position.  Extract from the original vertex and re-project
00110     * to screen space:
00111     */
00112    brw_MOV(p, tmp, deref_4f(vert_addr, c->offset[VERT_RESULT_HPOS]));
00113    brw_clip_project_position(c, tmp);
00114    brw_MOV(p, deref_4f(vert_addr, c->header_position_offset), tmp);
00115 
00116    release_tmp(c, tmp);
00117 #else
00118          #warning "disabled"
00119 #endif
00120 }
00121 
00122 
00123 
00124 
00125 /* Interpolate between two vertices and put the result into a0.0.
00126  * Increment a0.0 accordingly.
00127  */
00128 void brw_clip_interp_vertex( struct brw_clip_compile *c,
00129                              struct brw_indirect dest_ptr,
00130                              struct brw_indirect v0_ptr, /* from */
00131                              struct brw_indirect v1_ptr, /* to */
00132                              struct brw_reg t0,
00133                              boolean force_edgeflag)
00134 {
00135 #if 0
00136    struct brw_compile *p = &c->func;
00137    struct brw_reg tmp = get_tmp(c);
00138    unsigned i;
00139 
00140    /* Just copy the vertex header:
00141     */
00142    brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
00143 
00144    /* Iterate over each attribute (could be done in pairs?)
00145     */
00146    for (i = 0; i < c->nr_attrs; i++) {
00147       unsigned delta = i*16 + 32;
00148 
00149       if (delta == c->offset[VERT_RESULT_EDGE]) {
00150          if (force_edgeflag)
00151             brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
00152          else
00153             brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta));
00154       }
00155       else {
00156          /* Interpolate:
00157           *
00158           *        New = attr0 + t*attr1 - t*attr0
00159           */
00160          brw_MUL(p,
00161                  vec4(brw_null_reg()),
00162                  deref_4f(v1_ptr, delta),
00163                  t0);
00164 
00165          brw_MAC(p,
00166                  tmp,
00167                  negate(deref_4f(v0_ptr, delta)),
00168                  t0);
00169 
00170          brw_ADD(p,
00171                  deref_4f(dest_ptr, delta),
00172                  deref_4f(v0_ptr, delta),
00173                  tmp);
00174       }
00175    }
00176 
00177    if (i & 1) {
00178       unsigned delta = i*16 + 32;
00179       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
00180    }
00181 
00182    release_tmp(c, tmp);
00183 
00184    /* Recreate the projected (NDC) coordinate in the new vertex
00185     * header:
00186     */
00187    brw_clip_project_vertex(c, dest_ptr );
00188 #else
00189          #warning "disabled"
00190 #endif
00191 }
00192 
00193 
00194 
00195 
00196 #define MAX_MRF 16
00197 
00198 void brw_clip_emit_vue(struct brw_clip_compile *c,
00199                        struct brw_indirect vert,
00200                        boolean allocate,
00201                        boolean eot,
00202                        unsigned header)
00203 {
00204    struct brw_compile *p = &c->func;
00205    unsigned start = c->last_mrf;
00206 
00207    assert(!(allocate && eot));
00208 
00209    /* Cycle through mrf regs - probably futile as we have to wait for
00210     * the allocation response anyway.  Also, the order this function
00211     * is invoked doesn't correspond to the order the instructions will
00212     * be executed, so it won't have any effect in many cases.
00213     */
00214 #if 0
00215    if (start + c->nr_regs + 1 >= MAX_MRF)
00216       start = 0;
00217 
00218    c->last_mrf = start + c->nr_regs + 1;
00219 #endif
00220 
00221    /* Copy the vertex from vertn into m1..mN+1:
00222     */
00223    brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs);
00224 
00225    /* Overwrite PrimType and PrimStart in the message header, for
00226     * each vertex in turn:
00227     */
00228    brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
00229 
00230 
00231    /* Send each vertex as a seperate write to the urb.  This
00232     * is different to the concept in brw_sf_emit.c, where
00233     * subsequent writes are used to build up a single urb
00234     * entry.  Each of these writes instantiates a seperate
00235     * urb entry - (I think... what about 'allocate'?)
00236     */
00237    brw_urb_WRITE(p,
00238                  allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
00239                  start,
00240                  c->reg.R0,
00241                  allocate,
00242                  1,             /* used */
00243                  c->nr_regs + 1, /* msg length */
00244                  allocate ? 1 : 0, /* response_length */
00245                  eot,           /* eot */
00246                  1,             /* writes_complete */
00247                  0,             /* urb offset */
00248                  BRW_URB_SWIZZLE_NONE);
00249 }
00250 
00251 
00252 
00253 void brw_clip_kill_thread(struct brw_clip_compile *c)
00254 {
00255    struct brw_compile *p = &c->func;
00256 
00257    /* Send an empty message to kill the thread and release any
00258     * allocated urb entry:
00259     */
00260    brw_urb_WRITE(p,
00261                  retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
00262                  0,
00263                  c->reg.R0,
00264                  0,             /* allocate */
00265                  0,             /* used */
00266                  0,             /* msg len */
00267                  0,             /* response len */
00268                  1,             /* eot */
00269                  1,             /* writes complete */
00270                  0,
00271                  BRW_URB_SWIZZLE_NONE);
00272 }
00273 
00274 
00275 
00276 
00277 struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
00278 {
00279    return brw_address(c->reg.fixed_planes);
00280 }
00281 
00282 
00283 struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c )
00284 {
00285    if (c->key.nr_userclip) {
00286       return brw_imm_uw(16);
00287    }
00288    else {
00289       return brw_imm_uw(4);
00290    }
00291 }
00292 
00293 
00294 /* If flatshading, distribute color from provoking vertex prior to
00295  * clipping.
00296  */
00297 void brw_clip_copy_colors( struct brw_clip_compile *c,
00298                            unsigned to, unsigned from )
00299 {
00300 #if 0
00301    struct brw_compile *p = &c->func;
00302 
00303    if (c->offset[VERT_RESULT_COL0])
00304       brw_MOV(p,
00305               byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL0]),
00306               byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL0]));
00307 
00308    if (c->offset[VERT_RESULT_COL1])
00309       brw_MOV(p,
00310               byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL1]),
00311               byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL1]));
00312 
00313    if (c->offset[VERT_RESULT_BFC0])
00314       brw_MOV(p,
00315               byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC0]),
00316               byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC0]));
00317 
00318    if (c->offset[VERT_RESULT_BFC1])
00319       brw_MOV(p,
00320               byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC1]),
00321               byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC1]));
00322 #else
00323          #warning "disabled"
00324 #endif
00325 }
00326 
00327 
00328 
00329 void brw_clip_init_clipmask( struct brw_clip_compile *c )
00330 {
00331    struct brw_compile *p = &c->func;
00332    struct brw_reg incoming = get_element_ud(c->reg.R0, 2);
00333 
00334    /* Shift so that lowest outcode bit is rightmost:
00335     */
00336    brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
00337 
00338    if (c->key.nr_userclip) {
00339       struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
00340 
00341       /* Rearrange userclip outcodes so that they come directly after
00342        * the fixed plane bits.
00343        */
00344       brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14));
00345       brw_SHR(p, tmp, tmp, brw_imm_ud(8));
00346       brw_OR(p, c->reg.planemask, c->reg.planemask, tmp);
00347 
00348       release_tmp(c, tmp);
00349    }
00350 }
00351 

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