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