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