5a5520b1f75971bfd9f6138fd85e4a187c9a1603
[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    /* Set the maximum texture size small enough that we can guarentee that
293     * all texture units can bind a maximal texture and have all of them in
294     * texturable memory at once. Depending on the allow_large_textures driconf
295     * setting allow larger textures.
296     */
297
298    ctx = rmesa->radeon.glCtx;
299    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
300                                                  "texture_units");
301    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
302    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
303
304    ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
305
306    ctx->Const.StripTextureBorder = GL_TRUE;
307
308    i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");
309
310    /* FIXME: When no memory manager is available we should set this 
311     * to some reasonable value based on texture memory pool size */
312    ctx->Const.MaxTextureLevels = 12;
313    ctx->Const.Max3DTextureLevels = 9;
314    ctx->Const.MaxCubeTextureLevels = 12;
315    ctx->Const.MaxTextureRectSize = 2048;
316    ctx->Const.MaxRenderbufferSize = 2048;
317
318    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
319
320    /* No wide AA points.
321     */
322    ctx->Const.MinPointSize = 1.0;
323    ctx->Const.MinPointSizeAA = 1.0;
324    ctx->Const.MaxPointSizeAA = 1.0;
325    ctx->Const.PointSizeGranularity = 0.0625;
326    ctx->Const.MaxPointSize = 2047.0;
327
328    /* mesa initialization problem - _mesa_init_point was already called */
329    ctx->Point.MaxSize = ctx->Const.MaxPointSize;
330
331    ctx->Const.MinLineWidth = 1.0;
332    ctx->Const.MinLineWidthAA = 1.0;
333    ctx->Const.MaxLineWidth = 10.0;
334    ctx->Const.MaxLineWidthAA = 10.0;
335    ctx->Const.LineWidthGranularity = 0.0625;
336
337    ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
338    ctx->Const.VertexProgram.MaxNativeAttribs = 12;
339    ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
340    ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
341    ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
342
343    ctx->Const.MaxDrawBuffers = 1;
344    ctx->Const.MaxColorAttachments = 1;
345
346    _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
347
348    /* Initialize the software rasterizer and helper modules.
349     */
350    _swrast_CreateContext( ctx );
351    _vbo_CreateContext( ctx );
352    _tnl_CreateContext( ctx );
353    _swsetup_CreateContext( ctx );
354    _ae_create_context( ctx );
355
356    /* Install the customized pipeline:
357     */
358    _tnl_destroy_pipeline( ctx );
359    _tnl_install_pipeline( ctx, r200_pipeline );
360
361    /* Try and keep materials and vertices separate:
362     */
363 /*    _tnl_isolate_materials( ctx, GL_TRUE ); */
364
365
366    /* Configure swrast and TNL to match hardware characteristics:
367     */
368    _swrast_allow_pixel_fog( ctx, GL_FALSE );
369    _swrast_allow_vertex_fog( ctx, GL_TRUE );
370    _tnl_allow_pixel_fog( ctx, GL_FALSE );
371    _tnl_allow_vertex_fog( ctx, GL_TRUE );
372
373
374    for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
375       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
376       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
377    }
378    _math_matrix_ctr( &rmesa->tmpmat );
379    _math_matrix_set_identity( &rmesa->tmpmat );
380
381    ctx->Extensions.ARB_half_float_pixel = true;
382    ctx->Extensions.ARB_occlusion_query = true;
383    ctx->Extensions.ARB_texture_border_clamp = true;
384    ctx->Extensions.ARB_texture_env_combine = true;
385    ctx->Extensions.ARB_texture_env_dot3 = true;
386    ctx->Extensions.ARB_texture_env_crossbar = true;
387    ctx->Extensions.EXT_blend_color = true;
388    ctx->Extensions.EXT_blend_minmax = true;
389    ctx->Extensions.EXT_fog_coord = true;
390    ctx->Extensions.EXT_packed_depth_stencil = true;
391    ctx->Extensions.EXT_secondary_color = true;
392    ctx->Extensions.EXT_texture_env_dot3 = true;
393    ctx->Extensions.EXT_texture_filter_anisotropic = true;
394    ctx->Extensions.EXT_texture_mirror_clamp = true;
395    ctx->Extensions.ATI_texture_env_combine3 = true;
396    ctx->Extensions.ATI_texture_mirror_once = true;
397    ctx->Extensions.MESA_pack_invert = true;
398    ctx->Extensions.NV_blend_square = true;
399    ctx->Extensions.NV_texture_rectangle = true;
400 #if FEATURE_OES_EGL_image
401    ctx->Extensions.OES_EGL_image = true;
402 #endif
403
404    ctx->Extensions.EXT_framebuffer_object = true;
405    ctx->Extensions.ARB_occlusion_query = true;
406
407    if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
408      /* yuv textures don't work with some chips - R200 / rv280 okay so far
409         others get the bit ordering right but don't actually do YUV-RGB conversion */
410       ctx->Extensions.MESA_ycbcr_texture = true;
411    }
412    if (rmesa->radeon.glCtx->Mesa_DXTn) {
413       ctx->Extensions.EXT_texture_compression_s3tc = true;
414       ctx->Extensions.S3_s3tc = true;
415    }
416    else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
417       ctx->Extensions.EXT_texture_compression_s3tc = true;
418    }
419
420    ctx->Extensions.ARB_texture_cube_map = true;
421
422    ctx->Extensions.EXT_blend_equation_separate = true;
423    ctx->Extensions.EXT_blend_func_separate = true;
424
425    ctx->Extensions.ARB_vertex_program = true;
426    ctx->Extensions.EXT_gpu_program_parameters = true;
427
428    ctx->Extensions.NV_vertex_program =
429       driQueryOptionb(&rmesa->radeon.optionCache, "nv_vertex_program");
430
431    ctx->Extensions.ATI_fragment_shader = (ctx->Const.MaxTextureUnits == 6);
432
433    ctx->Extensions.ARB_point_sprite = true;
434    ctx->Extensions.EXT_point_parameters = true;
435
436 #if 0
437    r200InitDriverFuncs( ctx );
438    r200InitIoctlFuncs( ctx );
439    r200InitStateFuncs( ctx );
440    r200InitTextureFuncs( ctx );
441 #endif
442    /* plug in a few more device driver functions */
443    /* XXX these should really go right after _mesa_init_driver_functions() */
444    radeon_fbo_init(&rmesa->radeon);
445    radeonInitSpanFuncs( ctx );
446    r200InitTnlFuncs( ctx );
447    r200InitState( rmesa );
448    r200InitSwtcl( ctx );
449
450    rmesa->prefer_gart_client_texturing = 
451       (getenv("R200_GART_CLIENT_TEXTURES") != 0);
452
453    tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
454    if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
455       fprintf(stderr, "disabling 3D acceleration\n");
456       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
457    }
458    else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
459             !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
460       if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
461          rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
462          fprintf(stderr, "Disabling HW TCL support\n");
463       }
464       TCL_FALLBACK(rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
465    }
466
467    _mesa_compute_version(ctx);
468
469    *error = __DRI_CTX_ERROR_SUCCESS;
470    return GL_TRUE;
471 }
472
473
474 void r200DestroyContext( __DRIcontext *driContextPriv )
475 {
476         int i;
477         r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
478         if (rmesa)
479         {
480                 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
481                         _math_matrix_dtr( &rmesa->TexGenMatrix[i] );
482                 }
483         }
484         radeonDestroyContext(driContextPriv);
485 }