1 /**************************************************************************
3 Copyright 2006 Stephane Marchesin
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:
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
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.
25 **************************************************************************/
29 #include "simple_list.h"
32 #include "swrast/swrast.h"
33 #include "swrast_setup/swrast_setup.h"
34 #include "framebuffer.h"
37 #include "tnl/t_pipeline.h"
38 #include "tnl/t_vp_build.h"
40 #include "drivers/common/driverfuncs.h"
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"
59 #include "xmlpool.h" /* for symbolic values of enum-type options */
62 int NOUVEAU_DEBUG
= 0;
65 static const struct dri_debug_control debug_control
[] =
67 { "shaders" , DEBUG_SHADERS
},
68 { "mem" , DEBUG_MEM
},
69 { "bufferobj" , DEBUG_BUFFEROBJ
},
73 #define need_GL_ARB_vertex_program
74 #define need_GL_ARB_occlusion_query
75 #include "extension_helper.h"
77 const struct dri_extension common_extensions
[] =
82 const struct dri_extension nv10_extensions
[] =
87 const struct dri_extension nv20_extensions
[] =
92 const struct dri_extension nv30_extensions
[] =
94 { "GL_ARB_fragment_program", NULL
},
98 const struct dri_extension nv40_extensions
[] =
100 /* ARB_vp can be moved to nv20/30 once the shader backend has been
101 * written for those cards.
103 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
104 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions
},
108 const struct dri_extension nv50_extensions
[] =
113 /* Create the device specific context.
115 GLboolean
nouveauCreateContext( const __GLcontextModes
*glVisual
,
116 __DRIcontextPrivate
*driContextPriv
,
117 void *sharedContextPrivate
)
119 GLcontext
*ctx
, *shareCtx
;
120 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
121 struct dd_function_table functions
;
122 nouveauContextPtr nmesa
;
123 nouveauScreenPtr screen
;
125 /* Allocate the context */
126 nmesa
= (nouveauContextPtr
) CALLOC( sizeof(*nmesa
) );
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
;
137 nmesa
->screen
= (nouveauScreenPtr
)(sPriv
->private);
138 screen
=nmesa
->screen
;
140 /* Create the hardware context */
141 if (!nouveauDRMGetParam(nmesa
, NOUVEAU_GETPARAM_FB_PHYSICAL
,
144 if (!nouveauDRMGetParam(nmesa
, NOUVEAU_GETPARAM_AGP_PHYSICAL
,
147 if (!nouveauFifoInit(nmesa
))
149 nouveauObjectInit(nmesa
);
152 /* Init default driver functions then plug in our nouveau-specific functions
153 * (the texture functions are especially important)
155 _mesa_init_driver_functions( &functions
);
156 nouveauDriverInitFunctions( &functions
);
157 nouveauTexInitFunctions( &functions
);
159 /* Allocate the Mesa context */
160 if (sharedContextPrivate
)
161 shareCtx
= ((nouveauContextPtr
) sharedContextPrivate
)->glCtx
;
164 nmesa
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
165 &functions
, (void *) nmesa
);
170 driContextPriv
->driverPrivate
= nmesa
;
173 /* Parse configuration files */
174 driParseConfigFiles (&nmesa
->optionCache
, &screen
->optionCache
,
175 screen
->driScreen
->myNum
, "nouveau");
177 nmesa
->sarea
= (drm_nouveau_sarea_t
*)((char *)sPriv
->pSAREA
+
178 screen
->sarea_priv_offset
);
180 /* Enable any supported extensions */
181 driInitExtensions(ctx
, common_extensions
, GL_TRUE
);
182 if (nmesa
->screen
->card
->type
>= NV_10
)
183 driInitExtensions(ctx
, nv10_extensions
, GL_FALSE
);
184 if (nmesa
->screen
->card
->type
>= NV_20
)
185 driInitExtensions(ctx
, nv20_extensions
, GL_FALSE
);
186 if (nmesa
->screen
->card
->type
>= NV_30
)
187 driInitExtensions(ctx
, nv30_extensions
, GL_FALSE
);
188 if (nmesa
->screen
->card
->type
>= NV_40
)
189 driInitExtensions(ctx
, nv40_extensions
, GL_FALSE
);
190 if (nmesa
->screen
->card
->type
>= NV_50
)
191 driInitExtensions(ctx
, nv50_extensions
, GL_FALSE
);
193 nmesa
->current_primitive
= -1;
195 nouveauShaderInitFuncs(ctx
);
196 /* Install Mesa's fixed-function texenv shader support */
197 if (nmesa
->screen
->card
->type
>= NV_40
)
198 ctx
->_MaintainTexEnvProgram
= GL_TRUE
;
200 /* Initialize the swrast */
201 _swrast_CreateContext( ctx
);
202 _vbo_CreateContext( ctx
);
203 _tnl_CreateContext( ctx
);
204 _swsetup_CreateContext( ctx
);
206 _math_matrix_ctr(&nmesa
->viewport
);
208 nouveauDDInitStateFuncs( ctx
);
209 nouveauSpanInitFunctions( ctx
);
210 nouveauDDInitState( nmesa
);
211 switch(nmesa
->screen
->card
->type
)
214 //nv03TriInitFunctions( ctx );
218 nv04TriInitFunctions( ctx
);
227 nv10TriInitFunctions( ctx
);
231 nouveauInitBufferObjects(ctx
);
232 if (!nouveauSyncInitFuncs(ctx
))
234 nouveauQueryInitFuncs(ctx
);
235 nmesa
->hw_func
.InitCard(nmesa
);
236 nouveauInitState(ctx
);
238 driContextPriv
->driverPrivate
= (void *)nmesa
;
240 NOUVEAU_DEBUG
= driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
243 if (driQueryOptionb(&nmesa
->optionCache
, "no_rast")) {
244 fprintf(stderr
, "disabling 3D acceleration\n");
245 FALLBACK(nmesa
, NOUVEAU_FALLBACK_DISABLE
, 1);
251 /* Destroy the device specific context. */
252 void nouveauDestroyContext( __DRIcontextPrivate
*driContextPriv
)
254 nouveauContextPtr nmesa
= (nouveauContextPtr
) driContextPriv
->driverPrivate
;
258 /* free the option cache */
259 driDestroyOptionCache (&nmesa
->optionCache
);
267 /* Force the context `c' to be the current context and associate with it
270 GLboolean
nouveauMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
271 __DRIdrawablePrivate
*driDrawPriv
,
272 __DRIdrawablePrivate
*driReadPriv
)
274 if ( driContextPriv
) {
275 nouveauContextPtr nmesa
= (nouveauContextPtr
) driContextPriv
->driverPrivate
;
276 struct gl_framebuffer
*draw_fb
=
277 (struct gl_framebuffer
*)driDrawPriv
->driverPrivate
;
278 struct gl_framebuffer
*read_fb
=
279 (struct gl_framebuffer
*)driReadPriv
->driverPrivate
;
281 driDrawableInitVBlank(driDrawPriv
, nmesa
->vblank_flags
, &nmesa
->vblank_seq
);
282 nmesa
->driDrawable
= driDrawPriv
;
284 _mesa_resize_framebuffer(nmesa
->glCtx
, draw_fb
,
285 driDrawPriv
->w
, driDrawPriv
->h
);
286 if (draw_fb
!= read_fb
) {
287 _mesa_resize_framebuffer(nmesa
->glCtx
, draw_fb
,
291 _mesa_make_current(nmesa
->glCtx
, draw_fb
, read_fb
);
293 nouveau_build_framebuffer(nmesa
->glCtx
,
294 driDrawPriv
->driverPrivate
);
296 _mesa_make_current( NULL
, NULL
, NULL
);
303 /* Force the context `c' to be unbound from its buffer.
305 GLboolean
nouveauUnbindContext( __DRIcontextPrivate
*driContextPriv
)
310 static void nouveauDoSwapBuffers(nouveauContextPtr nmesa
,
311 __DRIdrawablePrivate
*dPriv
)
313 struct gl_framebuffer
*fb
;
314 nouveau_renderbuffer
*src
, *dst
;
315 drm_clip_rect_t
*box
;
318 fb
= (struct gl_framebuffer
*)dPriv
->driverPrivate
;
319 dst
= (nouveau_renderbuffer
*)
320 fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
321 src
= (nouveau_renderbuffer
*)
322 fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
324 #ifdef ALLOW_MULTI_SUBCHANNEL
325 LOCK_HARDWARE(nmesa
);
326 nbox
= dPriv
->numClipRects
;
327 box
= dPriv
->pClipRects
;
330 BEGIN_RING_SIZE(NvSubCtxSurf2D
,
331 NV10_CONTEXT_SURFACES_2D_FORMAT
, 4);
332 if (src
->mesa
._ActualFormat
== GL_RGBA8
)
333 OUT_RING (6); /* X8R8G8B8 */
335 OUT_RING (4); /* R5G6B5 */
336 OUT_RING ((dst
->pitch
<< 16) | src
->pitch
);
337 OUT_RING (src
->offset
);
338 OUT_RING (dst
->offset
);
341 for (i
=0; i
<nbox
; i
++, box
++) {
342 BEGIN_RING_SIZE(NvSubImageBlit
, NV10_IMAGE_BLIT_SET_POINT
, 3);
343 OUT_RING (((box
->y1
- dPriv
->y
) << 16) |
344 (box
->x1
- dPriv
->x
));
345 OUT_RING ((box
->y1
<< 16) | box
->x1
);
346 OUT_RING (((box
->y2
- box
->y1
) << 16) |
347 (box
->x2
- box
->x1
));
350 UNLOCK_HARDWARE(nmesa
);
354 void nouveauSwapBuffers(__DRIdrawablePrivate
*dPriv
)
356 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
357 nouveauContextPtr nmesa
= dPriv
->driContextPriv
->driverPrivate
;
359 if (nmesa
->glCtx
->Visual
.doubleBufferMode
) {
360 _mesa_notifySwapBuffers(nmesa
->glCtx
);
361 nouveauDoSwapBuffers(nmesa
, dPriv
);
367 void nouveauCopySubBuffer(__DRIdrawablePrivate
*dPriv
,
368 int x
, int y
, int w
, int h
)