swrast.c revision 92d7ed8a20d4a018ce5324e6537ae7b478b9e5bf
1/* 2 * Copyright (C) 2008 George Sapountzis <gsap7@yahoo.gr> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21 22/* 23 * DRI software rasterizer 24 * 25 * This is the mesa swrast module packaged into a DRI driver structure. 26 * 27 * The front-buffer is allocated by the loader. The loader provides read/write 28 * callbacks for access to the front-buffer. The driver uses a scratch row for 29 * front-buffer rendering to avoid repeated calls to the loader. 30 * 31 * The back-buffer is allocated by the driver and is private. 32 */ 33 34#include "main/context.h" 35#include "main/extensions.h" 36#include "main/framebuffer.h" 37#include "main/imports.h" 38#include "main/renderbuffer.h" 39#include "swrast/swrast.h" 40#include "swrast_setup/swrast_setup.h" 41#include "tnl/tnl.h" 42#include "tnl/t_context.h" 43#include "tnl/t_pipeline.h" 44#include "vbo/vbo.h" 45#include "drivers/common/driverfuncs.h" 46#include "utils.h" 47 48#include "swrast_priv.h" 49 50 51#define need_GL_VERSION_1_3 52#define need_GL_VERSION_1_4 53#define need_GL_VERSION_1_5 54#define need_GL_VERSION_2_0 55#define need_GL_VERSION_2_1 56 57/* sw extensions for imaging */ 58#define need_GL_EXT_blend_color 59#define need_GL_EXT_blend_minmax 60#define need_GL_EXT_convolution 61#define need_GL_EXT_histogram 62#define need_GL_SGI_color_table 63 64/* sw extensions not associated with some GL version */ 65#define need_GL_ARB_draw_elements_base_vertex 66#define need_GL_ARB_shader_objects 67#define need_GL_ARB_vertex_array_object 68#define need_GL_ARB_vertex_program 69#define need_GL_ARB_sync 70#define need_GL_APPLE_vertex_array_object 71#define need_GL_ATI_fragment_shader 72#define need_GL_ATI_separate_stencil 73#define need_GL_EXT_depth_bounds_test 74#define need_GL_EXT_framebuffer_object 75#define need_GL_EXT_framebuffer_blit 76#define need_GL_EXT_gpu_program_parameters 77#define need_GL_EXT_paletted_texture 78#define need_GL_EXT_stencil_two_side 79#define need_GL_MESA_resize_buffers 80#define need_GL_NV_vertex_program 81#define need_GL_NV_fragment_program 82 83#include "extension_helper.h" 84 85const struct dri_extension card_extensions[] = 86{ 87 { "GL_VERSION_1_3", GL_VERSION_1_3_functions }, 88 { "GL_VERSION_1_4", GL_VERSION_1_4_functions }, 89 { "GL_VERSION_1_5", GL_VERSION_1_5_functions }, 90 { "GL_VERSION_2_0", GL_VERSION_2_0_functions }, 91 { "GL_VERSION_2_1", GL_VERSION_2_1_functions }, 92 93 { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, 94 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, 95 { "GL_EXT_convolution", GL_EXT_convolution_functions }, 96 { "GL_EXT_histogram", GL_EXT_histogram_functions }, 97 { "GL_SGI_color_table", GL_SGI_color_table_functions }, 98 99 { "GL_ARB_depth_clamp", NULL }, 100 { "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions }, 101 { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, 102 { "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions }, 103 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, 104 { "GL_ARB_sync", GL_ARB_sync_functions }, 105 { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions }, 106 { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions }, 107 { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions }, 108 { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions }, 109 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, 110 { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions }, 111 { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions }, 112 { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions }, 113 { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, 114 { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions }, 115 { "GL_NV_depth_clamp", NULL }, 116 { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, 117 { "GL_NV_fragment_program", GL_NV_fragment_program_functions }, 118 { NULL, NULL } 119}; 120 121 122/** 123 * Screen and config-related functions 124 */ 125 126static void 127setupLoaderExtensions(__DRIscreen *psp, 128 const __DRIextension **extensions) 129{ 130 int i; 131 132 for (i = 0; extensions[i]; i++) { 133 if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) 134 psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; 135 } 136} 137 138static __DRIconfig ** 139swrastFillInModes(__DRIscreen *psp, 140 unsigned pixel_bits, unsigned depth_bits, 141 unsigned stencil_bits, GLboolean have_back_buffer) 142{ 143 __DRIconfig **configs; 144 unsigned depth_buffer_factor; 145 unsigned back_buffer_factor; 146 GLenum fb_format; 147 GLenum fb_type; 148 149 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't 150 * support pageflipping at all. 151 */ 152 static const GLenum back_buffer_modes[] = { 153 GLX_NONE, GLX_SWAP_UNDEFINED_OML 154 }; 155 156 uint8_t depth_bits_array[4]; 157 uint8_t stencil_bits_array[4]; 158 uint8_t msaa_samples_array[1]; 159 160 depth_bits_array[0] = 0; 161 depth_bits_array[1] = 0; 162 depth_bits_array[2] = depth_bits; 163 depth_bits_array[3] = depth_bits; 164 165 /* Just like with the accumulation buffer, always provide some modes 166 * with a stencil buffer. 167 */ 168 stencil_bits_array[0] = 0; 169 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; 170 stencil_bits_array[2] = 0; 171 stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits; 172 173 msaa_samples_array[0] = 0; 174 175 depth_buffer_factor = 4; 176 back_buffer_factor = 2; 177 178 switch (pixel_bits) { 179 case 8: 180 fb_format = GL_RGB; 181 fb_type = GL_UNSIGNED_BYTE_2_3_3_REV; 182 break; 183 case 16: 184 fb_format = GL_RGB; 185 fb_type = GL_UNSIGNED_SHORT_5_6_5; 186 break; 187 case 24: 188 fb_format = GL_BGR; 189 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; 190 break; 191 case 32: 192 fb_format = GL_BGRA; 193 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; 194 break; 195 default: 196 fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__, 197 pixel_bits); 198 return NULL; 199 } 200 201 configs = driCreateConfigs(fb_format, fb_type, 202 depth_bits_array, stencil_bits_array, 203 depth_buffer_factor, back_buffer_modes, 204 back_buffer_factor, msaa_samples_array, 1); 205 if (configs == NULL) { 206 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 207 __LINE__); 208 return NULL; 209 } 210 211 return configs; 212} 213 214static __DRIscreen * 215driCreateNewScreen(int scrn, const __DRIextension **extensions, 216 const __DRIconfig ***driver_configs, void *data) 217{ 218 static const __DRIextension *emptyExtensionList[] = { NULL }; 219 __DRIscreen *psp; 220 __DRIconfig **configs8, **configs16, **configs24, **configs32; 221 222 (void) data; 223 224 TRACE; 225 226 psp = _mesa_calloc(sizeof(*psp)); 227 if (!psp) 228 return NULL; 229 230 setupLoaderExtensions(psp, extensions); 231 232 psp->num = scrn; 233 psp->extensions = emptyExtensionList; 234 235 configs8 = swrastFillInModes(psp, 8, 8, 0, 1); 236 configs16 = swrastFillInModes(psp, 16, 16, 0, 1); 237 configs24 = swrastFillInModes(psp, 24, 24, 8, 1); 238 configs32 = swrastFillInModes(psp, 32, 24, 8, 1); 239 240 configs16 = driConcatConfigs(configs8, configs16); 241 configs24 = driConcatConfigs(configs16, configs24); 242 *driver_configs = (const __DRIconfig **) 243 driConcatConfigs(configs24, configs32); 244 245 driInitExtensions( NULL, card_extensions, GL_FALSE ); 246 247 return psp; 248} 249 250static void driDestroyScreen(__DRIscreen *psp) 251{ 252 TRACE; 253 254 if (psp) { 255 _mesa_free(psp); 256 } 257} 258 259static const __DRIextension **driGetExtensions(__DRIscreen *psp) 260{ 261 TRACE; 262 263 return psp->extensions; 264} 265 266 267/** 268 * Framebuffer and renderbuffer-related functions. 269 */ 270 271static GLuint 272choose_pixel_format(const GLvisual *v) 273{ 274 if (v->rgbMode) { 275 int depth = v->rgbBits; 276 277 if (depth == 32 278 && v->redMask == 0xff0000 279 && v->greenMask == 0x00ff00 280 && v->blueMask == 0x0000ff) 281 return PF_A8R8G8B8; 282 else if (depth == 24 283 && v->redMask == 0xff0000 284 && v->greenMask == 0x00ff00 285 && v->blueMask == 0x0000ff) 286 return PF_X8R8G8B8; 287 else if (depth == 16 288 && v->redMask == 0xf800 289 && v->greenMask == 0x07e0 290 && v->blueMask == 0x001f) 291 return PF_R5G6B5; 292 else if (depth == 8 293 && v->redMask == 0x07 294 && v->greenMask == 0x38 295 && v->blueMask == 0xc0) 296 return PF_R3G3B2; 297 } 298 else { 299 if (v->indexBits == 8) 300 return PF_CI8; 301 } 302 303 _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ ); 304 return 0; 305} 306 307static void 308swrast_delete_renderbuffer(struct gl_renderbuffer *rb) 309{ 310 TRACE; 311 312 _mesa_free(rb->Data); 313 _mesa_free(rb); 314} 315 316static GLboolean 317swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 318 GLenum internalFormat, GLuint width, GLuint height) 319{ 320 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); 321 unsigned mask = PITCH_ALIGN_BITS - 1; 322 323 TRACE; 324 325 rb->Data = NULL; 326 rb->Width = width; 327 rb->Height = height; 328 329 /* always pad to PITCH_ALIGN_BITS */ 330 xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8; 331 332 return GL_TRUE; 333} 334 335static GLboolean 336swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 337 GLenum internalFormat, GLuint width, GLuint height) 338{ 339 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); 340 341 TRACE; 342 343 _mesa_free(rb->Data); 344 345 swrast_alloc_front_storage(ctx, rb, internalFormat, width, height); 346 347 rb->Data = _mesa_malloc(height * xrb->pitch); 348 349 return GL_TRUE; 350} 351 352static struct swrast_renderbuffer * 353swrast_new_renderbuffer(const GLvisual *visual, GLboolean front) 354{ 355 struct swrast_renderbuffer *xrb = _mesa_calloc(sizeof *xrb); 356 GLuint pixel_format; 357 358 TRACE; 359 360 if (!xrb) 361 return NULL; 362 363 _mesa_init_renderbuffer(&xrb->Base, 0); 364 365 pixel_format = choose_pixel_format(visual); 366 367 xrb->Base.Delete = swrast_delete_renderbuffer; 368 if (front) { 369 xrb->Base.AllocStorage = swrast_alloc_front_storage; 370 swrast_set_span_funcs_front(xrb, pixel_format); 371 } 372 else { 373 xrb->Base.AllocStorage = swrast_alloc_back_storage; 374 swrast_set_span_funcs_back(xrb, pixel_format); 375 } 376 377 switch (pixel_format) { 378 case PF_A8R8G8B8: 379 xrb->Base.InternalFormat = GL_RGBA; 380 xrb->Base._BaseFormat = GL_RGBA; 381 xrb->Base.DataType = GL_UNSIGNED_BYTE; 382 xrb->Base.RedBits = 8 * sizeof(GLubyte); 383 xrb->Base.GreenBits = 8 * sizeof(GLubyte); 384 xrb->Base.BlueBits = 8 * sizeof(GLubyte); 385 xrb->Base.AlphaBits = 8 * sizeof(GLubyte); 386 xrb->bpp = 32; 387 break; 388 case PF_X8R8G8B8: 389 xrb->Base.InternalFormat = GL_RGB; 390 xrb->Base._BaseFormat = GL_RGB; 391 xrb->Base.DataType = GL_UNSIGNED_BYTE; 392 xrb->Base.RedBits = 8 * sizeof(GLubyte); 393 xrb->Base.GreenBits = 8 * sizeof(GLubyte); 394 xrb->Base.BlueBits = 8 * sizeof(GLubyte); 395 xrb->Base.AlphaBits = 0; 396 xrb->bpp = 32; 397 break; 398 case PF_R5G6B5: 399 xrb->Base.InternalFormat = GL_RGB; 400 xrb->Base._BaseFormat = GL_RGB; 401 xrb->Base.DataType = GL_UNSIGNED_BYTE; 402 xrb->Base.RedBits = 5 * sizeof(GLubyte); 403 xrb->Base.GreenBits = 6 * sizeof(GLubyte); 404 xrb->Base.BlueBits = 5 * sizeof(GLubyte); 405 xrb->Base.AlphaBits = 0; 406 xrb->bpp = 16; 407 break; 408 case PF_R3G3B2: 409 xrb->Base.InternalFormat = GL_RGB; 410 xrb->Base._BaseFormat = GL_RGB; 411 xrb->Base.DataType = GL_UNSIGNED_BYTE; 412 xrb->Base.RedBits = 3 * sizeof(GLubyte); 413 xrb->Base.GreenBits = 3 * sizeof(GLubyte); 414 xrb->Base.BlueBits = 2 * sizeof(GLubyte); 415 xrb->Base.AlphaBits = 0; 416 xrb->bpp = 8; 417 break; 418 case PF_CI8: 419 xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT; 420 xrb->Base._BaseFormat = GL_COLOR_INDEX; 421 xrb->Base.DataType = GL_UNSIGNED_BYTE; 422 xrb->Base.IndexBits = 8 * sizeof(GLubyte); 423 xrb->bpp = 8; 424 break; 425 default: 426 return NULL; 427 } 428 429 return xrb; 430} 431 432static __DRIdrawable * 433driCreateNewDrawable(__DRIscreen *screen, 434 const __DRIconfig *config, void *data) 435{ 436 __DRIdrawable *buf; 437 struct swrast_renderbuffer *frontrb, *backrb; 438 439 TRACE; 440 441 buf = _mesa_calloc(sizeof *buf); 442 if (!buf) 443 return NULL; 444 445 buf->loaderPrivate = data; 446 447 buf->driScreenPriv = screen; 448 449 buf->row = _mesa_malloc(MAX_WIDTH * 4); 450 451 /* basic framebuffer setup */ 452 _mesa_initialize_framebuffer(&buf->Base, &config->modes); 453 454 /* add front renderbuffer */ 455 frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); 456 _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base); 457 458 /* add back renderbuffer */ 459 if (config->modes.doubleBufferMode) { 460 backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE); 461 _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base); 462 } 463 464 /* add software renderbuffers */ 465 _mesa_add_soft_renderbuffers(&buf->Base, 466 GL_FALSE, /* color */ 467 config->modes.haveDepthBuffer, 468 config->modes.haveStencilBuffer, 469 config->modes.haveAccumBuffer, 470 GL_FALSE, /* alpha */ 471 GL_FALSE /* aux bufs */); 472 473 return buf; 474} 475 476static void 477driDestroyDrawable(__DRIdrawable *buf) 478{ 479 TRACE; 480 481 if (buf) { 482 struct gl_framebuffer *fb = &buf->Base; 483 484 _mesa_free(buf->row); 485 486 fb->DeletePending = GL_TRUE; 487 _mesa_reference_framebuffer(&fb, NULL); 488 } 489} 490 491static void driSwapBuffers(__DRIdrawable *buf) 492{ 493 GET_CURRENT_CONTEXT(ctx); 494 495 struct swrast_renderbuffer *frontrb = 496 swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); 497 struct swrast_renderbuffer *backrb = 498 swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); 499 500 __DRIscreen *screen = buf->driScreenPriv; 501 502 TRACE; 503 504 /* check for signle-buffered */ 505 if (backrb == NULL) 506 return; 507 508 /* check if swapping currently bound buffer */ 509 if (ctx && ctx->DrawBuffer == &(buf->Base)) { 510 /* flush pending rendering */ 511 _mesa_notifySwapBuffers(ctx); 512 } 513 514 screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP, 515 0, 0, 516 frontrb->Base.Width, 517 frontrb->Base.Height, 518 backrb->Base.Data, 519 buf->loaderPrivate); 520} 521 522 523/** 524 * General device driver functions. 525 */ 526 527static void 528get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h ) 529{ 530 __DRIdrawable *buf = swrast_drawable(fb); 531 __DRIscreen *screen = buf->driScreenPriv; 532 int x, y; 533 534 screen->swrast_loader->getDrawableInfo(buf, 535 &x, &y, w, h, 536 buf->loaderPrivate); 537} 538 539static void 540swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb ) 541{ 542 GLsizei width, height; 543 544 get_window_size(fb, &width, &height); 545 if (fb->Width != width || fb->Height != height) { 546 _mesa_resize_framebuffer(ctx, fb, width, height); 547 } 548} 549 550static const GLubyte * 551get_string(GLcontext *ctx, GLenum pname) 552{ 553 (void) ctx; 554 switch (pname) { 555 case GL_VENDOR: 556 return (const GLubyte *) "Mesa Project"; 557 case GL_RENDERER: 558 return (const GLubyte *) "Software Rasterizer"; 559 default: 560 return NULL; 561 } 562} 563 564static void 565update_state( GLcontext *ctx, GLuint new_state ) 566{ 567 /* not much to do here - pass it on */ 568 _swrast_InvalidateState( ctx, new_state ); 569 _swsetup_InvalidateState( ctx, new_state ); 570 _vbo_InvalidateState( ctx, new_state ); 571 _tnl_InvalidateState( ctx, new_state ); 572} 573 574static void 575viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) 576{ 577 GLframebuffer *draw = ctx->WinSysDrawBuffer; 578 GLframebuffer *read = ctx->WinSysReadBuffer; 579 580 swrast_check_and_update_window_size(ctx, draw); 581 swrast_check_and_update_window_size(ctx, read); 582} 583 584static void 585swrast_init_driver_functions(struct dd_function_table *driver) 586{ 587 driver->GetString = get_string; 588 driver->UpdateState = update_state; 589 driver->GetBufferSize = NULL; 590 driver->Viewport = viewport; 591} 592 593 594/** 595 * Context-related functions. 596 */ 597 598static __DRIcontext * 599driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, 600 __DRIcontext *shared, void *data) 601{ 602 __DRIcontext *ctx; 603 GLcontext *mesaCtx; 604 struct dd_function_table functions; 605 606 TRACE; 607 608 ctx = _mesa_calloc(sizeof *ctx); 609 if (!ctx) 610 return NULL; 611 612 ctx->loaderPrivate = data; 613 614 ctx->driScreenPriv = screen; 615 616 /* build table of device driver functions */ 617 _mesa_init_driver_functions(&functions); 618 swrast_init_driver_functions(&functions); 619 620 if (!_mesa_initialize_context(&ctx->Base, &config->modes, 621 shared ? &shared->Base : NULL, 622 &functions, (void *) ctx)) { 623 _mesa_free(ctx); 624 return NULL; 625 } 626 627 mesaCtx = &ctx->Base; 628 629 /* do bounds checking to prevent segfaults and server crashes! */ 630 mesaCtx->Const.CheckArrayBounds = GL_TRUE; 631 632 /* create module contexts */ 633 _swrast_CreateContext( mesaCtx ); 634 _vbo_CreateContext( mesaCtx ); 635 _tnl_CreateContext( mesaCtx ); 636 _swsetup_CreateContext( mesaCtx ); 637 _swsetup_Wakeup( mesaCtx ); 638 639 /* use default TCL pipeline */ 640 { 641 TNLcontext *tnl = TNL_CONTEXT(mesaCtx); 642 tnl->Driver.RunPipeline = _tnl_run_pipeline; 643 } 644 645 _mesa_enable_sw_extensions(mesaCtx); 646 _mesa_enable_1_3_extensions(mesaCtx); 647 _mesa_enable_1_4_extensions(mesaCtx); 648 _mesa_enable_1_5_extensions(mesaCtx); 649 _mesa_enable_2_0_extensions(mesaCtx); 650 _mesa_enable_2_1_extensions(mesaCtx); 651 652 return ctx; 653} 654 655static void 656driDestroyContext(__DRIcontext *ctx) 657{ 658 GLcontext *mesaCtx; 659 TRACE; 660 661 if (ctx) { 662 mesaCtx = &ctx->Base; 663 _swsetup_DestroyContext( mesaCtx ); 664 _swrast_DestroyContext( mesaCtx ); 665 _tnl_DestroyContext( mesaCtx ); 666 _vbo_DestroyContext( mesaCtx ); 667 _mesa_destroy_context( mesaCtx ); 668 } 669} 670 671static int 672driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask) 673{ 674 TRACE; 675 676 _mesa_copy_context(&src->Base, &dst->Base, mask); 677 return GL_TRUE; 678} 679 680static int driBindContext(__DRIcontext *ctx, 681 __DRIdrawable *draw, 682 __DRIdrawable *read) 683{ 684 GLcontext *mesaCtx; 685 GLframebuffer *mesaDraw; 686 GLframebuffer *mesaRead; 687 TRACE; 688 689 if (ctx) { 690 if (!draw || !read) 691 return GL_FALSE; 692 693 mesaCtx = &ctx->Base; 694 mesaDraw = &draw->Base; 695 mesaRead = &read->Base; 696 697 /* check for same context and buffer */ 698 if (mesaCtx == _mesa_get_current_context() 699 && mesaCtx->DrawBuffer == mesaDraw 700 && mesaCtx->ReadBuffer == mesaRead) { 701 return GL_TRUE; 702 } 703 704 _glapi_check_multithread(); 705 706 swrast_check_and_update_window_size(mesaCtx, mesaDraw); 707 if (read != draw) 708 swrast_check_and_update_window_size(mesaCtx, mesaRead); 709 710 _mesa_make_current( mesaCtx, 711 mesaDraw, 712 mesaRead ); 713 } 714 else { 715 /* unbind */ 716 _mesa_make_current( NULL, NULL, NULL ); 717 } 718 719 return GL_TRUE; 720} 721 722static int driUnbindContext(__DRIcontext *ctx) 723{ 724 TRACE; 725 (void) ctx; 726 return GL_TRUE; 727} 728 729 730static const __DRIcoreExtension driCoreExtension = { 731 { __DRI_CORE, __DRI_CORE_VERSION }, 732 NULL, /* driCreateNewScreen */ 733 driDestroyScreen, 734 driGetExtensions, 735 driGetConfigAttrib, 736 driIndexConfigAttrib, 737 NULL, /* driCreateNewDrawable */ 738 driDestroyDrawable, 739 driSwapBuffers, 740 driCreateNewContext, 741 driCopyContext, 742 driDestroyContext, 743 driBindContext, 744 driUnbindContext 745}; 746 747static const __DRIswrastExtension driSWRastExtension = { 748 { __DRI_SWRAST, __DRI_SWRAST_VERSION }, 749 driCreateNewScreen, 750 driCreateNewDrawable 751}; 752 753/* This is the table of extensions that the loader will dlsym() for. */ 754PUBLIC const __DRIextension *__driDriverExtensions[] = { 755 &driCoreExtension.base, 756 &driSWRastExtension.base, 757 NULL 758}; 759