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