Huge dumb drop. State:
[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
36 #include "glheader.h"
37 #include "api_arrayelt.h"
38 #include "context.h"
39 #include "simple_list.h"
40 #include "imports.h"
41 #include "matrix.h"
42 #include "extensions.h"
43 #include "state.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
61 #include "vblank.h"
62 #include "utils.h"
63 #include "xmlpool.h" /* for symbolic values of enum-type options */
64
65
66 /* Extension strings exported by the R300 driver.
67 */
68 static const char *const card_extensions[] = {
69 "GL_ARB_multisample",
70 "GL_ARB_multitexture",
71 "GL_ARB_texture_border_clamp",
72 "GL_ARB_texture_compression",
73 "GL_ARB_texture_cube_map",
74 "GL_ARB_texture_env_add",
75 "GL_ARB_texture_env_combine",
76 "GL_ARB_texture_env_dot3",
77 "GL_ARB_texture_mirrored_repeat",
78 "GL_ARB_vertex_buffer_object",
79 "GL_ARB_vertex_program",
80 "GL_EXT_blend_equation_separate",
81 "GL_EXT_blend_func_separate",
82 "GL_EXT_blend_minmax",
83 "GL_EXT_blend_subtract",
84 "GL_EXT_secondary_color",
85 "GL_EXT_stencil_wrap",
86 "GL_EXT_texture_edge_clamp",
87 "GL_EXT_texture_env_combine",
88 "GL_EXT_texture_env_dot3",
89 "GL_EXT_texture_filter_anisotropic",
90 "GL_EXT_texture_lod_bias",
91 "GL_EXT_texture_mirror_clamp",
92 "GL_EXT_texture_rectangle",
93 "GL_ATI_texture_env_combine3",
94 "GL_ATI_texture_mirror_once",
95 "GL_MESA_pack_invert",
96 "GL_MESA_ycbcr_texture",
97 "GL_NV_blend_square",
98 "GL_NV_vertex_program",
99 "GL_SGIS_generate_mipmap",
100 NULL
101 };
102
103 #if 0
104 extern const struct tnl_pipeline_stage _r300_render_stage;
105 extern const struct tnl_pipeline_stage _r300_tcl_stage;
106
107 static const struct tnl_pipeline_stage *r300_pipeline[] = {
108
109 /* Try and go straight to t&l
110 */
111 &_r300_tcl_stage,
112
113 /* Catch any t&l fallbacks
114 */
115 &_tnl_vertex_transform_stage,
116 &_tnl_normal_transform_stage,
117 &_tnl_lighting_stage,
118 &_tnl_fog_coordinate_stage,
119 &_tnl_texgen_stage,
120 &_tnl_texture_transform_stage,
121 &_tnl_vertex_program_stage,
122
123 /* Try again to go to tcl?
124 * - no good for asymmetric-twoside (do with multipass)
125 * - no good for asymmetric-unfilled (do with multipass)
126 * - good for material
127 * - good for texgen
128 * - need to manipulate a bit of state
129 *
130 * - worth it/not worth it?
131 */
132
133 /* Else do them here.
134 */
135 &_r300_render_stage,
136 &_tnl_render_stage, /* FALLBACK */
137 0,
138 };
139 #endif
140
141 /* Create the device specific rendering context.
142 */
143 GLboolean r300CreateContext(const __GLcontextModes * glVisual,
144 __DRIcontextPrivate * driContextPriv,
145 void *sharedContextPrivate)
146 {
147 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
148 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
149 struct dd_function_table functions;
150 r300ContextPtr r300;
151 GLcontext *ctx;
152 int tcl_mode;
153
154 assert(glVisual);
155 assert(driContextPriv);
156 assert(screen);
157
158 /* Allocate the R300 context */
159 r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
160 if (!r300)
161 return GL_FALSE;
162
163 /* Parse configuration files.
164 * Do this here so that initialMaxAnisotropy is set before we create
165 * the default textures.
166 */
167 driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
168 screen->driScreen->myNum, "r300");
169
170 /* Init default driver functions then plug in our R300-specific functions
171 * (the texture functions are especially important)
172 */
173 _mesa_init_driver_functions(&functions);
174 r300InitIoctlFuncs(&functions);
175 //r200InitStateFuncs(&functions);
176 //r200InitTextureFuncs(&functions);
177
178 if (!radeonInitContext(&r300->radeon, &functions,
179 glVisual, driContextPriv, sharedContextPrivate)) {
180 FREE(r300);
181 return GL_FALSE;
182 }
183
184 /* Init r300 context data */
185
186 /* Set the maximum texture size small enough that we can guarentee that
187 * all texture units can bind a maximal texture and have them both in
188 * texturable memory at once.
189 */
190
191 ctx = r300->radeon.glCtx;
192 ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
193 "texture_image_units");
194 ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
195 "texture_coord_units");
196 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
197 ctx->Const.MaxTextureCoordUnits);
198 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
199
200 /* No wide points.
201 */
202 ctx->Const.MinPointSize = 1.0;
203 ctx->Const.MinPointSizeAA = 1.0;
204 ctx->Const.MaxPointSize = 1.0;
205 ctx->Const.MaxPointSizeAA = 1.0;
206
207 ctx->Const.MinLineWidth = 1.0;
208 ctx->Const.MinLineWidthAA = 1.0;
209 ctx->Const.MaxLineWidth = 1.0;
210 ctx->Const.MaxLineWidthAA = 1.0;
211
212 /* Initialize the software rasterizer and helper modules.
213 */
214 _swrast_CreateContext(ctx);
215 _ac_CreateContext(ctx);
216 _tnl_CreateContext(ctx);
217 _swsetup_CreateContext(ctx);
218 _ae_create_context(ctx);
219
220 #if 0
221 /* Install the customized pipeline:
222 */
223 _tnl_destroy_pipeline(ctx);
224 _tnl_install_pipeline(ctx, r200_pipeline);
225 ctx->Driver.FlushVertices = r200FlushVertices;
226 #endif
227
228 /* Try and keep materials and vertices separate:
229 */
230 _tnl_isolate_materials(ctx, GL_TRUE);
231
232 /* Configure swrast and TNL to match hardware characteristics:
233 */
234 _swrast_allow_pixel_fog(ctx, GL_FALSE);
235 _swrast_allow_vertex_fog(ctx, GL_TRUE);
236 _tnl_allow_pixel_fog(ctx, GL_FALSE);
237 _tnl_allow_vertex_fog(ctx, GL_TRUE);
238
239 driInitExtensions(ctx, card_extensions, GL_TRUE);
240
241 radeonInitSpanFuncs(ctx);
242 r300InitCmdBuf(r300);
243 r300InitState(r300);
244 #if 0
245 /* plug in a few more device driver functions */
246 /* XXX these should really go right after _mesa_init_driver_functions() */
247 r200InitPixelFuncs(ctx);
248 r200InitTnlFuncs(ctx);
249 r200InitSwtcl(ctx);
250 #endif
251 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
252
253 tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
254 if (1 ||
255 driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
256 fprintf(stderr, "disabling 3D acceleration\n");
257 FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
258 }
259 if (tcl_mode == DRI_CONF_TCL_SW ||
260 !(r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
261 if (r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) {
262 r300->radeon.radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
263 fprintf(stderr, "Disabling HW TCL support\n");
264 }
265 TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
266 }
267
268 return GL_TRUE;
269 }
270
271 /* Destroy the device specific context.
272 */
273 void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
274 {
275 GET_CURRENT_CONTEXT(ctx);
276 r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
277 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
278
279 /* check if we're deleting the currently bound context */
280 if (&r300->radeon == current) {
281 radeonFlush(r300->radeon.glCtx);
282 _mesa_make_current2(NULL, NULL, NULL);
283 }
284
285 /* Free r300 context resources */
286 assert(r300); /* should never be null */
287
288 if (r300) {
289 GLboolean release_texture_heaps;
290
291 release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
292 _swsetup_DestroyContext(r300->radeon.glCtx);
293 _tnl_DestroyContext(r300->radeon.glCtx);
294 _ac_DestroyContext(r300->radeon.glCtx);
295 _swrast_DestroyContext(r300->radeon.glCtx);
296
297 r300DestroyCmdBuf(r300);
298
299 /* free the Mesa context */
300 r300->radeon.glCtx->DriverCtx = NULL;
301 _mesa_destroy_context(r300->radeon.glCtx);
302
303 /* free the option cache */
304 driDestroyOptionCache(&r300->radeon.optionCache);
305
306 FREE(r300);
307 }
308 }