OSDN Git Service

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