r200_context.c revision 674835f184b37ad378ce2e35f1a8326af0facc77
1/* 2Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 4The Weather Channel (TM) funded Tungsten Graphics to develop the 5initial release of the Radeon 8500 driver under the XFree86 license. 6This notice must be preserved. 7 8Permission is hereby granted, free of charge, to any person obtaining 9a copy of this software and associated documentation files (the 10"Software"), to deal in the Software without restriction, including 11without limitation the rights to use, copy, modify, merge, publish, 12distribute, sublicense, and/or sell copies of the Software, and to 13permit persons to whom the Software is furnished to do so, subject to 14the following conditions: 15 16The above copyright notice and this permission notice (including the 17next paragraph) shall be included in all copies or substantial 18portions of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 28**************************************************************************/ 29 30/* 31 * Authors: 32 * Keith Whitwell <keith@tungstengraphics.com> 33 */ 34 35#include "main/glheader.h" 36#include "main/api_arrayelt.h" 37#include "main/context.h" 38#include "main/simple_list.h" 39#include "main/imports.h" 40#include "main/matrix.h" 41#include "main/extensions.h" 42#include "main/framebuffer.h" 43#include "main/state.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_pixel.h" 58#include "r200_tex.h" 59#include "r200_swtcl.h" 60#include "r200_tcl.h" 61#include "r200_maos.h" 62#include "r200_vertprog.h" 63#include "radeon_queryobj.h" 64 65#include "radeon_span.h" 66 67#define need_GL_ARB_occlusion_query 68#define need_GL_ARB_vertex_program 69#define need_GL_ATI_fragment_shader 70#define need_GL_EXT_blend_minmax 71#define need_GL_EXT_fog_coord 72#define need_GL_EXT_secondary_color 73#define need_GL_EXT_blend_equation_separate 74#define need_GL_EXT_blend_func_separate 75#define need_GL_NV_vertex_program 76#define need_GL_ARB_point_parameters 77#define need_GL_EXT_framebuffer_object 78#include "extension_helper.h" 79 80#define DRIVER_DATE "20060602" 81 82#include "vblank.h" 83#include "utils.h" 84#include "xmlpool.h" /* for symbolic values of enum-type options */ 85 86/* Return various strings for glGetString(). 87 */ 88static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) 89{ 90 r200ContextPtr rmesa = R200_CONTEXT(ctx); 91 static char buffer[128]; 92 unsigned offset; 93 GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 : 94 rmesa->radeon.radeonScreen->AGPMode; 95 96 switch ( name ) { 97 case GL_VENDOR: 98 return (GLubyte *)"Tungsten Graphics, Inc."; 99 100 case GL_RENDERER: 101 offset = driGetRendererString( buffer, "R200", DRIVER_DATE, 102 agp_mode ); 103 104 sprintf( & buffer[ offset ], " %sTCL", 105 !(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) 106 ? "" : "NO-" ); 107 108 return (GLubyte *)buffer; 109 110 default: 111 return NULL; 112 } 113} 114 115 116/* Extension strings exported by the R200 driver. 117 */ 118const struct dri_extension card_extensions[] = 119{ 120 { "GL_ARB_multitexture", NULL }, 121 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, 122 { "GL_ARB_texture_border_clamp", NULL }, 123 { "GL_ARB_texture_env_add", NULL }, 124 { "GL_ARB_texture_env_combine", NULL }, 125 { "GL_ARB_texture_env_dot3", NULL }, 126 { "GL_ARB_texture_env_crossbar", NULL }, 127 { "GL_ARB_texture_mirrored_repeat", NULL }, 128 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, 129 { "GL_EXT_blend_subtract", NULL }, 130 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, 131 { "GL_EXT_packed_depth_stencil", NULL}, 132 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, 133 { "GL_EXT_stencil_wrap", NULL }, 134 { "GL_EXT_texture_edge_clamp", NULL }, 135 { "GL_EXT_texture_env_combine", NULL }, 136 { "GL_EXT_texture_env_dot3", NULL }, 137 { "GL_EXT_texture_filter_anisotropic", NULL }, 138 { "GL_EXT_texture_lod_bias", NULL }, 139 { "GL_EXT_texture_mirror_clamp", NULL }, 140 { "GL_EXT_texture_rectangle", NULL }, 141 { "GL_ATI_texture_env_combine3", NULL }, 142 { "GL_ATI_texture_mirror_once", NULL }, 143 { "GL_MESA_pack_invert", NULL }, 144 { "GL_NV_blend_square", NULL }, 145 { "GL_SGIS_generate_mipmap", NULL }, 146 { NULL, NULL } 147}; 148 149const struct dri_extension blend_extensions[] = { 150 { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, 151 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, 152 { NULL, NULL } 153}; 154 155const struct dri_extension ARB_vp_extension[] = { 156 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions } 157}; 158 159const struct dri_extension NV_vp_extension[] = { 160 { "GL_NV_vertex_program", GL_NV_vertex_program_functions } 161}; 162 163const struct dri_extension ATI_fs_extension[] = { 164 { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions } 165}; 166 167const struct dri_extension point_extensions[] = { 168 { "GL_ARB_point_sprite", NULL }, 169 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, 170 { NULL, NULL } 171}; 172 173const struct dri_extension mm_extensions[] = { 174 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, 175 { NULL, NULL } 176}; 177 178extern const struct tnl_pipeline_stage _r200_render_stage; 179extern const struct tnl_pipeline_stage _r200_tcl_stage; 180 181static const struct tnl_pipeline_stage *r200_pipeline[] = { 182 183 /* Try and go straight to t&l 184 */ 185 &_r200_tcl_stage, 186 187 /* Catch any t&l fallbacks 188 */ 189 &_tnl_vertex_transform_stage, 190 &_tnl_normal_transform_stage, 191 &_tnl_lighting_stage, 192 &_tnl_fog_coordinate_stage, 193 &_tnl_texgen_stage, 194 &_tnl_texture_transform_stage, 195 &_tnl_point_attenuation_stage, 196 &_tnl_vertex_program_stage, 197 /* Try again to go to tcl? 198 * - no good for asymmetric-twoside (do with multipass) 199 * - no good for asymmetric-unfilled (do with multipass) 200 * - good for material 201 * - good for texgen 202 * - need to manipulate a bit of state 203 * 204 * - worth it/not worth it? 205 */ 206 207 /* Else do them here. 208 */ 209/* &_r200_render_stage, */ /* FIXME: bugs with ut2003 */ 210 &_tnl_render_stage, /* FALLBACK: */ 211 NULL, 212}; 213 214 215 216/* Initialize the driver's misc functions. 217 */ 218static void r200InitDriverFuncs( struct dd_function_table *functions ) 219{ 220 functions->GetBufferSize = NULL; /* OBSOLETE */ 221 functions->GetString = r200GetString; 222} 223 224static const struct dri_debug_control debug_control[] = 225{ 226 { "fall", DEBUG_FALLBACKS }, 227 { "tex", DEBUG_TEXTURE }, 228 { "ioctl", DEBUG_IOCTL }, 229 { "prim", DEBUG_PRIMS }, 230 { "vert", DEBUG_VERTS }, 231 { "state", DEBUG_STATE }, 232 { "code", DEBUG_CODEGEN }, 233 { "vfmt", DEBUG_VFMT }, 234 { "vtxf", DEBUG_VFMT }, 235 { "verb", DEBUG_VERBOSE }, 236 { "dri", DEBUG_DRI }, 237 { "dma", DEBUG_DMA }, 238 { "san", DEBUG_SANITY }, 239 { "sync", DEBUG_SYNC }, 240 { "pix", DEBUG_PIXEL }, 241 { "mem", DEBUG_MEMORY }, 242 { NULL, 0 } 243}; 244 245static void r200_get_lock(radeonContextPtr radeon) 246{ 247 r200ContextPtr rmesa = (r200ContextPtr)radeon; 248 drm_radeon_sarea_t *sarea = radeon->sarea; 249 250 R200_STATECHANGE( rmesa, ctx ); 251 if (rmesa->radeon.sarea->tiling_enabled) { 252 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; 253 } 254 else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE; 255 256 if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) { 257 sarea->ctx_owner = rmesa->radeon.dri.hwContext; 258 if (!radeon->radeonScreen->kernel_mm) 259 radeon_bo_legacy_texture_age(radeon->radeonScreen->bom); 260 } 261 262} 263 264static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) 265{ 266} 267 268static void r200_emit_query_finish(radeonContextPtr radeon) 269{ 270 BATCH_LOCALS(radeon); 271 struct radeon_query_object *query = radeon->query.current; 272 273 BEGIN_BATCH_NO_AUTOSTATE(4); 274 OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0)); 275 OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0); 276 END_BATCH(); 277 query->curr_offset += sizeof(uint32_t); 278 assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE); 279 query->emitted_begin = GL_FALSE; 280} 281 282static void r200_init_vtbl(radeonContextPtr radeon) 283{ 284 radeon->vtbl.get_lock = r200_get_lock; 285 radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; 286 radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header; 287 radeon->vtbl.swtcl_flush = r200_swtcl_flush; 288 radeon->vtbl.fallback = r200Fallback; 289 radeon->vtbl.update_scissor = r200_vtbl_update_scissor; 290 radeon->vtbl.emit_query_finish = r200_emit_query_finish; 291} 292 293 294/* Create the device specific rendering context. 295 */ 296GLboolean r200CreateContext( const __GLcontextModes *glVisual, 297 __DRIcontextPrivate *driContextPriv, 298 void *sharedContextPrivate) 299{ 300 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; 301 radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); 302 struct dd_function_table functions; 303 r200ContextPtr rmesa; 304 GLcontext *ctx; 305 int i; 306 int tcl_mode; 307 308 assert(glVisual); 309 assert(driContextPriv); 310 assert(screen); 311 312 /* Allocate the R200 context */ 313 rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); 314 if ( !rmesa ) 315 return GL_FALSE; 316 317 r200_init_vtbl(&rmesa->radeon); 318 /* init exp fog table data */ 319 r200InitStaticFogData(); 320 321 /* Parse configuration files. 322 * Do this here so that initialMaxAnisotropy is set before we create 323 * the default textures. 324 */ 325 driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache, 326 screen->driScreen->myNum, "r200"); 327 rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache, 328 "def_max_anisotropy"); 329 330 if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) { 331 if ( sPriv->drm_version.minor < 13 ) 332 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, " 333 "disabling.\n", sPriv->drm_version.minor ); 334 else 335 rmesa->using_hyperz = GL_TRUE; 336 } 337 338 if ( sPriv->drm_version.minor >= 15 ) 339 rmesa->texmicrotile = GL_TRUE; 340 341 /* Init default driver functions then plug in our R200-specific functions 342 * (the texture functions are especially important) 343 */ 344 _mesa_init_driver_functions(&functions); 345 r200InitDriverFuncs(&functions); 346 r200InitIoctlFuncs(&functions); 347 r200InitStateFuncs(&functions); 348 r200InitTextureFuncs(&functions); 349 r200InitShaderFuncs(&functions); 350 radeonInitQueryObjFunctions(&functions); 351 352 if (!radeonInitContext(&rmesa->radeon, &functions, 353 glVisual, driContextPriv, 354 sharedContextPrivate)) { 355 FREE(rmesa); 356 return GL_FALSE; 357 } 358 359 rmesa->radeon.swtcl.RenderIndex = ~0; 360 rmesa->radeon.hw.all_dirty = 1; 361 362 /* Set the maximum texture size small enough that we can guarentee that 363 * all texture units can bind a maximal texture and have all of them in 364 * texturable memory at once. Depending on the allow_large_textures driconf 365 * setting allow larger textures. 366 */ 367 368 ctx = rmesa->radeon.glCtx; 369 ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache, 370 "texture_units"); 371 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; 372 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; 373 374 i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); 375 376 /* FIXME: When no memory manager is available we should set this 377 * to some reasonable value based on texture memory pool size */ 378 ctx->Const.MaxTextureLevels = 12; 379 ctx->Const.Max3DTextureLevels = 9; 380 ctx->Const.MaxCubeTextureLevels = 12; 381 ctx->Const.MaxTextureRectSize = 2048; 382 383 ctx->Const.MaxTextureMaxAnisotropy = 16.0; 384 385 /* No wide AA points. 386 */ 387 ctx->Const.MinPointSize = 1.0; 388 ctx->Const.MinPointSizeAA = 1.0; 389 ctx->Const.MaxPointSizeAA = 1.0; 390 ctx->Const.PointSizeGranularity = 0.0625; 391 if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) 392 ctx->Const.MaxPointSize = 2047.0; 393 else 394 ctx->Const.MaxPointSize = 1.0; 395 396 /* mesa initialization problem - _mesa_init_point was already called */ 397 ctx->Point.MaxSize = ctx->Const.MaxPointSize; 398 399 ctx->Const.MinLineWidth = 1.0; 400 ctx->Const.MinLineWidthAA = 1.0; 401 ctx->Const.MaxLineWidth = 10.0; 402 ctx->Const.MaxLineWidthAA = 10.0; 403 ctx->Const.LineWidthGranularity = 0.0625; 404 405 ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST; 406 ctx->Const.VertexProgram.MaxNativeAttribs = 12; 407 ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS; 408 ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM; 409 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; 410 411 ctx->Const.MaxDrawBuffers = 1; 412 413 _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); 414 415 /* Initialize the software rasterizer and helper modules. 416 */ 417 _swrast_CreateContext( ctx ); 418 _vbo_CreateContext( ctx ); 419 _tnl_CreateContext( ctx ); 420 _swsetup_CreateContext( ctx ); 421 _ae_create_context( ctx ); 422 423 /* Install the customized pipeline: 424 */ 425 _tnl_destroy_pipeline( ctx ); 426 _tnl_install_pipeline( ctx, r200_pipeline ); 427 428 /* Try and keep materials and vertices separate: 429 */ 430/* _tnl_isolate_materials( ctx, GL_TRUE ); */ 431 432 433 /* Configure swrast and TNL to match hardware characteristics: 434 */ 435 _swrast_allow_pixel_fog( ctx, GL_FALSE ); 436 _swrast_allow_vertex_fog( ctx, GL_TRUE ); 437 _tnl_allow_pixel_fog( ctx, GL_FALSE ); 438 _tnl_allow_vertex_fog( ctx, GL_TRUE ); 439 440 441 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) { 442 _math_matrix_ctr( &rmesa->TexGenMatrix[i] ); 443 _math_matrix_set_identity( &rmesa->TexGenMatrix[i] ); 444 } 445 _math_matrix_ctr( &rmesa->tmpmat ); 446 _math_matrix_set_identity( &rmesa->tmpmat ); 447 448 driInitExtensions( ctx, card_extensions, GL_TRUE ); 449 450 if (rmesa->radeon.radeonScreen->kernel_mm) 451 driInitExtensions(ctx, mm_extensions, GL_FALSE); 452 if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) { 453 /* yuv textures don't work with some chips - R200 / rv280 okay so far 454 others get the bit ordering right but don't actually do YUV-RGB conversion */ 455 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); 456 } 457 if (rmesa->radeon.glCtx->Mesa_DXTn) { 458 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); 459 _mesa_enable_extension( ctx, "GL_S3_s3tc" ); 460 } 461 else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) { 462 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); 463 } 464 465 if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200) 466 _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); 467 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) { 468 driInitExtensions( ctx, blend_extensions, GL_FALSE ); 469 } 470 if(rmesa->radeon.radeonScreen->drmSupportsVertexProgram) 471 driInitSingleExtension( ctx, ARB_vp_extension ); 472 if(driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program")) 473 driInitSingleExtension( ctx, NV_vp_extension ); 474 475 if ((ctx->Const.MaxTextureUnits == 6) && rmesa->radeon.radeonScreen->drmSupportsFragShader) 476 driInitSingleExtension( ctx, ATI_fs_extension ); 477 if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) 478 driInitExtensions( ctx, point_extensions, GL_FALSE ); 479 480 if (!rmesa->radeon.radeonScreen->kernel_mm) 481 _mesa_disable_extension(ctx, "GL_ARB_occlusion_query"); 482#if 0 483 r200InitDriverFuncs( ctx ); 484 r200InitIoctlFuncs( ctx ); 485 r200InitStateFuncs( ctx ); 486 r200InitTextureFuncs( ctx ); 487#endif 488 /* plug in a few more device driver functions */ 489 /* XXX these should really go right after _mesa_init_driver_functions() */ 490 radeon_fbo_init(&rmesa->radeon); 491 radeonInitSpanFuncs( ctx ); 492 r200InitPixelFuncs( ctx ); 493 r200InitTnlFuncs( ctx ); 494 r200InitState( rmesa ); 495 r200InitSwtcl( ctx ); 496 497 rmesa->prefer_gart_client_texturing = 498 (getenv("R200_GART_CLIENT_TEXTURES") != 0); 499 500#if DO_DEBUG 501 R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ), 502 debug_control ); 503 R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ), 504 debug_control ); 505#endif 506 507 tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode"); 508 if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) { 509 fprintf(stderr, "disabling 3D acceleration\n"); 510 FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1); 511 } 512 else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") || 513 !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { 514 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { 515 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL; 516 fprintf(stderr, "Disabling HW TCL support\n"); 517 } 518 TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); 519 } 520 521 return GL_TRUE; 522} 523 524 525void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) 526{ 527 int i; 528 r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate; 529 if (rmesa) 530 { 531 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) { 532 _math_matrix_dtr( &rmesa->TexGenMatrix[i] ); 533 } 534 } 535 radeonDestroyContext(driContextPriv); 536} 537