renderbuffer.c revision 3464ebd5
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 "renderbuffer.h" 507117f1b4Smrg 517117f1b4Smrg 527117f1b4Smrg/* 537117f1b4Smrg * Routines for get/put values in common buffer formats follow. 547117f1b4Smrg */ 557117f1b4Smrg 563464ebd5Sriastradh/* Returns a bytes per pixel of the DataType in the get/put span 573464ebd5Sriastradh * functions for at least a subset of the available combinations a 583464ebd5Sriastradh * renderbuffer can have. 593464ebd5Sriastradh * 603464ebd5Sriastradh * It would be nice to see gl_renderbuffer start talking about a 613464ebd5Sriastradh * gl_format instead of a GLenum DataType. 627117f1b4Smrg */ 633464ebd5Sriastradhstatic int 643464ebd5Sriastradhget_datatype_bytes(struct gl_renderbuffer *rb) 653464ebd5Sriastradh{ 663464ebd5Sriastradh int component_size; 677117f1b4Smrg 683464ebd5Sriastradh switch (rb->DataType) { 693464ebd5Sriastradh case GL_FLOAT: 703464ebd5Sriastradh case GL_UNSIGNED_INT: 713464ebd5Sriastradh case GL_UNSIGNED_INT_24_8_EXT: 723464ebd5Sriastradh component_size = 4; 733464ebd5Sriastradh break; 743464ebd5Sriastradh case GL_UNSIGNED_SHORT: 753464ebd5Sriastradh component_size = 2; 763464ebd5Sriastradh break; 773464ebd5Sriastradh case GL_UNSIGNED_BYTE: 783464ebd5Sriastradh component_size = 1; 793464ebd5Sriastradh break; 803464ebd5Sriastradh default: 813464ebd5Sriastradh component_size = 1; 823464ebd5Sriastradh assert(0); 833464ebd5Sriastradh } 843464ebd5Sriastradh 853464ebd5Sriastradh switch (rb->_BaseFormat) { 863464ebd5Sriastradh case GL_DEPTH_COMPONENT: 873464ebd5Sriastradh case GL_DEPTH_STENCIL: 883464ebd5Sriastradh return component_size; 893464ebd5Sriastradh default: 903464ebd5Sriastradh return 4 * component_size; 913464ebd5Sriastradh } 923464ebd5Sriastradh} 933464ebd5Sriastradh 943464ebd5Sriastradh/* This is commonly used by most of the accessors. */ 957117f1b4Smrgstatic void * 963464ebd5Sriastradhget_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 973464ebd5Sriastradh GLint x, GLint y) 987117f1b4Smrg{ 997117f1b4Smrg if (!rb->Data) 1007117f1b4Smrg return NULL; 1013464ebd5Sriastradh 1023464ebd5Sriastradh return ((char *) rb->Data + 1033464ebd5Sriastradh (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format)); 1047117f1b4Smrg} 1057117f1b4Smrg 1063464ebd5Sriastradh/* GetRow() implementation for formats where DataType matches the rb->Format. 1073464ebd5Sriastradh */ 1083464ebd5Sriastradhstatic void 1093464ebd5Sriastradhget_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 1103464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 1113464ebd5Sriastradh{ 1123464ebd5Sriastradh void *src = rb->GetPointer(ctx, rb, x, y); 1133464ebd5Sriastradh memcpy(values, src, count * _mesa_get_format_bytes(rb->Format)); 1143464ebd5Sriastradh} 1157117f1b4Smrg 1163464ebd5Sriastradh/* Only used for float textures currently, but might also be used for 1173464ebd5Sriastradh * RGBA8888, RGBA16, etc. 1183464ebd5Sriastradh */ 1197117f1b4Smrgstatic void 1203464ebd5Sriastradhget_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 1213464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], void *values) 1227117f1b4Smrg{ 1233464ebd5Sriastradh int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 1243464ebd5Sriastradh GLuint i; 1253464ebd5Sriastradh 1263464ebd5Sriastradh for (i = 0; i < count; i++) { 1273464ebd5Sriastradh const void *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1283464ebd5Sriastradh char *dst = (char *) values + i * format_bytes; 1293464ebd5Sriastradh memcpy(dst, src, format_bytes); 1303464ebd5Sriastradh } 1313464ebd5Sriastradh} 1323464ebd5Sriastradh 1333464ebd5Sriastradh/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and 1343464ebd5Sriastradh * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of 1353464ebd5Sriastradh * storing those initial components of the value per pixel into the 1363464ebd5Sriastradh * destination. 1373464ebd5Sriastradh */ 1383464ebd5Sriastradhstatic void 1393464ebd5Sriastradhput_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 1403464ebd5Sriastradh GLuint count, GLint x, GLint y, 1413464ebd5Sriastradh const void *values, const GLubyte *mask) 1423464ebd5Sriastradh{ 1433464ebd5Sriastradh void *row = rb->GetPointer(ctx, rb, x, y); 1443464ebd5Sriastradh int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 1453464ebd5Sriastradh int datatype_bytes = get_datatype_bytes(rb); 1463464ebd5Sriastradh unsigned int i; 1473464ebd5Sriastradh 1483464ebd5Sriastradh if (mask) { 1493464ebd5Sriastradh for (i = 0; i < count; i++) { 1503464ebd5Sriastradh char *dst = (char *) row + i * format_bytes; 1513464ebd5Sriastradh const char *src = (const char *) values + i * datatype_bytes; 1523464ebd5Sriastradh 1533464ebd5Sriastradh if (mask[i]) { 1543464ebd5Sriastradh memcpy(dst, src, format_bytes); 1553464ebd5Sriastradh } 1563464ebd5Sriastradh } 1573464ebd5Sriastradh } 1583464ebd5Sriastradh else { 1593464ebd5Sriastradh for (i = 0; i < count; i++) { 1603464ebd5Sriastradh char *dst = (char *) row + i * format_bytes; 1613464ebd5Sriastradh const char *src = (const char *) values + i * datatype_bytes; 1623464ebd5Sriastradh memcpy(dst, src, format_bytes); 1633464ebd5Sriastradh } 1643464ebd5Sriastradh } 1653464ebd5Sriastradh} 1663464ebd5Sriastradh 1673464ebd5Sriastradhstatic void 1683464ebd5Sriastradhput_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 1693464ebd5Sriastradh GLuint count, GLint x, GLint y, 1703464ebd5Sriastradh const void *value, const GLubyte *mask) 1713464ebd5Sriastradh{ 1723464ebd5Sriastradh void *row = rb->GetPointer(ctx, rb, x, y); 1733464ebd5Sriastradh int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 1743464ebd5Sriastradh unsigned int i; 1753464ebd5Sriastradh 1763464ebd5Sriastradh if (mask) { 1773464ebd5Sriastradh for (i = 0; i < count; i++) { 1783464ebd5Sriastradh char *dst = (char *) row + i * format_bytes; 1793464ebd5Sriastradh if (mask[i]) { 1803464ebd5Sriastradh memcpy(dst, value, format_bytes); 1813464ebd5Sriastradh } 1823464ebd5Sriastradh } 1833464ebd5Sriastradh } 1843464ebd5Sriastradh else { 1853464ebd5Sriastradh for (i = 0; i < count; i++) { 1863464ebd5Sriastradh char *dst = (char *) row + i * format_bytes; 1873464ebd5Sriastradh memcpy(dst, value, format_bytes); 1883464ebd5Sriastradh } 1893464ebd5Sriastradh } 1907117f1b4Smrg} 1917117f1b4Smrg 1927117f1b4Smrg 1937117f1b4Smrgstatic void 1943464ebd5Sriastradhput_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 1953464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 1963464ebd5Sriastradh const void *values, const GLubyte *mask) 1973464ebd5Sriastradh{ 1983464ebd5Sriastradh int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 1993464ebd5Sriastradh int datatype_bytes = get_datatype_bytes(rb); 2003464ebd5Sriastradh unsigned int i; 2013464ebd5Sriastradh 2023464ebd5Sriastradh for (i = 0; i < count; i++) { 2033464ebd5Sriastradh if (!mask || mask[i]) { 2043464ebd5Sriastradh void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 2053464ebd5Sriastradh const char *src = (const char *) values + i * datatype_bytes; 2063464ebd5Sriastradh memcpy(dst, src, format_bytes); 2073464ebd5Sriastradh } 2083464ebd5Sriastradh } 2093464ebd5Sriastradh} 2103464ebd5Sriastradh 2113464ebd5Sriastradh 2123464ebd5Sriastradhstatic void 2133464ebd5Sriastradhput_mono_values_generic(struct gl_context *ctx, 2143464ebd5Sriastradh struct gl_renderbuffer *rb, 2153464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 2163464ebd5Sriastradh const void *value, const GLubyte *mask) 2173464ebd5Sriastradh{ 2183464ebd5Sriastradh int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 2193464ebd5Sriastradh unsigned int i; 2203464ebd5Sriastradh 2213464ebd5Sriastradh for (i = 0; i < count; i++) { 2223464ebd5Sriastradh if (!mask || mask[i]) { 2233464ebd5Sriastradh void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 2243464ebd5Sriastradh memcpy(dst, value, format_bytes); 2253464ebd5Sriastradh } 2263464ebd5Sriastradh } 2273464ebd5Sriastradh} 2283464ebd5Sriastradh 2293464ebd5Sriastradh/********************************************************************** 2303464ebd5Sriastradh * Functions for buffers of 1 X GLubyte values. 2313464ebd5Sriastradh * Typically stencil. 2323464ebd5Sriastradh */ 2333464ebd5Sriastradh 2343464ebd5Sriastradhstatic void 2353464ebd5Sriastradhget_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 2367117f1b4Smrg const GLint x[], const GLint y[], void *values) 2377117f1b4Smrg{ 2387117f1b4Smrg GLubyte *dst = (GLubyte *) values; 2397117f1b4Smrg GLuint i; 2407117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 2417117f1b4Smrg for (i = 0; i < count; i++) { 2423464ebd5Sriastradh const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 2437117f1b4Smrg dst[i] = *src; 2447117f1b4Smrg } 2457117f1b4Smrg} 2467117f1b4Smrg 2477117f1b4Smrg 2487117f1b4Smrgstatic void 2493464ebd5Sriastradhput_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 2507117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 2517117f1b4Smrg{ 2527117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 2533464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 2547117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 2557117f1b4Smrg if (mask) { 2567117f1b4Smrg GLuint i; 2577117f1b4Smrg for (i = 0; i < count; i++) { 2587117f1b4Smrg if (mask[i]) { 2597117f1b4Smrg dst[i] = src[i]; 2607117f1b4Smrg } 2617117f1b4Smrg } 2627117f1b4Smrg } 2637117f1b4Smrg else { 264cdc920a0Smrg memcpy(dst, values, count * sizeof(GLubyte)); 2657117f1b4Smrg } 2667117f1b4Smrg} 2677117f1b4Smrg 2687117f1b4Smrg 2697117f1b4Smrgstatic void 2703464ebd5Sriastradhput_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 2717117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 2727117f1b4Smrg{ 2737117f1b4Smrg const GLubyte val = *((const GLubyte *) value); 2743464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 2757117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 2767117f1b4Smrg if (mask) { 2777117f1b4Smrg GLuint i; 2787117f1b4Smrg for (i = 0; i < count; i++) { 2797117f1b4Smrg if (mask[i]) { 2807117f1b4Smrg dst[i] = val; 2817117f1b4Smrg } 2827117f1b4Smrg } 2837117f1b4Smrg } 2847117f1b4Smrg else { 2857117f1b4Smrg GLuint i; 2867117f1b4Smrg for (i = 0; i < count; i++) { 2877117f1b4Smrg dst[i] = val; 2887117f1b4Smrg } 2897117f1b4Smrg } 2907117f1b4Smrg} 2917117f1b4Smrg 2927117f1b4Smrg 2937117f1b4Smrgstatic void 2943464ebd5Sriastradhput_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 2957117f1b4Smrg const GLint x[], const GLint y[], 2967117f1b4Smrg const void *values, const GLubyte *mask) 2977117f1b4Smrg{ 2987117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 2997117f1b4Smrg GLuint i; 3007117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 3017117f1b4Smrg for (i = 0; i < count; i++) { 3027117f1b4Smrg if (!mask || mask[i]) { 3033464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 3047117f1b4Smrg *dst = src[i]; 3057117f1b4Smrg } 3067117f1b4Smrg } 3077117f1b4Smrg} 3087117f1b4Smrg 3097117f1b4Smrg 3107117f1b4Smrgstatic void 3113464ebd5Sriastradhput_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 3127117f1b4Smrg const GLint x[], const GLint y[], 3137117f1b4Smrg const void *value, const GLubyte *mask) 3147117f1b4Smrg{ 3157117f1b4Smrg const GLubyte val = *((const GLubyte *) value); 3167117f1b4Smrg GLuint i; 3177117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 3187117f1b4Smrg for (i = 0; i < count; i++) { 3197117f1b4Smrg if (!mask || mask[i]) { 3203464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 3217117f1b4Smrg *dst = val; 3227117f1b4Smrg } 3237117f1b4Smrg } 3247117f1b4Smrg} 3257117f1b4Smrg 3267117f1b4Smrg 3277117f1b4Smrg/********************************************************************** 3287117f1b4Smrg * Functions for buffers of 1 X GLushort values. 3297117f1b4Smrg * Typically depth/Z. 3307117f1b4Smrg */ 3317117f1b4Smrg 3327117f1b4Smrgstatic void 3333464ebd5Sriastradhget_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 3347117f1b4Smrg const GLint x[], const GLint y[], void *values) 3357117f1b4Smrg{ 3367117f1b4Smrg GLushort *dst = (GLushort *) values; 3377117f1b4Smrg GLuint i; 3387117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 3397117f1b4Smrg for (i = 0; i < count; i++) { 3403464ebd5Sriastradh const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 3417117f1b4Smrg dst[i] = *src; 3427117f1b4Smrg } 3437117f1b4Smrg} 3447117f1b4Smrg 3457117f1b4Smrg 3467117f1b4Smrgstatic void 3473464ebd5Sriastradhput_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 3487117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 3497117f1b4Smrg{ 3507117f1b4Smrg const GLushort *src = (const GLushort *) values; 3513464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 3527117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 3537117f1b4Smrg if (mask) { 3547117f1b4Smrg GLuint i; 3557117f1b4Smrg for (i = 0; i < count; i++) { 3567117f1b4Smrg if (mask[i]) { 3577117f1b4Smrg dst[i] = src[i]; 3587117f1b4Smrg } 3597117f1b4Smrg } 3607117f1b4Smrg } 3617117f1b4Smrg else { 362cdc920a0Smrg memcpy(dst, src, count * sizeof(GLushort)); 3637117f1b4Smrg } 3647117f1b4Smrg} 3657117f1b4Smrg 3667117f1b4Smrg 3677117f1b4Smrgstatic void 3683464ebd5Sriastradhput_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 3697117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 3707117f1b4Smrg{ 3717117f1b4Smrg const GLushort val = *((const GLushort *) value); 3723464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 3737117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 3747117f1b4Smrg if (mask) { 3757117f1b4Smrg GLuint i; 3767117f1b4Smrg for (i = 0; i < count; i++) { 3777117f1b4Smrg if (mask[i]) { 3787117f1b4Smrg dst[i] = val; 3797117f1b4Smrg } 3807117f1b4Smrg } 3817117f1b4Smrg } 3827117f1b4Smrg else { 3837117f1b4Smrg GLuint i; 3847117f1b4Smrg for (i = 0; i < count; i++) { 3857117f1b4Smrg dst[i] = val; 3867117f1b4Smrg } 3877117f1b4Smrg } 3887117f1b4Smrg} 3897117f1b4Smrg 3907117f1b4Smrg 3917117f1b4Smrgstatic void 3923464ebd5Sriastradhput_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 3937117f1b4Smrg const GLint x[], const GLint y[], const void *values, 3947117f1b4Smrg const GLubyte *mask) 3957117f1b4Smrg{ 3967117f1b4Smrg const GLushort *src = (const GLushort *) values; 3977117f1b4Smrg GLuint i; 3987117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 3997117f1b4Smrg for (i = 0; i < count; i++) { 4007117f1b4Smrg if (!mask || mask[i]) { 4013464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 4027117f1b4Smrg *dst = src[i]; 4037117f1b4Smrg } 4047117f1b4Smrg } 4057117f1b4Smrg} 4067117f1b4Smrg 4077117f1b4Smrg 4087117f1b4Smrgstatic void 4093464ebd5Sriastradhput_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, 4107117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 4117117f1b4Smrg const void *value, const GLubyte *mask) 4127117f1b4Smrg{ 4137117f1b4Smrg const GLushort val = *((const GLushort *) value); 4147117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 4157117f1b4Smrg if (mask) { 4167117f1b4Smrg GLuint i; 4177117f1b4Smrg for (i = 0; i < count; i++) { 4187117f1b4Smrg if (mask[i]) { 4193464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 4207117f1b4Smrg *dst = val; 4217117f1b4Smrg } 4227117f1b4Smrg } 4237117f1b4Smrg } 4247117f1b4Smrg else { 4257117f1b4Smrg GLuint i; 4267117f1b4Smrg for (i = 0; i < count; i++) { 4273464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 4287117f1b4Smrg *dst = val; 4297117f1b4Smrg } 4307117f1b4Smrg } 4317117f1b4Smrg} 4327117f1b4Smrg 4337117f1b4Smrg 4347117f1b4Smrg/********************************************************************** 4357117f1b4Smrg * Functions for buffers of 1 X GLuint values. 4367117f1b4Smrg * Typically depth/Z or color index. 4377117f1b4Smrg */ 4387117f1b4Smrg 4397117f1b4Smrgstatic void 4403464ebd5Sriastradhget_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 4417117f1b4Smrg const GLint x[], const GLint y[], void *values) 4427117f1b4Smrg{ 4437117f1b4Smrg GLuint *dst = (GLuint *) values; 4447117f1b4Smrg GLuint i; 4457117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 4467117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 4477117f1b4Smrg for (i = 0; i < count; i++) { 4483464ebd5Sriastradh const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 4497117f1b4Smrg dst[i] = *src; 4507117f1b4Smrg } 4517117f1b4Smrg} 4527117f1b4Smrg 4537117f1b4Smrg 4547117f1b4Smrgstatic void 4553464ebd5Sriastradhput_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 4567117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 4577117f1b4Smrg{ 4587117f1b4Smrg const GLuint *src = (const GLuint *) values; 4593464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 4607117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 4617117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 4627117f1b4Smrg if (mask) { 4637117f1b4Smrg GLuint i; 4647117f1b4Smrg for (i = 0; i < count; i++) { 4657117f1b4Smrg if (mask[i]) { 4667117f1b4Smrg dst[i] = src[i]; 4677117f1b4Smrg } 4687117f1b4Smrg } 4697117f1b4Smrg } 4707117f1b4Smrg else { 471cdc920a0Smrg memcpy(dst, src, count * sizeof(GLuint)); 4727117f1b4Smrg } 4737117f1b4Smrg} 4747117f1b4Smrg 4757117f1b4Smrg 4767117f1b4Smrgstatic void 4773464ebd5Sriastradhput_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 4787117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 4797117f1b4Smrg{ 4807117f1b4Smrg const GLuint val = *((const GLuint *) value); 4813464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 4827117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 4837117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 4847117f1b4Smrg if (mask) { 4857117f1b4Smrg GLuint i; 4867117f1b4Smrg for (i = 0; i < count; i++) { 4877117f1b4Smrg if (mask[i]) { 4887117f1b4Smrg dst[i] = val; 4897117f1b4Smrg } 4907117f1b4Smrg } 4917117f1b4Smrg } 4927117f1b4Smrg else { 4937117f1b4Smrg GLuint i; 4947117f1b4Smrg for (i = 0; i < count; i++) { 4957117f1b4Smrg dst[i] = val; 4967117f1b4Smrg } 4977117f1b4Smrg } 4987117f1b4Smrg} 4997117f1b4Smrg 5007117f1b4Smrg 5017117f1b4Smrgstatic void 5023464ebd5Sriastradhput_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 5037117f1b4Smrg const GLint x[], const GLint y[], const void *values, 5047117f1b4Smrg const GLubyte *mask) 5057117f1b4Smrg{ 5067117f1b4Smrg const GLuint *src = (const GLuint *) values; 5077117f1b4Smrg GLuint i; 5087117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 5097117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 5107117f1b4Smrg for (i = 0; i < count; i++) { 5117117f1b4Smrg if (!mask || mask[i]) { 5123464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 5137117f1b4Smrg *dst = src[i]; 5147117f1b4Smrg } 5157117f1b4Smrg } 5167117f1b4Smrg} 5177117f1b4Smrg 5187117f1b4Smrg 5197117f1b4Smrgstatic void 5203464ebd5Sriastradhput_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 5217117f1b4Smrg const GLint x[], const GLint y[], const void *value, 5227117f1b4Smrg const GLubyte *mask) 5237117f1b4Smrg{ 5247117f1b4Smrg const GLuint val = *((const GLuint *) value); 5257117f1b4Smrg GLuint i; 5267117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_INT || 5277117f1b4Smrg rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 5287117f1b4Smrg for (i = 0; i < count; i++) { 5297117f1b4Smrg if (!mask || mask[i]) { 5303464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 5317117f1b4Smrg *dst = val; 5327117f1b4Smrg } 5337117f1b4Smrg } 5347117f1b4Smrg} 5357117f1b4Smrg 5367117f1b4Smrg 5377117f1b4Smrg/********************************************************************** 5387117f1b4Smrg * Functions for buffers of 3 X GLubyte (or GLbyte) values. 5397117f1b4Smrg * Typically color buffers. 5407117f1b4Smrg * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 5417117f1b4Smrg * alpha values and return 255 for outgoing alpha values. 5427117f1b4Smrg */ 5437117f1b4Smrg 5447117f1b4Smrgstatic void * 5453464ebd5Sriastradhget_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 5467117f1b4Smrg GLint x, GLint y) 5477117f1b4Smrg{ 5484a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 5497117f1b4Smrg /* No direct access since this buffer is RGB but caller will be 5507117f1b4Smrg * treating it as if it were RGBA. 5517117f1b4Smrg */ 5527117f1b4Smrg return NULL; 5537117f1b4Smrg} 5547117f1b4Smrg 5557117f1b4Smrg 5567117f1b4Smrgstatic void 5573464ebd5Sriastradhget_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 5587117f1b4Smrg GLint x, GLint y, void *values) 5597117f1b4Smrg{ 5603464ebd5Sriastradh const GLubyte *src = ((const GLubyte *) rb->Data) + 5613464ebd5Sriastradh 3 * (y * rb->RowStride + x); 5627117f1b4Smrg GLubyte *dst = (GLubyte *) values; 5637117f1b4Smrg GLuint i; 5644a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 5657117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5667117f1b4Smrg for (i = 0; i < count; i++) { 5677117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 5687117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 5697117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 5707117f1b4Smrg dst[i * 4 + 3] = 255; 5717117f1b4Smrg } 5727117f1b4Smrg} 5737117f1b4Smrg 5747117f1b4Smrg 5757117f1b4Smrgstatic void 5763464ebd5Sriastradhget_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 5777117f1b4Smrg const GLint x[], const GLint y[], void *values) 5787117f1b4Smrg{ 5797117f1b4Smrg GLubyte *dst = (GLubyte *) values; 5807117f1b4Smrg GLuint i; 5814a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 5827117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 5837117f1b4Smrg for (i = 0; i < count; i++) { 5847117f1b4Smrg const GLubyte *src 5853464ebd5Sriastradh = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 5867117f1b4Smrg dst[i * 4 + 0] = src[0]; 5877117f1b4Smrg dst[i * 4 + 1] = src[1]; 5887117f1b4Smrg dst[i * 4 + 2] = src[2]; 5897117f1b4Smrg dst[i * 4 + 3] = 255; 5907117f1b4Smrg } 5917117f1b4Smrg} 5927117f1b4Smrg 5937117f1b4Smrg 5947117f1b4Smrgstatic void 5953464ebd5Sriastradhput_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 5967117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 5977117f1b4Smrg{ 5987117f1b4Smrg /* note: incoming values are RGB+A! */ 5997117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 6003464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 6017117f1b4Smrg GLuint i; 6024a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 6037117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6047117f1b4Smrg for (i = 0; i < count; i++) { 6057117f1b4Smrg if (!mask || mask[i]) { 6067117f1b4Smrg dst[i * 3 + 0] = src[i * 4 + 0]; 6077117f1b4Smrg dst[i * 3 + 1] = src[i * 4 + 1]; 6087117f1b4Smrg dst[i * 3 + 2] = src[i * 4 + 2]; 6097117f1b4Smrg } 6107117f1b4Smrg } 6117117f1b4Smrg} 6127117f1b4Smrg 6137117f1b4Smrg 6147117f1b4Smrgstatic void 6153464ebd5Sriastradhput_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 6167117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 6177117f1b4Smrg{ 6187117f1b4Smrg /* note: incoming values are RGB+A! */ 6197117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 6203464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 6217117f1b4Smrg GLuint i; 6224a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 6237117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6247117f1b4Smrg for (i = 0; i < count; i++) { 6257117f1b4Smrg if (!mask || mask[i]) { 6267117f1b4Smrg dst[i * 3 + 0] = src[i * 3 + 0]; 6277117f1b4Smrg dst[i * 3 + 1] = src[i * 3 + 1]; 6287117f1b4Smrg dst[i * 3 + 2] = src[i * 3 + 2]; 6297117f1b4Smrg } 6307117f1b4Smrg } 6317117f1b4Smrg} 6327117f1b4Smrg 6337117f1b4Smrg 6347117f1b4Smrgstatic void 6353464ebd5Sriastradhput_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 6367117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 6377117f1b4Smrg{ 6387117f1b4Smrg /* note: incoming value is RGB+A! */ 6397117f1b4Smrg const GLubyte val0 = ((const GLubyte *) value)[0]; 6407117f1b4Smrg const GLubyte val1 = ((const GLubyte *) value)[1]; 6417117f1b4Smrg const GLubyte val2 = ((const GLubyte *) value)[2]; 6423464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 6434a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 6447117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6457117f1b4Smrg if (!mask && val0 == val1 && val1 == val2) { 6467117f1b4Smrg /* optimized case */ 647cdc920a0Smrg memset(dst, val0, 3 * count); 6487117f1b4Smrg } 6497117f1b4Smrg else { 6507117f1b4Smrg GLuint i; 6517117f1b4Smrg for (i = 0; i < count; i++) { 6527117f1b4Smrg if (!mask || mask[i]) { 6537117f1b4Smrg dst[i * 3 + 0] = val0; 6547117f1b4Smrg dst[i * 3 + 1] = val1; 6557117f1b4Smrg dst[i * 3 + 2] = val2; 6567117f1b4Smrg } 6577117f1b4Smrg } 6587117f1b4Smrg } 6597117f1b4Smrg} 6607117f1b4Smrg 6617117f1b4Smrg 6627117f1b4Smrgstatic void 6633464ebd5Sriastradhput_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 6647117f1b4Smrg const GLint x[], const GLint y[], const void *values, 6657117f1b4Smrg const GLubyte *mask) 6667117f1b4Smrg{ 6677117f1b4Smrg /* note: incoming values are RGB+A! */ 6687117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 6697117f1b4Smrg GLuint i; 6704a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 6717117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6727117f1b4Smrg for (i = 0; i < count; i++) { 6737117f1b4Smrg if (!mask || mask[i]) { 6743464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 6757117f1b4Smrg dst[0] = src[i * 4 + 0]; 6767117f1b4Smrg dst[1] = src[i * 4 + 1]; 6777117f1b4Smrg dst[2] = src[i * 4 + 2]; 6787117f1b4Smrg } 6797117f1b4Smrg } 6807117f1b4Smrg} 6817117f1b4Smrg 6827117f1b4Smrg 6837117f1b4Smrgstatic void 6843464ebd5Sriastradhput_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 6857117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 6867117f1b4Smrg const void *value, const GLubyte *mask) 6877117f1b4Smrg{ 6887117f1b4Smrg /* note: incoming value is RGB+A! */ 6897117f1b4Smrg const GLubyte val0 = ((const GLubyte *) value)[0]; 6907117f1b4Smrg const GLubyte val1 = ((const GLubyte *) value)[1]; 6917117f1b4Smrg const GLubyte val2 = ((const GLubyte *) value)[2]; 6927117f1b4Smrg GLuint i; 6934a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGB888); 6947117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 6957117f1b4Smrg for (i = 0; i < count; i++) { 6967117f1b4Smrg if (!mask || mask[i]) { 6973464ebd5Sriastradh GLubyte *dst = ((GLubyte *) rb->Data) + 6983464ebd5Sriastradh 3 * (y[i] * rb->RowStride + x[i]); 6997117f1b4Smrg dst[0] = val0; 7007117f1b4Smrg dst[1] = val1; 7017117f1b4Smrg dst[2] = val2; 7027117f1b4Smrg } 7037117f1b4Smrg } 7047117f1b4Smrg} 7057117f1b4Smrg 7067117f1b4Smrg 7077117f1b4Smrg/********************************************************************** 7087117f1b4Smrg * Functions for buffers of 4 X GLubyte (or GLbyte) values. 7097117f1b4Smrg * Typically color buffers. 7107117f1b4Smrg */ 7117117f1b4Smrg 7127117f1b4Smrgstatic void 7133464ebd5Sriastradhget_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 7147117f1b4Smrg const GLint x[], const GLint y[], void *values) 7157117f1b4Smrg{ 7167117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7177117f1b4Smrg GLuint *dst = (GLuint *) values; 7187117f1b4Smrg GLuint i; 7197117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7204a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 7217117f1b4Smrg for (i = 0; i < count; i++) { 7223464ebd5Sriastradh const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 7237117f1b4Smrg dst[i] = *src; 7247117f1b4Smrg } 7257117f1b4Smrg} 7267117f1b4Smrg 7277117f1b4Smrg 7287117f1b4Smrgstatic void 7293464ebd5Sriastradhput_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 7307117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 7317117f1b4Smrg{ 7327117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7337117f1b4Smrg const GLuint *src = (const GLuint *) values; 7343464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 7357117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7364a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 7377117f1b4Smrg if (mask) { 7387117f1b4Smrg GLuint i; 7397117f1b4Smrg for (i = 0; i < count; i++) { 7407117f1b4Smrg if (mask[i]) { 7417117f1b4Smrg dst[i] = src[i]; 7427117f1b4Smrg } 7437117f1b4Smrg } 7447117f1b4Smrg } 7457117f1b4Smrg else { 746cdc920a0Smrg memcpy(dst, src, 4 * count * sizeof(GLubyte)); 7477117f1b4Smrg } 7487117f1b4Smrg} 7497117f1b4Smrg 7507117f1b4Smrg 7517117f1b4Smrgstatic void 7523464ebd5Sriastradhput_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 7537117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 7547117f1b4Smrg{ 7557117f1b4Smrg /* Store RGB values in RGBA buffer */ 7567117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 7573464ebd5Sriastradh GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); 7587117f1b4Smrg GLuint i; 7597117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7604a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 7617117f1b4Smrg for (i = 0; i < count; i++) { 7627117f1b4Smrg if (!mask || mask[i]) { 7637117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 7647117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 7657117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 7667117f1b4Smrg dst[i * 4 + 3] = 0xff; 7677117f1b4Smrg } 7687117f1b4Smrg } 7697117f1b4Smrg} 7707117f1b4Smrg 7717117f1b4Smrg 7727117f1b4Smrgstatic void 7733464ebd5Sriastradhput_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 7747117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 7757117f1b4Smrg{ 7767117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 7777117f1b4Smrg const GLuint val = *((const GLuint *) value); 7783464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 7797117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 7804a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 7817117f1b4Smrg if (!mask && val == 0) { 7827117f1b4Smrg /* common case */ 783cdc920a0Smrg memset(dst, 0, count * 4 * sizeof(GLubyte)); 7847117f1b4Smrg } 7857117f1b4Smrg else { 7867117f1b4Smrg /* general case */ 7877117f1b4Smrg if (mask) { 7887117f1b4Smrg GLuint i; 7897117f1b4Smrg for (i = 0; i < count; i++) { 7907117f1b4Smrg if (mask[i]) { 7917117f1b4Smrg dst[i] = val; 7927117f1b4Smrg } 7937117f1b4Smrg } 7947117f1b4Smrg } 7957117f1b4Smrg else { 7967117f1b4Smrg GLuint i; 7977117f1b4Smrg for (i = 0; i < count; i++) { 7987117f1b4Smrg dst[i] = val; 7997117f1b4Smrg } 8007117f1b4Smrg } 8017117f1b4Smrg } 8027117f1b4Smrg} 8037117f1b4Smrg 8047117f1b4Smrg 8057117f1b4Smrgstatic void 8063464ebd5Sriastradhput_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 8077117f1b4Smrg const GLint x[], const GLint y[], const void *values, 8087117f1b4Smrg const GLubyte *mask) 8097117f1b4Smrg{ 8107117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 8117117f1b4Smrg const GLuint *src = (const GLuint *) values; 8127117f1b4Smrg GLuint i; 8137117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 8144a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 8157117f1b4Smrg for (i = 0; i < count; i++) { 8167117f1b4Smrg if (!mask || mask[i]) { 8173464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 8187117f1b4Smrg *dst = src[i]; 8197117f1b4Smrg } 8207117f1b4Smrg } 8217117f1b4Smrg} 8227117f1b4Smrg 8237117f1b4Smrg 8247117f1b4Smrgstatic void 8253464ebd5Sriastradhput_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, 8267117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 8277117f1b4Smrg const void *value, const GLubyte *mask) 8287117f1b4Smrg{ 8297117f1b4Smrg /* treat 4*GLubyte as 1*GLuint */ 8307117f1b4Smrg const GLuint val = *((const GLuint *) value); 8317117f1b4Smrg GLuint i; 8327117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 8334a49301eSmrg ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 8347117f1b4Smrg for (i = 0; i < count; i++) { 8357117f1b4Smrg if (!mask || mask[i]) { 8363464ebd5Sriastradh GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 8377117f1b4Smrg *dst = val; 8387117f1b4Smrg } 8397117f1b4Smrg } 8407117f1b4Smrg} 8417117f1b4Smrg 8427117f1b4Smrg 8437117f1b4Smrg/********************************************************************** 8447117f1b4Smrg * Functions for buffers of 4 X GLushort (or GLshort) values. 8457117f1b4Smrg * Typically accum buffer. 8467117f1b4Smrg */ 8477117f1b4Smrg 8487117f1b4Smrgstatic void 8493464ebd5Sriastradhget_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 8507117f1b4Smrg const GLint x[], const GLint y[], void *values) 8517117f1b4Smrg{ 8527117f1b4Smrg GLushort *dst = (GLushort *) values; 8537117f1b4Smrg GLuint i; 8547117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8557117f1b4Smrg for (i = 0; i < count; i++) { 8567117f1b4Smrg const GLushort *src 8573464ebd5Sriastradh = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); 8587117f1b4Smrg dst[i] = *src; 8597117f1b4Smrg } 8607117f1b4Smrg} 8617117f1b4Smrg 8627117f1b4Smrg 8637117f1b4Smrgstatic void 8643464ebd5Sriastradhput_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 8657117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 8667117f1b4Smrg{ 8677117f1b4Smrg const GLushort *src = (const GLushort *) values; 8683464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 8697117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8707117f1b4Smrg if (mask) { 8717117f1b4Smrg GLuint i; 8727117f1b4Smrg for (i = 0; i < count; i++) { 8737117f1b4Smrg if (mask[i]) { 8747117f1b4Smrg dst[i * 4 + 0] = src[i * 4 + 0]; 8757117f1b4Smrg dst[i * 4 + 1] = src[i * 4 + 1]; 8767117f1b4Smrg dst[i * 4 + 2] = src[i * 4 + 2]; 8777117f1b4Smrg dst[i * 4 + 3] = src[i * 4 + 3]; 8787117f1b4Smrg } 8797117f1b4Smrg } 8807117f1b4Smrg } 8817117f1b4Smrg else { 882cdc920a0Smrg memcpy(dst, src, 4 * count * sizeof(GLushort)); 8837117f1b4Smrg } 8847117f1b4Smrg} 8857117f1b4Smrg 8867117f1b4Smrg 8877117f1b4Smrgstatic void 8883464ebd5Sriastradhput_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 8897117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 8907117f1b4Smrg{ 8917117f1b4Smrg /* Put RGB values in RGBA buffer */ 8927117f1b4Smrg const GLushort *src = (const GLushort *) values; 8933464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 8947117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 8957117f1b4Smrg if (mask) { 8967117f1b4Smrg GLuint i; 8977117f1b4Smrg for (i = 0; i < count; i++) { 8987117f1b4Smrg if (mask[i]) { 8997117f1b4Smrg dst[i * 4 + 0] = src[i * 3 + 0]; 9007117f1b4Smrg dst[i * 4 + 1] = src[i * 3 + 1]; 9017117f1b4Smrg dst[i * 4 + 2] = src[i * 3 + 2]; 9027117f1b4Smrg dst[i * 4 + 3] = 0xffff; 9037117f1b4Smrg } 9047117f1b4Smrg } 9057117f1b4Smrg } 9067117f1b4Smrg else { 907cdc920a0Smrg memcpy(dst, src, 4 * count * sizeof(GLushort)); 9087117f1b4Smrg } 9097117f1b4Smrg} 9107117f1b4Smrg 9117117f1b4Smrg 9127117f1b4Smrgstatic void 9133464ebd5Sriastradhput_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 9147117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 9157117f1b4Smrg{ 9167117f1b4Smrg const GLushort val0 = ((const GLushort *) value)[0]; 9177117f1b4Smrg const GLushort val1 = ((const GLushort *) value)[1]; 9187117f1b4Smrg const GLushort val2 = ((const GLushort *) value)[2]; 9197117f1b4Smrg const GLushort val3 = ((const GLushort *) value)[3]; 9203464ebd5Sriastradh GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 9217117f1b4Smrg ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 9227117f1b4Smrg if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 9237117f1b4Smrg /* common case for clearing accum buffer */ 924cdc920a0Smrg memset(dst, 0, count * 4 * sizeof(GLushort)); 9257117f1b4Smrg } 9267117f1b4Smrg else { 9277117f1b4Smrg GLuint i; 9287117f1b4Smrg for (i = 0; i < count; i++) { 9297117f1b4Smrg if (!mask || mask[i]) { 9307117f1b4Smrg dst[i * 4 + 0] = val0; 9317117f1b4Smrg dst[i * 4 + 1] = val1; 9327117f1b4Smrg dst[i * 4 + 2] = val2; 9337117f1b4Smrg dst[i * 4 + 3] = val3; 9347117f1b4Smrg } 9357117f1b4Smrg } 9367117f1b4Smrg } 9377117f1b4Smrg} 9387117f1b4Smrg 9393464ebd5Sriastradh 9403464ebd5Sriastradhstatic void 9413464ebd5Sriastradhput_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 9423464ebd5Sriastradh const GLint x[], const GLint y[], const void *values, 9433464ebd5Sriastradh const GLubyte *mask) 9443464ebd5Sriastradh{ 9453464ebd5Sriastradh const GLushort *src = (const GLushort *) values; 9463464ebd5Sriastradh GLuint i; 9473464ebd5Sriastradh ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 9483464ebd5Sriastradh for (i = 0; i < count; i++) { 9493464ebd5Sriastradh if (!mask || mask[i]) { 9503464ebd5Sriastradh GLushort *dst = 9513464ebd5Sriastradh ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); 9523464ebd5Sriastradh dst[0] = src[i * 4 + 0]; 9533464ebd5Sriastradh dst[1] = src[i * 4 + 1]; 9543464ebd5Sriastradh dst[2] = src[i * 4 + 2]; 9553464ebd5Sriastradh dst[3] = src[i * 4 + 3]; 9563464ebd5Sriastradh } 9573464ebd5Sriastradh } 9583464ebd5Sriastradh} 9593464ebd5Sriastradh 9603464ebd5Sriastradh 9613464ebd5Sriastradhstatic void 9623464ebd5Sriastradhput_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, 9633464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 9643464ebd5Sriastradh const void *value, const GLubyte *mask) 9653464ebd5Sriastradh{ 9663464ebd5Sriastradh const GLushort val0 = ((const GLushort *) value)[0]; 9673464ebd5Sriastradh const GLushort val1 = ((const GLushort *) value)[1]; 9683464ebd5Sriastradh const GLushort val2 = ((const GLushort *) value)[2]; 9693464ebd5Sriastradh const GLushort val3 = ((const GLushort *) value)[3]; 9703464ebd5Sriastradh GLuint i; 9713464ebd5Sriastradh ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 9723464ebd5Sriastradh for (i = 0; i < count; i++) { 9733464ebd5Sriastradh if (!mask || mask[i]) { 9743464ebd5Sriastradh GLushort *dst = ((GLushort *) rb->Data) + 9753464ebd5Sriastradh 4 * (y[i] * rb->RowStride + x[i]); 9763464ebd5Sriastradh dst[0] = val0; 9773464ebd5Sriastradh dst[1] = val1; 9783464ebd5Sriastradh dst[2] = val2; 9793464ebd5Sriastradh dst[3] = val3; 9803464ebd5Sriastradh } 9813464ebd5Sriastradh } 9823464ebd5Sriastradh} 9833464ebd5Sriastradh 9843464ebd5Sriastradh/********************************************************************** 9853464ebd5Sriastradh * Functions for MESA_FORMAT_R8. 9863464ebd5Sriastradh */ 9873464ebd5Sriastradhstatic void 9883464ebd5Sriastradhget_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 9893464ebd5Sriastradh GLint x, GLint y, void *values) 9903464ebd5Sriastradh{ 9913464ebd5Sriastradh const GLubyte *src = rb->GetPointer(ctx, rb, x, y); 9923464ebd5Sriastradh GLuint *dst = values; 9933464ebd5Sriastradh GLuint i; 9943464ebd5Sriastradh 9953464ebd5Sriastradh for (i = 0; i < count; i++) { 9963464ebd5Sriastradh dst[i] = 0xff000000 | src[i]; 9973464ebd5Sriastradh } 9983464ebd5Sriastradh} 9993464ebd5Sriastradh 10003464ebd5Sriastradhstatic void 10013464ebd5Sriastradhget_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 10023464ebd5Sriastradh const GLint x[], const GLint y[], void *values) 10033464ebd5Sriastradh{ 10043464ebd5Sriastradh GLuint *dst = (GLuint *) values; 10053464ebd5Sriastradh GLuint i; 10063464ebd5Sriastradh 10073464ebd5Sriastradh for (i = 0; i < count; i++) { 10083464ebd5Sriastradh const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); 10093464ebd5Sriastradh dst[i] = 0xff000000 | *src; 10103464ebd5Sriastradh } 10113464ebd5Sriastradh} 10123464ebd5Sriastradh 10133464ebd5Sriastradh/********************************************************************** 10143464ebd5Sriastradh * Functions for MESA_FORMAT_RG88. 10153464ebd5Sriastradh */ 10163464ebd5Sriastradhstatic void 10173464ebd5Sriastradhget_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 10183464ebd5Sriastradh GLint x, GLint y, void *values) 10193464ebd5Sriastradh{ 10203464ebd5Sriastradh const GLushort *src = rb->GetPointer(ctx, rb, x, y); 10213464ebd5Sriastradh GLuint *dst = values; 10223464ebd5Sriastradh GLuint i; 10233464ebd5Sriastradh 10243464ebd5Sriastradh for (i = 0; i < count; i++) { 10253464ebd5Sriastradh dst[i] = 0xff000000 | src[i]; 10263464ebd5Sriastradh } 10273464ebd5Sriastradh} 10283464ebd5Sriastradh 10293464ebd5Sriastradhstatic void 10303464ebd5Sriastradhget_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, 10313464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], void *values) 10323464ebd5Sriastradh{ 10333464ebd5Sriastradh GLuint *dst = (GLuint *) values; 10343464ebd5Sriastradh GLuint i; 10353464ebd5Sriastradh 10363464ebd5Sriastradh for (i = 0; i < count; i++) { 10373464ebd5Sriastradh const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 10383464ebd5Sriastradh dst[i] = 0xff000000 | *src; 10393464ebd5Sriastradh } 10403464ebd5Sriastradh} 10413464ebd5Sriastradh 10423464ebd5Sriastradh/********************************************************************** 10433464ebd5Sriastradh * Functions for MESA_FORMAT_R16. 10443464ebd5Sriastradh */ 10453464ebd5Sriastradhstatic void 10463464ebd5Sriastradhget_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 10473464ebd5Sriastradh GLint x, GLint y, void *values) 10483464ebd5Sriastradh{ 10493464ebd5Sriastradh const GLushort *src = rb->GetPointer(ctx, rb, x, y); 10503464ebd5Sriastradh GLushort *dst = values; 10513464ebd5Sriastradh GLuint i; 10523464ebd5Sriastradh 10533464ebd5Sriastradh for (i = 0; i < count; i++) { 10543464ebd5Sriastradh dst[i * 4 + RCOMP] = src[i]; 10553464ebd5Sriastradh dst[i * 4 + GCOMP] = 0; 10563464ebd5Sriastradh dst[i * 4 + BCOMP] = 0; 10573464ebd5Sriastradh dst[i * 4 + ACOMP] = 0xffff; 10583464ebd5Sriastradh } 10593464ebd5Sriastradh} 10603464ebd5Sriastradh 10613464ebd5Sriastradhstatic void 10623464ebd5Sriastradhget_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 10633464ebd5Sriastradh const GLint x[], const GLint y[], void *values) 10643464ebd5Sriastradh{ 10653464ebd5Sriastradh GLushort *dst = values; 10663464ebd5Sriastradh GLuint i; 10673464ebd5Sriastradh 10683464ebd5Sriastradh for (i = 0; i < count; i++) { 10693464ebd5Sriastradh const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 10703464ebd5Sriastradh dst[i * 4 + RCOMP] = *src; 10713464ebd5Sriastradh dst[i * 4 + GCOMP] = 0; 10723464ebd5Sriastradh dst[i * 4 + BCOMP] = 0; 10733464ebd5Sriastradh dst[i * 4 + ACOMP] = 0xffff; 10743464ebd5Sriastradh } 10753464ebd5Sriastradh} 10763464ebd5Sriastradh 10773464ebd5Sriastradh/********************************************************************** 10783464ebd5Sriastradh * Functions for MESA_FORMAT_RG1616. 10793464ebd5Sriastradh */ 10803464ebd5Sriastradhstatic void 10813464ebd5Sriastradhget_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 10823464ebd5Sriastradh GLint x, GLint y, void *values) 10833464ebd5Sriastradh{ 10843464ebd5Sriastradh const GLushort *src = rb->GetPointer(ctx, rb, x, y); 10853464ebd5Sriastradh GLushort *dst = values; 10863464ebd5Sriastradh GLuint i; 10873464ebd5Sriastradh 10883464ebd5Sriastradh for (i = 0; i < count; i++) { 10893464ebd5Sriastradh dst[i * 4 + RCOMP] = src[i * 2]; 10903464ebd5Sriastradh dst[i * 4 + GCOMP] = src[i * 2 + 1]; 10913464ebd5Sriastradh dst[i * 4 + BCOMP] = 0; 10923464ebd5Sriastradh dst[i * 4 + ACOMP] = 0xffff; 10933464ebd5Sriastradh } 10943464ebd5Sriastradh} 10953464ebd5Sriastradh 10963464ebd5Sriastradhstatic void 10973464ebd5Sriastradhget_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, 10983464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], void *values) 10993464ebd5Sriastradh{ 11003464ebd5Sriastradh GLushort *dst = values; 11013464ebd5Sriastradh GLuint i; 11023464ebd5Sriastradh 11033464ebd5Sriastradh for (i = 0; i < count; i++) { 11043464ebd5Sriastradh const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 11053464ebd5Sriastradh dst[i * 4 + RCOMP] = src[0]; 11063464ebd5Sriastradh dst[i * 4 + GCOMP] = src[1]; 11073464ebd5Sriastradh dst[i * 4 + BCOMP] = 0; 11083464ebd5Sriastradh dst[i * 4 + ACOMP] = 0xffff; 11093464ebd5Sriastradh } 11103464ebd5Sriastradh} 11113464ebd5Sriastradh 11123464ebd5Sriastradh/********************************************************************** 11133464ebd5Sriastradh * Functions for MESA_FORMAT_INTENSITY_FLOAT32. 11143464ebd5Sriastradh */ 11153464ebd5Sriastradhstatic void 11163464ebd5Sriastradhget_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 11173464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 11183464ebd5Sriastradh{ 11193464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 11203464ebd5Sriastradh GLfloat *dst = values; 11213464ebd5Sriastradh GLuint i; 11223464ebd5Sriastradh 11233464ebd5Sriastradh for (i = 0; i < count; i++) { 11243464ebd5Sriastradh dst[i * 4 + RCOMP] = 11253464ebd5Sriastradh dst[i * 4 + GCOMP] = 11263464ebd5Sriastradh dst[i * 4 + BCOMP] = 11273464ebd5Sriastradh dst[i * 4 + ACOMP] = src[i]; 11283464ebd5Sriastradh } 11293464ebd5Sriastradh} 11303464ebd5Sriastradh 11313464ebd5Sriastradhstatic void 11323464ebd5Sriastradhget_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 11333464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 11343464ebd5Sriastradh void *values) 11353464ebd5Sriastradh{ 11363464ebd5Sriastradh GLfloat *dst = values; 11373464ebd5Sriastradh GLuint i; 11383464ebd5Sriastradh 11393464ebd5Sriastradh for (i = 0; i < count; i++) { 11403464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 11413464ebd5Sriastradh dst[i * 4 + RCOMP] = 11423464ebd5Sriastradh dst[i * 4 + GCOMP] = 11433464ebd5Sriastradh dst[i * 4 + BCOMP] = 11443464ebd5Sriastradh dst[i * 4 + ACOMP] = src[0]; 11453464ebd5Sriastradh } 11463464ebd5Sriastradh} 11473464ebd5Sriastradh 11483464ebd5Sriastradh/********************************************************************** 11493464ebd5Sriastradh * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. 11503464ebd5Sriastradh */ 11513464ebd5Sriastradhstatic void 11523464ebd5Sriastradhget_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 11533464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 11543464ebd5Sriastradh{ 11553464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 11563464ebd5Sriastradh GLfloat *dst = values; 11573464ebd5Sriastradh GLuint i; 11583464ebd5Sriastradh 11593464ebd5Sriastradh for (i = 0; i < count; i++) { 11603464ebd5Sriastradh dst[i * 4 + RCOMP] = 11613464ebd5Sriastradh dst[i * 4 + GCOMP] = 11623464ebd5Sriastradh dst[i * 4 + BCOMP] = src[i]; 11633464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 11643464ebd5Sriastradh } 11653464ebd5Sriastradh} 11663464ebd5Sriastradh 11673464ebd5Sriastradhstatic void 11683464ebd5Sriastradhget_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 11693464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 11703464ebd5Sriastradh void *values) 11713464ebd5Sriastradh{ 11723464ebd5Sriastradh GLfloat *dst = values; 11733464ebd5Sriastradh GLuint i; 11743464ebd5Sriastradh 11753464ebd5Sriastradh for (i = 0; i < count; i++) { 11763464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 11773464ebd5Sriastradh dst[i * 4 + RCOMP] = 11783464ebd5Sriastradh dst[i * 4 + GCOMP] = 11793464ebd5Sriastradh dst[i * 4 + BCOMP] = src[0]; 11803464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 11813464ebd5Sriastradh } 11823464ebd5Sriastradh} 11833464ebd5Sriastradh 11843464ebd5Sriastradh/********************************************************************** 11853464ebd5Sriastradh * Functions for MESA_FORMAT_ALPHA_FLOAT32. 11863464ebd5Sriastradh */ 11873464ebd5Sriastradhstatic void 11883464ebd5Sriastradhget_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 11893464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 11903464ebd5Sriastradh{ 11913464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 11923464ebd5Sriastradh GLfloat *dst = values; 11933464ebd5Sriastradh GLuint i; 11943464ebd5Sriastradh 11953464ebd5Sriastradh for (i = 0; i < count; i++) { 11963464ebd5Sriastradh dst[i * 4 + RCOMP] = 0.0; 11973464ebd5Sriastradh dst[i * 4 + GCOMP] = 0.0; 11983464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 11993464ebd5Sriastradh dst[i * 4 + ACOMP] = src[i]; 12003464ebd5Sriastradh } 12013464ebd5Sriastradh} 12023464ebd5Sriastradh 12033464ebd5Sriastradhstatic void 12043464ebd5Sriastradhget_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 12053464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 12063464ebd5Sriastradh void *values) 12073464ebd5Sriastradh{ 12083464ebd5Sriastradh GLfloat *dst = values; 12093464ebd5Sriastradh GLuint i; 12103464ebd5Sriastradh 12113464ebd5Sriastradh for (i = 0; i < count; i++) { 12123464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 12133464ebd5Sriastradh dst[i * 4 + RCOMP] = 0.0; 12143464ebd5Sriastradh dst[i * 4 + GCOMP] = 0.0; 12153464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 12163464ebd5Sriastradh dst[i * 4 + ACOMP] = src[0]; 12173464ebd5Sriastradh } 12183464ebd5Sriastradh} 12193464ebd5Sriastradh 12203464ebd5Sriastradhstatic void 12213464ebd5Sriastradhput_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 12223464ebd5Sriastradh GLuint count, GLint x, GLint y, 12233464ebd5Sriastradh const void *values, const GLubyte *mask) 12243464ebd5Sriastradh{ 12253464ebd5Sriastradh float *dst = rb->GetPointer(ctx, rb, x, y); 12263464ebd5Sriastradh const float *src = values; 12273464ebd5Sriastradh unsigned int i; 12283464ebd5Sriastradh 12293464ebd5Sriastradh if (mask) { 12303464ebd5Sriastradh for (i = 0; i < count; i++) { 12313464ebd5Sriastradh if (mask[i]) { 12323464ebd5Sriastradh dst[i] = src[i * 4 + ACOMP]; 12333464ebd5Sriastradh } 12343464ebd5Sriastradh } 12353464ebd5Sriastradh } 12363464ebd5Sriastradh else { 12373464ebd5Sriastradh for (i = 0; i < count; i++) { 12383464ebd5Sriastradh dst[i] = src[i * 4 + ACOMP]; 12393464ebd5Sriastradh } 12403464ebd5Sriastradh } 12413464ebd5Sriastradh} 12423464ebd5Sriastradh 12433464ebd5Sriastradhstatic void 12443464ebd5Sriastradhput_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 12453464ebd5Sriastradh GLuint count, GLint x, GLint y, 12463464ebd5Sriastradh const void *value, const GLubyte *mask) 12473464ebd5Sriastradh{ 12483464ebd5Sriastradh float *dst = rb->GetPointer(ctx, rb, x, y); 12493464ebd5Sriastradh const float *src = value; 12503464ebd5Sriastradh unsigned int i; 12513464ebd5Sriastradh 12523464ebd5Sriastradh if (mask) { 12533464ebd5Sriastradh for (i = 0; i < count; i++) { 12543464ebd5Sriastradh if (mask[i]) { 12553464ebd5Sriastradh dst[i] = src[ACOMP]; 12563464ebd5Sriastradh } 12573464ebd5Sriastradh } 12583464ebd5Sriastradh } 12593464ebd5Sriastradh else { 12603464ebd5Sriastradh for (i = 0; i < count; i++) { 12613464ebd5Sriastradh dst[i] = src[ACOMP]; 12623464ebd5Sriastradh } 12633464ebd5Sriastradh } 12643464ebd5Sriastradh} 12653464ebd5Sriastradh 12663464ebd5Sriastradhstatic void 12673464ebd5Sriastradhput_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 12683464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 12693464ebd5Sriastradh const void *values, const GLubyte *mask) 12703464ebd5Sriastradh{ 12713464ebd5Sriastradh const float *src = values; 12723464ebd5Sriastradh unsigned int i; 12733464ebd5Sriastradh 12743464ebd5Sriastradh for (i = 0; i < count; i++) { 12753464ebd5Sriastradh if (!mask || mask[i]) { 12763464ebd5Sriastradh float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 12773464ebd5Sriastradh 12783464ebd5Sriastradh *dst = src[i * 4 + ACOMP]; 12793464ebd5Sriastradh } 12803464ebd5Sriastradh } 12813464ebd5Sriastradh} 12823464ebd5Sriastradh 12837117f1b4Smrgstatic void 12843464ebd5Sriastradhput_mono_values_a_float32(struct gl_context *ctx, 12853464ebd5Sriastradh struct gl_renderbuffer *rb, 12863464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 12873464ebd5Sriastradh const void *value, const GLubyte *mask) 12887117f1b4Smrg{ 12893464ebd5Sriastradh const float *src = value; 12903464ebd5Sriastradh unsigned int i; 12913464ebd5Sriastradh 12927117f1b4Smrg for (i = 0; i < count; i++) { 12937117f1b4Smrg if (!mask || mask[i]) { 12943464ebd5Sriastradh float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 12953464ebd5Sriastradh *dst = src[ACOMP]; 12967117f1b4Smrg } 12977117f1b4Smrg } 12987117f1b4Smrg} 12997117f1b4Smrg 13003464ebd5Sriastradh/********************************************************************** 13013464ebd5Sriastradh * Functions for MESA_FORMAT_R_FLOAT32. 13023464ebd5Sriastradh */ 13033464ebd5Sriastradhstatic void 13043464ebd5Sriastradhget_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 13053464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 13063464ebd5Sriastradh{ 13073464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 13083464ebd5Sriastradh GLfloat *dst = values; 13093464ebd5Sriastradh GLuint i; 13103464ebd5Sriastradh 13113464ebd5Sriastradh for (i = 0; i < count; i++) { 13123464ebd5Sriastradh dst[i * 4 + RCOMP] = src[i]; 13133464ebd5Sriastradh dst[i * 4 + GCOMP] = 0.0; 13143464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 13153464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 13163464ebd5Sriastradh } 13173464ebd5Sriastradh} 13187117f1b4Smrg 13197117f1b4Smrgstatic void 13203464ebd5Sriastradhget_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 13213464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 13223464ebd5Sriastradh void *values) 13237117f1b4Smrg{ 13243464ebd5Sriastradh GLfloat *dst = values; 13257117f1b4Smrg GLuint i; 13263464ebd5Sriastradh 13277117f1b4Smrg for (i = 0; i < count; i++) { 13283464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 13293464ebd5Sriastradh dst[i * 4 + RCOMP] = src[0]; 13303464ebd5Sriastradh dst[i * 4 + GCOMP] = 0.0; 13313464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 13323464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 13333464ebd5Sriastradh } 13343464ebd5Sriastradh} 13353464ebd5Sriastradh 13363464ebd5Sriastradh/********************************************************************** 13373464ebd5Sriastradh * Functions for MESA_FORMAT_RG_FLOAT32. 13383464ebd5Sriastradh */ 13393464ebd5Sriastradhstatic void 13403464ebd5Sriastradhget_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 13413464ebd5Sriastradh GLuint count, GLint x, GLint y, void *values) 13423464ebd5Sriastradh{ 13433464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 13443464ebd5Sriastradh GLfloat *dst = values; 13453464ebd5Sriastradh GLuint i; 13463464ebd5Sriastradh 13473464ebd5Sriastradh for (i = 0; i < count; i++) { 13483464ebd5Sriastradh dst[i * 4 + RCOMP] = src[i * 2 + 0]; 13493464ebd5Sriastradh dst[i * 4 + GCOMP] = src[i * 2 + 1]; 13503464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 13513464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 13527117f1b4Smrg } 13537117f1b4Smrg} 13547117f1b4Smrg 13553464ebd5Sriastradhstatic void 13563464ebd5Sriastradhget_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 13573464ebd5Sriastradh GLuint count, const GLint x[], const GLint y[], 13583464ebd5Sriastradh void *values) 13593464ebd5Sriastradh{ 13603464ebd5Sriastradh GLfloat *dst = values; 13613464ebd5Sriastradh GLuint i; 13627117f1b4Smrg 13633464ebd5Sriastradh for (i = 0; i < count; i++) { 13643464ebd5Sriastradh const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 13653464ebd5Sriastradh dst[i * 4 + RCOMP] = src[0]; 13663464ebd5Sriastradh dst[i * 4 + GCOMP] = src[1]; 13673464ebd5Sriastradh dst[i * 4 + BCOMP] = 0.0; 13683464ebd5Sriastradh dst[i * 4 + ACOMP] = 1.0; 13693464ebd5Sriastradh } 13703464ebd5Sriastradh} 13717117f1b4Smrg 13727117f1b4Smrg/** 13733464ebd5Sriastradh * This is the default software fallback for gl_renderbuffer's span 13743464ebd5Sriastradh * access functions. 13757117f1b4Smrg * 13763464ebd5Sriastradh * The assumptions are that rb->Data will be a pointer to (0,0), that pixels 13773464ebd5Sriastradh * are packed in the type of rb->Format, and that subsequent rows appear 13783464ebd5Sriastradh * rb->RowStride pixels later. 13797117f1b4Smrg */ 13803464ebd5Sriastradhvoid 13813464ebd5Sriastradh_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb) 13827117f1b4Smrg{ 13833464ebd5Sriastradh rb->GetPointer = get_pointer_generic; 13843464ebd5Sriastradh rb->GetRow = get_row_generic; 13857117f1b4Smrg 13863464ebd5Sriastradh switch (rb->Format) { 13873464ebd5Sriastradh case MESA_FORMAT_RGB888: 13887117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 13897117f1b4Smrg rb->GetPointer = get_pointer_ubyte3; 13907117f1b4Smrg rb->GetRow = get_row_ubyte3; 13917117f1b4Smrg rb->GetValues = get_values_ubyte3; 13927117f1b4Smrg rb->PutRow = put_row_ubyte3; 13937117f1b4Smrg rb->PutRowRGB = put_row_rgb_ubyte3; 13947117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte3; 13957117f1b4Smrg rb->PutValues = put_values_ubyte3; 13967117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte3; 13977117f1b4Smrg break; 13983464ebd5Sriastradh 13993464ebd5Sriastradh case MESA_FORMAT_RGBA8888: 14007117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 14017117f1b4Smrg rb->GetValues = get_values_ubyte4; 14027117f1b4Smrg rb->PutRow = put_row_ubyte4; 14037117f1b4Smrg rb->PutRowRGB = put_row_rgb_ubyte4; 14047117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte4; 14057117f1b4Smrg rb->PutValues = put_values_ubyte4; 14067117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte4; 14077117f1b4Smrg break; 14083464ebd5Sriastradh 14093464ebd5Sriastradh case MESA_FORMAT_R8: 14103464ebd5Sriastradh rb->DataType = GL_UNSIGNED_BYTE; 14113464ebd5Sriastradh rb->GetValues = get_values_r8; 14123464ebd5Sriastradh rb->GetRow = get_row_r8; 14133464ebd5Sriastradh rb->PutRow = put_row_generic; 14143464ebd5Sriastradh rb->PutRowRGB = put_row_generic; 14153464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 14163464ebd5Sriastradh rb->PutValues = put_values_generic; 14173464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 14183464ebd5Sriastradh break; 14193464ebd5Sriastradh 14203464ebd5Sriastradh case MESA_FORMAT_RG88: 14213464ebd5Sriastradh rb->DataType = GL_UNSIGNED_BYTE; 14223464ebd5Sriastradh rb->GetValues = get_values_rg88; 14233464ebd5Sriastradh rb->GetRow = get_row_rg88; 14243464ebd5Sriastradh rb->PutRow = put_row_generic; 14253464ebd5Sriastradh rb->PutRowRGB = put_row_generic; 14263464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 14273464ebd5Sriastradh rb->PutValues = put_values_generic; 14283464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 14293464ebd5Sriastradh break; 14303464ebd5Sriastradh 14313464ebd5Sriastradh case MESA_FORMAT_R16: 14323464ebd5Sriastradh rb->DataType = GL_UNSIGNED_SHORT; 14333464ebd5Sriastradh rb->GetValues = get_values_r16; 14343464ebd5Sriastradh rb->GetRow = get_row_r16; 14353464ebd5Sriastradh rb->PutRow = put_row_generic; 14363464ebd5Sriastradh rb->PutRowRGB = put_row_generic; 14373464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 14383464ebd5Sriastradh rb->PutValues = put_values_generic; 14393464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 14403464ebd5Sriastradh break; 14413464ebd5Sriastradh 14423464ebd5Sriastradh case MESA_FORMAT_RG1616: 14433464ebd5Sriastradh rb->DataType = GL_UNSIGNED_SHORT; 14443464ebd5Sriastradh rb->GetValues = get_values_rg1616; 14453464ebd5Sriastradh rb->GetRow = get_row_rg1616; 14463464ebd5Sriastradh rb->PutRow = put_row_generic; 14473464ebd5Sriastradh rb->PutRowRGB = put_row_generic; 14483464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 14493464ebd5Sriastradh rb->PutValues = put_values_generic; 14503464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 14513464ebd5Sriastradh break; 14523464ebd5Sriastradh 14533464ebd5Sriastradh case MESA_FORMAT_SIGNED_RGBA_16: 14544a49301eSmrg rb->DataType = GL_SHORT; 14557117f1b4Smrg rb->GetValues = get_values_ushort4; 14567117f1b4Smrg rb->PutRow = put_row_ushort4; 14577117f1b4Smrg rb->PutRowRGB = put_row_rgb_ushort4; 14587117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort4; 14597117f1b4Smrg rb->PutValues = put_values_ushort4; 14607117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort4; 14617117f1b4Smrg break; 14623464ebd5Sriastradh 14634a49301eSmrg#if 0 14643464ebd5Sriastradh case MESA_FORMAT_A8: 14657117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 14667117f1b4Smrg rb->GetValues = get_values_alpha8; 14677117f1b4Smrg rb->PutRow = put_row_alpha8; 14687117f1b4Smrg rb->PutRowRGB = NULL; 14697117f1b4Smrg rb->PutMonoRow = put_mono_row_alpha8; 14707117f1b4Smrg rb->PutValues = put_values_alpha8; 14717117f1b4Smrg rb->PutMonoValues = put_mono_values_alpha8; 14727117f1b4Smrg break; 14737117f1b4Smrg#endif 14743464ebd5Sriastradh 14753464ebd5Sriastradh case MESA_FORMAT_S8: 14767117f1b4Smrg rb->DataType = GL_UNSIGNED_BYTE; 14777117f1b4Smrg rb->GetValues = get_values_ubyte; 14787117f1b4Smrg rb->PutRow = put_row_ubyte; 14797117f1b4Smrg rb->PutRowRGB = NULL; 14807117f1b4Smrg rb->PutMonoRow = put_mono_row_ubyte; 14817117f1b4Smrg rb->PutValues = put_values_ubyte; 14827117f1b4Smrg rb->PutMonoValues = put_mono_values_ubyte; 14837117f1b4Smrg break; 14843464ebd5Sriastradh 14853464ebd5Sriastradh case MESA_FORMAT_Z16: 14867117f1b4Smrg rb->DataType = GL_UNSIGNED_SHORT; 14877117f1b4Smrg rb->GetValues = get_values_ushort; 14887117f1b4Smrg rb->PutRow = put_row_ushort; 14897117f1b4Smrg rb->PutRowRGB = NULL; 14907117f1b4Smrg rb->PutMonoRow = put_mono_row_ushort; 14917117f1b4Smrg rb->PutValues = put_values_ushort; 14927117f1b4Smrg rb->PutMonoValues = put_mono_values_ushort; 14937117f1b4Smrg break; 14943464ebd5Sriastradh 14953464ebd5Sriastradh case MESA_FORMAT_Z32: 14963464ebd5Sriastradh case MESA_FORMAT_X8_Z24: 14973464ebd5Sriastradh case MESA_FORMAT_Z24_X8: 14984a49301eSmrg rb->DataType = GL_UNSIGNED_INT; 14994a49301eSmrg rb->GetValues = get_values_uint; 15004a49301eSmrg rb->PutRow = put_row_uint; 15014a49301eSmrg rb->PutRowRGB = NULL; 15024a49301eSmrg rb->PutMonoRow = put_mono_row_uint; 15034a49301eSmrg rb->PutValues = put_values_uint; 15044a49301eSmrg rb->PutMonoValues = put_mono_values_uint; 15054a49301eSmrg break; 15063464ebd5Sriastradh 15073464ebd5Sriastradh case MESA_FORMAT_Z24_S8: 15083464ebd5Sriastradh case MESA_FORMAT_S8_Z24: 15093464ebd5Sriastradh rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 15107117f1b4Smrg rb->GetValues = get_values_uint; 15117117f1b4Smrg rb->PutRow = put_row_uint; 15127117f1b4Smrg rb->PutRowRGB = NULL; 15137117f1b4Smrg rb->PutMonoRow = put_mono_row_uint; 15147117f1b4Smrg rb->PutValues = put_values_uint; 15157117f1b4Smrg rb->PutMonoValues = put_mono_values_uint; 15163464ebd5Sriastradh break; 15173464ebd5Sriastradh 15183464ebd5Sriastradh case MESA_FORMAT_RGBA_FLOAT32: 15193464ebd5Sriastradh rb->GetRow = get_row_generic; 15203464ebd5Sriastradh rb->GetValues = get_values_generic; 15213464ebd5Sriastradh rb->PutRow = put_row_generic; 15223464ebd5Sriastradh rb->PutRowRGB = NULL; 15233464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 15243464ebd5Sriastradh rb->PutValues = put_values_generic; 15253464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 15263464ebd5Sriastradh break; 15273464ebd5Sriastradh 15283464ebd5Sriastradh case MESA_FORMAT_INTENSITY_FLOAT32: 15293464ebd5Sriastradh rb->GetRow = get_row_i_float32; 15303464ebd5Sriastradh rb->GetValues = get_values_i_float32; 15313464ebd5Sriastradh rb->PutRow = put_row_generic; 15323464ebd5Sriastradh rb->PutRowRGB = NULL; 15333464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 15343464ebd5Sriastradh rb->PutValues = put_values_generic; 15353464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 15363464ebd5Sriastradh break; 15373464ebd5Sriastradh 15383464ebd5Sriastradh case MESA_FORMAT_LUMINANCE_FLOAT32: 15393464ebd5Sriastradh rb->GetRow = get_row_l_float32; 15403464ebd5Sriastradh rb->GetValues = get_values_l_float32; 15413464ebd5Sriastradh rb->PutRow = put_row_generic; 15423464ebd5Sriastradh rb->PutRowRGB = NULL; 15433464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 15443464ebd5Sriastradh rb->PutValues = put_values_generic; 15453464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 15463464ebd5Sriastradh break; 15473464ebd5Sriastradh 15483464ebd5Sriastradh case MESA_FORMAT_ALPHA_FLOAT32: 15493464ebd5Sriastradh rb->GetRow = get_row_a_float32; 15503464ebd5Sriastradh rb->GetValues = get_values_a_float32; 15513464ebd5Sriastradh rb->PutRow = put_row_a_float32; 15523464ebd5Sriastradh rb->PutRowRGB = NULL; 15533464ebd5Sriastradh rb->PutMonoRow = put_mono_row_a_float32; 15543464ebd5Sriastradh rb->PutValues = put_values_a_float32; 15553464ebd5Sriastradh rb->PutMonoValues = put_mono_values_a_float32; 15563464ebd5Sriastradh break; 15573464ebd5Sriastradh 15583464ebd5Sriastradh case MESA_FORMAT_RG_FLOAT32: 15593464ebd5Sriastradh rb->GetRow = get_row_rg_float32; 15603464ebd5Sriastradh rb->GetValues = get_values_rg_float32; 15613464ebd5Sriastradh rb->PutRow = put_row_generic; 15623464ebd5Sriastradh rb->PutRowRGB = NULL; 15633464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 15643464ebd5Sriastradh rb->PutValues = put_values_generic; 15653464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 15663464ebd5Sriastradh break; 15673464ebd5Sriastradh 15683464ebd5Sriastradh case MESA_FORMAT_R_FLOAT32: 15693464ebd5Sriastradh rb->GetRow = get_row_r_float32; 15703464ebd5Sriastradh rb->GetValues = get_values_r_float32; 15713464ebd5Sriastradh rb->PutRow = put_row_generic; 15723464ebd5Sriastradh rb->PutRowRGB = NULL; 15733464ebd5Sriastradh rb->PutMonoRow = put_mono_row_generic; 15743464ebd5Sriastradh rb->PutValues = put_values_generic; 15753464ebd5Sriastradh rb->PutMonoValues = put_mono_values_generic; 15763464ebd5Sriastradh break; 15773464ebd5Sriastradh 15783464ebd5Sriastradh default: 15793464ebd5Sriastradh break; 15803464ebd5Sriastradh } 15813464ebd5Sriastradh} 15823464ebd5Sriastradh 15833464ebd5Sriastradh/** 15843464ebd5Sriastradh * This is a software fallback for the gl_renderbuffer->AllocStorage 15853464ebd5Sriastradh * function. 15863464ebd5Sriastradh * Device drivers will typically override this function for the buffers 15873464ebd5Sriastradh * which it manages (typically color buffers, Z and stencil). 15883464ebd5Sriastradh * Other buffers (like software accumulation and aux buffers) which the driver 15893464ebd5Sriastradh * doesn't manage can be handled with this function. 15903464ebd5Sriastradh * 15913464ebd5Sriastradh * This one multi-purpose function can allocate stencil, depth, accum, color 15923464ebd5Sriastradh * or color-index buffers! 15933464ebd5Sriastradh * 15943464ebd5Sriastradh * This function also plugs in the appropriate GetPointer, Get/PutRow and 15953464ebd5Sriastradh * Get/PutValues functions. 15963464ebd5Sriastradh */ 15973464ebd5SriastradhGLboolean 15983464ebd5Sriastradh_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 15993464ebd5Sriastradh GLenum internalFormat, 16003464ebd5Sriastradh GLuint width, GLuint height) 16013464ebd5Sriastradh{ 16023464ebd5Sriastradh switch (internalFormat) { 16033464ebd5Sriastradh case GL_RGB: 16043464ebd5Sriastradh case GL_R3_G3_B2: 16053464ebd5Sriastradh case GL_RGB4: 16063464ebd5Sriastradh case GL_RGB5: 16073464ebd5Sriastradh case GL_RGB8: 16083464ebd5Sriastradh case GL_RGB10: 16093464ebd5Sriastradh case GL_RGB12: 16103464ebd5Sriastradh case GL_RGB16: 16113464ebd5Sriastradh rb->Format = MESA_FORMAT_RGB888; 16123464ebd5Sriastradh break; 16133464ebd5Sriastradh case GL_RGBA: 16143464ebd5Sriastradh case GL_RGBA2: 16153464ebd5Sriastradh case GL_RGBA4: 16163464ebd5Sriastradh case GL_RGB5_A1: 16173464ebd5Sriastradh case GL_RGBA8: 16183464ebd5Sriastradh#if 1 16193464ebd5Sriastradh case GL_RGB10_A2: 16203464ebd5Sriastradh case GL_RGBA12: 16213464ebd5Sriastradh#endif 16223464ebd5Sriastradh rb->Format = MESA_FORMAT_RGBA8888; 16233464ebd5Sriastradh break; 16243464ebd5Sriastradh case GL_RGBA16: 16253464ebd5Sriastradh case GL_RGBA16_SNORM: 16263464ebd5Sriastradh /* for accum buffer */ 16273464ebd5Sriastradh rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 16283464ebd5Sriastradh break; 16293464ebd5Sriastradh#if 0 16303464ebd5Sriastradh case GL_ALPHA8: 16313464ebd5Sriastradh rb->Format = MESA_FORMAT_A8; 16323464ebd5Sriastradh break; 16333464ebd5Sriastradh#endif 16343464ebd5Sriastradh case GL_STENCIL_INDEX: 16353464ebd5Sriastradh case GL_STENCIL_INDEX1_EXT: 16363464ebd5Sriastradh case GL_STENCIL_INDEX4_EXT: 16373464ebd5Sriastradh case GL_STENCIL_INDEX8_EXT: 16383464ebd5Sriastradh case GL_STENCIL_INDEX16_EXT: 16393464ebd5Sriastradh rb->Format = MESA_FORMAT_S8; 16403464ebd5Sriastradh break; 16413464ebd5Sriastradh case GL_DEPTH_COMPONENT: 16423464ebd5Sriastradh case GL_DEPTH_COMPONENT16: 16433464ebd5Sriastradh rb->Format = MESA_FORMAT_Z16; 16443464ebd5Sriastradh break; 16453464ebd5Sriastradh case GL_DEPTH_COMPONENT24: 16463464ebd5Sriastradh rb->Format = MESA_FORMAT_X8_Z24; 16473464ebd5Sriastradh break; 16483464ebd5Sriastradh case GL_DEPTH_COMPONENT32: 16494a49301eSmrg rb->Format = MESA_FORMAT_Z32; 16507117f1b4Smrg break; 16517117f1b4Smrg case GL_DEPTH_STENCIL_EXT: 16527117f1b4Smrg case GL_DEPTH24_STENCIL8_EXT: 16534a49301eSmrg rb->Format = MESA_FORMAT_Z24_S8; 16547117f1b4Smrg break; 16557117f1b4Smrg default: 16563464ebd5Sriastradh /* unsupported format */ 16577117f1b4Smrg return GL_FALSE; 16587117f1b4Smrg } 16597117f1b4Smrg 16603464ebd5Sriastradh _mesa_set_renderbuffer_accessors(rb); 16613464ebd5Sriastradh 16627117f1b4Smrg ASSERT(rb->DataType); 16637117f1b4Smrg ASSERT(rb->GetPointer); 16647117f1b4Smrg ASSERT(rb->GetRow); 16657117f1b4Smrg ASSERT(rb->GetValues); 16667117f1b4Smrg ASSERT(rb->PutRow); 16677117f1b4Smrg ASSERT(rb->PutMonoRow); 16687117f1b4Smrg ASSERT(rb->PutValues); 16697117f1b4Smrg ASSERT(rb->PutMonoValues); 16707117f1b4Smrg 16717117f1b4Smrg /* free old buffer storage */ 16727117f1b4Smrg if (rb->Data) { 1673cdc920a0Smrg free(rb->Data); 16747117f1b4Smrg rb->Data = NULL; 16757117f1b4Smrg } 16767117f1b4Smrg 16773464ebd5Sriastradh rb->RowStride = width; 16783464ebd5Sriastradh 16797117f1b4Smrg if (width > 0 && height > 0) { 16807117f1b4Smrg /* allocate new buffer storage */ 16813464ebd5Sriastradh rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); 16824a49301eSmrg 16837117f1b4Smrg if (rb->Data == NULL) { 16847117f1b4Smrg rb->Width = 0; 16857117f1b4Smrg rb->Height = 0; 16863464ebd5Sriastradh rb->RowStride = 0; 16877117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, 16887117f1b4Smrg "software renderbuffer allocation (%d x %d x %d)", 16893464ebd5Sriastradh width, height, _mesa_get_format_bytes(rb->Format)); 16907117f1b4Smrg return GL_FALSE; 16917117f1b4Smrg } 16927117f1b4Smrg } 16937117f1b4Smrg 16947117f1b4Smrg rb->Width = width; 16957117f1b4Smrg rb->Height = height; 16964a49301eSmrg rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 16973464ebd5Sriastradh 16983464ebd5Sriastradh if (rb->Name == 0 && 16993464ebd5Sriastradh internalFormat == GL_RGBA16_SNORM && 17003464ebd5Sriastradh rb->_BaseFormat == 0) { 17013464ebd5Sriastradh /* NOTE: This is a special case just for accumulation buffers. 17023464ebd5Sriastradh * This is a very limited use case- there's no snorm texturing or 17033464ebd5Sriastradh * rendering going on. 17043464ebd5Sriastradh */ 17053464ebd5Sriastradh rb->_BaseFormat = GL_RGBA; 17063464ebd5Sriastradh } 17073464ebd5Sriastradh else { 17083464ebd5Sriastradh /* the internalFormat should have been error checked long ago */ 17093464ebd5Sriastradh ASSERT(rb->_BaseFormat); 17103464ebd5Sriastradh } 17117117f1b4Smrg 17127117f1b4Smrg return GL_TRUE; 17137117f1b4Smrg} 17147117f1b4Smrg 17157117f1b4Smrg 17167117f1b4Smrg 17177117f1b4Smrg/**********************************************************************/ 17187117f1b4Smrg/**********************************************************************/ 17197117f1b4Smrg/**********************************************************************/ 17207117f1b4Smrg 17217117f1b4Smrg 17227117f1b4Smrg/** 17237117f1b4Smrg * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha 17247117f1b4Smrg * buffer wrapper around an existing RGB renderbuffer (hw or sw). 17257117f1b4Smrg * 17267117f1b4Smrg * When PutRow is called (for example), we store the alpha values in 17277117f1b4Smrg * this buffer, then pass on the PutRow call to the wrapped RGB 17287117f1b4Smrg * buffer. 17297117f1b4Smrg */ 17307117f1b4Smrg 17317117f1b4Smrg 17327117f1b4Smrgstatic GLboolean 17333464ebd5Sriastradhalloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 17347117f1b4Smrg GLenum internalFormat, GLuint width, GLuint height) 17357117f1b4Smrg{ 17367117f1b4Smrg ASSERT(arb != arb->Wrapped); 17374a49301eSmrg ASSERT(arb->Format == MESA_FORMAT_A8); 17387117f1b4Smrg 17397117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 17407117f1b4Smrg if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat, 17417117f1b4Smrg width, height)) { 17427117f1b4Smrg return GL_FALSE; 17437117f1b4Smrg } 17447117f1b4Smrg 17457117f1b4Smrg /* next, resize my alpha buffer */ 17467117f1b4Smrg if (arb->Data) { 1747cdc920a0Smrg free(arb->Data); 17487117f1b4Smrg } 17497117f1b4Smrg 1750cdc920a0Smrg arb->Data = malloc(width * height * sizeof(GLubyte)); 17517117f1b4Smrg if (arb->Data == NULL) { 17527117f1b4Smrg arb->Width = 0; 17537117f1b4Smrg arb->Height = 0; 17547117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 17557117f1b4Smrg return GL_FALSE; 17567117f1b4Smrg } 17577117f1b4Smrg 17587117f1b4Smrg arb->Width = width; 17597117f1b4Smrg arb->Height = height; 17603464ebd5Sriastradh arb->RowStride = width; 17617117f1b4Smrg 17627117f1b4Smrg return GL_TRUE; 17637117f1b4Smrg} 17647117f1b4Smrg 17657117f1b4Smrg 17667117f1b4Smrg/** 17677117f1b4Smrg * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 17687117f1b4Smrg */ 17697117f1b4Smrgstatic void 17707117f1b4Smrgdelete_renderbuffer_alpha8(struct gl_renderbuffer *arb) 17717117f1b4Smrg{ 17727117f1b4Smrg if (arb->Data) { 1773cdc920a0Smrg free(arb->Data); 17747117f1b4Smrg } 17757117f1b4Smrg ASSERT(arb->Wrapped); 17767117f1b4Smrg ASSERT(arb != arb->Wrapped); 17777117f1b4Smrg arb->Wrapped->Delete(arb->Wrapped); 17787117f1b4Smrg arb->Wrapped = NULL; 1779cdc920a0Smrg free(arb); 17807117f1b4Smrg} 17817117f1b4Smrg 17827117f1b4Smrg 17837117f1b4Smrgstatic void * 17843464ebd5Sriastradhget_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 17857117f1b4Smrg GLint x, GLint y) 17867117f1b4Smrg{ 17877117f1b4Smrg return NULL; /* don't allow direct access! */ 17887117f1b4Smrg} 17897117f1b4Smrg 17907117f1b4Smrg 17917117f1b4Smrgstatic void 17923464ebd5Sriastradhget_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 17937117f1b4Smrg GLint x, GLint y, void *values) 17947117f1b4Smrg{ 17957117f1b4Smrg /* NOTE: 'values' is RGBA format! */ 17963464ebd5Sriastradh const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x; 17977117f1b4Smrg GLubyte *dst = (GLubyte *) values; 17987117f1b4Smrg GLuint i; 17997117f1b4Smrg ASSERT(arb != arb->Wrapped); 18007117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 18017117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 18027117f1b4Smrg arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values); 18037117f1b4Smrg /* second, fill in alpha values from this buffer! */ 18047117f1b4Smrg for (i = 0; i < count; i++) { 18057117f1b4Smrg dst[i * 4 + 3] = src[i]; 18067117f1b4Smrg } 18077117f1b4Smrg} 18087117f1b4Smrg 18097117f1b4Smrg 18107117f1b4Smrgstatic void 18113464ebd5Sriastradhget_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 18127117f1b4Smrg const GLint x[], const GLint y[], void *values) 18137117f1b4Smrg{ 18147117f1b4Smrg GLubyte *dst = (GLubyte *) values; 18157117f1b4Smrg GLuint i; 18167117f1b4Smrg ASSERT(arb != arb->Wrapped); 18177117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 18187117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 18197117f1b4Smrg arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values); 18207117f1b4Smrg /* second, fill in alpha values from this buffer! */ 18217117f1b4Smrg for (i = 0; i < count; i++) { 18223464ebd5Sriastradh const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 18237117f1b4Smrg dst[i * 4 + 3] = *src; 18247117f1b4Smrg } 18257117f1b4Smrg} 18267117f1b4Smrg 18277117f1b4Smrg 18287117f1b4Smrgstatic void 18293464ebd5Sriastradhput_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 18307117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 18317117f1b4Smrg{ 18327117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 18333464ebd5Sriastradh GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 18347117f1b4Smrg GLuint i; 18357117f1b4Smrg ASSERT(arb != arb->Wrapped); 18367117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 18377117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 18387117f1b4Smrg arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask); 18397117f1b4Smrg /* second, store alpha in our buffer */ 18407117f1b4Smrg for (i = 0; i < count; i++) { 18417117f1b4Smrg if (!mask || mask[i]) { 18427117f1b4Smrg dst[i] = src[i * 4 + 3]; 18437117f1b4Smrg } 18447117f1b4Smrg } 18457117f1b4Smrg} 18467117f1b4Smrg 18477117f1b4Smrg 18487117f1b4Smrgstatic void 18493464ebd5Sriastradhput_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 18507117f1b4Smrg GLint x, GLint y, const void *values, const GLubyte *mask) 18517117f1b4Smrg{ 18527117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 18533464ebd5Sriastradh GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 18547117f1b4Smrg GLuint i; 18557117f1b4Smrg ASSERT(arb != arb->Wrapped); 18567117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 18577117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 18587117f1b4Smrg arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask); 18597117f1b4Smrg /* second, store alpha in our buffer */ 18607117f1b4Smrg for (i = 0; i < count; i++) { 18617117f1b4Smrg if (!mask || mask[i]) { 18627117f1b4Smrg dst[i] = src[i * 4 + 3]; 18637117f1b4Smrg } 18647117f1b4Smrg } 18657117f1b4Smrg} 18667117f1b4Smrg 18677117f1b4Smrg 18687117f1b4Smrgstatic void 18693464ebd5Sriastradhput_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 18707117f1b4Smrg GLint x, GLint y, const void *value, const GLubyte *mask) 18717117f1b4Smrg{ 18727117f1b4Smrg const GLubyte val = ((const GLubyte *) value)[3]; 18733464ebd5Sriastradh GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 18747117f1b4Smrg ASSERT(arb != arb->Wrapped); 18757117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 18767117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 18777117f1b4Smrg arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask); 18787117f1b4Smrg /* second, store alpha in our buffer */ 18797117f1b4Smrg if (mask) { 18807117f1b4Smrg GLuint i; 18817117f1b4Smrg for (i = 0; i < count; i++) { 18827117f1b4Smrg if (mask[i]) { 18837117f1b4Smrg dst[i] = val; 18847117f1b4Smrg } 18857117f1b4Smrg } 18867117f1b4Smrg } 18877117f1b4Smrg else { 1888cdc920a0Smrg memset(dst, val, count); 18897117f1b4Smrg } 18907117f1b4Smrg} 18917117f1b4Smrg 18927117f1b4Smrg 18937117f1b4Smrgstatic void 18943464ebd5Sriastradhput_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 18957117f1b4Smrg const GLint x[], const GLint y[], 18967117f1b4Smrg const void *values, const GLubyte *mask) 18977117f1b4Smrg{ 18987117f1b4Smrg const GLubyte *src = (const GLubyte *) values; 18997117f1b4Smrg GLuint i; 19007117f1b4Smrg ASSERT(arb != arb->Wrapped); 19017117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 19027117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 19037117f1b4Smrg arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask); 19047117f1b4Smrg /* second, store alpha in our buffer */ 19057117f1b4Smrg for (i = 0; i < count; i++) { 19067117f1b4Smrg if (!mask || mask[i]) { 19073464ebd5Sriastradh GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 19087117f1b4Smrg *dst = src[i * 4 + 3]; 19097117f1b4Smrg } 19107117f1b4Smrg } 19117117f1b4Smrg} 19127117f1b4Smrg 19137117f1b4Smrg 19147117f1b4Smrgstatic void 19153464ebd5Sriastradhput_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 19167117f1b4Smrg GLuint count, const GLint x[], const GLint y[], 19177117f1b4Smrg const void *value, const GLubyte *mask) 19187117f1b4Smrg{ 19197117f1b4Smrg const GLubyte val = ((const GLubyte *) value)[3]; 19207117f1b4Smrg GLuint i; 19217117f1b4Smrg ASSERT(arb != arb->Wrapped); 19227117f1b4Smrg ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 19237117f1b4Smrg /* first, pass the call to the wrapped RGB buffer */ 19247117f1b4Smrg arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask); 19257117f1b4Smrg /* second, store alpha in our buffer */ 19267117f1b4Smrg for (i = 0; i < count; i++) { 19277117f1b4Smrg if (!mask || mask[i]) { 19283464ebd5Sriastradh GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 19297117f1b4Smrg *dst = val; 19307117f1b4Smrg } 19317117f1b4Smrg } 19327117f1b4Smrg} 19337117f1b4Smrg 19347117f1b4Smrg 19357117f1b4Smrgstatic void 19367117f1b4Smrgcopy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) 19377117f1b4Smrg{ 19384a49301eSmrg ASSERT(dst->Format == MESA_FORMAT_A8); 19394a49301eSmrg ASSERT(src->Format == MESA_FORMAT_A8); 19407117f1b4Smrg ASSERT(dst->Width == src->Width); 19417117f1b4Smrg ASSERT(dst->Height == src->Height); 19423464ebd5Sriastradh ASSERT(dst->RowStride == src->RowStride); 19437117f1b4Smrg 19443464ebd5Sriastradh memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte)); 19457117f1b4Smrg} 19467117f1b4Smrg 19477117f1b4Smrg 19487117f1b4Smrg/**********************************************************************/ 19497117f1b4Smrg/**********************************************************************/ 19507117f1b4Smrg/**********************************************************************/ 19517117f1b4Smrg 19527117f1b4Smrg 19537117f1b4Smrg/** 19547117f1b4Smrg * Default GetPointer routine. Always return NULL to indicate that 19557117f1b4Smrg * direct buffer access is not supported. 19567117f1b4Smrg */ 19577117f1b4Smrgstatic void * 19583464ebd5Sriastradhnop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 19597117f1b4Smrg{ 19607117f1b4Smrg return NULL; 19617117f1b4Smrg} 19627117f1b4Smrg 19637117f1b4Smrg 19647117f1b4Smrg/** 19657117f1b4Smrg * Initialize the fields of a gl_renderbuffer to default values. 19667117f1b4Smrg */ 19677117f1b4Smrgvoid 19687117f1b4Smrg_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 19697117f1b4Smrg{ 19707117f1b4Smrg _glthread_INIT_MUTEX(rb->Mutex); 19717117f1b4Smrg 19727117f1b4Smrg rb->ClassID = 0; 19737117f1b4Smrg rb->Name = name; 19747117f1b4Smrg rb->RefCount = 0; 19757117f1b4Smrg rb->Delete = _mesa_delete_renderbuffer; 19767117f1b4Smrg 19777117f1b4Smrg /* The rest of these should be set later by the caller of this function or 19787117f1b4Smrg * the AllocStorage method: 19797117f1b4Smrg */ 19807117f1b4Smrg rb->AllocStorage = NULL; 19817117f1b4Smrg 19827117f1b4Smrg rb->Width = 0; 19837117f1b4Smrg rb->Height = 0; 19847117f1b4Smrg rb->InternalFormat = GL_NONE; 19854a49301eSmrg rb->Format = MESA_FORMAT_NONE; 19864a49301eSmrg 19877117f1b4Smrg rb->DataType = GL_NONE; 19887117f1b4Smrg rb->Data = NULL; 19897117f1b4Smrg 19907117f1b4Smrg /* Point back to ourself so that we don't have to check for Wrapped==NULL 19917117f1b4Smrg * all over the drivers. 19927117f1b4Smrg */ 19937117f1b4Smrg rb->Wrapped = rb; 19947117f1b4Smrg 19957117f1b4Smrg rb->GetPointer = nop_get_pointer; 19967117f1b4Smrg rb->GetRow = NULL; 19977117f1b4Smrg rb->GetValues = NULL; 19987117f1b4Smrg rb->PutRow = NULL; 19997117f1b4Smrg rb->PutRowRGB = NULL; 20007117f1b4Smrg rb->PutMonoRow = NULL; 20017117f1b4Smrg rb->PutValues = NULL; 20027117f1b4Smrg rb->PutMonoValues = NULL; 20037117f1b4Smrg} 20047117f1b4Smrg 20057117f1b4Smrg 20067117f1b4Smrg/** 20077117f1b4Smrg * Allocate a new gl_renderbuffer object. This can be used for user-created 20087117f1b4Smrg * renderbuffers or window-system renderbuffers. 20097117f1b4Smrg */ 20107117f1b4Smrgstruct gl_renderbuffer * 20113464ebd5Sriastradh_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name) 20127117f1b4Smrg{ 20137117f1b4Smrg struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 20147117f1b4Smrg if (rb) { 20157117f1b4Smrg _mesa_init_renderbuffer(rb, name); 20167117f1b4Smrg } 20177117f1b4Smrg return rb; 20187117f1b4Smrg} 20197117f1b4Smrg 20207117f1b4Smrg 20217117f1b4Smrg/** 20227117f1b4Smrg * Delete a gl_framebuffer. 20237117f1b4Smrg * This is the default function for renderbuffer->Delete(). 20247117f1b4Smrg */ 20257117f1b4Smrgvoid 20267117f1b4Smrg_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 20277117f1b4Smrg{ 20287117f1b4Smrg if (rb->Data) { 2029cdc920a0Smrg free(rb->Data); 20307117f1b4Smrg } 2031cdc920a0Smrg free(rb); 20327117f1b4Smrg} 20337117f1b4Smrg 20347117f1b4Smrg 20357117f1b4Smrg/** 20367117f1b4Smrg * Allocate a software-based renderbuffer. This is called via the 20377117f1b4Smrg * ctx->Driver.NewRenderbuffer() function when the user creates a new 20387117f1b4Smrg * renderbuffer. 20397117f1b4Smrg * This would not be used for hardware-based renderbuffers. 20407117f1b4Smrg */ 20417117f1b4Smrgstruct gl_renderbuffer * 20423464ebd5Sriastradh_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) 20437117f1b4Smrg{ 20447117f1b4Smrg struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 20457117f1b4Smrg if (rb) { 20467117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 20477117f1b4Smrg /* Normally, one would setup the PutRow, GetRow, etc functions here. 20487117f1b4Smrg * But we're doing that in the _mesa_soft_renderbuffer_storage() function 20497117f1b4Smrg * instead. 20507117f1b4Smrg */ 20517117f1b4Smrg } 20527117f1b4Smrg return rb; 20537117f1b4Smrg} 20547117f1b4Smrg 20557117f1b4Smrg 20567117f1b4Smrg/** 20577117f1b4Smrg * Add software-based color renderbuffers to the given framebuffer. 20587117f1b4Smrg * This is a helper routine for device drivers when creating a 20597117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 20607117f1b4Smrg * Once this function is called, you can basically forget about this 20617117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 20627117f1b4Smrg * rendering! 20637117f1b4Smrg */ 20647117f1b4SmrgGLboolean 20653464ebd5Sriastradh_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 20667117f1b4Smrg GLuint rgbBits, GLuint alphaBits, 20677117f1b4Smrg GLboolean frontLeft, GLboolean backLeft, 20687117f1b4Smrg GLboolean frontRight, GLboolean backRight) 20697117f1b4Smrg{ 20703464ebd5Sriastradh gl_buffer_index b; 20717117f1b4Smrg 20727117f1b4Smrg if (rgbBits > 16 || alphaBits > 16) { 20737117f1b4Smrg _mesa_problem(ctx, 20747117f1b4Smrg "Unsupported bit depth in _mesa_add_color_renderbuffers"); 20757117f1b4Smrg return GL_FALSE; 20767117f1b4Smrg } 20777117f1b4Smrg 20787117f1b4Smrg assert(MAX_COLOR_ATTACHMENTS >= 4); 20797117f1b4Smrg 20807117f1b4Smrg for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 20817117f1b4Smrg struct gl_renderbuffer *rb; 20827117f1b4Smrg 20837117f1b4Smrg if (b == BUFFER_FRONT_LEFT && !frontLeft) 20847117f1b4Smrg continue; 20857117f1b4Smrg else if (b == BUFFER_BACK_LEFT && !backLeft) 20867117f1b4Smrg continue; 20877117f1b4Smrg else if (b == BUFFER_FRONT_RIGHT && !frontRight) 20887117f1b4Smrg continue; 20897117f1b4Smrg else if (b == BUFFER_BACK_RIGHT && !backRight) 20907117f1b4Smrg continue; 20917117f1b4Smrg 20927117f1b4Smrg assert(fb->Attachment[b].Renderbuffer == NULL); 20937117f1b4Smrg 20947117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 20957117f1b4Smrg if (!rb) { 20967117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 20977117f1b4Smrg return GL_FALSE; 20987117f1b4Smrg } 20997117f1b4Smrg 21007117f1b4Smrg if (rgbBits <= 8) { 21017117f1b4Smrg if (alphaBits) 21024a49301eSmrg rb->Format = MESA_FORMAT_RGBA8888; 21037117f1b4Smrg else 21044a49301eSmrg rb->Format = MESA_FORMAT_RGB888; 21057117f1b4Smrg } 21067117f1b4Smrg else { 21077117f1b4Smrg assert(rgbBits <= 16); 21084a49301eSmrg rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/ 21097117f1b4Smrg } 21104a49301eSmrg rb->InternalFormat = GL_RGBA; 21117117f1b4Smrg 21127117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 21137117f1b4Smrg _mesa_add_renderbuffer(fb, b, rb); 21147117f1b4Smrg } 21157117f1b4Smrg 21167117f1b4Smrg return GL_TRUE; 21177117f1b4Smrg} 21187117f1b4Smrg 21197117f1b4Smrg 21207117f1b4Smrg/** 21217117f1b4Smrg * Add software-based alpha renderbuffers to the given framebuffer. 21227117f1b4Smrg * This is a helper routine for device drivers when creating a 21237117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 21247117f1b4Smrg * Once this function is called, you can basically forget about this 21257117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 21267117f1b4Smrg * rendering! 21277117f1b4Smrg */ 21287117f1b4SmrgGLboolean 21293464ebd5Sriastradh_mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 21307117f1b4Smrg GLuint alphaBits, 21317117f1b4Smrg GLboolean frontLeft, GLboolean backLeft, 21327117f1b4Smrg GLboolean frontRight, GLboolean backRight) 21337117f1b4Smrg{ 21343464ebd5Sriastradh gl_buffer_index b; 21357117f1b4Smrg 21367117f1b4Smrg /* for window system framebuffers only! */ 21377117f1b4Smrg assert(fb->Name == 0); 21387117f1b4Smrg 21397117f1b4Smrg if (alphaBits > 8) { 21407117f1b4Smrg _mesa_problem(ctx, 21417117f1b4Smrg "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 21427117f1b4Smrg return GL_FALSE; 21437117f1b4Smrg } 21447117f1b4Smrg 21457117f1b4Smrg assert(MAX_COLOR_ATTACHMENTS >= 4); 21467117f1b4Smrg 21477117f1b4Smrg /* Wrap each of the RGB color buffers with an alpha renderbuffer. 21487117f1b4Smrg */ 21497117f1b4Smrg for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 21507117f1b4Smrg struct gl_renderbuffer *arb; 21517117f1b4Smrg 21527117f1b4Smrg if (b == BUFFER_FRONT_LEFT && !frontLeft) 21537117f1b4Smrg continue; 21547117f1b4Smrg else if (b == BUFFER_BACK_LEFT && !backLeft) 21557117f1b4Smrg continue; 21567117f1b4Smrg else if (b == BUFFER_FRONT_RIGHT && !frontRight) 21577117f1b4Smrg continue; 21587117f1b4Smrg else if (b == BUFFER_BACK_RIGHT && !backRight) 21597117f1b4Smrg continue; 21607117f1b4Smrg 21617117f1b4Smrg /* the RGB buffer to wrap must already exist!! */ 21627117f1b4Smrg assert(fb->Attachment[b].Renderbuffer); 21637117f1b4Smrg 21647117f1b4Smrg /* only GLubyte supported for now */ 21657117f1b4Smrg assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 21667117f1b4Smrg 21677117f1b4Smrg /* allocate alpha renderbuffer */ 21687117f1b4Smrg arb = _mesa_new_renderbuffer(ctx, 0); 21697117f1b4Smrg if (!arb) { 21707117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 21717117f1b4Smrg return GL_FALSE; 21727117f1b4Smrg } 21737117f1b4Smrg 21747117f1b4Smrg /* wrap the alpha renderbuffer around the RGB renderbuffer */ 21757117f1b4Smrg arb->Wrapped = fb->Attachment[b].Renderbuffer; 21767117f1b4Smrg 21777117f1b4Smrg /* Set up my alphabuffer fields and plug in my functions. 21787117f1b4Smrg * The functions will put/get the alpha values from/to RGBA arrays 21797117f1b4Smrg * and then call the wrapped buffer's functions to handle the RGB 21807117f1b4Smrg * values. 21817117f1b4Smrg */ 21827117f1b4Smrg arb->InternalFormat = arb->Wrapped->InternalFormat; 21834a49301eSmrg arb->Format = MESA_FORMAT_A8; 21847117f1b4Smrg arb->DataType = arb->Wrapped->DataType; 21857117f1b4Smrg arb->AllocStorage = alloc_storage_alpha8; 21867117f1b4Smrg arb->Delete = delete_renderbuffer_alpha8; 21877117f1b4Smrg arb->GetPointer = get_pointer_alpha8; 21887117f1b4Smrg arb->GetRow = get_row_alpha8; 21897117f1b4Smrg arb->GetValues = get_values_alpha8; 21907117f1b4Smrg arb->PutRow = put_row_alpha8; 21917117f1b4Smrg arb->PutRowRGB = put_row_rgb_alpha8; 21927117f1b4Smrg arb->PutMonoRow = put_mono_row_alpha8; 21937117f1b4Smrg arb->PutValues = put_values_alpha8; 21947117f1b4Smrg arb->PutMonoValues = put_mono_values_alpha8; 21957117f1b4Smrg 21967117f1b4Smrg /* clear the pointer to avoid assertion/sanity check failure later */ 21977117f1b4Smrg fb->Attachment[b].Renderbuffer = NULL; 21987117f1b4Smrg 21997117f1b4Smrg /* plug the alpha renderbuffer into the colorbuffer attachment */ 22007117f1b4Smrg _mesa_add_renderbuffer(fb, b, arb); 22017117f1b4Smrg } 22027117f1b4Smrg 22037117f1b4Smrg return GL_TRUE; 22047117f1b4Smrg} 22057117f1b4Smrg 22067117f1b4Smrg 22077117f1b4Smrg/** 22087117f1b4Smrg * For framebuffers that use a software alpha channel wrapper 22097117f1b4Smrg * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers, 22107117f1b4Smrg * copy the back buffer alpha channel into the front buffer alpha channel. 22117117f1b4Smrg */ 22127117f1b4Smrgvoid 22133464ebd5Sriastradh_mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb) 22147117f1b4Smrg{ 22157117f1b4Smrg if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && 22167117f1b4Smrg fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) 22177117f1b4Smrg copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer, 22187117f1b4Smrg fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); 22197117f1b4Smrg 22207117f1b4Smrg 22217117f1b4Smrg if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && 22227117f1b4Smrg fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) 22237117f1b4Smrg copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer, 22247117f1b4Smrg fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); 22257117f1b4Smrg} 22267117f1b4Smrg 22277117f1b4Smrg 22287117f1b4Smrg/** 22297117f1b4Smrg * Add a software-based depth renderbuffer to the given framebuffer. 22307117f1b4Smrg * This is a helper routine for device drivers when creating a 22317117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 22327117f1b4Smrg * Once this function is called, you can basically forget about this 22337117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 22347117f1b4Smrg * rendering! 22357117f1b4Smrg */ 22367117f1b4SmrgGLboolean 22373464ebd5Sriastradh_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 22387117f1b4Smrg GLuint depthBits) 22397117f1b4Smrg{ 22407117f1b4Smrg struct gl_renderbuffer *rb; 22417117f1b4Smrg 22427117f1b4Smrg if (depthBits > 32) { 22437117f1b4Smrg _mesa_problem(ctx, 22447117f1b4Smrg "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 22457117f1b4Smrg return GL_FALSE; 22467117f1b4Smrg } 22477117f1b4Smrg 22487117f1b4Smrg assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 22497117f1b4Smrg 22507117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 22517117f1b4Smrg if (!rb) { 22527117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 22537117f1b4Smrg return GL_FALSE; 22547117f1b4Smrg } 22557117f1b4Smrg 22567117f1b4Smrg if (depthBits <= 16) { 22574a49301eSmrg rb->Format = MESA_FORMAT_Z16; 22584a49301eSmrg rb->InternalFormat = GL_DEPTH_COMPONENT16; 22597117f1b4Smrg } 22607117f1b4Smrg else if (depthBits <= 24) { 22614a49301eSmrg rb->Format = MESA_FORMAT_X8_Z24; 22624a49301eSmrg rb->InternalFormat = GL_DEPTH_COMPONENT24; 22637117f1b4Smrg } 22647117f1b4Smrg else { 22654a49301eSmrg rb->Format = MESA_FORMAT_Z32; 22664a49301eSmrg rb->InternalFormat = GL_DEPTH_COMPONENT32; 22677117f1b4Smrg } 22687117f1b4Smrg 22697117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 22707117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 22717117f1b4Smrg 22727117f1b4Smrg return GL_TRUE; 22737117f1b4Smrg} 22747117f1b4Smrg 22757117f1b4Smrg 22767117f1b4Smrg/** 22777117f1b4Smrg * Add a software-based stencil renderbuffer to the given framebuffer. 22787117f1b4Smrg * This is a helper routine for device drivers when creating a 22797117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 22807117f1b4Smrg * Once this function is called, you can basically forget about this 22817117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 22827117f1b4Smrg * rendering! 22837117f1b4Smrg */ 22847117f1b4SmrgGLboolean 22853464ebd5Sriastradh_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 22867117f1b4Smrg GLuint stencilBits) 22877117f1b4Smrg{ 22887117f1b4Smrg struct gl_renderbuffer *rb; 22897117f1b4Smrg 22907117f1b4Smrg if (stencilBits > 16) { 22917117f1b4Smrg _mesa_problem(ctx, 22927117f1b4Smrg "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 22937117f1b4Smrg return GL_FALSE; 22947117f1b4Smrg } 22957117f1b4Smrg 22967117f1b4Smrg assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 22977117f1b4Smrg 22987117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 22997117f1b4Smrg if (!rb) { 23007117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 23017117f1b4Smrg return GL_FALSE; 23027117f1b4Smrg } 23037117f1b4Smrg 23044a49301eSmrg assert(stencilBits <= 8); 23054a49301eSmrg rb->Format = MESA_FORMAT_S8; 23064a49301eSmrg rb->InternalFormat = GL_STENCIL_INDEX8; 23077117f1b4Smrg 23087117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 23097117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 23107117f1b4Smrg 23117117f1b4Smrg return GL_TRUE; 23127117f1b4Smrg} 23137117f1b4Smrg 23147117f1b4Smrg 23157117f1b4Smrg/** 23167117f1b4Smrg * Add a software-based accumulation renderbuffer to the given framebuffer. 23177117f1b4Smrg * This is a helper routine for device drivers when creating a 23187117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 23197117f1b4Smrg * Once this function is called, you can basically forget about this 23207117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 23217117f1b4Smrg * rendering! 23227117f1b4Smrg */ 23237117f1b4SmrgGLboolean 23243464ebd5Sriastradh_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 23257117f1b4Smrg GLuint redBits, GLuint greenBits, 23267117f1b4Smrg GLuint blueBits, GLuint alphaBits) 23277117f1b4Smrg{ 23287117f1b4Smrg struct gl_renderbuffer *rb; 23297117f1b4Smrg 23307117f1b4Smrg if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 23317117f1b4Smrg _mesa_problem(ctx, 23327117f1b4Smrg "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 23337117f1b4Smrg return GL_FALSE; 23347117f1b4Smrg } 23357117f1b4Smrg 23367117f1b4Smrg assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 23377117f1b4Smrg 23387117f1b4Smrg rb = _mesa_new_renderbuffer(ctx, 0); 23397117f1b4Smrg if (!rb) { 23407117f1b4Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 23417117f1b4Smrg return GL_FALSE; 23427117f1b4Smrg } 23437117f1b4Smrg 23444a49301eSmrg rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 23453464ebd5Sriastradh rb->InternalFormat = GL_RGBA16_SNORM; 23467117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 23477117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 23487117f1b4Smrg 23497117f1b4Smrg return GL_TRUE; 23507117f1b4Smrg} 23517117f1b4Smrg 23527117f1b4Smrg 23537117f1b4Smrg 23547117f1b4Smrg/** 23553464ebd5Sriastradh * Add a software-based aux renderbuffer to the given framebuffer. 23567117f1b4Smrg * This is a helper routine for device drivers when creating a 23577117f1b4Smrg * window system framebuffer (not a user-created render/framebuffer). 23587117f1b4Smrg * Once this function is called, you can basically forget about this 23597117f1b4Smrg * renderbuffer; core Mesa will handle all the buffer management and 23607117f1b4Smrg * rendering! 23617117f1b4Smrg * 23627117f1b4Smrg * NOTE: color-index aux buffers not supported. 23637117f1b4Smrg */ 23647117f1b4SmrgGLboolean 23653464ebd5Sriastradh_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 23667117f1b4Smrg GLuint colorBits, GLuint numBuffers) 23677117f1b4Smrg{ 23687117f1b4Smrg GLuint i; 23697117f1b4Smrg 23707117f1b4Smrg if (colorBits > 16) { 23717117f1b4Smrg _mesa_problem(ctx, 23727117f1b4Smrg "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 23737117f1b4Smrg return GL_FALSE; 23747117f1b4Smrg } 23757117f1b4Smrg 23764a49301eSmrg assert(numBuffers <= MAX_AUX_BUFFERS); 23777117f1b4Smrg 23787117f1b4Smrg for (i = 0; i < numBuffers; i++) { 23797117f1b4Smrg struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 23807117f1b4Smrg 23817117f1b4Smrg assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 23827117f1b4Smrg 23837117f1b4Smrg if (!rb) { 23843464ebd5Sriastradh _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); 23857117f1b4Smrg return GL_FALSE; 23867117f1b4Smrg } 23877117f1b4Smrg 23884a49301eSmrg assert (colorBits <= 8); 23894a49301eSmrg rb->Format = MESA_FORMAT_RGBA8888; 23904a49301eSmrg rb->InternalFormat = GL_RGBA; 23917117f1b4Smrg 23927117f1b4Smrg rb->AllocStorage = _mesa_soft_renderbuffer_storage; 23937117f1b4Smrg _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 23947117f1b4Smrg } 23957117f1b4Smrg return GL_TRUE; 23967117f1b4Smrg} 23977117f1b4Smrg 23987117f1b4Smrg 23997117f1b4Smrg/** 24007117f1b4Smrg * Create/attach software-based renderbuffers to the given framebuffer. 24017117f1b4Smrg * This is a helper routine for device drivers. Drivers can just as well 24027117f1b4Smrg * call the individual _mesa_add_*_renderbuffer() routines directly. 24037117f1b4Smrg */ 24047117f1b4Smrgvoid 24057117f1b4Smrg_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 24067117f1b4Smrg GLboolean color, 24077117f1b4Smrg GLboolean depth, 24087117f1b4Smrg GLboolean stencil, 24097117f1b4Smrg GLboolean accum, 24107117f1b4Smrg GLboolean alpha, 24117117f1b4Smrg GLboolean aux) 24127117f1b4Smrg{ 24137117f1b4Smrg GLboolean frontLeft = GL_TRUE; 24147117f1b4Smrg GLboolean backLeft = fb->Visual.doubleBufferMode; 24157117f1b4Smrg GLboolean frontRight = fb->Visual.stereoMode; 24167117f1b4Smrg GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 24177117f1b4Smrg 24187117f1b4Smrg if (color) { 2419cdc920a0Smrg assert(fb->Visual.redBits == fb->Visual.greenBits); 2420cdc920a0Smrg assert(fb->Visual.redBits == fb->Visual.blueBits); 2421cdc920a0Smrg _mesa_add_color_renderbuffers(NULL, fb, 2422cdc920a0Smrg fb->Visual.redBits, 2423cdc920a0Smrg fb->Visual.alphaBits, 2424cdc920a0Smrg frontLeft, backLeft, 2425cdc920a0Smrg frontRight, backRight); 24267117f1b4Smrg } 24277117f1b4Smrg 24287117f1b4Smrg if (depth) { 24297117f1b4Smrg assert(fb->Visual.depthBits > 0); 24307117f1b4Smrg _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 24317117f1b4Smrg } 24327117f1b4Smrg 24337117f1b4Smrg if (stencil) { 24347117f1b4Smrg assert(fb->Visual.stencilBits > 0); 24357117f1b4Smrg _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 24367117f1b4Smrg } 24377117f1b4Smrg 24387117f1b4Smrg if (accum) { 24397117f1b4Smrg assert(fb->Visual.accumRedBits > 0); 24407117f1b4Smrg assert(fb->Visual.accumGreenBits > 0); 24417117f1b4Smrg assert(fb->Visual.accumBlueBits > 0); 24427117f1b4Smrg _mesa_add_accum_renderbuffer(NULL, fb, 24437117f1b4Smrg fb->Visual.accumRedBits, 24447117f1b4Smrg fb->Visual.accumGreenBits, 24457117f1b4Smrg fb->Visual.accumBlueBits, 24467117f1b4Smrg fb->Visual.accumAlphaBits); 24477117f1b4Smrg } 24487117f1b4Smrg 24497117f1b4Smrg if (aux) { 24507117f1b4Smrg assert(fb->Visual.numAuxBuffers > 0); 24517117f1b4Smrg _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 24527117f1b4Smrg fb->Visual.numAuxBuffers); 24537117f1b4Smrg } 24547117f1b4Smrg 24557117f1b4Smrg if (alpha) { 24567117f1b4Smrg assert(fb->Visual.alphaBits > 0); 24577117f1b4Smrg _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 24587117f1b4Smrg frontLeft, backLeft, 24597117f1b4Smrg frontRight, backRight); 24607117f1b4Smrg } 24617117f1b4Smrg 24627117f1b4Smrg#if 0 24637117f1b4Smrg if (multisample) { 24647117f1b4Smrg /* maybe someday */ 24657117f1b4Smrg } 24667117f1b4Smrg#endif 24677117f1b4Smrg} 24687117f1b4Smrg 24697117f1b4Smrg 24707117f1b4Smrg/** 24717117f1b4Smrg * Attach a renderbuffer to a framebuffer. 24723464ebd5Sriastradh * \param bufferName one of the BUFFER_x tokens 24737117f1b4Smrg */ 24747117f1b4Smrgvoid 24757117f1b4Smrg_mesa_add_renderbuffer(struct gl_framebuffer *fb, 24763464ebd5Sriastradh gl_buffer_index bufferName, struct gl_renderbuffer *rb) 24777117f1b4Smrg{ 24787117f1b4Smrg assert(fb); 24797117f1b4Smrg assert(rb); 24807117f1b4Smrg assert(bufferName < BUFFER_COUNT); 24817117f1b4Smrg 24827117f1b4Smrg /* There should be no previous renderbuffer on this attachment point, 24837117f1b4Smrg * with the exception of depth/stencil since the same renderbuffer may 24847117f1b4Smrg * be used for both. 24857117f1b4Smrg */ 24867117f1b4Smrg assert(bufferName == BUFFER_DEPTH || 24877117f1b4Smrg bufferName == BUFFER_STENCIL || 24887117f1b4Smrg fb->Attachment[bufferName].Renderbuffer == NULL); 24897117f1b4Smrg 24907117f1b4Smrg /* winsys vs. user-created buffer cross check */ 24917117f1b4Smrg if (fb->Name) { 24927117f1b4Smrg assert(rb->Name); 24937117f1b4Smrg } 24947117f1b4Smrg else { 24957117f1b4Smrg assert(!rb->Name); 24967117f1b4Smrg } 24977117f1b4Smrg 24987117f1b4Smrg fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 24997117f1b4Smrg fb->Attachment[bufferName].Complete = GL_TRUE; 25007117f1b4Smrg _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); 25017117f1b4Smrg} 25027117f1b4Smrg 25037117f1b4Smrg 25047117f1b4Smrg/** 25057117f1b4Smrg * Remove the named renderbuffer from the given framebuffer. 25063464ebd5Sriastradh * \param bufferName one of the BUFFER_x tokens 25077117f1b4Smrg */ 25087117f1b4Smrgvoid 25093464ebd5Sriastradh_mesa_remove_renderbuffer(struct gl_framebuffer *fb, 25103464ebd5Sriastradh gl_buffer_index bufferName) 25117117f1b4Smrg{ 25127117f1b4Smrg struct gl_renderbuffer *rb; 25137117f1b4Smrg 25147117f1b4Smrg assert(bufferName < BUFFER_COUNT); 25157117f1b4Smrg 25167117f1b4Smrg rb = fb->Attachment[bufferName].Renderbuffer; 25177117f1b4Smrg if (!rb) 25187117f1b4Smrg return; 25197117f1b4Smrg 25207117f1b4Smrg _mesa_reference_renderbuffer(&rb, NULL); 25217117f1b4Smrg 25227117f1b4Smrg fb->Attachment[bufferName].Renderbuffer = NULL; 25237117f1b4Smrg} 25247117f1b4Smrg 25257117f1b4Smrg 25267117f1b4Smrg/** 25277117f1b4Smrg * Set *ptr to point to rb. If *ptr points to another renderbuffer, 25287117f1b4Smrg * dereference that buffer first. The new renderbuffer's refcount will 25297117f1b4Smrg * be incremented. The old renderbuffer's refcount will be decremented. 25307117f1b4Smrg */ 25317117f1b4Smrgvoid 25327117f1b4Smrg_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, 25337117f1b4Smrg struct gl_renderbuffer *rb) 25347117f1b4Smrg{ 25357117f1b4Smrg assert(ptr); 25367117f1b4Smrg if (*ptr == rb) { 25377117f1b4Smrg /* no change */ 25387117f1b4Smrg return; 25397117f1b4Smrg } 25407117f1b4Smrg 25417117f1b4Smrg if (*ptr) { 25427117f1b4Smrg /* Unreference the old renderbuffer */ 25437117f1b4Smrg GLboolean deleteFlag = GL_FALSE; 25447117f1b4Smrg struct gl_renderbuffer *oldRb = *ptr; 25457117f1b4Smrg 25467117f1b4Smrg _glthread_LOCK_MUTEX(oldRb->Mutex); 25477117f1b4Smrg ASSERT(oldRb->RefCount > 0); 25487117f1b4Smrg oldRb->RefCount--; 25497117f1b4Smrg /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/ 25507117f1b4Smrg deleteFlag = (oldRb->RefCount == 0); 25517117f1b4Smrg _glthread_UNLOCK_MUTEX(oldRb->Mutex); 25527117f1b4Smrg 25537117f1b4Smrg if (deleteFlag) { 25547117f1b4Smrg oldRb->Delete(oldRb); 25557117f1b4Smrg } 25567117f1b4Smrg 25577117f1b4Smrg *ptr = NULL; 25587117f1b4Smrg } 25597117f1b4Smrg assert(!*ptr); 25607117f1b4Smrg 25617117f1b4Smrg if (rb) { 25627117f1b4Smrg /* reference new renderbuffer */ 25637117f1b4Smrg _glthread_LOCK_MUTEX(rb->Mutex); 25647117f1b4Smrg rb->RefCount++; 25657117f1b4Smrg /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/ 25667117f1b4Smrg _glthread_UNLOCK_MUTEX(rb->Mutex); 25677117f1b4Smrg *ptr = rb; 25687117f1b4Smrg } 25697117f1b4Smrg} 2570