Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2 
      3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
      4                      Tungsten Graphics Inc., Austin, Texas.
      5 
      6 All Rights Reserved.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining
      9 a copy of this software and associated documentation files (the
     10 "Software"), to deal in the Software without restriction, including
     11 without limitation the rights to use, copy, modify, merge, publish,
     12 distribute, sublicense, and/or sell copies of the Software, and to
     13 permit persons to whom the Software is furnished to do so, subject to
     14 the following conditions:
     15 
     16 The above copyright notice and this permission notice (including the
     17 next paragraph) shall be included in all copies or substantial
     18 portions of the Software.
     19 
     20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     27 
     28 **************************************************************************/
     29 
     30 /*
     31  * Authors:
     32  *   Keith Whitwell <keith (at) tungstengraphics.com>
     33  */
     34 
     35 #include "main/glheader.h"
     36 #include "main/imports.h"
     37 #include "main/mtypes.h"
     38 
     39 #include "vbo/vbo.h"
     40 #include "math/m_translate.h"
     41 #include "tnl/tnl.h"
     42 #include "tnl/t_pipeline.h"
     43 #include "radeon_context.h"
     44 #include "radeon_state.h"
     45 #include "radeon_ioctl.h"
     46 #include "radeon_tex.h"
     47 #include "radeon_tcl.h"
     48 #include "radeon_swtcl.h"
     49 #include "radeon_maos.h"
     50 #include "radeon_fog.h"
     51 
     52 #define RADEON_TCL_MAX_SETUP 19
     53 
     54 union emit_union { float f; GLuint ui; radeon_color_t rgba; };
     55 
     56 static struct {
     57    void   (*emit)( struct gl_context *, GLuint, GLuint, void * );
     58    GLuint vertex_size;
     59    GLuint vertex_format;
     60 } setup_tab[RADEON_TCL_MAX_SETUP];
     61 
     62 #define DO_W    (IND & RADEON_CP_VC_FRMT_W0)
     63 #define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR)
     64 #define DO_SPEC_OR_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
     65 #define DO_SPEC ((IND & RADEON_CP_VC_FRMT_PKSPEC) && \
     66 		 (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
     67 #define DO_FOG  ((IND & RADEON_CP_VC_FRMT_PKSPEC) && ctx->Fog.Enabled && \
     68 		 (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))
     69 #define DO_TEX0 (IND & RADEON_CP_VC_FRMT_ST0)
     70 #define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1)
     71 #define DO_TEX2 (IND & RADEON_CP_VC_FRMT_ST2)
     72 #define DO_PTEX (IND & RADEON_CP_VC_FRMT_Q0)
     73 #define DO_NORM (IND & RADEON_CP_VC_FRMT_N0)
     74 
     75 #define DO_TEX3 0
     76 
     77 #define GET_TEXSOURCE(n)  n
     78 
     79 /***********************************************************************
     80  *             Generate vertex emit functions               *
     81  ***********************************************************************/
     82 
     83 
     84 /* Defined in order of increasing vertex size:
     85  */
     86 #define IDX 0
     87 #define IND (RADEON_CP_VC_FRMT_XY|		\
     88 	     RADEON_CP_VC_FRMT_Z|		\
     89 	     RADEON_CP_VC_FRMT_PKCOLOR)
     90 #define TAG(x) x##_rgba
     91 #include "radeon_maos_vbtmp.h"
     92 
     93 #define IDX 1
     94 #define IND (RADEON_CP_VC_FRMT_XY|		\
     95 	     RADEON_CP_VC_FRMT_Z|		\
     96 	     RADEON_CP_VC_FRMT_N0)
     97 #define TAG(x) x##_n
     98 #include "radeon_maos_vbtmp.h"
     99 
    100 #define IDX 2
    101 #define IND (RADEON_CP_VC_FRMT_XY|		\
    102 	     RADEON_CP_VC_FRMT_Z|		\
    103 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    104 	     RADEON_CP_VC_FRMT_ST0)
    105 #define TAG(x) x##_rgba_st
    106 #include "radeon_maos_vbtmp.h"
    107 
    108 #define IDX 3
    109 #define IND (RADEON_CP_VC_FRMT_XY|		\
    110 	     RADEON_CP_VC_FRMT_Z|		\
    111 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    112 	     RADEON_CP_VC_FRMT_N0)
    113 #define TAG(x) x##_rgba_n
    114 #include "radeon_maos_vbtmp.h"
    115 
    116 #define IDX 4
    117 #define IND (RADEON_CP_VC_FRMT_XY|		\
    118 	     RADEON_CP_VC_FRMT_Z|		\
    119 	     RADEON_CP_VC_FRMT_ST0|		\
    120 	     RADEON_CP_VC_FRMT_N0)
    121 #define TAG(x) x##_st_n
    122 #include "radeon_maos_vbtmp.h"
    123 
    124 #define IDX 5
    125 #define IND (RADEON_CP_VC_FRMT_XY|		\
    126 	     RADEON_CP_VC_FRMT_Z|		\
    127 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    128 	     RADEON_CP_VC_FRMT_ST0|		\
    129 	     RADEON_CP_VC_FRMT_ST1)
    130 #define TAG(x) x##_rgba_st_st
    131 #include "radeon_maos_vbtmp.h"
    132 
    133 #define IDX 6
    134 #define IND (RADEON_CP_VC_FRMT_XY|		\
    135 	     RADEON_CP_VC_FRMT_Z|		\
    136 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    137 	     RADEON_CP_VC_FRMT_ST0|		\
    138 	     RADEON_CP_VC_FRMT_N0)
    139 #define TAG(x) x##_rgba_st_n
    140 #include "radeon_maos_vbtmp.h"
    141 
    142 #define IDX 7
    143 #define IND (RADEON_CP_VC_FRMT_XY|		\
    144 	     RADEON_CP_VC_FRMT_Z|		\
    145 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    146 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    147 	     RADEON_CP_VC_FRMT_ST0|		\
    148 	     RADEON_CP_VC_FRMT_ST1)
    149 #define TAG(x) x##_rgba_spec_st_st
    150 #include "radeon_maos_vbtmp.h"
    151 
    152 #define IDX 8
    153 #define IND (RADEON_CP_VC_FRMT_XY|		\
    154 	     RADEON_CP_VC_FRMT_Z|		\
    155 	     RADEON_CP_VC_FRMT_ST0|		\
    156 	     RADEON_CP_VC_FRMT_ST1|		\
    157 	     RADEON_CP_VC_FRMT_N0)
    158 #define TAG(x) x##_st_st_n
    159 #include "radeon_maos_vbtmp.h"
    160 
    161 #define IDX 9
    162 #define IND (RADEON_CP_VC_FRMT_XY|		\
    163 	     RADEON_CP_VC_FRMT_Z|		\
    164 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    165 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    166 	     RADEON_CP_VC_FRMT_ST0|		\
    167 	     RADEON_CP_VC_FRMT_ST1|		\
    168 	     RADEON_CP_VC_FRMT_N0)
    169 #define TAG(x) x##_rgba_spec_st_st_n
    170 #include "radeon_maos_vbtmp.h"
    171 
    172 #define IDX 10
    173 #define IND (RADEON_CP_VC_FRMT_XY|		\
    174 	     RADEON_CP_VC_FRMT_Z|		\
    175 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    176 	     RADEON_CP_VC_FRMT_ST0|		\
    177 	     RADEON_CP_VC_FRMT_Q0)
    178 #define TAG(x) x##_rgba_stq
    179 #include "radeon_maos_vbtmp.h"
    180 
    181 #define IDX 11
    182 #define IND (RADEON_CP_VC_FRMT_XY|		\
    183 	     RADEON_CP_VC_FRMT_Z|		\
    184 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    185 	     RADEON_CP_VC_FRMT_ST1|		\
    186 	     RADEON_CP_VC_FRMT_Q1|		\
    187 	     RADEON_CP_VC_FRMT_ST0|		\
    188 	     RADEON_CP_VC_FRMT_Q0)
    189 #define TAG(x) x##_rgba_stq_stq
    190 #include "radeon_maos_vbtmp.h"
    191 
    192 #define IDX 12
    193 #define IND (RADEON_CP_VC_FRMT_XY|		\
    194 	     RADEON_CP_VC_FRMT_Z|		\
    195 	     RADEON_CP_VC_FRMT_W0|		\
    196 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    197 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    198 	     RADEON_CP_VC_FRMT_ST0|		\
    199 	     RADEON_CP_VC_FRMT_Q0|		\
    200 	     RADEON_CP_VC_FRMT_ST1|		\
    201 	     RADEON_CP_VC_FRMT_Q1|		\
    202 	     RADEON_CP_VC_FRMT_N0)
    203 #define TAG(x) x##_w_rgba_spec_stq_stq_n
    204 #include "radeon_maos_vbtmp.h"
    205 
    206 #define IDX 13
    207 #define IND (RADEON_CP_VC_FRMT_XY|		\
    208 	     RADEON_CP_VC_FRMT_Z|		\
    209 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    210 	     RADEON_CP_VC_FRMT_ST0|		\
    211 	     RADEON_CP_VC_FRMT_ST1|		\
    212 	     RADEON_CP_VC_FRMT_ST2)
    213 #define TAG(x) x##_rgba_st_st_st
    214 #include "radeon_maos_vbtmp.h"
    215 
    216 #define IDX 14
    217 #define IND (RADEON_CP_VC_FRMT_XY|		\
    218 	     RADEON_CP_VC_FRMT_Z|		\
    219 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    220 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    221 	     RADEON_CP_VC_FRMT_ST0|		\
    222 	     RADEON_CP_VC_FRMT_ST1|		\
    223 	     RADEON_CP_VC_FRMT_ST2)
    224 #define TAG(x) x##_rgba_spec_st_st_st
    225 #include "radeon_maos_vbtmp.h"
    226 
    227 #define IDX 15
    228 #define IND (RADEON_CP_VC_FRMT_XY|		\
    229 	     RADEON_CP_VC_FRMT_Z|		\
    230 	     RADEON_CP_VC_FRMT_ST0|		\
    231 	     RADEON_CP_VC_FRMT_ST1|		\
    232 	     RADEON_CP_VC_FRMT_ST2|		\
    233 	     RADEON_CP_VC_FRMT_N0)
    234 #define TAG(x) x##_st_st_st_n
    235 #include "radeon_maos_vbtmp.h"
    236 
    237 #define IDX 16
    238 #define IND (RADEON_CP_VC_FRMT_XY|		\
    239 	     RADEON_CP_VC_FRMT_Z|		\
    240 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    241 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    242 	     RADEON_CP_VC_FRMT_ST0|		\
    243 	     RADEON_CP_VC_FRMT_ST1|		\
    244 	     RADEON_CP_VC_FRMT_ST2|		\
    245 	     RADEON_CP_VC_FRMT_N0)
    246 #define TAG(x) x##_rgba_spec_st_st_st_n
    247 #include "radeon_maos_vbtmp.h"
    248 
    249 #define IDX 17
    250 #define IND (RADEON_CP_VC_FRMT_XY|		\
    251 	     RADEON_CP_VC_FRMT_Z|		\
    252 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    253 	     RADEON_CP_VC_FRMT_ST0|		\
    254 	     RADEON_CP_VC_FRMT_Q0|		\
    255 	     RADEON_CP_VC_FRMT_ST1|		\
    256 	     RADEON_CP_VC_FRMT_Q1|		\
    257 	     RADEON_CP_VC_FRMT_ST2|		\
    258 	     RADEON_CP_VC_FRMT_Q2)
    259 #define TAG(x) x##_rgba_stq_stq_stq
    260 #include "radeon_maos_vbtmp.h"
    261 
    262 #define IDX 18
    263 #define IND (RADEON_CP_VC_FRMT_XY|		\
    264 	     RADEON_CP_VC_FRMT_Z|		\
    265 	     RADEON_CP_VC_FRMT_W0|		\
    266 	     RADEON_CP_VC_FRMT_PKCOLOR|		\
    267 	     RADEON_CP_VC_FRMT_PKSPEC|		\
    268 	     RADEON_CP_VC_FRMT_ST0|		\
    269 	     RADEON_CP_VC_FRMT_Q0|		\
    270 	     RADEON_CP_VC_FRMT_ST1|		\
    271 	     RADEON_CP_VC_FRMT_Q1|		\
    272 	     RADEON_CP_VC_FRMT_ST2|		\
    273 	     RADEON_CP_VC_FRMT_Q2|		\
    274 	     RADEON_CP_VC_FRMT_N0)
    275 #define TAG(x) x##_w_rgba_spec_stq_stq_stq_n
    276 #include "radeon_maos_vbtmp.h"
    277 
    278 
    279 
    280 
    281 /***********************************************************************
    282  *                         Initialization
    283  ***********************************************************************/
    284 
    285 
    286 static void init_tcl_verts( void )
    287 {
    288    init_rgba();
    289    init_n();
    290    init_rgba_n();
    291    init_rgba_st();
    292    init_st_n();
    293    init_rgba_st_st();
    294    init_rgba_st_n();
    295    init_rgba_spec_st_st();
    296    init_st_st_n();
    297    init_rgba_spec_st_st_n();
    298    init_rgba_stq();
    299    init_rgba_stq_stq();
    300    init_w_rgba_spec_stq_stq_n();
    301    init_rgba_st_st_st();
    302    init_rgba_spec_st_st_st();
    303    init_st_st_st_n();
    304    init_rgba_spec_st_st_st_n();
    305    init_rgba_stq_stq_stq();
    306    init_w_rgba_spec_stq_stq_stq_n();
    307 }
    308 
    309 
    310 void radeonEmitArrays( struct gl_context *ctx, GLuint inputs )
    311 {
    312    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    313    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    314    GLuint req = 0;
    315    GLuint unit;
    316    GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
    317 		 ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1|RADEON_TCL_VTX_Q2));
    318    int i;
    319    static int firsttime = 1;
    320 
    321    if (firsttime) {
    322       init_tcl_verts();
    323       firsttime = 0;
    324    }
    325 
    326    if (1) {
    327       req |= RADEON_CP_VC_FRMT_Z;
    328       if (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 4) {
    329 	 req |= RADEON_CP_VC_FRMT_W0;
    330       }
    331    }
    332 
    333    if (inputs & VERT_BIT_NORMAL) {
    334       req |= RADEON_CP_VC_FRMT_N0;
    335    }
    336 
    337    if (inputs & VERT_BIT_COLOR0) {
    338       req |= RADEON_CP_VC_FRMT_PKCOLOR;
    339    }
    340 
    341    if (inputs & (VERT_BIT_COLOR1|VERT_BIT_FOG)) {
    342       req |= RADEON_CP_VC_FRMT_PKSPEC;
    343    }
    344 
    345    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
    346       if (inputs & VERT_BIT_TEX(unit)) {
    347 	 req |= RADEON_ST_BIT(unit);
    348 	 /* assume we need the 3rd coord if texgen is active for r/q OR at least
    349 	    3 coords are submitted. This may not be 100% correct */
    350 	 if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) {
    351 	    req |= RADEON_Q_BIT(unit);
    352 	    vtx |= RADEON_Q_BIT(unit);
    353 	 }
    354 	 if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
    355 	    vtx |= RADEON_Q_BIT(unit);
    356 	 else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) &&
    357 	          ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
    358 	    GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3);
    359 	    if (((rmesa->NeedTexMatrix >> unit) & 1) &&
    360 		 (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
    361 	       radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ;
    362 	 }
    363       }
    364    }
    365 
    366    if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
    367       RADEON_STATECHANGE( rmesa, tcl );
    368       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
    369    }
    370 
    371    for (i = 0 ; i < RADEON_TCL_MAX_SETUP ; i++)
    372       if ((setup_tab[i].vertex_format & req) == req)
    373 	 break;
    374 
    375    if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format &&
    376        rmesa->radeon.tcl.aos[0].bo)
    377       return;
    378 
    379    if (rmesa->radeon.tcl.aos[0].bo)
    380       radeonReleaseArrays( ctx, ~0 );
    381 
    382    radeonAllocDmaRegion( &rmesa->radeon,
    383 			 &rmesa->radeon.tcl.aos[0].bo,
    384 			 &rmesa->radeon.tcl.aos[0].offset,
    385 			 VB->Count * setup_tab[i].vertex_size * 4,
    386 			 4);
    387 
    388    /* The vertex code expects Obj to be clean to element 3.  To fix
    389     * this, add more vertex code (for obj-2, obj-3) or preferably move
    390     * to maos.
    391     */
    392    if (VB->AttribPtr[_TNL_ATTRIB_POS]->size < 3 ||
    393        (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 3 &&
    394 	(setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0))) {
    395 
    396       _math_trans_4f( rmesa->tcl.ObjClean.data,
    397 		      VB->AttribPtr[_TNL_ATTRIB_POS]->data,
    398 		      VB->AttribPtr[_TNL_ATTRIB_POS]->stride,
    399 		      GL_FLOAT,
    400 		      VB->AttribPtr[_TNL_ATTRIB_POS]->size,
    401 		      0,
    402 		      VB->Count );
    403 
    404       switch (VB->AttribPtr[_TNL_ATTRIB_POS]->size) {
    405       case 1:
    406 	    _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 1);
    407       case 2:
    408 	    _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 2);
    409       case 3:
    410 	 if (setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0) {
    411 	    _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 3);
    412 	 }
    413       case 4:
    414       default:
    415 	 break;
    416       }
    417 
    418       VB->AttribPtr[_TNL_ATTRIB_POS] = &rmesa->tcl.ObjClean;
    419    }
    420 
    421 
    422    radeon_bo_map(rmesa->radeon.tcl.aos[0].bo, 1);
    423    setup_tab[i].emit( ctx, 0, VB->Count,
    424 		      rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset);
    425    radeon_bo_unmap(rmesa->radeon.tcl.aos[0].bo);
    426    //   rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size;
    427    rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size;
    428    rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
    429    rmesa->radeon.tcl.aos_count = 1;
    430 }
    431 
    432 
    433