OSDN Git Service

95e54a6af500f1e2faf3f3fcfbfb40fa072d7b66
[android-x86/external-mesa.git] / src / mesa / drivers / dri / r128 / r128_context.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.8 2002/10/30 12:51:38 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5                                                Cedar Park, Texas.
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30  * Authors:
31  *   Kevin E. Martin <martin@valinux.com>
32  *   Gareth Hughes <gareth@valinux.com>
33  *
34  */
35
36 #include "glheader.h"
37 #include "context.h"
38 #include "simple_list.h"
39 #include "imports.h"
40 #include "matrix.h"
41 #include "extensions.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 "r128_context.h"
53 #include "r128_ioctl.h"
54 #include "r128_dd.h"
55 #include "r128_state.h"
56 #include "r128_span.h"
57 #include "r128_tex.h"
58 #include "r128_tris.h"
59
60 #include "vblank.h"
61 #include "utils.h"
62 #include "texmem.h"
63 #include "xmlpool.h" /* for symbolic values of enum-type options */
64
65 #ifndef R128_DEBUG
66 int R128_DEBUG = 0;
67 #endif
68
69 #define need_GL_ARB_multisample
70 #define need_GL_ARB_texture_compression
71 #define need_GL_ARB_vertex_buffer_object
72 #define need_GL_EXT_blend_minmax
73 #define need_GL_EXT_fog_coord
74 #define need_GL_EXT_secondary_color
75 #include "extension_helper.h"
76
77 const struct dri_extension card_extensions[] =
78 {
79     { "GL_ARB_multisample",                GL_ARB_multisample_functions },
80     { "GL_ARB_multitexture",               NULL },
81     { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
82     { "GL_ARB_texture_env_add",            NULL },
83     { "GL_ARB_texture_mirrored_repeat",    NULL },
84     { "GL_ARB_vertex_buffer_object",       GL_ARB_vertex_buffer_object_functions },
85     { "GL_EXT_blend_subtract",             GL_EXT_blend_minmax_functions },
86     { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
87     { "GL_EXT_texture_edge_clamp",         NULL },
88     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
89     { "GL_EXT_stencil_wrap",               NULL },
90     { "GL_MESA_ycbcr_texture",             NULL },
91     { "GL_NV_blend_square",                NULL },
92     { "GL_SGIS_generate_mipmap",           NULL },
93     { NULL,                                NULL }
94 };
95
96 static const struct dri_debug_control debug_control[] =
97 {
98     { "ioctl", DEBUG_VERBOSE_IOCTL },
99     { "verb",  DEBUG_VERBOSE_MSG },
100     { "dri",   DEBUG_VERBOSE_DRI },
101     { "2d",    DEBUG_VERBOSE_2D },
102     { "sync",  DEBUG_ALWAYS_SYNC },
103     { "api",   DEBUG_VERBOSE_API },
104     { "fall",  DEBUG_VERBOSE_FALL },
105     { NULL,    0 }
106 };
107
108 /* Create the device specific context.
109  */
110 GLboolean r128CreateContext( const __GLcontextModes *glVisual,
111                              __DRIcontextPrivate *driContextPriv,
112                              void *sharedContextPrivate )
113 {
114    GLcontext *ctx, *shareCtx;
115    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
116    struct dd_function_table functions;
117    r128ContextPtr rmesa;
118    r128ScreenPtr r128scrn;
119    int i;
120
121    /* Allocate the r128 context */
122    rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) );
123    if ( !rmesa )
124       return GL_FALSE;
125
126    /* Init default driver functions then plug in our Radeon-specific functions
127     * (the texture functions are especially important)
128     */
129    _mesa_init_driver_functions( &functions );
130    r128InitDriverFuncs( &functions );
131    r128InitIoctlFuncs( &functions );
132    r128InitTextureFuncs( &functions );
133
134    /* Allocate the Mesa context */
135    if (sharedContextPrivate)
136       shareCtx = ((r128ContextPtr) sharedContextPrivate)->glCtx;
137    else 
138       shareCtx = NULL;
139    rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
140                                        &functions, (void *) rmesa);
141    if (!rmesa->glCtx) {
142       FREE(rmesa);
143       return GL_FALSE;
144    }
145    driContextPriv->driverPrivate = rmesa;
146    ctx = rmesa->glCtx;
147
148    rmesa->driContext = driContextPriv;
149    rmesa->driScreen = sPriv;
150    rmesa->driDrawable = NULL;
151    rmesa->hHWContext = driContextPriv->hHWContext;
152    rmesa->driHwLock = &sPriv->pSAREA->lock;
153    rmesa->driFd = sPriv->fd;
154
155    r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private);
156
157    /* Parse configuration files */
158    driParseConfigFiles (&rmesa->optionCache, &r128scrn->optionCache,
159                         r128scrn->driScreen->myNum, "r128");
160
161    rmesa->sarea = (drm_r128_sarea_t *)((char *)sPriv->pSAREA +
162                                      r128scrn->sarea_priv_offset);
163
164    rmesa->CurrentTexObj[0] = NULL;
165    rmesa->CurrentTexObj[1] = NULL;
166
167    (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
168    make_empty_list( & rmesa->swapped );
169
170    rmesa->nr_heaps = r128scrn->numTexHeaps;
171    for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
172       rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
173             r128scrn->texSize[i],
174             12,
175             R128_NR_TEX_REGIONS,
176             (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
177             &rmesa->sarea->tex_age[i],
178             &rmesa->swapped,
179             sizeof( r128TexObj ),
180             (destroy_texture_object_t *) r128DestroyTexObj );
181
182       driSetTextureSwapCounterLocation( rmesa->texture_heaps[i],
183                                         & rmesa->c_textureSwaps );
184    }
185    rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
186                                            "texture_depth");
187    if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
188       rmesa->texture_depth = ( r128scrn->cpp == 4 ) ?
189          DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
190
191
192    rmesa->RenderIndex = -1;             /* Impossible value */
193    rmesa->vert_buf = NULL;
194    rmesa->num_verts = 0;
195    RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
196
197    /* Set the maximum texture size small enough that we can guarentee that
198     * all texture units can bind a maximal texture and have them both in
199     * texturable memory at once.
200     */
201
202    ctx->Const.MaxTextureUnits = 2;
203    ctx->Const.MaxTextureImageUnits = 2;
204    ctx->Const.MaxTextureCoordUnits = 2;
205
206    driCalculateMaxTextureLevels( rmesa->texture_heaps,
207                                  rmesa->nr_heaps,
208                                  & ctx->Const,
209                                  4,
210                                  10, /* max 2D texture size is 1024x1024 */
211                                  0,  /* 3D textures unsupported. */
212                                  0,  /* cube textures unsupported. */
213                                  0,  /* texture rectangles unsupported. */
214                                  11,
215                                  GL_FALSE,
216                                  0 );
217
218    /* No wide points.
219     */
220    ctx->Const.MinPointSize = 1.0;
221    ctx->Const.MinPointSizeAA = 1.0;
222    ctx->Const.MaxPointSize = 1.0;
223    ctx->Const.MaxPointSizeAA = 1.0;
224
225    /* No wide lines.
226     */
227    ctx->Const.MinLineWidth = 1.0;
228    ctx->Const.MinLineWidthAA = 1.0;
229    ctx->Const.MaxLineWidth = 1.0;
230    ctx->Const.MaxLineWidthAA = 1.0;
231    ctx->Const.LineWidthGranularity = 1.0;
232
233 #if ENABLE_PERF_BOXES
234    rmesa->boxes = driQueryOptionb(&rmesa->optionCache, "performance_boxes");
235 #endif
236
237    /* Initialize the software rasterizer and helper modules.
238     */
239    _swrast_CreateContext( ctx );
240    _vbo_CreateContext( ctx );
241    _tnl_CreateContext( ctx );
242    _swsetup_CreateContext( ctx );
243
244    /* Install the customized pipeline:
245     */
246 /*     _tnl_destroy_pipeline( ctx ); */
247 /*     _tnl_install_pipeline( ctx, r128_pipeline ); */
248
249    /* Configure swrast and T&L to match hardware characteristics:
250     */
251    _swrast_allow_pixel_fog( ctx, GL_FALSE );
252    _swrast_allow_vertex_fog( ctx, GL_TRUE );
253    _tnl_allow_pixel_fog( ctx, GL_FALSE );
254    _tnl_allow_vertex_fog( ctx, GL_TRUE );
255
256    driInitExtensions( ctx, card_extensions, GL_TRUE );
257    if (sPriv->drmMinor >= 4)
258       _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
259
260    r128InitTriFuncs( ctx );
261    r128DDInitStateFuncs( ctx );
262    r128DDInitSpanFuncs( ctx );
263    r128DDInitState( rmesa );
264
265    rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
266        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
267
268    driContextPriv->driverPrivate = (void *)rmesa;
269
270 #if DO_DEBUG
271    R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ),
272                                      debug_control );
273 #endif
274
275    if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
276       fprintf(stderr, "disabling 3D acceleration\n");
277       FALLBACK(rmesa, R128_FALLBACK_DISABLE, 1);
278    }
279
280    return GL_TRUE;
281 }
282
283 /* Destroy the device specific context.
284  */
285 void r128DestroyContext( __DRIcontextPrivate *driContextPriv  )
286 {
287    r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate;
288
289    assert(rmesa);  /* should never be null */
290    if ( rmesa ) {
291       GLboolean   release_texture_heaps;
292
293
294       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
295
296       _swsetup_DestroyContext( rmesa->glCtx );
297       _tnl_DestroyContext( rmesa->glCtx );
298       _vbo_DestroyContext( rmesa->glCtx );
299       _swrast_DestroyContext( rmesa->glCtx );
300
301       if ( release_texture_heaps ) {
302          /* This share group is about to go away, free our private
303           * texture object data.
304           */
305          int i;
306
307          for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
308             driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
309             rmesa->texture_heaps[ i ] = NULL;
310          }
311
312          assert( is_empty_list( & rmesa->swapped ) );
313       }
314
315       /* free the Mesa context */
316       rmesa->glCtx->DriverCtx = NULL;
317       _mesa_destroy_context(rmesa->glCtx);
318
319       /* free the option cache */
320       driDestroyOptionCache (&rmesa->optionCache);
321
322       FREE( rmesa );
323    }
324
325 #if 0
326    /* Use this to force shared object profiling. */
327    glx_fini_prof();
328 #endif
329 }
330
331
332 /* Force the context `c' to be the current context and associate with it
333  * buffer `b'.
334  */
335 GLboolean
336 r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
337                  __DRIdrawablePrivate *driDrawPriv,
338                  __DRIdrawablePrivate *driReadPriv )
339 {
340    if ( driContextPriv ) {
341       GET_CURRENT_CONTEXT(ctx);
342       r128ContextPtr oldR128Ctx = ctx ? R128_CONTEXT(ctx) : NULL;
343       r128ContextPtr newR128Ctx = (r128ContextPtr) driContextPriv->driverPrivate;
344
345       if ( newR128Ctx != oldR128Ctx ) {
346          newR128Ctx->new_state |= R128_NEW_CONTEXT;
347          newR128Ctx->dirty = R128_UPLOAD_ALL;
348       }
349
350       driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
351                              &newR128Ctx->vbl_seq );
352       newR128Ctx->driDrawable = driDrawPriv;
353
354       _mesa_make_current( newR128Ctx->glCtx,
355                           (GLframebuffer *) driDrawPriv->driverPrivate,
356                           (GLframebuffer *) driReadPriv->driverPrivate );
357
358       newR128Ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP;
359    } else {
360       _mesa_make_current( NULL, NULL, NULL );
361    }
362
363    return GL_TRUE;
364 }
365
366
367 /* Force the context `c' to be unbound from its buffer.
368  */
369 GLboolean
370 r128UnbindContext( __DRIcontextPrivate *driContextPriv )
371 {
372    return GL_TRUE;
373 }