renderbuffer.c revision 7117f1b4
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * Version: 6.5 47117f1b4Smrg * 57117f1b4Smrg * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 67117f1b4Smrg * 77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 97117f1b4Smrg * to deal in the Software without restriction, including without limitation 107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 127117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 137117f1b4Smrg * 147117f1b4Smrg * The above copyright notice and this permission notice shall be included 157117f1b4Smrg * in all copies or substantial portions of the Software. 167117f1b4Smrg * 177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg */ 247117f1b4Smrg 257117f1b4Smrg 267117f1b4Smrg/** 277117f1b4Smrg * Functions for allocating/managing renderbuffers. 287117f1b4Smrg * Also, routines for reading/writing software-based renderbuffer data as 297117f1b4Smrg * ubytes, ushorts, uints, etc. 307117f1b4Smrg * 317117f1b4Smrg * The 'alpha8' renderbuffer is interesting. It's used to add a software-based 327117f1b4Smrg * alpha channel to RGB renderbuffers. This is done by wrapping the RGB 337117f1b4Smrg * renderbuffer with the alpha renderbuffer. We can do this because of the 347117f1b4Smrg * OO-nature of renderbuffers. 357117f1b4Smrg * 367117f1b4Smrg * Down the road we'll use this for run-time support of 8, 16 and 32-bit 377117f1b4Smrg * color channels. For example, Mesa may use 32-bit/float color channels 387117f1b4Smrg * internally (swrast) and use wrapper renderbuffers to convert 32-bit 397117f1b4Smrg * values down to 16 or 8-bit values for whatever kind of framebuffer we have. 407117f1b4Smrg */ 417117f1b4Smrg 427117f1b4Smrg 437117f1b4Smrg#include "glheader.h" 447117f1b4Smrg#include "imports.h" 457117f1b4Smrg#include "context.h" 467117f1b4Smrg#include "mtypes.h" 477117f1b4Smrg#include "fbobject.h" 487117f1b4Smrg#include "renderbuffer.h" 497117f1b4Smrg 507117f1b4Smrg#include "rbadaptors.h" 517117f1b4Smrg 527117f1b4Smrg 537117f1b4Smrg/* 32-bit color index format. Not a public format. */ 547117f1b4Smrg#define COLOR_INDEX32 0x424243 557117f1b4Smrg 567117f1b4Smrg 577117f1b4Smrg/* 587117f1b4Smrg * Routines for get/put values in common buffer formats follow. 597117f1b4Smrg * Someday add support for arbitrary row stride to make them more 607117f1b4Smrg * flexible. 617117f1b4Smrg */ 627117f1b4Smrg 637117f1b4Smrg/********************************************************************** 647117f1b4Smrg * Functions for buffers of 1 X GLubyte values. 657117f1b4Smrg * Typically stencil. 667117f1b4Smrg */ 677117f1b4Smrg 687117f1b4Smrgstatic void * 697117f1b4Smrgget_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, 707117f1b4Smrg GLint x, GLint y) 717117f1b4Smrg{ 727117f1b4Smrg if (!rb->Data) 737117f1b4Smrg return NULL; 747117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 757117f1b4Smrg /* Can't assert _ActualFormat since these funcs may be used for serveral 767117f1b4Smrg * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc). 777117f1b4Smrg */ 787117f1b4Smrg return (GLubyte *) rb->Data + y * rb->Width + x; 797117f1b4Smrg} 807117f1b4Smrg 817117f1b4Smrg 827117f1b4Smrgstatic void 837117f1b4Smrgget_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 847117f1b4Smrg GLint x, GLint y, void *values) 857117f1b4Smrg{ 867117f1b4Smrg const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; 877117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 887117f1b4Smrg _mesa_memcpy(values, src, count * sizeof(GLubyte)); 897117f1b4Smrg} 907117f1b4Smrg 917117f1b4Smrg 927117f1b4Smrgstatic void 937117f1b4Smrgget_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 947117f1b4Smrg const GLint x[], const GLint y[], void *values) 957117f1b4Smrg{ 967117f1b4Smrg GLubyte *dst = (GLubyte *) values; 977117f1b4Smrg GLuint i; 987117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 997117f1b4Smrg for (i = 0; i < count; i++) { 1007117f1b4Smrg const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1017117f1b4Smrg dst[i] = *src; 1027117f1b4Smrg } 1037117f1b4Smrg} 1047117f1b4Smrg 1057117f1b4Smrg 1067117f1b4Smrgstatic void 1077117f1b4Smrgput_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1087117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 1097117f1b4Smrg{ 1107117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 1117117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1127117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1137117f1b4Smrg if (mask) { 1147117f1b4Smrg GLuint i; 1157117f1b4Smrg for (i = 0; i < count; i++) { 1167117f1b4Smrg if (mask[i]) { 1177117f1b4Smrg dst[i] = src[i]; 1187117f1b4Smrg } 1197117f1b4Smrg } 1207117f1b4Smrg } 1217117f1b4Smrg else { 1227117f1b4Smrg _mesa_memcpy(dst, values, count * sizeof(GLubyte)); 1237117f1b4Smrg } 1247117f1b4Smrg} 1257117f1b4Smrg 1267117f1b4Smrg 1277117f1b4Smrgstatic void 1287117f1b4Smrgput_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1297117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 1307117f1b4Smrg{ 1317117f1b4Smrg const GLubyte val = *((const GLubyte *) value); 1327117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; 1337117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1347117f1b4Smrg if (mask) { 1357117f1b4Smrg GLuint i; 1367117f1b4Smrg for (i = 0; i < count; i++) { 1377117f1b4Smrg if (mask[i]) { 1387117f1b4Smrg dst[i] = val; 1397117f1b4Smrg } 1407117f1b4Smrg } 1417117f1b4Smrg } 1427117f1b4Smrg else { 1437117f1b4Smrg GLuint i; 1447117f1b4Smrg for (i = 0; i < count; i++) { 1457117f1b4Smrg dst[i] = val; 1467117f1b4Smrg } 1477117f1b4Smrg } 1487117f1b4Smrg} 1497117f1b4Smrg 1507117f1b4Smrg 1517117f1b4Smrgstatic void 1527117f1b4Smrgput_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1537117f1b4Smrg const GLint x[], const GLint y[], 1547117f1b4Smrg const void *values, const GLubyte *mask) 1557117f1b4Smrg{ 1567117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 1577117f1b4Smrg GLuint i; 1587117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1597117f1b4Smrg for (i = 0; i < count; i++) { 1607117f1b4Smrg if (!mask || mask[i]) { 1617117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1627117f1b4Smrg *dst = src[i]; 1637117f1b4Smrg } 1647117f1b4Smrg } 1657117f1b4Smrg} 1667117f1b4Smrg 1677117f1b4Smrg 1687117f1b4Smrgstatic void 1697117f1b4Smrgput_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 1707117f1b4Smrg const GLint x[], const GLint y[], 1717117f1b4Smrg const void *value, const GLubyte *mask) 1727117f1b4Smrg{ 1737117f1b4Smrg const GLubyte val = *((const GLubyte *) value); 1747117f1b4Smrg GLuint i; 1757117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1767117f1b4Smrg for (i = 0; i < count; i++) { 1777117f1b4Smrg if (!mask || mask[i]) { 1787117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; 1797117f1b4Smrg *dst = val; 1807117f1b4Smrg } 1817117f1b4Smrg } 1827117f1b4Smrg} 1837117f1b4Smrg 1847117f1b4Smrg 1857117f1b4Smrg/********************************************************************** 1867117f1b4Smrg * Functions for buffers of 1 X GLushort values. 1877117f1b4Smrg * Typically depth/Z. 1887117f1b4Smrg */ 1897117f1b4Smrg 1907117f1b4Smrgstatic void * 1917117f1b4Smrgget_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, 1927117f1b4Smrg GLint x, GLint y) 1937117f1b4Smrg{ 1947117f1b4Smrg if (!rb->Data) 1957117f1b4Smrg return NULL; 1967117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 1977117f1b4Smrg ASSERT(rb->Width > 0); 1987117f1b4Smrg return (GLushort *) rb->Data + y * rb->Width + x; 1997117f1b4Smrg} 2007117f1b4Smrg 2017117f1b4Smrg 2027117f1b4Smrgstatic void 2037117f1b4Smrgget_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 2047117f1b4Smrg GLint x, GLint y, void *values) 2057117f1b4Smrg{ 2067117f1b4Smrg const void *src = rb->GetPointer(ctx, rb, x, y); 2077117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2087117f1b4Smrg _mesa_memcpy(values, src, count * sizeof(GLushort)); 2097117f1b4Smrg} 2107117f1b4Smrg 2117117f1b4Smrg 2127117f1b4Smrgstatic void 2137117f1b4Smrgget_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 2147117f1b4Smrg const GLint x[], const GLint y[], void *values) 2157117f1b4Smrg{ 2167117f1b4Smrg GLushort *dst = (GLushort *) values; 2177117f1b4Smrg GLuint i; 2187117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2197117f1b4Smrg for (i = 0; i < count; i++) { 2207117f1b4Smrg const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 2217117f1b4Smrg dst[i] = *src; 2227117f1b4Smrg } 2237117f1b4Smrg} 2247117f1b4Smrg 2257117f1b4Smrg 2267117f1b4Smrgstatic void 2277117f1b4Smrgput_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 2287117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 2297117f1b4Smrg{ 2307117f1b4Smrg const GLushort *src = (const GLushort *) values; 2317117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x; 2327117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2337117f1b4Smrg if (mask) { 2347117f1b4Smrg GLuint i; 2357117f1b4Smrg for (i = 0; i < count; i++) { 2367117f1b4Smrg if (mask[i]) { 2377117f1b4Smrg dst[i] = src[i]; 2387117f1b4Smrg } 2397117f1b4Smrg } 2407117f1b4Smrg } 2417117f1b4Smrg else { 2427117f1b4Smrg _mesa_memcpy(dst, src, count * sizeof(GLushort)); 2437117f1b4Smrg } 2447117f1b4Smrg} 2457117f1b4Smrg 2467117f1b4Smrg 2477117f1b4Smrgstatic void 2487117f1b4Smrgput_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 2497117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 2507117f1b4Smrg{ 2517117f1b4Smrg const GLushort val = *((const GLushort *) value); 2527117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x; 2537117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2547117f1b4Smrg if (mask) { 2557117f1b4Smrg GLuint i; 2567117f1b4Smrg for (i = 0; i < count; i++) { 2577117f1b4Smrg if (mask[i]) { 2587117f1b4Smrg dst[i] = val; 2597117f1b4Smrg } 2607117f1b4Smrg } 2617117f1b4Smrg } 2627117f1b4Smrg else { 2637117f1b4Smrg GLuint i; 2647117f1b4Smrg for (i = 0; i < count; i++) { 2657117f1b4Smrg dst[i] = val; 2667117f1b4Smrg } 2677117f1b4Smrg } 2687117f1b4Smrg} 2697117f1b4Smrg 2707117f1b4Smrg 2717117f1b4Smrgstatic void 2727117f1b4Smrgput_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 2737117f1b4Smrg const GLint x[], const GLint y[], const void *values, 2747117f1b4Smrg const GLubyte *mask) 2757117f1b4Smrg{ 2767117f1b4Smrg const GLushort *src = (const GLushort *) values; 2777117f1b4Smrg GLuint i; 2787117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2797117f1b4Smrg for (i = 0; i < count; i++) { 2807117f1b4Smrg if (!mask || mask[i]) { 2817117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 2827117f1b4Smrg *dst = src[i]; 2837117f1b4Smrg } 2847117f1b4Smrg } 2857117f1b4Smrg} 2867117f1b4Smrg 2877117f1b4Smrg 2887117f1b4Smrgstatic void 2897117f1b4Smrgput_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, 2907117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 2917117f1b4Smrg const void *value, const GLubyte *mask) 2927117f1b4Smrg{ 2937117f1b4Smrg const GLushort val = *((const GLushort *) value); 2947117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 2957117f1b4Smrg if (mask) { 2967117f1b4Smrg GLuint i; 2977117f1b4Smrg for (i = 0; i < count; i++) { 2987117f1b4Smrg if (mask[i]) { 2997117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 3007117f1b4Smrg *dst = val; 3017117f1b4Smrg } 3027117f1b4Smrg } 3037117f1b4Smrg } 3047117f1b4Smrg else { 3057117f1b4Smrg GLuint i; 3067117f1b4Smrg for (i = 0; i < count; i++) { 3077117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; 3087117f1b4Smrg *dst = val; 3097117f1b4Smrg } 3107117f1b4Smrg } 3117117f1b4Smrg} 3127117f1b4Smrg 3137117f1b4Smrg 3147117f1b4Smrg/********************************************************************** 3157117f1b4Smrg * Functions for buffers of 1 X GLuint values. 3167117f1b4Smrg * Typically depth/Z or color index. 3177117f1b4Smrg */ 3187117f1b4Smrg 3197117f1b4Smrgstatic void * 3207117f1b4Smrgget_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb, 3217117f1b4Smrg GLint x, GLint y) 3227117f1b4Smrg{ 3237117f1b4Smrg if (!rb->Data) 3247117f1b4Smrg return NULL; 3257117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 3267117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 3277117f1b4Smrg return (GLuint *) rb->Data + y * rb->Width + x; 3287117f1b4Smrg} 3297117f1b4Smrg 3307117f1b4Smrg 3317117f1b4Smrgstatic void 3327117f1b4Smrgget_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 3337117f1b4Smrg GLint x, GLint y, void *values) 3347117f1b4Smrg{ 3357117f1b4Smrg const void *src = rb->GetPointer(ctx, rb, x, y); 3367117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 3377117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 3387117f1b4Smrg _mesa_memcpy(values, src, count * sizeof(GLuint)); 3397117f1b4Smrg} 3407117f1b4Smrg 3417117f1b4Smrg 3427117f1b4Smrgstatic void 3437117f1b4Smrgget_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 3447117f1b4Smrg const GLint x[], const GLint y[], void *values) 3457117f1b4Smrg{ 3467117f1b4Smrg GLuint *dst = (GLuint *) values; 3477117f1b4Smrg GLuint i; 3487117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 3497117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 3507117f1b4Smrg for (i = 0; i < count; i++) { 3517117f1b4Smrg const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 3527117f1b4Smrg dst[i] = *src; 3537117f1b4Smrg } 3547117f1b4Smrg} 3557117f1b4Smrg 3567117f1b4Smrg 3577117f1b4Smrgstatic void 3587117f1b4Smrgput_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 3597117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 3607117f1b4Smrg{ 3617117f1b4Smrg const GLuint *src = (const GLuint *) values; 3627117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x; 3637117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 3647117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 3657117f1b4Smrg if (mask) { 3667117f1b4Smrg GLuint i; 3677117f1b4Smrg for (i = 0; i < count; i++) { 3687117f1b4Smrg if (mask[i]) { 3697117f1b4Smrg dst[i] = src[i]; 3707117f1b4Smrg } 3717117f1b4Smrg } 3727117f1b4Smrg } 3737117f1b4Smrg else { 3747117f1b4Smrg _mesa_memcpy(dst, src, count * sizeof(GLuint)); 3757117f1b4Smrg } 3767117f1b4Smrg} 3777117f1b4Smrg 3787117f1b4Smrg 3797117f1b4Smrgstatic void 3807117f1b4Smrgput_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 3817117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 3827117f1b4Smrg{ 3837117f1b4Smrg const GLuint val = *((const GLuint *) value); 3847117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x; 3857117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 3867117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 3877117f1b4Smrg if (mask) { 3887117f1b4Smrg GLuint i; 3897117f1b4Smrg for (i = 0; i < count; i++) { 3907117f1b4Smrg if (mask[i]) { 3917117f1b4Smrg dst[i] = val; 3927117f1b4Smrg } 3937117f1b4Smrg } 3947117f1b4Smrg } 3957117f1b4Smrg else { 3967117f1b4Smrg GLuint i; 3977117f1b4Smrg for (i = 0; i < count; i++) { 3987117f1b4Smrg dst[i] = val; 3997117f1b4Smrg } 4007117f1b4Smrg } 4017117f1b4Smrg} 4027117f1b4Smrg 4037117f1b4Smrg 4047117f1b4Smrgstatic void 4057117f1b4Smrgput_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 4067117f1b4Smrg const GLint x[], const GLint y[], const void *values, 4077117f1b4Smrg const GLubyte *mask) 4087117f1b4Smrg{ 4097117f1b4Smrg const GLuint *src = (const GLuint *) values; 4107117f1b4Smrg GLuint i; 4117117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 4127117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 4137117f1b4Smrg for (i = 0; i < count; i++) { 4147117f1b4Smrg if (!mask || mask[i]) { 4157117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 4167117f1b4Smrg *dst = src[i]; 4177117f1b4Smrg } 4187117f1b4Smrg } 4197117f1b4Smrg} 4207117f1b4Smrg 4217117f1b4Smrg 4227117f1b4Smrgstatic void 4237117f1b4Smrgput_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 4247117f1b4Smrg const GLint x[], const GLint y[], const void *value, 4257117f1b4Smrg const GLubyte *mask) 4267117f1b4Smrg{ 4277117f1b4Smrg const GLuint val = *((const GLuint *) value); 4287117f1b4Smrg GLuint i; 4297117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 4307117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 4317117f1b4Smrg for (i = 0; i < count; i++) { 4327117f1b4Smrg if (!mask || mask[i]) { 4337117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; 4347117f1b4Smrg *dst = val; 4357117f1b4Smrg } 4367117f1b4Smrg } 4377117f1b4Smrg} 4387117f1b4Smrg 4397117f1b4Smrg 4407117f1b4Smrg/********************************************************************** 4417117f1b4Smrg * Functions for buffers of 3 X GLubyte (or GLbyte) values. 4427117f1b4Smrg * Typically color buffers. 4437117f1b4Smrg * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 4447117f1b4Smrg * alpha values and return 255 for outgoing alpha values. 4457117f1b4Smrg */ 4467117f1b4Smrg 4477117f1b4Smrgstatic void * 4487117f1b4Smrgget_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 4497117f1b4Smrg GLint x, GLint y) 4507117f1b4Smrg{ 4517117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 4527117f1b4Smrg /* No direct access since this buffer is RGB but caller will be 4537117f1b4Smrg * treating it as if it were RGBA. 4547117f1b4Smrg */ 4557117f1b4Smrg return NULL; 4567117f1b4Smrg} 4577117f1b4Smrg 4587117f1b4Smrg 4597117f1b4Smrgstatic void 4607117f1b4Smrgget_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 4617117f1b4Smrg GLint x, GLint y, void *values) 4627117f1b4Smrg{ 4637117f1b4Smrg const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x); 4647117f1b4Smrg GLubyte *dst = (GLubyte *) values; 4657117f1b4Smrg GLuint i; 4667117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 4677117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 4687117f1b4Smrg for (i = 0; i < count; i++) { 4697117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 4707117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 4717117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 4727117f1b4Smrg dst[i * 4 + 3] = 255; 4737117f1b4Smrg } 4747117f1b4Smrg} 4757117f1b4Smrg 4767117f1b4Smrg 4777117f1b4Smrgstatic void 4787117f1b4Smrgget_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 4797117f1b4Smrg const GLint x[], const GLint y[], void *values) 4807117f1b4Smrg{ 4817117f1b4Smrg GLubyte *dst = (GLubyte *) values; 4827117f1b4Smrg GLuint i; 4837117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 4847117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 4857117f1b4Smrg for (i = 0; i < count; i++) { 4867117f1b4Smrg const GLubyte *src 4877117f1b4Smrg = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 4887117f1b4Smrg dst[i * 4 + 0] = src[0]; 4897117f1b4Smrg dst[i * 4 + 1] = src[1]; 4907117f1b4Smrg dst[i * 4 + 2] = src[2]; 4917117f1b4Smrg dst[i * 4 + 3] = 255; 4927117f1b4Smrg } 4937117f1b4Smrg} 4947117f1b4Smrg 4957117f1b4Smrg 4967117f1b4Smrgstatic void 4977117f1b4Smrgput_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 4987117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 4997117f1b4Smrg{ 5007117f1b4Smrg /* note: incoming values are RGB+A! */ 5017117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 5027117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 5037117f1b4Smrg GLuint i; 5047117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 5057117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5067117f1b4Smrg for (i = 0; i < count; i++) { 5077117f1b4Smrg if (!mask || mask[i]) { 5087117f1b4Smrg dst[i * 3 + 0] = src[i * 4 + 0]; 5097117f1b4Smrg dst[i * 3 + 1] = src[i * 4 + 1]; 5107117f1b4Smrg dst[i * 3 + 2] = src[i * 4 + 2]; 5117117f1b4Smrg } 5127117f1b4Smrg } 5137117f1b4Smrg} 5147117f1b4Smrg 5157117f1b4Smrg 5167117f1b4Smrgstatic void 5177117f1b4Smrgput_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 5187117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 5197117f1b4Smrg{ 5207117f1b4Smrg /* note: incoming values are RGB+A! */ 5217117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 5227117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 5237117f1b4Smrg GLuint i; 5247117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 5257117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5267117f1b4Smrg for (i = 0; i < count; i++) { 5277117f1b4Smrg if (!mask || mask[i]) { 5287117f1b4Smrg dst[i * 3 + 0] = src[i * 3 + 0]; 5297117f1b4Smrg dst[i * 3 + 1] = src[i * 3 + 1]; 5307117f1b4Smrg dst[i * 3 + 2] = src[i * 3 + 2]; 5317117f1b4Smrg } 5327117f1b4Smrg } 5337117f1b4Smrg} 5347117f1b4Smrg 5357117f1b4Smrg 5367117f1b4Smrgstatic void 5377117f1b4Smrgput_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 5387117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 5397117f1b4Smrg{ 5407117f1b4Smrg /* note: incoming value is RGB+A! */ 5417117f1b4Smrg const GLubyte val0 = ((const GLubyte *) value)[0]; 5427117f1b4Smrg const GLubyte val1 = ((const GLubyte *) value)[1]; 5437117f1b4Smrg const GLubyte val2 = ((const GLubyte *) value)[2]; 5447117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x); 5457117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 5467117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5477117f1b4Smrg if (!mask && val0 == val1 && val1 == val2) { 5487117f1b4Smrg /* optimized case */ 5497117f1b4Smrg _mesa_memset(dst, val0, 3 * count); 5507117f1b4Smrg } 5517117f1b4Smrg else { 5527117f1b4Smrg GLuint i; 5537117f1b4Smrg for (i = 0; i < count; i++) { 5547117f1b4Smrg if (!mask || mask[i]) { 5557117f1b4Smrg dst[i * 3 + 0] = val0; 5567117f1b4Smrg dst[i * 3 + 1] = val1; 5577117f1b4Smrg dst[i * 3 + 2] = val2; 5587117f1b4Smrg } 5597117f1b4Smrg } 5607117f1b4Smrg } 5617117f1b4Smrg} 5627117f1b4Smrg 5637117f1b4Smrg 5647117f1b4Smrgstatic void 5657117f1b4Smrgput_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 5667117f1b4Smrg const GLint x[], const GLint y[], const void *values, 5677117f1b4Smrg const GLubyte *mask) 5687117f1b4Smrg{ 5697117f1b4Smrg /* note: incoming values are RGB+A! */ 5707117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 5717117f1b4Smrg GLuint i; 5727117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 5737117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5747117f1b4Smrg for (i = 0; i < count; i++) { 5757117f1b4Smrg if (!mask || mask[i]) { 5767117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 5777117f1b4Smrg dst[0] = src[i * 4 + 0]; 5787117f1b4Smrg dst[1] = src[i * 4 + 1]; 5797117f1b4Smrg dst[2] = src[i * 4 + 2]; 5807117f1b4Smrg } 5817117f1b4Smrg } 5827117f1b4Smrg} 5837117f1b4Smrg 5847117f1b4Smrg 5857117f1b4Smrgstatic void 5867117f1b4Smrgput_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, 5877117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 5887117f1b4Smrg const void *value, const GLubyte *mask) 5897117f1b4Smrg{ 5907117f1b4Smrg /* note: incoming value is RGB+A! */ 5917117f1b4Smrg const GLubyte val0 = ((const GLubyte *) value)[0]; 5927117f1b4Smrg const GLubyte val1 = ((const GLubyte *) value)[1]; 5937117f1b4Smrg const GLubyte val2 = ((const GLubyte *) value)[2]; 5947117f1b4Smrg GLuint i; 5957117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGB8); 5967117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5977117f1b4Smrg for (i = 0; i < count; i++) { 5987117f1b4Smrg if (!mask || mask[i]) { 5997117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]); 6007117f1b4Smrg dst[0] = val0; 6017117f1b4Smrg dst[1] = val1; 6027117f1b4Smrg dst[2] = val2; 6037117f1b4Smrg } 6047117f1b4Smrg } 6057117f1b4Smrg} 6067117f1b4Smrg 6077117f1b4Smrg 6087117f1b4Smrg/********************************************************************** 6097117f1b4Smrg * Functions for buffers of 4 X GLubyte (or GLbyte) values. 6107117f1b4Smrg * Typically color buffers. 6117117f1b4Smrg */ 6127117f1b4Smrg 6137117f1b4Smrgstatic void * 6147117f1b4Smrgget_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 6157117f1b4Smrg GLint x, GLint y) 6167117f1b4Smrg{ 6177117f1b4Smrg if (!rb->Data) 6187117f1b4Smrg return NULL; 6197117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6207117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 6217117f1b4Smrg return (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 6227117f1b4Smrg} 6237117f1b4Smrg 6247117f1b4Smrg 6257117f1b4Smrgstatic void 6267117f1b4Smrgget_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 6277117f1b4Smrg GLint x, GLint y, void *values) 6287117f1b4Smrg{ 6297117f1b4Smrg const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x); 6307117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6317117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 6327117f1b4Smrg _mesa_memcpy(values, src, 4 * count * sizeof(GLubyte)); 6337117f1b4Smrg} 6347117f1b4Smrg 6357117f1b4Smrg 6367117f1b4Smrgstatic void 6377117f1b4Smrgget_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 6387117f1b4Smrg const GLint x[], const GLint y[], void *values) 6397117f1b4Smrg{ 6407117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 6417117f1b4Smrg GLuint *dst = (GLuint *) values; 6427117f1b4Smrg GLuint i; 6437117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6447117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 6457117f1b4Smrg for (i = 0; i < count; i++) { 6467117f1b4Smrg const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 6477117f1b4Smrg dst[i] = *src; 6487117f1b4Smrg } 6497117f1b4Smrg} 6507117f1b4Smrg 6517117f1b4Smrg 6527117f1b4Smrgstatic void 6537117f1b4Smrgput_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 6547117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 6557117f1b4Smrg{ 6567117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 6577117f1b4Smrg const GLuint *src = (const GLuint *) values; 6587117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 6597117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6607117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 6617117f1b4Smrg if (mask) { 6627117f1b4Smrg GLuint i; 6637117f1b4Smrg for (i = 0; i < count; i++) { 6647117f1b4Smrg if (mask[i]) { 6657117f1b4Smrg dst[i] = src[i]; 6667117f1b4Smrg } 6677117f1b4Smrg } 6687117f1b4Smrg } 6697117f1b4Smrg else { 6707117f1b4Smrg _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte)); 6717117f1b4Smrg } 6727117f1b4Smrg} 6737117f1b4Smrg 6747117f1b4Smrg 6757117f1b4Smrgstatic void 6767117f1b4Smrgput_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 6777117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 6787117f1b4Smrg{ 6797117f1b4Smrg /* Store RGB values in RGBA buffer */ 6807117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 6817117f1b4Smrg GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x); 6827117f1b4Smrg GLuint i; 6837117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6847117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 6857117f1b4Smrg for (i = 0; i < count; i++) { 6867117f1b4Smrg if (!mask || mask[i]) { 6877117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 6887117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 6897117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 6907117f1b4Smrg dst[i * 4 + 3] = 0xff; 6917117f1b4Smrg } 6927117f1b4Smrg } 6937117f1b4Smrg} 6947117f1b4Smrg 6957117f1b4Smrg 6967117f1b4Smrgstatic void 6977117f1b4Smrgput_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 6987117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 6997117f1b4Smrg{ 7007117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7017117f1b4Smrg const GLuint val = *((const GLuint *) value); 7027117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x); 7037117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7047117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 7057117f1b4Smrg if (!mask && val == 0) { 7067117f1b4Smrg /* common case */ 7077117f1b4Smrg _mesa_bzero(dst, count * 4 * sizeof(GLubyte)); 7087117f1b4Smrg } 7097117f1b4Smrg else { 7107117f1b4Smrg /* general case */ 7117117f1b4Smrg if (mask) { 7127117f1b4Smrg GLuint i; 7137117f1b4Smrg for (i = 0; i < count; i++) { 7147117f1b4Smrg if (mask[i]) { 7157117f1b4Smrg dst[i] = val; 7167117f1b4Smrg } 7177117f1b4Smrg } 7187117f1b4Smrg } 7197117f1b4Smrg else { 7207117f1b4Smrg GLuint i; 7217117f1b4Smrg for (i = 0; i < count; i++) { 7227117f1b4Smrg dst[i] = val; 7237117f1b4Smrg } 7247117f1b4Smrg } 7257117f1b4Smrg } 7267117f1b4Smrg} 7277117f1b4Smrg 7287117f1b4Smrg 7297117f1b4Smrgstatic void 7307117f1b4Smrgput_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 7317117f1b4Smrg const GLint x[], const GLint y[], const void *values, 7327117f1b4Smrg const GLubyte *mask) 7337117f1b4Smrg{ 7347117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7357117f1b4Smrg const GLuint *src = (const GLuint *) values; 7367117f1b4Smrg GLuint i; 7377117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7387117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 7397117f1b4Smrg for (i = 0; i < count; i++) { 7407117f1b4Smrg if (!mask || mask[i]) { 7417117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 7427117f1b4Smrg *dst = src[i]; 7437117f1b4Smrg } 7447117f1b4Smrg } 7457117f1b4Smrg} 7467117f1b4Smrg 7477117f1b4Smrg 7487117f1b4Smrgstatic void 7497117f1b4Smrgput_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, 7507117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 7517117f1b4Smrg const void *value, const GLubyte *mask) 7527117f1b4Smrg{ 7537117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7547117f1b4Smrg const GLuint val = *((const GLuint *) value); 7557117f1b4Smrg GLuint i; 7567117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7577117f1b4Smrg ASSERT(rb->_ActualFormat == GL_RGBA8); 7587117f1b4Smrg for (i = 0; i < count; i++) { 7597117f1b4Smrg if (!mask || mask[i]) { 7607117f1b4Smrg GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); 7617117f1b4Smrg *dst = val; 7627117f1b4Smrg } 7637117f1b4Smrg } 7647117f1b4Smrg} 7657117f1b4Smrg 7667117f1b4Smrg 7677117f1b4Smrg/********************************************************************** 7687117f1b4Smrg * Functions for buffers of 4 X GLushort (or GLshort) values. 7697117f1b4Smrg * Typically accum buffer. 7707117f1b4Smrg */ 7717117f1b4Smrg 7727117f1b4Smrgstatic void * 7737117f1b4Smrgget_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 7747117f1b4Smrg GLint x, GLint y) 7757117f1b4Smrg{ 7767117f1b4Smrg if (!rb->Data) 7777117f1b4Smrg return NULL; 7787117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 7797117f1b4Smrg return (GLushort *) rb->Data + 4 * (y * rb->Width + x); 7807117f1b4Smrg} 7817117f1b4Smrg 7827117f1b4Smrg 7837117f1b4Smrgstatic void 7847117f1b4Smrgget_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 7857117f1b4Smrg GLint x, GLint y, void *values) 7867117f1b4Smrg{ 7877117f1b4Smrg const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x); 7887117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 7897117f1b4Smrg _mesa_memcpy(values, src, 4 * count * sizeof(GLshort)); 7907117f1b4Smrg} 7917117f1b4Smrg 7927117f1b4Smrg 7937117f1b4Smrgstatic void 7947117f1b4Smrgget_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 7957117f1b4Smrg const GLint x[], const GLint y[], void *values) 7967117f1b4Smrg{ 7977117f1b4Smrg GLushort *dst = (GLushort *) values; 7987117f1b4Smrg GLuint i; 7997117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8007117f1b4Smrg for (i = 0; i < count; i++) { 8017117f1b4Smrg const GLushort *src 8027117f1b4Smrg = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 8037117f1b4Smrg dst[i] = *src; 8047117f1b4Smrg } 8057117f1b4Smrg} 8067117f1b4Smrg 8077117f1b4Smrg 8087117f1b4Smrgstatic void 8097117f1b4Smrgput_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 8107117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 8117117f1b4Smrg{ 8127117f1b4Smrg const GLushort *src = (const GLushort *) values; 8137117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 8147117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8157117f1b4Smrg if (mask) { 8167117f1b4Smrg GLuint i; 8177117f1b4Smrg for (i = 0; i < count; i++) { 8187117f1b4Smrg if (mask[i]) { 8197117f1b4Smrg dst[i * 4 + 0] = src[i * 4 + 0]; 8207117f1b4Smrg dst[i * 4 + 1] = src[i * 4 + 1]; 8217117f1b4Smrg dst[i * 4 + 2] = src[i * 4 + 2]; 8227117f1b4Smrg dst[i * 4 + 3] = src[i * 4 + 3]; 8237117f1b4Smrg } 8247117f1b4Smrg } 8257117f1b4Smrg } 8267117f1b4Smrg else { 8277117f1b4Smrg _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 8287117f1b4Smrg } 8297117f1b4Smrg} 8307117f1b4Smrg 8317117f1b4Smrg 8327117f1b4Smrgstatic void 8337117f1b4Smrgput_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 8347117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 8357117f1b4Smrg{ 8367117f1b4Smrg /* Put RGB values in RGBA buffer */ 8377117f1b4Smrg const GLushort *src = (const GLushort *) values; 8387117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 8397117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8407117f1b4Smrg if (mask) { 8417117f1b4Smrg GLuint i; 8427117f1b4Smrg for (i = 0; i < count; i++) { 8437117f1b4Smrg if (mask[i]) { 8447117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 8457117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 8467117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 8477117f1b4Smrg dst[i * 4 + 3] = 0xffff; 8487117f1b4Smrg } 8497117f1b4Smrg } 8507117f1b4Smrg } 8517117f1b4Smrg else { 8527117f1b4Smrg _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); 8537117f1b4Smrg } 8547117f1b4Smrg} 8557117f1b4Smrg 8567117f1b4Smrg 8577117f1b4Smrgstatic void 8587117f1b4Smrgput_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 8597117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 8607117f1b4Smrg{ 8617117f1b4Smrg const GLushort val0 = ((const GLushort *) value)[0]; 8627117f1b4Smrg const GLushort val1 = ((const GLushort *) value)[1]; 8637117f1b4Smrg const GLushort val2 = ((const GLushort *) value)[2]; 8647117f1b4Smrg const GLushort val3 = ((const GLushort *) value)[3]; 8657117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x); 8667117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8677117f1b4Smrg if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 8687117f1b4Smrg /* common case for clearing accum buffer */ 8697117f1b4Smrg _mesa_bzero(dst, count * 4 * sizeof(GLushort)); 8707117f1b4Smrg } 8717117f1b4Smrg else { 8727117f1b4Smrg GLuint i; 8737117f1b4Smrg for (i = 0; i < count; i++) { 8747117f1b4Smrg if (!mask || mask[i]) { 8757117f1b4Smrg dst[i * 4 + 0] = val0; 8767117f1b4Smrg dst[i * 4 + 1] = val1; 8777117f1b4Smrg dst[i * 4 + 2] = val2; 8787117f1b4Smrg dst[i * 4 + 3] = val3; 8797117f1b4Smrg } 8807117f1b4Smrg } 8817117f1b4Smrg } 8827117f1b4Smrg} 8837117f1b4Smrg 8847117f1b4Smrg 8857117f1b4Smrgstatic void 8867117f1b4Smrgput_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 8877117f1b4Smrg const GLint x[], const GLint y[], const void *values, 8887117f1b4Smrg const GLubyte *mask) 8897117f1b4Smrg{ 8907117f1b4Smrg const GLushort *src = (const GLushort *) values; 8917117f1b4Smrg GLuint i; 8927117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8937117f1b4Smrg for (i = 0; i < count; i++) { 8947117f1b4Smrg if (!mask || mask[i]) { 8957117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 8967117f1b4Smrg dst[0] = src[i * 4 + 0]; 8977117f1b4Smrg dst[1] = src[i * 4 + 1]; 8987117f1b4Smrg dst[2] = src[i * 4 + 2]; 8997117f1b4Smrg dst[3] = src[i * 4 + 3]; 9007117f1b4Smrg } 9017117f1b4Smrg } 9027117f1b4Smrg} 9037117f1b4Smrg 9047117f1b4Smrg 9057117f1b4Smrgstatic void 9067117f1b4Smrgput_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, 9077117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 9087117f1b4Smrg const void *value, const GLubyte *mask) 9097117f1b4Smrg{ 9107117f1b4Smrg const GLushort val0 = ((const GLushort *) value)[0]; 9117117f1b4Smrg const GLushort val1 = ((const GLushort *) value)[1]; 9127117f1b4Smrg const GLushort val2 = ((const GLushort *) value)[2]; 9137117f1b4Smrg const GLushort val3 = ((const GLushort *) value)[3]; 9147117f1b4Smrg GLuint i; 9157117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 9167117f1b4Smrg for (i = 0; i < count; i++) { 9177117f1b4Smrg if (!mask || mask[i]) { 9187117f1b4Smrg GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]); 9197117f1b4Smrg dst[0] = val0; 9207117f1b4Smrg dst[1] = val1; 9217117f1b4Smrg dst[2] = val2; 9227117f1b4Smrg dst[3] = val3; 9237117f1b4Smrg } 9247117f1b4Smrg } 9257117f1b4Smrg} 9267117f1b4Smrg 9277117f1b4Smrg 9287117f1b4Smrg 9297117f1b4Smrg/** 9307117f1b4Smrg * This is a software fallback for the gl_renderbuffer->AllocStorage 9317117f1b4Smrg * function. 9327117f1b4Smrg * Device drivers will typically override this function for the buffers 9337117f1b4Smrg * which it manages (typically color buffers, Z and stencil). 9347117f1b4Smrg * Other buffers (like software accumulation and aux buffers) which the driver 9357117f1b4Smrg * doesn't manage can be handled with this function. 9367117f1b4Smrg * 9377117f1b4Smrg * This one multi-purpose function can allocate stencil, depth, accum, color 9387117f1b4Smrg * or color-index buffers! 9397117f1b4Smrg * 9407117f1b4Smrg * This function also plugs in the appropriate GetPointer, Get/PutRow and 9417117f1b4Smrg * Get/PutValues functions. 9427117f1b4Smrg */ 9437117f1b4SmrgGLboolean 9447117f1b4Smrg_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, 9457117f1b4Smrg GLenum internalFormat, 9467117f1b4Smrg GLuint width, GLuint height) 9477117f1b4Smrg{ 9487117f1b4Smrg GLuint pixelSize; 9497117f1b4Smrg 9507117f1b4Smrg /* first clear these fields */ 9517117f1b4Smrg rb->RedBits = 9527117f1b4Smrg rb->GreenBits = 9537117f1b4Smrg rb->BlueBits = 9547117f1b4Smrg rb->AlphaBits = 9557117f1b4Smrg rb->IndexBits = 9567117f1b4Smrg rb->DepthBits = 9577117f1b4Smrg rb->StencilBits = 0; 9587117f1b4Smrg 9597117f1b4Smrg switch (internalFormat) { 9607117f1b4Smrg case GL_RGB: 9617117f1b4Smrg case GL_R3_G3_B2: 9627117f1b4Smrg case GL_RGB4: 9637117f1b4Smrg case GL_RGB5: 9647117f1b4Smrg case GL_RGB8: 9657117f1b4Smrg case GL_RGB10: 9667117f1b4Smrg case GL_RGB12: 9677117f1b4Smrg case GL_RGB16: 9687117f1b4Smrg rb->_ActualFormat = GL_RGB8; 9697117f1b4Smrg rb->_BaseFormat = GL_RGB; 9707117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 9717117f1b4Smrg rb->GetPointer = get_pointer_ubyte3; 9727117f1b4Smrg rb->GetRow = get_row_ubyte3; 9737117f1b4Smrg rb->GetValues = get_values_ubyte3; 9747117f1b4Smrg rb->PutRow = put_row_ubyte3; 9757117f1b4Smrg rb->PutRowRGB = put_row_rgb_ubyte3; 9767117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte3; 9777117f1b4Smrg rb->PutValues = put_values_ubyte3; 9787117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte3; 9797117f1b4Smrg rb->RedBits = 8 * sizeof(GLubyte); 9807117f1b4Smrg rb->GreenBits = 8 * sizeof(GLubyte); 9817117f1b4Smrg rb->BlueBits = 8 * sizeof(GLubyte); 9827117f1b4Smrg rb->AlphaBits = 0; 9837117f1b4Smrg pixelSize = 3 * sizeof(GLubyte); 9847117f1b4Smrg break; 9857117f1b4Smrg case GL_RGBA: 9867117f1b4Smrg case GL_RGBA2: 9877117f1b4Smrg case GL_RGBA4: 9887117f1b4Smrg case GL_RGB5_A1: 9897117f1b4Smrg case GL_RGBA8: 9907117f1b4Smrg rb->_ActualFormat = GL_RGBA8; 9917117f1b4Smrg rb->_BaseFormat = GL_RGBA; 9927117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 9937117f1b4Smrg rb->GetPointer = get_pointer_ubyte4; 9947117f1b4Smrg rb->GetRow = get_row_ubyte4; 9957117f1b4Smrg rb->GetValues = get_values_ubyte4; 9967117f1b4Smrg rb->PutRow = put_row_ubyte4; 9977117f1b4Smrg rb->PutRowRGB = put_row_rgb_ubyte4; 9987117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte4; 9997117f1b4Smrg rb->PutValues = put_values_ubyte4; 10007117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte4; 10017117f1b4Smrg rb->RedBits = 8 * sizeof(GLubyte); 10027117f1b4Smrg rb->GreenBits = 8 * sizeof(GLubyte); 10037117f1b4Smrg rb->BlueBits = 8 * sizeof(GLubyte); 10047117f1b4Smrg rb->AlphaBits = 8 * sizeof(GLubyte); 10057117f1b4Smrg pixelSize = 4 * sizeof(GLubyte); 10067117f1b4Smrg break; 10077117f1b4Smrg case GL_RGB10_A2: 10087117f1b4Smrg case GL_RGBA12: 10097117f1b4Smrg case GL_RGBA16: 10107117f1b4Smrg rb->_ActualFormat = GL_RGBA16; 10117117f1b4Smrg rb->_BaseFormat = GL_RGBA; 10127117f1b4Smrg rb->DataType = GL_UNSIGNED_SHORT; 10137117f1b4Smrg rb->GetPointer = get_pointer_ushort4; 10147117f1b4Smrg rb->GetRow = get_row_ushort4; 10157117f1b4Smrg rb->GetValues = get_values_ushort4; 10167117f1b4Smrg rb->PutRow = put_row_ushort4; 10177117f1b4Smrg rb->PutRowRGB = put_row_rgb_ushort4; 10187117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort4; 10197117f1b4Smrg rb->PutValues = put_values_ushort4; 10207117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort4; 10217117f1b4Smrg rb->RedBits = 8 * sizeof(GLushort); 10227117f1b4Smrg rb->GreenBits = 8 * sizeof(GLushort); 10237117f1b4Smrg rb->BlueBits = 8 * sizeof(GLushort); 10247117f1b4Smrg rb->AlphaBits = 8 * sizeof(GLushort); 10257117f1b4Smrg pixelSize = 4 * sizeof(GLushort); 10267117f1b4Smrg break; 10277117f1b4Smrg#if 00 10287117f1b4Smrg case GL_ALPHA8: 10297117f1b4Smrg rb->_ActualFormat = GL_ALPHA8; 10307117f1b4Smrg rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */ 10317117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 10327117f1b4Smrg rb->GetPointer = get_pointer_alpha8; 10337117f1b4Smrg rb->GetRow = get_row_alpha8; 10347117f1b4Smrg rb->GetValues = get_values_alpha8; 10357117f1b4Smrg rb->PutRow = put_row_alpha8; 10367117f1b4Smrg rb->PutRowRGB = NULL; 10377117f1b4Smrg rb->PutMonoRow = put_mono_row_alpha8; 10387117f1b4Smrg rb->PutValues = put_values_alpha8; 10397117f1b4Smrg rb->PutMonoValues = put_mono_values_alpha8; 10407117f1b4Smrg rb->RedBits = 0; /*red*/ 10417117f1b4Smrg rb->GreenBits = 0; /*green*/ 10427117f1b4Smrg rb->BlueBits = 0; /*blue*/ 10437117f1b4Smrg rb->AlphaBits = 8 * sizeof(GLubyte); 10447117f1b4Smrg pixelSize = sizeof(GLubyte); 10457117f1b4Smrg break; 10467117f1b4Smrg#endif 10477117f1b4Smrg case GL_STENCIL_INDEX: 10487117f1b4Smrg case GL_STENCIL_INDEX1_EXT: 10497117f1b4Smrg case GL_STENCIL_INDEX4_EXT: 10507117f1b4Smrg case GL_STENCIL_INDEX8_EXT: 10517117f1b4Smrg rb->_ActualFormat = GL_STENCIL_INDEX8_EXT; 10527117f1b4Smrg rb->_BaseFormat = GL_STENCIL_INDEX; 10537117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 10547117f1b4Smrg rb->GetPointer = get_pointer_ubyte; 10557117f1b4Smrg rb->GetRow = get_row_ubyte; 10567117f1b4Smrg rb->GetValues = get_values_ubyte; 10577117f1b4Smrg rb->PutRow = put_row_ubyte; 10587117f1b4Smrg rb->PutRowRGB = NULL; 10597117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte; 10607117f1b4Smrg rb->PutValues = put_values_ubyte; 10617117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte; 10627117f1b4Smrg rb->StencilBits = 8 * sizeof(GLubyte); 10637117f1b4Smrg pixelSize = sizeof(GLubyte); 10647117f1b4Smrg break; 10657117f1b4Smrg case GL_STENCIL_INDEX16_EXT: 10667117f1b4Smrg rb->_ActualFormat = GL_STENCIL_INDEX16_EXT; 10677117f1b4Smrg rb->_BaseFormat = GL_STENCIL_INDEX; 10687117f1b4Smrg rb->DataType = GL_UNSIGNED_SHORT; 10697117f1b4Smrg rb->GetPointer = get_pointer_ushort; 10707117f1b4Smrg rb->GetRow = get_row_ushort; 10717117f1b4Smrg rb->GetValues = get_values_ushort; 10727117f1b4Smrg rb->PutRow = put_row_ushort; 10737117f1b4Smrg rb->PutRowRGB = NULL; 10747117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort; 10757117f1b4Smrg rb->PutValues = put_values_ushort; 10767117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort; 10777117f1b4Smrg rb->StencilBits = 8 * sizeof(GLushort); 10787117f1b4Smrg pixelSize = sizeof(GLushort); 10797117f1b4Smrg break; 10807117f1b4Smrg case GL_DEPTH_COMPONENT: 10817117f1b4Smrg case GL_DEPTH_COMPONENT16: 10827117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT16; 10837117f1b4Smrg rb->_BaseFormat = GL_DEPTH_COMPONENT; 10847117f1b4Smrg rb->DataType = GL_UNSIGNED_SHORT; 10857117f1b4Smrg rb->GetPointer = get_pointer_ushort; 10867117f1b4Smrg rb->GetRow = get_row_ushort; 10877117f1b4Smrg rb->GetValues = get_values_ushort; 10887117f1b4Smrg rb->PutRow = put_row_ushort; 10897117f1b4Smrg rb->PutRowRGB = NULL; 10907117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort; 10917117f1b4Smrg rb->PutValues = put_values_ushort; 10927117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort; 10937117f1b4Smrg rb->DepthBits = 8 * sizeof(GLushort); 10947117f1b4Smrg pixelSize = sizeof(GLushort); 10957117f1b4Smrg break; 10967117f1b4Smrg case GL_DEPTH_COMPONENT24: 10977117f1b4Smrg case GL_DEPTH_COMPONENT32: 10987117f1b4Smrg rb->_BaseFormat = GL_DEPTH_COMPONENT; 10997117f1b4Smrg rb->DataType = GL_UNSIGNED_INT; 11007117f1b4Smrg rb->GetPointer = get_pointer_uint; 11017117f1b4Smrg rb->GetRow = get_row_uint; 11027117f1b4Smrg rb->GetValues = get_values_uint; 11037117f1b4Smrg rb->PutRow = put_row_uint; 11047117f1b4Smrg rb->PutRowRGB = NULL; 11057117f1b4Smrg rb->PutMonoRow = put_mono_row_uint; 11067117f1b4Smrg rb->PutValues = put_values_uint; 11077117f1b4Smrg rb->PutMonoValues = put_mono_values_uint; 11087117f1b4Smrg if (internalFormat == GL_DEPTH_COMPONENT24) { 11097117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT24; 11107117f1b4Smrg rb->DepthBits = 24; 11117117f1b4Smrg } 11127117f1b4Smrg else { 11137117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT32; 11147117f1b4Smrg rb->DepthBits = 32; 11157117f1b4Smrg } 11167117f1b4Smrg pixelSize = sizeof(GLuint); 11177117f1b4Smrg break; 11187117f1b4Smrg case GL_DEPTH_STENCIL_EXT: 11197117f1b4Smrg case GL_DEPTH24_STENCIL8_EXT: 11207117f1b4Smrg rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; 11217117f1b4Smrg rb->_BaseFormat = GL_DEPTH_STENCIL_EXT; 11227117f1b4Smrg rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 11237117f1b4Smrg rb->GetPointer = get_pointer_uint; 11247117f1b4Smrg rb->GetRow = get_row_uint; 11257117f1b4Smrg rb->GetValues = get_values_uint; 11267117f1b4Smrg rb->PutRow = put_row_uint; 11277117f1b4Smrg rb->PutRowRGB = NULL; 11287117f1b4Smrg rb->PutMonoRow = put_mono_row_uint; 11297117f1b4Smrg rb->PutValues = put_values_uint; 11307117f1b4Smrg rb->PutMonoValues = put_mono_values_uint; 11317117f1b4Smrg rb->DepthBits = 24; 11327117f1b4Smrg rb->StencilBits = 8; 11337117f1b4Smrg pixelSize = sizeof(GLuint); 11347117f1b4Smrg break; 11357117f1b4Smrg case GL_COLOR_INDEX8_EXT: 11367117f1b4Smrg rb->_ActualFormat = GL_COLOR_INDEX8_EXT; 11377117f1b4Smrg rb->_BaseFormat = GL_COLOR_INDEX; 11387117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 11397117f1b4Smrg rb->GetPointer = get_pointer_ubyte; 11407117f1b4Smrg rb->GetRow = get_row_ubyte; 11417117f1b4Smrg rb->GetValues = get_values_ubyte; 11427117f1b4Smrg rb->PutRow = put_row_ubyte; 11437117f1b4Smrg rb->PutRowRGB = NULL; 11447117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte; 11457117f1b4Smrg rb->PutValues = put_values_ubyte; 11467117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte; 11477117f1b4Smrg rb->IndexBits = 8 * sizeof(GLubyte); 11487117f1b4Smrg pixelSize = sizeof(GLubyte); 11497117f1b4Smrg break; 11507117f1b4Smrg case GL_COLOR_INDEX16_EXT: 11517117f1b4Smrg rb->_ActualFormat = GL_COLOR_INDEX16_EXT; 11527117f1b4Smrg rb->_BaseFormat = GL_COLOR_INDEX; 11537117f1b4Smrg rb->DataType = GL_UNSIGNED_SHORT; 11547117f1b4Smrg rb->GetPointer = get_pointer_ushort; 11557117f1b4Smrg rb->GetRow = get_row_ushort; 11567117f1b4Smrg rb->GetValues = get_values_ushort; 11577117f1b4Smrg rb->PutRow = put_row_ushort; 11587117f1b4Smrg rb->PutRowRGB = NULL; 11597117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort; 11607117f1b4Smrg rb->PutValues = put_values_ushort; 11617117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort; 11627117f1b4Smrg rb->IndexBits = 8 * sizeof(GLushort); 11637117f1b4Smrg pixelSize = sizeof(GLushort); 11647117f1b4Smrg break; 11657117f1b4Smrg case COLOR_INDEX32: 11667117f1b4Smrg rb->_ActualFormat = COLOR_INDEX32; 11677117f1b4Smrg rb->_BaseFormat = GL_COLOR_INDEX; 11687117f1b4Smrg rb->DataType = GL_UNSIGNED_INT; 11697117f1b4Smrg rb->GetPointer = get_pointer_uint; 11707117f1b4Smrg rb->GetRow = get_row_uint; 11717117f1b4Smrg rb->GetValues = get_values_uint; 11727117f1b4Smrg rb->PutRow = put_row_uint; 11737117f1b4Smrg rb->PutRowRGB = NULL; 11747117f1b4Smrg rb->PutMonoRow = put_mono_row_uint; 11757117f1b4Smrg rb->PutValues = put_values_uint; 11767117f1b4Smrg rb->PutMonoValues = put_mono_values_uint; 11777117f1b4Smrg rb->IndexBits = 8 * sizeof(GLuint); 11787117f1b4Smrg pixelSize = sizeof(GLuint); 11797117f1b4Smrg break; 11807117f1b4Smrg default: 11817117f1b4Smrg _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage"); 11827117f1b4Smrg return GL_FALSE; 11837117f1b4Smrg } 11847117f1b4Smrg 11857117f1b4Smrg ASSERT(rb->DataType); 11867117f1b4Smrg ASSERT(rb->GetPointer); 11877117f1b4Smrg ASSERT(rb->GetRow); 11887117f1b4Smrg ASSERT(rb->GetValues); 11897117f1b4Smrg ASSERT(rb->PutRow); 11907117f1b4Smrg ASSERT(rb->PutMonoRow); 11917117f1b4Smrg ASSERT(rb->PutValues); 11927117f1b4Smrg ASSERT(rb->PutMonoValues); 11937117f1b4Smrg 11947117f1b4Smrg /* free old buffer storage */ 11957117f1b4Smrg if (rb->Data) { 11967117f1b4Smrg _mesa_free(rb->Data); 11977117f1b4Smrg rb->Data = NULL; 11987117f1b4Smrg } 11997117f1b4Smrg 12007117f1b4Smrg if (width > 0 && height > 0) { 12017117f1b4Smrg /* allocate new buffer storage */ 12027117f1b4Smrg rb->Data = _mesa_malloc(width * height * pixelSize); 12037117f1b4Smrg if (rb->Data == NULL) { 12047117f1b4Smrg rb->Width = 0; 12057117f1b4Smrg rb->Height = 0; 12067117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, 12077117f1b4Smrg "software renderbuffer allocation (%d x %d x %d)", 12087117f1b4Smrg width, height, pixelSize); 12097117f1b4Smrg return GL_FALSE; 12107117f1b4Smrg } 12117117f1b4Smrg } 12127117f1b4Smrg 12137117f1b4Smrg rb->Width = width; 12147117f1b4Smrg rb->Height = height; 12157117f1b4Smrg 12167117f1b4Smrg return GL_TRUE; 12177117f1b4Smrg} 12187117f1b4Smrg 12197117f1b4Smrg 12207117f1b4Smrg 12217117f1b4Smrg/**********************************************************************/ 12227117f1b4Smrg/**********************************************************************/ 12237117f1b4Smrg/**********************************************************************/ 12247117f1b4Smrg 12257117f1b4Smrg 12267117f1b4Smrg/** 12277117f1b4Smrg * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha 12287117f1b4Smrg * buffer wrapper around an existing RGB renderbuffer (hw or sw). 12297117f1b4Smrg * 12307117f1b4Smrg * When PutRow is called (for example), we store the alpha values in 12317117f1b4Smrg * this buffer, then pass on the PutRow call to the wrapped RGB 12327117f1b4Smrg * buffer. 12337117f1b4Smrg */ 12347117f1b4Smrg 12357117f1b4Smrg 12367117f1b4Smrgstatic GLboolean 12377117f1b4Smrgalloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, 12387117f1b4Smrg GLenum internalFormat, GLuint width, GLuint height) 12397117f1b4Smrg{ 12407117f1b4Smrg ASSERT(arb != arb->Wrapped); 12417117f1b4Smrg ASSERT(arb->_ActualFormat == GL_ALPHA8); 12427117f1b4Smrg 12437117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 12447117f1b4Smrg if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat, 12457117f1b4Smrg width, height)) { 12467117f1b4Smrg return GL_FALSE; 12477117f1b4Smrg } 12487117f1b4Smrg 12497117f1b4Smrg /* next, resize my alpha buffer */ 12507117f1b4Smrg if (arb->Data) { 12517117f1b4Smrg _mesa_free(arb->Data); 12527117f1b4Smrg } 12537117f1b4Smrg 12547117f1b4Smrg arb->Data = _mesa_malloc(width * height * sizeof(GLubyte)); 12557117f1b4Smrg if (arb->Data == NULL) { 12567117f1b4Smrg arb->Width = 0; 12577117f1b4Smrg arb->Height = 0; 12587117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 12597117f1b4Smrg return GL_FALSE; 12607117f1b4Smrg } 12617117f1b4Smrg 12627117f1b4Smrg arb->Width = width; 12637117f1b4Smrg arb->Height = height; 12647117f1b4Smrg 12657117f1b4Smrg return GL_TRUE; 12667117f1b4Smrg} 12677117f1b4Smrg 12687117f1b4Smrg 12697117f1b4Smrg/** 12707117f1b4Smrg * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 12717117f1b4Smrg */ 12727117f1b4Smrgstatic void 12737117f1b4Smrgdelete_renderbuffer_alpha8(struct gl_renderbuffer *arb) 12747117f1b4Smrg{ 12757117f1b4Smrg if (arb->Data) { 12767117f1b4Smrg _mesa_free(arb->Data); 12777117f1b4Smrg } 12787117f1b4Smrg ASSERT(arb->Wrapped); 12797117f1b4Smrg ASSERT(arb != arb->Wrapped); 12807117f1b4Smrg arb->Wrapped->Delete(arb->Wrapped); 12817117f1b4Smrg arb->Wrapped = NULL; 12827117f1b4Smrg _mesa_free(arb); 12837117f1b4Smrg} 12847117f1b4Smrg 12857117f1b4Smrg 12867117f1b4Smrgstatic void * 12877117f1b4Smrgget_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, 12887117f1b4Smrg GLint x, GLint y) 12897117f1b4Smrg{ 12907117f1b4Smrg return NULL; /* don't allow direct access! */ 12917117f1b4Smrg} 12927117f1b4Smrg 12937117f1b4Smrg 12947117f1b4Smrgstatic void 12957117f1b4Smrgget_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 12967117f1b4Smrg GLint x, GLint y, void *values) 12977117f1b4Smrg{ 12987117f1b4Smrg /* NOTE: 'values' is RGBA format! */ 12997117f1b4Smrg const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x; 13007117f1b4Smrg GLubyte *dst = (GLubyte *) values; 13017117f1b4Smrg GLuint i; 13027117f1b4Smrg ASSERT(arb != arb->Wrapped); 13037117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 13047117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 13057117f1b4Smrg arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values); 13067117f1b4Smrg /* second, fill in alpha values from this buffer! */ 13077117f1b4Smrg for (i = 0; i < count; i++) { 13087117f1b4Smrg dst[i * 4 + 3] = src[i]; 13097117f1b4Smrg } 13107117f1b4Smrg} 13117117f1b4Smrg 13127117f1b4Smrg 13137117f1b4Smrgstatic void 13147117f1b4Smrgget_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 13157117f1b4Smrg const GLint x[], const GLint y[], void *values) 13167117f1b4Smrg{ 13177117f1b4Smrg GLubyte *dst = (GLubyte *) values; 13187117f1b4Smrg GLuint i; 13197117f1b4Smrg ASSERT(arb != arb->Wrapped); 13207117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 13217117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 13227117f1b4Smrg arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values); 13237117f1b4Smrg /* second, fill in alpha values from this buffer! */ 13247117f1b4Smrg for (i = 0; i < count; i++) { 13257117f1b4Smrg const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i]; 13267117f1b4Smrg dst[i * 4 + 3] = *src; 13277117f1b4Smrg } 13287117f1b4Smrg} 13297117f1b4Smrg 13307117f1b4Smrg 13317117f1b4Smrgstatic void 13327117f1b4Smrgput_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 13337117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 13347117f1b4Smrg{ 13357117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 13367117f1b4Smrg GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x; 13377117f1b4Smrg GLuint i; 13387117f1b4Smrg ASSERT(arb != arb->Wrapped); 13397117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 13407117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 13417117f1b4Smrg arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask); 13427117f1b4Smrg /* second, store alpha in our buffer */ 13437117f1b4Smrg for (i = 0; i < count; i++) { 13447117f1b4Smrg if (!mask || mask[i]) { 13457117f1b4Smrg dst[i] = src[i * 4 + 3]; 13467117f1b4Smrg } 13477117f1b4Smrg } 13487117f1b4Smrg} 13497117f1b4Smrg 13507117f1b4Smrg 13517117f1b4Smrgstatic void 13527117f1b4Smrgput_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 13537117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 13547117f1b4Smrg{ 13557117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 13567117f1b4Smrg GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x; 13577117f1b4Smrg GLuint i; 13587117f1b4Smrg ASSERT(arb != arb->Wrapped); 13597117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 13607117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 13617117f1b4Smrg arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask); 13627117f1b4Smrg /* second, store alpha in our buffer */ 13637117f1b4Smrg for (i = 0; i < count; i++) { 13647117f1b4Smrg if (!mask || mask[i]) { 13657117f1b4Smrg dst[i] = src[i * 4 + 3]; 13667117f1b4Smrg } 13677117f1b4Smrg } 13687117f1b4Smrg} 13697117f1b4Smrg 13707117f1b4Smrg 13717117f1b4Smrgstatic void 13727117f1b4Smrgput_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 13737117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 13747117f1b4Smrg{ 13757117f1b4Smrg const GLubyte val = ((const GLubyte *) value)[3]; 13767117f1b4Smrg GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x; 13777117f1b4Smrg ASSERT(arb != arb->Wrapped); 13787117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 13797117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 13807117f1b4Smrg arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask); 13817117f1b4Smrg /* second, store alpha in our buffer */ 13827117f1b4Smrg if (mask) { 13837117f1b4Smrg GLuint i; 13847117f1b4Smrg for (i = 0; i < count; i++) { 13857117f1b4Smrg if (mask[i]) { 13867117f1b4Smrg dst[i] = val; 13877117f1b4Smrg } 13887117f1b4Smrg } 13897117f1b4Smrg } 13907117f1b4Smrg else { 13917117f1b4Smrg _mesa_memset(dst, val, count); 13927117f1b4Smrg } 13937117f1b4Smrg} 13947117f1b4Smrg 13957117f1b4Smrg 13967117f1b4Smrgstatic void 13977117f1b4Smrgput_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, 13987117f1b4Smrg const GLint x[], const GLint y[], 13997117f1b4Smrg const void *values, const GLubyte *mask) 14007117f1b4Smrg{ 14017117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 14027117f1b4Smrg GLuint i; 14037117f1b4Smrg ASSERT(arb != arb->Wrapped); 14047117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 14057117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 14067117f1b4Smrg arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask); 14077117f1b4Smrg /* second, store alpha in our buffer */ 14087117f1b4Smrg for (i = 0; i < count; i++) { 14097117f1b4Smrg if (!mask || mask[i]) { 14107117f1b4Smrg GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i]; 14117117f1b4Smrg *dst = src[i * 4 + 3]; 14127117f1b4Smrg } 14137117f1b4Smrg } 14147117f1b4Smrg} 14157117f1b4Smrg 14167117f1b4Smrg 14177117f1b4Smrgstatic void 14187117f1b4Smrgput_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, 14197117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 14207117f1b4Smrg const void *value, const GLubyte *mask) 14217117f1b4Smrg{ 14227117f1b4Smrg const GLubyte val = ((const GLubyte *) value)[3]; 14237117f1b4Smrg GLuint i; 14247117f1b4Smrg ASSERT(arb != arb->Wrapped); 14257117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 14267117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 14277117f1b4Smrg arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask); 14287117f1b4Smrg /* second, store alpha in our buffer */ 14297117f1b4Smrg for (i = 0; i < count; i++) { 14307117f1b4Smrg if (!mask || mask[i]) { 14317117f1b4Smrg GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i]; 14327117f1b4Smrg *dst = val; 14337117f1b4Smrg } 14347117f1b4Smrg } 14357117f1b4Smrg} 14367117f1b4Smrg 14377117f1b4Smrg 14387117f1b4Smrgstatic void 14397117f1b4Smrgcopy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) 14407117f1b4Smrg{ 14417117f1b4Smrg ASSERT(dst->_ActualFormat == GL_ALPHA8); 14427117f1b4Smrg ASSERT(src->_ActualFormat == GL_ALPHA8); 14437117f1b4Smrg ASSERT(dst->Width == src->Width); 14447117f1b4Smrg ASSERT(dst->Height == src->Height); 14457117f1b4Smrg 14467117f1b4Smrg _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte)); 14477117f1b4Smrg} 14487117f1b4Smrg 14497117f1b4Smrg 14507117f1b4Smrg/**********************************************************************/ 14517117f1b4Smrg/**********************************************************************/ 14527117f1b4Smrg/**********************************************************************/ 14537117f1b4Smrg 14547117f1b4Smrg 14557117f1b4Smrg/** 14567117f1b4Smrg * Default GetPointer routine. Always return NULL to indicate that 14577117f1b4Smrg * direct buffer access is not supported. 14587117f1b4Smrg */ 14597117f1b4Smrgstatic void * 14607117f1b4Smrgnop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 14617117f1b4Smrg{ 14627117f1b4Smrg return NULL; 14637117f1b4Smrg} 14647117f1b4Smrg 14657117f1b4Smrg 14667117f1b4Smrg/** 14677117f1b4Smrg * Initialize the fields of a gl_renderbuffer to default values. 14687117f1b4Smrg */ 14697117f1b4Smrgvoid 14707117f1b4Smrg_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 14717117f1b4Smrg{ 14727117f1b4Smrg _glthread_INIT_MUTEX(rb->Mutex); 14737117f1b4Smrg 14747117f1b4Smrg rb->Magic = RB_MAGIC; 14757117f1b4Smrg rb->ClassID = 0; 14767117f1b4Smrg rb->Name = name; 14777117f1b4Smrg rb->RefCount = 0; 14787117f1b4Smrg rb->Delete = _mesa_delete_renderbuffer; 14797117f1b4Smrg 14807117f1b4Smrg /* The rest of these should be set later by the caller of this function or 14817117f1b4Smrg * the AllocStorage method: 14827117f1b4Smrg */ 14837117f1b4Smrg rb->AllocStorage = NULL; 14847117f1b4Smrg 14857117f1b4Smrg rb->Width = 0; 14867117f1b4Smrg rb->Height = 0; 14877117f1b4Smrg rb->InternalFormat = GL_NONE; 14887117f1b4Smrg rb->_ActualFormat = GL_NONE; 14897117f1b4Smrg rb->_BaseFormat = GL_NONE; 14907117f1b4Smrg rb->DataType = GL_NONE; 14917117f1b4Smrg rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0; 14927117f1b4Smrg rb->IndexBits = 0; 14937117f1b4Smrg rb->DepthBits = 0; 14947117f1b4Smrg rb->StencilBits = 0; 14957117f1b4Smrg rb->Data = NULL; 14967117f1b4Smrg 14977117f1b4Smrg /* Point back to ourself so that we don't have to check for Wrapped==NULL 14987117f1b4Smrg * all over the drivers. 14997117f1b4Smrg */ 15007117f1b4Smrg rb->Wrapped = rb; 15017117f1b4Smrg 15027117f1b4Smrg rb->GetPointer = nop_get_pointer; 15037117f1b4Smrg rb->GetRow = NULL; 15047117f1b4Smrg rb->GetValues = NULL; 15057117f1b4Smrg rb->PutRow = NULL; 15067117f1b4Smrg rb->PutRowRGB = NULL; 15077117f1b4Smrg rb->PutMonoRow = NULL; 15087117f1b4Smrg rb->PutValues = NULL; 15097117f1b4Smrg rb->PutMonoValues = NULL; 15107117f1b4Smrg} 15117117f1b4Smrg 15127117f1b4Smrg 15137117f1b4Smrg/** 15147117f1b4Smrg * Allocate a new gl_renderbuffer object. This can be used for user-created 15157117f1b4Smrg * renderbuffers or window-system renderbuffers. 15167117f1b4Smrg */ 15177117f1b4Smrgstruct gl_renderbuffer * 15187117f1b4Smrg_mesa_new_renderbuffer(GLcontext *ctx, GLuint name) 15197117f1b4Smrg{ 15207117f1b4Smrg struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 15217117f1b4Smrg if (rb) { 15227117f1b4Smrg _mesa_init_renderbuffer(rb, name); 15237117f1b4Smrg } 15247117f1b4Smrg return rb; 15257117f1b4Smrg} 15267117f1b4Smrg 15277117f1b4Smrg 15287117f1b4Smrg/** 15297117f1b4Smrg * Delete a gl_framebuffer. 15307117f1b4Smrg * This is the default function for renderbuffer->Delete(). 15317117f1b4Smrg */ 15327117f1b4Smrgvoid 15337117f1b4Smrg_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 15347117f1b4Smrg{ 15357117f1b4Smrg if (rb->Data) { 15367117f1b4Smrg _mesa_free(rb->Data); 15377117f1b4Smrg } 15387117f1b4Smrg _mesa_free(rb); 15397117f1b4Smrg} 15407117f1b4Smrg 15417117f1b4Smrg 15427117f1b4Smrg/** 15437117f1b4Smrg * Allocate a software-based renderbuffer. This is called via the 15447117f1b4Smrg * ctx->Driver.NewRenderbuffer() function when the user creates a new 15457117f1b4Smrg * renderbuffer. 15467117f1b4Smrg * This would not be used for hardware-based renderbuffers. 15477117f1b4Smrg */ 15487117f1b4Smrgstruct gl_renderbuffer * 15497117f1b4Smrg_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name) 15507117f1b4Smrg{ 15517117f1b4Smrg struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 15527117f1b4Smrg if (rb) { 15537117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 15547117f1b4Smrg /* Normally, one would setup the PutRow, GetRow, etc functions here. 15557117f1b4Smrg * But we're doing that in the _mesa_soft_renderbuffer_storage() function 15567117f1b4Smrg * instead. 15577117f1b4Smrg */ 15587117f1b4Smrg } 15597117f1b4Smrg return rb; 15607117f1b4Smrg} 15617117f1b4Smrg 15627117f1b4Smrg 15637117f1b4Smrg/** 15647117f1b4Smrg * Add software-based color renderbuffers to the given framebuffer. 15657117f1b4Smrg * This is a helper routine for device drivers when creating a 15667117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 15677117f1b4Smrg * Once this function is called, you can basically forget about this 15687117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 15697117f1b4Smrg * rendering! 15707117f1b4Smrg */ 15717117f1b4SmrgGLboolean 15727117f1b4Smrg_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 15737117f1b4Smrg GLuint rgbBits, GLuint alphaBits, 15747117f1b4Smrg GLboolean frontLeft, GLboolean backLeft, 15757117f1b4Smrg GLboolean frontRight, GLboolean backRight) 15767117f1b4Smrg{ 15777117f1b4Smrg GLuint b; 15787117f1b4Smrg 15797117f1b4Smrg if (rgbBits > 16 || alphaBits > 16) { 15807117f1b4Smrg _mesa_problem(ctx, 15817117f1b4Smrg "Unsupported bit depth in _mesa_add_color_renderbuffers"); 15827117f1b4Smrg return GL_FALSE; 15837117f1b4Smrg } 15847117f1b4Smrg 15857117f1b4Smrg assert(MAX_COLOR_ATTACHMENTS >= 4); 15867117f1b4Smrg 15877117f1b4Smrg for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 15887117f1b4Smrg struct gl_renderbuffer *rb; 15897117f1b4Smrg 15907117f1b4Smrg if (b == BUFFER_FRONT_LEFT && !frontLeft) 15917117f1b4Smrg continue; 15927117f1b4Smrg else if (b == BUFFER_BACK_LEFT && !backLeft) 15937117f1b4Smrg continue; 15947117f1b4Smrg else if (b == BUFFER_FRONT_RIGHT && !frontRight) 15957117f1b4Smrg continue; 15967117f1b4Smrg else if (b == BUFFER_BACK_RIGHT && !backRight) 15977117f1b4Smrg continue; 15987117f1b4Smrg 15997117f1b4Smrg assert(fb->Attachment[b].Renderbuffer == NULL); 16007117f1b4Smrg 16017117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 16027117f1b4Smrg if (!rb) { 16037117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 16047117f1b4Smrg return GL_FALSE; 16057117f1b4Smrg } 16067117f1b4Smrg 16077117f1b4Smrg if (rgbBits <= 8) { 16087117f1b4Smrg if (alphaBits) 16097117f1b4Smrg rb->_ActualFormat = GL_RGBA8; 16107117f1b4Smrg else 16117117f1b4Smrg rb->_ActualFormat = GL_RGB8; 16127117f1b4Smrg } 16137117f1b4Smrg else { 16147117f1b4Smrg assert(rgbBits <= 16); 16157117f1b4Smrg if (alphaBits) 16167117f1b4Smrg rb->_ActualFormat = GL_RGBA16; 16177117f1b4Smrg else 16187117f1b4Smrg rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */ 16197117f1b4Smrg } 16207117f1b4Smrg rb->InternalFormat = rb->_ActualFormat; 16217117f1b4Smrg 16227117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 16237117f1b4Smrg _mesa_add_renderbuffer(fb, b, rb); 16247117f1b4Smrg } 16257117f1b4Smrg 16267117f1b4Smrg return GL_TRUE; 16277117f1b4Smrg} 16287117f1b4Smrg 16297117f1b4Smrg 16307117f1b4Smrg/** 16317117f1b4Smrg * Add software-based color index renderbuffers to the given framebuffer. 16327117f1b4Smrg * This is a helper routine for device drivers when creating a 16337117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 16347117f1b4Smrg * Once this function is called, you can basically forget about this 16357117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 16367117f1b4Smrg * rendering! 16377117f1b4Smrg */ 16387117f1b4SmrgGLboolean 16397117f1b4Smrg_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 16407117f1b4Smrg GLuint indexBits, 16417117f1b4Smrg GLboolean frontLeft, GLboolean backLeft, 16427117f1b4Smrg GLboolean frontRight, GLboolean backRight) 16437117f1b4Smrg{ 16447117f1b4Smrg GLuint b; 16457117f1b4Smrg 16467117f1b4Smrg if (indexBits > 8) { 16477117f1b4Smrg _mesa_problem(ctx, 16487117f1b4Smrg "Unsupported bit depth in _mesa_add_color_index_renderbuffers"); 16497117f1b4Smrg return GL_FALSE; 16507117f1b4Smrg } 16517117f1b4Smrg 16527117f1b4Smrg assert(MAX_COLOR_ATTACHMENTS >= 4); 16537117f1b4Smrg 16547117f1b4Smrg for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 16557117f1b4Smrg struct gl_renderbuffer *rb; 16567117f1b4Smrg 16577117f1b4Smrg if (b == BUFFER_FRONT_LEFT && !frontLeft) 16587117f1b4Smrg continue; 16597117f1b4Smrg else if (b == BUFFER_BACK_LEFT && !backLeft) 16607117f1b4Smrg continue; 16617117f1b4Smrg else if (b == BUFFER_FRONT_RIGHT && !frontRight) 16627117f1b4Smrg continue; 16637117f1b4Smrg else if (b == BUFFER_BACK_RIGHT && !backRight) 16647117f1b4Smrg continue; 16657117f1b4Smrg 16667117f1b4Smrg assert(fb->Attachment[b].Renderbuffer == NULL); 16677117f1b4Smrg 16687117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 16697117f1b4Smrg if (!rb) { 16707117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 16717117f1b4Smrg return GL_FALSE; 16727117f1b4Smrg } 16737117f1b4Smrg 16747117f1b4Smrg if (indexBits <= 8) { 16757117f1b4Smrg /* only support GLuint for now */ 16767117f1b4Smrg /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/ 16777117f1b4Smrg rb->_ActualFormat = COLOR_INDEX32; 16787117f1b4Smrg } 16797117f1b4Smrg else { 16807117f1b4Smrg rb->_ActualFormat = COLOR_INDEX32; 16817117f1b4Smrg } 16827117f1b4Smrg rb->InternalFormat = rb->_ActualFormat; 16837117f1b4Smrg 16847117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 16857117f1b4Smrg _mesa_add_renderbuffer(fb, b, rb); 16867117f1b4Smrg } 16877117f1b4Smrg 16887117f1b4Smrg return GL_TRUE; 16897117f1b4Smrg} 16907117f1b4Smrg 16917117f1b4Smrg 16927117f1b4Smrg/** 16937117f1b4Smrg * Add software-based alpha renderbuffers to the given framebuffer. 16947117f1b4Smrg * This is a helper routine for device drivers when creating a 16957117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 16967117f1b4Smrg * Once this function is called, you can basically forget about this 16977117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 16987117f1b4Smrg * rendering! 16997117f1b4Smrg */ 17007117f1b4SmrgGLboolean 17017117f1b4Smrg_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 17027117f1b4Smrg GLuint alphaBits, 17037117f1b4Smrg GLboolean frontLeft, GLboolean backLeft, 17047117f1b4Smrg GLboolean frontRight, GLboolean backRight) 17057117f1b4Smrg{ 17067117f1b4Smrg GLuint b; 17077117f1b4Smrg 17087117f1b4Smrg /* for window system framebuffers only! */ 17097117f1b4Smrg assert(fb->Name == 0); 17107117f1b4Smrg 17117117f1b4Smrg if (alphaBits > 8) { 17127117f1b4Smrg _mesa_problem(ctx, 17137117f1b4Smrg "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 17147117f1b4Smrg return GL_FALSE; 17157117f1b4Smrg } 17167117f1b4Smrg 17177117f1b4Smrg assert(MAX_COLOR_ATTACHMENTS >= 4); 17187117f1b4Smrg 17197117f1b4Smrg /* Wrap each of the RGB color buffers with an alpha renderbuffer. 17207117f1b4Smrg */ 17217117f1b4Smrg for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 17227117f1b4Smrg struct gl_renderbuffer *arb; 17237117f1b4Smrg 17247117f1b4Smrg if (b == BUFFER_FRONT_LEFT && !frontLeft) 17257117f1b4Smrg continue; 17267117f1b4Smrg else if (b == BUFFER_BACK_LEFT && !backLeft) 17277117f1b4Smrg continue; 17287117f1b4Smrg else if (b == BUFFER_FRONT_RIGHT && !frontRight) 17297117f1b4Smrg continue; 17307117f1b4Smrg else if (b == BUFFER_BACK_RIGHT && !backRight) 17317117f1b4Smrg continue; 17327117f1b4Smrg 17337117f1b4Smrg /* the RGB buffer to wrap must already exist!! */ 17347117f1b4Smrg assert(fb->Attachment[b].Renderbuffer); 17357117f1b4Smrg 17367117f1b4Smrg /* only GLubyte supported for now */ 17377117f1b4Smrg assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 17387117f1b4Smrg 17397117f1b4Smrg /* allocate alpha renderbuffer */ 17407117f1b4Smrg arb = _mesa_new_renderbuffer(ctx, 0); 17417117f1b4Smrg if (!arb) { 17427117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 17437117f1b4Smrg return GL_FALSE; 17447117f1b4Smrg } 17457117f1b4Smrg 17467117f1b4Smrg /* wrap the alpha renderbuffer around the RGB renderbuffer */ 17477117f1b4Smrg arb->Wrapped = fb->Attachment[b].Renderbuffer; 17487117f1b4Smrg 17497117f1b4Smrg /* Set up my alphabuffer fields and plug in my functions. 17507117f1b4Smrg * The functions will put/get the alpha values from/to RGBA arrays 17517117f1b4Smrg * and then call the wrapped buffer's functions to handle the RGB 17527117f1b4Smrg * values. 17537117f1b4Smrg */ 17547117f1b4Smrg arb->InternalFormat = arb->Wrapped->InternalFormat; 17557117f1b4Smrg arb->_ActualFormat = GL_ALPHA8; 17567117f1b4Smrg arb->_BaseFormat = arb->Wrapped->_BaseFormat; 17577117f1b4Smrg arb->DataType = arb->Wrapped->DataType; 17587117f1b4Smrg arb->AllocStorage = alloc_storage_alpha8; 17597117f1b4Smrg arb->Delete = delete_renderbuffer_alpha8; 17607117f1b4Smrg arb->GetPointer = get_pointer_alpha8; 17617117f1b4Smrg arb->GetRow = get_row_alpha8; 17627117f1b4Smrg arb->GetValues = get_values_alpha8; 17637117f1b4Smrg arb->PutRow = put_row_alpha8; 17647117f1b4Smrg arb->PutRowRGB = put_row_rgb_alpha8; 17657117f1b4Smrg arb->PutMonoRow = put_mono_row_alpha8; 17667117f1b4Smrg arb->PutValues = put_values_alpha8; 17677117f1b4Smrg arb->PutMonoValues = put_mono_values_alpha8; 17687117f1b4Smrg 17697117f1b4Smrg /* clear the pointer to avoid assertion/sanity check failure later */ 17707117f1b4Smrg fb->Attachment[b].Renderbuffer = NULL; 17717117f1b4Smrg 17727117f1b4Smrg /* plug the alpha renderbuffer into the colorbuffer attachment */ 17737117f1b4Smrg _mesa_add_renderbuffer(fb, b, arb); 17747117f1b4Smrg } 17757117f1b4Smrg 17767117f1b4Smrg return GL_TRUE; 17777117f1b4Smrg} 17787117f1b4Smrg 17797117f1b4Smrg 17807117f1b4Smrg/** 17817117f1b4Smrg * For framebuffers that use a software alpha channel wrapper 17827117f1b4Smrg * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers, 17837117f1b4Smrg * copy the back buffer alpha channel into the front buffer alpha channel. 17847117f1b4Smrg */ 17857117f1b4Smrgvoid 17867117f1b4Smrg_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb) 17877117f1b4Smrg{ 17887117f1b4Smrg if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && 17897117f1b4Smrg fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) 17907117f1b4Smrg copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer, 17917117f1b4Smrg fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); 17927117f1b4Smrg 17937117f1b4Smrg 17947117f1b4Smrg if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && 17957117f1b4Smrg fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) 17967117f1b4Smrg copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer, 17977117f1b4Smrg fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); 17987117f1b4Smrg} 17997117f1b4Smrg 18007117f1b4Smrg 18017117f1b4Smrg/** 18027117f1b4Smrg * Add a software-based depth renderbuffer to the given framebuffer. 18037117f1b4Smrg * This is a helper routine for device drivers when creating a 18047117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 18057117f1b4Smrg * Once this function is called, you can basically forget about this 18067117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 18077117f1b4Smrg * rendering! 18087117f1b4Smrg */ 18097117f1b4SmrgGLboolean 18107117f1b4Smrg_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 18117117f1b4Smrg GLuint depthBits) 18127117f1b4Smrg{ 18137117f1b4Smrg struct gl_renderbuffer *rb; 18147117f1b4Smrg 18157117f1b4Smrg if (depthBits > 32) { 18167117f1b4Smrg _mesa_problem(ctx, 18177117f1b4Smrg "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 18187117f1b4Smrg return GL_FALSE; 18197117f1b4Smrg } 18207117f1b4Smrg 18217117f1b4Smrg assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 18227117f1b4Smrg 18237117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 18247117f1b4Smrg if (!rb) { 18257117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 18267117f1b4Smrg return GL_FALSE; 18277117f1b4Smrg } 18287117f1b4Smrg 18297117f1b4Smrg if (depthBits <= 16) { 18307117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT16; 18317117f1b4Smrg } 18327117f1b4Smrg else if (depthBits <= 24) { 18337117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT24; 18347117f1b4Smrg } 18357117f1b4Smrg else { 18367117f1b4Smrg rb->_ActualFormat = GL_DEPTH_COMPONENT32; 18377117f1b4Smrg } 18387117f1b4Smrg rb->InternalFormat = rb->_ActualFormat; 18397117f1b4Smrg 18407117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 18417117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 18427117f1b4Smrg 18437117f1b4Smrg return GL_TRUE; 18447117f1b4Smrg} 18457117f1b4Smrg 18467117f1b4Smrg 18477117f1b4Smrg/** 18487117f1b4Smrg * Add a software-based stencil renderbuffer to the given framebuffer. 18497117f1b4Smrg * This is a helper routine for device drivers when creating a 18507117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 18517117f1b4Smrg * Once this function is called, you can basically forget about this 18527117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 18537117f1b4Smrg * rendering! 18547117f1b4Smrg */ 18557117f1b4SmrgGLboolean 18567117f1b4Smrg_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 18577117f1b4Smrg GLuint stencilBits) 18587117f1b4Smrg{ 18597117f1b4Smrg struct gl_renderbuffer *rb; 18607117f1b4Smrg 18617117f1b4Smrg if (stencilBits > 16) { 18627117f1b4Smrg _mesa_problem(ctx, 18637117f1b4Smrg "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 18647117f1b4Smrg return GL_FALSE; 18657117f1b4Smrg } 18667117f1b4Smrg 18677117f1b4Smrg assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 18687117f1b4Smrg 18697117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 18707117f1b4Smrg if (!rb) { 18717117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 18727117f1b4Smrg return GL_FALSE; 18737117f1b4Smrg } 18747117f1b4Smrg 18757117f1b4Smrg if (stencilBits <= 8) { 18767117f1b4Smrg rb->_ActualFormat = GL_STENCIL_INDEX8_EXT; 18777117f1b4Smrg } 18787117f1b4Smrg else { 18797117f1b4Smrg /* not really supported (see s_stencil.c code) */ 18807117f1b4Smrg rb->_ActualFormat = GL_STENCIL_INDEX16_EXT; 18817117f1b4Smrg } 18827117f1b4Smrg rb->InternalFormat = rb->_ActualFormat; 18837117f1b4Smrg 18847117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 18857117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 18867117f1b4Smrg 18877117f1b4Smrg return GL_TRUE; 18887117f1b4Smrg} 18897117f1b4Smrg 18907117f1b4Smrg 18917117f1b4Smrg/** 18927117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer. 18937117f1b4Smrg * This is a helper routine for device drivers when creating a 18947117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 18957117f1b4Smrg * Once this function is called, you can basically forget about this 18967117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 18977117f1b4Smrg * rendering! 18987117f1b4Smrg */ 18997117f1b4SmrgGLboolean 19007117f1b4Smrg_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, 19017117f1b4Smrg GLuint redBits, GLuint greenBits, 19027117f1b4Smrg GLuint blueBits, GLuint alphaBits) 19037117f1b4Smrg{ 19047117f1b4Smrg struct gl_renderbuffer *rb; 19057117f1b4Smrg 19067117f1b4Smrg if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 19077117f1b4Smrg _mesa_problem(ctx, 19087117f1b4Smrg "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 19097117f1b4Smrg return GL_FALSE; 19107117f1b4Smrg } 19117117f1b4Smrg 19127117f1b4Smrg assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 19137117f1b4Smrg 19147117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 19157117f1b4Smrg if (!rb) { 19167117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 19177117f1b4Smrg return GL_FALSE; 19187117f1b4Smrg } 19197117f1b4Smrg 19207117f1b4Smrg rb->_ActualFormat = GL_RGBA16; 19217117f1b4Smrg rb->InternalFormat = GL_RGBA16; 19227117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 19237117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 19247117f1b4Smrg 19257117f1b4Smrg return GL_TRUE; 19267117f1b4Smrg} 19277117f1b4Smrg 19287117f1b4Smrg 19297117f1b4Smrg 19307117f1b4Smrg/** 19317117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer. 19327117f1b4Smrg * This is a helper routine for device drivers when creating a 19337117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 19347117f1b4Smrg * Once this function is called, you can basically forget about this 19357117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 19367117f1b4Smrg * rendering! 19377117f1b4Smrg * 19387117f1b4Smrg * NOTE: color-index aux buffers not supported. 19397117f1b4Smrg */ 19407117f1b4SmrgGLboolean 19417117f1b4Smrg_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, 19427117f1b4Smrg GLuint colorBits, GLuint numBuffers) 19437117f1b4Smrg{ 19447117f1b4Smrg GLuint i; 19457117f1b4Smrg 19467117f1b4Smrg if (colorBits > 16) { 19477117f1b4Smrg _mesa_problem(ctx, 19487117f1b4Smrg "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 19497117f1b4Smrg return GL_FALSE; 19507117f1b4Smrg } 19517117f1b4Smrg 19527117f1b4Smrg assert(numBuffers < MAX_AUX_BUFFERS); 19537117f1b4Smrg 19547117f1b4Smrg for (i = 0; i < numBuffers; i++) { 19557117f1b4Smrg struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 19567117f1b4Smrg 19577117f1b4Smrg assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 19587117f1b4Smrg 19597117f1b4Smrg if (!rb) { 19607117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 19617117f1b4Smrg return GL_FALSE; 19627117f1b4Smrg } 19637117f1b4Smrg 19647117f1b4Smrg if (colorBits <= 8) { 19657117f1b4Smrg rb->_ActualFormat = GL_RGBA8; 19667117f1b4Smrg } 19677117f1b4Smrg else { 19687117f1b4Smrg rb->_ActualFormat = GL_RGBA16; 19697117f1b4Smrg } 19707117f1b4Smrg rb->InternalFormat = rb->_ActualFormat; 19717117f1b4Smrg 19727117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 19737117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 19747117f1b4Smrg } 19757117f1b4Smrg return GL_TRUE; 19767117f1b4Smrg} 19777117f1b4Smrg 19787117f1b4Smrg 19797117f1b4Smrg/** 19807117f1b4Smrg * Create/attach software-based renderbuffers to the given framebuffer. 19817117f1b4Smrg * This is a helper routine for device drivers. Drivers can just as well 19827117f1b4Smrg * call the individual _mesa_add_*_renderbuffer() routines directly. 19837117f1b4Smrg */ 19847117f1b4Smrgvoid 19857117f1b4Smrg_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 19867117f1b4Smrg GLboolean color, 19877117f1b4Smrg GLboolean depth, 19887117f1b4Smrg GLboolean stencil, 19897117f1b4Smrg GLboolean accum, 19907117f1b4Smrg GLboolean alpha, 19917117f1b4Smrg GLboolean aux) 19927117f1b4Smrg{ 19937117f1b4Smrg GLboolean frontLeft = GL_TRUE; 19947117f1b4Smrg GLboolean backLeft = fb->Visual.doubleBufferMode; 19957117f1b4Smrg GLboolean frontRight = fb->Visual.stereoMode; 19967117f1b4Smrg GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 19977117f1b4Smrg 19987117f1b4Smrg if (color) { 19997117f1b4Smrg if (fb->Visual.rgbMode) { 20007117f1b4Smrg assert(fb->Visual.redBits == fb->Visual.greenBits); 20017117f1b4Smrg assert(fb->Visual.redBits == fb->Visual.blueBits); 20027117f1b4Smrg _mesa_add_color_renderbuffers(NULL, fb, 20037117f1b4Smrg fb->Visual.redBits, 20047117f1b4Smrg fb->Visual.alphaBits, 20057117f1b4Smrg frontLeft, backLeft, 20067117f1b4Smrg frontRight, backRight); 20077117f1b4Smrg } 20087117f1b4Smrg else { 20097117f1b4Smrg _mesa_add_color_index_renderbuffers(NULL, fb, 20107117f1b4Smrg fb->Visual.indexBits, 20117117f1b4Smrg frontLeft, backLeft, 20127117f1b4Smrg frontRight, backRight); 20137117f1b4Smrg } 20147117f1b4Smrg } 20157117f1b4Smrg 20167117f1b4Smrg if (depth) { 20177117f1b4Smrg assert(fb->Visual.depthBits > 0); 20187117f1b4Smrg _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 20197117f1b4Smrg } 20207117f1b4Smrg 20217117f1b4Smrg if (stencil) { 20227117f1b4Smrg assert(fb->Visual.stencilBits > 0); 20237117f1b4Smrg _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 20247117f1b4Smrg } 20257117f1b4Smrg 20267117f1b4Smrg if (accum) { 20277117f1b4Smrg assert(fb->Visual.rgbMode); 20287117f1b4Smrg assert(fb->Visual.accumRedBits > 0); 20297117f1b4Smrg assert(fb->Visual.accumGreenBits > 0); 20307117f1b4Smrg assert(fb->Visual.accumBlueBits > 0); 20317117f1b4Smrg _mesa_add_accum_renderbuffer(NULL, fb, 20327117f1b4Smrg fb->Visual.accumRedBits, 20337117f1b4Smrg fb->Visual.accumGreenBits, 20347117f1b4Smrg fb->Visual.accumBlueBits, 20357117f1b4Smrg fb->Visual.accumAlphaBits); 20367117f1b4Smrg } 20377117f1b4Smrg 20387117f1b4Smrg if (aux) { 20397117f1b4Smrg assert(fb->Visual.rgbMode); 20407117f1b4Smrg assert(fb->Visual.numAuxBuffers > 0); 20417117f1b4Smrg _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 20427117f1b4Smrg fb->Visual.numAuxBuffers); 20437117f1b4Smrg } 20447117f1b4Smrg 20457117f1b4Smrg if (alpha) { 20467117f1b4Smrg assert(fb->Visual.rgbMode); 20477117f1b4Smrg assert(fb->Visual.alphaBits > 0); 20487117f1b4Smrg _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 20497117f1b4Smrg frontLeft, backLeft, 20507117f1b4Smrg frontRight, backRight); 20517117f1b4Smrg } 20527117f1b4Smrg 20537117f1b4Smrg#if 0 20547117f1b4Smrg if (multisample) { 20557117f1b4Smrg /* maybe someday */ 20567117f1b4Smrg } 20577117f1b4Smrg#endif 20587117f1b4Smrg} 20597117f1b4Smrg 20607117f1b4Smrg 20617117f1b4Smrg/** 20627117f1b4Smrg * Attach a renderbuffer to a framebuffer. 20637117f1b4Smrg */ 20647117f1b4Smrgvoid 20657117f1b4Smrg_mesa_add_renderbuffer(struct gl_framebuffer *fb, 20667117f1b4Smrg GLuint bufferName, struct gl_renderbuffer *rb) 20677117f1b4Smrg{ 20687117f1b4Smrg assert(fb); 20697117f1b4Smrg assert(rb); 20707117f1b4Smrg assert(bufferName < BUFFER_COUNT); 20717117f1b4Smrg 20727117f1b4Smrg /* There should be no previous renderbuffer on this attachment point, 20737117f1b4Smrg * with the exception of depth/stencil since the same renderbuffer may 20747117f1b4Smrg * be used for both. 20757117f1b4Smrg */ 20767117f1b4Smrg assert(bufferName == BUFFER_DEPTH || 20777117f1b4Smrg bufferName == BUFFER_STENCIL || 20787117f1b4Smrg fb->Attachment[bufferName].Renderbuffer == NULL); 20797117f1b4Smrg 20807117f1b4Smrg /* winsys vs. user-created buffer cross check */ 20817117f1b4Smrg if (fb->Name) { 20827117f1b4Smrg assert(rb->Name); 20837117f1b4Smrg } 20847117f1b4Smrg else { 20857117f1b4Smrg assert(!rb->Name); 20867117f1b4Smrg } 20877117f1b4Smrg 20887117f1b4Smrg /* If Mesa's compiled with deep color channels (16 or 32 bits / channel) 20897117f1b4Smrg * and the device driver is expecting 8-bit values (GLubyte), we can 20907117f1b4Smrg * use a "renderbuffer adaptor/wrapper" to do the necessary conversions. 20917117f1b4Smrg */ 20927117f1b4Smrg if (rb->_BaseFormat == GL_RGBA) { 20937117f1b4Smrg if (CHAN_BITS == 16 && rb->DataType == GL_UNSIGNED_BYTE) { 20947117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 20957117f1b4Smrg rb = _mesa_new_renderbuffer_16wrap8(ctx, rb); 20967117f1b4Smrg } 20977117f1b4Smrg else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_BYTE) { 20987117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 20997117f1b4Smrg rb = _mesa_new_renderbuffer_32wrap8(ctx, rb); 21007117f1b4Smrg } 21017117f1b4Smrg else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_SHORT) { 21027117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 21037117f1b4Smrg rb = _mesa_new_renderbuffer_32wrap16(ctx, rb); 21047117f1b4Smrg } 21057117f1b4Smrg } 21067117f1b4Smrg 21077117f1b4Smrg fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 21087117f1b4Smrg fb->Attachment[bufferName].Complete = GL_TRUE; 21097117f1b4Smrg _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); 21107117f1b4Smrg} 21117117f1b4Smrg 21127117f1b4Smrg 21137117f1b4Smrg/** 21147117f1b4Smrg * Remove the named renderbuffer from the given framebuffer. 21157117f1b4Smrg */ 21167117f1b4Smrgvoid 21177117f1b4Smrg_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName) 21187117f1b4Smrg{ 21197117f1b4Smrg struct gl_renderbuffer *rb; 21207117f1b4Smrg 21217117f1b4Smrg assert(bufferName < BUFFER_COUNT); 21227117f1b4Smrg 21237117f1b4Smrg rb = fb->Attachment[bufferName].Renderbuffer; 21247117f1b4Smrg if (!rb) 21257117f1b4Smrg return; 21267117f1b4Smrg 21277117f1b4Smrg _mesa_reference_renderbuffer(&rb, NULL); 21287117f1b4Smrg 21297117f1b4Smrg fb->Attachment[bufferName].Renderbuffer = NULL; 21307117f1b4Smrg} 21317117f1b4Smrg 21327117f1b4Smrg 21337117f1b4Smrg/** 21347117f1b4Smrg * Set *ptr to point to rb. If *ptr points to another renderbuffer, 21357117f1b4Smrg * dereference that buffer first. The new renderbuffer's refcount will 21367117f1b4Smrg * be incremented. The old renderbuffer's refcount will be decremented. 21377117f1b4Smrg */ 21387117f1b4Smrgvoid 21397117f1b4Smrg_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, 21407117f1b4Smrg struct gl_renderbuffer *rb) 21417117f1b4Smrg{ 21427117f1b4Smrg assert(ptr); 21437117f1b4Smrg if (*ptr == rb) { 21447117f1b4Smrg /* no change */ 21457117f1b4Smrg return; 21467117f1b4Smrg } 21477117f1b4Smrg 21487117f1b4Smrg if (*ptr) { 21497117f1b4Smrg /* Unreference the old renderbuffer */ 21507117f1b4Smrg GLboolean deleteFlag = GL_FALSE; 21517117f1b4Smrg struct gl_renderbuffer *oldRb = *ptr; 21527117f1b4Smrg 21537117f1b4Smrg assert(oldRb->Magic == RB_MAGIC); 21547117f1b4Smrg _glthread_LOCK_MUTEX(oldRb->Mutex); 21557117f1b4Smrg assert(oldRb->Magic == RB_MAGIC); 21567117f1b4Smrg ASSERT(oldRb->RefCount > 0); 21577117f1b4Smrg oldRb->RefCount--; 21587117f1b4Smrg /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/ 21597117f1b4Smrg deleteFlag = (oldRb->RefCount == 0); 21607117f1b4Smrg _glthread_UNLOCK_MUTEX(oldRb->Mutex); 21617117f1b4Smrg 21627117f1b4Smrg if (deleteFlag) { 21637117f1b4Smrg oldRb->Magic = 0; /* now invalid memory! */ 21647117f1b4Smrg oldRb->Delete(oldRb); 21657117f1b4Smrg } 21667117f1b4Smrg 21677117f1b4Smrg *ptr = NULL; 21687117f1b4Smrg } 21697117f1b4Smrg assert(!*ptr); 21707117f1b4Smrg 21717117f1b4Smrg if (rb) { 21727117f1b4Smrg assert(rb->Magic == RB_MAGIC); 21737117f1b4Smrg /* reference new renderbuffer */ 21747117f1b4Smrg _glthread_LOCK_MUTEX(rb->Mutex); 21757117f1b4Smrg rb->RefCount++; 21767117f1b4Smrg /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/ 21777117f1b4Smrg _glthread_UNLOCK_MUTEX(rb->Mutex); 21787117f1b4Smrg *ptr = rb; 21797117f1b4Smrg } 21807117f1b4Smrg} 21817117f1b4Smrg 21827117f1b4Smrg 21837117f1b4Smrg/** 21847117f1b4Smrg * Create a new combined depth/stencil renderbuffer for implementing 21857117f1b4Smrg * the GL_EXT_packed_depth_stencil extension. 21867117f1b4Smrg * \return new depth/stencil renderbuffer 21877117f1b4Smrg */ 21887117f1b4Smrgstruct gl_renderbuffer * 21897117f1b4Smrg_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name) 21907117f1b4Smrg{ 21917117f1b4Smrg struct gl_renderbuffer *dsrb; 21927117f1b4Smrg 21937117f1b4Smrg dsrb = _mesa_new_renderbuffer(ctx, name); 21947117f1b4Smrg if (!dsrb) 21957117f1b4Smrg return NULL; 21967117f1b4Smrg 21977117f1b4Smrg /* init fields not covered by _mesa_new_renderbuffer() */ 21987117f1b4Smrg dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT; 21997117f1b4Smrg dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; 22007117f1b4Smrg dsrb->AllocStorage = _mesa_soft_renderbuffer_storage; 22017117f1b4Smrg 22027117f1b4Smrg return dsrb; 22037117f1b4Smrg} 2204