OSDN Git Service

Skeletal extension handling across chipsets.
[android-x86/external-mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_context.c
1 /**************************************************************************
2
3 Copyright 2006 Stephane Marchesin
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 on the rights to use, copy, modify, merge, publish, distribute, sub
10 license, and/or sell copies of the Software, and to permit persons to whom
11 the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
20 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 **************************************************************************/
26
27 #include "glheader.h"
28 #include "context.h"
29 #include "simple_list.h"
30 #include "imports.h"
31 #include "matrix.h"
32 #include "swrast/swrast.h"
33 #include "swrast_setup/swrast_setup.h"
34 #include "array_cache/acache.h"
35 #include "framebuffer.h"
36
37 #include "tnl/tnl.h"
38 #include "tnl/t_pipeline.h"
39 #include "tnl/t_vp_build.h"
40
41 #include "drivers/common/driverfuncs.h"
42
43 #include "nouveau_context.h"
44 #include "nouveau_driver.h"
45 //#include "nouveau_state.h"
46 #include "nouveau_span.h"
47 #include "nouveau_object.h"
48 #include "nouveau_fifo.h"
49 #include "nouveau_tex.h"
50 #include "nouveau_msg.h"
51 #include "nouveau_reg.h"
52 #include "nv10_swtcl.h"
53
54 #include "vblank.h"
55 #include "utils.h"
56 #include "texmem.h"
57 #include "xmlpool.h" /* for symbolic values of enum-type options */
58
59 #ifndef NOUVEAU_DEBUG
60 int NOUVEAU_DEBUG = 0;
61 #endif
62
63 static const struct dri_debug_control debug_control[] =
64 {
65         { NULL,    0 }
66 };
67
68 #define need_GL_ARB_vertex_program
69 #include "extension_helper.h"
70
71 const struct dri_extension common_extensions[] =
72 {
73         { NULL,    0 }
74 };
75
76 const struct dri_extension nv10_extensions[] =
77 {
78         { NULL,    0 }
79 };
80
81 const struct dri_extension nv20_extensions[] =
82 {
83         { NULL,    0 }
84 };
85
86 const struct dri_extension nv30_extensions[] =
87 {
88         { "GL_ARB_fragment_program",    NULL                            },
89         { NULL,    0 }
90 };
91
92 const struct dri_extension nv40_extensions[] =
93 {
94    /* ARB_vp can be moved to nv20/30 once the shader backend has been
95     * written for those cards.
96     */
97         { "GL_ARB_vertex_program",      GL_ARB_vertex_program_functions },
98         { NULL, 0 }
99 };
100
101 const struct dri_extension nv50_extensions[] =
102 {
103         { NULL,    0 }
104 };
105
106 /* Create the device specific context.
107  */
108 GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
109                 __DRIcontextPrivate *driContextPriv,
110                 void *sharedContextPrivate )
111 {
112         GLcontext *ctx, *shareCtx;
113         __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
114         struct dd_function_table functions;
115         nouveauContextPtr nmesa;
116         nouveauScreenPtr screen;
117
118         /* Allocate the context */
119         nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
120         if ( !nmesa )
121                 return GL_FALSE;
122
123         nmesa->driContext = driContextPriv;
124         nmesa->driScreen = sPriv;
125         nmesa->driDrawable = NULL;
126         nmesa->hHWContext = driContextPriv->hHWContext;
127         nmesa->driHwLock = &sPriv->pSAREA->lock;
128         nmesa->driFd = sPriv->fd;
129
130         nmesa->screen = (nouveauScreenPtr)(sPriv->private);
131         screen=nmesa->screen;
132
133         /* Create the hardware context */
134         if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
135                                 &nmesa->vram_phys))
136            return GL_FALSE;
137         if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL,
138                                 &nmesa->agp_phys))
139            return GL_FALSE;
140         if (!nouveauFifoInit(nmesa))
141            return GL_FALSE;
142         nouveauObjectInit(nmesa);
143
144
145         /* Init default driver functions then plug in our nouveau-specific functions
146          * (the texture functions are especially important)
147          */
148         _mesa_init_driver_functions( &functions );
149         nouveauDriverInitFunctions( &functions );
150         nouveauTexInitFunctions( &functions );
151
152         /* Allocate the Mesa context */
153         if (sharedContextPrivate)
154                 shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
155         else 
156                 shareCtx = NULL;
157         nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
158                         &functions, (void *) nmesa);
159         if (!nmesa->glCtx) {
160                 FREE(nmesa);
161                 return GL_FALSE;
162         }
163         driContextPriv->driverPrivate = nmesa;
164         ctx = nmesa->glCtx;
165
166         /* Parse configuration files */
167         driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
168                         screen->driScreen->myNum, "nouveau");
169
170         nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
171                         screen->sarea_priv_offset);
172
173         /* Enable any supported extensions */
174         driInitExtensions(ctx, common_extensions, GL_TRUE);
175         if (nmesa->screen->card->type >= NV_10)
176                 driInitExtensions(ctx, nv10_extensions, GL_FALSE);
177         if (nmesa->screen->card->type >= NV_20)
178                 driInitExtensions(ctx, nv20_extensions, GL_FALSE);
179         if (nmesa->screen->card->type >= NV_30)
180                 driInitExtensions(ctx, nv30_extensions, GL_FALSE);
181         if (nmesa->screen->card->type >= NV_40)
182                 driInitExtensions(ctx, nv40_extensions, GL_FALSE);
183         if (nmesa->screen->card->type >= NV_50)
184                 driInitExtensions(ctx, nv50_extensions, GL_FALSE);
185
186         nmesa->current_primitive = -1;
187
188         nouveauShaderInitFuncs(ctx);
189         /* Install Mesa's fixed-function shader support */
190         if (nmesa->screen->card->type >= NV_40) {
191                 ctx->_MaintainTnlProgram    = GL_TRUE;
192                 ctx->_MaintainTexEnvProgram = GL_TRUE;
193         }
194
195         /* Initialize the swrast */
196         _swrast_CreateContext( ctx );
197         _ac_CreateContext( ctx );
198         _tnl_CreateContext( ctx );
199         _swsetup_CreateContext( ctx );
200
201         _math_matrix_ctr(&nmesa->viewport);
202
203         nouveauDDInitStateFuncs( ctx );
204         nouveauSpanInitFunctions( ctx );
205         nouveauDDInitState( nmesa );
206         switch(nmesa->screen->card->type)
207         {
208                 case NV_03:
209                         //nv03TriInitFunctions( ctx );
210                         break;
211                 case NV_04:
212                 case NV_05:
213                         //nv04TriInitFunctions( ctx );
214                         break;
215                 case NV_10:
216                 case NV_20:
217                 case NV_30:
218                 case NV_40:
219                 case NV_44:
220                 case NV_50:
221                 default:
222                         nv10TriInitFunctions( ctx );
223                         break;
224         }
225
226         nmesa->hw_func.InitCard(nmesa);
227         nouveauInitState(ctx);
228
229         driContextPriv->driverPrivate = (void *)nmesa;
230
231         NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
232                         debug_control );
233
234         if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
235                 fprintf(stderr, "disabling 3D acceleration\n");
236                 FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
237         }
238
239         return GL_TRUE;
240 }
241
242 /* Destroy the device specific context. */
243 void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv  )
244 {
245         nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
246
247         assert(nmesa);
248         if ( nmesa ) {
249                 /* free the option cache */
250                 driDestroyOptionCache (&nmesa->optionCache);
251
252                 FREE( nmesa );
253         }
254
255 }
256
257
258 /* Force the context `c' to be the current context and associate with it
259  * buffer `b'.
260  */
261 GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
262                 __DRIdrawablePrivate *driDrawPriv,
263                 __DRIdrawablePrivate *driReadPriv )
264 {
265         if ( driContextPriv ) {
266                 nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
267                 struct gl_framebuffer *draw_fb =
268                         (struct gl_framebuffer*)driDrawPriv->driverPrivate;
269                 struct gl_framebuffer *read_fb =
270                         (struct gl_framebuffer*)driReadPriv->driverPrivate;
271
272                 driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
273                 nmesa->driDrawable = driDrawPriv;
274
275                 _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
276                                          driDrawPriv->w, driDrawPriv->h);
277                 if (draw_fb != read_fb) {
278                         _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
279                                                  driReadPriv->w,
280                                                  driReadPriv->h);
281                 }
282                 _mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
283
284                 nouveau_build_framebuffer(nmesa->glCtx,
285                                           driDrawPriv->driverPrivate);
286         } else {
287                 _mesa_make_current( NULL, NULL, NULL );
288         }
289
290         return GL_TRUE;
291 }
292
293
294 /* Force the context `c' to be unbound from its buffer.
295  */
296 GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
297 {
298         return GL_TRUE;
299 }
300
301 static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
302                                  __DRIdrawablePrivate *dPriv)
303 {
304         struct gl_framebuffer *fb;
305         nouveau_renderbuffer *src, *dst;
306
307         fb = (struct gl_framebuffer *)dPriv->driverPrivate;
308         dst = (nouveau_renderbuffer*)
309                 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
310         src = (nouveau_renderbuffer*)
311                 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
312
313 #ifdef ALLOW_MULTI_SUBCHANNEL
314         /* Ignore this.. it's a hack to test double-buffering, and not how
315          * SwapBuffers should look :)
316          */
317         BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
318         OUT_RING       (6); /* X8R8G8B8 */
319         OUT_RING       ((dst->pitch << 16) | src->pitch);
320         OUT_RING       (src->offset);
321         OUT_RING       (dst->offset);
322
323         BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
324         OUT_RING       ((0 << 16) | 0); /* src point */
325         OUT_RING       ((0 << 16) | 0); /* dst point */
326         OUT_RING       ((fb->Height << 16) | fb->Width); /* width/height */
327 #endif
328 }
329
330 void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
331 {
332         if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
333                 nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate;
334
335                 if (nmesa->glCtx->Visual.doubleBufferMode) {
336                         _mesa_notifySwapBuffers(nmesa->glCtx);
337                         nouveauDoSwapBuffers(nmesa, dPriv);
338                 }
339
340         }
341 }
342
343 void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
344                           int x, int y, int w, int h)
345 {
346 }
347