Merge branch 'draw-instanced'
[mesa.git] / src / mesa / drivers / dri / r200 / r200_context.c
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@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/extensions.h"
41 #include "main/mfeatures.h"
42
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "vbo/vbo.h"
46
47 #include "tnl/tnl.h"
48 #include "tnl/t_pipeline.h"
49
50 #include "drivers/common/driverfuncs.h"
51
52 #include "r200_context.h"
53 #include "r200_ioctl.h"
54 #include "r200_state.h"
55 #include "r200_tex.h"
56 #include "r200_swtcl.h"
57 #include "r200_tcl.h"
58 #include "r200_vertprog.h"
59 #include "radeon_queryobj.h"
60 #include "r200_blit.h"
61
62 #include "radeon_span.h"
63
64 #define need_GL_ARB_occlusion_query
65 #define need_GL_ARB_vertex_program
66 #define need_GL_ATI_fragment_shader
67 #define need_GL_EXT_blend_minmax
68 #define need_GL_EXT_fog_coord
69 #define need_GL_EXT_secondary_color
70 #define need_GL_EXT_blend_equation_separate
71 #define need_GL_EXT_blend_func_separate
72 #define need_GL_NV_vertex_program
73 #define need_GL_ARB_point_parameters
74 #define need_GL_EXT_framebuffer_object
75 #define need_GL_OES_EGL_image
76
77 #include "main/remap_helper.h"
78
79 #define DRIVER_DATE "20060602"
80
81 #include "utils.h"
82 #include "xmlpool.h" /* for symbolic values of enum-type options */
83
84 /* Return various strings for glGetString().
85 */
86 static const GLubyte *r200GetString( struct gl_context *ctx, GLenum name )
87 {
88 r200ContextPtr rmesa = R200_CONTEXT(ctx);
89 static char buffer[128];
90 unsigned offset;
91 GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 :
92 rmesa->radeon.radeonScreen->AGPMode;
93
94 switch ( name ) {
95 case GL_VENDOR:
96 return (GLubyte *)"Tungsten Graphics, Inc.";
97
98 case GL_RENDERER:
99 offset = driGetRendererString( buffer, "R200", DRIVER_DATE,
100 agp_mode );
101
102 sprintf( & buffer[ offset ], " %sTCL",
103 !(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
104 ? "" : "NO-" );
105
106 return (GLubyte *)buffer;
107
108 default:
109 return NULL;
110 }
111 }
112
113
114 /* Extension strings exported by the R200 driver.
115 */
116 static const struct dri_extension card_extensions[] =
117 {
118 { "GL_ARB_multitexture", NULL },
119 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
120 { "GL_ARB_texture_border_clamp", NULL },
121 { "GL_ARB_texture_env_add", NULL },
122 { "GL_ARB_texture_env_combine", NULL },
123 { "GL_ARB_texture_env_dot3", NULL },
124 { "GL_ARB_texture_env_crossbar", NULL },
125 { "GL_ARB_texture_mirrored_repeat", NULL },
126 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
127 { "GL_EXT_blend_subtract", NULL },
128 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
129 { "GL_EXT_packed_depth_stencil", NULL},
130 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
131 { "GL_EXT_stencil_wrap", NULL },
132 { "GL_EXT_texture_edge_clamp", NULL },
133 { "GL_EXT_texture_env_combine", NULL },
134 { "GL_EXT_texture_env_dot3", NULL },
135 { "GL_EXT_texture_filter_anisotropic", NULL },
136 { "GL_EXT_texture_lod_bias", NULL },
137 { "GL_EXT_texture_mirror_clamp", NULL },
138 { "GL_EXT_texture_rectangle", NULL },
139 { "GL_ATI_texture_env_combine3", NULL },
140 { "GL_ATI_texture_mirror_once", NULL },
141 { "GL_MESA_pack_invert", NULL },
142 { "GL_NV_blend_square", NULL },
143 #if FEATURE_OES_EGL_image
144 { "GL_OES_EGL_image", GL_OES_EGL_image_functions },
145 #endif
146 { NULL, NULL }
147 };
148
149 static const 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
155 static const struct dri_extension ARB_vp_extension[] = {
156 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }
157 };
158
159 static const struct dri_extension NV_vp_extension[] = {
160 { "GL_NV_vertex_program", GL_NV_vertex_program_functions }
161 };
162
163 static const struct dri_extension ATI_fs_extension[] = {
164 { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions }
165 };
166
167 static const 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
173 static const struct dri_extension mm_extensions[] = {
174 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
175 { NULL, NULL }
176 };
177
178 extern const struct tnl_pipeline_stage _r200_render_stage;
179 extern const struct tnl_pipeline_stage _r200_tcl_stage;
180
181 static 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 */
218 static void r200InitDriverFuncs( struct dd_function_table *functions )
219 {
220 functions->GetBufferSize = NULL; /* OBSOLETE */
221 functions->GetString = r200GetString;
222 }
223
224
225 static void r200_get_lock(radeonContextPtr radeon)
226 {
227 r200ContextPtr rmesa = (r200ContextPtr)radeon;
228 drm_radeon_sarea_t *sarea = radeon->sarea;
229
230 R200_STATECHANGE( rmesa, ctx );
231 if (rmesa->radeon.sarea->tiling_enabled) {
232 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
233 }
234 else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE;
235
236 if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) {
237 sarea->ctx_owner = rmesa->radeon.dri.hwContext;
238 if (!radeon->radeonScreen->kernel_mm)
239 radeon_bo_legacy_texture_age(radeon->radeonScreen->bom);
240 }
241
242 }
243
244 static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
245 {
246 }
247
248 static void r200_emit_query_finish(radeonContextPtr radeon)
249 {
250 BATCH_LOCALS(radeon);
251 struct radeon_query_object *query = radeon->query.current;
252
253 BEGIN_BATCH_NO_AUTOSTATE(4);
254 OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
255 OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
256 END_BATCH();
257 query->curr_offset += sizeof(uint32_t);
258 assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
259 query->emitted_begin = GL_FALSE;
260 }
261
262 static void r200_init_vtbl(radeonContextPtr radeon)
263 {
264 radeon->vtbl.get_lock = r200_get_lock;
265 radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset;
266 radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
267 radeon->vtbl.swtcl_flush = r200_swtcl_flush;
268 radeon->vtbl.fallback = r200Fallback;
269 radeon->vtbl.update_scissor = r200_vtbl_update_scissor;
270 radeon->vtbl.emit_query_finish = r200_emit_query_finish;
271 radeon->vtbl.check_blit = r200_check_blit;
272 radeon->vtbl.blit = r200_blit;
273 radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
274 }
275
276
277 /* Create the device specific rendering context.
278 */
279 GLboolean r200CreateContext( gl_api api,
280 const struct gl_config *glVisual,
281 __DRIcontext *driContextPriv,
282 void *sharedContextPrivate)
283 {
284 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
285 radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
286 struct dd_function_table functions;
287 r200ContextPtr rmesa;
288 struct gl_context *ctx;
289 int i;
290 int tcl_mode;
291
292 assert(glVisual);
293 assert(driContextPriv);
294 assert(screen);
295
296 /* Allocate the R200 context */
297 rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
298 if ( !rmesa )
299 return GL_FALSE;
300
301 rmesa->radeon.radeonScreen = screen;
302 r200_init_vtbl(&rmesa->radeon);
303 /* init exp fog table data */
304 r200InitStaticFogData();
305
306 /* Parse configuration files.
307 * Do this here so that initialMaxAnisotropy is set before we create
308 * the default textures.
309 */
310 driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
311 screen->driScreen->myNum, "r200");
312 rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
313 "def_max_anisotropy");
314
315 if ( sPriv->drm_version.major == 1
316 && driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
317 if ( sPriv->drm_version.minor < 13 )
318 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
319 "disabling.\n", sPriv->drm_version.minor );
320 else
321 rmesa->using_hyperz = GL_TRUE;
322 }
323
324 if ( sPriv->drm_version.minor >= 15 )
325 rmesa->texmicrotile = GL_TRUE;
326
327 /* Init default driver functions then plug in our R200-specific functions
328 * (the texture functions are especially important)
329 */
330 _mesa_init_driver_functions(&functions);
331 r200InitDriverFuncs(&functions);
332 r200InitIoctlFuncs(&functions);
333 r200InitStateFuncs(&rmesa->radeon, &functions);
334 r200InitTextureFuncs(&rmesa->radeon, &functions);
335 r200InitShaderFuncs(&functions);
336 radeonInitQueryObjFunctions(&functions);
337
338 if (!radeonInitContext(&rmesa->radeon, &functions,
339 glVisual, driContextPriv,
340 sharedContextPrivate)) {
341 FREE(rmesa);
342 return GL_FALSE;
343 }
344
345 rmesa->radeon.swtcl.RenderIndex = ~0;
346 rmesa->radeon.hw.all_dirty = 1;
347
348 /* Set the maximum texture size small enough that we can guarentee that
349 * all texture units can bind a maximal texture and have all of them in
350 * texturable memory at once. Depending on the allow_large_textures driconf
351 * setting allow larger textures.
352 */
353
354 ctx = rmesa->radeon.glCtx;
355 ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
356 "texture_units");
357 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
358 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
359
360 ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
361
362 i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");
363
364 /* FIXME: When no memory manager is available we should set this
365 * to some reasonable value based on texture memory pool size */
366 ctx->Const.MaxTextureLevels = 12;
367 ctx->Const.Max3DTextureLevels = 9;
368 ctx->Const.MaxCubeTextureLevels = 12;
369 ctx->Const.MaxTextureRectSize = 2048;
370 ctx->Const.MaxRenderbufferSize = 2048;
371
372 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
373
374 /* No wide AA points.
375 */
376 ctx->Const.MinPointSize = 1.0;
377 ctx->Const.MinPointSizeAA = 1.0;
378 ctx->Const.MaxPointSizeAA = 1.0;
379 ctx->Const.PointSizeGranularity = 0.0625;
380 if (rmesa->radeon.radeonScreen->drmSupportsPointSprites)
381 ctx->Const.MaxPointSize = 2047.0;
382 else
383 ctx->Const.MaxPointSize = 1.0;
384
385 /* mesa initialization problem - _mesa_init_point was already called */
386 ctx->Point.MaxSize = ctx->Const.MaxPointSize;
387
388 ctx->Const.MinLineWidth = 1.0;
389 ctx->Const.MinLineWidthAA = 1.0;
390 ctx->Const.MaxLineWidth = 10.0;
391 ctx->Const.MaxLineWidthAA = 10.0;
392 ctx->Const.LineWidthGranularity = 0.0625;
393
394 ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
395 ctx->Const.VertexProgram.MaxNativeAttribs = 12;
396 ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
397 ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
398 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
399
400 ctx->Const.MaxDrawBuffers = 1;
401 ctx->Const.MaxColorAttachments = 1;
402
403 _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
404
405 /* Initialize the software rasterizer and helper modules.
406 */
407 _swrast_CreateContext( ctx );
408 _vbo_CreateContext( ctx );
409 _tnl_CreateContext( ctx );
410 _swsetup_CreateContext( ctx );
411 _ae_create_context( ctx );
412
413 /* Install the customized pipeline:
414 */
415 _tnl_destroy_pipeline( ctx );
416 _tnl_install_pipeline( ctx, r200_pipeline );
417
418 /* Try and keep materials and vertices separate:
419 */
420 /* _tnl_isolate_materials( ctx, GL_TRUE ); */
421
422
423 /* Configure swrast and TNL to match hardware characteristics:
424 */
425 _swrast_allow_pixel_fog( ctx, GL_FALSE );
426 _swrast_allow_vertex_fog( ctx, GL_TRUE );
427 _tnl_allow_pixel_fog( ctx, GL_FALSE );
428 _tnl_allow_vertex_fog( ctx, GL_TRUE );
429
430
431 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
432 _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
433 _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
434 }
435 _math_matrix_ctr( &rmesa->tmpmat );
436 _math_matrix_set_identity( &rmesa->tmpmat );
437
438 driInitExtensions( ctx, card_extensions, GL_TRUE );
439
440 if (rmesa->radeon.radeonScreen->kernel_mm)
441 driInitExtensions(ctx, mm_extensions, GL_FALSE);
442 if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
443 /* yuv textures don't work with some chips - R200 / rv280 okay so far
444 others get the bit ordering right but don't actually do YUV-RGB conversion */
445 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
446 }
447 if (rmesa->radeon.glCtx->Mesa_DXTn) {
448 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
449 _mesa_enable_extension( ctx, "GL_S3_s3tc" );
450 }
451 else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
452 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
453 }
454
455 if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200)
456 _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
457 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
458 driInitExtensions( ctx, blend_extensions, GL_FALSE );
459 }
460 if(rmesa->radeon.radeonScreen->drmSupportsVertexProgram)
461 driInitSingleExtension( ctx, ARB_vp_extension );
462 if(driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program"))
463 driInitSingleExtension( ctx, NV_vp_extension );
464
465 if ((ctx->Const.MaxTextureUnits == 6) && rmesa->radeon.radeonScreen->drmSupportsFragShader)
466 driInitSingleExtension( ctx, ATI_fs_extension );
467 if (rmesa->radeon.radeonScreen->drmSupportsPointSprites)
468 driInitExtensions( ctx, point_extensions, GL_FALSE );
469
470 if (!rmesa->radeon.radeonScreen->kernel_mm)
471 _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
472 #if 0
473 r200InitDriverFuncs( ctx );
474 r200InitIoctlFuncs( ctx );
475 r200InitStateFuncs( ctx );
476 r200InitTextureFuncs( ctx );
477 #endif
478 /* plug in a few more device driver functions */
479 /* XXX these should really go right after _mesa_init_driver_functions() */
480 radeon_fbo_init(&rmesa->radeon);
481 radeonInitSpanFuncs( ctx );
482 r200InitTnlFuncs( ctx );
483 r200InitState( rmesa );
484 r200InitSwtcl( ctx );
485
486 rmesa->prefer_gart_client_texturing =
487 (getenv("R200_GART_CLIENT_TEXTURES") != 0);
488
489 tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
490 if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
491 fprintf(stderr, "disabling 3D acceleration\n");
492 FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
493 }
494 else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
495 !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
496 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
497 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
498 fprintf(stderr, "Disabling HW TCL support\n");
499 }
500 TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
501 }
502
503 return GL_TRUE;
504 }
505
506
507 void r200DestroyContext( __DRIcontext *driContextPriv )
508 {
509 int i;
510 r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
511 if (rmesa)
512 {
513 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
514 _math_matrix_dtr( &rmesa->TexGenMatrix[i] );
515 }
516 }
517 radeonDestroyContext(driContextPriv);
518 }