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