Major rip-up of internal function insertion interface. The old
[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 "array_cache/acache.h"
48
49 #include "tnl/tnl.h"
50 #include "tnl/t_pipeline.h"
51
52 #include "drivers/common/driverfuncs.h"
53
54 #include "radeon_ioctl.h"
55 #include "radeon_span.h"
56 #include "r300_context.h"
57 #include "r300_cmdbuf.h"
58 #include "r300_state.h"
59 #include "r300_ioctl.h"
60 #include "r300_tex.h"
61
62 #include "vblank.h"
63 #include "utils.h"
64 #include "xmlpool.h" /* for symbolic values of enum-type options */
65
66 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
67 int future_hw_tcl_on=0;
68 int hw_tcl_on=0;
69
70 #if 1
71 #define need_GL_ARB_multisample
72 #define need_GL_ARB_texture_compression
73 #define need_GL_EXT_blend_minmax
74 #include "extension_helper.h"
75
76 const struct dri_extension card_extensions[] = {
77 {"GL_ARB_multisample", GL_ARB_multisample_functions},
78 {"GL_ARB_multitexture", NULL},
79 {"GL_ARB_texture_border_clamp", NULL},
80 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
81 /* disable until we support it, fixes a few things in ut2004 */
82 /* {"GL_ARB_texture_cube_map", NULL}, */
83 {"GL_ARB_texture_env_add", NULL},
84 {"GL_ARB_texture_env_combine", NULL},
85 {"GL_ARB_texture_env_crossbar", NULL},
86 {"GL_ARB_texture_env_dot3", NULL},
87 {"GL_ARB_texture_mirrored_repeat", NULL},
88 {"GL_ARB_vertex_buffer_object", NULL},
89 {"GL_ARB_vertex_program", NULL},
90 #if USE_ARB_F_P == 1
91 {"GL_ARB_fragment_program", NULL},
92 #endif
93 {"GL_EXT_blend_equation_separate", NULL},
94 {"GL_EXT_blend_func_separate", NULL},
95 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
96 {"GL_EXT_blend_subtract", NULL},
97 {"GL_EXT_secondary_color", NULL},
98 {"GL_EXT_stencil_wrap", NULL},
99 {"GL_EXT_texture_edge_clamp", NULL},
100 {"GL_EXT_texture_env_combine", NULL},
101 {"GL_EXT_texture_env_dot3", NULL},
102 {"GL_EXT_texture_filter_anisotropic", NULL},
103 {"GL_EXT_texture_lod_bias", NULL},
104 {"GL_EXT_texture_mirror_clamp", NULL},
105 {"GL_EXT_texture_rectangle", NULL},
106 {"GL_ATI_texture_env_combine3", NULL},
107 {"GL_ATI_texture_mirror_once", NULL},
108 {"GL_MESA_pack_invert", NULL},
109 {"GL_MESA_ycbcr_texture", NULL},
110 {"GL_NV_blend_square", NULL},
111 {"GL_NV_vertex_program", NULL},
112 {"GL_SGIS_generate_mipmap", NULL},
113 {NULL, NULL}
114 };
115
116 #else
117 /* Extension strings exported by the R300 driver.
118 */
119 static const char *const card_extensions[] = {
120 "GL_ARB_multisample",
121 "GL_ARB_multitexture",
122 "GL_ARB_texture_border_clamp",
123 "GL_ARB_texture_compression",
124 /* disable until we support it, fixes a few things in ut2004 */
125 /* "GL_ARB_texture_cube_map", */
126 "GL_ARB_texture_env_add",
127 "GL_ARB_texture_env_combine",
128 "GL_ARB_texture_env_crossbar",
129 "GL_ARB_texture_env_dot3",
130 "GL_ARB_texture_mirrored_repeat",
131 "GL_ARB_vertex_buffer_object",
132 "GL_ARB_vertex_program",
133 #if USE_ARB_F_P == 1
134 "GL_ARB_fragment_program",
135 #endif
136 "GL_EXT_blend_equation_separate",
137 "GL_EXT_blend_func_separate",
138 "GL_EXT_blend_minmax",
139 "GL_EXT_blend_subtract",
140 "GL_EXT_secondary_color",
141 "GL_EXT_stencil_wrap",
142 "GL_EXT_texture_edge_clamp",
143 "GL_EXT_texture_env_combine",
144 "GL_EXT_texture_env_dot3",
145 "GL_EXT_texture_filter_anisotropic",
146 "GL_EXT_texture_lod_bias",
147 "GL_EXT_texture_mirror_clamp",
148 "GL_EXT_texture_rectangle",
149 "GL_ATI_texture_env_combine3",
150 "GL_ATI_texture_mirror_once",
151 "GL_MESA_pack_invert",
152 "GL_MESA_ycbcr_texture",
153 "GL_NV_blend_square",
154 "GL_NV_vertex_program",
155 "GL_SGIS_generate_mipmap",
156 NULL
157 };
158 #endif
159 extern struct tnl_pipeline_stage _r300_render_stage;
160 extern struct tnl_pipeline_stage _r300_tcl_stage;
161
162 static const struct tnl_pipeline_stage *r300_pipeline[] = {
163
164 /* Try and go straight to t&l
165 */
166 &_r300_tcl_stage,
167
168 /* Catch any t&l fallbacks
169 */
170 &_tnl_vertex_transform_stage,
171 &_tnl_normal_transform_stage,
172 &_tnl_lighting_stage,
173 &_tnl_fog_coordinate_stage,
174 &_tnl_texgen_stage,
175 &_tnl_texture_transform_stage,
176 &_tnl_vertex_program_stage,
177
178 /* Try again to go to tcl?
179 * - no good for asymmetric-twoside (do with multipass)
180 * - no good for asymmetric-unfilled (do with multipass)
181 * - good for material
182 * - good for texgen
183 * - need to manipulate a bit of state
184 *
185 * - worth it/not worth it?
186 */
187
188 /* Else do them here.
189 */
190 &_r300_render_stage,
191 &_tnl_render_stage, /* FALLBACK */
192 0,
193 };
194
195 static void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
196 const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
197 {
198 r300ContextPtr rmesa = R300_CONTEXT(ctx);
199 drm_radeon_mem_alloc_t alloc;
200 int offset, ret;
201
202 /* Free previous buffer */
203 if (obj->OnCard) {
204 drm_radeon_mem_free_t memfree;
205
206 memfree.region = RADEON_MEM_REGION_GART;
207 memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
208
209 ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
210 DRM_RADEON_FREE, &memfree, sizeof(memfree));
211
212 if (ret) {
213 WARN_ONCE("Failed to free GART memroy!\n");
214 }
215 obj->OnCard = GL_FALSE;
216 }
217
218 alloc.region = RADEON_MEM_REGION_GART;
219 alloc.alignment = 4;
220 alloc.size = size;
221 alloc.region_offset = &offset;
222
223 ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, sizeof(alloc));
224 if (ret) {
225 WARN_ONCE("Ran out of GART memory!\n");
226 obj->Data = NULL;
227 _mesa_buffer_data(ctx, target, size, data, usage, obj);
228 return ;
229 }
230 obj->Data = ((char *)rmesa->radeon.radeonScreen->gartTextures.map) + offset;
231
232 if (data)
233 memcpy(obj->Data, data, size);
234
235 obj->Size = size;
236 obj->Usage = usage;
237 obj->OnCard = GL_TRUE;
238 #if 0
239 fprintf(stderr, "allocated %d bytes at %p, offset=%d\n", size, obj->Data, offset);
240 #endif
241 }
242
243 static void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
244 {
245 r300ContextPtr rmesa = R300_CONTEXT(ctx);
246
247 if(r300IsGartMemory(rmesa, obj->Data, obj->Size)){
248 drm_radeon_mem_free_t memfree;
249 int ret;
250
251 memfree.region = RADEON_MEM_REGION_GART;
252 memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
253
254 ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
255 DRM_RADEON_FREE, &memfree, sizeof(memfree));
256
257 if(ret){
258 WARN_ONCE("Failed to free GART memroy!\n");
259 }
260 obj->Data = NULL;
261 }
262 _mesa_delete_buffer_object(ctx, obj);
263 }
264
265 /* Create the device specific rendering context.
266 */
267 GLboolean r300CreateContext(const __GLcontextModes * glVisual,
268 __DRIcontextPrivate * driContextPriv,
269 void *sharedContextPrivate)
270 {
271 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
272 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
273 struct dd_function_table functions;
274 r300ContextPtr r300;
275 GLcontext *ctx;
276 int tcl_mode, i;
277
278 assert(glVisual);
279 assert(driContextPriv);
280 assert(screen);
281
282 /* Allocate the R300 context */
283 r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
284 if (!r300)
285 return GL_FALSE;
286
287 /* Parse configuration files.
288 * Do this here so that initialMaxAnisotropy is set before we create
289 * the default textures.
290 */
291 driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
292 screen->driScreen->myNum, "r300");
293
294 /* Init default driver functions then plug in our R300-specific functions
295 * (the texture functions are especially important)
296 */
297 _mesa_init_driver_functions(&functions);
298 r300InitIoctlFuncs(&functions);
299 r300InitStateFuncs(&functions);
300 r300InitTextureFuncs(&functions);
301 r300InitShaderFuncs(&functions);
302
303 #if 0 /* Needs various Mesa changes... */
304 if (hw_tcl_on) {
305 functions.BufferData = r300BufferData;
306 functions.DeleteBuffer = r300DeleteBuffer;
307 }
308 #endif
309
310 if (!radeonInitContext(&r300->radeon, &functions,
311 glVisual, driContextPriv, sharedContextPrivate)) {
312 FREE(r300);
313 return GL_FALSE;
314 }
315
316 /* Init r300 context data */
317 r300->dma.buf0_address = r300->radeon.radeonScreen->buffers->list[0].address;
318
319 (void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
320 make_empty_list(&r300->swapped);
321
322 r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
323 assert(r300->nr_heaps < R200_NR_TEX_HEAPS);
324 for (i = 0; i < r300->nr_heaps; i++) {
325 r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
326 screen->
327 texSize[i], 12,
328 RADEON_NR_TEX_REGIONS,
329 (drmTextureRegionPtr)
330 r300->radeon.sarea->
331 tex_list[i],
332 &r300->radeon.sarea->
333 tex_age[i],
334 &r300->swapped,
335 sizeof
336 (r300TexObj),
337 (destroy_texture_object_t
338 *)
339 r300DestroyTexObj);
340 }
341 r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
342 "texture_depth");
343 if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
344 r300->texture_depth = (screen->cpp == 4) ?
345 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
346
347 /* Set the maximum texture size small enough that we can guarentee that
348 * all texture units can bind a maximal texture and have them both in
349 * texturable memory at once.
350 */
351
352 ctx = r300->radeon.glCtx;
353
354 ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
355 "texture_image_units");
356 ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
357 "texture_coord_units");
358 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
359 ctx->Const.MaxTextureCoordUnits);
360 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
361
362 ctx->Const.MinPointSize = 1.0;
363 ctx->Const.MinPointSizeAA = 1.0;
364 ctx->Const.MaxPointSize = R300_POINTSIZE_MAX;
365 ctx->Const.MaxPointSizeAA = R300_POINTSIZE_MAX;
366
367 ctx->Const.MinLineWidth = 1.0;
368 ctx->Const.MinLineWidthAA = 1.0;
369 ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
370 ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
371
372 /* Initialize the software rasterizer and helper modules.
373 */
374 _swrast_CreateContext(ctx);
375 _ac_CreateContext(ctx);
376 _tnl_CreateContext(ctx);
377 _swsetup_CreateContext(ctx);
378 _swsetup_Wakeup(ctx);
379 _ae_create_context(ctx);
380
381 /* Install the customized pipeline:
382 */
383 _tnl_destroy_pipeline(ctx);
384 _tnl_install_pipeline(ctx, r300_pipeline);
385
386 /* Try and keep materials and vertices separate:
387 */
388 _tnl_isolate_materials(ctx, GL_TRUE);
389
390 /* Configure swrast and TNL to match hardware characteristics:
391 */
392 _swrast_allow_pixel_fog(ctx, GL_FALSE);
393 _swrast_allow_vertex_fog(ctx, GL_TRUE);
394 _tnl_allow_pixel_fog(ctx, GL_FALSE);
395 _tnl_allow_vertex_fog(ctx, GL_TRUE);
396
397 /* currently bogus data */
398 ctx->Const.MaxVertexProgramInstructions=VSF_MAX_FRAGMENT_LENGTH;
399 ctx->Const.MaxVertexProgramAttribs=16; // r420
400 ctx->Const.MaxVertexProgramTemps=VSF_MAX_FRAGMENT_TEMPS;
401 ctx->Const.MaxVertexProgramLocalParams=256; // r420
402 ctx->Const.MaxVertexProgramEnvParams=256; // r420
403 ctx->Const.MaxVertexProgramAddressRegs=1;
404
405 #if USE_ARB_F_P
406 ctx->Const.MaxFragmentProgramTemps = PFS_NUM_TEMP_REGS;
407 ctx->Const.MaxFragmentProgramAttribs = 11; /* copy i915... */
408 ctx->Const.MaxFragmentProgramLocalParams = PFS_NUM_CONST_REGS;
409 ctx->Const.MaxFragmentProgramEnvParams = PFS_NUM_CONST_REGS;
410 ctx->Const.MaxFragmentProgramAluInstructions = PFS_MAX_ALU_INST;
411 ctx->Const.MaxFragmentProgramTexInstructions = PFS_MAX_TEX_INST;
412 ctx->Const.MaxFragmentProgramInstructions = PFS_MAX_ALU_INST+PFS_MAX_TEX_INST;
413 ctx->Const.MaxFragmentProgramTexIndirections = PFS_MAX_TEX_INDIRECT;
414 ctx->Const.MaxFragmentProgramAddressRegs = 0; /* and these are?? */
415 ctx->_MaintainTexEnvProgram = GL_TRUE;
416 #endif
417
418 driInitExtensions(ctx, card_extensions, GL_TRUE);
419
420 radeonInitSpanFuncs(ctx);
421 r300InitCmdBuf(r300);
422 r300InitState(r300);
423
424 #if 0
425 /* plug in a few more device driver functions */
426 /* XXX these should really go right after _mesa_init_driver_functions() */
427 r300InitPixelFuncs(ctx);
428 r300InitSwtcl(ctx);
429 #endif
430 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
431
432 tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
433 if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
434 fprintf(stderr, "disabling 3D acceleration\n");
435 #if R200_MERGED
436 FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
437 #endif
438 }
439 if (tcl_mode == DRI_CONF_TCL_SW ||
440 !(r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
441 if (r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) {
442 r300->radeon.radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
443 fprintf(stderr, "Disabling HW TCL support\n");
444 }
445 TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
446 }
447
448 return GL_TRUE;
449 }
450
451 /* Destroy the device specific context.
452 */
453 void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
454 {
455 GET_CURRENT_CONTEXT(ctx);
456 r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
457 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
458
459 if (RADEON_DEBUG & DEBUG_DRI) {
460 fprintf(stderr, "Destroying context !\n");
461 }
462
463 /* check if we're deleting the currently bound context */
464 if (&r300->radeon == current) {
465 radeonFlush(r300->radeon.glCtx);
466 _mesa_make_current(NULL, NULL, NULL);
467 }
468
469 /* Free r300 context resources */
470 assert(r300); /* should never be null */
471
472 if (r300) {
473 GLboolean release_texture_heaps;
474
475 release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
476 _swsetup_DestroyContext(r300->radeon.glCtx);
477 _tnl_DestroyContext(r300->radeon.glCtx);
478 _ac_DestroyContext(r300->radeon.glCtx);
479 _swrast_DestroyContext(r300->radeon.glCtx);
480
481 r300DestroyCmdBuf(r300);
482
483 radeonCleanupContext(&r300->radeon);
484
485 /* free the option cache */
486 driDestroyOptionCache(&r300->radeon.optionCache);
487
488 FREE(r300);
489 }
490 }