1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
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 **************************************************************************/
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
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/extensions.h"
44 #include "main/mfeatures.h"
45 #include "main/version.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
52 #include "tnl/t_pipeline.h"
54 #include "drivers/common/driverfuncs.h"
56 #include "radeon_common.h"
57 #include "radeon_context.h"
58 #include "radeon_ioctl.h"
59 #include "radeon_state.h"
60 #include "radeon_span.h"
61 #include "radeon_tex.h"
62 #include "radeon_swtcl.h"
63 #include "radeon_tcl.h"
64 #include "radeon_queryobj.h"
65 #include "radeon_blit.h"
68 #include "xmlpool.h" /* for symbolic values of enum-type options */
70 extern const struct tnl_pipeline_stage _radeon_render_stage
;
71 extern const struct tnl_pipeline_stage _radeon_tcl_stage
;
73 static const struct tnl_pipeline_stage
*radeon_pipeline
[] = {
75 /* Try and go straight to t&l
79 /* Catch any t&l fallbacks
81 &_tnl_vertex_transform_stage
,
82 &_tnl_normal_transform_stage
,
84 &_tnl_fog_coordinate_stage
,
86 &_tnl_texture_transform_stage
,
88 &_radeon_render_stage
,
89 &_tnl_render_stage
, /* FALLBACK: */
93 static void r100_get_lock(radeonContextPtr radeon
)
95 r100ContextPtr rmesa
= (r100ContextPtr
)radeon
;
96 drm_radeon_sarea_t
*sarea
= radeon
->sarea
;
98 RADEON_STATECHANGE(rmesa
, ctx
);
99 if (rmesa
->radeon
.sarea
->tiling_enabled
) {
100 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
101 RADEON_COLOR_TILE_ENABLE
;
103 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] &=
104 ~RADEON_COLOR_TILE_ENABLE
;
107 if (sarea
->ctx_owner
!= rmesa
->radeon
.dri
.hwContext
) {
108 sarea
->ctx_owner
= rmesa
->radeon
.dri
.hwContext
;
112 static void r100_vtbl_emit_cs_header(struct radeon_cs
*cs
, radeonContextPtr rmesa
)
116 static void r100_vtbl_pre_emit_state(radeonContextPtr radeon
)
118 r100ContextPtr rmesa
= (r100ContextPtr
)radeon
;
120 /* r100 always needs to emit ZBS to avoid TCL lockups */
121 rmesa
->hw
.zbs
.dirty
= 1;
122 radeon
->hw
.is_dirty
= 1;
125 static void r100_vtbl_free_context(struct gl_context
*ctx
)
127 r100ContextPtr rmesa
= R100_CONTEXT(ctx
);
128 _mesa_vector4f_free( &rmesa
->tcl
.ObjClean
);
131 static void r100_emit_query_finish(radeonContextPtr radeon
)
133 BATCH_LOCALS(radeon
);
134 struct radeon_query_object
*query
= radeon
->query
.current
;
136 BEGIN_BATCH_NO_AUTOSTATE(4);
137 OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR
, 0));
138 OUT_BATCH_RELOC(0, query
->bo
, query
->curr_offset
, 0, RADEON_GEM_DOMAIN_GTT
, 0);
140 query
->curr_offset
+= sizeof(uint32_t);
141 assert(query
->curr_offset
< RADEON_QUERY_PAGE_SIZE
);
142 query
->emitted_begin
= GL_FALSE
;
145 static void r100_init_vtbl(radeonContextPtr radeon
)
147 radeon
->vtbl
.get_lock
= r100_get_lock
;
148 radeon
->vtbl
.update_viewport_offset
= radeonUpdateViewportOffset
;
149 radeon
->vtbl
.emit_cs_header
= r100_vtbl_emit_cs_header
;
150 radeon
->vtbl
.swtcl_flush
= r100_swtcl_flush
;
151 radeon
->vtbl
.pre_emit_state
= r100_vtbl_pre_emit_state
;
152 radeon
->vtbl
.fallback
= radeonFallback
;
153 radeon
->vtbl
.free_context
= r100_vtbl_free_context
;
154 radeon
->vtbl
.emit_query_finish
= r100_emit_query_finish
;
155 radeon
->vtbl
.check_blit
= r100_check_blit
;
156 radeon
->vtbl
.blit
= r100_blit
;
157 radeon
->vtbl
.is_format_renderable
= radeonIsFormatRenderable
;
160 /* Create the device specific context.
163 r100CreateContext( gl_api api
,
164 const struct gl_config
*glVisual
,
165 __DRIcontext
*driContextPriv
,
166 unsigned major_version
,
167 unsigned minor_version
,
170 void *sharedContextPrivate
)
172 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
173 radeonScreenPtr screen
= (radeonScreenPtr
)(sPriv
->driverPrivate
);
174 struct dd_function_table functions
;
175 r100ContextPtr rmesa
;
176 struct gl_context
*ctx
;
178 int tcl_mode
, fthrottle_mode
;
180 /* API and flag filtering is handled in dri2CreateContextAttribs.
186 assert(driContextPriv
);
189 /* Allocate the Radeon context */
190 rmesa
= (r100ContextPtr
) CALLOC( sizeof(*rmesa
) );
192 *error
= __DRI_CTX_ERROR_NO_MEMORY
;
196 rmesa
->radeon
.radeonScreen
= screen
;
197 r100_init_vtbl(&rmesa
->radeon
);
199 /* init exp fog table data */
200 radeonInitStaticFogData();
202 /* Parse configuration files.
203 * Do this here so that initialMaxAnisotropy is set before we create
204 * the default textures.
206 driParseConfigFiles (&rmesa
->radeon
.optionCache
, &screen
->optionCache
,
207 screen
->driScreen
->myNum
, "radeon");
208 rmesa
->radeon
.initialMaxAnisotropy
= driQueryOptionf(&rmesa
->radeon
.optionCache
,
209 "def_max_anisotropy");
211 if ( driQueryOptionb( &rmesa
->radeon
.optionCache
, "hyperz" ) ) {
212 if ( sPriv
->drm_version
.minor
< 13 )
213 fprintf( stderr
, "DRM version 1.%d too old to support HyperZ, "
214 "disabling.\n", sPriv
->drm_version
.minor
);
216 rmesa
->using_hyperz
= GL_TRUE
;
219 if ( sPriv
->drm_version
.minor
>= 15 )
220 rmesa
->texmicrotile
= GL_TRUE
;
222 /* Init default driver functions then plug in our Radeon-specific functions
223 * (the texture functions are especially important)
225 _mesa_init_driver_functions( &functions
);
226 radeonInitTextureFuncs( &rmesa
->radeon
, &functions
);
227 radeonInitQueryObjFunctions(&functions
);
229 if (!radeonInitContext(&rmesa
->radeon
, &functions
,
230 glVisual
, driContextPriv
,
231 sharedContextPrivate
)) {
233 *error
= __DRI_CTX_ERROR_NO_MEMORY
;
237 rmesa
->radeon
.swtcl
.RenderIndex
= ~0;
238 rmesa
->radeon
.hw
.all_dirty
= GL_TRUE
;
240 /* Set the maximum texture size small enough that we can guarentee that
241 * all texture units can bind a maximal texture and have all of them in
242 * texturable memory at once. Depending on the allow_large_textures driconf
243 * setting allow larger textures.
246 ctx
= rmesa
->radeon
.glCtx
;
247 ctx
->Const
.MaxTextureUnits
= driQueryOptioni (&rmesa
->radeon
.optionCache
,
249 ctx
->Const
.MaxTextureImageUnits
= ctx
->Const
.MaxTextureUnits
;
250 ctx
->Const
.MaxTextureCoordUnits
= ctx
->Const
.MaxTextureUnits
;
251 ctx
->Const
.MaxCombinedTextureImageUnits
= ctx
->Const
.MaxTextureUnits
;
253 ctx
->Const
.StripTextureBorder
= GL_TRUE
;
255 i
= driQueryOptioni( &rmesa
->radeon
.optionCache
, "allow_large_textures");
257 /* FIXME: When no memory manager is available we should set this
258 * to some reasonable value based on texture memory pool size */
259 ctx
->Const
.MaxTextureLevels
= 12;
260 ctx
->Const
.Max3DTextureLevels
= 9;
261 ctx
->Const
.MaxCubeTextureLevels
= 12;
262 ctx
->Const
.MaxTextureRectSize
= 2048;
264 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
268 ctx
->Const
.MinPointSize
= 1.0;
269 ctx
->Const
.MinPointSizeAA
= 1.0;
270 ctx
->Const
.MaxPointSize
= 1.0;
271 ctx
->Const
.MaxPointSizeAA
= 1.0;
273 ctx
->Const
.MinLineWidth
= 1.0;
274 ctx
->Const
.MinLineWidthAA
= 1.0;
275 ctx
->Const
.MaxLineWidth
= 10.0;
276 ctx
->Const
.MaxLineWidthAA
= 10.0;
277 ctx
->Const
.LineWidthGranularity
= 0.0625;
279 /* Set maxlocksize (and hence vb size) small enough to avoid
280 * fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
281 * fit in a single dma buffer for indexed rendering of quad strips,
284 ctx
->Const
.MaxArrayLockSize
=
285 MIN2( ctx
->Const
.MaxArrayLockSize
,
286 RADEON_BUFFER_SIZE
/ RADEON_MAX_TCL_VERTSIZE
);
290 ctx
->Const
.MaxDrawBuffers
= 1;
291 ctx
->Const
.MaxColorAttachments
= 1;
292 ctx
->Const
.MaxRenderbufferSize
= 2048;
294 _mesa_set_mvp_with_dp4( ctx
, GL_TRUE
);
296 /* Initialize the software rasterizer and helper modules.
298 _swrast_CreateContext( ctx
);
299 _vbo_CreateContext( ctx
);
300 _tnl_CreateContext( ctx
);
301 _swsetup_CreateContext( ctx
);
302 _ae_create_context( ctx
);
304 /* Install the customized pipeline:
306 _tnl_destroy_pipeline( ctx
);
307 _tnl_install_pipeline( ctx
, radeon_pipeline
);
309 /* Try and keep materials and vertices separate:
311 /* _tnl_isolate_materials( ctx, GL_TRUE ); */
313 /* Configure swrast and T&L to match hardware characteristics:
315 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
316 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
317 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
318 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
321 for ( i
= 0 ; i
< RADEON_MAX_TEXTURE_UNITS
; i
++ ) {
322 _math_matrix_ctr( &rmesa
->TexGenMatrix
[i
] );
323 _math_matrix_ctr( &rmesa
->tmpmat
[i
] );
324 _math_matrix_set_identity( &rmesa
->TexGenMatrix
[i
] );
325 _math_matrix_set_identity( &rmesa
->tmpmat
[i
] );
328 ctx
->Extensions
.ARB_texture_border_clamp
= true;
329 ctx
->Extensions
.ARB_texture_env_combine
= true;
330 ctx
->Extensions
.ARB_texture_env_crossbar
= true;
331 ctx
->Extensions
.ARB_texture_env_dot3
= true;
332 ctx
->Extensions
.EXT_fog_coord
= true;
333 ctx
->Extensions
.EXT_packed_depth_stencil
= true;
334 ctx
->Extensions
.EXT_secondary_color
= true;
335 ctx
->Extensions
.EXT_texture_env_dot3
= true;
336 ctx
->Extensions
.EXT_texture_filter_anisotropic
= true;
337 ctx
->Extensions
.EXT_texture_mirror_clamp
= true;
338 ctx
->Extensions
.ATI_texture_env_combine3
= true;
339 ctx
->Extensions
.ATI_texture_mirror_once
= true;
340 ctx
->Extensions
.MESA_ycbcr_texture
= true;
341 ctx
->Extensions
.NV_blend_square
= true;
342 #if FEATURE_OES_EGL_image
343 ctx
->Extensions
.OES_EGL_image
= true;
346 ctx
->Extensions
.EXT_framebuffer_object
= true;
348 ctx
->Extensions
.ARB_texture_cube_map
= true;
350 if (rmesa
->radeon
.glCtx
->Mesa_DXTn
) {
351 ctx
->Extensions
.EXT_texture_compression_s3tc
= true;
352 ctx
->Extensions
.S3_s3tc
= true;
354 else if (driQueryOptionb (&rmesa
->radeon
.optionCache
, "force_s3tc_enable")) {
355 ctx
->Extensions
.EXT_texture_compression_s3tc
= true;
358 ctx
->Extensions
.NV_texture_rectangle
= true;
359 ctx
->Extensions
.ARB_occlusion_query
= true;
361 /* XXX these should really go right after _mesa_init_driver_functions() */
362 radeon_fbo_init(&rmesa
->radeon
);
363 radeonInitSpanFuncs( ctx
);
364 radeonInitIoctlFuncs( ctx
);
365 radeonInitStateFuncs( ctx
);
366 radeonInitState( rmesa
);
367 radeonInitSwtcl( ctx
);
369 _mesa_vector4f_alloc( &rmesa
->tcl
.ObjClean
, 0,
370 ctx
->Const
.MaxArrayLockSize
, 32 );
372 fthrottle_mode
= driQueryOptioni(&rmesa
->radeon
.optionCache
, "fthrottle_mode");
373 rmesa
->radeon
.iw
.irq_seq
= -1;
374 rmesa
->radeon
.irqsEmitted
= 0;
375 rmesa
->radeon
.do_irqs
= (rmesa
->radeon
.radeonScreen
->irq
!= 0 &&
376 fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
);
378 rmesa
->radeon
.do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
382 RADEON_DEBUG
= driParseDebugString( getenv( "RADEON_DEBUG" ),
386 tcl_mode
= driQueryOptioni(&rmesa
->radeon
.optionCache
, "tcl_mode");
387 if (driQueryOptionb(&rmesa
->radeon
.optionCache
, "no_rast")) {
388 fprintf(stderr
, "disabling 3D acceleration\n");
389 FALLBACK(rmesa
, RADEON_FALLBACK_DISABLE
, 1);
390 } else if (tcl_mode
== DRI_CONF_TCL_SW
||
391 !(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)) {
392 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
393 rmesa
->radeon
.radeonScreen
->chip_flags
&= ~RADEON_CHIPSET_TCL
;
394 fprintf(stderr
, "Disabling HW TCL support\n");
396 TCL_FALLBACK(rmesa
->radeon
.glCtx
, RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);
399 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
400 /* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
403 _mesa_compute_version(ctx
);
404 if (ctx
->VersionMajor
< major_version
405 || (ctx
->VersionMajor
== major_version
406 && ctx
->VersionMinor
< minor_version
)) {
407 radeonDestroyContext(driContextPriv
);
408 *error
= __DRI_CTX_ERROR_BAD_VERSION
;
412 *error
= __DRI_CTX_ERROR_SUCCESS
;