renderbuffer.c revision 8fadf8f900d4f979af50a86f98a3577946d93fd1
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 ASSERT(rb->DataType == GL_UNSIGNED_INT); 377 if (mask) { 378 GLuint i; 379 for (i = 0; i < count; i++) { 380 if (mask[i]) { 381 dst[i] = val; 382 } 383 } 384 } 385 else { 386 GLuint i; 387 for (i = 0; i < count; i++) { 388 dst[i] = val; 389 } 390 } 391} 392 393 394static void 395put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 396 const GLint x[], const GLint y[], const void *values, 397 const GLubyte *mask) 398{ 399 const GLuint *src = (const GLuint *) values; 400 GLuint i; 401 ASSERT(rb->DataType == GL_UNSIGNED_INT); 402 for (i = 0; i < count; i++) { 403 if (!mask || mask[i]) { 404 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 405 *dst = src[i]; 406 } 407 } 408} 409 410 411static void 412put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 413 const GLint x[], const GLint y[], const void *value, 414 const GLubyte *mask) 415{ 416 const GLuint val = *((const GLuint *) value); 417 GLuint i; 418 ASSERT(rb->DataType == GL_UNSIGNED_INT); 419 for (i = 0; i < count; i++) { 420 if (!mask || mask[i]) { 421 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 422 *dst = val; 423 } 424 } 425} 426 427 428/********************************************************************** 429 * Functions for buffers of 3 X GLubyte (or GLbyte) values. 430 * Typically color buffers. 431 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 432 * alpha values and return 255 for outgoing alpha values. 433 */ 434 435static void * 436get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 437 GLint x, GLint y) 438{ 439 /* No direct access since this buffer is RGB but caller will be 440 * treating it as if it were RGBA. 441 */ 442 return NULL; 443} 444 445 446static void 447get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 448 GLint x, GLint y, void *values) 449{ 450 const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x); 451 GLubyte *dst = (GLubyte *) values; 452 GLuint i; 453 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 454 for (i = 0; i < count; i++) { 455 dst[i * 4 + 0] = src[i * 3 + 0]; 456 dst[i * 4 + 1] = src[i * 3 + 1]; 457 dst[i * 4 + 2] = src[i * 3 + 2]; 458 dst[i * 4 + 3] = 255; 459 } 460} 461 462 463static void 464get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 465 const GLint x[], const GLint y[], void *values) 466{ 467 GLubyte *dst = (GLubyte *) values; 468 GLuint i; 469 assert(rb->DataType == GL_UNSIGNED_BYTE); 470 for (i = 0; i < count; i++) { 471 const GLubyte *src 472 = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 473 dst[i * 4 + 0] = src[0]; 474 dst[i * 4 + 1] = src[1]; 475 dst[i * 4 + 2] = src[2]; 476 dst[i * 4 + 3] = 255; 477 } 478} 479 480 481static void 482put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 483 GLint x, GLint y, const void *values, const GLubyte *mask) 484{ 485 /* note: incoming values are RGB+A! */ 486 const GLubyte *src = (const GLubyte *) values; 487 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 488 GLuint i; 489 assert(rb->DataType == GL_UNSIGNED_BYTE); 490 for (i = 0; i < count; i++) { 491 if (!mask || mask[i]) { 492 dst[i * 3 + 0] = src[i * 4 + 0]; 493 dst[i * 3 + 1] = src[i * 4 + 1]; 494 dst[i * 3 + 2] = src[i * 4 + 2]; 495 } 496 } 497} 498 499 500static void 501put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 502 GLint x, GLint y, const void *values, const GLubyte *mask) 503{ 504 /* note: incoming values are RGB+A! */ 505 const GLubyte *src = (const GLubyte *) values; 506 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 507 GLuint i; 508 assert(rb->DataType == GL_UNSIGNED_BYTE); 509 for (i = 0; i < count; i++) { 510 if (!mask || mask[i]) { 511 dst[i * 3 + 0] = src[i * 3 + 0]; 512 dst[i * 3 + 1] = src[i * 3 + 1]; 513 dst[i * 3 + 2] = src[i * 3 + 2]; 514 } 515 } 516} 517 518 519static void 520put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 521 GLint x, GLint y, const void *value, const GLubyte *mask) 522{ 523 /* note: incoming value is RGB+A! */ 524 const GLubyte val0 = ((const GLubyte *) value)[0]; 525 const GLubyte val1 = ((const GLubyte *) value)[1]; 526 const GLubyte val2 = ((const GLubyte *) value)[2]; 527 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 528 assert(rb->DataType == GL_UNSIGNED_BYTE); 529 if (!mask && val0 == val1 && val1 == val2) { 530 /* optimized case */ 531 _mesa_memset(dst, val0, 3 * count); 532 } 533 else { 534 GLuint i; 535 for (i = 0; i < count; i++) { 536 if (!mask || mask[i]) { 537 dst[i * 3 + 0] = val0; 538 dst[i * 3 + 1] = val1; 539 dst[i * 3 + 2] = val2; 540 } 541 } 542 } 543} 544 545 546static void 547put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 548 const GLint x[], const GLint y[], const void *values, 549 const GLubyte *mask) 550{ 551 /* note: incoming values are RGB+A! */ 552 const GLubyte *src = (const GLubyte *) values; 553 GLuint i; 554 assert(rb->DataType == GL_UNSIGNED_BYTE); 555 for (i = 0; i < count; i++) { 556 if (!mask || mask[i]) { 557 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 558 dst[0] = src[i * 4 + 0]; 559 dst[1] = src[i * 4 + 1]; 560 dst[2] = src[i * 4 + 2]; 561 } 562 } 563} 564 565 566static void 567put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 568 GLuint count, const GLint x[], const GLint y[], 569 const void *value, const GLubyte *mask) 570{ 571 /* note: incoming value is RGB+A! */ 572 const GLubyte val0 = ((const GLubyte *) value)[0]; 573 const GLubyte val1 = ((const GLubyte *) value)[1]; 574 const GLubyte val2 = ((const GLubyte *) value)[2]; 575 GLuint i; 576 assert(rb->DataType == GL_UNSIGNED_BYTE); 577 for (i = 0; i < count; i++) { 578 if (!mask || mask[i]) { 579 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 580 dst[0] = val0; 581 dst[1] = val1; 582 dst[2] = val2; 583 } 584 } 585} 586 587 588/********************************************************************** 589 * Functions for buffers of 4 X GLubyte (or GLbyte) values. 590 * Typically color buffers. 591 */ 592 593static void * 594get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 595 GLint x, GLint y) 596{ 597 if (!rb->Data) 598 return NULL; 599 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 600 return (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 601} 602 603 604static void 605get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 606 GLint x, GLint y, void *values) 607{ 608 const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x); 609 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 610 _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte)); 611} 612 613 614static void 615get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 616 const GLint x[], const GLint y[], void *values) 617{ 618 /* treat 4*GLubyte as 1*GLuint */ 619 GLuint *dst = (GLuint *) values; 620 GLuint i; 621 assert(rb->DataType == GL_UNSIGNED_BYTE); 622 for (i = 0; i < count; i++) { 623 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 624 dst[i] = *src; 625 } 626} 627 628 629static void 630put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 631 GLint x, GLint y, const void *values, const GLubyte *mask) 632{ 633 /* treat 4*GLubyte as 1*GLuint */ 634 const GLuint *src = (const GLuint *) values; 635 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 636 assert(rb->DataType == GL_UNSIGNED_BYTE); 637 if (mask) { 638 GLuint i; 639 for (i = 0; i < count; i++) { 640 if (mask[i]) { 641 dst[i] = src[i]; 642 } 643 } 644 } 645 else { 646 _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte)); 647 } 648} 649 650 651static void 652put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 653 GLint x, GLint y, const void *values, const GLubyte *mask) 654{ 655 /* Store RGB values in RGBA buffer */ 656 const GLubyte *src = (const GLubyte *) values; 657 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 658 GLuint i; 659 assert(rb->DataType == GL_UNSIGNED_BYTE); 660 for (i = 0; i < count; i++) { 661 if (!mask || mask[i]) { 662 dst[i * 4 + 0] = src[i * 3 + 0]; 663 dst[i * 4 + 1] = src[i * 3 + 1]; 664 dst[i * 4 + 2] = src[i * 3 + 2]; 665 dst[i * 4 + 3] = 0xff; 666 } 667 } 668} 669 670 671static void 672put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 673 GLint x, GLint y, const void *value, const GLubyte *mask) 674{ 675 /* treat 4*GLubyte as 1*GLuint */ 676 const GLuint val = *((const GLuint *) value); 677 GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 678 assert(rb->DataType == GL_UNSIGNED_BYTE); 679 if (!mask && val == 0) { 680 /* common case */ 681 _mesa_bzero(dst, count * 4 * sizeof(GLubyte)); 682 } 683 else { 684 /* general case */ 685 if (mask) { 686 GLuint i; 687 for (i = 0; i < count; i++) { 688 if (mask[i]) { 689 dst[i] = val; 690 } 691 } 692 } 693 else { 694 GLuint i; 695 for (i = 0; i < count; i++) { 696 dst[i] = val; 697 } 698 } 699 } 700} 701 702 703static void 704put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 705 const GLint x[], const GLint y[], const void *values, 706 const GLubyte *mask) 707{ 708 /* treat 4*GLubyte as 1*GLuint */ 709 const GLuint *src = (const GLuint *) values; 710 GLuint i; 711 assert(rb->DataType == GL_UNSIGNED_BYTE); 712 for (i = 0; i < count; i++) { 713 if (!mask || mask[i]) { 714 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 715 *dst = src[i]; 716 } 717 } 718} 719 720 721static void 722put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 723 GLuint count, const GLint x[], const GLint y[], 724 const void *value, const GLubyte *mask) 725{ 726 /* treat 4*GLubyte as 1*GLuint */ 727 const GLuint val = *((const GLuint *) value); 728 GLuint i; 729 assert(rb->DataType == GL_UNSIGNED_BYTE); 730 for (i = 0; i < count; i++) { 731 if (!mask || mask[i]) { 732 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 733 *dst = val; 734 } 735 } 736} 737 738 739/********************************************************************** 740 * Functions for buffers of 4 X GLushort (or GLshort) values. 741 * Typically accum buffer. 742 */ 743 744static void * 745get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 746 GLint x, GLint y) 747{ 748 if (!rb->Data) 749 return NULL; 750 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 751 return (GLushort *) rb->Data + 4 * (y * rb->Width + x); 752} 753 754 755static void 756get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 757 GLint x, GLint y, void *values) 758{ 759 const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x); 760 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 761 _mesa_memcpy(values, src, 4 * count * sizeof(GLshort)); 762} 763 764 765static void 766get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 767 const GLint x[], const GLint y[], void *values) 768{ 769 GLushort *dst = (GLushort *) values; 770 GLuint i; 771 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 772 for (i = 0; i < count; i++) { 773 const GLushort *src 774 = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 775 dst[i] = *src; 776 } 777} 778 779 780static void 781put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 782 GLint x, GLint y, const void *values, const GLubyte *mask) 783{ 784 const GLushort *src = (const GLushort *) values; 785 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 786 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 787 if (mask) { 788 GLuint i; 789 for (i = 0; i < count; i++) { 790 if (mask[i]) { 791 dst[i * 4 + 0] = src[i * 4 + 0]; 792 dst[i * 4 + 1] = src[i * 4 + 1]; 793 dst[i * 4 + 2] = src[i * 4 + 2]; 794 dst[i * 4 + 3] = src[i * 4 + 3]; 795 } 796 } 797 } 798 else { 799 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 800 } 801} 802 803 804static void 805put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 806 GLint x, GLint y, const void *values, const GLubyte *mask) 807{ 808 /* Put RGB values in RGBA buffer */ 809 const GLushort *src = (const GLushort *) values; 810 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 811 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 812 if (mask) { 813 GLuint i; 814 for (i = 0; i < count; i++) { 815 if (mask[i]) { 816 dst[i * 4 + 0] = src[i * 3 + 0]; 817 dst[i * 4 + 1] = src[i * 3 + 1]; 818 dst[i * 4 + 2] = src[i * 3 + 2]; 819 dst[i * 4 + 3] = 0xffff; 820 } 821 } 822 } 823 else { 824 _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 825 } 826} 827 828 829static void 830put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 831 GLint x, GLint y, const void *value, const GLubyte *mask) 832{ 833 const GLushort val0 = ((const GLushort *) value)[0]; 834 const GLushort val1 = ((const GLushort *) value)[1]; 835 const GLushort val2 = ((const GLushort *) value)[2]; 836 const GLushort val3 = ((const GLushort *) value)[3]; 837 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 838 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 839 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 840 /* common case for clearing accum buffer */ 841 _mesa_bzero(dst, count * 4 * sizeof(GLushort)); 842 } 843 else { 844 GLuint i; 845 for (i = 0; i < count; i++) { 846 if (!mask || mask[i]) { 847 dst[i * 4 + 0] = val0; 848 dst[i * 4 + 1] = val1; 849 dst[i * 4 + 2] = val2; 850 dst[i * 4 + 3] = val3; 851 } 852 } 853 } 854} 855 856 857static void 858put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 859 const GLint x[], const GLint y[], const void *values, 860 const GLubyte *mask) 861{ 862 const GLushort *src = (const GLushort *) values; 863 GLuint i; 864 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 865 for (i = 0; i < count; i++) { 866 if (!mask || mask[i]) { 867 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 868 dst[0] = src[i * 4 + 0]; 869 dst[1] = src[i * 4 + 1]; 870 dst[2] = src[i * 4 + 2]; 871 dst[3] = src[i * 4 + 3]; 872 } 873 } 874} 875 876 877static void 878put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 879 GLuint count, const GLint x[], const GLint y[], 880 const void *value, const GLubyte *mask) 881{ 882 const GLushort val0 = ((const GLushort *) value)[0]; 883 const GLushort val1 = ((const GLushort *) value)[1]; 884 const GLushort val2 = ((const GLushort *) value)[2]; 885 const GLushort val3 = ((const GLushort *) value)[3]; 886 GLuint i; 887 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 888 for (i = 0; i < count; i++) { 889 if (!mask || mask[i]) { 890 GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 891 dst[0] = val0; 892 dst[1] = val1; 893 dst[2] = val2; 894 dst[3] = val3; 895 } 896 } 897} 898 899 900 901/** 902 * This is a software fallback for the gl_renderbuffer->AllocStorage 903 * function. 904 * Device drivers will typically override this function for the buffers 905 * which it manages (typically color buffers, Z and stencil). 906 * Other buffers (like software accumulation and aux buffers) which the driver 907 * doesn't manage can be handled with this function. 908 * 909 * This one multi-purpose function can allocate stencil, depth, accum, color 910 * or color-index buffers! 911 * 912 * This function also plugs in the appropriate GetPointer, Get/PutRow and 913 * Get/PutValues functions. 914 */ 915static GLboolean 916soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 917 GLenum internalFormat, GLuint width, GLuint height) 918{ 919 GLuint pixelSize; 920 921 switch (internalFormat) { 922 case GL_RGB: 923 case GL_R3_G3_B2: 924 case GL_RGB4: 925 case GL_RGB5: 926 case GL_RGB8: 927 case GL_RGB10: 928 case GL_RGB12: 929 case GL_RGB16: 930 rb->_BaseFormat = GL_RGB; 931 rb->DataType = GL_UNSIGNED_BYTE; 932 rb->GetPointer = get_pointer_ubyte3; 933 rb->GetRow = get_row_ubyte3; 934 rb->GetValues = get_values_ubyte3; 935 rb->PutRow = put_row_ubyte3; 936 rb->PutRowRGB = put_row_rgb_ubyte3; 937 rb->PutMonoRow = put_mono_row_ubyte3; 938 rb->PutValues = put_values_ubyte3; 939 rb->PutMonoValues = put_mono_values_ubyte3; 940 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 941 rb->ComponentSizes[1] = 8 * sizeof(GLubyte); 942 rb->ComponentSizes[2] = 8 * sizeof(GLubyte); 943 rb->ComponentSizes[3] = 0; 944 pixelSize = 3 * sizeof(GLubyte); 945 break; 946 case GL_RGBA: 947 case GL_RGBA2: 948 case GL_RGBA4: 949 case GL_RGB5_A1: 950 case GL_RGBA8: 951 rb->_BaseFormat = GL_RGBA; 952 rb->DataType = GL_UNSIGNED_BYTE; 953 rb->GetPointer = get_pointer_ubyte4; 954 rb->GetRow = get_row_ubyte4; 955 rb->GetValues = get_values_ubyte4; 956 rb->PutRow = put_row_ubyte4; 957 rb->PutRowRGB = put_row_rgb_ubyte4; 958 rb->PutMonoRow = put_mono_row_ubyte4; 959 rb->PutValues = put_values_ubyte4; 960 rb->PutMonoValues = put_mono_values_ubyte4; 961 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 962 rb->ComponentSizes[1] = 8 * sizeof(GLubyte); 963 rb->ComponentSizes[2] = 8 * sizeof(GLubyte); 964 rb->ComponentSizes[3] = 8 * sizeof(GLubyte); 965 pixelSize = 4 * sizeof(GLubyte); 966 break; 967 case GL_RGB10_A2: 968 case GL_RGBA12: 969 case GL_RGBA16: 970 rb->_BaseFormat = GL_RGBA; 971 rb->DataType = GL_UNSIGNED_SHORT; 972 rb->GetPointer = get_pointer_ushort4; 973 rb->GetRow = get_row_ushort4; 974 rb->GetValues = get_values_ushort4; 975 rb->PutRow = put_row_ushort4; 976 rb->PutRowRGB = put_row_rgb_ushort4; 977 rb->PutMonoRow = put_mono_row_ushort4; 978 rb->PutValues = put_values_ushort4; 979 rb->PutMonoValues = put_mono_values_ushort4; 980 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 981 rb->ComponentSizes[1] = 8 * sizeof(GLushort); 982 rb->ComponentSizes[2] = 8 * sizeof(GLushort); 983 rb->ComponentSizes[3] = 8 * sizeof(GLushort); 984 pixelSize = 4 * sizeof(GLushort); 985 break; 986#if 00 987 case ALPHA8: 988 rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */ 989 rb->DataType = GL_UNSIGNED_BYTE; 990 rb->GetPointer = get_pointer_alpha8; 991 rb->GetRow = get_row_alpha8; 992 rb->GetValues = get_values_alpha8; 993 rb->PutRow = put_row_alpha8; 994 rb->PutRowRGB = NULL; 995 rb->PutMonoRow = put_mono_row_alpha8; 996 rb->PutValues = put_values_alpha8; 997 rb->PutMonoValues = put_mono_values_alpha8; 998 rb->ComponentSizes[0] = 0; /*red*/ 999 rb->ComponentSizes[1] = 0; /*green*/ 1000 rb->ComponentSizes[2] = 0; /*blue*/ 1001 rb->ComponentSizes[3] = 8 * sizeof(GLubyte); 1002 pixelSize = sizeof(GLubyte); 1003 break; 1004#endif 1005 case GL_STENCIL_INDEX: 1006 case GL_STENCIL_INDEX1_EXT: 1007 case GL_STENCIL_INDEX4_EXT: 1008 case GL_STENCIL_INDEX8_EXT: 1009 rb->_BaseFormat = GL_STENCIL_INDEX; 1010 rb->DataType = GL_UNSIGNED_BYTE; 1011 rb->GetPointer = get_pointer_ubyte; 1012 rb->GetRow = get_row_ubyte; 1013 rb->GetValues = get_values_ubyte; 1014 rb->PutRow = put_row_ubyte; 1015 rb->PutRowRGB = NULL; 1016 rb->PutMonoRow = put_mono_row_ubyte; 1017 rb->PutValues = put_values_ubyte; 1018 rb->PutMonoValues = put_mono_values_ubyte; 1019 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 1020 pixelSize = sizeof(GLubyte); 1021 break; 1022 case GL_STENCIL_INDEX16_EXT: 1023 rb->_BaseFormat = GL_STENCIL_INDEX; 1024 rb->DataType = GL_UNSIGNED_SHORT; 1025 rb->GetPointer = get_pointer_ushort; 1026 rb->GetRow = get_row_ushort; 1027 rb->GetValues = get_values_ushort; 1028 rb->PutRow = put_row_ushort; 1029 rb->PutRowRGB = NULL; 1030 rb->PutMonoRow = put_mono_row_ushort; 1031 rb->PutValues = put_values_ushort; 1032 rb->PutMonoValues = put_mono_values_ushort; 1033 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1034 pixelSize = sizeof(GLushort); 1035 break; 1036 case GL_DEPTH_COMPONENT: 1037 case GL_DEPTH_COMPONENT16: 1038 rb->_BaseFormat = GL_DEPTH_COMPONENT; 1039 rb->DataType = GL_UNSIGNED_SHORT; 1040 rb->GetPointer = get_pointer_ushort; 1041 rb->GetRow = get_row_ushort; 1042 rb->GetValues = get_values_ushort; 1043 rb->PutRow = put_row_ushort; 1044 rb->PutRowRGB = NULL; 1045 rb->PutMonoRow = put_mono_row_ushort; 1046 rb->PutValues = put_values_ushort; 1047 rb->PutMonoValues = put_mono_values_ushort; 1048 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1049 pixelSize = sizeof(GLushort); 1050 break; 1051 case GL_DEPTH_COMPONENT24: 1052 case GL_DEPTH_COMPONENT32: 1053 rb->_BaseFormat = GL_DEPTH_COMPONENT; 1054 rb->DataType = GL_UNSIGNED_INT; 1055 rb->GetPointer = get_pointer_uint; 1056 rb->GetRow = get_row_uint; 1057 rb->GetValues = get_values_uint; 1058 rb->PutRow = put_row_uint; 1059 rb->PutRowRGB = NULL; 1060 rb->PutMonoRow = put_mono_row_uint; 1061 rb->PutValues = put_values_uint; 1062 rb->PutMonoValues = put_mono_values_uint; 1063 rb->ComponentSizes[0] = 8 * sizeof(GLuint); 1064 pixelSize = sizeof(GLuint); 1065 break; 1066 case GL_COLOR_INDEX8_EXT: 1067 rb->_BaseFormat = GL_COLOR_INDEX; 1068 rb->DataType = GL_UNSIGNED_BYTE; 1069 rb->GetPointer = get_pointer_ubyte; 1070 rb->GetRow = get_row_ubyte; 1071 rb->GetValues = get_values_ubyte; 1072 rb->PutRow = put_row_ubyte; 1073 rb->PutRowRGB = NULL; 1074 rb->PutMonoRow = put_mono_row_ubyte; 1075 rb->PutValues = put_values_ubyte; 1076 rb->PutMonoValues = put_mono_values_ubyte; 1077 rb->ComponentSizes[0] = 8 * sizeof(GLubyte); 1078 pixelSize = sizeof(GLubyte); 1079 break; 1080 case GL_COLOR_INDEX16_EXT: 1081 rb->_BaseFormat = GL_COLOR_INDEX; 1082 rb->DataType = GL_UNSIGNED_SHORT; 1083 rb->GetPointer = get_pointer_ushort; 1084 rb->GetRow = get_row_ushort; 1085 rb->GetValues = get_values_ushort; 1086 rb->PutRow = put_row_ushort; 1087 rb->PutRowRGB = NULL; 1088 rb->PutMonoRow = put_mono_row_ushort; 1089 rb->PutValues = put_values_ushort; 1090 rb->PutMonoValues = put_mono_values_ushort; 1091 rb->ComponentSizes[0] = 8 * sizeof(GLushort); 1092 pixelSize = sizeof(GLushort); 1093 break; 1094 case COLOR_INDEX32: 1095 rb->_BaseFormat = GL_COLOR_INDEX; 1096 rb->DataType = GL_UNSIGNED_INT; 1097 rb->GetPointer = get_pointer_uint; 1098 rb->GetRow = get_row_uint; 1099 rb->GetValues = get_values_uint; 1100 rb->PutRow = put_row_uint; 1101 rb->PutRowRGB = NULL; 1102 rb->PutMonoRow = put_mono_row_uint; 1103 rb->PutValues = put_values_uint; 1104 rb->PutMonoValues = put_mono_values_uint; 1105 rb->ComponentSizes[0] = 8 * sizeof(GLuint); 1106 pixelSize = sizeof(GLuint); 1107 break; 1108 default: 1109 _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage"); 1110 return GL_FALSE; 1111 } 1112 1113 ASSERT(rb->DataType); 1114 ASSERT(rb->GetPointer); 1115 ASSERT(rb->GetRow); 1116 ASSERT(rb->GetValues); 1117 ASSERT(rb->PutRow); 1118 ASSERT(rb->PutMonoRow); 1119 ASSERT(rb->PutValues); 1120 ASSERT(rb->PutMonoValues); 1121 ASSERT(rb->ComponentSizes[0] > 0); 1122 1123 /* free old buffer storage */ 1124 if (rb->Data) 1125 _mesa_free(rb->Data); 1126 1127 /* allocate new buffer storage */ 1128 rb->Data = _mesa_malloc(width * height * pixelSize); 1129 if (rb->Data == NULL) { 1130 rb->Width = 0; 1131 rb->Height = 0; 1132 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation"); 1133 return GL_FALSE; 1134 } 1135 1136 rb->Width = width; 1137 rb->Height = height; 1138 rb->InternalFormat = internalFormat; 1139 1140 return GL_TRUE; 1141} 1142 1143 1144/**********************************************************************/ 1145/**********************************************************************/ 1146/**********************************************************************/ 1147 1148 1149/** 1150 * The alpha_renderbuffer class is used to augment an RGB renderbuffer with 1151 * an alpha channel. The RGB buffer can be hardware-based. 1152 * We basically wrap the RGB buffer. When PutRow is called (for example), 1153 * we store the alpha values in this buffer, then pass on the PutRow call 1154 * to the wrapped RGB buffer. 1155 */ 1156struct alpha_renderbuffer 1157{ 1158 struct gl_renderbuffer Base; /* the alpha buffer */ 1159 struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */ 1160}; 1161 1162 1163static GLboolean 1164alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1165 GLenum internalFormat, GLuint width, GLuint height) 1166{ 1167 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1168 1169 /* first, pass the call to the wrapped RGB buffer */ 1170 if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat, 1171 width, height)) { 1172 return GL_FALSE; 1173 } 1174 1175 /* next, resize my alpha buffer */ 1176 if (arb->Base.Data) { 1177 _mesa_free(arb->Base.Data); 1178 } 1179 1180 arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte)); 1181 if (arb->Base.Data == NULL) { 1182 arb->Base.Width = 0; 1183 arb->Base.Height = 0; 1184 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 1185 return GL_FALSE; 1186 } 1187 1188 arb->Base.Width = width; 1189 arb->Base.Height = height; 1190 arb->Base.InternalFormat = internalFormat; 1191 1192 return GL_TRUE; 1193} 1194 1195 1196/** 1197 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 1198 */ 1199static void 1200delete_renderbuffer_alpha8(struct gl_renderbuffer *rb) 1201{ 1202 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1203 if (arb->Base.Data) { 1204 _mesa_free(arb->Base.Data); 1205 } 1206 assert(arb->RGBbuffer); 1207 arb->RGBbuffer->Delete(arb->RGBbuffer); 1208 arb->RGBbuffer = NULL; 1209 _mesa_free(arb); 1210} 1211 1212 1213static void * 1214get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1215 GLint x, GLint y) 1216{ 1217 return NULL; /* don't allow direct access! */ 1218} 1219 1220 1221static void 1222get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1223 GLint x, GLint y, void *values) 1224{ 1225 /* NOTE: 'values' is RGBA format! */ 1226 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1227 const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; 1228 GLubyte *dst = (GLubyte *) values; 1229 GLuint i; 1230 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1231 /* first, pass the call to the wrapped RGB buffer */ 1232 arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values); 1233 /* second, fill in alpha values from this buffer! */ 1234 for (i = 0; i < count; i++) { 1235 dst[i * 4 + 3] = src[i]; 1236 } 1237} 1238 1239 1240static void 1241get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1242 const GLint x[], const GLint y[], void *values) 1243{ 1244 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1245 GLubyte *dst = (GLubyte *) values; 1246 GLuint i; 1247 assert(rb->DataType == GL_UNSIGNED_BYTE); 1248 /* first, pass the call to the wrapped RGB buffer */ 1249 arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values); 1250 /* second, fill in alpha values from this buffer! */ 1251 for (i = 0; i < count; i++) { 1252 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1253 dst[i * 4 + 3] = *src; 1254 } 1255} 1256 1257 1258static void 1259put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1260 GLint x, GLint y, const void *values, const GLubyte *mask) 1261{ 1262 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1263 const GLubyte *src = (const GLubyte *) values; 1264 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1265 GLuint i; 1266 assert(rb->DataType == GL_UNSIGNED_BYTE); 1267 /* first, pass the call to the wrapped RGB buffer */ 1268 arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask); 1269 /* second, store alpha in our buffer */ 1270 for (i = 0; i < count; i++) { 1271 if (!mask || mask[i]) { 1272 dst[i] = src[i * 4 + 3]; 1273 } 1274 } 1275} 1276 1277 1278static void 1279put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1280 GLint x, GLint y, const void *values, const GLubyte *mask) 1281{ 1282 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1283 const GLubyte *src = (const GLubyte *) values; 1284 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1285 GLuint i; 1286 assert(rb->DataType == GL_UNSIGNED_BYTE); 1287 /* first, pass the call to the wrapped RGB buffer */ 1288 arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask); 1289 /* second, store alpha in our buffer */ 1290 for (i = 0; i < count; i++) { 1291 if (!mask || mask[i]) { 1292 dst[i] = src[i * 4 + 3]; 1293 } 1294 } 1295} 1296 1297 1298static void 1299put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1300 GLint x, GLint y, const void *value, const GLubyte *mask) 1301{ 1302 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1303 const GLubyte val = ((const GLubyte *) value)[3]; 1304 GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1305 assert(rb->DataType == GL_UNSIGNED_BYTE); 1306 /* first, pass the call to the wrapped RGB buffer */ 1307 arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask); 1308 /* second, store alpha in our buffer */ 1309 if (mask) { 1310 GLuint i; 1311 for (i = 0; i < count; i++) { 1312 if (mask[i]) { 1313 dst[i] = val; 1314 } 1315 } 1316 } 1317 else { 1318 _mesa_memset(dst, val, count); 1319 } 1320} 1321 1322 1323static void 1324put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1325 const GLint x[], const GLint y[], 1326 const void *values, const GLubyte *mask) 1327{ 1328 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1329 const GLubyte *src = (const GLubyte *) values; 1330 GLuint i; 1331 assert(rb->DataType == GL_UNSIGNED_BYTE); 1332 /* first, pass the call to the wrapped RGB buffer */ 1333 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask); 1334 /* second, store alpha in our buffer */ 1335 for (i = 0; i < count; i++) { 1336 if (!mask || mask[i]) { 1337 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1338 *dst = src[i * 4 + 3]; 1339 } 1340 } 1341} 1342 1343 1344static void 1345put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, 1346 GLuint count, const GLint x[], const GLint y[], 1347 const void *value, const GLubyte *mask) 1348{ 1349 struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; 1350 const GLubyte val = ((const GLubyte *) value)[3]; 1351 GLuint i; 1352 assert(rb->DataType == GL_UNSIGNED_BYTE); 1353 /* first, pass the call to the wrapped RGB buffer */ 1354 arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask); 1355 /* second, store alpha in our buffer */ 1356 for (i = 0; i < count; i++) { 1357 if (!mask || mask[i]) { 1358 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1359 *dst = val; 1360 } 1361 } 1362} 1363 1364 1365 1366/**********************************************************************/ 1367/**********************************************************************/ 1368/**********************************************************************/ 1369 1370 1371/** 1372 * Default GetPointer routine. Always return NULL to indicate that 1373 * direct buffer access is not supported. 1374 */ 1375static void * 1376nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 1377{ 1378 return NULL; 1379} 1380 1381 1382/** 1383 * Initialize the fields of a gl_renderbuffer to default values. 1384 */ 1385void 1386_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 1387{ 1388 rb->Name = name; 1389 rb->RefCount = 1; 1390 rb->Delete = _mesa_delete_renderbuffer; 1391 1392 /* The rest of these should be set later by the caller of this function or 1393 * the AllocStorage method: 1394 */ 1395 rb->AllocStorage = NULL; 1396 1397 rb->Width = 0; 1398 rb->Height = 0; 1399 rb->InternalFormat = GL_NONE; 1400 rb->_BaseFormat = GL_NONE; 1401 rb->DataType = GL_NONE; 1402 rb->ComponentSizes[0] = 0; 1403 rb->ComponentSizes[1] = 0; 1404 rb->ComponentSizes[2] = 0; 1405 rb->ComponentSizes[3] = 0; 1406 rb->Data = NULL; 1407 1408 rb->GetPointer = nop_get_pointer; 1409 rb->GetRow = NULL; 1410 rb->GetValues = NULL; 1411 rb->PutRow = NULL; 1412 rb->PutRowRGB = NULL; 1413 rb->PutMonoRow = NULL; 1414 rb->PutValues = NULL; 1415 rb->PutMonoValues = NULL; 1416} 1417 1418 1419/** 1420 * Allocate a new gl_renderbuffer object. This can be used for user-created 1421 * renderbuffers or window-system renderbuffers. 1422 */ 1423struct gl_renderbuffer * 1424_mesa_new_renderbuffer(GLcontext *ctx, GLuint name) 1425{ 1426 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 1427 if (rb) { 1428 _mesa_init_renderbuffer(rb, name); 1429 } 1430 return rb; 1431} 1432 1433 1434/** 1435 * Delete a gl_framebuffer. 1436 * This is the default function for framebuffer->Delete(). 1437 */ 1438void 1439_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 1440{ 1441 if (rb->Data) { 1442 _mesa_free(rb->Data); 1443 } 1444 _mesa_free(rb); 1445} 1446 1447 1448/** 1449 * Allocate a software-based renderbuffer. This is called via the 1450 * ctx->Driver.NewRenderbuffer() function when the user creates a new 1451 * renderbuffer. 1452 * This would not be used for hardware-based renderbuffers. 1453 */ 1454struct gl_renderbuffer * 1455_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name) 1456{ 1457 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 1458 if (rb) { 1459 rb->AllocStorage = soft_renderbuffer_storage; 1460 /* Normally, one would setup the PutRow, GetRow, etc functions here. 1461 * But we're doing that in the soft_renderbuffer_storage() function 1462 * instead. 1463 */ 1464 } 1465 return rb; 1466} 1467 1468 1469/** 1470 * Add software-based color renderbuffers to the given framebuffer. 1471 * This is a helper routine for device drivers when creating a 1472 * window system framebuffer (not a user-created render/framebuffer). 1473 * Once this function is called, you can basically forget about this 1474 * renderbuffer; core Mesa will handle all the buffer management and 1475 * rendering! 1476 */ 1477GLboolean 1478_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1479 GLuint rgbBits, GLuint alphaBits, 1480 GLboolean frontLeft, GLboolean backLeft, 1481 GLboolean frontRight, GLboolean backRight) 1482{ 1483 GLuint b; 1484 1485 if (rgbBits > 16 || alphaBits > 16) { 1486 _mesa_problem(ctx, 1487 "Unsupported bit depth in _mesa_add_color_renderbuffers"); 1488 return GL_FALSE; 1489 } 1490 1491 assert(MAX_COLOR_ATTACHMENTS >= 4); 1492 1493 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1494 struct gl_renderbuffer *rb; 1495 1496 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1497 continue; 1498 else if (b == BUFFER_BACK_LEFT && !backLeft) 1499 continue; 1500 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1501 continue; 1502 else if (b == BUFFER_BACK_RIGHT && !backRight) 1503 continue; 1504 1505 assert(fb->Attachment[b].Renderbuffer == NULL); 1506 1507 rb = _mesa_new_renderbuffer(ctx, 0); 1508 if (!rb) { 1509 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 1510 return GL_FALSE; 1511 } 1512 1513 if (rgbBits <= 8) { 1514 if (alphaBits) 1515 rb->InternalFormat = GL_RGBA8; 1516 else 1517 rb->InternalFormat = GL_RGB8; 1518 } 1519 else { 1520 assert(rgbBits <= 16); 1521 if (alphaBits) 1522 rb->InternalFormat = GL_RGBA16; 1523 else 1524 rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */ 1525 } 1526 1527 rb->AllocStorage = soft_renderbuffer_storage; 1528 _mesa_add_renderbuffer(fb, b, rb); 1529 } 1530 1531 return GL_TRUE; 1532} 1533 1534 1535/** 1536 * Add software-based color index renderbuffers to the given framebuffer. 1537 * This is a helper routine for device drivers when creating a 1538 * window system framebuffer (not a user-created render/framebuffer). 1539 * Once this function is called, you can basically forget about this 1540 * renderbuffer; core Mesa will handle all the buffer management and 1541 * rendering! 1542 */ 1543GLboolean 1544_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1545 GLuint indexBits, 1546 GLboolean frontLeft, GLboolean backLeft, 1547 GLboolean frontRight, GLboolean backRight) 1548{ 1549 GLuint b; 1550 1551 if (indexBits > 8) { 1552 _mesa_problem(ctx, 1553 "Unsupported bit depth in _mesa_add_color_index_renderbuffers"); 1554 return GL_FALSE; 1555 } 1556 1557 assert(MAX_COLOR_ATTACHMENTS >= 4); 1558 1559 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1560 struct gl_renderbuffer *rb; 1561 1562 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1563 continue; 1564 else if (b == BUFFER_BACK_LEFT && !backLeft) 1565 continue; 1566 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1567 continue; 1568 else if (b == BUFFER_BACK_RIGHT && !backRight) 1569 continue; 1570 1571 assert(fb->Attachment[b].Renderbuffer == NULL); 1572 1573 rb = _mesa_new_renderbuffer(ctx, 0); 1574 if (!rb) { 1575 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 1576 return GL_FALSE; 1577 } 1578 1579 if (indexBits <= 8) { 1580 /* only support GLuint for now */ 1581 /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/ 1582 rb->InternalFormat = COLOR_INDEX32; 1583 } 1584 else { 1585 rb->InternalFormat = COLOR_INDEX32; 1586 } 1587 rb->AllocStorage = soft_renderbuffer_storage; 1588 _mesa_add_renderbuffer(fb, b, rb); 1589 } 1590 1591 return GL_TRUE; 1592} 1593 1594 1595/** 1596 * Add software-based alpha renderbuffers to the given framebuffer. 1597 * This is a helper routine for device drivers when creating a 1598 * window system framebuffer (not a user-created render/framebuffer). 1599 * Once this function is called, you can basically forget about this 1600 * renderbuffer; core Mesa will handle all the buffer management and 1601 * rendering! 1602 */ 1603GLboolean 1604_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1605 GLuint alphaBits, 1606 GLboolean frontLeft, GLboolean backLeft, 1607 GLboolean frontRight, GLboolean backRight) 1608{ 1609 GLuint b; 1610 1611 /* for window system framebuffers only! */ 1612 assert(fb->Name == 0); 1613 1614 if (alphaBits > 8) { 1615 _mesa_problem(ctx, 1616 "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 1617 return GL_FALSE; 1618 } 1619 1620 assert(MAX_COLOR_ATTACHMENTS >= 4); 1621 1622 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 1623 struct alpha_renderbuffer *arb; 1624 1625 if (b == BUFFER_FRONT_LEFT && !frontLeft) 1626 continue; 1627 else if (b == BUFFER_BACK_LEFT && !backLeft) 1628 continue; 1629 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 1630 continue; 1631 else if (b == BUFFER_BACK_RIGHT && !backRight) 1632 continue; 1633 1634 /* the RGB buffer to wrap must already exist!! */ 1635 assert(fb->Attachment[b].Renderbuffer); 1636 1637 /* only GLubyte supported for now */ 1638 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 1639 1640 arb = CALLOC_STRUCT(alpha_renderbuffer); 1641 if (!arb) { 1642 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 1643 return GL_FALSE; 1644 } 1645 1646 _mesa_init_renderbuffer(&arb->Base, 0); 1647 1648 /* wrap the RGB buffer */ 1649 arb->RGBbuffer = fb->Attachment[b].Renderbuffer; 1650 1651 /* plug in my functions */ 1652 arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat; 1653 arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat; 1654 arb->Base.DataType = arb->RGBbuffer->DataType; 1655 arb->Base.AllocStorage = alloc_storage_alpha8; 1656 arb->Base.Delete = delete_renderbuffer_alpha8; 1657 arb->Base.GetPointer = get_pointer_alpha8; 1658 arb->Base.GetRow = get_row_alpha8; 1659 arb->Base.GetValues = get_values_alpha8; 1660 arb->Base.PutRow = put_row_alpha8; 1661 arb->Base.PutRowRGB = put_row_rgb_alpha8; 1662 arb->Base.PutMonoRow = put_mono_row_alpha8; 1663 arb->Base.PutValues = put_values_alpha8; 1664 arb->Base.PutMonoValues = put_mono_values_alpha8; 1665 1666 /* clear the pointer to avoid assertion/sanity check failure later */ 1667 fb->Attachment[b].Renderbuffer = NULL; 1668 1669 /* plug the alpha renderbuffer into the colorbuffer attachment */ 1670 _mesa_add_renderbuffer(fb, b, &arb->Base); 1671 } 1672 1673 return GL_TRUE; 1674} 1675 1676 1677/** 1678 * Add a software-based depth renderbuffer to the given framebuffer. 1679 * This is a helper routine for device drivers when creating a 1680 * window system framebuffer (not a user-created render/framebuffer). 1681 * Once this function is called, you can basically forget about this 1682 * renderbuffer; core Mesa will handle all the buffer management and 1683 * rendering! 1684 */ 1685GLboolean 1686_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1687 GLuint depthBits) 1688{ 1689 struct gl_renderbuffer *rb; 1690 1691 if (depthBits > 32) { 1692 _mesa_problem(ctx, 1693 "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 1694 return GL_FALSE; 1695 } 1696 1697 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 1698 1699 rb = _mesa_new_renderbuffer(ctx, 0); 1700 if (!rb) { 1701 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 1702 return GL_FALSE; 1703 } 1704 1705 if (depthBits <= 16) { 1706 rb->InternalFormat = GL_DEPTH_COMPONENT16; 1707 } 1708 else { 1709 rb->InternalFormat = GL_DEPTH_COMPONENT32; 1710 } 1711 1712 rb->AllocStorage = soft_renderbuffer_storage; 1713 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 1714 1715 return GL_TRUE; 1716} 1717 1718 1719/** 1720 * Add a software-based stencil renderbuffer to the given framebuffer. 1721 * This is a helper routine for device drivers when creating a 1722 * window system framebuffer (not a user-created render/framebuffer). 1723 * Once this function is called, you can basically forget about this 1724 * renderbuffer; core Mesa will handle all the buffer management and 1725 * rendering! 1726 */ 1727GLboolean 1728_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1729 GLuint stencilBits) 1730{ 1731 struct gl_renderbuffer *rb; 1732 1733 if (stencilBits > 16) { 1734 _mesa_problem(ctx, 1735 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 1736 return GL_FALSE; 1737 } 1738 1739 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 1740 1741 rb = _mesa_new_renderbuffer(ctx, 0); 1742 if (!rb) { 1743 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 1744 return GL_FALSE; 1745 } 1746 1747 if (stencilBits <= 8) { 1748 rb->InternalFormat = GL_STENCIL_INDEX8_EXT; 1749 } 1750 else { 1751 /* not really supported (see s_stencil.c code) */ 1752 rb->InternalFormat = GL_STENCIL_INDEX16_EXT; 1753 } 1754 1755 rb->AllocStorage = soft_renderbuffer_storage; 1756 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 1757 1758 return GL_TRUE; 1759} 1760 1761 1762/** 1763 * Add a software-based accumulation renderbuffer to the given framebuffer. 1764 * This is a helper routine for device drivers when creating a 1765 * window system framebuffer (not a user-created render/framebuffer). 1766 * Once this function is called, you can basically forget about this 1767 * renderbuffer; core Mesa will handle all the buffer management and 1768 * rendering! 1769 */ 1770GLboolean 1771_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 1772 GLuint redBits, GLuint greenBits, 1773 GLuint blueBits, GLuint alphaBits) 1774{ 1775 struct gl_renderbuffer *rb; 1776 1777 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 1778 _mesa_problem(ctx, 1779 "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 1780 return GL_FALSE; 1781 } 1782 1783 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 1784 1785 rb = _mesa_new_renderbuffer(ctx, 0); 1786 if (!rb) { 1787 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 1788 return GL_FALSE; 1789 } 1790 1791 rb->InternalFormat = GL_RGBA16; 1792 rb->AllocStorage = soft_renderbuffer_storage; 1793 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 1794 1795 return GL_TRUE; 1796} 1797 1798 1799 1800/** 1801 * Add a software-based accumulation renderbuffer to the given framebuffer. 1802 * This is a helper routine for device drivers when creating a 1803 * window system framebuffer (not a user-created render/framebuffer). 1804 * Once this function is called, you can basically forget about this 1805 * renderbuffer; core Mesa will handle all the buffer management and 1806 * rendering! 1807 * 1808 * NOTE: color-index aux buffers not supported. 1809 */ 1810GLboolean 1811_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 1812 GLuint colorBits, GLuint numBuffers) 1813{ 1814 GLuint i; 1815 1816 if (colorBits > 16) { 1817 _mesa_problem(ctx, 1818 "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 1819 return GL_FALSE; 1820 } 1821 1822 assert(numBuffers < MAX_AUX_BUFFERS); 1823 1824 for (i = 0; i < numBuffers; i++) { 1825 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 1826 1827 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 1828 1829 if (!rb) { 1830 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 1831 return GL_FALSE; 1832 } 1833 1834 if (colorBits <= 8) { 1835 rb->InternalFormat = GL_RGBA8; 1836 } 1837 else { 1838 rb->InternalFormat = GL_RGBA16; 1839 } 1840 1841 rb->AllocStorage = soft_renderbuffer_storage; 1842 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 1843 } 1844 return GL_TRUE; 1845} 1846 1847 1848/** 1849 * Create/attach software-based renderbuffers to the given framebuffer. 1850 * This is a helper routine for device drivers. Drivers can just as well 1851 * call the individual _mesa_add_*_renderbuffer() routines directly. 1852 */ 1853void 1854_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 1855 GLboolean color, 1856 GLboolean depth, 1857 GLboolean stencil, 1858 GLboolean accum, 1859 GLboolean alpha, 1860 GLboolean aux) 1861{ 1862 GLboolean frontLeft = GL_TRUE; 1863 GLboolean backLeft = fb->Visual.doubleBufferMode; 1864 GLboolean frontRight = fb->Visual.stereoMode; 1865 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 1866 1867 if (color) { 1868 if (fb->Visual.rgbMode) { 1869 assert(fb->Visual.redBits == fb->Visual.greenBits); 1870 assert(fb->Visual.redBits == fb->Visual.blueBits); 1871 _mesa_add_color_renderbuffers(NULL, fb, 1872 fb->Visual.redBits, 1873 fb->Visual.alphaBits, 1874 frontLeft, backLeft, 1875 frontRight, backRight); 1876 } 1877 else { 1878 _mesa_add_color_index_renderbuffers(NULL, fb, 1879 fb->Visual.indexBits, 1880 frontLeft, backLeft, 1881 frontRight, backRight); 1882 } 1883 } 1884 1885 if (depth) { 1886 assert(fb->Visual.depthBits > 0); 1887 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 1888 } 1889 1890 if (stencil) { 1891 assert(fb->Visual.stencilBits > 0); 1892 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 1893 } 1894 1895 if (accum) { 1896 assert(fb->Visual.rgbMode); 1897 assert(fb->Visual.accumRedBits > 0); 1898 assert(fb->Visual.accumGreenBits > 0); 1899 assert(fb->Visual.accumBlueBits > 0); 1900 _mesa_add_accum_renderbuffer(NULL, fb, 1901 fb->Visual.accumRedBits, 1902 fb->Visual.accumGreenBits, 1903 fb->Visual.accumBlueBits, 1904 fb->Visual.accumAlphaBits); 1905 } 1906 1907 if (aux) { 1908 assert(fb->Visual.rgbMode); 1909 assert(fb->Visual.numAuxBuffers > 0); 1910 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 1911 fb->Visual.numAuxBuffers); 1912 } 1913 1914 if (alpha) { 1915 assert(fb->Visual.rgbMode); 1916 assert(fb->Visual.alphaBits > 0); 1917 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 1918 frontLeft, backLeft, 1919 frontRight, backRight); 1920 } 1921 1922#if 0 1923 if (multisample) { 1924 /* maybe someday */ 1925 } 1926#endif 1927} 1928 1929 1930/** 1931 * Attach a renderbuffer to a framebuffer. 1932 */ 1933void 1934_mesa_add_renderbuffer(struct gl_framebuffer *fb, 1935 GLuint bufferName, struct gl_renderbuffer *rb) 1936{ 1937 assert(fb); 1938 assert(rb); 1939#if 00 1940 /* there should be no previous renderbuffer on this attachment point! */ 1941 assert(fb->Attachment[bufferName].Renderbuffer == NULL); 1942#endif 1943 assert(bufferName < BUFFER_COUNT); 1944 1945 /* winsys vs. user-created buffer cross check */ 1946 if (fb->Name) { 1947 assert(rb->Name); 1948 } 1949 else { 1950 assert(!rb->Name); 1951 } 1952 1953 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 1954 fb->Attachment[bufferName].Complete = GL_TRUE; 1955 fb->Attachment[bufferName].Renderbuffer = rb; 1956} 1957