• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2 
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                      VA Linux Systems Inc., Fremont, California.
5 
6 All Rights Reserved.
7 
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:
15 
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.
19 
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.
27 
28 **************************************************************************/
29 
30 /*
31  * Authors:
32  *   Kevin E. Martin <martin@valinux.com>
33  *   Gareth Hughes <gareth@valinux.com>
34  *   Keith Whitwell <keithw@vmware.com>
35  */
36 
37 #include <stdbool.h>
38 #include "main/glheader.h"
39 #include "main/api_arrayelt.h"
40 #include "main/api_exec.h"
41 #include "main/context.h"
42 #include "util/simple_list.h"
43 #include "main/imports.h"
44 #include "main/extensions.h"
45 #include "main/version.h"
46 #include "main/vtxfmt.h"
47 
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "vbo/vbo.h"
51 
52 #include "tnl/tnl.h"
53 #include "tnl/t_pipeline.h"
54 
55 #include "drivers/common/driverfuncs.h"
56 
57 #include "radeon_common.h"
58 #include "radeon_context.h"
59 #include "radeon_ioctl.h"
60 #include "radeon_state.h"
61 #include "radeon_span.h"
62 #include "radeon_tex.h"
63 #include "radeon_swtcl.h"
64 #include "radeon_tcl.h"
65 #include "radeon_queryobj.h"
66 #include "radeon_blit.h"
67 #include "radeon_fog.h"
68 
69 #include "utils.h"
70 #include "xmlpool.h" /* for symbolic values of enum-type options */
71 
72 extern const struct tnl_pipeline_stage _radeon_render_stage;
73 extern const struct tnl_pipeline_stage _radeon_tcl_stage;
74 
75 static const struct tnl_pipeline_stage *radeon_pipeline[] = {
76 
77    /* Try and go straight to t&l
78     */
79    &_radeon_tcl_stage,
80 
81    /* Catch any t&l fallbacks
82     */
83    &_tnl_vertex_transform_stage,
84    &_tnl_normal_transform_stage,
85    &_tnl_lighting_stage,
86    &_tnl_fog_coordinate_stage,
87    &_tnl_texgen_stage,
88    &_tnl_texture_transform_stage,
89 
90    &_radeon_render_stage,
91    &_tnl_render_stage,		/* FALLBACK:  */
92    NULL,
93 };
94 
r100_vtbl_pre_emit_state(radeonContextPtr radeon)95 static void r100_vtbl_pre_emit_state(radeonContextPtr radeon)
96 {
97    r100ContextPtr rmesa = (r100ContextPtr)radeon;
98 
99    /* r100 always needs to emit ZBS to avoid TCL lockups */
100    rmesa->hw.zbs.dirty = 1;
101    radeon->hw.is_dirty = 1;
102 }
103 
r100_vtbl_free_context(struct gl_context * ctx)104 static void r100_vtbl_free_context(struct gl_context *ctx)
105 {
106    r100ContextPtr rmesa = R100_CONTEXT(ctx);
107    _mesa_vector4f_free( &rmesa->tcl.ObjClean );
108 }
109 
r100_emit_query_finish(radeonContextPtr radeon)110 static void r100_emit_query_finish(radeonContextPtr radeon)
111 {
112    BATCH_LOCALS(radeon);
113    struct radeon_query_object *query = radeon->query.current;
114 
115    BEGIN_BATCH(4);
116    OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
117    OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
118    END_BATCH();
119    query->curr_offset += sizeof(uint32_t);
120    assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
121    query->emitted_begin = GL_FALSE;
122 }
123 
r100_init_vtbl(radeonContextPtr radeon)124 static void r100_init_vtbl(radeonContextPtr radeon)
125 {
126    radeon->vtbl.swtcl_flush = r100_swtcl_flush;
127    radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state;
128    radeon->vtbl.fallback = radeonFallback;
129    radeon->vtbl.free_context = r100_vtbl_free_context;
130    radeon->vtbl.emit_query_finish = r100_emit_query_finish;
131    radeon->vtbl.check_blit = r100_check_blit;
132    radeon->vtbl.blit = r100_blit;
133    radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
134    radeon->vtbl.revalidate_all_buffers = r100ValidateBuffers;
135 }
136 
137 /* Create the device specific context.
138  */
139 GLboolean
r100CreateContext(gl_api api,const struct gl_config * glVisual,__DRIcontext * driContextPriv,unsigned major_version,unsigned minor_version,uint32_t flags,bool notify_reset,unsigned * error,void * sharedContextPrivate)140 r100CreateContext( gl_api api,
141 		   const struct gl_config *glVisual,
142 		   __DRIcontext *driContextPriv,
143 		   unsigned major_version,
144 		   unsigned minor_version,
145 		   uint32_t flags,
146                    bool notify_reset,
147 		   unsigned *error,
148 		   void *sharedContextPrivate)
149 {
150    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
151    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
152    struct dd_function_table functions;
153    r100ContextPtr rmesa;
154    struct gl_context *ctx;
155    int i;
156    int tcl_mode, fthrottle_mode;
157 
158    if (flags & ~__DRI_CTX_FLAG_DEBUG) {
159       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
160       return false;
161    }
162 
163    if (notify_reset) {
164       *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
165       return false;
166    }
167 
168    assert(glVisual);
169    assert(driContextPriv);
170    assert(screen);
171 
172    /* Allocate the Radeon context */
173    rmesa = calloc(1, sizeof(*rmesa));
174    if ( !rmesa ) {
175       *error = __DRI_CTX_ERROR_NO_MEMORY;
176       return GL_FALSE;
177    }
178 
179    rmesa->radeon.radeonScreen = screen;
180    r100_init_vtbl(&rmesa->radeon);
181 
182    /* init exp fog table data */
183    radeonInitStaticFogData();
184 
185    /* Parse configuration files.
186     * Do this here so that initialMaxAnisotropy is set before we create
187     * the default textures.
188     */
189    driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
190 			screen->driScreen->myNum, "radeon");
191    rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
192                                                  "def_max_anisotropy");
193 
194    if (driQueryOptionb(&rmesa->radeon.optionCache, "hyperz"))
195       rmesa->using_hyperz = GL_TRUE;
196 
197    /* Init default driver functions then plug in our Radeon-specific functions
198     * (the texture functions are especially important)
199     */
200    _mesa_init_driver_functions( &functions );
201    radeonInitTextureFuncs( &rmesa->radeon, &functions );
202    radeonInitQueryObjFunctions(&functions);
203 
204    if (!radeonInitContext(&rmesa->radeon, api, &functions,
205 			  glVisual, driContextPriv,
206 			  sharedContextPrivate)) {
207      free(rmesa);
208      *error = __DRI_CTX_ERROR_NO_MEMORY;
209      return GL_FALSE;
210    }
211 
212    rmesa->radeon.swtcl.RenderIndex = ~0;
213    rmesa->radeon.hw.all_dirty = GL_TRUE;
214 
215    ctx = &rmesa->radeon.glCtx;
216 
217    driContextSetFlags(ctx, flags);
218 
219    /* Initialize the software rasterizer and helper modules.
220     */
221    _swrast_CreateContext( ctx );
222    _vbo_CreateContext( ctx );
223    _tnl_CreateContext( ctx );
224    _swsetup_CreateContext( ctx );
225    _ae_create_context( ctx );
226 
227    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
228 						 "texture_units");
229    ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
230    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
231    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
232 
233    ctx->Const.StripTextureBorder = GL_TRUE;
234 
235    /* FIXME: When no memory manager is available we should set this
236     * to some reasonable value based on texture memory pool size */
237    ctx->Const.MaxTextureLevels = 12;
238    ctx->Const.Max3DTextureLevels = 9;
239    ctx->Const.MaxCubeTextureLevels = 12;
240    ctx->Const.MaxTextureRectSize = 2048;
241 
242    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
243 
244    /* No wide points.
245     */
246    ctx->Const.MinPointSize = 1.0;
247    ctx->Const.MinPointSizeAA = 1.0;
248    ctx->Const.MaxPointSize = 1.0;
249    ctx->Const.MaxPointSizeAA = 1.0;
250 
251    ctx->Const.MinLineWidth = 1.0;
252    ctx->Const.MinLineWidthAA = 1.0;
253    ctx->Const.MaxLineWidth = 10.0;
254    ctx->Const.MaxLineWidthAA = 10.0;
255    ctx->Const.LineWidthGranularity = 0.0625;
256 
257    /* Set maxlocksize (and hence vb size) small enough to avoid
258     * fallbacks in radeon_tcl.c.  ie. guarentee that all vertices can
259     * fit in a single dma buffer for indexed rendering of quad strips,
260     * etc.
261     */
262    ctx->Const.MaxArrayLockSize =
263       MIN2( ctx->Const.MaxArrayLockSize,
264  	    RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE );
265 
266    rmesa->boxes = 0;
267 
268    ctx->Const.MaxDrawBuffers = 1;
269    ctx->Const.MaxColorAttachments = 1;
270    ctx->Const.MaxRenderbufferSize = 2048;
271 
272    ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
273 
274    /* Install the customized pipeline:
275     */
276    _tnl_destroy_pipeline( ctx );
277    _tnl_install_pipeline( ctx, radeon_pipeline );
278 
279    /* Try and keep materials and vertices separate:
280     */
281 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
282 
283    /* Configure swrast and T&L to match hardware characteristics:
284     */
285    _swrast_allow_pixel_fog( ctx, GL_FALSE );
286    _swrast_allow_vertex_fog( ctx, GL_TRUE );
287    _tnl_allow_pixel_fog( ctx, GL_FALSE );
288    _tnl_allow_vertex_fog( ctx, GL_TRUE );
289 
290 
291    for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
292       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
293       _math_matrix_ctr( &rmesa->tmpmat[i] );
294       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
295       _math_matrix_set_identity( &rmesa->tmpmat[i] );
296    }
297 
298    ctx->Extensions.ARB_occlusion_query = true;
299    ctx->Extensions.ARB_texture_border_clamp = true;
300    ctx->Extensions.ARB_texture_cube_map = true;
301    ctx->Extensions.ARB_texture_env_combine = true;
302    ctx->Extensions.ARB_texture_env_crossbar = true;
303    ctx->Extensions.ARB_texture_env_dot3 = true;
304    ctx->Extensions.ARB_texture_mirror_clamp_to_edge = true;
305    ctx->Extensions.ATI_texture_env_combine3 = true;
306    ctx->Extensions.ATI_texture_mirror_once = true;
307    ctx->Extensions.EXT_texture_env_dot3 = true;
308    ctx->Extensions.EXT_texture_filter_anisotropic = true;
309    ctx->Extensions.EXT_texture_mirror_clamp = true;
310    ctx->Extensions.MESA_ycbcr_texture = true;
311    ctx->Extensions.NV_texture_rectangle = true;
312    ctx->Extensions.OES_EGL_image = true;
313 
314    if (rmesa->radeon.glCtx.Mesa_DXTn) {
315       ctx->Extensions.EXT_texture_compression_s3tc = true;
316       ctx->Extensions.ANGLE_texture_compression_dxt = true;
317    }
318    else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
319       ctx->Extensions.EXT_texture_compression_s3tc = true;
320       ctx->Extensions.ANGLE_texture_compression_dxt = true;
321    }
322 
323    /* XXX these should really go right after _mesa_init_driver_functions() */
324    radeon_fbo_init(&rmesa->radeon);
325    radeonInitSpanFuncs( ctx );
326    radeonInitIoctlFuncs( ctx );
327    radeonInitStateFuncs( ctx );
328    radeonInitState( rmesa );
329    radeonInitSwtcl( ctx );
330 
331    _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0,
332 			 ctx->Const.MaxArrayLockSize, 32 );
333 
334    fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode");
335    rmesa->radeon.iw.irq_seq = -1;
336    rmesa->radeon.irqsEmitted = 0;
337    rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 &&
338 			    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
339 
340    rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
341 
342 
343 #if DO_DEBUG
344    RADEON_DEBUG = parse_debug_string( getenv( "RADEON_DEBUG" ),
345                                       debug_control );
346 #endif
347 
348    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
349    if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
350       fprintf(stderr, "disabling 3D acceleration\n");
351       FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
352    } else if (tcl_mode == DRI_CONF_TCL_SW ||
353 	      !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
354       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
355 	 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
356 	 fprintf(stderr, "Disabling HW TCL support\n");
357       }
358       TCL_FALLBACK(&rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
359    }
360 
361    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
362 /*       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
363    }
364 
365    _mesa_compute_version(ctx);
366 
367    /* Exec table initialization requires the version to be computed */
368    _mesa_initialize_dispatch_tables(ctx);
369    _mesa_initialize_vbo_vtxfmt(ctx);
370 
371    *error = __DRI_CTX_ERROR_SUCCESS;
372    return GL_TRUE;
373 }
374