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"
47 #include "main/texobj.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 "r600_context.h"
60 #include "radeon_context.h"
61 #include "radeon_span.h"
62 #include "r600_cmdbuf.h"
63 #include "r600_emit.h"
64 #include "r600_swtcl.h"
65 #include "radeon_bocs_wrapper.h"
67 #include "r700_chip.h"
68 #include "r700_state.h"
69 #include "r700_ioctl.h"
74 #include "xmlpool.h" /* for symbolic values of enum-type options */
76 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
77 int future_hw_tcl_on
= 1;
80 #define need_GL_VERSION_2_0
81 #define need_GL_ARB_point_parameters
82 #define need_GL_ARB_vertex_program
83 #define need_GL_EXT_blend_equation_separate
84 #define need_GL_EXT_blend_func_separate
85 #define need_GL_EXT_blend_minmax
86 #define need_GL_EXT_framebuffer_object
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
94 #include "extension_helper.h"
97 const struct dri_extension card_extensions
[] = {
99 {"GL_ARB_depth_texture", NULL
},
100 {"GL_ARB_fragment_program", NULL
},
101 {"GL_ARB_multitexture", NULL
},
102 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
103 {"GL_ARB_shadow", NULL
},
104 {"GL_ARB_shadow_ambient", NULL
},
105 {"GL_ARB_texture_border_clamp", NULL
},
106 {"GL_ARB_texture_cube_map", NULL
},
107 {"GL_ARB_texture_env_add", NULL
},
108 {"GL_ARB_texture_env_combine", NULL
},
109 {"GL_ARB_texture_env_crossbar", NULL
},
110 {"GL_ARB_texture_env_dot3", NULL
},
111 {"GL_ARB_texture_mirrored_repeat", NULL
},
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_packed_depth_stencil", NULL
},
118 {"GL_EXT_fog_coord", GL_EXT_fog_coord_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_separate_stencil", GL_ATI_separate_stencil_functions
},
132 {"GL_ATI_texture_env_combine3", NULL
},
133 {"GL_ATI_texture_mirror_once", NULL
},
134 {"GL_MESA_pack_invert", NULL
},
135 {"GL_MESA_ycbcr_texture", NULL
},
136 {"GL_MESAX_texture_float", NULL
},
137 {"GL_NV_blend_square", NULL
},
138 {"GL_NV_vertex_program", GL_NV_vertex_program_functions
},
139 {"GL_SGIS_generate_mipmap", NULL
},
145 const struct dri_extension mm_extensions
[] = {
146 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions
},
151 * The GL 2.0 functions are needed to make display lists work with
152 * functions added by GL_ATI_separate_stencil.
154 const struct dri_extension gl_20_extension
[] = {
155 {"GL_VERSION_2_0", GL_VERSION_2_0_functions
},
159 static void r600RunPipeline(GLcontext
* ctx
)
161 _mesa_lock_context_textures(ctx
);
164 _mesa_update_state_locked(ctx
);
166 _tnl_run_pipeline(ctx
);
167 _mesa_unlock_context_textures(ctx
);
170 static void r600_get_lock(radeonContextPtr rmesa
)
172 drm_radeon_sarea_t
*sarea
= rmesa
->sarea
;
174 if (sarea
->ctx_owner
!= rmesa
->dri
.hwContext
) {
175 sarea
->ctx_owner
= rmesa
->dri
.hwContext
;
176 if (!rmesa
->radeonScreen
->kernel_mm
)
177 radeon_bo_legacy_texture_age(rmesa
->radeonScreen
->bom
);
181 static void r600_vtbl_emit_cs_header(struct radeon_cs
*cs
, radeonContextPtr rmesa
)
183 /* please flush pipe do all pending work */
187 static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon
)
192 static void r600_fallback(GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
194 r600ContextPtr r600
= R600_CONTEXT(ctx
);
196 r600
->radeon
.Fallback
|= bit
;
198 r600
->radeon
.Fallback
&= ~bit
;
201 static void r600_init_vtbl(radeonContextPtr radeon
)
203 radeon
->vtbl
.get_lock
= r600_get_lock
;
204 radeon
->vtbl
.update_viewport_offset
= r700UpdateViewportOffset
;
205 radeon
->vtbl
.emit_cs_header
= r600_vtbl_emit_cs_header
;
206 radeon
->vtbl
.swtcl_flush
= r600_swtcl_flush
;
207 radeon
->vtbl
.pre_emit_atoms
= r600_vtbl_pre_emit_atoms
;
208 radeon
->vtbl
.fallback
= r600_fallback
;
212 static GLboolean
r600LoadMemSurf(context_t
*context
,
213 GLuint dst_offset
, /* gpu addr */
214 GLuint dst_pitch_in_pixel
,
215 GLuint src_width_in_pixel
,
217 GLuint byte_per_pixel
,
218 unsigned char* pSrc
) /* source data */
223 static GLboolean
r600AllocMemSurf(context_t
*context
,
226 GLuint
*prefered_heap
, /* Now used RADEON_LOCAL_TEX_HEAP, return actual heap used. */
232 static int r600FlushCmdBuffer(context_t
*context
)
239 static void r600MemUse(context_t
*context
, int id
)
243 /* Create the device specific rendering context.
245 GLboolean
r600CreateContext(const __GLcontextModes
* glVisual
,
246 __DRIcontextPrivate
* driContextPriv
,
247 void *sharedContextPrivate
)
249 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
250 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
251 struct dd_function_table functions
;
257 assert(driContextPriv
);
260 /* Allocate the R600 context */
261 r600
= (r600ContextPtr
) CALLOC(sizeof(*r600
));
265 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
266 hw_tcl_on
= future_hw_tcl_on
= 0;
268 r600_init_vtbl(&r600
->radeon
);
269 /* Parse configuration files.
270 * Do this here so that initialMaxAnisotropy is set before we create
271 * the default textures.
273 driParseConfigFiles(&r600
->radeon
.optionCache
, &screen
->optionCache
,
274 screen
->driScreen
->myNum
, "r600");
276 r600
->radeon
.initialMaxAnisotropy
= driQueryOptionf(&r600
->radeon
.optionCache
,
277 "def_max_anisotropy");
279 /* Init default driver functions then plug in our R600-specific functions
280 * (the texture functions are especially important)
282 _mesa_init_driver_functions(&functions
);
284 r700InitChipObject(r600
); /* let the eag... */
286 (r600
->chipobj
.InitFuncs
)(&functions
);
287 r600
->chipobj
.EmitShader
= r600EmitShader
;
288 r600
->chipobj
.DeleteShader
= r600DeleteShader
;
289 r600
->chipobj
.FreeDmaRegion
= r600FreeDmaRegion
;
290 r600
->chipobj
.EmitVec
= r600EmitVec
;
291 r600
->chipobj
.ReleaseArrays
= r600ReleaseVec
;
292 r600
->chipobj
.LoadMemSurf
= r600LoadMemSurf
;
293 r600
->chipobj
.AllocMemSurf
= r600AllocMemSurf
;
294 r600
->chipobj
.FlushCmdBuffer
= r600FlushCmdBuffer
;
295 r600
->chipobj
.MemUse
= r600MemUse
;
297 if (!radeonInitContext(&r600
->radeon
, &functions
,
298 glVisual
, driContextPriv
,
299 sharedContextPrivate
)) {
304 /* Init r600 context data */
305 /* Set the maximum texture size small enough that we can guarentee that
306 * all texture units can bind a maximal texture and have them both in
307 * texturable memory at once.
310 ctx
= r600
->radeon
.glCtx
;
312 ctx
->Const
.MaxTextureImageUnits
=
313 driQueryOptioni(&r600
->radeon
.optionCache
, "texture_image_units");
314 ctx
->Const
.MaxTextureCoordUnits
=
315 driQueryOptioni(&r600
->radeon
.optionCache
, "texture_coord_units");
316 ctx
->Const
.MaxTextureUnits
=
317 MIN2(ctx
->Const
.MaxTextureImageUnits
,
318 ctx
->Const
.MaxTextureCoordUnits
);
319 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
320 ctx
->Const
.MaxTextureLodBias
= 16.0;
322 if (screen
->chip_family
>= CHIP_FAMILY_RV515
) {
323 ctx
->Const
.MaxTextureLevels
= 13;
324 ctx
->Const
.MaxTextureRectSize
= 4096;
327 ctx
->Const
.MinPointSize
= 0x0001 / 8.0;
328 ctx
->Const
.MinPointSizeAA
= 0x0001 / 8.0;
329 ctx
->Const
.MaxPointSize
= 0xffff / 8.0;
330 ctx
->Const
.MaxPointSizeAA
= 0xffff / 8.0;
332 ctx
->Const
.MinLineWidth
= 0x0001 / 8.0;
333 ctx
->Const
.MinLineWidthAA
= 0x0001 / 8.0;
334 ctx
->Const
.MaxLineWidth
= 0xffff / 8.0;
335 ctx
->Const
.MaxLineWidthAA
= 0xffff / 8.0;
337 /* Needs further modifications */
339 ctx
->Const
.MaxArrayLockSize
=
340 ( /*512 */ RADEON_BUFFER_SIZE
* 16 * 1024) / (4 * 4);
343 ctx
->Const
.MaxDrawBuffers
= 1;
345 /* Initialize the software rasterizer and helper modules.
347 _swrast_CreateContext(ctx
);
348 _vbo_CreateContext(ctx
);
349 _tnl_CreateContext(ctx
);
350 _swsetup_CreateContext(ctx
);
351 _swsetup_Wakeup(ctx
);
352 _ae_create_context(ctx
);
354 /* Install the customized pipeline:
356 _tnl_destroy_pipeline(ctx
);
357 _tnl_install_pipeline(ctx
, (const struct tnl_pipeline_stage
**)(r600
->chipobj
.stages
));
359 /* Try and keep materials and vertices separate:
361 /* _tnl_isolate_materials(ctx, GL_TRUE); */
363 /* Configure swrast and TNL to match hardware characteristics:
365 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
366 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
367 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
368 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
370 /* currently bogus data */
371 if (screen
->chip_flags
& RADEON_CHIPSET_TCL
) {
372 ctx
->Const
.VertexProgram
.MaxInstructions
= VSF_MAX_FRAGMENT_LENGTH
/ 4;
373 ctx
->Const
.VertexProgram
.MaxNativeInstructions
=
374 VSF_MAX_FRAGMENT_LENGTH
/ 4;
375 ctx
->Const
.VertexProgram
.MaxNativeAttribs
= 16; /* r420 */
376 ctx
->Const
.VertexProgram
.MaxTemps
= 32;
377 ctx
->Const
.VertexProgram
.MaxNativeTemps
=
378 /*VSF_MAX_FRAGMENT_TEMPS */ 32;
379 ctx
->Const
.VertexProgram
.MaxNativeParameters
= 256; /* r420 */
380 ctx
->Const
.VertexProgram
.MaxNativeAddressRegs
= 1;
383 ctx
->Const
.FragmentProgram
.MaxNativeTemps
= PFS_NUM_TEMP_REGS
;
384 ctx
->Const
.FragmentProgram
.MaxNativeAttribs
= 11; /* copy i915... */
385 ctx
->Const
.FragmentProgram
.MaxNativeParameters
= PFS_NUM_CONST_REGS
;
386 ctx
->Const
.FragmentProgram
.MaxNativeAluInstructions
= PFS_MAX_ALU_INST
;
387 ctx
->Const
.FragmentProgram
.MaxNativeTexInstructions
= PFS_MAX_TEX_INST
;
388 ctx
->Const
.FragmentProgram
.MaxNativeInstructions
=
389 PFS_MAX_ALU_INST
+ PFS_MAX_TEX_INST
;
390 ctx
->Const
.FragmentProgram
.MaxNativeTexIndirections
=
391 PFS_MAX_TEX_INDIRECT
;
392 ctx
->Const
.FragmentProgram
.MaxNativeAddressRegs
= 0; /* and these are?? */
393 ctx
->VertexProgram
._MaintainTnlProgram
= GL_TRUE
;
394 ctx
->FragmentProgram
._MaintainTexEnvProgram
= GL_TRUE
;
396 driInitExtensions(ctx
, card_extensions
, GL_TRUE
);
397 if (r600
->radeon
.radeonScreen
->kernel_mm
)
398 driInitExtensions(ctx
, mm_extensions
, GL_FALSE
);
401 (&r600
->radeon
.optionCache
, "disable_stencil_two_side"))
402 _mesa_disable_extension(ctx
, "GL_EXT_stencil_two_side");
404 if (r600
->radeon
.glCtx
->Mesa_DXTn
405 && !driQueryOptionb(&r600
->radeon
.optionCache
, "disable_s3tc")) {
406 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
407 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
409 if (driQueryOptionb(&r600
->radeon
.optionCache
, "force_s3tc_enable"))
411 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
414 r600
->disable_lowimpact_fallback
=
415 driQueryOptionb(&r600
->radeon
.optionCache
,
416 "disable_lowimpact_fallback");
417 radeon_fbo_init(&r600
->radeon
);
418 radeonInitSpanFuncs( ctx
);
420 r600InitCmdBuf(r600
);
422 (r600
->chipobj
.InitState
)(r600
->radeon
.glCtx
);
423 #if 0 /* to be enabled */
424 if (!(screen
->chip_flags
& RADEON_CHIPSET_TCL
))
428 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= r600RunPipeline
;
430 tcl_mode
= driQueryOptioni(&r600
->radeon
.optionCache
, "tcl_mode");
431 if (driQueryOptionb(&r600
->radeon
.optionCache
, "no_rast")) {
432 fprintf(stderr
, "disabling 3D acceleration\n");
434 FALLBACK(&r600
->radeon
, RADEON_FALLBACK_DISABLE
, 1);
437 if (tcl_mode
== DRI_CONF_TCL_SW
||
438 !(r600
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)) {
439 if (r600
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
440 r600
->radeon
.radeonScreen
->chip_flags
&=
442 fprintf(stderr
, "Disabling HW TCL support\n");
444 TCL_FALLBACK(r600
->radeon
.glCtx
,
445 RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);