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 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
33 * Nicolai Haehnle <prefect_@gmx.net>
36 #include "api_arrayelt.h"
38 #include "simple_list.h"
41 #include "extensions.h"
43 #include "bufferobj.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "array_cache/acache.h"
50 #include "tnl/t_pipeline.h"
52 #include "drivers/common/driverfuncs.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_span.h"
56 #include "r300_context.h"
57 #include "r300_cmdbuf.h"
58 #include "r300_state.h"
59 #include "r300_ioctl.h"
64 #include "xmlpool.h" /* for symbolic values of enum-type options */
66 /* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
67 int future_hw_tcl_on
=0;
71 #define need_GL_ARB_multisample
72 #define need_GL_ARB_texture_compression
73 #define need_GL_EXT_blend_minmax
74 #include "extension_helper.h"
76 const struct dri_extension card_extensions
[] = {
77 {"GL_ARB_multisample", GL_ARB_multisample_functions
},
78 {"GL_ARB_multitexture", NULL
},
79 {"GL_ARB_texture_border_clamp", NULL
},
80 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
81 /* disable until we support it, fixes a few things in ut2004 */
82 /* {"GL_ARB_texture_cube_map", NULL}, */
83 {"GL_ARB_texture_env_add", NULL
},
84 {"GL_ARB_texture_env_combine", NULL
},
85 {"GL_ARB_texture_env_crossbar", NULL
},
86 {"GL_ARB_texture_env_dot3", NULL
},
87 {"GL_ARB_texture_mirrored_repeat", NULL
},
88 {"GL_ARB_vertex_buffer_object", NULL
},
89 {"GL_ARB_vertex_program", NULL
},
91 {"GL_ARB_fragment_program", NULL
},
93 {"GL_EXT_blend_equation_separate", NULL
},
94 {"GL_EXT_blend_func_separate", NULL
},
95 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions
},
96 {"GL_EXT_blend_subtract", NULL
},
97 {"GL_EXT_secondary_color", NULL
},
98 {"GL_EXT_stencil_wrap", NULL
},
99 {"GL_EXT_texture_edge_clamp", NULL
},
100 {"GL_EXT_texture_env_combine", NULL
},
101 {"GL_EXT_texture_env_dot3", NULL
},
102 {"GL_EXT_texture_filter_anisotropic", NULL
},
103 {"GL_EXT_texture_lod_bias", NULL
},
104 {"GL_EXT_texture_mirror_clamp", NULL
},
105 {"GL_EXT_texture_rectangle", NULL
},
106 {"GL_ATI_texture_env_combine3", NULL
},
107 {"GL_ATI_texture_mirror_once", NULL
},
108 {"GL_MESA_pack_invert", NULL
},
109 {"GL_MESA_ycbcr_texture", NULL
},
110 {"GL_NV_blend_square", NULL
},
111 {"GL_NV_vertex_program", NULL
},
112 {"GL_SGIS_generate_mipmap", NULL
},
117 /* Extension strings exported by the R300 driver.
119 static const char *const card_extensions
[] = {
120 "GL_ARB_multisample",
121 "GL_ARB_multitexture",
122 "GL_ARB_texture_border_clamp",
123 "GL_ARB_texture_compression",
124 /* disable until we support it, fixes a few things in ut2004 */
125 /* "GL_ARB_texture_cube_map", */
126 "GL_ARB_texture_env_add",
127 "GL_ARB_texture_env_combine",
128 "GL_ARB_texture_env_crossbar",
129 "GL_ARB_texture_env_dot3",
130 "GL_ARB_texture_mirrored_repeat",
131 "GL_ARB_vertex_buffer_object",
132 "GL_ARB_vertex_program",
134 "GL_ARB_fragment_program",
136 "GL_EXT_blend_equation_separate",
137 "GL_EXT_blend_func_separate",
138 "GL_EXT_blend_minmax",
139 "GL_EXT_blend_subtract",
140 "GL_EXT_secondary_color",
141 "GL_EXT_stencil_wrap",
142 "GL_EXT_texture_edge_clamp",
143 "GL_EXT_texture_env_combine",
144 "GL_EXT_texture_env_dot3",
145 "GL_EXT_texture_filter_anisotropic",
146 "GL_EXT_texture_lod_bias",
147 "GL_EXT_texture_mirror_clamp",
148 "GL_EXT_texture_rectangle",
149 "GL_ATI_texture_env_combine3",
150 "GL_ATI_texture_mirror_once",
151 "GL_MESA_pack_invert",
152 "GL_MESA_ycbcr_texture",
153 "GL_NV_blend_square",
154 "GL_NV_vertex_program",
155 "GL_SGIS_generate_mipmap",
159 extern struct tnl_pipeline_stage _r300_render_stage
;
160 extern struct tnl_pipeline_stage _r300_tcl_stage
;
162 static const struct tnl_pipeline_stage
*r300_pipeline
[] = {
164 /* Try and go straight to t&l
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_vertex_program_stage
,
178 /* Try again to go to tcl?
179 * - no good for asymmetric-twoside (do with multipass)
180 * - no good for asymmetric-unfilled (do with multipass)
181 * - good for material
183 * - need to manipulate a bit of state
185 * - worth it/not worth it?
188 /* Else do them here.
191 &_tnl_render_stage
, /* FALLBACK */
195 static void r300BufferData(GLcontext
*ctx
, GLenum target
, GLsizeiptrARB size
,
196 const GLvoid
*data
, GLenum usage
, struct gl_buffer_object
*obj
)
198 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
199 drm_radeon_mem_alloc_t alloc
;
202 /* Free previous buffer */
204 drm_radeon_mem_free_t memfree
;
206 memfree
.region
= RADEON_MEM_REGION_GART
;
207 memfree
.region_offset
= (char *)obj
->Data
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
209 ret
= drmCommandWrite(rmesa
->radeon
.radeonScreen
->driScreen
->fd
,
210 DRM_RADEON_FREE
, &memfree
, sizeof(memfree
));
213 WARN_ONCE("Failed to free GART memroy!\n");
215 obj
->OnCard
= GL_FALSE
;
218 alloc
.region
= RADEON_MEM_REGION_GART
;
221 alloc
.region_offset
= &offset
;
223 ret
= drmCommandWriteRead( rmesa
->radeon
.dri
.fd
, DRM_RADEON_ALLOC
, &alloc
, sizeof(alloc
));
225 WARN_ONCE("Ran out of GART memory!\n");
227 _mesa_buffer_data(ctx
, target
, size
, data
, usage
, obj
);
230 obj
->Data
= ((char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
) + offset
;
233 memcpy(obj
->Data
, data
, size
);
237 obj
->OnCard
= GL_TRUE
;
239 fprintf(stderr
, "allocated %d bytes at %p, offset=%d\n", size
, obj
->Data
, offset
);
243 static void r300DeleteBuffer(GLcontext
*ctx
, struct gl_buffer_object
*obj
)
245 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
247 if(r300IsGartMemory(rmesa
, obj
->Data
, obj
->Size
)){
248 drm_radeon_mem_free_t memfree
;
251 memfree
.region
= RADEON_MEM_REGION_GART
;
252 memfree
.region_offset
= (char *)obj
->Data
- (char *)rmesa
->radeon
.radeonScreen
->gartTextures
.map
;
254 ret
= drmCommandWrite(rmesa
->radeon
.radeonScreen
->driScreen
->fd
,
255 DRM_RADEON_FREE
, &memfree
, sizeof(memfree
));
258 WARN_ONCE("Failed to free GART memroy!\n");
262 _mesa_delete_buffer_object(ctx
, obj
);
265 /* Create the device specific rendering context.
267 GLboolean
r300CreateContext(const __GLcontextModes
* glVisual
,
268 __DRIcontextPrivate
* driContextPriv
,
269 void *sharedContextPrivate
)
271 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
272 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
273 struct dd_function_table functions
;
279 assert(driContextPriv
);
282 /* Allocate the R300 context */
283 r300
= (r300ContextPtr
)CALLOC(sizeof(*r300
));
287 /* Parse configuration files.
288 * Do this here so that initialMaxAnisotropy is set before we create
289 * the default textures.
291 driParseConfigFiles(&r300
->radeon
.optionCache
, &screen
->optionCache
,
292 screen
->driScreen
->myNum
, "r300");
294 /* Init default driver functions then plug in our R300-specific functions
295 * (the texture functions are especially important)
297 _mesa_init_driver_functions(&functions
);
298 r300InitIoctlFuncs(&functions
);
299 r300InitStateFuncs(&functions
);
300 r300InitTextureFuncs(&functions
);
301 r300InitShaderFuncs(&functions
);
303 #if 0 /* Needs various Mesa changes... */
305 functions
.BufferData
= r300BufferData
;
306 functions
.DeleteBuffer
= r300DeleteBuffer
;
310 if (!radeonInitContext(&r300
->radeon
, &functions
,
311 glVisual
, driContextPriv
, sharedContextPrivate
)) {
316 /* Init r300 context data */
317 r300
->dma
.buf0_address
= r300
->radeon
.radeonScreen
->buffers
->list
[0].address
;
319 (void)memset(r300
->texture_heaps
, 0, sizeof(r300
->texture_heaps
));
320 make_empty_list(&r300
->swapped
);
322 r300
->nr_heaps
= 1 /* screen->numTexHeaps */ ;
323 assert(r300
->nr_heaps
< R200_NR_TEX_HEAPS
);
324 for (i
= 0; i
< r300
->nr_heaps
; i
++) {
325 r300
->texture_heaps
[i
] = driCreateTextureHeap(i
, r300
,
328 RADEON_NR_TEX_REGIONS
,
329 (drmTextureRegionPtr
)
332 &r300
->radeon
.sarea
->
337 (destroy_texture_object_t
341 r300
->texture_depth
= driQueryOptioni(&r300
->radeon
.optionCache
,
343 if (r300
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
344 r300
->texture_depth
= (screen
->cpp
== 4) ?
345 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
347 /* Set the maximum texture size small enough that we can guarentee that
348 * all texture units can bind a maximal texture and have them both in
349 * texturable memory at once.
352 ctx
= r300
->radeon
.glCtx
;
354 ctx
->Const
.MaxTextureImageUnits
= driQueryOptioni(&r300
->radeon
.optionCache
,
355 "texture_image_units");
356 ctx
->Const
.MaxTextureCoordUnits
= driQueryOptioni(&r300
->radeon
.optionCache
,
357 "texture_coord_units");
358 ctx
->Const
.MaxTextureUnits
= MIN2(ctx
->Const
.MaxTextureImageUnits
,
359 ctx
->Const
.MaxTextureCoordUnits
);
360 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
362 ctx
->Const
.MinPointSize
= 1.0;
363 ctx
->Const
.MinPointSizeAA
= 1.0;
364 ctx
->Const
.MaxPointSize
= R300_POINTSIZE_MAX
;
365 ctx
->Const
.MaxPointSizeAA
= R300_POINTSIZE_MAX
;
367 ctx
->Const
.MinLineWidth
= 1.0;
368 ctx
->Const
.MinLineWidthAA
= 1.0;
369 ctx
->Const
.MaxLineWidth
= R300_LINESIZE_MAX
;
370 ctx
->Const
.MaxLineWidthAA
= R300_LINESIZE_MAX
;
372 /* Initialize the software rasterizer and helper modules.
374 _swrast_CreateContext(ctx
);
375 _ac_CreateContext(ctx
);
376 _tnl_CreateContext(ctx
);
377 _swsetup_CreateContext(ctx
);
378 _swsetup_Wakeup(ctx
);
379 _ae_create_context(ctx
);
381 /* Install the customized pipeline:
383 _tnl_destroy_pipeline(ctx
);
384 _tnl_install_pipeline(ctx
, r300_pipeline
);
386 /* Try and keep materials and vertices separate:
388 _tnl_isolate_materials(ctx
, GL_TRUE
);
390 /* Configure swrast and TNL to match hardware characteristics:
392 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
393 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
394 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
395 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
397 /* currently bogus data */
398 ctx
->Const
.MaxVertexProgramInstructions
=VSF_MAX_FRAGMENT_LENGTH
;
399 ctx
->Const
.MaxVertexProgramAttribs
=16; // r420
400 ctx
->Const
.MaxVertexProgramTemps
=VSF_MAX_FRAGMENT_TEMPS
;
401 ctx
->Const
.MaxVertexProgramLocalParams
=256; // r420
402 ctx
->Const
.MaxVertexProgramEnvParams
=256; // r420
403 ctx
->Const
.MaxVertexProgramAddressRegs
=1;
406 ctx
->Const
.MaxFragmentProgramTemps
= PFS_NUM_TEMP_REGS
;
407 ctx
->Const
.MaxFragmentProgramAttribs
= 11; /* copy i915... */
408 ctx
->Const
.MaxFragmentProgramLocalParams
= PFS_NUM_CONST_REGS
;
409 ctx
->Const
.MaxFragmentProgramEnvParams
= PFS_NUM_CONST_REGS
;
410 ctx
->Const
.MaxFragmentProgramAluInstructions
= PFS_MAX_ALU_INST
;
411 ctx
->Const
.MaxFragmentProgramTexInstructions
= PFS_MAX_TEX_INST
;
412 ctx
->Const
.MaxFragmentProgramInstructions
= PFS_MAX_ALU_INST
+PFS_MAX_TEX_INST
;
413 ctx
->Const
.MaxFragmentProgramTexIndirections
= PFS_MAX_TEX_INDIRECT
;
414 ctx
->Const
.MaxFragmentProgramAddressRegs
= 0; /* and these are?? */
415 ctx
->_MaintainTexEnvProgram
= GL_TRUE
;
418 driInitExtensions(ctx
, card_extensions
, GL_TRUE
);
420 radeonInitSpanFuncs(ctx
);
421 r300InitCmdBuf(r300
);
425 /* plug in a few more device driver functions */
426 /* XXX these should really go right after _mesa_init_driver_functions() */
427 r300InitPixelFuncs(ctx
);
430 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
432 tcl_mode
= driQueryOptioni(&r300
->radeon
.optionCache
, "tcl_mode");
433 if (driQueryOptionb(&r300
->radeon
.optionCache
, "no_rast")) {
434 fprintf(stderr
, "disabling 3D acceleration\n");
436 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_DISABLE
, 1);
439 if (tcl_mode
== DRI_CONF_TCL_SW
||
440 !(r300
->radeon
.radeonScreen
->chipset
& RADEON_CHIPSET_TCL
)) {
441 if (r300
->radeon
.radeonScreen
->chipset
& RADEON_CHIPSET_TCL
) {
442 r300
->radeon
.radeonScreen
->chipset
&= ~RADEON_CHIPSET_TCL
;
443 fprintf(stderr
, "Disabling HW TCL support\n");
445 TCL_FALLBACK(r300
->radeon
.glCtx
, RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);
451 /* Destroy the device specific context.
453 void r300DestroyContext(__DRIcontextPrivate
* driContextPriv
)
455 GET_CURRENT_CONTEXT(ctx
);
456 r300ContextPtr r300
= (r300ContextPtr
) driContextPriv
->driverPrivate
;
457 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
459 if (RADEON_DEBUG
& DEBUG_DRI
) {
460 fprintf(stderr
, "Destroying context !\n");
463 /* check if we're deleting the currently bound context */
464 if (&r300
->radeon
== current
) {
465 radeonFlush(r300
->radeon
.glCtx
);
466 _mesa_make_current(NULL
, NULL
, NULL
);
469 /* Free r300 context resources */
470 assert(r300
); /* should never be null */
473 GLboolean release_texture_heaps
;
475 release_texture_heaps
= (r300
->radeon
.glCtx
->Shared
->RefCount
== 1);
476 _swsetup_DestroyContext(r300
->radeon
.glCtx
);
477 _tnl_DestroyContext(r300
->radeon
.glCtx
);
478 _ac_DestroyContext(r300
->radeon
.glCtx
);
479 _swrast_DestroyContext(r300
->radeon
.glCtx
);
481 r300DestroyCmdBuf(r300
);
483 radeonCleanupContext(&r300
->radeon
);
485 /* free the option cache */
486 driDestroyOptionCache(&r300
->radeon
.optionCache
);