nouveau_context.c revision c04c74bc5da454478fd0dbf3b25dd54190ac0942
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 "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 60int NOUVEAU_DEBUG = 0; 61#endif 62 63static 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 71const struct dri_extension common_extensions[] = 72{ 73 { NULL, 0 } 74}; 75 76const struct dri_extension nv10_extensions[] = 77{ 78 { NULL, 0 } 79}; 80 81const struct dri_extension nv20_extensions[] = 82{ 83 { NULL, 0 } 84}; 85 86const struct dri_extension nv30_extensions[] = 87{ 88 { "GL_ARB_fragment_program", NULL }, 89 { NULL, 0 } 90}; 91 92const 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 101const struct dri_extension nv50_extensions[] = 102{ 103 { NULL, 0 } 104}; 105 106/* Create the device specific context. 107 */ 108GLboolean 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. */ 243void 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 */ 261GLboolean 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 */ 296GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ) 297{ 298 return GL_TRUE; 299} 300 301static 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 330void 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 343void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, 344 int x, int y, int w, int h) 345{ 346} 347 348