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