Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2 
      3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
      4                      VA Linux Systems Inc., Fremont, California.
      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  *   Kevin E. Martin <martin (at) valinux.com>
     33  *   Gareth Hughes <gareth (at) valinux.com>
     34  *   Keith Whitwell <keithw (at) vmware.com>
     35  */
     36 
     37 #include <stdbool.h>
     38 #include "main/glheader.h"
     39 #include "main/api_arrayelt.h"
     40 #include "main/api_exec.h"
     41 #include "main/context.h"
     42 #include "util/simple_list.h"
     43 #include "main/imports.h"
     44 #include "main/extensions.h"
     45 #include "main/version.h"
     46 #include "main/vtxfmt.h"
     47 
     48 #include "swrast/swrast.h"
     49 #include "swrast_setup/swrast_setup.h"
     50 #include "vbo/vbo.h"
     51 
     52 #include "tnl/tnl.h"
     53 #include "tnl/t_pipeline.h"
     54 
     55 #include "drivers/common/driverfuncs.h"
     56 
     57 #include "radeon_common.h"
     58 #include "radeon_context.h"
     59 #include "radeon_ioctl.h"
     60 #include "radeon_state.h"
     61 #include "radeon_span.h"
     62 #include "radeon_tex.h"
     63 #include "radeon_swtcl.h"
     64 #include "radeon_tcl.h"
     65 #include "radeon_queryobj.h"
     66 #include "radeon_blit.h"
     67 #include "radeon_fog.h"
     68 
     69 #include "utils.h"
     70 #include "xmlpool.h" /* for symbolic values of enum-type options */
     71 
     72 extern const struct tnl_pipeline_stage _radeon_render_stage;
     73 extern const struct tnl_pipeline_stage _radeon_tcl_stage;
     74 
     75 static const struct tnl_pipeline_stage *radeon_pipeline[] = {
     76 
     77    /* Try and go straight to t&l
     78     */
     79    &_radeon_tcl_stage,
     80 
     81    /* Catch any t&l fallbacks
     82     */
     83    &_tnl_vertex_transform_stage,
     84    &_tnl_normal_transform_stage,
     85    &_tnl_lighting_stage,
     86    &_tnl_fog_coordinate_stage,
     87    &_tnl_texgen_stage,
     88    &_tnl_texture_transform_stage,
     89 
     90    &_radeon_render_stage,
     91    &_tnl_render_stage,		/* FALLBACK:  */
     92    NULL,
     93 };
     94 
     95 static void r100_vtbl_pre_emit_state(radeonContextPtr radeon)
     96 {
     97    r100ContextPtr rmesa = (r100ContextPtr)radeon;
     98 
     99    /* r100 always needs to emit ZBS to avoid TCL lockups */
    100    rmesa->hw.zbs.dirty = 1;
    101    radeon->hw.is_dirty = 1;
    102 }
    103 
    104 static void r100_vtbl_free_context(struct gl_context *ctx)
    105 {
    106    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    107    _mesa_vector4f_free( &rmesa->tcl.ObjClean );
    108 }
    109 
    110 static void r100_emit_query_finish(radeonContextPtr radeon)
    111 {
    112    BATCH_LOCALS(radeon);
    113    struct radeon_query_object *query = radeon->query.current;
    114 
    115    BEGIN_BATCH(4);
    116    OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
    117    OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
    118    END_BATCH();
    119    query->curr_offset += sizeof(uint32_t);
    120    assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
    121    query->emitted_begin = GL_FALSE;
    122 }
    123 
    124 static void r100_init_vtbl(radeonContextPtr radeon)
    125 {
    126    radeon->vtbl.swtcl_flush = r100_swtcl_flush;
    127    radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state;
    128    radeon->vtbl.fallback = radeonFallback;
    129    radeon->vtbl.free_context = r100_vtbl_free_context;
    130    radeon->vtbl.emit_query_finish = r100_emit_query_finish;
    131    radeon->vtbl.check_blit = r100_check_blit;
    132    radeon->vtbl.blit = r100_blit;
    133    radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
    134    radeon->vtbl.revalidate_all_buffers = r100ValidateBuffers;
    135 }
    136 
    137 /* Create the device specific context.
    138  */
    139 GLboolean
    140 r100CreateContext( gl_api api,
    141 		   const struct gl_config *glVisual,
    142 		   __DRIcontext *driContextPriv,
    143 		   unsigned major_version,
    144 		   unsigned minor_version,
    145 		   uint32_t flags,
    146                    bool notify_reset,
    147 		   unsigned *error,
    148 		   void *sharedContextPrivate)
    149 {
    150    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    151    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
    152    struct dd_function_table functions;
    153    r100ContextPtr rmesa;
    154    struct gl_context *ctx;
    155    int i;
    156    int tcl_mode, fthrottle_mode;
    157 
    158    if (flags & ~__DRI_CTX_FLAG_DEBUG) {
    159       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
    160       return false;
    161    }
    162 
    163    if (notify_reset) {
    164       *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
    165       return false;
    166    }
    167 
    168    assert(glVisual);
    169    assert(driContextPriv);
    170    assert(screen);
    171 
    172    /* Allocate the Radeon context */
    173    rmesa = calloc(1, sizeof(*rmesa));
    174    if ( !rmesa ) {
    175       *error = __DRI_CTX_ERROR_NO_MEMORY;
    176       return GL_FALSE;
    177    }
    178 
    179    rmesa->radeon.radeonScreen = screen;
    180    r100_init_vtbl(&rmesa->radeon);
    181 
    182    /* init exp fog table data */
    183    radeonInitStaticFogData();
    184 
    185    /* Parse configuration files.
    186     * Do this here so that initialMaxAnisotropy is set before we create
    187     * the default textures.
    188     */
    189    driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
    190 			screen->driScreen->myNum, "radeon");
    191    rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
    192                                                  "def_max_anisotropy");
    193 
    194    if (driQueryOptionb(&rmesa->radeon.optionCache, "hyperz"))
    195       rmesa->using_hyperz = GL_TRUE;
    196 
    197    /* Init default driver functions then plug in our Radeon-specific functions
    198     * (the texture functions are especially important)
    199     */
    200    _mesa_init_driver_functions( &functions );
    201    radeonInitTextureFuncs( &rmesa->radeon, &functions );
    202    radeonInitQueryObjFunctions(&functions);
    203 
    204    if (!radeonInitContext(&rmesa->radeon, api, &functions,
    205 			  glVisual, driContextPriv,
    206 			  sharedContextPrivate)) {
    207      free(rmesa);
    208      *error = __DRI_CTX_ERROR_NO_MEMORY;
    209      return GL_FALSE;
    210    }
    211 
    212    rmesa->radeon.swtcl.RenderIndex = ~0;
    213    rmesa->radeon.hw.all_dirty = GL_TRUE;
    214 
    215    ctx = &rmesa->radeon.glCtx;
    216 
    217    driContextSetFlags(ctx, flags);
    218 
    219    /* Initialize the software rasterizer and helper modules.
    220     */
    221    _swrast_CreateContext( ctx );
    222    _vbo_CreateContext( ctx );
    223    _tnl_CreateContext( ctx );
    224    _swsetup_CreateContext( ctx );
    225    _ae_create_context( ctx );
    226 
    227    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
    228 						 "texture_units");
    229    ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
    230    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
    231    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
    232 
    233    ctx->Const.StripTextureBorder = GL_TRUE;
    234 
    235    /* FIXME: When no memory manager is available we should set this
    236     * to some reasonable value based on texture memory pool size */
    237    ctx->Const.MaxTextureLevels = 12;
    238    ctx->Const.Max3DTextureLevels = 9;
    239    ctx->Const.MaxCubeTextureLevels = 12;
    240    ctx->Const.MaxTextureRectSize = 2048;
    241 
    242    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
    243 
    244    /* No wide points.
    245     */
    246    ctx->Const.MinPointSize = 1.0;
    247    ctx->Const.MinPointSizeAA = 1.0;
    248    ctx->Const.MaxPointSize = 1.0;
    249    ctx->Const.MaxPointSizeAA = 1.0;
    250 
    251    ctx->Const.MinLineWidth = 1.0;
    252    ctx->Const.MinLineWidthAA = 1.0;
    253    ctx->Const.MaxLineWidth = 10.0;
    254    ctx->Const.MaxLineWidthAA = 10.0;
    255    ctx->Const.LineWidthGranularity = 0.0625;
    256 
    257    /* Set maxlocksize (and hence vb size) small enough to avoid
    258     * fallbacks in radeon_tcl.c.  ie. guarentee that all vertices can
    259     * fit in a single dma buffer for indexed rendering of quad strips,
    260     * etc.
    261     */
    262    ctx->Const.MaxArrayLockSize =
    263       MIN2( ctx->Const.MaxArrayLockSize,
    264  	    RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE );
    265 
    266    rmesa->boxes = 0;
    267 
    268    ctx->Const.MaxDrawBuffers = 1;
    269    ctx->Const.MaxColorAttachments = 1;
    270    ctx->Const.MaxRenderbufferSize = 2048;
    271 
    272    ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
    273 
    274    /* Install the customized pipeline:
    275     */
    276    _tnl_destroy_pipeline( ctx );
    277    _tnl_install_pipeline( ctx, radeon_pipeline );
    278 
    279    /* Try and keep materials and vertices separate:
    280     */
    281 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
    282 
    283    /* Configure swrast and T&L to match hardware characteristics:
    284     */
    285    _swrast_allow_pixel_fog( ctx, GL_FALSE );
    286    _swrast_allow_vertex_fog( ctx, GL_TRUE );
    287    _tnl_allow_pixel_fog( ctx, GL_FALSE );
    288    _tnl_allow_vertex_fog( ctx, GL_TRUE );
    289 
    290 
    291    for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
    292       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
    293       _math_matrix_ctr( &rmesa->tmpmat[i] );
    294       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
    295       _math_matrix_set_identity( &rmesa->tmpmat[i] );
    296    }
    297 
    298    ctx->Extensions.ARB_occlusion_query = true;
    299    ctx->Extensions.ARB_texture_border_clamp = true;
    300    ctx->Extensions.ARB_texture_cube_map = true;
    301    ctx->Extensions.ARB_texture_env_combine = true;
    302    ctx->Extensions.ARB_texture_env_crossbar = true;
    303    ctx->Extensions.ARB_texture_env_dot3 = true;
    304    ctx->Extensions.ARB_texture_mirror_clamp_to_edge = true;
    305    ctx->Extensions.ATI_texture_env_combine3 = true;
    306    ctx->Extensions.ATI_texture_mirror_once = true;
    307    ctx->Extensions.EXT_texture_env_dot3 = true;
    308    ctx->Extensions.EXT_texture_filter_anisotropic = true;
    309    ctx->Extensions.EXT_texture_mirror_clamp = true;
    310    ctx->Extensions.MESA_ycbcr_texture = true;
    311    ctx->Extensions.NV_texture_rectangle = true;
    312    ctx->Extensions.OES_EGL_image = true;
    313 
    314    if (rmesa->radeon.glCtx.Mesa_DXTn) {
    315       ctx->Extensions.EXT_texture_compression_s3tc = true;
    316       ctx->Extensions.ANGLE_texture_compression_dxt = true;
    317    }
    318    else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
    319       ctx->Extensions.EXT_texture_compression_s3tc = true;
    320       ctx->Extensions.ANGLE_texture_compression_dxt = true;
    321    }
    322 
    323    /* XXX these should really go right after _mesa_init_driver_functions() */
    324    radeon_fbo_init(&rmesa->radeon);
    325    radeonInitSpanFuncs( ctx );
    326    radeonInitIoctlFuncs( ctx );
    327    radeonInitStateFuncs( ctx );
    328    radeonInitState( rmesa );
    329    radeonInitSwtcl( ctx );
    330 
    331    _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0,
    332 			 ctx->Const.MaxArrayLockSize, 32 );
    333 
    334    fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode");
    335    rmesa->radeon.iw.irq_seq = -1;
    336    rmesa->radeon.irqsEmitted = 0;
    337    rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 &&
    338 			    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
    339 
    340    rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
    341 
    342 
    343 #if DO_DEBUG
    344    RADEON_DEBUG = parse_debug_string( getenv( "RADEON_DEBUG" ),
    345                                       debug_control );
    346 #endif
    347 
    348    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
    349    if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
    350       fprintf(stderr, "disabling 3D acceleration\n");
    351       FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
    352    } else if (tcl_mode == DRI_CONF_TCL_SW ||
    353 	      !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
    354       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
    355 	 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
    356 	 fprintf(stderr, "Disabling HW TCL support\n");
    357       }
    358       TCL_FALLBACK(&rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
    359    }
    360 
    361    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
    362 /*       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
    363    }
    364 
    365    _mesa_compute_version(ctx);
    366 
    367    /* Exec table initialization requires the version to be computed */
    368    _mesa_initialize_dispatch_tables(ctx);
    369    _mesa_initialize_vbo_vtxfmt(ctx);
    370 
    371    *error = __DRI_CTX_ERROR_SUCCESS;
    372    return GL_TRUE;
    373 }
    374