nouveau_context.c revision 9a20ae70ecda2e78ea6b52c3fd829d283434c1ad
1/**************************************************************************
2
3Copyright 2006 Stephane Marchesin
4All Rights Reserved.
5
6Permission is hereby granted, free of charge, to any person obtaining a
7copy of this software and associated documentation files (the "Software"),
8to deal in the Software without restriction, including without limitation
9on the rights to use, copy, modify, merge, publish, distribute, sub
10license, and/or sell copies of the Software, and to permit persons to whom
11the Software is furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice (including the next
14paragraph) shall be included in all copies or substantial portions of the
15Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
21DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23USE 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
61int NOUVEAU_DEBUG = 0;
62#endif
63
64static const struct dri_debug_control debug_control[] =
65{
66	{ "shaders"   , DEBUG_SHADERS    },
67	{ "mem"       , DEBUG_MEM        },
68	{ "bufferobj" , DEBUG_BUFFEROBJ  },
69	{ NULL        , 0                }
70};
71
72#define need_GL_ARB_vertex_program
73#include "extension_helper.h"
74
75const struct dri_extension common_extensions[] =
76{
77	{ NULL,    0 }
78};
79
80const struct dri_extension nv10_extensions[] =
81{
82	{ NULL,    0 }
83};
84
85const struct dri_extension nv20_extensions[] =
86{
87	{ NULL,    0 }
88};
89
90const struct dri_extension nv30_extensions[] =
91{
92	{ "GL_ARB_fragment_program",	NULL                            },
93	{ NULL,    0 }
94};
95
96const struct dri_extension nv40_extensions[] =
97{
98   /* ARB_vp can be moved to nv20/30 once the shader backend has been
99    * written for those cards.
100    */
101	{ "GL_ARB_vertex_program",	GL_ARB_vertex_program_functions },
102	{ NULL, 0 }
103};
104
105const struct dri_extension nv50_extensions[] =
106{
107	{ NULL,    0 }
108};
109
110/* Create the device specific context.
111 */
112GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
113		__DRIcontextPrivate *driContextPriv,
114		void *sharedContextPrivate )
115{
116	GLcontext *ctx, *shareCtx;
117	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
118	struct dd_function_table functions;
119	nouveauContextPtr nmesa;
120	nouveauScreenPtr screen;
121
122	/* Allocate the context */
123	nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
124	if ( !nmesa )
125		return GL_FALSE;
126
127	nmesa->driContext = driContextPriv;
128	nmesa->driScreen = sPriv;
129	nmesa->driDrawable = NULL;
130	nmesa->hHWContext = driContextPriv->hHWContext;
131	nmesa->driHwLock = &sPriv->pSAREA->lock;
132	nmesa->driFd = sPriv->fd;
133
134	nmesa->screen = (nouveauScreenPtr)(sPriv->private);
135	screen=nmesa->screen;
136
137	/* Create the hardware context */
138	if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
139		 		&nmesa->vram_phys))
140	   return GL_FALSE;
141	if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL,
142		 		&nmesa->agp_phys))
143	   return GL_FALSE;
144	if (!nouveauFifoInit(nmesa))
145	   return GL_FALSE;
146	nouveauObjectInit(nmesa);
147
148
149	/* Init default driver functions then plug in our nouveau-specific functions
150	 * (the texture functions are especially important)
151	 */
152	_mesa_init_driver_functions( &functions );
153	nouveauDriverInitFunctions( &functions );
154	nouveauTexInitFunctions( &functions );
155
156	/* Allocate the Mesa context */
157	if (sharedContextPrivate)
158		shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
159	else
160		shareCtx = NULL;
161	nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
162			&functions, (void *) nmesa);
163	if (!nmesa->glCtx) {
164		FREE(nmesa);
165		return GL_FALSE;
166	}
167	driContextPriv->driverPrivate = nmesa;
168	ctx = nmesa->glCtx;
169
170	/* Parse configuration files */
171	driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
172			screen->driScreen->myNum, "nouveau");
173
174	nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
175			screen->sarea_priv_offset);
176
177	/* Enable any supported extensions */
178	driInitExtensions(ctx, common_extensions, GL_TRUE);
179	if (nmesa->screen->card->type >= NV_10)
180		driInitExtensions(ctx, nv10_extensions, GL_FALSE);
181	if (nmesa->screen->card->type >= NV_20)
182		driInitExtensions(ctx, nv20_extensions, GL_FALSE);
183	if (nmesa->screen->card->type >= NV_30)
184		driInitExtensions(ctx, nv30_extensions, GL_FALSE);
185	if (nmesa->screen->card->type >= NV_40)
186		driInitExtensions(ctx, nv40_extensions, GL_FALSE);
187	if (nmesa->screen->card->type >= NV_50)
188		driInitExtensions(ctx, nv50_extensions, GL_FALSE);
189
190	nmesa->current_primitive = -1;
191
192	nouveauShaderInitFuncs(ctx);
193	/* Install Mesa's fixed-function texenv shader support */
194	if (nmesa->screen->card->type >= NV_40)
195		ctx->_MaintainTexEnvProgram = GL_TRUE;
196
197	/* Initialize the swrast */
198	_swrast_CreateContext( ctx );
199	_ac_CreateContext( ctx );
200	_tnl_CreateContext( ctx );
201	_swsetup_CreateContext( ctx );
202
203	_math_matrix_ctr(&nmesa->viewport);
204
205	nouveauDDInitStateFuncs( ctx );
206	nouveauSpanInitFunctions( ctx );
207	nouveauDDInitState( nmesa );
208	switch(nmesa->screen->card->type)
209	{
210		case NV_03:
211			//nv03TriInitFunctions( ctx );
212			break;
213		case NV_04:
214		case NV_05:
215			//nv04TriInitFunctions( ctx );
216			break;
217		case NV_10:
218		case NV_20:
219		case NV_30:
220		case NV_40:
221		case NV_44:
222		case NV_50:
223		default:
224			nv10TriInitFunctions( ctx );
225			break;
226	}
227
228	nouveauInitBufferObjects(ctx);
229	if (!nouveauSyncInitFuncs(ctx))
230	   return GL_FALSE;
231	nmesa->hw_func.InitCard(nmesa);
232        nouveauInitState(ctx);
233
234	driContextPriv->driverPrivate = (void *)nmesa;
235
236	NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
237			debug_control );
238
239	if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
240		fprintf(stderr, "disabling 3D acceleration\n");
241		FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
242	}
243
244	return GL_TRUE;
245}
246
247/* Destroy the device specific context. */
248void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv  )
249{
250	nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
251
252	assert(nmesa);
253	if ( nmesa ) {
254		/* free the option cache */
255		driDestroyOptionCache (&nmesa->optionCache);
256
257		FREE( nmesa );
258	}
259
260}
261
262
263/* Force the context `c' to be the current context and associate with it
264 * buffer `b'.
265 */
266GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
267		__DRIdrawablePrivate *driDrawPriv,
268		__DRIdrawablePrivate *driReadPriv )
269{
270	if ( driContextPriv ) {
271		nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
272		struct gl_framebuffer *draw_fb =
273			(struct gl_framebuffer*)driDrawPriv->driverPrivate;
274		struct gl_framebuffer *read_fb =
275			(struct gl_framebuffer*)driReadPriv->driverPrivate;
276
277		driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
278		nmesa->driDrawable = driDrawPriv;
279
280		_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
281					 driDrawPriv->w, driDrawPriv->h);
282		if (draw_fb != read_fb) {
283			_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
284						 driReadPriv->w,
285						 driReadPriv->h);
286		}
287		_mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
288
289		nouveau_build_framebuffer(nmesa->glCtx,
290		      			  driDrawPriv->driverPrivate);
291	} else {
292		_mesa_make_current( NULL, NULL, NULL );
293	}
294
295	return GL_TRUE;
296}
297
298
299/* Force the context `c' to be unbound from its buffer.
300 */
301GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
302{
303	return GL_TRUE;
304}
305
306static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
307				 __DRIdrawablePrivate *dPriv)
308{
309	struct gl_framebuffer *fb;
310	nouveau_renderbuffer *src, *dst;
311	drm_clip_rect_t *box;
312	int nbox, i;
313
314	fb = (struct gl_framebuffer *)dPriv->driverPrivate;
315	dst = (nouveau_renderbuffer*)
316		fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
317	src = (nouveau_renderbuffer*)
318		fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
319
320#ifdef ALLOW_MULTI_SUBCHANNEL
321	LOCK_HARDWARE(nmesa);
322	nbox = dPriv->numClipRects;
323	box  = dPriv->pClipRects;
324
325	if (nbox) {
326		BEGIN_RING_SIZE(NvSubCtxSurf2D,
327				NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
328		if (src->mesa._ActualFormat == GL_RGBA8)
329			OUT_RING       (6); /* X8R8G8B8 */
330		else
331			OUT_RING       (4); /* R5G6B5 */
332		OUT_RING       ((dst->pitch << 16) | src->pitch);
333		OUT_RING       (src->offset);
334		OUT_RING       (dst->offset);
335	}
336
337	for (i=0; i<nbox; i++, box++) {
338		BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
339		OUT_RING       (((box->y1 - dPriv->y) << 16) |
340				(box->x1 - dPriv->x));
341		OUT_RING       ((box->y1 << 16) | box->x1);
342		OUT_RING       (((box->y2 - box->y1) << 16) |
343				(box->x2 - box->x1));
344	}
345
346	UNLOCK_HARDWARE(nmesa);
347#endif
348}
349
350void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
351{
352	if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
353		nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate;
354
355		if (nmesa->glCtx->Visual.doubleBufferMode) {
356			_mesa_notifySwapBuffers(nmesa->glCtx);
357			nouveauDoSwapBuffers(nmesa, dPriv);
358		}
359
360	}
361}
362
363void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
364			  int x, int y, int w, int h)
365{
366}
367
368