Home | History | Annotate | Download | only in r200
      1 /*
      2 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
      3 
      4 The Weather Channel (TM) funded Tungsten Graphics to develop the
      5 initial release of the Radeon 8500 driver under the XFree86 license.
      6 This notice must be preserved.
      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 <stdbool.h>
     36 #include "main/glheader.h"
     37 #include "main/api_arrayelt.h"
     38 #include "main/context.h"
     39 #include "main/simple_list.h"
     40 #include "main/imports.h"
     41 #include "main/extensions.h"
     42 #include "main/mfeatures.h"
     43 #include "main/version.h"
     44 
     45 #include "swrast/swrast.h"
     46 #include "swrast_setup/swrast_setup.h"
     47 #include "vbo/vbo.h"
     48 
     49 #include "tnl/tnl.h"
     50 #include "tnl/t_pipeline.h"
     51 
     52 #include "drivers/common/driverfuncs.h"
     53 
     54 #include "r200_context.h"
     55 #include "r200_ioctl.h"
     56 #include "r200_state.h"
     57 #include "r200_tex.h"
     58 #include "r200_swtcl.h"
     59 #include "r200_tcl.h"
     60 #include "r200_vertprog.h"
     61 #include "radeon_queryobj.h"
     62 #include "r200_blit.h"
     63 #include "radeon_fog.h"
     64 
     65 #include "radeon_span.h"
     66 
     67 #include "utils.h"
     68 #include "xmlpool.h" /* for symbolic values of enum-type options */
     69 
     70 /* Return various strings for glGetString().
     71  */
     72 static const GLubyte *r200GetString( struct gl_context *ctx, GLenum name )
     73 {
     74    r200ContextPtr rmesa = R200_CONTEXT(ctx);
     75    static char buffer[128];
     76    unsigned   offset;
     77    GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 :
     78       rmesa->radeon.radeonScreen->AGPMode;
     79 
     80    switch ( name ) {
     81    case GL_VENDOR:
     82       return (GLubyte *)"Tungsten Graphics, Inc.";
     83 
     84    case GL_RENDERER:
     85       offset = driGetRendererString( buffer, "R200", agp_mode );
     86 
     87       sprintf( & buffer[ offset ], " %sTCL",
     88 	       !(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
     89 	       ? "" : "NO-" );
     90 
     91       return (GLubyte *)buffer;
     92 
     93    default:
     94       return NULL;
     95    }
     96 }
     97 
     98 
     99 extern const struct tnl_pipeline_stage _r200_render_stage;
    100 extern const struct tnl_pipeline_stage _r200_tcl_stage;
    101 
    102 static const struct tnl_pipeline_stage *r200_pipeline[] = {
    103 
    104    /* Try and go straight to t&l
    105     */
    106    &_r200_tcl_stage,
    107 
    108    /* Catch any t&l fallbacks
    109     */
    110    &_tnl_vertex_transform_stage,
    111    &_tnl_normal_transform_stage,
    112    &_tnl_lighting_stage,
    113    &_tnl_fog_coordinate_stage,
    114    &_tnl_texgen_stage,
    115    &_tnl_texture_transform_stage,
    116    &_tnl_point_attenuation_stage,
    117    &_tnl_vertex_program_stage,
    118    /* Try again to go to tcl?
    119     *     - no good for asymmetric-twoside (do with multipass)
    120     *     - no good for asymmetric-unfilled (do with multipass)
    121     *     - good for material
    122     *     - good for texgen
    123     *     - need to manipulate a bit of state
    124     *
    125     * - worth it/not worth it?
    126     */
    127 
    128    /* Else do them here.
    129     */
    130 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
    131    &_tnl_render_stage,		/* FALLBACK:  */
    132    NULL,
    133 };
    134 
    135 
    136 
    137 /* Initialize the driver's misc functions.
    138  */
    139 static void r200InitDriverFuncs( struct dd_function_table *functions )
    140 {
    141     functions->GetBufferSize		= NULL; /* OBSOLETE */
    142     functions->GetString		= r200GetString;
    143 }
    144 
    145 
    146 static void r200_get_lock(radeonContextPtr radeon)
    147 {
    148    r200ContextPtr rmesa = (r200ContextPtr)radeon;
    149    drm_radeon_sarea_t *sarea = radeon->sarea;
    150 
    151    R200_STATECHANGE( rmesa, ctx );
    152    if (rmesa->radeon.sarea->tiling_enabled) {
    153       rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
    154    }
    155    else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE;
    156 
    157    if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) {
    158       sarea->ctx_owner = rmesa->radeon.dri.hwContext;
    159    }
    160 
    161 }
    162 
    163 static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
    164 {
    165 }
    166 
    167 static void r200_emit_query_finish(radeonContextPtr radeon)
    168 {
    169    BATCH_LOCALS(radeon);
    170    struct radeon_query_object *query = radeon->query.current;
    171 
    172    BEGIN_BATCH_NO_AUTOSTATE(4);
    173    OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
    174    OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
    175    END_BATCH();
    176    query->curr_offset += sizeof(uint32_t);
    177    assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
    178    query->emitted_begin = GL_FALSE;
    179 }
    180 
    181 static void r200_init_vtbl(radeonContextPtr radeon)
    182 {
    183    radeon->vtbl.get_lock = r200_get_lock;
    184    radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset;
    185    radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
    186    radeon->vtbl.swtcl_flush = r200_swtcl_flush;
    187    radeon->vtbl.fallback = r200Fallback;
    188    radeon->vtbl.update_scissor = r200_vtbl_update_scissor;
    189    radeon->vtbl.emit_query_finish = r200_emit_query_finish;
    190    radeon->vtbl.check_blit = r200_check_blit;
    191    radeon->vtbl.blit = r200_blit;
    192    radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
    193 }
    194 
    195 
    196 /* Create the device specific rendering context.
    197  */
    198 GLboolean r200CreateContext( gl_api api,
    199 			     const struct gl_config *glVisual,
    200 			     __DRIcontext *driContextPriv,
    201 			     unsigned major_version,
    202 			     unsigned minor_version,
    203 			     uint32_t flags,
    204 			     unsigned *error,
    205 			     void *sharedContextPrivate)
    206 {
    207    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    208    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
    209    struct dd_function_table functions;
    210    r200ContextPtr rmesa;
    211    struct gl_context *ctx;
    212    int i;
    213    int tcl_mode;
    214 
    215    switch (api) {
    216    case API_OPENGL:
    217       if (major_version > 1 || minor_version > 3) {
    218          *error = __DRI_CTX_ERROR_BAD_VERSION;
    219          return GL_FALSE;
    220       }
    221       break;
    222    case API_OPENGLES:
    223       break;
    224    default:
    225       *error = __DRI_CTX_ERROR_BAD_API;
    226       return GL_FALSE;
    227    }
    228 
    229    /* Flag filtering is handled in dri2CreateContextAttribs.
    230     */
    231    (void) flags;
    232 
    233    assert(glVisual);
    234    assert(driContextPriv);
    235    assert(screen);
    236 
    237    /* Allocate the R200 context */
    238    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
    239    if ( !rmesa ) {
    240       *error = __DRI_CTX_ERROR_NO_MEMORY;
    241       return GL_FALSE;
    242    }
    243 
    244    rmesa->radeon.radeonScreen = screen;
    245    r200_init_vtbl(&rmesa->radeon);
    246    /* init exp fog table data */
    247    radeonInitStaticFogData();
    248 
    249    /* Parse configuration files.
    250     * Do this here so that initialMaxAnisotropy is set before we create
    251     * the default textures.
    252     */
    253    driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
    254 			screen->driScreen->myNum, "r200");
    255    rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
    256 							"def_max_anisotropy");
    257 
    258    if ( sPriv->drm_version.major == 1
    259        && driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
    260       if ( sPriv->drm_version.minor < 13 )
    261 	 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
    262 			  "disabling.\n", sPriv->drm_version.minor );
    263       else
    264 	 rmesa->using_hyperz = GL_TRUE;
    265    }
    266 
    267    if ( sPriv->drm_version.minor >= 15 )
    268       rmesa->texmicrotile = GL_TRUE;
    269 
    270    /* Init default driver functions then plug in our R200-specific functions
    271     * (the texture functions are especially important)
    272     */
    273    _mesa_init_driver_functions(&functions);
    274    r200InitDriverFuncs(&functions);
    275    r200InitIoctlFuncs(&functions);
    276    r200InitStateFuncs(&rmesa->radeon, &functions);
    277    r200InitTextureFuncs(&rmesa->radeon, &functions);
    278    r200InitShaderFuncs(&functions);
    279    radeonInitQueryObjFunctions(&functions);
    280 
    281    if (!radeonInitContext(&rmesa->radeon, &functions,
    282 			  glVisual, driContextPriv,
    283 			  sharedContextPrivate)) {
    284      FREE(rmesa);
    285      *error = __DRI_CTX_ERROR_NO_MEMORY;
    286      return GL_FALSE;
    287    }
    288 
    289    rmesa->radeon.swtcl.RenderIndex = ~0;
    290    rmesa->radeon.hw.all_dirty = 1;
    291 
    292    ctx = rmesa->radeon.glCtx;
    293    /* Initialize the software rasterizer and helper modules.
    294     */
    295    _swrast_CreateContext( ctx );
    296    _vbo_CreateContext( ctx );
    297    _tnl_CreateContext( ctx );
    298    _swsetup_CreateContext( ctx );
    299    _ae_create_context( ctx );
    300 
    301    /* Set the maximum texture size small enough that we can guarentee that
    302     * all texture units can bind a maximal texture and have all of them in
    303     * texturable memory at once. Depending on the allow_large_textures driconf
    304     * setting allow larger textures.
    305     */
    306    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
    307 						 "texture_units");
    308    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
    309    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
    310 
    311    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
    312 
    313    ctx->Const.StripTextureBorder = GL_TRUE;
    314 
    315    i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");
    316 
    317    /* FIXME: When no memory manager is available we should set this
    318     * to some reasonable value based on texture memory pool size */
    319    ctx->Const.MaxTextureLevels = 12;
    320    ctx->Const.Max3DTextureLevels = 9;
    321    ctx->Const.MaxCubeTextureLevels = 12;
    322    ctx->Const.MaxTextureRectSize = 2048;
    323    ctx->Const.MaxRenderbufferSize = 2048;
    324 
    325    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
    326 
    327    /* No wide AA points.
    328     */
    329    ctx->Const.MinPointSize = 1.0;
    330    ctx->Const.MinPointSizeAA = 1.0;
    331    ctx->Const.MaxPointSizeAA = 1.0;
    332    ctx->Const.PointSizeGranularity = 0.0625;
    333    ctx->Const.MaxPointSize = 2047.0;
    334 
    335    /* mesa initialization problem - _mesa_init_point was already called */
    336    ctx->Point.MaxSize = ctx->Const.MaxPointSize;
    337 
    338    ctx->Const.MinLineWidth = 1.0;
    339    ctx->Const.MinLineWidthAA = 1.0;
    340    ctx->Const.MaxLineWidth = 10.0;
    341    ctx->Const.MaxLineWidthAA = 10.0;
    342    ctx->Const.LineWidthGranularity = 0.0625;
    343 
    344    ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
    345    ctx->Const.VertexProgram.MaxNativeAttribs = 12;
    346    ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
    347    ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
    348    ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
    349 
    350    ctx->Const.MaxDrawBuffers = 1;
    351    ctx->Const.MaxColorAttachments = 1;
    352 
    353    _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
    354 
    355    /* Install the customized pipeline:
    356     */
    357    _tnl_destroy_pipeline( ctx );
    358    _tnl_install_pipeline( ctx, r200_pipeline );
    359 
    360    /* Try and keep materials and vertices separate:
    361     */
    362 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
    363 
    364 
    365    /* Configure swrast and TNL to match hardware characteristics:
    366     */
    367    _swrast_allow_pixel_fog( ctx, GL_FALSE );
    368    _swrast_allow_vertex_fog( ctx, GL_TRUE );
    369    _tnl_allow_pixel_fog( ctx, GL_FALSE );
    370    _tnl_allow_vertex_fog( ctx, GL_TRUE );
    371 
    372 
    373    for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
    374       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
    375       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
    376    }
    377    _math_matrix_ctr( &rmesa->tmpmat );
    378    _math_matrix_set_identity( &rmesa->tmpmat );
    379 
    380    ctx->Extensions.ARB_half_float_pixel = true;
    381    ctx->Extensions.ARB_occlusion_query = true;
    382    ctx->Extensions.ARB_texture_border_clamp = true;
    383    ctx->Extensions.ARB_texture_env_combine = true;
    384    ctx->Extensions.ARB_texture_env_dot3 = true;
    385    ctx->Extensions.ARB_texture_env_crossbar = true;
    386    ctx->Extensions.EXT_blend_color = true;
    387    ctx->Extensions.EXT_blend_minmax = true;
    388    ctx->Extensions.EXT_fog_coord = true;
    389    ctx->Extensions.EXT_packed_depth_stencil = true;
    390    ctx->Extensions.EXT_secondary_color = true;
    391    ctx->Extensions.EXT_texture_env_dot3 = true;
    392    ctx->Extensions.EXT_texture_filter_anisotropic = true;
    393    ctx->Extensions.EXT_texture_mirror_clamp = true;
    394    ctx->Extensions.ATI_texture_env_combine3 = true;
    395    ctx->Extensions.ATI_texture_mirror_once = true;
    396    ctx->Extensions.MESA_pack_invert = true;
    397    ctx->Extensions.NV_blend_square = true;
    398    ctx->Extensions.NV_texture_rectangle = true;
    399 #if FEATURE_OES_EGL_image
    400    ctx->Extensions.OES_EGL_image = true;
    401 #endif
    402 
    403    ctx->Extensions.EXT_framebuffer_object = true;
    404    ctx->Extensions.ARB_occlusion_query = true;
    405 
    406    if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
    407      /* yuv textures don't work with some chips - R200 / rv280 okay so far
    408 	others get the bit ordering right but don't actually do YUV-RGB conversion */
    409       ctx->Extensions.MESA_ycbcr_texture = true;
    410    }
    411    if (rmesa->radeon.glCtx->Mesa_DXTn) {
    412       ctx->Extensions.EXT_texture_compression_s3tc = true;
    413       ctx->Extensions.S3_s3tc = true;
    414    }
    415    else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
    416       ctx->Extensions.EXT_texture_compression_s3tc = true;
    417    }
    418 
    419    ctx->Extensions.ARB_texture_cube_map = true;
    420 
    421    ctx->Extensions.EXT_blend_equation_separate = true;
    422    ctx->Extensions.EXT_blend_func_separate = true;
    423 
    424    ctx->Extensions.ARB_vertex_program = true;
    425    ctx->Extensions.EXT_gpu_program_parameters = true;
    426 
    427    ctx->Extensions.NV_vertex_program =
    428       driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program");
    429 
    430    ctx->Extensions.ATI_fragment_shader = (ctx->Const.MaxTextureUnits == 6);
    431 
    432    ctx->Extensions.ARB_point_sprite = true;
    433    ctx->Extensions.EXT_point_parameters = true;
    434 
    435 #if 0
    436    r200InitDriverFuncs( ctx );
    437    r200InitIoctlFuncs( ctx );
    438    r200InitStateFuncs( ctx );
    439    r200InitTextureFuncs( ctx );
    440 #endif
    441    /* plug in a few more device driver functions */
    442    /* XXX these should really go right after _mesa_init_driver_functions() */
    443    radeon_fbo_init(&rmesa->radeon);
    444    radeonInitSpanFuncs( ctx );
    445    r200InitTnlFuncs( ctx );
    446    r200InitState( rmesa );
    447    r200InitSwtcl( ctx );
    448 
    449    rmesa->prefer_gart_client_texturing =
    450       (getenv("R200_GART_CLIENT_TEXTURES") != 0);
    451 
    452    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
    453    if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
    454       fprintf(stderr, "disabling 3D acceleration\n");
    455       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
    456    }
    457    else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
    458 	    !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
    459       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
    460 	 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
    461 	 fprintf(stderr, "Disabling HW TCL support\n");
    462       }
    463       TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
    464    }
    465 
    466    _mesa_compute_version(ctx);
    467 
    468    *error = __DRI_CTX_ERROR_SUCCESS;
    469    return GL_TRUE;
    470 }
    471 
    472 
    473 void r200DestroyContext( __DRIcontext *driContextPriv )
    474 {
    475 	int i;
    476 	r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
    477 	if (rmesa)
    478 	{
    479 		for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
    480 			_math_matrix_dtr( &rmesa->TexGenMatrix[i] );
    481 		}
    482 	}
    483 	radeonDestroyContext(driContextPriv);
    484 }
    485