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/texobj.h"
47 #include "main/bufferobj.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
54 #include "tnl/t_pipeline.h"
55 #include "tnl/t_vp_build.h"
57 #include "drivers/common/driverfuncs.h"
59 #include "radeon_ioctl.h"
60 #include "radeon_span.h"
61 #include "r300_context.h"
62 #include "r300_cmdbuf.h"
63 #include "r300_state.h"
64 #include "r300_ioctl.h"
66 #include "r300_emit.h"
67 #include "r300_swtcl.h"
75 #include "xmlpool.h" /* for symbolic values of enum-type options */
77 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
78 int future_hw_tcl_on
= 1;
81 #define need_GL_VERSION_2_0
82 #define need_GL_ARB_point_parameters
83 #define need_GL_ARB_vertex_program
84 #define need_GL_EXT_blend_equation_separate
85 #define need_GL_EXT_blend_func_separate
86 #define need_GL_EXT_blend_minmax
87 #define need_GL_EXT_fog_coord
88 #define need_GL_EXT_gpu_program_parameters
89 #define need_GL_EXT_secondary_color
90 #define need_GL_EXT_stencil_two_side
91 #define need_GL_ATI_separate_stencil
92 #define need_GL_NV_vertex_program
93 #include "extension_helper.h"
95 const struct dri_extension card_extensions
[] = {
97 {"GL_ARB_depth_texture", NULL
},
98 {"GL_ARB_fragment_program", NULL
},
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_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_program", GL_ARB_vertex_program_functions
},
111 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions
},
112 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions
},
113 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions
},
114 {"GL_EXT_blend_subtract", NULL
},
115 {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
116 {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions
},
117 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
118 {"GL_EXT_shadow_funcs", NULL
},
119 {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions
},
120 {"GL_EXT_stencil_wrap", NULL
},
121 {"GL_EXT_texture_edge_clamp", NULL
},
122 {"GL_EXT_texture_env_combine", NULL
},
123 {"GL_EXT_texture_env_dot3", NULL
},
124 {"GL_EXT_texture_filter_anisotropic", NULL
},
125 {"GL_EXT_texture_lod_bias", NULL
},
126 {"GL_EXT_texture_mirror_clamp", NULL
},
127 {"GL_EXT_texture_rectangle", NULL
},
128 {"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions
},
129 {"GL_ATI_texture_env_combine3", NULL
},
130 {"GL_ATI_texture_mirror_once", NULL
},
131 {"GL_MESA_pack_invert", NULL
},
132 {"GL_MESA_ycbcr_texture", NULL
},
133 {"GL_MESAX_texture_float", NULL
},
134 {"GL_NV_blend_square", NULL
},
135 {"GL_NV_vertex_program", GL_NV_vertex_program_functions
},
136 {"GL_SGIS_generate_mipmap", NULL
},
143 * The GL 2.0 functions are needed to make display lists work with
144 * functions added by GL_ATI_separate_stencil.
146 const struct dri_extension gl_20_extension
[] = {
147 {"GL_VERSION_2_0", GL_VERSION_2_0_functions
},
151 extern struct tnl_pipeline_stage _r300_render_stage
;
152 extern const struct tnl_pipeline_stage _r300_tcl_stage
;
154 static const struct tnl_pipeline_stage
*r300_pipeline
[] = {
156 /* Try and go straight to t&l
160 /* Catch any t&l fallbacks
162 &_tnl_vertex_transform_stage
,
163 &_tnl_normal_transform_stage
,
164 &_tnl_lighting_stage
,
165 &_tnl_fog_coordinate_stage
,
167 &_tnl_texture_transform_stage
,
168 &_tnl_vertex_program_stage
,
170 /* Try again to go to tcl?
171 * - no good for asymmetric-twoside (do with multipass)
172 * - no good for asymmetric-unfilled (do with multipass)
173 * - good for material
175 * - need to manipulate a bit of state
177 * - worth it/not worth it?
180 /* Else do them here.
183 &_tnl_render_stage
, /* FALLBACK */
187 /* Create the device specific rendering context.
189 GLboolean
r300CreateContext(const __GLcontextModes
* glVisual
,
190 __DRIcontextPrivate
* driContextPriv
,
191 void *sharedContextPrivate
)
193 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
194 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
195 struct dd_function_table functions
;
201 assert(driContextPriv
);
204 /* Allocate the R300 context */
205 r300
= (r300ContextPtr
) CALLOC(sizeof(*r300
));
209 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
210 hw_tcl_on
= future_hw_tcl_on
= 0;
212 /* Parse configuration files.
213 * Do this here so that initialMaxAnisotropy is set before we create
214 * the default textures.
216 driParseConfigFiles(&r300
->radeon
.optionCache
, &screen
->optionCache
,
217 screen
->driScreen
->myNum
, "r300");
218 r300
->initialMaxAnisotropy
= driQueryOptionf(&r300
->radeon
.optionCache
,
219 "def_max_anisotropy");
221 /* Init default driver functions then plug in our R300-specific functions
222 * (the texture functions are especially important)
224 _mesa_init_driver_functions(&functions
);
225 r300InitIoctlFuncs(&functions
);
226 r300InitStateFuncs(&functions
);
227 r300InitTextureFuncs(&functions
);
228 r300InitShaderFuncs(&functions
);
234 if (!radeonInitContext(&r300
->radeon
, &functions
,
235 glVisual
, driContextPriv
,
236 sharedContextPrivate
)) {
241 /* Init r300 context data */
242 r300
->dma
.buf0_address
=
243 r300
->radeon
.radeonScreen
->buffers
->list
[0].address
;
245 (void)memset(r300
->texture_heaps
, 0, sizeof(r300
->texture_heaps
));
246 make_empty_list(&r300
->swapped
);
248 r300
->nr_heaps
= 1 /* screen->numTexHeaps */ ;
249 assert(r300
->nr_heaps
< RADEON_NR_TEX_HEAPS
);
250 for (i
= 0; i
< r300
->nr_heaps
; i
++) {
252 r300
->texture_heaps
[i
] = driCreateTextureHeap(i
, r300
,
255 RADEON_NR_TEX_REGIONS
,
256 (drmTextureRegionPtr
)
259 &r300
->radeon
.sarea
->
264 (destroy_texture_object_t
269 r300
->texture_depth
= driQueryOptioni(&r300
->radeon
.optionCache
,
271 if (r300
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
272 r300
->texture_depth
= (screen
->cpp
== 4) ?
273 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
275 /* Set the maximum texture size small enough that we can guarentee that
276 * all texture units can bind a maximal texture and have them both in
277 * texturable memory at once.
280 ctx
= r300
->radeon
.glCtx
;
282 ctx
->Const
.MaxTextureImageUnits
=
283 driQueryOptioni(&r300
->radeon
.optionCache
, "texture_image_units");
284 ctx
->Const
.MaxTextureCoordUnits
=
285 driQueryOptioni(&r300
->radeon
.optionCache
, "texture_coord_units");
286 ctx
->Const
.MaxTextureUnits
=
287 MIN2(ctx
->Const
.MaxTextureImageUnits
,
288 ctx
->Const
.MaxTextureCoordUnits
);
289 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
290 ctx
->Const
.MaxTextureLodBias
= 16.0;
292 if (screen
->chip_family
>= CHIP_FAMILY_RV515
)
293 ctx
->Const
.MaxTextureLevels
= 13;
295 ctx
->Const
.MaxTextureLevels
= 12;
297 driCalculateMaxTextureLevels( r300
->texture_heaps
,
301 ctx
->Const
.MaxTextureLevels
- 1,
302 MIN2(ctx
->Const
.MaxTextureLevels
,
303 MAX_3D_TEXTURE_LEVELS
) - 1,
304 ctx
->Const
.MaxTextureLevels
- 1,
305 ctx
->Const
.MaxTextureLevels
- 1,
306 ctx
->Const
.MaxTextureLevels
- 1,
310 ctx
->Const
.MinPointSize
= 1.0;
311 ctx
->Const
.MinPointSizeAA
= 1.0;
312 ctx
->Const
.MaxPointSize
= R300_POINTSIZE_MAX
;
313 ctx
->Const
.MaxPointSizeAA
= R300_POINTSIZE_MAX
;
315 ctx
->Const
.MinLineWidth
= 1.0;
316 ctx
->Const
.MinLineWidthAA
= 1.0;
317 ctx
->Const
.MaxLineWidth
= R300_LINESIZE_MAX
;
318 ctx
->Const
.MaxLineWidthAA
= R300_LINESIZE_MAX
;
321 /* Needs further modifications */
323 ctx
->Const
.MaxArrayLockSize
=
324 ( /*512 */ RADEON_BUFFER_SIZE
* 16 * 1024) / (4 * 4);
328 ctx
->Const
.MaxDrawBuffers
= 1;
330 /* Initialize the software rasterizer and helper modules.
332 _swrast_CreateContext(ctx
);
333 _vbo_CreateContext(ctx
);
334 _tnl_CreateContext(ctx
);
335 _swsetup_CreateContext(ctx
);
336 _swsetup_Wakeup(ctx
);
337 _ae_create_context(ctx
);
339 /* Install the customized pipeline:
341 _tnl_destroy_pipeline(ctx
);
342 _tnl_install_pipeline(ctx
, r300_pipeline
);
344 /* Try and keep materials and vertices separate:
346 /* _tnl_isolate_materials(ctx, GL_TRUE); */
348 /* Configure swrast and TNL to match hardware characteristics:
350 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
351 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
352 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
353 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
355 /* currently bogus data */
356 if (screen
->chip_flags
& RADEON_CHIPSET_TCL
) {
357 ctx
->Const
.VertexProgram
.MaxInstructions
= VSF_MAX_FRAGMENT_LENGTH
/ 4;
358 ctx
->Const
.VertexProgram
.MaxNativeInstructions
=
359 VSF_MAX_FRAGMENT_LENGTH
/ 4;
360 ctx
->Const
.VertexProgram
.MaxNativeAttribs
= 16; /* r420 */
361 ctx
->Const
.VertexProgram
.MaxTemps
= 32;
362 ctx
->Const
.VertexProgram
.MaxNativeTemps
=
363 /*VSF_MAX_FRAGMENT_TEMPS */ 32;
364 ctx
->Const
.VertexProgram
.MaxNativeParameters
= 256; /* r420 */
365 ctx
->Const
.VertexProgram
.MaxNativeAddressRegs
= 1;
368 ctx
->Const
.FragmentProgram
.MaxNativeTemps
= PFS_NUM_TEMP_REGS
;
369 ctx
->Const
.FragmentProgram
.MaxNativeAttribs
= 11; /* copy i915... */
370 ctx
->Const
.FragmentProgram
.MaxNativeParameters
= PFS_NUM_CONST_REGS
;
371 ctx
->Const
.FragmentProgram
.MaxNativeAluInstructions
= PFS_MAX_ALU_INST
;
372 ctx
->Const
.FragmentProgram
.MaxNativeTexInstructions
= PFS_MAX_TEX_INST
;
373 ctx
->Const
.FragmentProgram
.MaxNativeInstructions
=
374 PFS_MAX_ALU_INST
+ PFS_MAX_TEX_INST
;
375 ctx
->Const
.FragmentProgram
.MaxNativeTexIndirections
=
376 PFS_MAX_TEX_INDIRECT
;
377 ctx
->Const
.FragmentProgram
.MaxNativeAddressRegs
= 0; /* and these are?? */
378 ctx
->VertexProgram
._MaintainTnlProgram
= GL_TRUE
;
379 ctx
->FragmentProgram
._MaintainTexEnvProgram
= GL_TRUE
;
381 driInitExtensions(ctx
, card_extensions
, GL_TRUE
);
384 (&r300
->radeon
.optionCache
, "disable_stencil_two_side"))
385 _mesa_disable_extension(ctx
, "GL_EXT_stencil_two_side");
387 if (r300
->radeon
.glCtx
->Mesa_DXTn
388 && !driQueryOptionb(&r300
->radeon
.optionCache
, "disable_s3tc")) {
389 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
390 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
392 if (driQueryOptionb(&r300
->radeon
.optionCache
, "force_s3tc_enable"))
394 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
397 r300
->disable_lowimpact_fallback
=
398 driQueryOptionb(&r300
->radeon
.optionCache
,
399 "disable_lowimpact_fallback");
401 radeonInitSpanFuncs(ctx
);
402 r300InitCmdBuf(r300
);
404 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
407 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
409 tcl_mode
= driQueryOptioni(&r300
->radeon
.optionCache
, "tcl_mode");
410 if (driQueryOptionb(&r300
->radeon
.optionCache
, "no_rast")) {
411 fprintf(stderr
, "disabling 3D acceleration\n");
413 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_DISABLE
, 1);
416 if (tcl_mode
== DRI_CONF_TCL_SW
||
417 !(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)) {
418 if (r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
419 r300
->radeon
.radeonScreen
->chip_flags
&=
421 fprintf(stderr
, "Disabling HW TCL support\n");
423 TCL_FALLBACK(r300
->radeon
.glCtx
,
424 RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);
430 static void r300FreeGartAllocations(r300ContextPtr r300
)
432 int i
, ret
, tries
= 0, done_age
, in_use
= 0;
433 drm_radeon_mem_free_t memfree
;
435 memfree
.region
= RADEON_MEM_REGION_GART
;
438 for (i
= r300
->rmm
->u_last
; i
> 0; i
--) {
439 if (r300
->rmm
->u_list
[i
].ptr
== NULL
) {
443 /* check whether this buffer is still in use */
444 if (r300
->rmm
->u_list
[i
].pending
) {
448 /* Cannot flush/lock if no context exists. */
450 r300FlushCmdBuf(r300
, __FUNCTION__
);
452 done_age
= radeonGetAge((radeonContextPtr
) r300
);
454 for (i
= r300
->rmm
->u_last
; i
> 0; i
--) {
455 if (r300
->rmm
->u_list
[i
].ptr
== NULL
) {
459 /* check whether this buffer is still in use */
460 if (!r300
->rmm
->u_list
[i
].pending
) {
464 assert(r300
->rmm
->u_list
[i
].h_pending
== 0);
467 while (r300
->rmm
->u_list
[i
].age
> done_age
&& tries
++ < 1000) {
469 done_age
= radeonGetAge((radeonContextPtr
) r300
);
472 WARN_ONCE("Failed to idle region!");
475 memfree
.region_offset
= (char *)r300
->rmm
->u_list
[i
].ptr
-
476 (char *)r300
->radeon
.radeonScreen
->gartTextures
.map
;
478 ret
= drmCommandWrite(r300
->radeon
.radeonScreen
->driScreen
->fd
,
479 DRM_RADEON_FREE
, &memfree
,
482 fprintf(stderr
, "Failed to free at %p\nret = %s\n",
483 r300
->rmm
->u_list
[i
].ptr
, strerror(-ret
));
485 if (i
== r300
->rmm
->u_last
)
488 r300
->rmm
->u_list
[i
].pending
= 0;
489 r300
->rmm
->u_list
[i
].ptr
= NULL
;
492 r300
->rmm
->u_head
= i
;
493 #endif /* USER_BUFFERS */
496 /* Destroy the device specific context.
498 void r300DestroyContext(__DRIcontextPrivate
* driContextPriv
)
500 GET_CURRENT_CONTEXT(ctx
);
501 r300ContextPtr r300
= (r300ContextPtr
) driContextPriv
->driverPrivate
;
502 radeonContextPtr radeon
= (radeonContextPtr
) r300
;
503 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
506 if (RADEON_DEBUG
& DEBUG_DRI
) {
507 fprintf(stderr
, "Destroying context !\n");
510 /* check if we're deleting the currently bound context */
511 if (&r300
->radeon
== current
) {
512 radeonFlush(r300
->radeon
.glCtx
);
513 _mesa_make_current(NULL
, NULL
, NULL
);
516 /* Free r300 context resources */
517 assert(r300
); /* should never be null */
520 GLboolean release_texture_heaps
;
522 release_texture_heaps
=
523 (r300
->radeon
.glCtx
->Shared
->RefCount
== 1);
524 _swsetup_DestroyContext(r300
->radeon
.glCtx
);
525 _tnl_DestroyContext(r300
->radeon
.glCtx
);
526 _vbo_DestroyContext(r300
->radeon
.glCtx
);
527 _swrast_DestroyContext(r300
->radeon
.glCtx
);
529 if (r300
->dma
.current
.buf
) {
530 r300ReleaseDmaRegion(r300
, &r300
->dma
.current
,
533 r300FlushCmdBuf(r300
, __FUNCTION__
);
536 r300FreeGartAllocations(r300
);
537 r300DestroyCmdBuf(r300
);
539 if (radeon
->state
.scissor
.pClipRects
) {
540 FREE(radeon
->state
.scissor
.pClipRects
);
541 radeon
->state
.scissor
.pClipRects
= NULL
;
544 if (release_texture_heaps
) {
545 /* This share group is about to go away, free our private
546 * texture object data.
550 for (i
= 0; i
< r300
->nr_heaps
; i
++) {
551 driDestroyTextureHeap(r300
->texture_heaps
[i
]);
552 r300
->texture_heaps
[i
] = NULL
;
555 assert(is_empty_list(&r300
->swapped
));
558 /* Drop texture object references from current hardware state */
559 for (i
= 0; i
< 8; i
++) {
560 _mesa_reference_texobj(&r300
->state
.texture
.unit
[i
].texobj
, NULL
);
563 radeonCleanupContext(&r300
->radeon
);
566 /* the memory manager might be accessed when Mesa frees the shared
567 * state, so don't destroy it earlier
569 r300_mem_destroy(r300
);
572 /* free the option cache */
573 driDestroyOptionCache(&r300
->radeon
.optionCache
);