radeon/r200/r300: another big merge upheavel.
[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 "main/glheader.h"
39 #include "main/api_arrayelt.h"
40 #include "main/context.h"
41 #include "main/simple_list.h"
42 #include "main/imports.h"
43 #include "main/matrix.h"
44 #include "main/extensions.h"
45 #include "main/state.h"
46 #include "main/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_span.h"
59 #include "r300_context.h"
60 #include "r300_cmdbuf.h"
61 #include "r300_state.h"
62 #include "r300_ioctl.h"
63 #include "r300_tex.h"
64 #include "r300_emit.h"
65 #include "r300_swtcl.h"
66 #include "radeon_bo_legacy.h"
67
68
69 #include "vblank.h"
70 #include "utils.h"
71 #include "xmlpool.h" /* for symbolic values of enum-type options */
72
73 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
74 int future_hw_tcl_on = 1;
75 int hw_tcl_on = 1;
76
77 #define need_GL_EXT_stencil_two_side
78 #define need_GL_ARB_multisample
79 #define need_GL_ARB_point_parameters
80 #define need_GL_ARB_texture_compression
81 #define need_GL_ARB_vertex_buffer_object
82 #define need_GL_ARB_vertex_program
83 #define need_GL_EXT_blend_minmax
84 //#define need_GL_EXT_fog_coord
85 #define need_GL_EXT_multi_draw_arrays
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_depth_texture", NULL},
96 {"GL_ARB_fragment_program", NULL},
97 {"GL_ARB_multisample", GL_ARB_multisample_functions},
98 {"GL_ARB_multitexture", NULL},
99 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
100 {"GL_ARB_shadow", NULL},
101 {"GL_ARB_shadow_ambient", NULL},
102 {"GL_ARB_texture_border_clamp", NULL},
103 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
104 {"GL_ARB_texture_cube_map", NULL},
105 {"GL_ARB_texture_env_add", NULL},
106 {"GL_ARB_texture_env_combine", NULL},
107 {"GL_ARB_texture_env_crossbar", NULL},
108 {"GL_ARB_texture_env_dot3", NULL},
109 {"GL_ARB_texture_mirrored_repeat", NULL},
110 {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
111 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
112 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
113 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
114 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
115 {"GL_EXT_blend_subtract", NULL},
116 // {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
117 {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
118 {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
119 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
120 {"GL_EXT_shadow_funcs", NULL},
121 {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
122 {"GL_EXT_stencil_wrap", NULL},
123 {"GL_EXT_texture_edge_clamp", NULL},
124 {"GL_EXT_texture_env_combine", NULL},
125 {"GL_EXT_texture_env_dot3", NULL},
126 {"GL_EXT_texture_filter_anisotropic", NULL},
127 {"GL_EXT_texture_lod_bias", NULL},
128 {"GL_EXT_texture_mirror_clamp", NULL},
129 {"GL_EXT_texture_rectangle", NULL},
130 {"GL_ATI_texture_env_combine3", NULL},
131 {"GL_ATI_texture_mirror_once", NULL},
132 {"GL_MESA_pack_invert", NULL},
133 {"GL_MESA_ycbcr_texture", NULL},
134 {"GL_MESAX_texture_float", NULL},
135 {"GL_NV_blend_square", NULL},
136 {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
137 {"GL_SGIS_generate_mipmap", NULL},
138 {NULL, NULL}
139 /* *INDENT-ON* */
140 };
141
142 extern struct tnl_pipeline_stage _r300_render_stage;
143 extern const struct tnl_pipeline_stage _r300_tcl_stage;
144
145 static const struct tnl_pipeline_stage *r300_pipeline[] = {
146
147 /* Try and go straight to t&l
148 */
149 &_r300_tcl_stage,
150
151 /* Catch any t&l fallbacks
152 */
153 &_tnl_vertex_transform_stage,
154 &_tnl_normal_transform_stage,
155 &_tnl_lighting_stage,
156 &_tnl_fog_coordinate_stage,
157 &_tnl_texgen_stage,
158 &_tnl_texture_transform_stage,
159 &_tnl_vertex_program_stage,
160
161 /* Try again to go to tcl?
162 * - no good for asymmetric-twoside (do with multipass)
163 * - no good for asymmetric-unfilled (do with multipass)
164 * - good for material
165 * - good for texgen
166 * - need to manipulate a bit of state
167 *
168 * - worth it/not worth it?
169 */
170
171 /* Else do them here.
172 */
173 &_r300_render_stage,
174 &_tnl_render_stage, /* FALLBACK */
175 0,
176 };
177
178 static void r300RunPipeline(GLcontext * ctx)
179 {
180 _mesa_lock_context_textures(ctx);
181
182 if (ctx->NewState)
183 _mesa_update_state_locked(ctx);
184
185 _tnl_run_pipeline(ctx);
186 _mesa_unlock_context_textures(ctx);
187 }
188
189 static void r300_get_lock(radeonContextPtr rmesa)
190 {
191 drm_radeon_sarea_t *sarea = rmesa->sarea;
192
193 if (sarea->ctx_owner != rmesa->dri.hwContext) {
194 sarea->ctx_owner = rmesa->dri.hwContext;
195 if (!rmesa->radeonScreen->kernel_mm)
196 radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom);
197 }
198 }
199
200 static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
201 {
202 /* please flush pipe do all pending work */
203 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
204 R300_SC_SCREENDOOR, 1));
205 radeon_cs_write_dword(cs, 0x0);
206 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
207 R300_SC_SCREENDOOR, 1));
208 radeon_cs_write_dword(cs, 0x00FFFFFF);
209 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
210 R300_SC_HYPERZ, 1));
211 radeon_cs_write_dword(cs, 0x0);
212 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
213 R300_US_CONFIG, 1));
214 radeon_cs_write_dword(cs, 0x0);
215 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
216 R300_ZB_CNTL, 1));
217 radeon_cs_write_dword(cs, 0x0);
218 radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen, R300_WAIT_3D));
219 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
220 R300_RB3D_DSTCACHE_CTLSTAT, 1));
221 radeon_cs_write_dword(cs, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
222 radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
223 R300_ZB_ZCACHE_CTLSTAT, 1));
224 radeon_cs_write_dword(cs, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE);
225 radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen,
226 R300_WAIT_3D | R300_WAIT_3D_CLEAN));
227 }
228
229 static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
230 {
231 BATCH_LOCALS(radeon);
232 cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
233 BEGIN_BATCH_NO_AUTOSTATE(2);
234 OUT_BATCH(cmdpacket0(radeon->radeonScreen, R300_TX_INVALTAGS, 1));
235 OUT_BATCH(R300_TX_FLUSH);
236 END_BATCH();
237 end_3d(radeon);
238 }
239
240 static void r300_init_vtbl(radeonContextPtr radeon)
241 {
242 radeon->vtbl.get_lock = r300_get_lock;
243 radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset;
244 radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer;
245 radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header;
246 radeon->vtbl.swtcl_flush = r300_swtcl_flush;
247 radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
248 }
249
250
251 /* Create the device specific rendering context.
252 */
253 GLboolean r300CreateContext(const __GLcontextModes * glVisual,
254 __DRIcontextPrivate * driContextPriv,
255 void *sharedContextPrivate)
256 {
257 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
258 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
259 struct dd_function_table functions;
260 r300ContextPtr r300;
261 GLcontext *ctx;
262 int tcl_mode;
263
264 assert(glVisual);
265 assert(driContextPriv);
266 assert(screen);
267
268 /* Allocate the R300 context */
269 r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
270 if (!r300)
271 return GL_FALSE;
272
273 if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
274 hw_tcl_on = future_hw_tcl_on = 0;
275
276 r300_init_vtbl(&r300->radeon);
277 /* Parse configuration files.
278 * Do this here so that initialMaxAnisotropy is set before we create
279 * the default textures.
280 */
281 driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
282 screen->driScreen->myNum, "r300");
283 r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
284 "def_max_anisotropy");
285
286 /* Init default driver functions then plug in our R300-specific functions
287 * (the texture functions are especially important)
288 */
289 _mesa_init_driver_functions(&functions);
290 r300InitIoctlFuncs(&functions);
291 r300InitStateFuncs(&functions);
292 r300InitTextureFuncs(&functions);
293 r300InitShaderFuncs(&functions);
294
295 if (!radeonInitContext(&r300->radeon, &functions,
296 glVisual, driContextPriv,
297 sharedContextPrivate)) {
298 FREE(r300);
299 return GL_FALSE;
300 }
301
302 /* Init r300 context data */
303 r300->radeon.texture_depth = driQueryOptioni(&r300->radeon.optionCache,
304 "texture_depth");
305 if (r300->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
306 r300->radeon.texture_depth = (screen->cpp == 4) ?
307 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
308
309 /* Set the maximum texture size small enough that we can guarentee that
310 * all texture units can bind a maximal texture and have them both in
311 * texturable memory at once.
312 */
313
314 ctx = r300->radeon.glCtx;
315
316 ctx->Const.MaxTextureImageUnits =
317 driQueryOptioni(&r300->radeon.optionCache, "texture_image_units");
318 ctx->Const.MaxTextureCoordUnits =
319 driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units");
320 ctx->Const.MaxTextureUnits =
321 MIN2(ctx->Const.MaxTextureImageUnits,
322 ctx->Const.MaxTextureCoordUnits);
323 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
324 ctx->Const.MaxTextureLodBias = 16.0;
325
326 if (screen->chip_family >= CHIP_FAMILY_RV515) {
327 ctx->Const.MaxTextureLevels = 13;
328 ctx->Const.MaxTextureRectSize = 4096;
329 }
330
331 ctx->Const.MinPointSize = 1.0;
332 ctx->Const.MinPointSizeAA = 1.0;
333 ctx->Const.MaxPointSize = R300_POINTSIZE_MAX;
334 ctx->Const.MaxPointSizeAA = R300_POINTSIZE_MAX;
335
336 ctx->Const.MinLineWidth = 1.0;
337 ctx->Const.MinLineWidthAA = 1.0;
338 ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
339 ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
340
341 /* Needs further modifications */
342 #if 0
343 ctx->Const.MaxArrayLockSize =
344 ( /*512 */ RADEON_BUFFER_SIZE * 16 * 1024) / (4 * 4);
345 #endif
346
347 /* Initialize the software rasterizer and helper modules.
348 */
349 _swrast_CreateContext(ctx);
350 _vbo_CreateContext(ctx);
351 _tnl_CreateContext(ctx);
352 _swsetup_CreateContext(ctx);
353 _swsetup_Wakeup(ctx);
354 _ae_create_context(ctx);
355
356 /* Install the customized pipeline:
357 */
358 _tnl_destroy_pipeline(ctx);
359 _tnl_install_pipeline(ctx, r300_pipeline);
360
361 /* Try and keep materials and vertices separate:
362 */
363 /* _tnl_isolate_materials(ctx, GL_TRUE); */
364
365 /* Configure swrast and TNL to match hardware characteristics:
366 */
367 _swrast_allow_pixel_fog(ctx, GL_FALSE);
368 _swrast_allow_vertex_fog(ctx, GL_TRUE);
369 _tnl_allow_pixel_fog(ctx, GL_FALSE);
370 _tnl_allow_vertex_fog(ctx, GL_TRUE);
371
372 /* currently bogus data */
373 if (screen->chip_flags & RADEON_CHIPSET_TCL) {
374 ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
375 ctx->Const.VertexProgram.MaxNativeInstructions =
376 VSF_MAX_FRAGMENT_LENGTH / 4;
377 ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */
378 ctx->Const.VertexProgram.MaxTemps = 32;
379 ctx->Const.VertexProgram.MaxNativeTemps =
380 /*VSF_MAX_FRAGMENT_TEMPS */ 32;
381 ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */
382 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
383 }
384
385 ctx->Const.FragmentProgram.MaxNativeTemps = PFS_NUM_TEMP_REGS;
386 ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
387 ctx->Const.FragmentProgram.MaxNativeParameters = PFS_NUM_CONST_REGS;
388 ctx->Const.FragmentProgram.MaxNativeAluInstructions = PFS_MAX_ALU_INST;
389 ctx->Const.FragmentProgram.MaxNativeTexInstructions = PFS_MAX_TEX_INST;
390 ctx->Const.FragmentProgram.MaxNativeInstructions =
391 PFS_MAX_ALU_INST + PFS_MAX_TEX_INST;
392 ctx->Const.FragmentProgram.MaxNativeTexIndirections =
393 PFS_MAX_TEX_INDIRECT;
394 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
395 ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
396 ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
397
398 driInitExtensions(ctx, card_extensions, GL_TRUE);
399
400 if (driQueryOptionb
401 (&r300->radeon.optionCache, "disable_stencil_two_side"))
402 _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
403
404 if (r300->radeon.glCtx->Mesa_DXTn
405 && !driQueryOptionb(&r300->radeon.optionCache, "disable_s3tc")) {
406 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
407 _mesa_enable_extension(ctx, "GL_S3_s3tc");
408 } else
409 if (driQueryOptionb(&r300->radeon.optionCache, "force_s3tc_enable"))
410 {
411 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
412 }
413
414 r300->disable_lowimpact_fallback =
415 driQueryOptionb(&r300->radeon.optionCache,
416 "disable_lowimpact_fallback");
417
418 radeonInitSpanFuncs( ctx );
419 r300InitCmdBuf(r300);
420 r300InitState(r300);
421 if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
422 r300InitSwtcl(ctx);
423
424 TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline;
425
426 tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
427 if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
428 fprintf(stderr, "disabling 3D acceleration\n");
429 #if R200_MERGED
430 FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
431 #endif
432 }
433 if (tcl_mode == DRI_CONF_TCL_SW ||
434 !(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
435 if (r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
436 r300->radeon.radeonScreen->chip_flags &=
437 ~RADEON_CHIPSET_TCL;
438 fprintf(stderr, "Disabling HW TCL support\n");
439 }
440 TCL_FALLBACK(r300->radeon.glCtx,
441 RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
442 }
443
444 return GL_TRUE;
445 }
446
447 /* Destroy the device specific context.
448 */
449 void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
450 {
451 GET_CURRENT_CONTEXT(ctx);
452 r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
453 radeonContextPtr radeon = (radeonContextPtr) r300;
454 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
455
456 if (RADEON_DEBUG & DEBUG_DRI) {
457 fprintf(stderr, "Destroying context !\n");
458 }
459
460 /* check if we're deleting the currently bound context */
461 if (&r300->radeon == current) {
462 radeonFlush(r300->radeon.glCtx);
463 _mesa_make_current(NULL, NULL, NULL);
464 }
465
466 /* Free r300 context resources */
467 assert(r300); /* should never be null */
468
469 if (r300) {
470 _swsetup_DestroyContext(r300->radeon.glCtx);
471 _tnl_DestroyContext(r300->radeon.glCtx);
472 _vbo_DestroyContext(r300->radeon.glCtx);
473 _swrast_DestroyContext(r300->radeon.glCtx);
474
475 rcommonFlushCmdBuf(&r300->radeon, __FUNCTION__);
476
477 if (radeon->state.scissor.pClipRects) {
478 FREE(radeon->state.scissor.pClipRects);
479 radeon->state.scissor.pClipRects = NULL;
480 }
481
482 r300DestroyCmdBuf(r300);
483
484 radeonCleanupContext(&r300->radeon);
485
486
487 /* the memory manager might be accessed when Mesa frees the shared
488 * state, so don't destroy it earlier
489 */
490
491
492 FREE(r300);
493 }
494 }