Merge git://proxy01.pd.intel.com:9419/git/mesa/mesa into crestline
[mesa.git] / src / mesa / drivers / dri / r300 / r300_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 * Nicolai Haehnle <prefect_@gmx.net>
34 */
35 #include "glheader.h"
36 #include "api_arrayelt.h"
37 #include "context.h"
38 #include "simple_list.h"
39 #include "imports.h"
40 #include "matrix.h"
41 #include "extensions.h"
42 #include "state.h"
43 #include "bufferobj.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 #include "tnl/t_vp_build.h"
52
53 #include "drivers/common/driverfuncs.h"
54
55 #include "radeon_ioctl.h"
56 #include "radeon_span.h"
57 #include "r300_context.h"
58 #include "r300_cmdbuf.h"
59 #include "r300_state.h"
60 #include "r300_ioctl.h"
61 #include "r300_tex.h"
62 #include "r300_maos.h"
63
64 #ifdef USER_BUFFERS
65 #include "radeon_mm.h"
66 #endif
67
68 #include "vblank.h"
69 #include "utils.h"
70 #include "xmlpool.h" /* for symbolic values of enum-type options */
71
72 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
73 int future_hw_tcl_on=1;
74 int hw_tcl_on=1;
75
76 #define need_GL_EXT_stencil_two_side
77 #define need_GL_ARB_multisample
78 #define need_GL_ARB_texture_compression
79 #define need_GL_ARB_vertex_buffer_object
80 #define need_GL_ARB_vertex_program
81 #define need_GL_EXT_blend_minmax
82 //#define need_GL_EXT_fog_coord
83 #define need_GL_EXT_secondary_color
84 #define need_GL_EXT_blend_equation_separate
85 #define need_GL_EXT_blend_func_separate
86 #define need_GL_EXT_gpu_program_parameters
87 #define need_GL_NV_vertex_program
88 #include "extension_helper.h"
89
90 const struct dri_extension card_extensions[] = {
91 {"GL_ARB_multisample", GL_ARB_multisample_functions},
92 {"GL_ARB_multitexture", NULL},
93 {"GL_ARB_texture_border_clamp", NULL},
94 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
95 {"GL_ARB_texture_cube_map", NULL},
96 {"GL_ARB_texture_env_add", NULL},
97 {"GL_ARB_texture_env_combine", NULL},
98 {"GL_ARB_texture_env_crossbar", NULL},
99 {"GL_ARB_texture_env_dot3", NULL},
100 {"GL_ARB_texture_mirrored_repeat", NULL},
101 {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
102 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
103 {"GL_ARB_fragment_program", NULL},
104 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
105 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
106 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
107 {"GL_EXT_blend_subtract", NULL},
108 // {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
109 {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
110 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
111 {"GL_EXT_stencil_wrap", NULL},
112 {"GL_EXT_texture_edge_clamp", NULL},
113 {"GL_EXT_texture_env_combine", NULL},
114 {"GL_EXT_texture_env_dot3", NULL},
115 {"GL_EXT_texture_filter_anisotropic", NULL},
116 {"GL_EXT_texture_lod_bias", NULL},
117 {"GL_EXT_texture_mirror_clamp", NULL},
118 {"GL_EXT_texture_rectangle", NULL},
119 {"GL_ATI_texture_env_combine3", NULL},
120 {"GL_ATI_texture_mirror_once", NULL},
121 {"GL_MESA_pack_invert", NULL},
122 {"GL_MESA_ycbcr_texture", NULL},
123 {"GL_MESAX_texture_float", NULL},
124 {"GL_NV_blend_square", NULL},
125 {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
126 {"GL_SGIS_generate_mipmap", NULL},
127 {NULL, NULL}
128 };
129
130 const struct dri_extension stencil_two_side[] = {
131 {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
132 };
133
134 extern struct tnl_pipeline_stage _r300_render_stage;
135 extern const struct tnl_pipeline_stage _r300_tcl_stage;
136
137 static const struct tnl_pipeline_stage *r300_pipeline[] = {
138
139 /* Try and go straight to t&l
140 */
141 &_r300_tcl_stage,
142
143 /* Catch any t&l fallbacks
144 */
145 &_tnl_vertex_transform_stage,
146 &_tnl_normal_transform_stage,
147 &_tnl_lighting_stage,
148 &_tnl_fog_coordinate_stage,
149 &_tnl_texgen_stage,
150 &_tnl_texture_transform_stage,
151 &_tnl_arb_vertex_program_stage,
152 &_tnl_vertex_program_stage,
153
154 /* Try again to go to tcl?
155 * - no good for asymmetric-twoside (do with multipass)
156 * - no good for asymmetric-unfilled (do with multipass)
157 * - good for material
158 * - good for texgen
159 * - need to manipulate a bit of state
160 *
161 * - worth it/not worth it?
162 */
163
164 /* Else do them here.
165 */
166 &_r300_render_stage,
167 &_tnl_render_stage, /* FALLBACK */
168 0,
169 };
170
171
172 /* Create the device specific rendering context.
173 */
174 GLboolean r300CreateContext(const __GLcontextModes * glVisual,
175 __DRIcontextPrivate * driContextPriv,
176 void *sharedContextPrivate)
177 {
178 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
179 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
180 struct dd_function_table functions;
181 r300ContextPtr r300;
182 GLcontext *ctx;
183 int tcl_mode, i;
184
185 assert(glVisual);
186 assert(driContextPriv);
187 assert(screen);
188
189 /* Allocate the R300 context */
190 r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
191 if (!r300)
192 return GL_FALSE;
193
194 /* Parse configuration files.
195 * Do this here so that initialMaxAnisotropy is set before we create
196 * the default textures.
197 */
198 driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
199 screen->driScreen->myNum, "r300");
200 r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
201 "def_max_anisotropy");
202
203 //r300->texmicrotile = GL_TRUE;
204
205 /* Init default driver functions then plug in our R300-specific functions
206 * (the texture functions are especially important)
207 */
208 _mesa_init_driver_functions(&functions);
209 r300InitIoctlFuncs(&functions);
210 r300InitStateFuncs(&functions);
211 r300InitTextureFuncs(&functions);
212 r300InitShaderFuncs(&functions);
213
214 #ifdef USER_BUFFERS
215 radeon_mm_init(r300);
216 #endif
217 #ifdef HW_VBOS
218 if (hw_tcl_on) {
219 r300_init_vbo_funcs(&functions);
220 }
221 #endif
222 if (!radeonInitContext(&r300->radeon, &functions,
223 glVisual, driContextPriv, sharedContextPrivate)) {
224 FREE(r300);
225 return GL_FALSE;
226 }
227
228 /* Init r300 context data */
229 r300->dma.buf0_address = r300->radeon.radeonScreen->buffers->list[0].address;
230
231 (void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
232 make_empty_list(&r300->swapped);
233
234 r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
235 assert(r300->nr_heaps < RADEON_NR_TEX_HEAPS);
236 for (i = 0; i < r300->nr_heaps; i++) {
237 r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
238 screen->
239 texSize[i], 12,
240 RADEON_NR_TEX_REGIONS,
241 (drmTextureRegionPtr)
242 r300->radeon.sarea->
243 tex_list[i],
244 &r300->radeon.sarea->
245 tex_age[i],
246 &r300->swapped,
247 sizeof
248 (r300TexObj),
249 (destroy_texture_object_t
250 *)
251 r300DestroyTexObj);
252 }
253 r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
254 "texture_depth");
255 if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
256 r300->texture_depth = (screen->cpp == 4) ?
257 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
258
259 /* Set the maximum texture size small enough that we can guarentee that
260 * all texture units can bind a maximal texture and have them both in
261 * texturable memory at once.
262 */
263
264 ctx = r300->radeon.glCtx;
265
266 ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
267 "texture_image_units");
268 ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
269 "texture_coord_units");
270 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
271 ctx->Const.MaxTextureCoordUnits);
272 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
273
274 ctx->Const.MinPointSize = 1.0;
275 ctx->Const.MinPointSizeAA = 1.0;
276 ctx->Const.MaxPointSize = R300_POINTSIZE_MAX;
277 ctx->Const.MaxPointSizeAA = R300_POINTSIZE_MAX;
278
279 ctx->Const.MinLineWidth = 1.0;
280 ctx->Const.MinLineWidthAA = 1.0;
281 ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
282 ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
283
284 #ifdef USER_BUFFERS
285 /* Needs further modifications */
286 #if 0
287 ctx->Const.MaxArrayLockSize = (/*512*/RADEON_BUFFER_SIZE*16*1024) / (4*4);
288 #endif
289 #endif
290
291 /* Initialize the software rasterizer and helper modules.
292 */
293 _swrast_CreateContext(ctx);
294 _vbo_CreateContext(ctx);
295 _tnl_CreateContext(ctx);
296 _swsetup_CreateContext(ctx);
297 _swsetup_Wakeup(ctx);
298 _ae_create_context(ctx);
299
300 /* Install the customized pipeline:
301 */
302 _tnl_destroy_pipeline(ctx);
303 _tnl_install_pipeline(ctx, r300_pipeline);
304
305 /* Try and keep materials and vertices separate:
306 */
307 /* _tnl_isolate_materials(ctx, GL_TRUE); */
308
309 /* Configure swrast and TNL to match hardware characteristics:
310 */
311 _swrast_allow_pixel_fog(ctx, GL_FALSE);
312 _swrast_allow_vertex_fog(ctx, GL_TRUE);
313 _tnl_allow_pixel_fog(ctx, GL_FALSE);
314 _tnl_allow_vertex_fog(ctx, GL_TRUE);
315
316 /* currently bogus data */
317 ctx->Const.VertexProgram.MaxInstructions=VSF_MAX_FRAGMENT_LENGTH/4;
318 ctx->Const.VertexProgram.MaxNativeInstructions=VSF_MAX_FRAGMENT_LENGTH/4;
319 ctx->Const.VertexProgram.MaxNativeAttribs=16; /* r420 */
320 ctx->Const.VertexProgram.MaxTemps=32;
321 ctx->Const.VertexProgram.MaxNativeTemps=/*VSF_MAX_FRAGMENT_TEMPS*/32;
322 ctx->Const.VertexProgram.MaxNativeParameters=256; /* r420 */
323 ctx->Const.VertexProgram.MaxNativeAddressRegs=1;
324
325 ctx->Const.FragmentProgram.MaxNativeTemps = PFS_NUM_TEMP_REGS;
326 ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
327 ctx->Const.FragmentProgram.MaxNativeParameters = PFS_NUM_CONST_REGS;
328 ctx->Const.FragmentProgram.MaxNativeAluInstructions = PFS_MAX_ALU_INST;
329 ctx->Const.FragmentProgram.MaxNativeTexInstructions = PFS_MAX_TEX_INST;
330 ctx->Const.FragmentProgram.MaxNativeInstructions = PFS_MAX_ALU_INST+PFS_MAX_TEX_INST;
331 ctx->Const.FragmentProgram.MaxNativeTexIndirections = PFS_MAX_TEX_INDIRECT;
332 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
333 _tnl_ProgramCacheInit(ctx);
334 ctx->_MaintainTexEnvProgram = GL_TRUE;
335
336 driInitExtensions(ctx, card_extensions, GL_TRUE);
337
338 if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0)
339 driInitSingleExtension(ctx, stencil_two_side);
340
341 if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) {
342 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
343 _mesa_enable_extension( ctx, "GL_S3_s3tc" );
344 }
345 else if (driQueryOptionb (&r300->radeon.optionCache, "force_s3tc_enable")) {
346 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
347 }
348
349 r300->disable_lowimpact_fallback = driQueryOptionb(&r300->radeon.optionCache, "disable_lowimpact_fallback");
350
351 radeonInitSpanFuncs(ctx);
352 r300InitCmdBuf(r300);
353 r300InitState(r300);
354
355 #ifdef RADEON_VTXFMT_A
356 radeon_init_vtxfmt_a(r300);
357 #endif
358
359 #if 0
360 /* plug in a few more device driver functions */
361 /* XXX these should really go right after _mesa_init_driver_functions() */
362 r300InitPixelFuncs(ctx);
363 r300InitSwtcl(ctx);
364 #endif
365 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
366
367 tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
368 if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
369 fprintf(stderr, "disabling 3D acceleration\n");
370 #if R200_MERGED
371 FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
372 #endif
373 }
374 if (tcl_mode == DRI_CONF_TCL_SW ||
375 !(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
376 if (r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
377 r300->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
378 fprintf(stderr, "Disabling HW TCL support\n");
379 }
380 TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
381 }
382
383 return GL_TRUE;
384 }
385
386 static void r300FreeGartAllocations(r300ContextPtr r300)
387 {
388 int i, ret, tries=0, done_age, in_use=0;
389 drm_radeon_mem_free_t memfree;
390
391 memfree.region = RADEON_MEM_REGION_GART;
392
393 #ifdef USER_BUFFERS
394 for (i = r300->rmm->u_last; i > 0; i--) {
395 if (r300->rmm->u_list[i].ptr == NULL) {
396 continue;
397 }
398
399 /* check whether this buffer is still in use */
400 if (r300->rmm->u_list[i].pending) {
401 in_use++;
402 }
403 }
404 /* Cannot flush/lock if no context exists. */
405 if (in_use)
406 r300FlushCmdBuf(r300, __FUNCTION__);
407
408 done_age = radeonGetAge((radeonContextPtr)r300);
409
410 for (i = r300->rmm->u_last; i > 0; i--) {
411 if (r300->rmm->u_list[i].ptr == NULL) {
412 continue;
413 }
414
415 /* check whether this buffer is still in use */
416 if (!r300->rmm->u_list[i].pending) {
417 continue;
418 }
419
420 assert(r300->rmm->u_list[i].h_pending == 0);
421
422 tries = 0;
423 while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
424 usleep(10);
425 done_age = radeonGetAge((radeonContextPtr)r300);
426 }
427 if (tries >= 1000) {
428 WARN_ONCE("Failed to idle region!");
429 }
430
431 memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
432 (char *)r300->radeon.radeonScreen->gartTextures.map;
433
434 ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
435 DRM_RADEON_FREE, &memfree, sizeof(memfree));
436 if (ret) {
437 fprintf(stderr, "Failed to free at %p\nret = %s\n",
438 r300->rmm->u_list[i].ptr, strerror(-ret));
439 } else {
440 if (i == r300->rmm->u_last)
441 r300->rmm->u_last--;
442
443 r300->rmm->u_list[i].pending = 0;
444 r300->rmm->u_list[i].ptr = NULL;
445 if (r300->rmm->u_list[i].fb) {
446 LOCK_HARDWARE(&(r300->radeon));
447 ret = mmFreeMem(r300->rmm->u_list[i].fb);
448 UNLOCK_HARDWARE(&(r300->radeon));
449 if (ret) fprintf(stderr, "failed to free!\n");
450 r300->rmm->u_list[i].fb = NULL;
451 }
452 r300->rmm->u_list[i].ref_count = 0;
453 }
454 }
455 r300->rmm->u_head = i;
456 #endif /* USER_BUFFERS */
457 }
458
459 /* Destroy the device specific context.
460 */
461 void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
462 {
463 GET_CURRENT_CONTEXT(ctx);
464 r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
465 radeonContextPtr radeon = (radeonContextPtr) r300;
466 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
467
468 if (RADEON_DEBUG & DEBUG_DRI) {
469 fprintf(stderr, "Destroying context !\n");
470 }
471
472 /* check if we're deleting the currently bound context */
473 if (&r300->radeon == current) {
474 radeonFlush(r300->radeon.glCtx);
475 _mesa_make_current(NULL, NULL, NULL);
476 }
477
478 /* Free r300 context resources */
479 assert(r300); /* should never be null */
480
481 if (r300) {
482 GLboolean release_texture_heaps;
483
484 release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
485 _swsetup_DestroyContext(r300->radeon.glCtx);
486 _tnl_ProgramCacheDestroy(r300->radeon.glCtx);
487 _tnl_DestroyContext(r300->radeon.glCtx);
488 _vbo_DestroyContext(r300->radeon.glCtx);
489 _swrast_DestroyContext(r300->radeon.glCtx);
490
491 if (r300->dma.current.buf) {
492 r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ );
493 #ifndef USER_BUFFERS
494 r300FlushCmdBuf(r300, __FUNCTION__);
495 #endif
496 }
497 r300FreeGartAllocations(r300);
498 r300DestroyCmdBuf(r300);
499
500 if (radeon->state.scissor.pClipRects) {
501 FREE(radeon->state.scissor.pClipRects);
502 radeon->state.scissor.pClipRects = NULL;
503 }
504
505 if (release_texture_heaps) {
506 /* This share group is about to go away, free our private
507 * texture object data.
508 */
509 int i;
510
511 for (i = 0; i < r300->nr_heaps; i++) {
512 driDestroyTextureHeap(r300->texture_heaps[i]);
513 r300->texture_heaps[i] = NULL;
514 }
515
516 assert(is_empty_list(&r300->swapped));
517 }
518
519 radeonCleanupContext(&r300->radeon);
520
521 #ifdef USER_BUFFERS
522 /* the memory manager might be accessed when Mesa frees the shared
523 * state, so don't destroy it earlier
524 */
525 radeon_mm_destroy(r300);
526 #endif
527
528 /* free the option cache */
529 driDestroyOptionCache(&r300->radeon.optionCache);
530
531 FREE(r300);
532 }
533 }