Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / mach64 / mach64_context.c
1 /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3  * Copyright 2000 Gareth Hughes
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /*
26  * Authors:
27  *      Gareth Hughes <gareth@valinux.com>
28  *      Leif Delgass <ldelgass@retinalburn.net>
29  *      Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30  */
31
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/simple_list.h"
35 #include "main/imports.h"
36
37 #include "swrast/swrast.h"
38 #include "swrast_setup/swrast_setup.h"
39 #include "vbo/vbo.h"
40
41 #include "tnl/tnl.h"
42 #include "tnl/t_pipeline.h"
43
44 #include "drivers/common/driverfuncs.h"
45
46 #include "mach64_context.h"
47 #include "mach64_ioctl.h"
48 #include "mach64_dd.h"
49 #include "mach64_span.h"
50 #include "mach64_state.h"
51 #include "mach64_tex.h"
52 #include "mach64_tris.h"
53 #include "mach64_vb.h"
54
55 #include "utils.h"
56 #include "vblank.h"
57
58 #ifndef MACH64_DEBUG
59 int MACH64_DEBUG = (0);
60 #endif
61
62 static const struct dri_debug_control debug_control[] =
63 {
64     { "sync",   DEBUG_ALWAYS_SYNC },
65     { "api",    DEBUG_VERBOSE_API },
66     { "msg",    DEBUG_VERBOSE_MSG },
67     { "lru",    DEBUG_VERBOSE_LRU },
68     { "dri",    DEBUG_VERBOSE_DRI },
69     { "ioctl",  DEBUG_VERBOSE_IOCTL },
70     { "prims",  DEBUG_VERBOSE_PRIMS },
71     { "count",  DEBUG_VERBOSE_COUNT },
72     { "nowait", DEBUG_NOWAIT },
73     { "fall",   DEBUG_VERBOSE_FALLBACK },
74     { NULL,    0 }
75 };
76
77 static const struct dri_extension card_extensions[] =
78 {
79     { "GL_ARB_multitexture",               NULL },
80     { "GL_EXT_texture_edge_clamp",         NULL },
81     { "GL_MESA_ycbcr_texture",             NULL },
82     { NULL,                                NULL }
83 };
84
85
86 /* Create the device specific context.
87   */
88 GLboolean mach64CreateContext( gl_api api,
89                                const struct gl_config *glVisual,
90                                __DRIcontext *driContextPriv,
91                                void *sharedContextPrivate )
92 {
93    struct gl_context *ctx, *shareCtx;
94    __DRIscreen *driScreen = driContextPriv->driScreenPriv;
95    struct dd_function_table functions;
96    mach64ContextPtr mmesa;
97    mach64ScreenPtr mach64Screen;
98    int i, heap;
99    GLuint *c_textureSwapsPtr = NULL;
100
101 #if DO_DEBUG
102    MACH64_DEBUG = driParseDebugString(getenv("MACH64_DEBUG"), debug_control);
103 #endif
104
105    /* Allocate the mach64 context */
106    mmesa = (mach64ContextPtr) CALLOC( sizeof(*mmesa) );
107    if ( !mmesa ) 
108       return GL_FALSE;
109
110    /* Init default driver functions then plug in our Mach64-specific functions
111     * (the texture functions are especially important)
112     */
113    _mesa_init_driver_functions( &functions );
114    mach64InitDriverFuncs( &functions );
115    mach64InitIoctlFuncs( &functions );
116    mach64InitTextureFuncs( &functions );
117
118    /* Allocate the Mesa context */
119    if (sharedContextPrivate)
120       shareCtx = ((mach64ContextPtr) sharedContextPrivate)->glCtx;
121    else 
122       shareCtx = NULL;
123    mmesa->glCtx = _mesa_create_context(API_OPENGL, glVisual, shareCtx, 
124                                         &functions, (void *)mmesa);
125    if (!mmesa->glCtx) {
126       FREE(mmesa);
127       return GL_FALSE;
128    }
129    driContextPriv->driverPrivate = mmesa;
130    ctx = mmesa->glCtx;
131
132    mmesa->driContext = driContextPriv;
133    mmesa->driScreen = driScreen;
134    mmesa->driDrawable = NULL;
135    mmesa->hHWContext = driContextPriv->hHWContext;
136    mmesa->driHwLock = &driScreen->pSAREA->lock;
137    mmesa->driFd = driScreen->fd;
138
139    mach64Screen = mmesa->mach64Screen = (mach64ScreenPtr)driScreen->private;
140
141    /* Parse configuration files */
142    driParseConfigFiles (&mmesa->optionCache, &mach64Screen->optionCache,
143                         mach64Screen->driScreen->myNum, "mach64");
144
145    mmesa->sarea = (drm_mach64_sarea_t *)((char *)driScreen->pSAREA +
146                                     sizeof(drm_sarea_t));
147
148    mmesa->CurrentTexObj[0] = NULL;
149    mmesa->CurrentTexObj[1] = NULL;
150
151    (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
152    make_empty_list( &mmesa->swapped );
153
154    mmesa->firstTexHeap = mach64Screen->firstTexHeap;
155    mmesa->lastTexHeap = mach64Screen->firstTexHeap + mach64Screen->numTexHeaps;
156
157    for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
158       mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa,
159             mach64Screen->texSize[i],
160             6, /* align to 64-byte boundary, use 12 for page-size boundary */
161             MACH64_NR_TEX_REGIONS,
162             (drmTextureRegionPtr)mmesa->sarea->tex_list[i],
163             &mmesa->sarea->tex_age[i],
164             &mmesa->swapped,
165             sizeof( mach64TexObj ),
166             (destroy_texture_object_t *) mach64DestroyTexObj );
167
168 #if ENABLE_PERF_BOXES
169       c_textureSwapsPtr = & mmesa->c_textureSwaps;
170 #endif
171       driSetTextureSwapCounterLocation( mmesa->texture_heaps[i],
172                                         c_textureSwapsPtr );
173    }
174
175    mmesa->RenderIndex = -1;             /* Impossible value */
176    mmesa->vert_buf = NULL;
177    mmesa->num_verts = 0;
178    mmesa->new_state = MACH64_NEW_ALL;
179    mmesa->dirty = MACH64_UPLOAD_ALL;
180
181    /* Set the maximum texture size small enough that we can
182     * guarentee that both texture units can bind a maximal texture
183     * and have them both in memory (on-card or AGP) at once.
184     * Test for 2 textures * bytes/texel * size * size.  There's no
185     * need to account for mipmaps since we only upload one level.
186     */
187
188    ctx->Const.MaxTextureUnits = 2;
189    ctx->Const.MaxTextureImageUnits = 2;
190    ctx->Const.MaxTextureCoordUnits = 2;
191    ctx->Const.MaxDrawBuffers = 1;
192
193    heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP;
194
195    driCalculateMaxTextureLevels( & mmesa->texture_heaps[heap],
196                                  1,
197                                  & ctx->Const,
198                                  mach64Screen->cpp,
199                                  10, /* max 2D texture size is 1024x1024 */
200                                  0,  /* 3D textures unsupported. */
201                                  0,  /* cube textures unsupported. */
202                                  0,  /* texture rectangles unsupported. */
203                                  1,  /* mipmapping unsupported. */
204                                  GL_TRUE, /* need to have both textures in
205                                              either local or AGP memory */
206                                  0 );
207
208 #if ENABLE_PERF_BOXES
209    mmesa->boxes = ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL );
210 #endif
211
212    /* Allocate the vertex buffer
213     */
214    mmesa->vert_buf = _mesa_align_malloc(MACH64_BUFFER_SIZE, 32);
215    if ( !mmesa->vert_buf )
216       return GL_FALSE;
217    mmesa->vert_used = 0;
218    mmesa->vert_total = MACH64_BUFFER_SIZE;
219    
220    /* Initialize the software rasterizer and helper modules.
221     */
222    _swrast_CreateContext( ctx );
223    _vbo_CreateContext( ctx );
224    _tnl_CreateContext( ctx );
225    _swsetup_CreateContext( ctx );
226
227    /* Install the customized pipeline:
228     */
229 /*     _tnl_destroy_pipeline( ctx ); */
230 /*     _tnl_install_pipeline( ctx, mach64_pipeline ); */
231
232    /* Configure swrast and T&L to match hardware characteristics:
233     */
234    _swrast_allow_pixel_fog( ctx, GL_FALSE );
235    _swrast_allow_vertex_fog( ctx, GL_TRUE );
236    _tnl_allow_pixel_fog( ctx, GL_FALSE );
237    _tnl_allow_vertex_fog( ctx, GL_TRUE );
238
239    driInitExtensions( ctx, card_extensions, GL_TRUE );
240
241    mach64InitVB( ctx );
242    mach64InitTriFuncs( ctx );
243    mach64DDInitStateFuncs( ctx );
244    mach64DDInitSpanFuncs( ctx );
245    mach64DDInitState( mmesa );
246
247    mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
248
249    driContextPriv->driverPrivate = (void *)mmesa;
250
251    if (driQueryOptionb(&mmesa->optionCache, "no_rast")) {
252       fprintf(stderr, "disabling 3D acceleration\n");
253       FALLBACK(mmesa, MACH64_FALLBACK_DISABLE, 1);
254    }
255
256    return GL_TRUE;
257 }
258
259 /* Destroy the device specific context.
260  */
261 void mach64DestroyContext( __DRIcontext *driContextPriv  )
262 {
263    mach64ContextPtr mmesa = (mach64ContextPtr) driContextPriv->driverPrivate;
264
265    assert(mmesa);  /* should never be null */
266    if ( mmesa ) {
267       GLboolean   release_texture_heaps;
268
269       release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
270
271       _swsetup_DestroyContext( mmesa->glCtx );
272       _tnl_DestroyContext( mmesa->glCtx );
273       _vbo_DestroyContext( mmesa->glCtx );
274       _swrast_DestroyContext( mmesa->glCtx );
275
276       if (release_texture_heaps) {
277          /* This share group is about to go away, free our private
278           * texture object data.
279           */
280          int i;
281
282          for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
283             driDestroyTextureHeap( mmesa->texture_heaps[i] );
284             mmesa->texture_heaps[i] = NULL;
285          }
286
287          assert( is_empty_list( & mmesa->swapped ) );
288       }
289
290       mach64FreeVB( mmesa->glCtx );
291
292       /* Free the vertex buffer */
293       if ( mmesa->vert_buf )
294          _mesa_align_free( mmesa->vert_buf );
295       
296       /* free the Mesa context */
297       mmesa->glCtx->DriverCtx = NULL;
298       _mesa_destroy_context(mmesa->glCtx);
299
300       FREE( mmesa );
301    }
302 }
303
304 /* Force the context `c' to be the current context and associate with it
305  * buffer `b'.
306  */
307 GLboolean
308 mach64MakeCurrent( __DRIcontext *driContextPriv,
309                  __DRIdrawable *driDrawPriv,
310                  __DRIdrawable *driReadPriv )
311 {
312    if ( driContextPriv ) {
313       GET_CURRENT_CONTEXT(ctx);
314       mach64ContextPtr oldMach64Ctx = ctx ? MACH64_CONTEXT(ctx) : NULL;
315       mach64ContextPtr newMach64Ctx = (mach64ContextPtr) driContextPriv->driverPrivate;
316
317       if ( newMach64Ctx != oldMach64Ctx ) {
318          newMach64Ctx->new_state |= MACH64_NEW_CONTEXT;
319          newMach64Ctx->dirty = MACH64_UPLOAD_ALL;
320       }
321
322       
323       if ( newMach64Ctx->driDrawable != driDrawPriv ) {
324          if (driDrawPriv->swap_interval == (unsigned)-1) {
325             driDrawPriv->vblFlags = (newMach64Ctx->do_irqs)
326                ? driGetDefaultVBlankFlags(&newMach64Ctx->optionCache)
327                : VBLANK_FLAG_NO_IRQ;
328
329             driDrawableInitVBlank( driDrawPriv );
330          }
331
332          newMach64Ctx->driDrawable = driDrawPriv;
333          mach64CalcViewport( newMach64Ctx->glCtx );
334       }
335
336       _mesa_make_current( newMach64Ctx->glCtx,
337                           (struct gl_framebuffer *) driDrawPriv->driverPrivate,
338                           (struct gl_framebuffer *) driReadPriv->driverPrivate );
339
340
341       newMach64Ctx->new_state |=  MACH64_NEW_CLIP;
342    } else {
343       _mesa_make_current( NULL, NULL, NULL );
344    }
345
346    return GL_TRUE;
347 }
348
349
350 /* Force the context `c' to be unbound from its buffer.
351  */
352 GLboolean
353 mach64UnbindContext( __DRIcontext *driContextPriv )
354 {
355    return GL_TRUE;
356 }