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 "radeon_debug.h"
60 #include "r600_context.h"
61 #include "radeon_common_context.h"
62 #include "radeon_buffer_objects.h"
63 #include "radeon_span.h"
64 #include "r600_cmdbuf.h"
65 #include "r600_emit.h"
66 #include "radeon_bocs_wrapper.h"
67 #include "radeon_queryobj.h"
69 #include "r700_state.h"
70 #include "r700_ioctl.h"
75 #include "xmlpool.h" /* for symbolic values of enum-type options */
77 //#define R600_ENABLE_GLSL_TEST 1
79 #define need_GL_VERSION_2_0
80 #define need_GL_ARB_occlusion_query
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_provoking_vertex
90 #define need_GL_EXT_secondary_color
91 #define need_GL_EXT_stencil_two_side
92 #define need_GL_ATI_separate_stencil
93 #define need_GL_NV_vertex_program
95 #include "main/remap_helper.h"
97 static const struct dri_extension card_extensions
[] = {
99 {"GL_ARB_depth_clamp", NULL
},
100 {"GL_ARB_depth_texture", NULL
},
101 {"GL_ARB_fragment_program", NULL
},
102 {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions
},
103 {"GL_ARB_multitexture", NULL
},
104 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
105 {"GL_ARB_shadow", NULL
},
106 {"GL_ARB_shadow_ambient", NULL
},
107 {"GL_ARB_texture_border_clamp", NULL
},
108 {"GL_ARB_texture_cube_map", NULL
},
109 {"GL_ARB_texture_env_add", NULL
},
110 {"GL_ARB_texture_env_combine", NULL
},
111 {"GL_ARB_texture_env_crossbar", NULL
},
112 {"GL_ARB_texture_env_dot3", NULL
},
113 {"GL_ARB_texture_mirrored_repeat", NULL
},
114 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
115 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions
},
116 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions
},
117 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions
},
118 {"GL_EXT_blend_subtract", NULL
},
119 {"GL_EXT_packed_depth_stencil", NULL
},
120 {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
121 {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions
},
122 {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions
},
123 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
124 {"GL_EXT_shadow_funcs", NULL
},
125 {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions
},
126 {"GL_EXT_stencil_wrap", NULL
},
127 {"GL_EXT_texture_edge_clamp", NULL
},
128 {"GL_EXT_texture_env_combine", NULL
},
129 {"GL_EXT_texture_env_dot3", NULL
},
130 {"GL_EXT_texture_filter_anisotropic", NULL
},
131 {"GL_EXT_texture_lod_bias", NULL
},
132 {"GL_EXT_texture_mirror_clamp", NULL
},
133 {"GL_EXT_texture_rectangle", NULL
},
134 {"GL_EXT_vertex_array_bgra", NULL
},
135 {"GL_EXT_texture_sRGB", NULL
},
136 {"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions
},
137 {"GL_ATI_texture_env_combine3", NULL
},
138 {"GL_ATI_texture_mirror_once", NULL
},
139 {"GL_MESA_pack_invert", NULL
},
140 {"GL_MESA_ycbcr_texture", NULL
},
141 {"GL_MESAX_texture_float", NULL
},
142 {"GL_NV_blend_square", NULL
},
143 {"GL_NV_vertex_program", GL_NV_vertex_program_functions
},
144 {"GL_SGIS_generate_mipmap", NULL
},
150 static const struct dri_extension mm_extensions
[] = {
151 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions
},
156 * The GL 2.0 functions are needed to make display lists work with
157 * functions added by GL_ATI_separate_stencil.
159 static const struct dri_extension gl_20_extension
[] = {
160 #ifdef R600_ENABLE_GLSL_TEST
161 {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions
},
163 {"GL_VERSION_2_0", GL_VERSION_2_0_functions
},
164 #endif /* R600_ENABLE_GLSL_TEST */
167 static const struct tnl_pipeline_stage
*r600_pipeline
[] = {
168 /* Catch any t&l fallbacks
170 &_tnl_vertex_transform_stage
,
171 &_tnl_normal_transform_stage
,
172 &_tnl_lighting_stage
,
173 &_tnl_fog_coordinate_stage
,
175 &_tnl_texture_transform_stage
,
176 &_tnl_point_attenuation_stage
,
177 &_tnl_vertex_program_stage
,
182 static void r600_get_lock(radeonContextPtr rmesa
)
184 drm_radeon_sarea_t
*sarea
= rmesa
->sarea
;
186 if (sarea
->ctx_owner
!= rmesa
->dri
.hwContext
) {
187 sarea
->ctx_owner
= rmesa
->dri
.hwContext
;
188 if (!rmesa
->radeonScreen
->kernel_mm
)
189 radeon_bo_legacy_texture_age(rmesa
->radeonScreen
->bom
);
193 static void r600_vtbl_emit_cs_header(struct radeon_cs
*cs
, radeonContextPtr rmesa
)
195 /* please flush pipe do all pending work */
199 static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon
)
201 r700Start3D((context_t
*)radeon
);
204 static void r600_fallback(GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
206 context_t
*context
= R700_CONTEXT(ctx
);
208 context
->radeon
.Fallback
|= bit
;
210 context
->radeon
.Fallback
&= ~bit
;
213 static void r600_emit_query_finish(radeonContextPtr radeon
)
215 context_t
*context
= (context_t
*) radeon
;
216 BATCH_LOCALS(&context
->radeon
);
218 struct radeon_query_object
*query
= radeon
->query
.current
;
220 BEGIN_BATCH_NO_AUTOSTATE(4 + 2);
221 R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE
, 2));
222 R600_OUT_BATCH(ZPASS_DONE
);
223 R600_OUT_BATCH(query
->curr_offset
+ 8); /* hw writes qwords */
224 R600_OUT_BATCH(0x00000000);
225 R600_OUT_BATCH_RELOC(VGT_EVENT_INITIATOR
, query
->bo
, 0, 0, RADEON_GEM_DOMAIN_GTT
, 0);
227 assert(query
->curr_offset
< RADEON_QUERY_PAGE_SIZE
);
228 query
->emitted_begin
= GL_FALSE
;
231 static void r600_init_vtbl(radeonContextPtr radeon
)
233 radeon
->vtbl
.get_lock
= r600_get_lock
;
234 radeon
->vtbl
.update_viewport_offset
= r700UpdateViewportOffset
;
235 radeon
->vtbl
.emit_cs_header
= r600_vtbl_emit_cs_header
;
236 radeon
->vtbl
.swtcl_flush
= NULL
;
237 radeon
->vtbl
.pre_emit_atoms
= r600_vtbl_pre_emit_atoms
;
238 radeon
->vtbl
.fallback
= r600_fallback
;
239 radeon
->vtbl
.emit_query_finish
= r600_emit_query_finish
;
242 static void r600InitConstValues(GLcontext
*ctx
, radeonScreenPtr screen
)
244 context_t
*r600
= R700_CONTEXT(ctx
);
246 ctx
->Const
.MaxTextureImageUnits
=
247 driQueryOptioni(&r600
->radeon
.optionCache
, "texture_image_units");
248 ctx
->Const
.MaxTextureCoordUnits
=
249 driQueryOptioni(&r600
->radeon
.optionCache
, "texture_coord_units");
250 ctx
->Const
.MaxTextureUnits
=
251 MIN2(ctx
->Const
.MaxTextureImageUnits
,
252 ctx
->Const
.MaxTextureCoordUnits
);
253 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
254 ctx
->Const
.MaxTextureLodBias
= 16.0;
256 ctx
->Const
.MaxTextureLevels
= 13; /* hw support 14 */
257 ctx
->Const
.MaxTextureRectSize
= 4096; /* hw support 8192 */
259 ctx
->Const
.MinPointSize
= 0x0001 / 8.0;
260 ctx
->Const
.MinPointSizeAA
= 0x0001 / 8.0;
261 ctx
->Const
.MaxPointSize
= 0xffff / 8.0;
262 ctx
->Const
.MaxPointSizeAA
= 0xffff / 8.0;
264 ctx
->Const
.MinLineWidth
= 0x0001 / 8.0;
265 ctx
->Const
.MinLineWidthAA
= 0x0001 / 8.0;
266 ctx
->Const
.MaxLineWidth
= 0xffff / 8.0;
267 ctx
->Const
.MaxLineWidthAA
= 0xffff / 8.0;
269 ctx
->Const
.MaxDrawBuffers
= 1; /* hw supports 8 */
271 /* 256 for reg-based consts, inline consts also supported */
272 ctx
->Const
.VertexProgram
.MaxInstructions
= 8192; /* in theory no limit */
273 ctx
->Const
.VertexProgram
.MaxNativeInstructions
= 8192;
274 ctx
->Const
.VertexProgram
.MaxNativeAttribs
= 160;
275 ctx
->Const
.VertexProgram
.MaxTemps
= 128;
276 ctx
->Const
.VertexProgram
.MaxNativeTemps
= 128;
277 ctx
->Const
.VertexProgram
.MaxNativeParameters
= 256;
278 ctx
->Const
.VertexProgram
.MaxNativeAddressRegs
= 1; /* ??? */
280 ctx
->Const
.FragmentProgram
.MaxNativeTemps
= 128;
281 ctx
->Const
.FragmentProgram
.MaxNativeAttribs
= 32;
282 ctx
->Const
.FragmentProgram
.MaxNativeParameters
= 256;
283 ctx
->Const
.FragmentProgram
.MaxNativeAluInstructions
= 8192;
284 /* 8 per clause on r6xx, 16 on rv670/r7xx */
285 if ((screen
->chip_family
== CHIP_FAMILY_RV670
) ||
286 (screen
->chip_family
>= CHIP_FAMILY_RV770
))
287 ctx
->Const
.FragmentProgram
.MaxNativeTexInstructions
= 16;
289 ctx
->Const
.FragmentProgram
.MaxNativeTexInstructions
= 8;
290 ctx
->Const
.FragmentProgram
.MaxNativeInstructions
= 8192;
291 ctx
->Const
.FragmentProgram
.MaxNativeTexIndirections
= 8; /* ??? */
292 ctx
->Const
.FragmentProgram
.MaxNativeAddressRegs
= 0; /* and these are?? */
295 static void r600ParseOptions(context_t
*r600
, radeonScreenPtr screen
)
297 /* Parse configuration files.
298 * Do this here so that initialMaxAnisotropy is set before we create
299 * the default textures.
301 driParseConfigFiles(&r600
->radeon
.optionCache
, &screen
->optionCache
,
302 screen
->driScreen
->myNum
, "r600");
304 r600
->radeon
.initialMaxAnisotropy
= driQueryOptionf(&r600
->radeon
.optionCache
,
305 "def_max_anisotropy");
309 static void r600InitGLExtensions(GLcontext
*ctx
)
311 context_t
*r600
= R700_CONTEXT(ctx
);
313 driInitExtensions(ctx
, card_extensions
, GL_TRUE
);
314 if (r600
->radeon
.radeonScreen
->kernel_mm
)
315 driInitExtensions(ctx
, mm_extensions
, GL_FALSE
);
317 #ifdef R600_ENABLE_GLSL_TEST
318 driInitExtensions(ctx
, gl_20_extension
, GL_TRUE
);
319 //_mesa_enable_2_0_extensions(ctx);
321 ctx
->Extensions
.ARB_occlusion_query
= GL_TRUE
;
322 ctx
->Extensions
.ARB_vertex_buffer_object
= GL_TRUE
;
323 ctx
->Extensions
.EXT_shadow_funcs
= GL_TRUE
;
325 ctx
->Extensions
.ARB_draw_buffers
= GL_TRUE
;
326 ctx
->Extensions
.ARB_point_sprite
= GL_TRUE
;
327 ctx
->Extensions
.ARB_shader_objects
= GL_TRUE
;
328 ctx
->Extensions
.ARB_vertex_shader
= GL_TRUE
;
329 ctx
->Extensions
.ARB_fragment_shader
= GL_TRUE
;
330 ctx
->Extensions
.ARB_texture_non_power_of_two
= GL_TRUE
;
331 ctx
->Extensions
.EXT_blend_equation_separate
= GL_TRUE
;
332 ctx
->Extensions
.ATI_separate_stencil
= GL_TRUE
;
334 /* glsl compiler has problem if this is not GL_TRUE */
335 ctx
->Shader
.EmitCondCodes
= GL_TRUE
;
336 #endif /* R600_ENABLE_GLSL_TEST */
339 (&r600
->radeon
.optionCache
, "disable_stencil_two_side"))
340 _mesa_disable_extension(ctx
, "GL_EXT_stencil_two_side");
342 if (r600
->radeon
.glCtx
->Mesa_DXTn
343 && !driQueryOptionb(&r600
->radeon
.optionCache
, "disable_s3tc")) {
344 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
345 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
347 if (driQueryOptionb(&r600
->radeon
.optionCache
, "force_s3tc_enable"))
349 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
352 /* XXX: RV740 only seems to report results from half of its DBs */
353 if (r600
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV740
)
354 _mesa_disable_extension(ctx
, "GL_ARB_occlusion_query");
357 /* Create the device specific rendering context.
359 GLboolean
r600CreateContext(const __GLcontextModes
* glVisual
,
360 __DRIcontextPrivate
* driContextPriv
,
361 void *sharedContextPrivate
)
363 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
364 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
365 struct dd_function_table functions
;
370 assert(driContextPriv
);
373 /* Allocate the R600 context */
374 r600
= (context_t
*) CALLOC(sizeof(*r600
));
376 radeon_error("Failed to allocate memory for context.\n");
380 r600ParseOptions(r600
, screen
);
382 r600
->radeon
.radeonScreen
= screen
;
383 r600_init_vtbl(&r600
->radeon
);
385 /* Init default driver functions then plug in our R600-specific functions
386 * (the texture functions are especially important)
388 _mesa_init_driver_functions(&functions
);
390 r700InitStateFuncs(&functions
);
391 r600InitTextureFuncs(&functions
);
392 r700InitShaderFuncs(&functions
);
393 radeonInitQueryObjFunctions(&functions
);
394 r700InitIoctlFuncs(&functions
);
395 radeonInitBufferObjectFuncs(&functions
);
397 if (!radeonInitContext(&r600
->radeon
, &functions
,
398 glVisual
, driContextPriv
,
399 sharedContextPrivate
)) {
400 radeon_error("Initializing context failed.\n");
405 ctx
= r600
->radeon
.glCtx
;
407 ctx
->VertexProgram
._MaintainTnlProgram
= GL_TRUE
;
408 ctx
->FragmentProgram
._MaintainTexEnvProgram
= GL_TRUE
;
410 r600InitConstValues(ctx
, screen
);
412 _mesa_set_mvp_with_dp4( ctx
, GL_TRUE
);
414 /* Initialize the software rasterizer and helper modules.
416 _swrast_CreateContext(ctx
);
417 _vbo_CreateContext(ctx
);
418 _tnl_CreateContext(ctx
);
419 _swsetup_CreateContext(ctx
);
420 _swsetup_Wakeup(ctx
);
422 /* Install the customized pipeline:
424 _tnl_destroy_pipeline(ctx
);
425 _tnl_install_pipeline(ctx
, r600_pipeline
);
426 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
428 /* Configure swrast and TNL to match hardware characteristics:
430 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
431 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
432 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
433 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
439 radeon_fbo_init(&r600
->radeon
);
440 radeonInitSpanFuncs( ctx
);
441 r600InitCmdBuf(r600
);
442 r700InitState(r600
->radeon
.glCtx
);
444 r600InitGLExtensions(ctx
);