renderbuffer.c revision 42d377224af0fcf5a21269958ce5f96c4306c4fa
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 "fbobject.h" 47#include "formats.h" 48#include "mtypes.h" 49#include "renderbuffer.h" 50 51 52/* 53 * Routines for get/put values in common buffer formats follow. 54 */ 55 56/* Returns a bytes per pixel of the DataType in the get/put span 57 * functions for at least a subset of the available combinations a 58 * renderbuffer can have. 59 * 60 * It would be nice to see gl_renderbuffer start talking about a 61 * gl_format instead of a GLenum DataType. 62 */ 63static int 64get_datatype_bytes(struct gl_renderbuffer *rb) 65{ 66 int component_size; 67 68 switch (rb->DataType) { 69 case GL_FLOAT: 70 case GL_UNSIGNED_INT: 71 case GL_UNSIGNED_INT_24_8_EXT: 72 component_size = 4; 73 break; 74 case GL_UNSIGNED_SHORT: 75 component_size = 2; 76 break; 77 case GL_UNSIGNED_BYTE: 78 component_size = 1; 79 break; 80 default: 81 component_size = 1; 82 assert(0); 83 } 84 85 switch (rb->_BaseFormat) { 86 case GL_DEPTH_COMPONENT: 87 case GL_DEPTH_STENCIL: 88 return component_size; 89 default: 90 return 4 * component_size; 91 } 92} 93 94/* This is commonly used by most of the accessors. */ 95static void * 96get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 97 GLint x, GLint y) 98{ 99 if (!rb->Data) 100 return NULL; 101 102 return ((char *) rb->Data + 103 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format)); 104} 105 106/* GetRow() implementation for formats where DataType matches the rb->Format. 107 */ 108static void 109get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 110 GLuint count, GLint x, GLint y, void *values) 111{ 112 void *src = rb->GetPointer(ctx, rb, x, y); 113 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format)); 114} 115 116/* Only used for float textures currently, but might also be used for 117 * RGBA8888, RGBA16, etc. 118 */ 119static void 120get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 121 GLuint count, const GLint x[], const GLint y[], void *values) 122{ 123 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 124 GLuint i; 125 126 for (i = 0; i < count; i++) { 127 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]); 128 char *dst = (char *) values + i * format_bytes; 129 memcpy(dst, src, format_bytes); 130 } 131} 132 133/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and 134 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of 135 * storing those initial components of the value per pixel into the 136 * destination. 137 */ 138static void 139put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 140 GLuint count, GLint x, GLint y, 141 const void *values, const GLubyte *mask) 142{ 143 void *row = rb->GetPointer(ctx, rb, x, y); 144 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 145 int datatype_bytes = get_datatype_bytes(rb); 146 unsigned int i; 147 148 if (mask) { 149 for (i = 0; i < count; i++) { 150 char *dst = (char *) row + i * format_bytes; 151 const char *src = (const char *) values + i * datatype_bytes; 152 153 if (mask[i]) { 154 memcpy(dst, src, format_bytes); 155 } 156 } 157 } 158 else { 159 for (i = 0; i < count; i++) { 160 char *dst = (char *) row + i * format_bytes; 161 const char *src = (const char *) values + i * datatype_bytes; 162 memcpy(dst, src, format_bytes); 163 } 164 } 165} 166 167static void 168put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 169 GLuint count, GLint x, GLint y, 170 const void *value, const GLubyte *mask) 171{ 172 void *row = rb->GetPointer(ctx, rb, x, y); 173 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 174 unsigned int i; 175 176 if (mask) { 177 for (i = 0; i < count; i++) { 178 char *dst = (char *) row + i * format_bytes; 179 if (mask[i]) { 180 memcpy(dst, value, format_bytes); 181 } 182 } 183 } 184 else { 185 for (i = 0; i < count; i++) { 186 char *dst = (char *) row + i * format_bytes; 187 memcpy(dst, value, format_bytes); 188 } 189 } 190} 191 192 193static void 194put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 195 GLuint count, const GLint x[], const GLint y[], 196 const void *values, const GLubyte *mask) 197{ 198 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 199 int datatype_bytes = get_datatype_bytes(rb); 200 unsigned int i; 201 202 for (i = 0; i < count; i++) { 203 if (!mask || mask[i]) { 204 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 205 const char *src = (const char *) values + i * datatype_bytes; 206 memcpy(dst, src, format_bytes); 207 } 208 } 209} 210 211 212static void 213put_mono_values_generic(struct gl_context *ctx, 214 struct gl_renderbuffer *rb, 215 GLuint count, const GLint x[], const GLint y[], 216 const void *value, const GLubyte *mask) 217{ 218 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 219 unsigned int i; 220 221 for (i = 0; i < count; i++) { 222 if (!mask || mask[i]) { 223 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 224 memcpy(dst, value, format_bytes); 225 } 226 } 227} 228 229/********************************************************************** 230 * Functions for buffers of 1 X GLubyte values. 231 * Typically stencil. 232 */ 233 234static void 235get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 236 const GLint x[], const GLint y[], void *values) 237{ 238 GLubyte *dst = (GLubyte *) values; 239 GLuint i; 240 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 241 for (i = 0; i < count; i++) { 242 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 243 dst[i] = *src; 244 } 245} 246 247 248static void 249put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 250 GLint x, GLint y, const void *values, const GLubyte *mask) 251{ 252 const GLubyte *src = (const GLubyte *) values; 253 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 254 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 255 if (mask) { 256 GLuint i; 257 for (i = 0; i < count; i++) { 258 if (mask[i]) { 259 dst[i] = src[i]; 260 } 261 } 262 } 263 else { 264 memcpy(dst, values, count * sizeof(GLubyte)); 265 } 266} 267 268 269static void 270put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 271 GLint x, GLint y, const void *value, const GLubyte *mask) 272{ 273 const GLubyte val = *((const GLubyte *) value); 274 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 275 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 276 if (mask) { 277 GLuint i; 278 for (i = 0; i < count; i++) { 279 if (mask[i]) { 280 dst[i] = val; 281 } 282 } 283 } 284 else { 285 GLuint i; 286 for (i = 0; i < count; i++) { 287 dst[i] = val; 288 } 289 } 290} 291 292 293static void 294put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 295 const GLint x[], const GLint y[], 296 const void *values, const GLubyte *mask) 297{ 298 const GLubyte *src = (const GLubyte *) values; 299 GLuint i; 300 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 301 for (i = 0; i < count; i++) { 302 if (!mask || mask[i]) { 303 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 304 *dst = src[i]; 305 } 306 } 307} 308 309 310static void 311put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 312 const GLint x[], const GLint y[], 313 const void *value, const GLubyte *mask) 314{ 315 const GLubyte val = *((const GLubyte *) value); 316 GLuint i; 317 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 318 for (i = 0; i < count; i++) { 319 if (!mask || mask[i]) { 320 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 321 *dst = val; 322 } 323 } 324} 325 326 327/********************************************************************** 328 * Functions for buffers of 1 X GLushort values. 329 * Typically depth/Z. 330 */ 331 332static void 333get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 334 const GLint x[], const GLint y[], void *values) 335{ 336 GLushort *dst = (GLushort *) values; 337 GLuint i; 338 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 339 for (i = 0; i < count; i++) { 340 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 341 dst[i] = *src; 342 } 343} 344 345 346static void 347put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 348 GLint x, GLint y, const void *values, const GLubyte *mask) 349{ 350 const GLushort *src = (const GLushort *) values; 351 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 352 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 353 if (mask) { 354 GLuint i; 355 for (i = 0; i < count; i++) { 356 if (mask[i]) { 357 dst[i] = src[i]; 358 } 359 } 360 } 361 else { 362 memcpy(dst, src, count * sizeof(GLushort)); 363 } 364} 365 366 367static void 368put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 369 GLint x, GLint y, const void *value, const GLubyte *mask) 370{ 371 const GLushort val = *((const GLushort *) value); 372 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 373 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 374 if (mask) { 375 GLuint i; 376 for (i = 0; i < count; i++) { 377 if (mask[i]) { 378 dst[i] = val; 379 } 380 } 381 } 382 else { 383 GLuint i; 384 for (i = 0; i < count; i++) { 385 dst[i] = val; 386 } 387 } 388} 389 390 391static void 392put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 393 const GLint x[], const GLint y[], const void *values, 394 const GLubyte *mask) 395{ 396 const GLushort *src = (const GLushort *) values; 397 GLuint i; 398 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 399 for (i = 0; i < count; i++) { 400 if (!mask || mask[i]) { 401 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 402 *dst = src[i]; 403 } 404 } 405} 406 407 408static void 409put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, 410 GLuint count, const GLint x[], const GLint y[], 411 const void *value, const GLubyte *mask) 412{ 413 const GLushort val = *((const GLushort *) value); 414 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 415 if (mask) { 416 GLuint i; 417 for (i = 0; i < count; i++) { 418 if (mask[i]) { 419 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 420 *dst = val; 421 } 422 } 423 } 424 else { 425 GLuint i; 426 for (i = 0; i < count; i++) { 427 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 428 *dst = val; 429 } 430 } 431} 432 433 434/********************************************************************** 435 * Functions for buffers of 1 X GLuint values. 436 * Typically depth/Z or color index. 437 */ 438 439static void 440get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 441 const GLint x[], const GLint y[], void *values) 442{ 443 GLuint *dst = (GLuint *) values; 444 GLuint i; 445 ASSERT(rb->DataType == GL_UNSIGNED_INT || 446 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 447 for (i = 0; i < count; i++) { 448 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 449 dst[i] = *src; 450 } 451} 452 453 454static void 455put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 456 GLint x, GLint y, const void *values, const GLubyte *mask) 457{ 458 const GLuint *src = (const GLuint *) values; 459 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 460 ASSERT(rb->DataType == GL_UNSIGNED_INT || 461 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 462 if (mask) { 463 GLuint i; 464 for (i = 0; i < count; i++) { 465 if (mask[i]) { 466 dst[i] = src[i]; 467 } 468 } 469 } 470 else { 471 memcpy(dst, src, count * sizeof(GLuint)); 472 } 473} 474 475 476static void 477put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 478 GLint x, GLint y, const void *value, const GLubyte *mask) 479{ 480 const GLuint val = *((const GLuint *) value); 481 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 482 ASSERT(rb->DataType == GL_UNSIGNED_INT || 483 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 484 if (mask) { 485 GLuint i; 486 for (i = 0; i < count; i++) { 487 if (mask[i]) { 488 dst[i] = val; 489 } 490 } 491 } 492 else { 493 GLuint i; 494 for (i = 0; i < count; i++) { 495 dst[i] = val; 496 } 497 } 498} 499 500 501static void 502put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 503 const GLint x[], const GLint y[], const void *values, 504 const GLubyte *mask) 505{ 506 const GLuint *src = (const GLuint *) values; 507 GLuint i; 508 ASSERT(rb->DataType == GL_UNSIGNED_INT || 509 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 510 for (i = 0; i < count; i++) { 511 if (!mask || mask[i]) { 512 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 513 *dst = src[i]; 514 } 515 } 516} 517 518 519static void 520put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 521 const GLint x[], const GLint y[], const void *value, 522 const GLubyte *mask) 523{ 524 const GLuint val = *((const GLuint *) value); 525 GLuint i; 526 ASSERT(rb->DataType == GL_UNSIGNED_INT || 527 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 528 for (i = 0; i < count; i++) { 529 if (!mask || mask[i]) { 530 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 531 *dst = val; 532 } 533 } 534} 535 536 537/********************************************************************** 538 * Functions for buffers of 3 X GLubyte (or GLbyte) values. 539 * Typically color buffers. 540 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 541 * alpha values and return 255 for outgoing alpha values. 542 */ 543 544static void * 545get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 546 GLint x, GLint y) 547{ 548 ASSERT(rb->Format == MESA_FORMAT_RGB888); 549 /* No direct access since this buffer is RGB but caller will be 550 * treating it as if it were RGBA. 551 */ 552 return NULL; 553} 554 555 556static void 557get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 558 GLint x, GLint y, void *values) 559{ 560 const GLubyte *src = ((const GLubyte *) rb->Data) + 561 3 * (y * rb->RowStride + x); 562 GLubyte *dst = (GLubyte *) values; 563 GLuint i; 564 ASSERT(rb->Format == MESA_FORMAT_RGB888); 565 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 566 for (i = 0; i < count; i++) { 567 dst[i * 4 + 0] = src[i * 3 + 0]; 568 dst[i * 4 + 1] = src[i * 3 + 1]; 569 dst[i * 4 + 2] = src[i * 3 + 2]; 570 dst[i * 4 + 3] = 255; 571 } 572} 573 574 575static void 576get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 577 const GLint x[], const GLint y[], void *values) 578{ 579 GLubyte *dst = (GLubyte *) values; 580 GLuint i; 581 ASSERT(rb->Format == MESA_FORMAT_RGB888); 582 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 583 for (i = 0; i < count; i++) { 584 const GLubyte *src 585 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 586 dst[i * 4 + 0] = src[0]; 587 dst[i * 4 + 1] = src[1]; 588 dst[i * 4 + 2] = src[2]; 589 dst[i * 4 + 3] = 255; 590 } 591} 592 593 594static void 595put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 596 GLint x, GLint y, const void *values, const GLubyte *mask) 597{ 598 /* note: incoming values are RGB+A! */ 599 const GLubyte *src = (const GLubyte *) values; 600 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 601 GLuint i; 602 ASSERT(rb->Format == MESA_FORMAT_RGB888); 603 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 604 for (i = 0; i < count; i++) { 605 if (!mask || mask[i]) { 606 dst[i * 3 + 0] = src[i * 4 + 0]; 607 dst[i * 3 + 1] = src[i * 4 + 1]; 608 dst[i * 3 + 2] = src[i * 4 + 2]; 609 } 610 } 611} 612 613 614static void 615put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 616 GLint x, GLint y, const void *values, const GLubyte *mask) 617{ 618 /* note: incoming values are RGB+A! */ 619 const GLubyte *src = (const GLubyte *) values; 620 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 621 GLuint i; 622 ASSERT(rb->Format == MESA_FORMAT_RGB888); 623 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 624 for (i = 0; i < count; i++) { 625 if (!mask || mask[i]) { 626 dst[i * 3 + 0] = src[i * 3 + 0]; 627 dst[i * 3 + 1] = src[i * 3 + 1]; 628 dst[i * 3 + 2] = src[i * 3 + 2]; 629 } 630 } 631} 632 633 634static void 635put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 636 GLint x, GLint y, const void *value, const GLubyte *mask) 637{ 638 /* note: incoming value is RGB+A! */ 639 const GLubyte val0 = ((const GLubyte *) value)[0]; 640 const GLubyte val1 = ((const GLubyte *) value)[1]; 641 const GLubyte val2 = ((const GLubyte *) value)[2]; 642 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 643 ASSERT(rb->Format == MESA_FORMAT_RGB888); 644 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 645 if (!mask && val0 == val1 && val1 == val2) { 646 /* optimized case */ 647 memset(dst, val0, 3 * count); 648 } 649 else { 650 GLuint i; 651 for (i = 0; i < count; i++) { 652 if (!mask || mask[i]) { 653 dst[i * 3 + 0] = val0; 654 dst[i * 3 + 1] = val1; 655 dst[i * 3 + 2] = val2; 656 } 657 } 658 } 659} 660 661 662static void 663put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 664 const GLint x[], const GLint y[], const void *values, 665 const GLubyte *mask) 666{ 667 /* note: incoming values are RGB+A! */ 668 const GLubyte *src = (const GLubyte *) values; 669 GLuint i; 670 ASSERT(rb->Format == MESA_FORMAT_RGB888); 671 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 672 for (i = 0; i < count; i++) { 673 if (!mask || mask[i]) { 674 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 675 dst[0] = src[i * 4 + 0]; 676 dst[1] = src[i * 4 + 1]; 677 dst[2] = src[i * 4 + 2]; 678 } 679 } 680} 681 682 683static void 684put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 685 GLuint count, const GLint x[], const GLint y[], 686 const void *value, const GLubyte *mask) 687{ 688 /* note: incoming value is RGB+A! */ 689 const GLubyte val0 = ((const GLubyte *) value)[0]; 690 const GLubyte val1 = ((const GLubyte *) value)[1]; 691 const GLubyte val2 = ((const GLubyte *) value)[2]; 692 GLuint i; 693 ASSERT(rb->Format == MESA_FORMAT_RGB888); 694 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 695 for (i = 0; i < count; i++) { 696 if (!mask || mask[i]) { 697 GLubyte *dst = ((GLubyte *) rb->Data) + 698 3 * (y[i] * rb->RowStride + x[i]); 699 dst[0] = val0; 700 dst[1] = val1; 701 dst[2] = val2; 702 } 703 } 704} 705 706 707/********************************************************************** 708 * Functions for buffers of 4 X GLubyte (or GLbyte) values. 709 * Typically color buffers. 710 */ 711 712static void 713get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 714 const GLint x[], const GLint y[], void *values) 715{ 716 /* treat 4*GLubyte as 1*GLuint */ 717 GLuint *dst = (GLuint *) values; 718 GLuint i; 719 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 720 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 721 for (i = 0; i < count; i++) { 722 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 723 dst[i] = *src; 724 } 725} 726 727 728static void 729put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 730 GLint x, GLint y, const void *values, const GLubyte *mask) 731{ 732 /* treat 4*GLubyte as 1*GLuint */ 733 const GLuint *src = (const GLuint *) values; 734 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 735 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 736 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 737 if (mask) { 738 GLuint i; 739 for (i = 0; i < count; i++) { 740 if (mask[i]) { 741 dst[i] = src[i]; 742 } 743 } 744 } 745 else { 746 memcpy(dst, src, 4 * count * sizeof(GLubyte)); 747 } 748} 749 750 751static void 752put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 753 GLint x, GLint y, const void *values, const GLubyte *mask) 754{ 755 /* Store RGB values in RGBA buffer */ 756 const GLubyte *src = (const GLubyte *) values; 757 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); 758 GLuint i; 759 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 760 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 761 for (i = 0; i < count; i++) { 762 if (!mask || mask[i]) { 763 dst[i * 4 + 0] = src[i * 3 + 0]; 764 dst[i * 4 + 1] = src[i * 3 + 1]; 765 dst[i * 4 + 2] = src[i * 3 + 2]; 766 dst[i * 4 + 3] = 0xff; 767 } 768 } 769} 770 771 772static void 773put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 774 GLint x, GLint y, const void *value, const GLubyte *mask) 775{ 776 /* treat 4*GLubyte as 1*GLuint */ 777 const GLuint val = *((const GLuint *) value); 778 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 779 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 780 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 781 if (!mask && val == 0) { 782 /* common case */ 783 memset(dst, 0, count * 4 * sizeof(GLubyte)); 784 } 785 else { 786 /* general case */ 787 if (mask) { 788 GLuint i; 789 for (i = 0; i < count; i++) { 790 if (mask[i]) { 791 dst[i] = val; 792 } 793 } 794 } 795 else { 796 GLuint i; 797 for (i = 0; i < count; i++) { 798 dst[i] = val; 799 } 800 } 801 } 802} 803 804 805static void 806put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 807 const GLint x[], const GLint y[], const void *values, 808 const GLubyte *mask) 809{ 810 /* treat 4*GLubyte as 1*GLuint */ 811 const GLuint *src = (const GLuint *) values; 812 GLuint i; 813 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 814 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 815 for (i = 0; i < count; i++) { 816 if (!mask || mask[i]) { 817 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 818 *dst = src[i]; 819 } 820 } 821} 822 823 824static void 825put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, 826 GLuint count, const GLint x[], const GLint y[], 827 const void *value, const GLubyte *mask) 828{ 829 /* treat 4*GLubyte as 1*GLuint */ 830 const GLuint val = *((const GLuint *) value); 831 GLuint i; 832 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 833 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 834 for (i = 0; i < count; i++) { 835 if (!mask || mask[i]) { 836 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 837 *dst = val; 838 } 839 } 840} 841 842 843/********************************************************************** 844 * Functions for buffers of 4 X GLushort (or GLshort) values. 845 * Typically accum buffer. 846 */ 847 848static void 849get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 850 const GLint x[], const GLint y[], void *values) 851{ 852 GLushort *dst = (GLushort *) values; 853 GLuint i; 854 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 855 for (i = 0; i < count; i++) { 856 const GLushort *src 857 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); 858 dst[i] = *src; 859 } 860} 861 862 863static void 864put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 865 GLint x, GLint y, const void *values, const GLubyte *mask) 866{ 867 const GLushort *src = (const GLushort *) values; 868 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 869 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 870 if (mask) { 871 GLuint i; 872 for (i = 0; i < count; i++) { 873 if (mask[i]) { 874 dst[i * 4 + 0] = src[i * 4 + 0]; 875 dst[i * 4 + 1] = src[i * 4 + 1]; 876 dst[i * 4 + 2] = src[i * 4 + 2]; 877 dst[i * 4 + 3] = src[i * 4 + 3]; 878 } 879 } 880 } 881 else { 882 memcpy(dst, src, 4 * count * sizeof(GLushort)); 883 } 884} 885 886 887static void 888put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 889 GLint x, GLint y, const void *values, const GLubyte *mask) 890{ 891 /* Put RGB values in RGBA buffer */ 892 const GLushort *src = (const GLushort *) values; 893 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 894 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 895 if (mask) { 896 GLuint i; 897 for (i = 0; i < count; i++) { 898 if (mask[i]) { 899 dst[i * 4 + 0] = src[i * 3 + 0]; 900 dst[i * 4 + 1] = src[i * 3 + 1]; 901 dst[i * 4 + 2] = src[i * 3 + 2]; 902 dst[i * 4 + 3] = 0xffff; 903 } 904 } 905 } 906 else { 907 memcpy(dst, src, 4 * count * sizeof(GLushort)); 908 } 909} 910 911 912static void 913put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 914 GLint x, GLint y, const void *value, const GLubyte *mask) 915{ 916 const GLushort val0 = ((const GLushort *) value)[0]; 917 const GLushort val1 = ((const GLushort *) value)[1]; 918 const GLushort val2 = ((const GLushort *) value)[2]; 919 const GLushort val3 = ((const GLushort *) value)[3]; 920 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 921 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 922 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 923 /* common case for clearing accum buffer */ 924 memset(dst, 0, count * 4 * sizeof(GLushort)); 925 } 926 else { 927 GLuint i; 928 for (i = 0; i < count; i++) { 929 if (!mask || mask[i]) { 930 dst[i * 4 + 0] = val0; 931 dst[i * 4 + 1] = val1; 932 dst[i * 4 + 2] = val2; 933 dst[i * 4 + 3] = val3; 934 } 935 } 936 } 937} 938 939 940static void 941put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 942 const GLint x[], const GLint y[], const void *values, 943 const GLubyte *mask) 944{ 945 const GLushort *src = (const GLushort *) values; 946 GLuint i; 947 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 948 for (i = 0; i < count; i++) { 949 if (!mask || mask[i]) { 950 GLushort *dst = 951 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); 952 dst[0] = src[i * 4 + 0]; 953 dst[1] = src[i * 4 + 1]; 954 dst[2] = src[i * 4 + 2]; 955 dst[3] = src[i * 4 + 3]; 956 } 957 } 958} 959 960 961static void 962put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, 963 GLuint count, const GLint x[], const GLint y[], 964 const void *value, const GLubyte *mask) 965{ 966 const GLushort val0 = ((const GLushort *) value)[0]; 967 const GLushort val1 = ((const GLushort *) value)[1]; 968 const GLushort val2 = ((const GLushort *) value)[2]; 969 const GLushort val3 = ((const GLushort *) value)[3]; 970 GLuint i; 971 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 972 for (i = 0; i < count; i++) { 973 if (!mask || mask[i]) { 974 GLushort *dst = ((GLushort *) rb->Data) + 975 4 * (y[i] * rb->RowStride + x[i]); 976 dst[0] = val0; 977 dst[1] = val1; 978 dst[2] = val2; 979 dst[3] = val3; 980 } 981 } 982} 983 984/********************************************************************** 985 * Functions for MESA_FORMAT_R8. 986 */ 987static void 988get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 989 GLint x, GLint y, void *values) 990{ 991 const GLubyte *src = rb->GetPointer(ctx, rb, x, y); 992 GLuint *dst = values; 993 GLuint i; 994 995 for (i = 0; i < count; i++) { 996 dst[i] = 0xff000000 | src[i]; 997 } 998} 999 1000static void 1001get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1002 const GLint x[], const GLint y[], void *values) 1003{ 1004 GLuint *dst = (GLuint *) values; 1005 GLuint i; 1006 1007 for (i = 0; i < count; i++) { 1008 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1009 dst[i] = 0xff000000 | *src; 1010 } 1011} 1012 1013/********************************************************************** 1014 * Functions for MESA_FORMAT_RG88. 1015 */ 1016static void 1017get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1018 GLint x, GLint y, void *values) 1019{ 1020 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1021 GLuint *dst = values; 1022 GLuint i; 1023 1024 for (i = 0; i < count; i++) { 1025 dst[i] = 0xff000000 | src[i]; 1026 } 1027} 1028 1029static void 1030get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, 1031 GLuint count, const GLint x[], const GLint y[], void *values) 1032{ 1033 GLuint *dst = (GLuint *) values; 1034 GLuint i; 1035 1036 for (i = 0; i < count; i++) { 1037 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1038 dst[i] = 0xff000000 | *src; 1039 } 1040} 1041 1042/********************************************************************** 1043 * Functions for MESA_FORMAT_R16. 1044 */ 1045static void 1046get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1047 GLint x, GLint y, void *values) 1048{ 1049 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1050 GLushort *dst = values; 1051 GLuint i; 1052 1053 for (i = 0; i < count; i++) { 1054 dst[i * 4 + RCOMP] = src[i]; 1055 dst[i * 4 + GCOMP] = 0; 1056 dst[i * 4 + BCOMP] = 0; 1057 dst[i * 4 + ACOMP] = 0xffff; 1058 } 1059} 1060 1061static void 1062get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1063 const GLint x[], const GLint y[], void *values) 1064{ 1065 GLushort *dst = values; 1066 GLuint i; 1067 1068 for (i = 0; i < count; i++) { 1069 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1070 dst[i * 4 + RCOMP] = *src; 1071 dst[i * 4 + GCOMP] = 0; 1072 dst[i * 4 + BCOMP] = 0; 1073 dst[i * 4 + ACOMP] = 0xffff; 1074 } 1075} 1076 1077/********************************************************************** 1078 * Functions for MESA_FORMAT_RG1616. 1079 */ 1080static void 1081get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1082 GLint x, GLint y, void *values) 1083{ 1084 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1085 GLushort *dst = values; 1086 GLuint i; 1087 1088 for (i = 0; i < count; i++) { 1089 dst[i * 4 + RCOMP] = src[i * 2]; 1090 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1091 dst[i * 4 + BCOMP] = 0; 1092 dst[i * 4 + ACOMP] = 0xffff; 1093 } 1094} 1095 1096static void 1097get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, 1098 GLuint count, const GLint x[], const GLint y[], void *values) 1099{ 1100 GLushort *dst = values; 1101 GLuint i; 1102 1103 for (i = 0; i < count; i++) { 1104 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1105 dst[i * 4 + RCOMP] = src[0]; 1106 dst[i * 4 + GCOMP] = src[1]; 1107 dst[i * 4 + BCOMP] = 0; 1108 dst[i * 4 + ACOMP] = 0xffff; 1109 } 1110} 1111 1112/********************************************************************** 1113 * Functions for MESA_FORMAT_INTENSITY_FLOAT32. 1114 */ 1115static void 1116get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1117 GLuint count, GLint x, GLint y, void *values) 1118{ 1119 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1120 GLfloat *dst = values; 1121 GLuint i; 1122 1123 for (i = 0; i < count; i++) { 1124 dst[i * 4 + RCOMP] = 1125 dst[i * 4 + GCOMP] = 1126 dst[i * 4 + BCOMP] = 1127 dst[i * 4 + ACOMP] = src[i]; 1128 } 1129} 1130 1131static void 1132get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1133 GLuint count, const GLint x[], const GLint y[], 1134 void *values) 1135{ 1136 GLfloat *dst = values; 1137 GLuint i; 1138 1139 for (i = 0; i < count; i++) { 1140 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1141 dst[i * 4 + RCOMP] = 1142 dst[i * 4 + GCOMP] = 1143 dst[i * 4 + BCOMP] = 1144 dst[i * 4 + ACOMP] = src[0]; 1145 } 1146} 1147 1148/********************************************************************** 1149 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. 1150 */ 1151static void 1152get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1153 GLuint count, GLint x, GLint y, void *values) 1154{ 1155 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1156 GLfloat *dst = values; 1157 GLuint i; 1158 1159 for (i = 0; i < count; i++) { 1160 dst[i * 4 + RCOMP] = 1161 dst[i * 4 + GCOMP] = 1162 dst[i * 4 + BCOMP] = src[i]; 1163 dst[i * 4 + ACOMP] = 1.0; 1164 } 1165} 1166 1167static void 1168get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1169 GLuint count, const GLint x[], const GLint y[], 1170 void *values) 1171{ 1172 GLfloat *dst = values; 1173 GLuint i; 1174 1175 for (i = 0; i < count; i++) { 1176 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1177 dst[i * 4 + RCOMP] = 1178 dst[i * 4 + GCOMP] = 1179 dst[i * 4 + BCOMP] = src[0]; 1180 dst[i * 4 + ACOMP] = 1.0; 1181 } 1182} 1183 1184/********************************************************************** 1185 * Functions for MESA_FORMAT_ALPHA_FLOAT32. 1186 */ 1187static void 1188get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1189 GLuint count, GLint x, GLint y, void *values) 1190{ 1191 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1192 GLfloat *dst = values; 1193 GLuint i; 1194 1195 for (i = 0; i < count; i++) { 1196 dst[i * 4 + RCOMP] = 0.0; 1197 dst[i * 4 + GCOMP] = 0.0; 1198 dst[i * 4 + BCOMP] = 0.0; 1199 dst[i * 4 + ACOMP] = src[i]; 1200 } 1201} 1202 1203static void 1204get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1205 GLuint count, const GLint x[], const GLint y[], 1206 void *values) 1207{ 1208 GLfloat *dst = values; 1209 GLuint i; 1210 1211 for (i = 0; i < count; i++) { 1212 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1213 dst[i * 4 + RCOMP] = 0.0; 1214 dst[i * 4 + GCOMP] = 0.0; 1215 dst[i * 4 + BCOMP] = 0.0; 1216 dst[i * 4 + ACOMP] = src[0]; 1217 } 1218} 1219 1220static void 1221put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1222 GLuint count, GLint x, GLint y, 1223 const void *values, const GLubyte *mask) 1224{ 1225 float *dst = rb->GetPointer(ctx, rb, x, y); 1226 const float *src = values; 1227 unsigned int i; 1228 1229 if (mask) { 1230 for (i = 0; i < count; i++) { 1231 if (mask[i]) { 1232 dst[i] = src[i * 4 + ACOMP]; 1233 } 1234 } 1235 } 1236 else { 1237 for (i = 0; i < count; i++) { 1238 dst[i] = src[i * 4 + ACOMP]; 1239 } 1240 } 1241} 1242 1243static void 1244put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1245 GLuint count, GLint x, GLint y, 1246 const void *value, const GLubyte *mask) 1247{ 1248 float *dst = rb->GetPointer(ctx, rb, x, y); 1249 const float *src = value; 1250 unsigned int i; 1251 1252 if (mask) { 1253 for (i = 0; i < count; i++) { 1254 if (mask[i]) { 1255 dst[i] = src[ACOMP]; 1256 } 1257 } 1258 } 1259 else { 1260 for (i = 0; i < count; i++) { 1261 dst[i] = src[ACOMP]; 1262 } 1263 } 1264} 1265 1266static void 1267put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1268 GLuint count, const GLint x[], const GLint y[], 1269 const void *values, const GLubyte *mask) 1270{ 1271 const float *src = values; 1272 unsigned int i; 1273 1274 for (i = 0; i < count; i++) { 1275 if (!mask || mask[i]) { 1276 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1277 1278 *dst = src[i * 4 + ACOMP]; 1279 } 1280 } 1281} 1282 1283static void 1284put_mono_values_a_float32(struct gl_context *ctx, 1285 struct gl_renderbuffer *rb, 1286 GLuint count, const GLint x[], const GLint y[], 1287 const void *value, const GLubyte *mask) 1288{ 1289 const float *src = value; 1290 unsigned int i; 1291 1292 for (i = 0; i < count; i++) { 1293 if (!mask || mask[i]) { 1294 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1295 *dst = src[ACOMP]; 1296 } 1297 } 1298} 1299 1300/********************************************************************** 1301 * Functions for MESA_FORMAT_R_FLOAT32. 1302 */ 1303static void 1304get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1305 GLuint count, GLint x, GLint y, void *values) 1306{ 1307 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1308 GLfloat *dst = values; 1309 GLuint i; 1310 1311 for (i = 0; i < count; i++) { 1312 dst[i * 4 + RCOMP] = src[i]; 1313 dst[i * 4 + GCOMP] = 0.0; 1314 dst[i * 4 + BCOMP] = 0.0; 1315 dst[i * 4 + ACOMP] = 1.0; 1316 } 1317} 1318 1319static void 1320get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1321 GLuint count, const GLint x[], const GLint y[], 1322 void *values) 1323{ 1324 GLfloat *dst = values; 1325 GLuint i; 1326 1327 for (i = 0; i < count; i++) { 1328 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1329 dst[i * 4 + RCOMP] = src[0]; 1330 dst[i * 4 + GCOMP] = 0.0; 1331 dst[i * 4 + BCOMP] = 0.0; 1332 dst[i * 4 + ACOMP] = 1.0; 1333 } 1334} 1335 1336/********************************************************************** 1337 * Functions for MESA_FORMAT_RG_FLOAT32. 1338 */ 1339static void 1340get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1341 GLuint count, GLint x, GLint y, void *values) 1342{ 1343 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1344 GLfloat *dst = values; 1345 GLuint i; 1346 1347 for (i = 0; i < count; i++) { 1348 dst[i * 4 + RCOMP] = src[i * 2 + 0]; 1349 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1350 dst[i * 4 + BCOMP] = 0.0; 1351 dst[i * 4 + ACOMP] = 1.0; 1352 } 1353} 1354 1355static void 1356get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1357 GLuint count, const GLint x[], const GLint y[], 1358 void *values) 1359{ 1360 GLfloat *dst = values; 1361 GLuint i; 1362 1363 for (i = 0; i < count; i++) { 1364 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1365 dst[i * 4 + RCOMP] = src[0]; 1366 dst[i * 4 + GCOMP] = src[1]; 1367 dst[i * 4 + BCOMP] = 0.0; 1368 dst[i * 4 + ACOMP] = 1.0; 1369 } 1370} 1371 1372/** 1373 * This is the default software fallback for gl_renderbuffer's span 1374 * access functions. 1375 * 1376 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels 1377 * are packed in the type of rb->Format, and that subsequent rows appear 1378 * rb->RowStride pixels later. 1379 */ 1380void 1381_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb) 1382{ 1383 rb->GetPointer = get_pointer_generic; 1384 rb->GetRow = get_row_generic; 1385 1386 switch (rb->Format) { 1387 case MESA_FORMAT_RGB888: 1388 rb->DataType = GL_UNSIGNED_BYTE; 1389 rb->GetPointer = get_pointer_ubyte3; 1390 rb->GetRow = get_row_ubyte3; 1391 rb->GetValues = get_values_ubyte3; 1392 rb->PutRow = put_row_ubyte3; 1393 rb->PutRowRGB = put_row_rgb_ubyte3; 1394 rb->PutMonoRow = put_mono_row_ubyte3; 1395 rb->PutValues = put_values_ubyte3; 1396 rb->PutMonoValues = put_mono_values_ubyte3; 1397 break; 1398 1399 case MESA_FORMAT_RGBA8888: 1400 rb->DataType = GL_UNSIGNED_BYTE; 1401 rb->GetValues = get_values_ubyte4; 1402 rb->PutRow = put_row_ubyte4; 1403 rb->PutRowRGB = put_row_rgb_ubyte4; 1404 rb->PutMonoRow = put_mono_row_ubyte4; 1405 rb->PutValues = put_values_ubyte4; 1406 rb->PutMonoValues = put_mono_values_ubyte4; 1407 break; 1408 1409 case MESA_FORMAT_R8: 1410 rb->DataType = GL_UNSIGNED_BYTE; 1411 rb->GetValues = get_values_r8; 1412 rb->GetRow = get_row_r8; 1413 rb->PutRow = put_row_generic; 1414 rb->PutRowRGB = put_row_generic; 1415 rb->PutMonoRow = put_mono_row_generic; 1416 rb->PutValues = put_values_generic; 1417 rb->PutMonoValues = put_mono_values_generic; 1418 break; 1419 1420 case MESA_FORMAT_RG88: 1421 rb->DataType = GL_UNSIGNED_BYTE; 1422 rb->GetValues = get_values_rg88; 1423 rb->GetRow = get_row_rg88; 1424 rb->PutRow = put_row_generic; 1425 rb->PutRowRGB = put_row_generic; 1426 rb->PutMonoRow = put_mono_row_generic; 1427 rb->PutValues = put_values_generic; 1428 rb->PutMonoValues = put_mono_values_generic; 1429 break; 1430 1431 case MESA_FORMAT_R16: 1432 rb->DataType = GL_UNSIGNED_SHORT; 1433 rb->GetValues = get_values_r16; 1434 rb->GetRow = get_row_r16; 1435 rb->PutRow = put_row_generic; 1436 rb->PutRowRGB = put_row_generic; 1437 rb->PutMonoRow = put_mono_row_generic; 1438 rb->PutValues = put_values_generic; 1439 rb->PutMonoValues = put_mono_values_generic; 1440 break; 1441 1442 case MESA_FORMAT_RG1616: 1443 rb->DataType = GL_UNSIGNED_SHORT; 1444 rb->GetValues = get_values_rg1616; 1445 rb->GetRow = get_row_rg1616; 1446 rb->PutRow = put_row_generic; 1447 rb->PutRowRGB = put_row_generic; 1448 rb->PutMonoRow = put_mono_row_generic; 1449 rb->PutValues = put_values_generic; 1450 rb->PutMonoValues = put_mono_values_generic; 1451 break; 1452 1453 case MESA_FORMAT_SIGNED_RGBA_16: 1454 rb->DataType = GL_SHORT; 1455 rb->GetValues = get_values_ushort4; 1456 rb->PutRow = put_row_ushort4; 1457 rb->PutRowRGB = put_row_rgb_ushort4; 1458 rb->PutMonoRow = put_mono_row_ushort4; 1459 rb->PutValues = put_values_ushort4; 1460 rb->PutMonoValues = put_mono_values_ushort4; 1461 break; 1462 1463#if 0 1464 case MESA_FORMAT_A8: 1465 rb->DataType = GL_UNSIGNED_BYTE; 1466 rb->GetValues = get_values_alpha8; 1467 rb->PutRow = put_row_alpha8; 1468 rb->PutRowRGB = NULL; 1469 rb->PutMonoRow = put_mono_row_alpha8; 1470 rb->PutValues = put_values_alpha8; 1471 rb->PutMonoValues = put_mono_values_alpha8; 1472 break; 1473#endif 1474 1475 case MESA_FORMAT_S8: 1476 rb->DataType = GL_UNSIGNED_BYTE; 1477 rb->GetValues = get_values_ubyte; 1478 rb->PutRow = put_row_ubyte; 1479 rb->PutRowRGB = NULL; 1480 rb->PutMonoRow = put_mono_row_ubyte; 1481 rb->PutValues = put_values_ubyte; 1482 rb->PutMonoValues = put_mono_values_ubyte; 1483 break; 1484 1485 case MESA_FORMAT_Z16: 1486 rb->DataType = GL_UNSIGNED_SHORT; 1487 rb->GetValues = get_values_ushort; 1488 rb->PutRow = put_row_ushort; 1489 rb->PutRowRGB = NULL; 1490 rb->PutMonoRow = put_mono_row_ushort; 1491 rb->PutValues = put_values_ushort; 1492 rb->PutMonoValues = put_mono_values_ushort; 1493 break; 1494 1495 case MESA_FORMAT_Z32: 1496 case MESA_FORMAT_X8_Z24: 1497 case MESA_FORMAT_Z24_X8: 1498 rb->DataType = GL_UNSIGNED_INT; 1499 rb->GetValues = get_values_uint; 1500 rb->PutRow = put_row_uint; 1501 rb->PutRowRGB = NULL; 1502 rb->PutMonoRow = put_mono_row_uint; 1503 rb->PutValues = put_values_uint; 1504 rb->PutMonoValues = put_mono_values_uint; 1505 break; 1506 1507 case MESA_FORMAT_Z24_S8: 1508 case MESA_FORMAT_S8_Z24: 1509 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 1510 rb->GetValues = get_values_uint; 1511 rb->PutRow = put_row_uint; 1512 rb->PutRowRGB = NULL; 1513 rb->PutMonoRow = put_mono_row_uint; 1514 rb->PutValues = put_values_uint; 1515 rb->PutMonoValues = put_mono_values_uint; 1516 break; 1517 1518 case MESA_FORMAT_RGBA_FLOAT32: 1519 rb->GetRow = get_row_generic; 1520 rb->GetValues = get_values_generic; 1521 rb->PutRow = put_row_generic; 1522 rb->PutRowRGB = NULL; 1523 rb->PutMonoRow = put_mono_row_generic; 1524 rb->PutValues = put_values_generic; 1525 rb->PutMonoValues = put_mono_values_generic; 1526 break; 1527 1528 case MESA_FORMAT_INTENSITY_FLOAT32: 1529 rb->GetRow = get_row_i_float32; 1530 rb->GetValues = get_values_i_float32; 1531 rb->PutRow = put_row_generic; 1532 rb->PutRowRGB = NULL; 1533 rb->PutMonoRow = put_mono_row_generic; 1534 rb->PutValues = put_values_generic; 1535 rb->PutMonoValues = put_mono_values_generic; 1536 break; 1537 1538 case MESA_FORMAT_LUMINANCE_FLOAT32: 1539 rb->GetRow = get_row_l_float32; 1540 rb->GetValues = get_values_l_float32; 1541 rb->PutRow = put_row_generic; 1542 rb->PutRowRGB = NULL; 1543 rb->PutMonoRow = put_mono_row_generic; 1544 rb->PutValues = put_values_generic; 1545 rb->PutMonoValues = put_mono_values_generic; 1546 break; 1547 1548 case MESA_FORMAT_ALPHA_FLOAT32: 1549 rb->GetRow = get_row_a_float32; 1550 rb->GetValues = get_values_a_float32; 1551 rb->PutRow = put_row_a_float32; 1552 rb->PutRowRGB = NULL; 1553 rb->PutMonoRow = put_mono_row_a_float32; 1554 rb->PutValues = put_values_a_float32; 1555 rb->PutMonoValues = put_mono_values_a_float32; 1556 break; 1557 1558 case MESA_FORMAT_RG_FLOAT32: 1559 rb->GetRow = get_row_rg_float32; 1560 rb->GetValues = get_values_rg_float32; 1561 rb->PutRow = put_row_generic; 1562 rb->PutRowRGB = NULL; 1563 rb->PutMonoRow = put_mono_row_generic; 1564 rb->PutValues = put_values_generic; 1565 rb->PutMonoValues = put_mono_values_generic; 1566 break; 1567 1568 case MESA_FORMAT_R_FLOAT32: 1569 rb->GetRow = get_row_r_float32; 1570 rb->GetValues = get_values_r_float32; 1571 rb->PutRow = put_row_generic; 1572 rb->PutRowRGB = NULL; 1573 rb->PutMonoRow = put_mono_row_generic; 1574 rb->PutValues = put_values_generic; 1575 rb->PutMonoValues = put_mono_values_generic; 1576 break; 1577 1578 default: 1579 break; 1580 } 1581} 1582 1583/** 1584 * This is a software fallback for the gl_renderbuffer->AllocStorage 1585 * function. 1586 * Device drivers will typically override this function for the buffers 1587 * which it manages (typically color buffers, Z and stencil). 1588 * Other buffers (like software accumulation and aux buffers) which the driver 1589 * doesn't manage can be handled with this function. 1590 * 1591 * This one multi-purpose function can allocate stencil, depth, accum, color 1592 * or color-index buffers! 1593 * 1594 * This function also plugs in the appropriate GetPointer, Get/PutRow and 1595 * Get/PutValues functions. 1596 */ 1597GLboolean 1598_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 1599 GLenum internalFormat, 1600 GLuint width, GLuint height) 1601{ 1602 switch (internalFormat) { 1603 case GL_RGB: 1604 case GL_R3_G3_B2: 1605 case GL_RGB4: 1606 case GL_RGB5: 1607 case GL_RGB8: 1608 case GL_RGB10: 1609 case GL_RGB12: 1610 case GL_RGB16: 1611 rb->Format = MESA_FORMAT_RGB888; 1612 break; 1613 case GL_RGBA: 1614 case GL_RGBA2: 1615 case GL_RGBA4: 1616 case GL_RGB5_A1: 1617 case GL_RGBA8: 1618#if 1 1619 case GL_RGB10_A2: 1620 case GL_RGBA12: 1621#endif 1622 rb->Format = MESA_FORMAT_RGBA8888; 1623 break; 1624 case GL_RGBA16: 1625 case GL_RGBA16_SNORM: 1626 /* for accum buffer */ 1627 rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 1628 break; 1629#if 0 1630 case GL_ALPHA8: 1631 rb->Format = MESA_FORMAT_A8; 1632 break; 1633#endif 1634 case GL_STENCIL_INDEX: 1635 case GL_STENCIL_INDEX1_EXT: 1636 case GL_STENCIL_INDEX4_EXT: 1637 case GL_STENCIL_INDEX8_EXT: 1638 case GL_STENCIL_INDEX16_EXT: 1639 rb->Format = MESA_FORMAT_S8; 1640 break; 1641 case GL_DEPTH_COMPONENT: 1642 case GL_DEPTH_COMPONENT16: 1643 rb->Format = MESA_FORMAT_Z16; 1644 break; 1645 case GL_DEPTH_COMPONENT24: 1646 rb->Format = MESA_FORMAT_X8_Z24; 1647 break; 1648 case GL_DEPTH_COMPONENT32: 1649 rb->Format = MESA_FORMAT_Z32; 1650 break; 1651 case GL_DEPTH_STENCIL_EXT: 1652 case GL_DEPTH24_STENCIL8_EXT: 1653 rb->Format = MESA_FORMAT_Z24_S8; 1654 break; 1655 default: 1656 /* unsupported format */ 1657 return GL_FALSE; 1658 } 1659 1660 _mesa_set_renderbuffer_accessors(rb); 1661 1662 ASSERT(rb->DataType); 1663 ASSERT(rb->GetPointer); 1664 ASSERT(rb->GetRow); 1665 ASSERT(rb->GetValues); 1666 ASSERT(rb->PutRow); 1667 ASSERT(rb->PutMonoRow); 1668 ASSERT(rb->PutValues); 1669 ASSERT(rb->PutMonoValues); 1670 1671 /* free old buffer storage */ 1672 if (rb->Data) { 1673 free(rb->Data); 1674 rb->Data = NULL; 1675 } 1676 1677 rb->RowStride = width; 1678 1679 if (width > 0 && height > 0) { 1680 /* allocate new buffer storage */ 1681 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); 1682 1683 if (rb->Data == NULL) { 1684 rb->Width = 0; 1685 rb->Height = 0; 1686 rb->RowStride = 0; 1687 _mesa_error(ctx, GL_OUT_OF_MEMORY, 1688 "software renderbuffer allocation (%d x %d x %d)", 1689 width, height, _mesa_get_format_bytes(rb->Format)); 1690 return GL_FALSE; 1691 } 1692 } 1693 1694 rb->Width = width; 1695 rb->Height = height; 1696 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 1697 1698 if (rb->Name == 0 && 1699 internalFormat == GL_RGBA16_SNORM && 1700 rb->_BaseFormat == 0) { 1701 /* NOTE: This is a special case just for accumulation buffers. 1702 * This is a very limited use case- there's no snorm texturing or 1703 * rendering going on. 1704 */ 1705 rb->_BaseFormat = GL_RGBA; 1706 } 1707 else { 1708 /* the internalFormat should have been error checked long ago */ 1709 ASSERT(rb->_BaseFormat); 1710 } 1711 1712 return GL_TRUE; 1713} 1714 1715 1716 1717/**********************************************************************/ 1718/**********************************************************************/ 1719/**********************************************************************/ 1720 1721 1722/** 1723 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha 1724 * buffer wrapper around an existing RGB renderbuffer (hw or sw). 1725 * 1726 * When PutRow is called (for example), we store the alpha values in 1727 * this buffer, then pass on the PutRow call to the wrapped RGB 1728 * buffer. 1729 */ 1730 1731 1732static GLboolean 1733alloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1734 GLenum internalFormat, GLuint width, GLuint height) 1735{ 1736 ASSERT(arb != arb->Wrapped); 1737 ASSERT(arb->Format == MESA_FORMAT_A8); 1738 1739 /* first, pass the call to the wrapped RGB buffer */ 1740 if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat, 1741 width, height)) { 1742 return GL_FALSE; 1743 } 1744 1745 /* next, resize my alpha buffer */ 1746 if (arb->Data) { 1747 free(arb->Data); 1748 } 1749 1750 arb->Data = malloc(width * height * sizeof(GLubyte)); 1751 if (arb->Data == NULL) { 1752 arb->Width = 0; 1753 arb->Height = 0; 1754 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 1755 return GL_FALSE; 1756 } 1757 1758 arb->Width = width; 1759 arb->Height = height; 1760 arb->RowStride = width; 1761 1762 return GL_TRUE; 1763} 1764 1765 1766/** 1767 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 1768 */ 1769static void 1770delete_renderbuffer_alpha8(struct gl_renderbuffer *arb) 1771{ 1772 if (arb->Data) { 1773 free(arb->Data); 1774 } 1775 ASSERT(arb->Wrapped); 1776 ASSERT(arb != arb->Wrapped); 1777 arb->Wrapped->Delete(arb->Wrapped); 1778 arb->Wrapped = NULL; 1779 free(arb); 1780} 1781 1782 1783static void * 1784get_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1785 GLint x, GLint y) 1786{ 1787 return NULL; /* don't allow direct access! */ 1788} 1789 1790 1791static void 1792get_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1793 GLint x, GLint y, void *values) 1794{ 1795 /* NOTE: 'values' is RGBA format! */ 1796 const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x; 1797 GLubyte *dst = (GLubyte *) values; 1798 GLuint i; 1799 ASSERT(arb != arb->Wrapped); 1800 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1801 /* first, pass the call to the wrapped RGB buffer */ 1802 arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values); 1803 /* second, fill in alpha values from this buffer! */ 1804 for (i = 0; i < count; i++) { 1805 dst[i * 4 + 3] = src[i]; 1806 } 1807} 1808 1809 1810static void 1811get_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1812 const GLint x[], const GLint y[], void *values) 1813{ 1814 GLubyte *dst = (GLubyte *) values; 1815 GLuint i; 1816 ASSERT(arb != arb->Wrapped); 1817 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1818 /* first, pass the call to the wrapped RGB buffer */ 1819 arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values); 1820 /* second, fill in alpha values from this buffer! */ 1821 for (i = 0; i < count; i++) { 1822 const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1823 dst[i * 4 + 3] = *src; 1824 } 1825} 1826 1827 1828static void 1829put_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1830 GLint x, GLint y, const void *values, const GLubyte *mask) 1831{ 1832 const GLubyte *src = (const GLubyte *) values; 1833 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1834 GLuint i; 1835 ASSERT(arb != arb->Wrapped); 1836 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1837 /* first, pass the call to the wrapped RGB buffer */ 1838 arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask); 1839 /* second, store alpha in our buffer */ 1840 for (i = 0; i < count; i++) { 1841 if (!mask || mask[i]) { 1842 dst[i] = src[i * 4 + 3]; 1843 } 1844 } 1845} 1846 1847 1848static void 1849put_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1850 GLint x, GLint y, const void *values, const GLubyte *mask) 1851{ 1852 const GLubyte *src = (const GLubyte *) values; 1853 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1854 GLuint i; 1855 ASSERT(arb != arb->Wrapped); 1856 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1857 /* first, pass the call to the wrapped RGB buffer */ 1858 arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask); 1859 /* second, store alpha in our buffer */ 1860 for (i = 0; i < count; i++) { 1861 if (!mask || mask[i]) { 1862 dst[i] = src[i * 4 + 3]; 1863 } 1864 } 1865} 1866 1867 1868static void 1869put_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1870 GLint x, GLint y, const void *value, const GLubyte *mask) 1871{ 1872 const GLubyte val = ((const GLubyte *) value)[3]; 1873 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1874 ASSERT(arb != arb->Wrapped); 1875 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1876 /* first, pass the call to the wrapped RGB buffer */ 1877 arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask); 1878 /* second, store alpha in our buffer */ 1879 if (mask) { 1880 GLuint i; 1881 for (i = 0; i < count; i++) { 1882 if (mask[i]) { 1883 dst[i] = val; 1884 } 1885 } 1886 } 1887 else { 1888 memset(dst, val, count); 1889 } 1890} 1891 1892 1893static void 1894put_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1895 const GLint x[], const GLint y[], 1896 const void *values, const GLubyte *mask) 1897{ 1898 const GLubyte *src = (const GLubyte *) values; 1899 GLuint i; 1900 ASSERT(arb != arb->Wrapped); 1901 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1902 /* first, pass the call to the wrapped RGB buffer */ 1903 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask); 1904 /* second, store alpha in our buffer */ 1905 for (i = 0; i < count; i++) { 1906 if (!mask || mask[i]) { 1907 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1908 *dst = src[i * 4 + 3]; 1909 } 1910 } 1911} 1912 1913 1914static void 1915put_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1916 GLuint count, const GLint x[], const GLint y[], 1917 const void *value, const GLubyte *mask) 1918{ 1919 const GLubyte val = ((const GLubyte *) value)[3]; 1920 GLuint i; 1921 ASSERT(arb != arb->Wrapped); 1922 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1923 /* first, pass the call to the wrapped RGB buffer */ 1924 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask); 1925 /* second, store alpha in our buffer */ 1926 for (i = 0; i < count; i++) { 1927 if (!mask || mask[i]) { 1928 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1929 *dst = val; 1930 } 1931 } 1932} 1933 1934 1935static void 1936copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) 1937{ 1938 ASSERT(dst->Format == MESA_FORMAT_A8); 1939 ASSERT(src->Format == MESA_FORMAT_A8); 1940 ASSERT(dst->Width == src->Width); 1941 ASSERT(dst->Height == src->Height); 1942 ASSERT(dst->RowStride == src->RowStride); 1943 1944 memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte)); 1945} 1946 1947 1948/**********************************************************************/ 1949/**********************************************************************/ 1950/**********************************************************************/ 1951 1952 1953/** 1954 * Default GetPointer routine. Always return NULL to indicate that 1955 * direct buffer access is not supported. 1956 */ 1957static void * 1958nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 1959{ 1960 return NULL; 1961} 1962 1963 1964/** 1965 * Initialize the fields of a gl_renderbuffer to default values. 1966 */ 1967void 1968_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 1969{ 1970 _glthread_INIT_MUTEX(rb->Mutex); 1971 1972 rb->ClassID = 0; 1973 rb->Name = name; 1974 rb->RefCount = 0; 1975 rb->Delete = _mesa_delete_renderbuffer; 1976 1977 /* The rest of these should be set later by the caller of this function or 1978 * the AllocStorage method: 1979 */ 1980 rb->AllocStorage = NULL; 1981 1982 rb->Width = 0; 1983 rb->Height = 0; 1984 rb->InternalFormat = GL_NONE; 1985 rb->Format = MESA_FORMAT_NONE; 1986 1987 rb->DataType = GL_NONE; 1988 rb->Data = NULL; 1989 1990 /* Point back to ourself so that we don't have to check for Wrapped==NULL 1991 * all over the drivers. 1992 */ 1993 rb->Wrapped = rb; 1994 1995 rb->GetPointer = nop_get_pointer; 1996 rb->GetRow = NULL; 1997 rb->GetValues = NULL; 1998 rb->PutRow = NULL; 1999 rb->PutRowRGB = NULL; 2000 rb->PutMonoRow = NULL; 2001 rb->PutValues = NULL; 2002 rb->PutMonoValues = NULL; 2003} 2004 2005 2006/** 2007 * Allocate a new gl_renderbuffer object. This can be used for user-created 2008 * renderbuffers or window-system renderbuffers. 2009 */ 2010struct gl_renderbuffer * 2011_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name) 2012{ 2013 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 2014 if (rb) { 2015 _mesa_init_renderbuffer(rb, name); 2016 } 2017 return rb; 2018} 2019 2020 2021/** 2022 * Delete a gl_framebuffer. 2023 * This is the default function for renderbuffer->Delete(). 2024 */ 2025void 2026_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 2027{ 2028 if (rb->Data) { 2029 free(rb->Data); 2030 } 2031 free(rb); 2032} 2033 2034 2035/** 2036 * Allocate a software-based renderbuffer. This is called via the 2037 * ctx->Driver.NewRenderbuffer() function when the user creates a new 2038 * renderbuffer. 2039 * This would not be used for hardware-based renderbuffers. 2040 */ 2041struct gl_renderbuffer * 2042_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) 2043{ 2044 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 2045 if (rb) { 2046 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2047 /* Normally, one would setup the PutRow, GetRow, etc functions here. 2048 * But we're doing that in the _mesa_soft_renderbuffer_storage() function 2049 * instead. 2050 */ 2051 } 2052 return rb; 2053} 2054 2055 2056/** 2057 * Add software-based color renderbuffers to the given framebuffer. 2058 * This is a helper routine for device drivers when creating a 2059 * window system framebuffer (not a user-created render/framebuffer). 2060 * Once this function is called, you can basically forget about this 2061 * renderbuffer; core Mesa will handle all the buffer management and 2062 * rendering! 2063 */ 2064GLboolean 2065_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2066 GLuint rgbBits, GLuint alphaBits, 2067 GLboolean frontLeft, GLboolean backLeft, 2068 GLboolean frontRight, GLboolean backRight) 2069{ 2070 gl_buffer_index b; 2071 2072 if (rgbBits > 16 || alphaBits > 16) { 2073 _mesa_problem(ctx, 2074 "Unsupported bit depth in _mesa_add_color_renderbuffers"); 2075 return GL_FALSE; 2076 } 2077 2078 assert(MAX_COLOR_ATTACHMENTS >= 4); 2079 2080 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 2081 struct gl_renderbuffer *rb; 2082 2083 if (b == BUFFER_FRONT_LEFT && !frontLeft) 2084 continue; 2085 else if (b == BUFFER_BACK_LEFT && !backLeft) 2086 continue; 2087 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 2088 continue; 2089 else if (b == BUFFER_BACK_RIGHT && !backRight) 2090 continue; 2091 2092 assert(fb->Attachment[b].Renderbuffer == NULL); 2093 2094 rb = _mesa_new_renderbuffer(ctx, 0); 2095 if (!rb) { 2096 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 2097 return GL_FALSE; 2098 } 2099 2100 if (rgbBits <= 8) { 2101 if (alphaBits) 2102 rb->Format = MESA_FORMAT_RGBA8888; 2103 else 2104 rb->Format = MESA_FORMAT_RGB888; 2105 } 2106 else { 2107 assert(rgbBits <= 16); 2108 rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/ 2109 } 2110 rb->InternalFormat = GL_RGBA; 2111 2112 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2113 _mesa_add_renderbuffer(fb, b, rb); 2114 } 2115 2116 return GL_TRUE; 2117} 2118 2119 2120/** 2121 * Add software-based alpha renderbuffers to the given framebuffer. 2122 * This is a helper routine for device drivers when creating a 2123 * window system framebuffer (not a user-created render/framebuffer). 2124 * Once this function is called, you can basically forget about this 2125 * renderbuffer; core Mesa will handle all the buffer management and 2126 * rendering! 2127 */ 2128GLboolean 2129_mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2130 GLuint alphaBits, 2131 GLboolean frontLeft, GLboolean backLeft, 2132 GLboolean frontRight, GLboolean backRight) 2133{ 2134 gl_buffer_index b; 2135 2136 /* for window system framebuffers only! */ 2137 assert(fb->Name == 0); 2138 2139 if (alphaBits > 8) { 2140 _mesa_problem(ctx, 2141 "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 2142 return GL_FALSE; 2143 } 2144 2145 assert(MAX_COLOR_ATTACHMENTS >= 4); 2146 2147 /* Wrap each of the RGB color buffers with an alpha renderbuffer. 2148 */ 2149 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 2150 struct gl_renderbuffer *arb; 2151 2152 if (b == BUFFER_FRONT_LEFT && !frontLeft) 2153 continue; 2154 else if (b == BUFFER_BACK_LEFT && !backLeft) 2155 continue; 2156 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 2157 continue; 2158 else if (b == BUFFER_BACK_RIGHT && !backRight) 2159 continue; 2160 2161 /* the RGB buffer to wrap must already exist!! */ 2162 assert(fb->Attachment[b].Renderbuffer); 2163 2164 /* only GLubyte supported for now */ 2165 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 2166 2167 /* allocate alpha renderbuffer */ 2168 arb = _mesa_new_renderbuffer(ctx, 0); 2169 if (!arb) { 2170 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 2171 return GL_FALSE; 2172 } 2173 2174 /* wrap the alpha renderbuffer around the RGB renderbuffer */ 2175 arb->Wrapped = fb->Attachment[b].Renderbuffer; 2176 2177 /* Set up my alphabuffer fields and plug in my functions. 2178 * The functions will put/get the alpha values from/to RGBA arrays 2179 * and then call the wrapped buffer's functions to handle the RGB 2180 * values. 2181 */ 2182 arb->InternalFormat = arb->Wrapped->InternalFormat; 2183 arb->Format = MESA_FORMAT_A8; 2184 arb->DataType = arb->Wrapped->DataType; 2185 arb->AllocStorage = alloc_storage_alpha8; 2186 arb->Delete = delete_renderbuffer_alpha8; 2187 arb->GetPointer = get_pointer_alpha8; 2188 arb->GetRow = get_row_alpha8; 2189 arb->GetValues = get_values_alpha8; 2190 arb->PutRow = put_row_alpha8; 2191 arb->PutRowRGB = put_row_rgb_alpha8; 2192 arb->PutMonoRow = put_mono_row_alpha8; 2193 arb->PutValues = put_values_alpha8; 2194 arb->PutMonoValues = put_mono_values_alpha8; 2195 2196 /* clear the pointer to avoid assertion/sanity check failure later */ 2197 fb->Attachment[b].Renderbuffer = NULL; 2198 2199 /* plug the alpha renderbuffer into the colorbuffer attachment */ 2200 _mesa_add_renderbuffer(fb, b, arb); 2201 } 2202 2203 return GL_TRUE; 2204} 2205 2206 2207/** 2208 * For framebuffers that use a software alpha channel wrapper 2209 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers, 2210 * copy the back buffer alpha channel into the front buffer alpha channel. 2211 */ 2212void 2213_mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb) 2214{ 2215 if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && 2216 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) 2217 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer, 2218 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); 2219 2220 2221 if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && 2222 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) 2223 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer, 2224 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); 2225} 2226 2227 2228/** 2229 * Add a software-based depth renderbuffer to the given framebuffer. 2230 * This is a helper routine for device drivers when creating a 2231 * window system framebuffer (not a user-created render/framebuffer). 2232 * Once this function is called, you can basically forget about this 2233 * renderbuffer; core Mesa will handle all the buffer management and 2234 * rendering! 2235 */ 2236GLboolean 2237_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2238 GLuint depthBits) 2239{ 2240 struct gl_renderbuffer *rb; 2241 2242 if (depthBits > 32) { 2243 _mesa_problem(ctx, 2244 "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 2245 return GL_FALSE; 2246 } 2247 2248 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 2249 2250 rb = _mesa_new_renderbuffer(ctx, 0); 2251 if (!rb) { 2252 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 2253 return GL_FALSE; 2254 } 2255 2256 if (depthBits <= 16) { 2257 rb->Format = MESA_FORMAT_Z16; 2258 rb->InternalFormat = GL_DEPTH_COMPONENT16; 2259 } 2260 else if (depthBits <= 24) { 2261 rb->Format = MESA_FORMAT_X8_Z24; 2262 rb->InternalFormat = GL_DEPTH_COMPONENT24; 2263 } 2264 else { 2265 rb->Format = MESA_FORMAT_Z32; 2266 rb->InternalFormat = GL_DEPTH_COMPONENT32; 2267 } 2268 2269 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2270 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 2271 2272 return GL_TRUE; 2273} 2274 2275 2276/** 2277 * Add a software-based stencil renderbuffer to the given framebuffer. 2278 * This is a helper routine for device drivers when creating a 2279 * window system framebuffer (not a user-created render/framebuffer). 2280 * Once this function is called, you can basically forget about this 2281 * renderbuffer; core Mesa will handle all the buffer management and 2282 * rendering! 2283 */ 2284GLboolean 2285_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2286 GLuint stencilBits) 2287{ 2288 struct gl_renderbuffer *rb; 2289 2290 if (stencilBits > 16) { 2291 _mesa_problem(ctx, 2292 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 2293 return GL_FALSE; 2294 } 2295 2296 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 2297 2298 rb = _mesa_new_renderbuffer(ctx, 0); 2299 if (!rb) { 2300 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 2301 return GL_FALSE; 2302 } 2303 2304 assert(stencilBits <= 8); 2305 rb->Format = MESA_FORMAT_S8; 2306 rb->InternalFormat = GL_STENCIL_INDEX8; 2307 2308 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2309 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 2310 2311 return GL_TRUE; 2312} 2313 2314 2315/** 2316 * Add a software-based accumulation renderbuffer to the given framebuffer. 2317 * This is a helper routine for device drivers when creating a 2318 * window system framebuffer (not a user-created render/framebuffer). 2319 * Once this function is called, you can basically forget about this 2320 * renderbuffer; core Mesa will handle all the buffer management and 2321 * rendering! 2322 */ 2323GLboolean 2324_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2325 GLuint redBits, GLuint greenBits, 2326 GLuint blueBits, GLuint alphaBits) 2327{ 2328 struct gl_renderbuffer *rb; 2329 2330 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 2331 _mesa_problem(ctx, 2332 "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 2333 return GL_FALSE; 2334 } 2335 2336 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 2337 2338 rb = _mesa_new_renderbuffer(ctx, 0); 2339 if (!rb) { 2340 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 2341 return GL_FALSE; 2342 } 2343 2344 rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 2345 rb->InternalFormat = GL_RGBA16_SNORM; 2346 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2347 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 2348 2349 return GL_TRUE; 2350} 2351 2352 2353 2354/** 2355 * Add a software-based aux renderbuffer to the given framebuffer. 2356 * This is a helper routine for device drivers when creating a 2357 * window system framebuffer (not a user-created render/framebuffer). 2358 * Once this function is called, you can basically forget about this 2359 * renderbuffer; core Mesa will handle all the buffer management and 2360 * rendering! 2361 * 2362 * NOTE: color-index aux buffers not supported. 2363 */ 2364GLboolean 2365_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2366 GLuint colorBits, GLuint numBuffers) 2367{ 2368 GLuint i; 2369 2370 if (colorBits > 16) { 2371 _mesa_problem(ctx, 2372 "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 2373 return GL_FALSE; 2374 } 2375 2376 assert(numBuffers <= MAX_AUX_BUFFERS); 2377 2378 for (i = 0; i < numBuffers; i++) { 2379 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 2380 2381 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 2382 2383 if (!rb) { 2384 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); 2385 return GL_FALSE; 2386 } 2387 2388 assert (colorBits <= 8); 2389 rb->Format = MESA_FORMAT_RGBA8888; 2390 rb->InternalFormat = GL_RGBA; 2391 2392 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2393 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 2394 } 2395 return GL_TRUE; 2396} 2397 2398 2399/** 2400 * Create/attach software-based renderbuffers to the given framebuffer. 2401 * This is a helper routine for device drivers. Drivers can just as well 2402 * call the individual _mesa_add_*_renderbuffer() routines directly. 2403 */ 2404void 2405_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 2406 GLboolean color, 2407 GLboolean depth, 2408 GLboolean stencil, 2409 GLboolean accum, 2410 GLboolean alpha, 2411 GLboolean aux) 2412{ 2413 GLboolean frontLeft = GL_TRUE; 2414 GLboolean backLeft = fb->Visual.doubleBufferMode; 2415 GLboolean frontRight = fb->Visual.stereoMode; 2416 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 2417 2418 if (color) { 2419 assert(fb->Visual.redBits == fb->Visual.greenBits); 2420 assert(fb->Visual.redBits == fb->Visual.blueBits); 2421 _mesa_add_color_renderbuffers(NULL, fb, 2422 fb->Visual.redBits, 2423 fb->Visual.alphaBits, 2424 frontLeft, backLeft, 2425 frontRight, backRight); 2426 } 2427 2428 if (depth) { 2429 assert(fb->Visual.depthBits > 0); 2430 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 2431 } 2432 2433 if (stencil) { 2434 assert(fb->Visual.stencilBits > 0); 2435 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 2436 } 2437 2438 if (accum) { 2439 assert(fb->Visual.accumRedBits > 0); 2440 assert(fb->Visual.accumGreenBits > 0); 2441 assert(fb->Visual.accumBlueBits > 0); 2442 _mesa_add_accum_renderbuffer(NULL, fb, 2443 fb->Visual.accumRedBits, 2444 fb->Visual.accumGreenBits, 2445 fb->Visual.accumBlueBits, 2446 fb->Visual.accumAlphaBits); 2447 } 2448 2449 if (aux) { 2450 assert(fb->Visual.numAuxBuffers > 0); 2451 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 2452 fb->Visual.numAuxBuffers); 2453 } 2454 2455 if (alpha) { 2456 assert(fb->Visual.alphaBits > 0); 2457 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 2458 frontLeft, backLeft, 2459 frontRight, backRight); 2460 } 2461 2462#if 0 2463 if (multisample) { 2464 /* maybe someday */ 2465 } 2466#endif 2467} 2468 2469 2470/** 2471 * Attach a renderbuffer to a framebuffer. 2472 * \param bufferName one of the BUFFER_x tokens 2473 */ 2474void 2475_mesa_add_renderbuffer(struct gl_framebuffer *fb, 2476 gl_buffer_index bufferName, struct gl_renderbuffer *rb) 2477{ 2478 assert(fb); 2479 assert(rb); 2480 assert(bufferName < BUFFER_COUNT); 2481 2482 /* There should be no previous renderbuffer on this attachment point, 2483 * with the exception of depth/stencil since the same renderbuffer may 2484 * be used for both. 2485 */ 2486 assert(bufferName == BUFFER_DEPTH || 2487 bufferName == BUFFER_STENCIL || 2488 fb->Attachment[bufferName].Renderbuffer == NULL); 2489 2490 /* winsys vs. user-created buffer cross check */ 2491 if (fb->Name) { 2492 assert(rb->Name); 2493 } 2494 else { 2495 assert(!rb->Name); 2496 } 2497 2498 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 2499 fb->Attachment[bufferName].Complete = GL_TRUE; 2500 _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); 2501} 2502 2503 2504/** 2505 * Remove the named renderbuffer from the given framebuffer. 2506 * \param bufferName one of the BUFFER_x tokens 2507 */ 2508void 2509_mesa_remove_renderbuffer(struct gl_framebuffer *fb, 2510 gl_buffer_index bufferName) 2511{ 2512 struct gl_renderbuffer *rb; 2513 2514 assert(bufferName < BUFFER_COUNT); 2515 2516 rb = fb->Attachment[bufferName].Renderbuffer; 2517 if (!rb) 2518 return; 2519 2520 _mesa_reference_renderbuffer(&rb, NULL); 2521 2522 fb->Attachment[bufferName].Renderbuffer = NULL; 2523} 2524 2525 2526/** 2527 * Set *ptr to point to rb. If *ptr points to another renderbuffer, 2528 * dereference that buffer first. The new renderbuffer's refcount will 2529 * be incremented. The old renderbuffer's refcount will be decremented. 2530 */ 2531void 2532_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, 2533 struct gl_renderbuffer *rb) 2534{ 2535 assert(ptr); 2536 if (*ptr == rb) { 2537 /* no change */ 2538 return; 2539 } 2540 2541 if (*ptr) { 2542 /* Unreference the old renderbuffer */ 2543 GLboolean deleteFlag = GL_FALSE; 2544 struct gl_renderbuffer *oldRb = *ptr; 2545 2546 _glthread_LOCK_MUTEX(oldRb->Mutex); 2547 ASSERT(oldRb->RefCount > 0); 2548 oldRb->RefCount--; 2549 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/ 2550 deleteFlag = (oldRb->RefCount == 0); 2551 _glthread_UNLOCK_MUTEX(oldRb->Mutex); 2552 2553 if (deleteFlag) { 2554 oldRb->Delete(oldRb); 2555 } 2556 2557 *ptr = NULL; 2558 } 2559 assert(!*ptr); 2560 2561 if (rb) { 2562 /* reference new renderbuffer */ 2563 _glthread_LOCK_MUTEX(rb->Mutex); 2564 rb->RefCount++; 2565 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/ 2566 _glthread_UNLOCK_MUTEX(rb->Mutex); 2567 *ptr = rb; 2568 } 2569} 2570 2571 2572/** 2573 * Create a new combined depth/stencil renderbuffer for implementing 2574 * the GL_EXT_packed_depth_stencil extension. 2575 * \return new depth/stencil renderbuffer 2576 */ 2577struct gl_renderbuffer * 2578_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name) 2579{ 2580 struct gl_renderbuffer *dsrb; 2581 2582 dsrb = _mesa_new_renderbuffer(ctx, name); 2583 if (!dsrb) 2584 return NULL; 2585 2586 /* init fields not covered by _mesa_new_renderbuffer() */ 2587 dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT; 2588 dsrb->Format = MESA_FORMAT_Z24_S8; 2589 dsrb->AllocStorage = _mesa_soft_renderbuffer_storage; 2590 2591 return dsrb; 2592} 2593