r200: Initialize swrast before setting limits
[profile/ivi/mesa.git] / src / mesa / drivers / dri / r200 / r200_context.c
1 /*
2 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
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.
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  *   Keith Whitwell <keith@tungstengraphics.com>
33  */
34
35 #include <stdbool.h>
36 #include "main/glheader.h"
37 #include "main/api_arrayelt.h"
38 #include "main/context.h"
39 #include "main/simple_list.h"
40 #include "main/imports.h"
41 #include "main/extensions.h"
42 #include "main/mfeatures.h"
43 #include "main/version.h"
44
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "vbo/vbo.h"
48
49 #include "tnl/tnl.h"
50 #include "tnl/t_pipeline.h"
51
52 #include "drivers/common/driverfuncs.h"
53
54 #include "r200_context.h"
55 #include "r200_ioctl.h"
56 #include "r200_state.h"
57 #include "r200_tex.h"
58 #include "r200_swtcl.h"
59 #include "r200_tcl.h"
60 #include "r200_vertprog.h"
61 #include "radeon_queryobj.h"
62 #include "r200_blit.h"
63 #include "radeon_fog.h"
64
65 #include "radeon_span.h"
66
67 #include "utils.h"
68 #include "xmlpool.h" /* for symbolic values of enum-type options */
69
70 /* Return various strings for glGetString().
71  */
72 static const GLubyte *r200GetString( struct gl_context *ctx, GLenum name )
73 {
74    r200ContextPtr rmesa = R200_CONTEXT(ctx);
75    static char buffer[128];
76    unsigned   offset;
77    GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 :
78       rmesa->radeon.radeonScreen->AGPMode;
79
80    switch ( name ) {
81    case GL_VENDOR:
82       return (GLubyte *)"Tungsten Graphics, Inc.";
83
84    case GL_RENDERER:
85       offset = driGetRendererString( buffer, "R200", agp_mode );
86
87       sprintf( & buffer[ offset ], " %sTCL",
88                !(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
89                ? "" : "NO-" );
90
91       return (GLubyte *)buffer;
92
93    default:
94       return NULL;
95    }
96 }
97
98
99 extern const struct tnl_pipeline_stage _r200_render_stage;
100 extern const struct tnl_pipeline_stage _r200_tcl_stage;
101
102 static const struct tnl_pipeline_stage *r200_pipeline[] = {
103
104    /* Try and go straight to t&l
105     */
106    &_r200_tcl_stage,  
107
108    /* Catch any t&l fallbacks
109     */
110    &_tnl_vertex_transform_stage,
111    &_tnl_normal_transform_stage,
112    &_tnl_lighting_stage,
113    &_tnl_fog_coordinate_stage,
114    &_tnl_texgen_stage,
115    &_tnl_texture_transform_stage,
116    &_tnl_point_attenuation_stage,
117    &_tnl_vertex_program_stage,
118    /* Try again to go to tcl? 
119     *     - no good for asymmetric-twoside (do with multipass)
120     *     - no good for asymmetric-unfilled (do with multipass)
121     *     - good for material
122     *     - good for texgen
123     *     - need to manipulate a bit of state
124     *
125     * - worth it/not worth it?
126     */
127                         
128    /* Else do them here.
129     */
130 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
131    &_tnl_render_stage,          /* FALLBACK:  */
132    NULL,
133 };
134
135
136
137 /* Initialize the driver's misc functions.
138  */
139 static void r200InitDriverFuncs( struct dd_function_table *functions )
140 {
141     functions->GetBufferSize            = NULL; /* OBSOLETE */
142     functions->GetString                = r200GetString;
143 }
144
145
146 static void r200_get_lock(radeonContextPtr radeon)
147 {
148    r200ContextPtr rmesa = (r200ContextPtr)radeon;
149    drm_radeon_sarea_t *sarea = radeon->sarea;
150
151    R200_STATECHANGE( rmesa, ctx );
152    if (rmesa->radeon.sarea->tiling_enabled) {
153       rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
154    }
155    else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE;
156
157    if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) {
158       sarea->ctx_owner = rmesa->radeon.dri.hwContext;
159    }
160
161 }
162
163 static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
164 {
165 }
166
167 static void r200_emit_query_finish(radeonContextPtr radeon)
168 {
169    BATCH_LOCALS(radeon);
170    struct radeon_query_object *query = radeon->query.current;
171
172    BEGIN_BATCH_NO_AUTOSTATE(4);
173    OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
174    OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
175    END_BATCH();
176    query->curr_offset += sizeof(uint32_t);
177    assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
178    query->emitted_begin = GL_FALSE;
179 }
180
181 static void r200_init_vtbl(radeonContextPtr radeon)
182 {
183    radeon->vtbl.get_lock = r200_get_lock;
184    radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset;
185    radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
186    radeon->vtbl.swtcl_flush = r200_swtcl_flush;
187    radeon->vtbl.fallback = r200Fallback;
188    radeon->vtbl.update_scissor = r200_vtbl_update_scissor;
189    radeon->vtbl.emit_query_finish = r200_emit_query_finish;
190    radeon->vtbl.check_blit = r200_check_blit;
191    radeon->vtbl.blit = r200_blit;
192    radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
193 }
194
195
196 /* Create the device specific rendering context.
197  */
198 GLboolean r200CreateContext( gl_api api,
199                              const struct gl_config *glVisual,
200                              __DRIcontext *driContextPriv,
201                              unsigned major_version,
202                              unsigned minor_version,
203                              uint32_t flags,
204                              unsigned *error,
205                              void *sharedContextPrivate)
206 {
207    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
208    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
209    struct dd_function_table functions;
210    r200ContextPtr rmesa;
211    struct gl_context *ctx;
212    int i;
213    int tcl_mode;
214
215    switch (api) {
216    case API_OPENGL:
217       if (major_version > 1 || minor_version > 3) {
218          *error = __DRI_CTX_ERROR_BAD_VERSION;
219          return GL_FALSE;
220       }
221       break;
222    case API_OPENGLES:
223       break;
224    default:
225       *error = __DRI_CTX_ERROR_BAD_API;
226       return GL_FALSE;
227    }
228
229    /* Flag filtering is handled in dri2CreateContextAttribs.
230     */
231    (void) flags;
232
233    assert(glVisual);
234    assert(driContextPriv);
235    assert(screen);
236
237    /* Allocate the R200 context */
238    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
239    if ( !rmesa ) {
240       *error = __DRI_CTX_ERROR_NO_MEMORY;
241       return GL_FALSE;
242    }
243
244    rmesa->radeon.radeonScreen = screen;
245    r200_init_vtbl(&rmesa->radeon);
246    /* init exp fog table data */
247    radeonInitStaticFogData();
248
249    /* Parse configuration files.
250     * Do this here so that initialMaxAnisotropy is set before we create
251     * the default textures.
252     */
253    driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
254                         screen->driScreen->myNum, "r200");
255    rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
256                                                         "def_max_anisotropy");
257
258    if ( sPriv->drm_version.major == 1
259        && driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
260       if ( sPriv->drm_version.minor < 13 )
261          fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
262                           "disabling.\n", sPriv->drm_version.minor );
263       else
264          rmesa->using_hyperz = GL_TRUE;
265    }
266  
267    if ( sPriv->drm_version.minor >= 15 )
268       rmesa->texmicrotile = GL_TRUE;
269
270    /* Init default driver functions then plug in our R200-specific functions
271     * (the texture functions are especially important)
272     */
273    _mesa_init_driver_functions(&functions);
274    r200InitDriverFuncs(&functions);
275    r200InitIoctlFuncs(&functions);
276    r200InitStateFuncs(&rmesa->radeon, &functions);
277    r200InitTextureFuncs(&rmesa->radeon, &functions);
278    r200InitShaderFuncs(&functions);
279    radeonInitQueryObjFunctions(&functions);
280
281    if (!radeonInitContext(&rmesa->radeon, &functions,
282                           glVisual, driContextPriv,
283                           sharedContextPrivate)) {
284      FREE(rmesa);
285      *error = __DRI_CTX_ERROR_NO_MEMORY;
286      return GL_FALSE;
287    }
288
289    rmesa->radeon.swtcl.RenderIndex = ~0;
290    rmesa->radeon.hw.all_dirty = 1;
291
292    ctx = rmesa->radeon.glCtx;
293    /* Initialize the software rasterizer and helper modules.
294     */
295    _swrast_CreateContext( ctx );
296    _vbo_CreateContext( ctx );
297    _tnl_CreateContext( ctx );
298    _swsetup_CreateContext( ctx );
299    _ae_create_context( ctx );
300
301    /* Set the maximum texture size small enough that we can guarentee that
302     * all texture units can bind a maximal texture and have all of them in
303     * texturable memory at once. Depending on the allow_large_textures driconf
304     * setting allow larger textures.
305     */
306    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
307                                                  "texture_units");
308    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
309    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
310
311    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
312
313    ctx->Const.StripTextureBorder = GL_TRUE;
314
315    i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");
316
317    /* FIXME: When no memory manager is available we should set this 
318     * to some reasonable value based on texture memory pool size */
319    ctx->Const.MaxTextureLevels = 12;
320    ctx->Const.Max3DTextureLevels = 9;
321    ctx->Const.MaxCubeTextureLevels = 12;
322    ctx->Const.MaxTextureRectSize = 2048;
323    ctx->Const.MaxRenderbufferSize = 2048;
324
325    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
326
327    /* No wide AA points.
328     */
329    ctx->Const.MinPointSize = 1.0;
330    ctx->Const.MinPointSizeAA = 1.0;
331    ctx->Const.MaxPointSizeAA = 1.0;
332    ctx->Const.PointSizeGranularity = 0.0625;
333    ctx->Const.MaxPointSize = 2047.0;
334
335    /* mesa initialization problem - _mesa_init_point was already called */
336    ctx->Point.MaxSize = ctx->Const.MaxPointSize;
337
338    ctx->Const.MinLineWidth = 1.0;
339    ctx->Const.MinLineWidthAA = 1.0;
340    ctx->Const.MaxLineWidth = 10.0;
341    ctx->Const.MaxLineWidthAA = 10.0;
342    ctx->Const.LineWidthGranularity = 0.0625;
343
344    ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
345    ctx->Const.VertexProgram.MaxNativeAttribs = 12;
346    ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
347    ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
348    ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
349
350    ctx->Const.MaxDrawBuffers = 1;
351    ctx->Const.MaxColorAttachments = 1;
352
353    _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
354
355    /* Install the customized pipeline:
356     */
357    _tnl_destroy_pipeline( ctx );
358    _tnl_install_pipeline( ctx, r200_pipeline );
359
360    /* Try and keep materials and vertices separate:
361     */
362 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
363
364
365    /* Configure swrast and TNL to match hardware characteristics:
366     */
367    _swrast_allow_pixel_fog( ctx, GL_FALSE );
368    _swrast_allow_vertex_fog( ctx, GL_TRUE );
369    _tnl_allow_pixel_fog( ctx, GL_FALSE );
370    _tnl_allow_vertex_fog( ctx, GL_TRUE );
371
372
373    for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
374       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
375       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
376    }
377    _math_matrix_ctr( &rmesa->tmpmat );
378    _math_matrix_set_identity( &rmesa->tmpmat );
379
380    ctx->Extensions.ARB_half_float_pixel = true;
381    ctx->Extensions.ARB_occlusion_query = true;
382    ctx->Extensions.ARB_texture_border_clamp = true;
383    ctx->Extensions.ARB_texture_env_combine = true;
384    ctx->Extensions.ARB_texture_env_dot3 = true;
385    ctx->Extensions.ARB_texture_env_crossbar = true;
386    ctx->Extensions.EXT_blend_color = true;
387    ctx->Extensions.EXT_blend_minmax = true;
388    ctx->Extensions.EXT_fog_coord = true;
389    ctx->Extensions.EXT_packed_depth_stencil = true;
390    ctx->Extensions.EXT_secondary_color = true;
391    ctx->Extensions.EXT_texture_env_dot3 = true;
392    ctx->Extensions.EXT_texture_filter_anisotropic = true;
393    ctx->Extensions.EXT_texture_mirror_clamp = true;
394    ctx->Extensions.ATI_texture_env_combine3 = true;
395    ctx->Extensions.ATI_texture_mirror_once = true;
396    ctx->Extensions.MESA_pack_invert = true;
397    ctx->Extensions.NV_blend_square = true;
398    ctx->Extensions.NV_texture_rectangle = true;
399 #if FEATURE_OES_EGL_image
400    ctx->Extensions.OES_EGL_image = true;
401 #endif
402
403    ctx->Extensions.EXT_framebuffer_object = true;
404    ctx->Extensions.ARB_occlusion_query = true;
405
406    if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
407      /* yuv textures don't work with some chips - R200 / rv280 okay so far
408         others get the bit ordering right but don't actually do YUV-RGB conversion */
409       ctx->Extensions.MESA_ycbcr_texture = true;
410    }
411    if (rmesa->radeon.glCtx->Mesa_DXTn) {
412       ctx->Extensions.EXT_texture_compression_s3tc = true;
413       ctx->Extensions.S3_s3tc = true;
414    }
415    else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
416       ctx->Extensions.EXT_texture_compression_s3tc = true;
417    }
418
419    ctx->Extensions.ARB_texture_cube_map = true;
420
421    ctx->Extensions.EXT_blend_equation_separate = true;
422    ctx->Extensions.EXT_blend_func_separate = true;
423
424    ctx->Extensions.ARB_vertex_program = true;
425    ctx->Extensions.EXT_gpu_program_parameters = true;
426
427    ctx->Extensions.NV_vertex_program =
428       driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program");
429
430    ctx->Extensions.ATI_fragment_shader = (ctx->Const.MaxTextureUnits == 6);
431
432    ctx->Extensions.ARB_point_sprite = true;
433    ctx->Extensions.EXT_point_parameters = true;
434
435 #if 0
436    r200InitDriverFuncs( ctx );
437    r200InitIoctlFuncs( ctx );
438    r200InitStateFuncs( ctx );
439    r200InitTextureFuncs( ctx );
440 #endif
441    /* plug in a few more device driver functions */
442    /* XXX these should really go right after _mesa_init_driver_functions() */
443    radeon_fbo_init(&rmesa->radeon);
444    radeonInitSpanFuncs( ctx );
445    r200InitTnlFuncs( ctx );
446    r200InitState( rmesa );
447    r200InitSwtcl( ctx );
448
449    rmesa->prefer_gart_client_texturing = 
450       (getenv("R200_GART_CLIENT_TEXTURES") != 0);
451
452    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
453    if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
454       fprintf(stderr, "disabling 3D acceleration\n");
455       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
456    }
457    else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
458             !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
459       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
460          rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
461          fprintf(stderr, "Disabling HW TCL support\n");
462       }
463       TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
464    }
465
466    _mesa_compute_version(ctx);
467
468    *error = __DRI_CTX_ERROR_SUCCESS;
469    return GL_TRUE;
470 }
471
472
473 void r200DestroyContext( __DRIcontext *driContextPriv )
474 {
475         int i;
476         r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
477         if (rmesa)
478         {
479                 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
480                         _math_matrix_dtr( &rmesa->TexGenMatrix[i] );
481                 }
482         }
483         radeonDestroyContext(driContextPriv);
484 }