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