OSDN Git Service

Merge branch 'nouveau-import'
[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 "nouveau_lock.h"
53 #include "nv10_swtcl.h"
54
55 #include "vblank.h"
56 #include "utils.h"
57 #include "texmem.h"
58 #include "xmlpool.h" /* for symbolic values of enum-type options */
59
60 #ifndef NOUVEAU_DEBUG
61 int NOUVEAU_DEBUG = 0;
62 #endif
63
64 static const struct dri_debug_control debug_control[] =
65 {
66         { NULL,    0 }
67 };
68
69 #define need_GL_ARB_vertex_program
70 #include "extension_helper.h"
71
72 const struct dri_extension common_extensions[] =
73 {
74         { NULL,    0 }
75 };
76
77 const struct dri_extension nv10_extensions[] =
78 {
79         { NULL,    0 }
80 };
81
82 const struct dri_extension nv20_extensions[] =
83 {
84         { NULL,    0 }
85 };
86
87 const struct dri_extension nv30_extensions[] =
88 {
89         { "GL_ARB_fragment_program",    NULL                            },
90         { NULL,    0 }
91 };
92
93 const struct dri_extension nv40_extensions[] =
94 {
95    /* ARB_vp can be moved to nv20/30 once the shader backend has been
96     * written for those cards.
97     */
98         { "GL_ARB_vertex_program",      GL_ARB_vertex_program_functions },
99         { NULL, 0 }
100 };
101
102 const struct dri_extension nv50_extensions[] =
103 {
104         { NULL,    0 }
105 };
106
107 /* Create the device specific context.
108  */
109 GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
110                 __DRIcontextPrivate *driContextPriv,
111                 void *sharedContextPrivate )
112 {
113         GLcontext *ctx, *shareCtx;
114         __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
115         struct dd_function_table functions;
116         nouveauContextPtr nmesa;
117         nouveauScreenPtr screen;
118
119         /* Allocate the context */
120         nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
121         if ( !nmesa )
122                 return GL_FALSE;
123
124         nmesa->driContext = driContextPriv;
125         nmesa->driScreen = sPriv;
126         nmesa->driDrawable = NULL;
127         nmesa->hHWContext = driContextPriv->hHWContext;
128         nmesa->driHwLock = &sPriv->pSAREA->lock;
129         nmesa->driFd = sPriv->fd;
130
131         nmesa->screen = (nouveauScreenPtr)(sPriv->private);
132         screen=nmesa->screen;
133
134         /* Create the hardware context */
135         if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
136                                 &nmesa->vram_phys))
137            return GL_FALSE;
138         if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL,
139                                 &nmesa->agp_phys))
140            return GL_FALSE;
141         if (!nouveauFifoInit(nmesa))
142            return GL_FALSE;
143         nouveauObjectInit(nmesa);
144
145
146         /* Init default driver functions then plug in our nouveau-specific functions
147          * (the texture functions are especially important)
148          */
149         _mesa_init_driver_functions( &functions );
150         nouveauDriverInitFunctions( &functions );
151         nouveauTexInitFunctions( &functions );
152
153         /* Allocate the Mesa context */
154         if (sharedContextPrivate)
155                 shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
156         else 
157                 shareCtx = NULL;
158         nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
159                         &functions, (void *) nmesa);
160         if (!nmesa->glCtx) {
161                 FREE(nmesa);
162                 return GL_FALSE;
163         }
164         driContextPriv->driverPrivate = nmesa;
165         ctx = nmesa->glCtx;
166
167         /* Parse configuration files */
168         driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
169                         screen->driScreen->myNum, "nouveau");
170
171         nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
172                         screen->sarea_priv_offset);
173
174         /* Enable any supported extensions */
175         driInitExtensions(ctx, common_extensions, GL_TRUE);
176         if (nmesa->screen->card->type >= NV_10)
177                 driInitExtensions(ctx, nv10_extensions, GL_FALSE);
178         if (nmesa->screen->card->type >= NV_20)
179                 driInitExtensions(ctx, nv20_extensions, GL_FALSE);
180         if (nmesa->screen->card->type >= NV_30)
181                 driInitExtensions(ctx, nv30_extensions, GL_FALSE);
182         if (nmesa->screen->card->type >= NV_40)
183                 driInitExtensions(ctx, nv40_extensions, GL_FALSE);
184         if (nmesa->screen->card->type >= NV_50)
185                 driInitExtensions(ctx, nv50_extensions, GL_FALSE);
186
187         nmesa->current_primitive = -1;
188
189         nouveauShaderInitFuncs(ctx);
190         /* Install Mesa's fixed-function texenv shader support */
191         if (nmesa->screen->card->type >= NV_40)
192                 ctx->_MaintainTexEnvProgram = GL_TRUE;
193
194         /* Initialize the swrast */
195         _swrast_CreateContext( ctx );
196         _ac_CreateContext( ctx );
197         _tnl_CreateContext( ctx );
198         _swsetup_CreateContext( ctx );
199
200         _math_matrix_ctr(&nmesa->viewport);
201
202         nouveauDDInitStateFuncs( ctx );
203         nouveauSpanInitFunctions( ctx );
204         nouveauDDInitState( nmesa );
205         switch(nmesa->screen->card->type)
206         {
207                 case NV_03:
208                         //nv03TriInitFunctions( ctx );
209                         break;
210                 case NV_04:
211                 case NV_05:
212                         //nv04TriInitFunctions( ctx );
213                         break;
214                 case NV_10:
215                 case NV_20:
216                 case NV_30:
217                 case NV_40:
218                 case NV_44:
219                 case NV_50:
220                 default:
221                         nv10TriInitFunctions( ctx );
222                         break;
223         }
224
225         nmesa->hw_func.InitCard(nmesa);
226         nouveauInitState(ctx);
227
228         driContextPriv->driverPrivate = (void *)nmesa;
229
230         NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
231                         debug_control );
232
233         if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
234                 fprintf(stderr, "disabling 3D acceleration\n");
235                 FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
236         }
237
238         return GL_TRUE;
239 }
240
241 /* Destroy the device specific context. */
242 void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv  )
243 {
244         nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
245
246         assert(nmesa);
247         if ( nmesa ) {
248                 /* free the option cache */
249                 driDestroyOptionCache (&nmesa->optionCache);
250
251                 FREE( nmesa );
252         }
253
254 }
255
256
257 /* Force the context `c' to be the current context and associate with it
258  * buffer `b'.
259  */
260 GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
261                 __DRIdrawablePrivate *driDrawPriv,
262                 __DRIdrawablePrivate *driReadPriv )
263 {
264         if ( driContextPriv ) {
265                 nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
266                 struct gl_framebuffer *draw_fb =
267                         (struct gl_framebuffer*)driDrawPriv->driverPrivate;
268                 struct gl_framebuffer *read_fb =
269                         (struct gl_framebuffer*)driReadPriv->driverPrivate;
270
271                 driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
272                 nmesa->driDrawable = driDrawPriv;
273
274                 _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
275                                          driDrawPriv->w, driDrawPriv->h);
276                 if (draw_fb != read_fb) {
277                         _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
278                                                  driReadPriv->w,
279                                                  driReadPriv->h);
280                 }
281                 _mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
282
283                 nouveau_build_framebuffer(nmesa->glCtx,
284                                           driDrawPriv->driverPrivate);
285         } else {
286                 _mesa_make_current( NULL, NULL, NULL );
287         }
288
289         return GL_TRUE;
290 }
291
292
293 /* Force the context `c' to be unbound from its buffer.
294  */
295 GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
296 {
297         return GL_TRUE;
298 }
299
300 static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
301                                  __DRIdrawablePrivate *dPriv)
302 {
303         struct gl_framebuffer *fb;
304         nouveau_renderbuffer *src, *dst;
305         drm_clip_rect_t *box;
306         int nbox, i;
307
308         fb = (struct gl_framebuffer *)dPriv->driverPrivate;
309         dst = (nouveau_renderbuffer*)
310                 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
311         src = (nouveau_renderbuffer*)
312                 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
313
314 #ifdef ALLOW_MULTI_SUBCHANNEL
315         LOCK_HARDWARE(nmesa);
316         nbox = dPriv->numClipRects;
317         box  = dPriv->pClipRects;
318
319         if (nbox) {
320                 BEGIN_RING_SIZE(NvSubCtxSurf2D,
321                                 NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
322                 OUT_RING       (6); /* X8R8G8B8 */
323                 OUT_RING       ((dst->pitch << 16) | src->pitch);
324                 OUT_RING       (src->offset);
325                 OUT_RING       (dst->offset);
326         }
327
328         for (i=0; i<nbox; i++, box++) {
329                 BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
330                 OUT_RING       (((box->y1 - dPriv->y) << 16) |
331                                 (box->x1 - dPriv->x));
332                 OUT_RING       ((box->y1 << 16) | box->x1);
333                 OUT_RING       (((box->y2 - box->y1) << 16) |
334                                 (box->x2 - box->x1));
335         }
336
337         UNLOCK_HARDWARE(nmesa);
338 #endif
339 }
340
341 void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
342 {
343         if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
344                 nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate;
345
346                 if (nmesa->glCtx->Visual.doubleBufferMode) {
347                         _mesa_notifySwapBuffers(nmesa->glCtx);
348                         nouveauDoSwapBuffers(nmesa, dPriv);
349                 }
350
351         }
352 }
353
354 void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
355                           int x, int y, int w, int h)
356 {
357 }
358