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