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