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 #include "util/u_memory.h"
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(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,const struct __DriverContextConfig * ctx_config,unsigned * error,void * sharedContextPrivate)140 r100CreateContext( gl_api api,
141 		   const struct gl_config *glVisual,
142 		   __DRIcontext *driContextPriv,
143 		   const struct __DriverContextConfig *ctx_config,
144 		   unsigned *error,
145 		   void *sharedContextPrivate)
146 {
147    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
148    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
149    struct dd_function_table functions;
150    r100ContextPtr rmesa;
151    struct gl_context *ctx;
152    int i;
153    int tcl_mode, fthrottle_mode;
154 
155    if (ctx_config->flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_NO_ERROR)) {
156       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
157       return false;
158    }
159 
160    if (ctx_config->attribute_mask) {
161       *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
162       return false;
163    }
164 
165    assert(driContextPriv);
166    assert(screen);
167 
168    /* Allocate the Radeon context */
169    rmesa = align_calloc(sizeof(*rmesa), 16);
170    if ( !rmesa ) {
171       *error = __DRI_CTX_ERROR_NO_MEMORY;
172       return GL_FALSE;
173    }
174 
175    rmesa->radeon.radeonScreen = screen;
176    r100_init_vtbl(&rmesa->radeon);
177 
178    /* init exp fog table data */
179    radeonInitStaticFogData();
180 
181    /* Parse configuration files.
182     * Do this here so that initialMaxAnisotropy is set before we create
183     * the default textures.
184     */
185    driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
186 			screen->driScreen->myNum, "radeon", NULL, NULL, NULL, 0, NULL, 0);
187    rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
188                                                  "def_max_anisotropy");
189 
190    if (driQueryOptionb(&rmesa->radeon.optionCache, "hyperz"))
191       rmesa->using_hyperz = GL_TRUE;
192 
193    /* Init default driver functions then plug in our Radeon-specific functions
194     * (the texture functions are especially important)
195     */
196    _mesa_init_driver_functions( &functions );
197    _tnl_init_driver_draw_function( &functions );
198    radeonInitTextureFuncs( &rmesa->radeon, &functions );
199    radeonInitQueryObjFunctions(&functions);
200 
201    if (!radeonInitContext(&rmesa->radeon, api, &functions,
202 			  glVisual, driContextPriv,
203 			  sharedContextPrivate)) {
204      align_free(rmesa);
205      *error = __DRI_CTX_ERROR_NO_MEMORY;
206      return GL_FALSE;
207    }
208 
209    rmesa->radeon.swtcl.RenderIndex = ~0;
210    rmesa->radeon.hw.all_dirty = GL_TRUE;
211 
212    ctx = &rmesa->radeon.glCtx;
213 
214    driContextSetFlags(ctx, ctx_config->flags);
215 
216    /* Initialize the software rasterizer and helper modules.
217     */
218    _swrast_CreateContext( ctx );
219    _vbo_CreateContext( ctx, false );
220    _tnl_CreateContext( ctx );
221    _swsetup_CreateContext( ctx );
222 
223    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
224 						 "texture_units");
225    ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
226    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
227    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
228 
229    ctx->Const.StripTextureBorder = GL_TRUE;
230 
231    /* FIXME: When no memory manager is available we should set this
232     * to some reasonable value based on texture memory pool size */
233    ctx->Const.MaxTextureSize = 2048;
234    ctx->Const.Max3DTextureLevels = 9;
235    ctx->Const.MaxCubeTextureLevels = 12;
236    ctx->Const.MaxTextureRectSize = 2048;
237 
238    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
239 
240    /* No wide points.
241     */
242    ctx->Const.MinPointSize = 1.0;
243    ctx->Const.MinPointSizeAA = 1.0;
244    ctx->Const.MaxPointSize = 1.0;
245    ctx->Const.MaxPointSizeAA = 1.0;
246 
247    ctx->Const.MinLineWidth = 1.0;
248    ctx->Const.MinLineWidthAA = 1.0;
249    ctx->Const.MaxLineWidth = 10.0;
250    ctx->Const.MaxLineWidthAA = 10.0;
251    ctx->Const.LineWidthGranularity = 0.0625;
252 
253    /* Set maxlocksize (and hence vb size) small enough to avoid
254     * fallbacks in radeon_tcl.c.  ie. guarentee that all vertices can
255     * fit in a single dma buffer for indexed rendering of quad strips,
256     * etc.
257     */
258    ctx->Const.MaxArrayLockSize =
259       MIN2( ctx->Const.MaxArrayLockSize,
260  	    RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE );
261 
262    rmesa->boxes = 0;
263 
264    ctx->Const.MaxDrawBuffers = 1;
265    ctx->Const.MaxColorAttachments = 1;
266    ctx->Const.MaxRenderbufferSize = 2048;
267 
268    ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
269 
270    /* Install the customized pipeline:
271     */
272    _tnl_destroy_pipeline( ctx );
273    _tnl_install_pipeline( ctx, radeon_pipeline );
274 
275    /* Try and keep materials and vertices separate:
276     */
277 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
278 
279    /* Configure swrast and T&L to match hardware characteristics:
280     */
281    _swrast_allow_pixel_fog( ctx, GL_FALSE );
282    _swrast_allow_vertex_fog( ctx, GL_TRUE );
283    _tnl_allow_pixel_fog( ctx, GL_FALSE );
284    _tnl_allow_vertex_fog( ctx, GL_TRUE );
285 
286 
287    for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
288       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
289       _math_matrix_ctr( &rmesa->tmpmat[i] );
290       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
291       _math_matrix_set_identity( &rmesa->tmpmat[i] );
292    }
293 
294    ctx->Extensions.ARB_occlusion_query = true;
295    ctx->Extensions.ARB_texture_border_clamp = true;
296    ctx->Extensions.ARB_texture_cube_map = true;
297    ctx->Extensions.ARB_texture_env_combine = true;
298    ctx->Extensions.ARB_texture_env_crossbar = true;
299    ctx->Extensions.ARB_texture_env_dot3 = true;
300    ctx->Extensions.ARB_texture_filter_anisotropic = true;
301    ctx->Extensions.ARB_texture_mirror_clamp_to_edge = true;
302    ctx->Extensions.ATI_texture_env_combine3 = true;
303    ctx->Extensions.ATI_texture_mirror_once = true;
304    ctx->Extensions.EXT_texture_env_dot3 = true;
305    ctx->Extensions.EXT_texture_filter_anisotropic = true;
306    ctx->Extensions.EXT_texture_mirror_clamp = true;
307    ctx->Extensions.MESA_ycbcr_texture = true;
308    ctx->Extensions.NV_texture_rectangle = true;
309    ctx->Extensions.OES_EGL_image = true;
310 
311    ctx->Extensions.EXT_texture_compression_s3tc = true;
312    ctx->Extensions.ANGLE_texture_compression_dxt = true;
313 
314    /* XXX these should really go right after _mesa_init_driver_functions() */
315    radeon_fbo_init(&rmesa->radeon);
316    radeonInitSpanFuncs( ctx );
317    radeonInitIoctlFuncs( ctx );
318    radeonInitStateFuncs( ctx );
319    radeonInitState( rmesa );
320    radeonInitSwtcl( ctx );
321 
322    _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0,
323 			 ctx->Const.MaxArrayLockSize, 32 );
324 
325    fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode");
326    rmesa->radeon.iw.irq_seq = -1;
327    rmesa->radeon.irqsEmitted = 0;
328    rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 &&
329 			    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
330 
331    rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
332 
333    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
334    if (getenv("RADEON_NO_RAST")) {
335       fprintf(stderr, "disabling 3D acceleration\n");
336       FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
337    } else if (tcl_mode == DRI_CONF_TCL_SW ||
338 	      !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
339       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
340 	 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
341 	 fprintf(stderr, "Disabling HW TCL support\n");
342       }
343       TCL_FALLBACK(&rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
344    }
345 
346    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
347 /*       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
348    }
349 
350    _mesa_override_extensions(ctx);
351    _mesa_compute_version(ctx);
352 
353    /* Exec table initialization requires the version to be computed */
354    _mesa_initialize_dispatch_tables(ctx);
355    _mesa_initialize_vbo_vtxfmt(ctx);
356 
357    *error = __DRI_CTX_ERROR_SUCCESS;
358    return GL_TRUE;
359 }
360