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