2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
28 **************************************************************************/
33 * \author Keith Whitwell <keith@tungstengraphics.com>
35 * \author Nicolai Haehnle <prefect_@gmx.net>
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"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
53 #include "tnl/t_pipeline.h"
54 #include "tnl/t_vp_build.h"
56 #include "drivers/common/driverfuncs.h"
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"
66 #include "r300_emit.h"
67 #include "r300_swtcl.h"
72 #include "xmlpool.h" /* for symbolic values of enum-type options */
74 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
75 int future_hw_tcl_on
= 1;
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"
94 const struct dri_extension card_extensions
[] = {
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
},
143 extern struct tnl_pipeline_stage _r300_render_stage
;
144 extern const struct tnl_pipeline_stage _r300_tcl_stage
;
146 static const struct tnl_pipeline_stage
*r300_pipeline
[] = {
148 /* Try and go straight to t&l
152 /* Catch any t&l fallbacks
154 &_tnl_vertex_transform_stage
,
155 &_tnl_normal_transform_stage
,
156 &_tnl_lighting_stage
,
157 &_tnl_fog_coordinate_stage
,
159 &_tnl_texture_transform_stage
,
160 &_tnl_vertex_program_stage
,
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
167 * - need to manipulate a bit of state
169 * - worth it/not worth it?
172 /* Else do them here.
175 &_tnl_render_stage
, /* FALLBACK */
179 static void r300RunPipeline(GLcontext
* ctx
)
181 _mesa_lock_context_textures(ctx
);
184 _mesa_update_state_locked(ctx
);
186 _tnl_run_pipeline(ctx
);
187 _mesa_unlock_context_textures(ctx
);
190 static void r300_get_lock(radeonContextPtr rmesa
)
192 drm_radeon_sarea_t
*sarea
= rmesa
->sarea
;
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
);
201 static void r300_init_vtbl(radeonContextPtr radeon
)
203 radeon
->vtbl
.get_lock
= r300_get_lock
;
204 radeon
->vtbl
.update_viewport_offset
= r300UpdateViewportOffset
;
207 /* Create the device specific rendering context.
209 GLboolean
r300CreateContext(const __GLcontextModes
* glVisual
,
210 __DRIcontextPrivate
* driContextPriv
,
211 void *sharedContextPrivate
)
213 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
214 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
215 struct dd_function_table functions
;
221 assert(driContextPriv
);
224 /* Allocate the R300 context */
225 r300
= (r300ContextPtr
) CALLOC(sizeof(*r300
));
229 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
230 hw_tcl_on
= future_hw_tcl_on
= 0;
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.
237 driParseConfigFiles(&r300
->radeon
.optionCache
, &screen
->optionCache
,
238 screen
->driScreen
->myNum
, "r300");
239 r300
->initialMaxAnisotropy
= driQueryOptionf(&r300
->radeon
.optionCache
,
240 "def_max_anisotropy");
242 /* Init default driver functions then plug in our R300-specific functions
243 * (the texture functions are especially important)
245 _mesa_init_driver_functions(&functions
);
246 r300InitIoctlFuncs(&functions
);
247 r300InitStateFuncs(&functions
);
248 r300InitTextureFuncs(&functions
);
249 r300InitShaderFuncs(&functions
);
251 if (!radeonInitContext(&r300
->radeon
, &functions
,
252 glVisual
, driContextPriv
,
253 sharedContextPrivate
)) {
258 /* Init r300 context data */
259 r300
->texture_depth
= driQueryOptioni(&r300
->radeon
.optionCache
,
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
;
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.
270 ctx
= r300
->radeon
.glCtx
;
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;
282 if (screen
->chip_family
>= CHIP_FAMILY_RV515
) {
283 ctx
->Const
.MaxTextureLevels
= 13;
284 ctx
->Const
.MaxTextureRectSize
= 4096;
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
;
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
;
297 /* Needs further modifications */
299 ctx
->Const
.MaxArrayLockSize
=
300 ( /*512 */ RADEON_BUFFER_SIZE
* 16 * 1024) / (4 * 4);
303 /* Initialize the software rasterizer and helper modules.
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
);
312 /* Install the customized pipeline:
314 _tnl_destroy_pipeline(ctx
);
315 _tnl_install_pipeline(ctx
, r300_pipeline
);
317 /* Try and keep materials and vertices separate:
319 /* _tnl_isolate_materials(ctx, GL_TRUE); */
321 /* Configure swrast and TNL to match hardware characteristics:
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
);
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;
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
;
354 driInitExtensions(ctx
, card_extensions
, GL_TRUE
);
357 (&r300
->radeon
.optionCache
, "disable_stencil_two_side"))
358 _mesa_disable_extension(ctx
, "GL_EXT_stencil_two_side");
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");
365 if (driQueryOptionb(&r300
->radeon
.optionCache
, "force_s3tc_enable"))
367 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
370 r300
->disable_lowimpact_fallback
=
371 driQueryOptionb(&r300
->radeon
.optionCache
,
372 "disable_lowimpact_fallback");
374 radeonInitSpanFuncs(ctx
);
375 r300InitCmdBuf(r300
);
377 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
380 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= r300RunPipeline
;
382 tcl_mode
= driQueryOptioni(&r300
->radeon
.optionCache
, "tcl_mode");
383 if (driQueryOptionb(&r300
->radeon
.optionCache
, "no_rast")) {
384 fprintf(stderr
, "disabling 3D acceleration\n");
386 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_DISABLE
, 1);
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
&=
394 fprintf(stderr
, "Disabling HW TCL support\n");
396 TCL_FALLBACK(r300
->radeon
.glCtx
,
397 RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);
403 /* Destroy the device specific context.
405 void r300DestroyContext(__DRIcontextPrivate
* driContextPriv
)
407 GET_CURRENT_CONTEXT(ctx
);
408 r300ContextPtr r300
= (r300ContextPtr
) driContextPriv
->driverPrivate
;
409 radeonContextPtr radeon
= (radeonContextPtr
) r300
;
410 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
412 if (RADEON_DEBUG
& DEBUG_DRI
) {
413 fprintf(stderr
, "Destroying context !\n");
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
);
422 /* Free r300 context resources */
423 assert(r300
); /* should never be null */
426 _swsetup_DestroyContext(r300
->radeon
.glCtx
);
427 _tnl_DestroyContext(r300
->radeon
.glCtx
);
428 _vbo_DestroyContext(r300
->radeon
.glCtx
);
429 _swrast_DestroyContext(r300
->radeon
.glCtx
);
431 r300FlushCmdBuf(r300
, __FUNCTION__
);
432 r300DestroyCmdBuf(r300
);
434 if (radeon
->state
.scissor
.pClipRects
) {
435 FREE(radeon
->state
.scissor
.pClipRects
);
436 radeon
->state
.scissor
.pClipRects
= NULL
;
439 radeonCleanupContext(&r300
->radeon
);
441 /* the memory manager might be accessed when Mesa frees the shared
442 * state, so don't destroy it earlier
445 /* free the option cache */
446 driDestroyOptionCache(&r300
->radeon
.optionCache
);