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