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