OSDN Git Service

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