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