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