renderbuffer.c revision c650bb0b7d2f8b1c9823001ab2012c4cbecfbc6c
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5 4 * 5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * Functions for allocating/managing renderbuffers. 28 * Also, routines for reading/writing software-based renderbuffer data as 29 * ubytes, ushorts, uints, etc. 30 * 31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based 32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB 33 * renderbuffer with the alpha renderbuffer. We can do this because of the 34 * OO-nature of renderbuffers. 35 * 36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit 37 * color channels. For example, Mesa may use 32-bit/float color channels 38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit 39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have. 40 */ 41 42 43#include "glheader.h" 44#include "imports.h" 45#include "context.h" 46#include "mtypes.h" 47#include "fbobject.h" 48#include "renderbuffer.h" 49 50 51/* 32-bit color index format. Not a public format. */ 52#define COLOR_INDEX32 0x424243 53 54 55/* 56 * Routines for get/put values in common buffer formats follow. 57 * Someday add support for arbitrary row stride to make them more 58 * flexible. 59 */ 60 61/********************************************************************** 62 * Functions for buffers of 1 X GLubyte values. 63 * Typically stencil. 64 */ 65 66static void * 67get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, 68 GLint x, GLint y) 69{ 70 if (!rb->Data) 71 return NULL; 72 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 73 return (GLubyte *) rb->Data + y * rb->Width + x; 74} 75 76 77static void 78get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 79 GLint x, GLint y, void *values) 80{ 81 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; 82 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 83 _mesa_memcpy(values, src, count * sizeof(GLubyte)); 84} 85 86 87static void 88get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 89 const GLint x[], const GLint y[], void *values) 90{ 91 GLubyte *dst = (GLubyte *) values; 92 GLuint i; 93 assert(rb->DataType == GL_UNSIGNED_BYTE); 94 for (i = 0; i < count; i++) { 95 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 96 dst[i] = *src; 97 } 98} 99 100 101static void 102put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 103 GLint x, GLint y, const void *values, const GLubyte *mask) 104{ 105 const GLubyte *src = (const GLubyte *) values; 106 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 107 assert(rb->DataType == GL_UNSIGNED_BYTE); 108 if (mask) { 109 GLuint i; 110 for (i = 0; i < count; i++) { 111 if (mask[i]) { 112 dst[i] = src[i]; 113 } 114 } 115 } 116 else { 117 _mesa_memcpy(dst, values, count * sizeof(GLubyte)); 118 } 119} 120 121 122static void 123put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 124 GLint x, GLint y, const void *value, const GLubyte *mask) 125{ 126 const GLubyte val = *((const GLubyte *) value); 127 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 128 assert(rb->DataType == GL_UNSIGNED_BYTE); 129 if (mask) { 130 GLuint i; 131 for (i = 0; i < count; i++) { 132 if (mask[i]) { 133 dst[i] = val; 134 } 135 } 136 } 137 else { 138 GLuint i; 139 for (i = 0; i < count; i++) { 140 dst[i] = val; 141 } 142 } 143} 144 145 146static void 147put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 148 const GLint x[], const GLint y[], 149 const void *values, const GLubyte *mask) 150{ 151 const GLubyte *src = (const GLubyte *) values; 152 GLuint i; 153 assert(rb->DataType == GL_UNSIGNED_BYTE); 154 for (i = 0; i < count; i++) { 155 if (!mask || mask[i]) { 156 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 157 *dst = src[i]; 158 } 159 } 160} 161 162 163static void 164put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 165 const GLint x[], const GLint y[], 166 const void *value, const GLubyte *mask) 167{ 168 const GLubyte val = *((const GLubyte *) value); 169 GLuint i; 170 assert(rb->DataType == GL_UNSIGNED_BYTE); 171 for (i = 0; i < count; i++) { 172 if (!mask || mask[i]) { 173 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 174 *dst = val; 175 } 176 } 177} 178 179 180/********************************************************************** 181 * Functions for buffers of 1 X GLushort values. 182 * Typically depth/Z. 183 */ 184 185static void * 186get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, 187 GLint x, GLint y) 188{ 189 if (!rb->Data) 190 return NULL; 191 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 192 ASSERT(rb->Width > 0); 193 return (GLushort *) rb->Data + y * rb->Width + x; 194} 195 196 197static void 198get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 199 GLint x, GLint y, void *values) 200{ 201 const void *src = rb->GetPointer(ctx, rb, x, y); 202 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 203 _mesa_memcpy(values, src, count * sizeof(GLushort)); 204} 205 206 207static void 208get_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 209 const GLint x[], const GLint y[], void *values) 210{ 211 GLushort *dst = (GLushort *) values; 212 GLuint i; 213 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 214 for (i = 0; i < count; i++) { 215 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 216 dst[i] = *src; 217 } 218} 219 220 221static void 222put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 223 GLint x, GLint y, const void *values, const GLubyte *mask) 224{ 225 const GLushort *src = (const GLushort *) values; 226 GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x; 227 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 228 if (mask) { 229 GLuint i; 230 for (i = 0; i < count; i++) { 231 if (mask[i]) { 232 dst[i] = src[i]; 233 } 234 } 235 } 236 else { 237 _mesa_memcpy(dst, src, count * sizeof(GLushort)); 238 } 239} 240 241 242static void 243put_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 244 GLint x, GLint y, const void *value, const GLubyte *mask) 245{ 246 const GLushort val = *((const GLushort *) value); 247 GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x; 248 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 249 if (mask) { 250 GLuint i; 251 for (i = 0; i < count; i++) { 252 if (mask[i]) { 253 dst[i] = val; 254 } 255 } 256 } 257 else { 258 GLuint i; 259 for (i = 0; i < count; i++) { 260 dst[i] = val; 261 } 262 } 263} 264 265 266static void 267put_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 268 const GLint x[], const GLint y[], const void *values, 269 const GLubyte *mask) 270{ 271 const GLushort *src = (const GLushort *) values; 272 GLuint i; 273 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 274 for (i = 0; i < count; i++) { 275 if (!mask || mask[i]) { 276 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 277 *dst = src[i]; 278 } 279 } 280} 281 282 283static void 284put_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, 285 GLuint count, const GLint x[], const GLint y[], 286 const void *value, const GLubyte *mask) 287{ 288 const GLushort val = *((const GLushort *) value); 289 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 290 if (mask) { 291 GLuint i; 292 for (i = 0; i < count; i++) { 293 if (mask[i]) { 294 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 295 *dst = val; 296 } 297 } 298 } 299 else { 300 GLuint i; 301 for (i = 0; i < count; i++) { 302 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 303 *dst = val; 304 } 305 } 306} 307 308 309/********************************************************************** 310 * Functions for buffers of 1 X GLuint values. 311 * Typically depth/Z or color index. 312 */ 313 314static void * 315get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb, 316 GLint x, GLint y) 317{ 318 if (!rb->Data) 319 return NULL; 320 ASSERT(rb->DataType == GL_UNSIGNED_INT); 321 return (GLuint *) rb->Data + y * rb->Width + x; 322} 323 324 325static void 326get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 327 GLint x, GLint y, void *values) 328{ 329 const void *src = rb->GetPointer(ctx, rb, x, y); 330 ASSERT(rb->DataType == GL_UNSIGNED_INT); 331 _mesa_memcpy(values, src, count * sizeof(GLuint)); 332} 333 334 335static void 336get_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 337 const GLint x[], const GLint y[], void *values) 338{ 339 GLuint *dst = (GLuint *) values; 340 GLuint i; 341 ASSERT(rb->DataType == GL_UNSIGNED_INT); 342 for (i = 0; i < count; i++) { 343 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 344 dst[i] = *src; 345 } 346} 347 348 349static void 350put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 351 GLint x, GLint y, const void *values, const GLubyte *mask) 352{ 353 const GLuint *src = (const GLuint *) values; 354 GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x; 355 ASSERT(rb->DataType == GL_UNSIGNED_INT); 356 if (mask) { 357 GLuint i; 358 for (i = 0; i < count; i++) { 359 if (mask[i]) { 360 dst[i] = src[i]; 361 } 362 } 363 } 364 else { 365 _mesa_memcpy(dst, src, count * sizeof(GLuint)); 366 } 367} 368 369 370static void 371put_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 372 GLint x, GLint y, const void *value, const GLubyte *mask) 373{ 374 const GLuint val = *((const GLuint *) value); 375 GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x; 376 GLuint i; 377 ASSERT(rb->DataType == GL_UNSIGNED_INT); 378 for (i = 0; i < count; i++) { 379 if (!mask || mask[i]) { 380 dst[i] = val; 381 } 382 } 383} 384 385 386static void 387put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 388 const GLint x[], const GLint y[], const void *values, 389 const GLubyte *mask) 390{ 391 const GLuint *src = (const GLuint *) values; 392 GLuint i; 393 ASSERT(rb->DataType == GL_UNSIGNED_INT); 394 for (i = 0; i < count; i++) { 395 if (!mask || mask[i]) { 396 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 397 *dst = src[i]; 398 } 399 } 400} 401 402 403static void 404put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 405 const GLint x[], const GLint y[], const void *value, 406 const GLubyte *mask) 407{ 408 const GLuint val = *((const GLuint *) value); 409 GLuint i; 410 ASSERT(rb->DataType == GL_UNSIGNED_INT); 411 for (i = 0; i < count; i++) { 412 if (!mask || mask[i]) { 413 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 414 *dst = val; 415 } 416 } 417} 418 419 420/********************************************************************** 421 * Functions for buffers of 3 X GLubyte (or GLbyte) values. 422 * Typically color buffers. 423 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 424 * alpha values and return 255 for outgoing alpha values. 425 */ 426 427static void * 428get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 429 GLint x, GLint y) 430{ 431 /* No direct access since this buffer is RGB but caller will be 432 * treating it as if it were RGBA. 433 */ 434 return NULL; 435} 436 437 438static void 439get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 440 GLint x, GLint y, void *values) 441{ 442 const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x); 443 GLubyte *dst = (GLubyte *) values; 444 GLuint i; 445 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 446 for (i = 0; i < count; i++) { 447 dst[i * 4 + 0] = src[i * 3 + 0]; 448 dst[i * 4 + 1] = src[i * 3 + 1]; 449 dst[i * 4 + 2] = src[i * 3 + 2]; 450 dst[i * 4 + 3] = 255; 451 } 452} 453 454 455static void 456get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 457 const GLint x[], const GLint y[], void *values) 458{ 459 GLubyte *dst = (GLubyte *) values; 460 GLuint i; 461 assert(rb->DataType == GL_UNSIGNED_BYTE); 462 for (i = 0; i < count; i++) { 463 const GLubyte *src 464 = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 465 dst[i * 4 + 0] = src[0]; 466 dst[i * 4 + 1] = src[1]; 467 dst[i * 4 + 2] = src[2]; 468 dst[i * 4 + 3] = 255; 469 } 470} 471 472 473static void 474put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 475 GLint x, GLint y, const void *values, const GLubyte *mask) 476{ 477 /* note: incoming values are RGB+A! */ 478 const GLubyte *src = (const GLubyte *) values; 479 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 480 GLuint i; 481 assert(rb->DataType == GL_UNSIGNED_BYTE); 482 for (i = 0; i < count; i++) { 483 if (!mask || mask[i]) { 484 dst[i * 3 + 0] = src[i * 4 + 0]; 485 dst[i * 3 + 1] = src[i * 4 + 1]; 486 dst[i * 3 + 2] = src[i * 4 + 2]; 487 } 488 } 489} 490 491 492static void 493put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 494 GLint x, GLint y, const void *values, const GLubyte *mask) 495{ 496 /* note: incoming values are RGB+A! */ 497 const GLubyte *src = (const GLubyte *) values; 498 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 499 GLuint i; 500 assert(rb->DataType == GL_UNSIGNED_BYTE); 501 for (i = 0; i < count; i++) { 502 if (!mask || mask[i]) { 503 dst[i * 3 + 0] = src[i * 3 + 0]; 504 dst[i * 3 + 1] = src[i * 3 + 1]; 505 dst[i * 3 + 2] = src[i * 3 + 2]; 506 } 507 } 508} 509 510 511static void 512put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 513 GLint x, GLint y, const void *value, const GLubyte *mask) 514{ 515 /* note: incoming value is RGB+A! */ 516 const GLubyte val0 = ((const GLubyte *) value)[0]; 517 const GLubyte val1 = ((const GLubyte *) value)[1]; 518 const GLubyte val2 = ((const GLubyte *) value)[2]; 519 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 520 assert(rb->DataType == GL_UNSIGNED_BYTE); 521 if (!mask && val0 == val1 && val1 == val2) { 522 /* optimized case */ 523 _mesa_memset(dst, val0, 3 * count); 524 } 525 else { 526 GLuint i; 527 for (i = 0; i < count; i++) { 528 if (!mask || mask[i]) { 529 dst[i * 3 + 0] = val0; 530 dst[i * 3 + 1] = val1; 531 dst[i * 3 + 2] = val2; 532 } 533 } 534 } 535} 536 537 538static void 539put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 540 const GLint x[], const GLint y[], const void *values, 541 const GLubyte *mask) 542{ 543 /* note: incoming values are RGB+A! */ 544 const GLubyte *src = (const GLubyte *) values; 545 GLuint i; 546 assert(rb->DataType == GL_UNSIGNED_BYTE); 547 for (i = 0; i < count; i++) { 548 if (!mask || mask[i]) { 549 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 550 dst[0] = src[i * 4 + 0]; 551 dst[1] = src[i * 4 + 1]; 552 dst[2] = src[i * 4 + 2]; 553 } 554 } 555} 556 557 558static void 559put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 560 GLuint count, const GLint x[], const GLint y[], 561 const void *value, const GLubyte *mask) 562{ 563 /* note: incoming value is RGB+A! */ 564 const GLubyte val0 = ((const GLubyte *) value)[0]; 565 const GLubyte val1 = ((const GLubyte *) value)[1]; 566 const GLubyte val2 = ((const GLubyte *) value)[2]; 567 GLuint i; 568 assert(rb->DataType == GL_UNSIGNED_BYTE); 569 for (i = 0; i < count; i++) { 570 if (!mask || mask[i]) { 571 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 572 dst[0] = val0; 573 dst[1] = val1; 574 dst[2] = val2; 575 } 576 } 577} 578 579 580/********************************************************************** 581 * Functions for buffers of 4 X GLubyte (or GLbyte) values. 582 * Typically color buffers. 583 */ 584 585static void * 586get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 587 GLint x, GLint y) 588{ 589 if (!rb->Data) 590 return NULL; 591 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 592 return (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 593} 594 595 596static void 597get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 598 GLint x, GLint y, void *values) 599{ 600 const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x); 601 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 602 _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte)); 603} 604 605 606static void 607get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 608 const GLint x[], const GLint y[], void *values) 609{ 610 /* treat 4*GLubyte as 1*GLuint */ 611 GLuint *dst = (GLuint *) values; 612 GLuint i; 613 assert(rb->DataType == GL_UNSIGNED_BYTE); 614 for (i = 0; i < count; i++) { 615 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 616 dst[i] = *src; 617 } 618} 619 620 621static void 622put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 623 GLint x, GLint y, const void *values, const GLubyte *mask) 624{ 625 /* treat 4*GLubyte as 1*GLuint */ 626 const GLuint *src = (const GLuint *) values; 627 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 628 assert(rb->DataType == GL_UNSIGNED_BYTE); 629 if (mask) { 630 GLuint i; 631 for (i = 0; i < count; i++) { 632 if (mask[i]) { 633 dst[i] = src[i]; 634 } 635 } 636 } 637 else { 638 _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte)); 639 } 640} 641 642 643static void 644put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 645 GLint x, GLint y, const void *values, const GLubyte *mask) 646{ 647 /* Store RGB values in RGBA buffer */ 648 const GLubyte *src = (const GLubyte *) values; 649 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 650 GLuint i; 651 assert(rb->DataType == GL_UNSIGNED_BYTE); 652 for (i = 0; i < count; i++) { 653 if (!mask || mask[i]) { 654 dst[i * 4 + 0] = src[i * 3 + 0]; 655 dst[i * 4 + 1] = src[i * 3 + 1]; 656 dst[i * 4 + 2] = src[i * 3 + 2]; 657 dst[i * 4 + 3] = 0xff; 658 } 659 } 660} 661 662 663static void 664put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 665 GLint x, GLint y, const void *value, const GLubyte *mask) 666{ 667 /* treat 4*GLubyte as 1*GLuint */ 668 const GLuint val = *((const GLuint *) value); 669 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 670 assert(rb->DataType == GL_UNSIGNED_BYTE); 671 if (!mask && val == 0) { 672 /* common case */ 673 _mesa_bzero(dst, count * 4 * sizeof(GLubyte)); 674 } 675 else { 676 /* general case */ 677 if (mask) { 678 GLuint i; 679 for (i = 0; i < count; i++) { 680 if (mask[i]) { 681 dst[i] = val; 682 } 683 } 684 } 685 else { 686 GLuint i; 687 for (i = 0; i < count; i++) { 688 dst[i] = val; 689 } 690 } 691 } 692} 693 694 695static void 696put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 697 const GLint x[], const GLint y[], const void *values, 698 const GLubyte *mask) 699{ 700 /* treat 4*GLubyte as 1*GLuint */ 701 const GLuint *src = (const GLuint *) values; 702 GLuint i; 703 assert(rb->DataType == GL_UNSIGNED_BYTE); 704 for (i = 0; i < count; i++) { 705 if (!mask || mask[i]) { 706 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 707 *dst = src[i]; 708 } 709 } 710} 711 712 713static void 714put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 715 GLuint count, const GLint x[], const GLint y[], 716 const void *value, const GLubyte *mask) 717{ 718 /* treat 4*GLubyte as 1*GLuint */ 719 const GLuint val = *((const GLuint *) value); 720 GLuint i; 721 assert(rb->DataType == GL_UNSIGNED_BYTE); 722 for (i = 0; i < count; i++) { 723 if (!mask || mask[i]) { 724 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 725 *dst = val; 726 } 727 } 728} 729 730 731/********************************************************************** 732 * Functions for buffers of 4 X GLushort (or GLshort) values. 733 * Typically accum buffer. 734 */ 735 736static void * 737get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 738 GLint x, GLint y) 739{ 740 if (!rb->Data) 741 return NULL; 742 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 743 return (GLushort *) rb->Data + 4 * (y * rb->Width + x); 744} 745 746 747static void 748get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 749 GLint x, GLint y, void *values) 750{ 751 const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x); 752 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 753 _mesa_memcpy(values, src, 4 * count * sizeof(GLshort)); 754} 755 756 757static void 758get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 759 const GLint x[], const GLint y[], void *values) 760{ 761 GLushort *dst = (GLushort *) values; 762 GLuint i; 763 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 764 for (i = 0; i < count; i++) { 765 const GLushort *src 766 = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 767 dst[i] = *src; 768 } 769} 770 771 772static void 773put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 774 GLint x, GLint y, const void *values, const GLubyte *mask) 775{ 776 const GLushort *src = (const GLushort *) values; 777 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 778 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 779 if (mask) { 780 GLuint i; 781 for (i = 0; i < count; i++) { 782 if (mask[i]) { 783 dst[i * 4 + 0] = src[i * 4 + 0]; 784 dst[i * 4 + 1] = src[i * 4 + 1]; 785 dst[i * 4 + 2] = src[i * 4 + 2]; 786 dst[i * 4 + 3] = src[i * 4 + 3]; 787 } 788 } 789 } 790 else { 791 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 792 } 793} 794 795 796static void 797put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 798 GLint x, GLint y, const void *values, const GLubyte *mask) 799{ 800 /* Put RGB values in RGBA buffer */ 801 const GLushort *src = (const GLushort *) values; 802 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 803 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 804 if (mask) { 805 GLuint i; 806 for (i = 0; i < count; i++) { 807 if (mask[i]) { 808 dst[i * 4 + 0] = src[i * 3 + 0]; 809 dst[i * 4 + 1] = src[i * 3 + 1]; 810 dst[i * 4 + 2] = src[i * 3 + 2]; 811 dst[i * 4 + 3] = 0xffff; 812 } 813 } 814 } 815 else { 816 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 817 } 818} 819 820 821static void 822put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 823 GLint x, GLint y, const void *value, const GLubyte *mask) 824{ 825 const GLushort val0 = ((const GLushort *) value)[0]; 826 const GLushort val1 = ((const GLushort *) value)[1]; 827 const GLushort val2 = ((const GLushort *) value)[2]; 828 const GLushort val3 = ((const GLushort *) value)[3]; 829 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 830 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 831 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 832 /* common case for clearing accum buffer */ 833 _mesa_bzero(dst, count * 4 * sizeof(GLushort)); 834 } 835 else { 836 GLuint i; 837 for (i = 0; i < count; i++) { 838 if (!mask || mask[i]) { 839 dst[i * 4 + 0] = val0; 840 dst[i * 4 + 1] = val1; 841 dst[i * 4 + 2] = val2; 842 dst[i * 4 + 3] = val3; 843 } 844 } 845 } 846} 847 848 849static void 850put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 851 const GLint x[], const GLint y[], const void *values, 852 const GLubyte *mask) 853{ 854 const GLushort *src = (const GLushort *) values; 855 GLuint i; 856 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 857 for (i = 0; i < count; i++) { 858 if (!mask || mask[i]) { 859 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 860 dst[0] = src[i * 4 + 0]; 861 dst[1] = src[i * 4 + 1]; 862 dst[2] = src[i * 4 + 2]; 863 dst[3] = src[i * 4 + 3]; 864 } 865 } 866} 867 868 869static void 870put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 871 GLuint count, const GLint x[], const GLint y[], 872 const void *value, const GLubyte *mask) 873{ 874 const GLushort val0 = ((const GLushort *) value)[0]; 875 const GLushort val1 = ((const GLushort *) value)[1]; 876 const GLushort val2 = ((const GLushort *) value)[2]; 877 const GLushort val3 = ((const GLushort *) value)[3]; 878 GLuint i; 879 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 880 for (i = 0; i < count; i++) { 881 if (!mask || mask[i]) { 882 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 883 dst[0] = val0; 884 dst[1] = val1; 885 dst[2] = val2; 886 dst[3] = val3; 887 } 888 } 889} 890 891 892 893/** 894 * This is a software fallback for the gl_renderbuffer->AllocStorage 895 * function. 896 * Device drivers will typically override this function for the buffers 897 * which it manages (typically color buffers, Z and stencil). 898 * Other buffers (like software accumulation and aux buffers) which the driver 899 * doesn't manage can be handled with this function. 900 * 901 * This one multi-purpose function can allocate stencil, depth, accum, color 902 * or color-index buffers! 903 * 904 * This function also plugs in the appropriate GetPointer, Get/PutRow and 905 * Get/PutValues functions. 906 */ 907static GLboolean 908soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 909 GLenum internalFormat, GLuint width, GLuint height) 910{ 911 GLuint pixelSize; 912 913 switch (internalFormat) { 914 case GL_RGB: 915 case GL_R3_G3_B2: 916 case GL_RGB4: 917 case GL_RGB5: 918 case GL_RGB8: 919 case GL_RGB10: 920 case GL_RGB12: 921 case GL_RGB16: 922 rb->_BaseFormat = GL_RGB; 923 rb->DataType = GL_UNSIGNED_BYTE; 924 rb->GetPointer = get_pointer_ubyte3; 925 rb->GetRow = get_row_ubyte3; 926 rb->GetValues = get_values_ubyte3; 927 rb->PutRow = put_row_ubyte3; 928 rb->PutRowRGB = put_row_rgb_ubyte3; 929 rb->PutMonoRow = put_mono_row_ubyte3; 930 rb->PutValues = put_values_ubyte3; 931 rb->PutMonoValues = put_mono_values_ubyte3; 932 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 933 rb->ComponentSizes[1] = 8 * sizeof(GLubyte); 934 rb->ComponentSizes[2] = 8 * sizeof(GLubyte); 935 rb->ComponentSizes[3] = 0; 936 pixelSize = 3 * sizeof(GLubyte); 937 break; 938 case GL_RGBA: 939 case GL_RGBA2: 940 case GL_RGBA4: 941 case GL_RGB5_A1: 942 case GL_RGBA8: 943 rb->_BaseFormat = GL_RGBA; 944 rb->DataType = GL_UNSIGNED_BYTE; 945 rb->GetPointer = get_pointer_ubyte4; 946 rb->GetRow = get_row_ubyte4; 947 rb->GetValues = get_values_ubyte4; 948 rb->PutRow = put_row_ubyte4; 949 rb->PutRowRGB = put_row_rgb_ubyte4; 950 rb->PutMonoRow = put_mono_row_ubyte4; 951 rb->PutValues = put_values_ubyte4; 952 rb->PutMonoValues = put_mono_values_ubyte4; 953 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 954 rb->ComponentSizes[1] = 8 * sizeof(GLubyte); 955 rb->ComponentSizes[2] = 8 * sizeof(GLubyte); 956 rb->ComponentSizes[3] = 8 * sizeof(GLubyte); 957 pixelSize = 4 * sizeof(GLubyte); 958 break; 959 case GL_RGB10_A2: 960 case GL_RGBA12: 961 case GL_RGBA16: 962 rb->_BaseFormat = GL_RGBA; 963 rb->DataType = GL_UNSIGNED_SHORT; 964 rb->GetPointer = get_pointer_ushort4; 965 rb->GetRow = get_row_ushort4; 966 rb->GetValues = get_values_ushort4; 967 rb->PutRow = put_row_ushort4; 968 rb->PutRowRGB = put_row_rgb_ushort4; 969 rb->PutMonoRow = put_mono_row_ushort4; 970 rb->PutValues = put_values_ushort4; 971 rb->PutMonoValues = put_mono_values_ushort4; 972 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 973 rb->ComponentSizes[1] = 8 * sizeof(GLushort); 974 rb->ComponentSizes[2] = 8 * sizeof(GLushort); 975 rb->ComponentSizes[3] = 8 * sizeof(GLushort); 976 pixelSize = 4 * sizeof(GLushort); 977 break; 978#if 00 979 case ALPHA8: 980 rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */ 981 rb->DataType = GL_UNSIGNED_BYTE; 982 rb->GetPointer = get_pointer_alpha8; 983 rb->GetRow = get_row_alpha8; 984 rb->GetValues = get_values_alpha8; 985 rb->PutRow = put_row_alpha8; 986 rb->PutRowRGB = NULL; 987 rb->PutMonoRow = put_mono_row_alpha8; 988 rb->PutValues = put_values_alpha8; 989 rb->PutMonoValues = put_mono_values_alpha8; 990 rb->ComponentSizes[0] = 0; /*red*/ 991 rb->ComponentSizes[1] = 0; /*green*/ 992 rb->ComponentSizes[2] = 0; /*blue*/ 993 rb->ComponentSizes[3] = 8 * sizeof(GLubyte); 994 pixelSize = sizeof(GLubyte); 995 break; 996#endif 997 case GL_STENCIL_INDEX: 998 case GL_STENCIL_INDEX1_EXT: 999 case GL_STENCIL_INDEX4_EXT: 1000 case GL_STENCIL_INDEX8_EXT: 1001 rb->_BaseFormat = GL_STENCIL_INDEX; 1002 rb->DataType = GL_UNSIGNED_BYTE; 1003 rb->GetPointer = get_pointer_ubyte; 1004 rb->GetRow = get_row_ubyte; 1005 rb->GetValues = get_values_ubyte; 1006 rb->PutRow = put_row_ubyte; 1007 rb->PutRowRGB = NULL; 1008 rb->PutMonoRow = put_mono_row_ubyte; 1009 rb->PutValues = put_values_ubyte; 1010 rb->PutMonoValues = put_mono_values_ubyte; 1011 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 1012 pixelSize = sizeof(GLubyte); 1013 break; 1014 case GL_STENCIL_INDEX16_EXT: 1015 rb->_BaseFormat = GL_STENCIL_INDEX; 1016 rb->DataType = GL_UNSIGNED_SHORT; 1017 rb->GetPointer = get_pointer_ushort; 1018 rb->GetRow = get_row_ushort; 1019 rb->GetValues = get_values_ushort; 1020 rb->PutRow = put_row_ushort; 1021 rb->PutRowRGB = NULL; 1022 rb->PutMonoRow = put_mono_row_ushort; 1023 rb->PutValues = put_values_ushort; 1024 rb->PutMonoValues = put_mono_values_ushort; 1025 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1026 pixelSize = sizeof(GLushort); 1027 break; 1028 case GL_DEPTH_COMPONENT: 1029 case GL_DEPTH_COMPONENT16: 1030 rb->_BaseFormat = GL_DEPTH_COMPONENT; 1031 rb->DataType = GL_UNSIGNED_SHORT; 1032 rb->GetPointer = get_pointer_ushort; 1033 rb->GetRow = get_row_ushort; 1034 rb->GetValues = get_values_ushort; 1035 rb->PutRow = put_row_ushort; 1036 rb->PutRowRGB = NULL; 1037 rb->PutMonoRow = put_mono_row_ushort; 1038 rb->PutValues = put_values_ushort; 1039 rb->PutMonoValues = put_mono_values_ushort; 1040 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1041 pixelSize = sizeof(GLushort); 1042 break; 1043 case GL_DEPTH_COMPONENT24: 1044 case GL_DEPTH_COMPONENT32: 1045 rb->_BaseFormat = GL_DEPTH_COMPONENT; 1046 rb->DataType = GL_UNSIGNED_INT; 1047 rb->GetPointer = get_pointer_uint; 1048 rb->GetRow = get_row_uint; 1049 rb->GetValues = get_values_uint; 1050 rb->PutRow = put_row_uint; 1051 rb->PutRowRGB = NULL; 1052 rb->PutMonoRow = put_mono_row_uint; 1053 rb->PutValues = put_values_uint; 1054 rb->PutMonoValues = put_mono_values_uint; 1055 rb->ComponentSizes[0] = 8 * sizeof(GLuint); 1056 pixelSize = sizeof(GLuint); 1057 break; 1058 case GL_COLOR_INDEX8_EXT: 1059 rb->_BaseFormat = GL_COLOR_INDEX; 1060 rb->DataType = GL_UNSIGNED_BYTE; 1061 rb->GetPointer = get_pointer_ubyte; 1062 rb->GetRow = get_row_ubyte; 1063 rb->GetValues = get_values_ubyte; 1064 rb->PutRow = put_row_ubyte; 1065 rb->PutRowRGB = NULL; 1066 rb->PutMonoRow = put_mono_row_ubyte; 1067 rb->PutValues = put_values_ubyte; 1068 rb->PutMonoValues = put_mono_values_ubyte; 1069 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 1070 pixelSize = sizeof(GLubyte); 1071 break; 1072 case GL_COLOR_INDEX16_EXT: 1073 rb->_BaseFormat = GL_COLOR_INDEX; 1074 rb->DataType = GL_UNSIGNED_SHORT; 1075 rb->GetPointer = get_pointer_ushort; 1076 rb->GetRow = get_row_ushort; 1077 rb->GetValues = get_values_ushort; 1078 rb->PutRow = put_row_ushort; 1079 rb->PutRowRGB = NULL; 1080 rb->PutMonoRow = put_mono_row_ushort; 1081 rb->PutValues = put_values_ushort; 1082 rb->PutMonoValues = put_mono_values_ushort; 1083 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1084 pixelSize = sizeof(GLushort); 1085 break; 1086 case COLOR_INDEX32: 1087 rb->_BaseFormat = GL_COLOR_INDEX; 1088 rb->DataType = GL_UNSIGNED_INT; 1089 rb->GetPointer = get_pointer_uint; 1090 rb->GetRow = get_row_uint; 1091 rb->GetValues = get_values_uint; 1092 rb->PutRow = put_row_uint; 1093 rb->PutRowRGB = NULL; 1094 rb->PutMonoRow = put_mono_row_uint; 1095 rb->PutValues = put_values_uint; 1096 rb->PutMonoValues = put_mono_values_uint; 1097 rb->ComponentSizes[0] = 8 * sizeof(GLuint); 1098 pixelSize = sizeof(GLuint); 1099 break; 1100 default: 1101 _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage"); 1102 return GL_FALSE; 1103 } 1104 1105 ASSERT(rb->DataType); 1106 ASSERT(rb->GetPointer); 1107 ASSERT(rb->GetRow); 1108 ASSERT(rb->GetValues); 1109 ASSERT(rb->PutRow); 1110 ASSERT(rb->PutMonoRow); 1111 ASSERT(rb->PutValues); 1112 ASSERT(rb->PutMonoValues); 1113 ASSERT(rb->ComponentSizes[0] > 0); 1114 1115 /* free old buffer storage */ 1116 if (rb->Data) 1117 _mesa_free(rb->Data); 1118 1119 /* allocate new buffer storage */ 1120 rb->Data = _mesa_malloc(width * height * pixelSize); 1121 if (rb->Data == NULL) { 1122 rb->Width = 0; 1123 rb->Height = 0; 1124 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation"); 1125 return GL_FALSE; 1126 } 1127 1128 rb->Width = width; 1129 rb->Height = height; 1130 rb->InternalFormat = internalFormat; 1131 1132 return GL_TRUE; 1133} 1134 1135 1136/**********************************************************************/ 1137/**********************************************************************/ 1138/**********************************************************************/ 1139 1140 1141/** 1142 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with 1143 * an alpha channel. The RGB buffer can be hardware-based. 1144 * We basically wrap the RGB buffer. When PutRow is called (for example), 1145 * we store the alpha values in this buffer, then pass on the PutRow call 1146 * to the wrapped RGB buffer. 1147 */ 1148struct alpha_renderbuffer 1149{ 1150 struct gl_renderbuffer Base; /* the alpha buffer */ 1151 struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */ 1152}; 1153 1154 1155static GLboolean 1156alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1157 GLenum internalFormat, GLuint width, GLuint height) 1158{ 1159 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1160 1161 /* first, pass the call to the wrapped RGB buffer */ 1162 if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat, 1163 width, height)) { 1164 return GL_FALSE; 1165 } 1166 1167 /* next, resize my alpha buffer */ 1168 if (arb->Base.Data) { 1169 _mesa_free(arb->Base.Data); 1170 } 1171 1172 arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte)); 1173 if (arb->Base.Data == NULL) { 1174 arb->Base.Width = 0; 1175 arb->Base.Height = 0; 1176 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 1177 return GL_FALSE; 1178 } 1179 1180 arb->Base.Width = width; 1181 arb->Base.Height = height; 1182 arb->Base.InternalFormat = internalFormat; 1183 1184 return GL_TRUE; 1185} 1186 1187 1188/** 1189 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 1190 */ 1191static void 1192delete_renderbuffer_alpha8(struct gl_renderbuffer *rb) 1193{ 1194 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1195 if (arb->Base.Data) { 1196 _mesa_free(arb->Base.Data); 1197 } 1198 assert(arb->RGBbuffer); 1199 arb->RGBbuffer->Delete(arb->RGBbuffer); 1200 arb->RGBbuffer = NULL; 1201 _mesa_free(arb); 1202} 1203 1204 1205static void * 1206get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1207 GLint x, GLint y) 1208{ 1209 return NULL; /* don't allow direct access! */ 1210} 1211 1212 1213static void 1214get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1215 GLint x, GLint y, void *values) 1216{ 1217 /* NOTE: 'values' is RGBA format! */ 1218 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1219 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; 1220 GLubyte *dst = (GLubyte *) values; 1221 GLuint i; 1222 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1223 /* first, pass the call to the wrapped RGB buffer */ 1224 arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values); 1225 /* second, fill in alpha values from this buffer! */ 1226 for (i = 0; i < count; i++) { 1227 dst[i * 4 + 3] = src[i]; 1228 } 1229} 1230 1231 1232static void 1233get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1234 const GLint x[], const GLint y[], void *values) 1235{ 1236 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1237 GLubyte *dst = (GLubyte *) values; 1238 GLuint i; 1239 assert(rb->DataType == GL_UNSIGNED_BYTE); 1240 /* first, pass the call to the wrapped RGB buffer */ 1241 arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values); 1242 /* second, fill in alpha values from this buffer! */ 1243 for (i = 0; i < count; i++) { 1244 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1245 dst[i * 4 + 3] = *src; 1246 } 1247} 1248 1249 1250static void 1251put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1252 GLint x, GLint y, const void *values, const GLubyte *mask) 1253{ 1254 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1255 const GLubyte *src = (const GLubyte *) values; 1256 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1257 GLuint i; 1258 assert(rb->DataType == GL_UNSIGNED_BYTE); 1259 /* first, pass the call to the wrapped RGB buffer */ 1260 arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask); 1261 /* second, store alpha in our buffer */ 1262 for (i = 0; i < count; i++) { 1263 if (!mask || mask[i]) { 1264 dst[i] = src[i * 4 + 3]; 1265 } 1266 } 1267} 1268 1269 1270static void 1271put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1272 GLint x, GLint y, const void *values, const GLubyte *mask) 1273{ 1274 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1275 const GLubyte *src = (const GLubyte *) values; 1276 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1277 GLuint i; 1278 assert(rb->DataType == GL_UNSIGNED_BYTE); 1279 /* first, pass the call to the wrapped RGB buffer */ 1280 arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask); 1281 /* second, store alpha in our buffer */ 1282 for (i = 0; i < count; i++) { 1283 if (!mask || mask[i]) { 1284 dst[i] = src[i * 4 + 3]; 1285 } 1286 } 1287} 1288 1289 1290static void 1291put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1292 GLint x, GLint y, const void *value, const GLubyte *mask) 1293{ 1294 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1295 const GLubyte val = ((const GLubyte *) value)[3]; 1296 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1297 assert(rb->DataType == GL_UNSIGNED_BYTE); 1298 /* first, pass the call to the wrapped RGB buffer */ 1299 arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask); 1300 /* second, store alpha in our buffer */ 1301 if (mask) { 1302 GLuint i; 1303 for (i = 0; i < count; i++) { 1304 if (mask[i]) { 1305 dst[i] = val; 1306 } 1307 } 1308 } 1309 else { 1310 _mesa_memset(dst, val, count); 1311 } 1312} 1313 1314 1315static void 1316put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1317 const GLint x[], const GLint y[], 1318 const void *values, const GLubyte *mask) 1319{ 1320 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1321 const GLubyte *src = (const GLubyte *) values; 1322 GLuint i; 1323 assert(rb->DataType == GL_UNSIGNED_BYTE); 1324 /* first, pass the call to the wrapped RGB buffer */ 1325 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask); 1326 /* second, store alpha in our buffer */ 1327 for (i = 0; i < count; i++) { 1328 if (!mask || mask[i]) { 1329 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1330 *dst = src[i * 4 + 3]; 1331 } 1332 } 1333} 1334 1335 1336static void 1337put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1338 GLuint count, const GLint x[], const GLint y[], 1339 const void *value, const GLubyte *mask) 1340{ 1341 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1342 const GLubyte val = ((const GLubyte *) value)[3]; 1343 GLuint i; 1344 assert(rb->DataType == GL_UNSIGNED_BYTE); 1345 /* first, pass the call to the wrapped RGB buffer */ 1346 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask); 1347 /* second, store alpha in our buffer */ 1348 for (i = 0; i < count; i++) { 1349 if (!mask || mask[i]) { 1350 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1351 *dst = val; 1352 } 1353 } 1354} 1355 1356 1357 1358/**********************************************************************/ 1359/**********************************************************************/ 1360/**********************************************************************/ 1361 1362 1363/** 1364 * Default GetPointer routine. Always return NULL to indicate that 1365 * direct buffer access is not supported. 1366 */ 1367static void * 1368nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 1369{ 1370 return NULL; 1371} 1372 1373 1374/** 1375 * Initialize the fields of a gl_renderbuffer to default values. 1376 */ 1377void 1378_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 1379{ 1380 rb->Name = name; 1381 rb->RefCount = 1; 1382 rb->Delete = _mesa_delete_renderbuffer; 1383 1384 /* The rest of these should be set later by the caller of this function or 1385 * the AllocStorage method: 1386 */ 1387 rb->AllocStorage = NULL; 1388 1389 rb->Width = 0; 1390 rb->Height = 0; 1391 rb->InternalFormat = GL_NONE; 1392 rb->_BaseFormat = GL_NONE; 1393 rb->DataType = GL_NONE; 1394 rb->ComponentSizes[0] = 0; 1395 rb->ComponentSizes[1] = 0; 1396 rb->ComponentSizes[2] = 0; 1397 rb->ComponentSizes[3] = 0; 1398 rb->Data = NULL; 1399 1400 rb->GetPointer = nop_get_pointer; 1401 rb->GetRow = NULL; 1402 rb->GetValues = NULL; 1403 rb->PutRow = NULL; 1404 rb->PutRowRGB = NULL; 1405 rb->PutMonoRow = NULL; 1406 rb->PutValues = NULL; 1407 rb->PutMonoValues = NULL; 1408} 1409 1410 1411/** 1412 * Allocate a new gl_renderbuffer object. This can be used for user-created 1413 * renderbuffers or window-system renderbuffers. 1414 */ 1415struct gl_renderbuffer * 1416_mesa_new_renderbuffer(GLcontext *ctx, GLuint name) 1417{ 1418 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 1419 if (rb) { 1420 _mesa_init_renderbuffer(rb, name); 1421 } 1422 return rb; 1423} 1424 1425 1426/** 1427 * Delete a gl_framebuffer. 1428 * This is the default function for framebuffer->Delete(). 1429 */ 1430void 1431_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 1432{ 1433 if (rb->Data) { 1434 _mesa_free(rb->Data); 1435 } 1436 _mesa_free(rb); 1437} 1438 1439 1440/** 1441 * Allocate a software-based renderbuffer. This is called via the 1442 * ctx->Driver.NewRenderbuffer() function when the user creates a new 1443 * renderbuffer. 1444 * This would not be used for hardware-based renderbuffers. 1445 */ 1446struct gl_renderbuffer * 1447_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name) 1448{ 1449 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 1450 if (rb) { 1451 rb->AllocStorage = soft_renderbuffer_storage; 1452 /* Normally, one would setup the PutRow, GetRow, etc functions here. 1453 * But we're doing that in the soft_renderbuffer_storage() function 1454 * instead. 1455 */ 1456 } 1457 return rb; 1458} 1459 1460 1461/** 1462 * Add software-based color renderbuffers to the given framebuffer. 1463 * This is a helper routine for device drivers when creating a 1464 * window system framebuffer (not a user-created render/framebuffer). 1465 * Once this function is called, you can basically forget about this 1466 * renderbuffer; core Mesa will handle all the buffer management and 1467 * rendering! 1468 */ 1469GLboolean 1470_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1471 GLuint rgbBits, GLuint alphaBits, 1472 GLboolean frontLeft, GLboolean backLeft, 1473 GLboolean frontRight, GLboolean backRight) 1474{ 1475 GLuint b; 1476 1477 if (rgbBits > 16 || alphaBits > 16) { 1478 _mesa_problem(ctx, 1479 "Unsupported bit depth in _mesa_add_color_renderbuffers"); 1480 return GL_FALSE; 1481 } 1482 1483 assert(MAX_COLOR_ATTACHMENTS >= 4); 1484 1485 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1486 struct gl_renderbuffer *rb; 1487 1488 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1489 continue; 1490 else if (b == BUFFER_BACK_LEFT && !backLeft) 1491 continue; 1492 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1493 continue; 1494 else if (b == BUFFER_BACK_RIGHT && !backRight) 1495 continue; 1496 1497 assert(fb->Attachment[b].Renderbuffer == NULL); 1498 1499 rb = _mesa_new_renderbuffer(ctx, 0); 1500 if (!rb) { 1501 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 1502 return GL_FALSE; 1503 } 1504 1505 if (rgbBits <= 8) { 1506 if (alphaBits) 1507 rb->InternalFormat = GL_RGBA8; 1508 else 1509 rb->InternalFormat = GL_RGB8; 1510 } 1511 else { 1512 assert(rgbBits <= 16); 1513 if (alphaBits) 1514 rb->InternalFormat = GL_RGBA16; 1515 else 1516 rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */ 1517 } 1518 1519 rb->AllocStorage = soft_renderbuffer_storage; 1520 _mesa_add_renderbuffer(fb, b, rb); 1521 } 1522 1523 return GL_TRUE; 1524} 1525 1526 1527/** 1528 * Add software-based color index renderbuffers to the given framebuffer. 1529 * This is a helper routine for device drivers when creating a 1530 * window system framebuffer (not a user-created render/framebuffer). 1531 * Once this function is called, you can basically forget about this 1532 * renderbuffer; core Mesa will handle all the buffer management and 1533 * rendering! 1534 */ 1535GLboolean 1536_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1537 GLuint indexBits, 1538 GLboolean frontLeft, GLboolean backLeft, 1539 GLboolean frontRight, GLboolean backRight) 1540{ 1541 GLuint b; 1542 1543 if (indexBits > 8) { 1544 _mesa_problem(ctx, 1545 "Unsupported bit depth in _mesa_add_color_index_renderbuffers"); 1546 return GL_FALSE; 1547 } 1548 1549 assert(MAX_COLOR_ATTACHMENTS >= 4); 1550 1551 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1552 struct gl_renderbuffer *rb; 1553 1554 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1555 continue; 1556 else if (b == BUFFER_BACK_LEFT && !backLeft) 1557 continue; 1558 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1559 continue; 1560 else if (b == BUFFER_BACK_RIGHT && !backRight) 1561 continue; 1562 1563 assert(fb->Attachment[b].Renderbuffer == NULL); 1564 1565 rb = _mesa_new_renderbuffer(ctx, 0); 1566 if (!rb) { 1567 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 1568 return GL_FALSE; 1569 } 1570 1571 if (indexBits <= 8) { 1572 /* only support GLuint for now */ 1573 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/ 1574 rb->InternalFormat = COLOR_INDEX32; 1575 } 1576 else { 1577 rb->InternalFormat = COLOR_INDEX32; 1578 } 1579 rb->AllocStorage = soft_renderbuffer_storage; 1580 _mesa_add_renderbuffer(fb, b, rb); 1581 } 1582 1583 return GL_TRUE; 1584} 1585 1586 1587/** 1588 * Add software-based alpha renderbuffers to the given framebuffer. 1589 * This is a helper routine for device drivers when creating a 1590 * window system framebuffer (not a user-created render/framebuffer). 1591 * Once this function is called, you can basically forget about this 1592 * renderbuffer; core Mesa will handle all the buffer management and 1593 * rendering! 1594 */ 1595GLboolean 1596_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1597 GLuint alphaBits, 1598 GLboolean frontLeft, GLboolean backLeft, 1599 GLboolean frontRight, GLboolean backRight) 1600{ 1601 GLuint b; 1602 1603 /* for window system framebuffers only! */ 1604 assert(fb->Name == 0); 1605 1606 if (alphaBits > 8) { 1607 _mesa_problem(ctx, 1608 "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 1609 return GL_FALSE; 1610 } 1611 1612 assert(MAX_COLOR_ATTACHMENTS >= 4); 1613 1614 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1615 struct alpha_renderbuffer *arb; 1616 1617 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1618 continue; 1619 else if (b == BUFFER_BACK_LEFT && !backLeft) 1620 continue; 1621 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1622 continue; 1623 else if (b == BUFFER_BACK_RIGHT && !backRight) 1624 continue; 1625 1626 /* the RGB buffer to wrap must already exist!! */ 1627 assert(fb->Attachment[b].Renderbuffer); 1628 1629 /* only GLubyte supported for now */ 1630 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 1631 1632 arb = CALLOC_STRUCT(alpha_renderbuffer); 1633 if (!arb) { 1634 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 1635 return GL_FALSE; 1636 } 1637 1638 _mesa_init_renderbuffer(&arb->Base, 0); 1639 1640 /* wrap the RGB buffer */ 1641 arb->RGBbuffer = fb->Attachment[b].Renderbuffer; 1642 1643 /* plug in my functions */ 1644 arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat; 1645 arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat; 1646 arb->Base.DataType = arb->RGBbuffer->DataType; 1647 arb->Base.AllocStorage = alloc_storage_alpha8; 1648 arb->Base.Delete = delete_renderbuffer_alpha8; 1649 arb->Base.GetPointer = get_pointer_alpha8; 1650 arb->Base.GetRow = get_row_alpha8; 1651 arb->Base.GetValues = get_values_alpha8; 1652 arb->Base.PutRow = put_row_alpha8; 1653 arb->Base.PutRowRGB = put_row_rgb_alpha8; 1654 arb->Base.PutMonoRow = put_mono_row_alpha8; 1655 arb->Base.PutValues = put_values_alpha8; 1656 arb->Base.PutMonoValues = put_mono_values_alpha8; 1657 1658 /* clear the pointer to avoid assertion/sanity check failure later */ 1659 fb->Attachment[b].Renderbuffer = NULL; 1660 1661 /* plug the alpha renderbuffer into the colorbuffer attachment */ 1662 _mesa_add_renderbuffer(fb, b, &arb->Base); 1663 } 1664 1665 return GL_TRUE; 1666} 1667 1668 1669/** 1670 * Add a software-based depth renderbuffer to the given framebuffer. 1671 * This is a helper routine for device drivers when creating a 1672 * window system framebuffer (not a user-created render/framebuffer). 1673 * Once this function is called, you can basically forget about this 1674 * renderbuffer; core Mesa will handle all the buffer management and 1675 * rendering! 1676 */ 1677GLboolean 1678_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1679 GLuint depthBits) 1680{ 1681 struct gl_renderbuffer *rb; 1682 1683 if (depthBits > 32) { 1684 _mesa_problem(ctx, 1685 "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 1686 return GL_FALSE; 1687 } 1688 1689 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 1690 1691 rb = _mesa_new_renderbuffer(ctx, 0); 1692 if (!rb) { 1693 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 1694 return GL_FALSE; 1695 } 1696 1697 if (depthBits <= 16) { 1698 rb->InternalFormat = GL_DEPTH_COMPONENT16; 1699 } 1700 else { 1701 rb->InternalFormat = GL_DEPTH_COMPONENT32; 1702 } 1703 1704 rb->AllocStorage = soft_renderbuffer_storage; 1705 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 1706 1707 return GL_TRUE; 1708} 1709 1710 1711/** 1712 * Add a software-based stencil renderbuffer to the given framebuffer. 1713 * This is a helper routine for device drivers when creating a 1714 * window system framebuffer (not a user-created render/framebuffer). 1715 * Once this function is called, you can basically forget about this 1716 * renderbuffer; core Mesa will handle all the buffer management and 1717 * rendering! 1718 */ 1719GLboolean 1720_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1721 GLuint stencilBits) 1722{ 1723 struct gl_renderbuffer *rb; 1724 1725 if (stencilBits > 16) { 1726 _mesa_problem(ctx, 1727 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 1728 return GL_FALSE; 1729 } 1730 1731 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 1732 1733 rb = _mesa_new_renderbuffer(ctx, 0); 1734 if (!rb) { 1735 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 1736 return GL_FALSE; 1737 } 1738 1739 if (stencilBits <= 8) { 1740 rb->InternalFormat = GL_STENCIL_INDEX8_EXT; 1741 } 1742 else { 1743 /* not really supported (see s_stencil.c code) */ 1744 rb->InternalFormat = GL_STENCIL_INDEX16_EXT; 1745 } 1746 1747 rb->AllocStorage = soft_renderbuffer_storage; 1748 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 1749 1750 return GL_TRUE; 1751} 1752 1753 1754/** 1755 * Add a software-based accumulation renderbuffer to the given framebuffer. 1756 * This is a helper routine for device drivers when creating a 1757 * window system framebuffer (not a user-created render/framebuffer). 1758 * Once this function is called, you can basically forget about this 1759 * renderbuffer; core Mesa will handle all the buffer management and 1760 * rendering! 1761 */ 1762GLboolean 1763_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1764 GLuint redBits, GLuint greenBits, 1765 GLuint blueBits, GLuint alphaBits) 1766{ 1767 struct gl_renderbuffer *rb; 1768 1769 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 1770 _mesa_problem(ctx, 1771 "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 1772 return GL_FALSE; 1773 } 1774 1775 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 1776 1777 rb = _mesa_new_renderbuffer(ctx, 0); 1778 if (!rb) { 1779 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 1780 return GL_FALSE; 1781 } 1782 1783 rb->InternalFormat = GL_RGBA16; 1784 rb->AllocStorage = soft_renderbuffer_storage; 1785 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 1786 1787 return GL_TRUE; 1788} 1789 1790 1791 1792/** 1793 * Add a software-based accumulation renderbuffer to the given framebuffer. 1794 * This is a helper routine for device drivers when creating a 1795 * window system framebuffer (not a user-created render/framebuffer). 1796 * Once this function is called, you can basically forget about this 1797 * renderbuffer; core Mesa will handle all the buffer management and 1798 * rendering! 1799 * 1800 * NOTE: color-index aux buffers not supported. 1801 */ 1802GLboolean 1803_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1804 GLuint colorBits, GLuint numBuffers) 1805{ 1806 GLuint i; 1807 1808 if (colorBits > 16) { 1809 _mesa_problem(ctx, 1810 "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 1811 return GL_FALSE; 1812 } 1813 1814 assert(numBuffers < MAX_AUX_BUFFERS); 1815 1816 for (i = 0; i < numBuffers; i++) { 1817 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 1818 1819 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 1820 1821 if (!rb) { 1822 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 1823 return GL_FALSE; 1824 } 1825 1826 if (colorBits <= 8) { 1827 rb->InternalFormat = GL_RGBA8; 1828 } 1829 else { 1830 rb->InternalFormat = GL_RGBA16; 1831 } 1832 1833 rb->AllocStorage = soft_renderbuffer_storage; 1834 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 1835 } 1836 return GL_TRUE; 1837} 1838 1839 1840/** 1841 * Create/attach software-based renderbuffers to the given framebuffer. 1842 * This is a helper routine for device drivers. Drivers can just as well 1843 * call the individual _mesa_add_*_renderbuffer() routines directly. 1844 */ 1845void 1846_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 1847 GLboolean color, 1848 GLboolean depth, 1849 GLboolean stencil, 1850 GLboolean accum, 1851 GLboolean alpha, 1852 GLboolean aux) 1853{ 1854 GLboolean frontLeft = GL_TRUE; 1855 GLboolean backLeft = fb->Visual.doubleBufferMode; 1856 GLboolean frontRight = fb->Visual.stereoMode; 1857 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 1858 1859 if (color) { 1860 if (fb->Visual.rgbMode) { 1861 assert(fb->Visual.redBits == fb->Visual.greenBits); 1862 assert(fb->Visual.redBits == fb->Visual.blueBits); 1863 _mesa_add_color_renderbuffers(NULL, fb, 1864 fb->Visual.redBits, 1865 fb->Visual.alphaBits, 1866 frontLeft, backLeft, 1867 frontRight, backRight); 1868 } 1869 else { 1870 _mesa_add_color_index_renderbuffers(NULL, fb, 1871 fb->Visual.indexBits, 1872 frontLeft, backLeft, 1873 frontRight, backRight); 1874 } 1875 } 1876 1877 if (depth) { 1878 assert(fb->Visual.depthBits > 0); 1879 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 1880 } 1881 1882 if (stencil) { 1883 assert(fb->Visual.stencilBits > 0); 1884 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 1885 } 1886 1887 if (accum) { 1888 assert(fb->Visual.rgbMode); 1889 assert(fb->Visual.accumRedBits > 0); 1890 assert(fb->Visual.accumGreenBits > 0); 1891 assert(fb->Visual.accumBlueBits > 0); 1892 _mesa_add_accum_renderbuffer(NULL, fb, 1893 fb->Visual.accumRedBits, 1894 fb->Visual.accumGreenBits, 1895 fb->Visual.accumBlueBits, 1896 fb->Visual.accumAlphaBits); 1897 } 1898 1899 if (aux) { 1900 assert(fb->Visual.rgbMode); 1901 assert(fb->Visual.numAuxBuffers > 0); 1902 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 1903 fb->Visual.numAuxBuffers); 1904 } 1905 1906 if (alpha) { 1907 assert(fb->Visual.rgbMode); 1908 assert(fb->Visual.alphaBits > 0); 1909 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 1910 frontLeft, backLeft, 1911 frontRight, backRight); 1912 } 1913 1914#if 0 1915 if (multisample) { 1916 /* maybe someday */ 1917 } 1918#endif 1919} 1920 1921 1922/** 1923 * Attach a renderbuffer to a framebuffer. 1924 */ 1925void 1926_mesa_add_renderbuffer(struct gl_framebuffer *fb, 1927 GLuint bufferName, struct gl_renderbuffer *rb) 1928{ 1929 assert(fb); 1930 assert(rb); 1931#if 00 1932 /* there should be no previous renderbuffer on this attachment point! */ 1933 assert(fb->Attachment[bufferName].Renderbuffer == NULL); 1934#endif 1935 assert(bufferName < BUFFER_COUNT); 1936 1937 /* winsys vs. user-created buffer cross check */ 1938 if (fb->Name) { 1939 assert(rb->Name); 1940 } 1941 else { 1942 assert(!rb->Name); 1943 } 1944 1945 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 1946 fb->Attachment[bufferName].Complete = GL_TRUE; 1947 fb->Attachment[bufferName].Renderbuffer = rb; 1948} 1949