s_renderbuffer.c revision 0c1862851f27c428a18ba5509636efcc2f0084f8
1ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/* 2ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Mesa 3-D graphics library 3ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Version: 6.5 4ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 5ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 7ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 8ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * copy of this software and associated documentation files (the "Software"), 9ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * to deal in the Software without restriction, including without limitation 10ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 12ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Software is furnished to do so, subject to the following conditions: 13ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 14ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * The above copyright notice and this permission notice shall be included 15ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * in all copies or substantial portions of the Software. 16ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 17ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 24ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 25ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 26ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 27379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul * Functions for allocating/managing software-based renderbuffers. 28ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Also, routines for reading/writing software-based renderbuffer data as 29ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * ubytes, ushorts, uints, etc. 30ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 31ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 32ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 33379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/glheader.h" 34379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/imports.h" 35379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/context.h" 36379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/fbobject.h" 37379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/formats.h" 38379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/mtypes.h" 39379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "main/renderbuffer.h" 400c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul#include "swrast/s_context.h" 41379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul#include "swrast/s_renderbuffer.h" 42ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 43ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 44ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 45ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a software fallback for the gl_renderbuffer->AllocStorage 46ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * function. 47ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Device drivers will typically override this function for the buffers 48ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * which it manages (typically color buffers, Z and stencil). 49ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Other buffers (like software accumulation and aux buffers) which the driver 50ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * doesn't manage can be handled with this function. 51ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 52ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This one multi-purpose function can allocate stencil, depth, accum, color 53ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * or color-index buffers! 54ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 55ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 56ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulsoft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 57ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLenum internalFormat, 58ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint width, GLuint height) 59ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 600c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 610c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul 62ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul switch (internalFormat) { 63ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB: 64ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_R3_G3_B2: 65ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB4: 66ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB5: 67ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB8: 68ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB10: 69ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB12: 70ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB16: 71ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_RGB888; 72ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 73ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA: 74ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA2: 75ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA4: 76ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB5_A1: 77ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA8: 78ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul#if 1 79ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGB10_A2: 80ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA12: 81ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul#endif 82ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (_mesa_little_endian()) 83ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_RGBA8888_REV; 84ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else 85ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_RGBA8888; 86ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 87ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA16: 88ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_RGBA16_SNORM: 89ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* for accum buffer */ 90ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 91ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 92ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_STENCIL_INDEX: 93ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_STENCIL_INDEX1_EXT: 94ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_STENCIL_INDEX4_EXT: 95ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_STENCIL_INDEX8_EXT: 96ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_STENCIL_INDEX16_EXT: 97ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_S8; 98ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 99ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH_COMPONENT: 100ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH_COMPONENT16: 101ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_Z16; 102ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 103ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH_COMPONENT24: 104ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_X8_Z24; 105ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 106ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH_COMPONENT32: 107ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_Z32; 108ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 109ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH_STENCIL_EXT: 110ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul case GL_DEPTH24_STENCIL8_EXT: 111ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Format = MESA_FORMAT_Z24_S8; 112ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul break; 113ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul default: 114ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* unsupported format */ 115ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 116ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 117ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 118ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* free old buffer storage */ 1190c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul if (srb->Buffer) { 1200c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul free(srb->Buffer); 1210c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->Buffer = NULL; 122ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 123ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 1240c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->RowStride = width * _mesa_get_format_bytes(rb->Format); 125ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 126ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (width > 0 && height > 0) { 127ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* allocate new buffer storage */ 1280c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->Buffer = malloc(width * height 1290c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul * _mesa_get_format_bytes(rb->Format)); 130ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 1310c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul if (srb->Buffer == NULL) { 132ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Width = 0; 133ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Height = 0; 134ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 135ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "software renderbuffer allocation (%d x %d x %d)", 136ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul width, height, _mesa_get_format_bytes(rb->Format)); 137ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 138ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 139ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 140ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 141ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Width = width; 142ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->Height = height; 143ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 144ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 145ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (rb->Name == 0 && 146ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul internalFormat == GL_RGBA16_SNORM && 147ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->_BaseFormat == 0) { 148ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* NOTE: This is a special case just for accumulation buffers. 149ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a very limited use case- there's no snorm texturing or 150ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering going on. 151ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 152ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->_BaseFormat = GL_RGBA; 153ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 154ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else { 155ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* the internalFormat should have been error checked long ago */ 156ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul ASSERT(rb->_BaseFormat); 157ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 158ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 159ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 160ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 161ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 162ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 163f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul/** 164f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul * Called via gl_renderbuffer::Delete() 165f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul */ 166f6a3979a0444a14c198c10501e9ff13f24625443Brian Paulstatic void 167f6a3979a0444a14c198c10501e9ff13f24625443Brian Paulsoft_renderbuffer_delete(struct gl_renderbuffer *rb) 168f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul{ 1690c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 1700c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul 1710c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul if (srb->Buffer) { 1720c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul free(srb->Buffer); 1730c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->Buffer = NULL; 174f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul } 1750c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul free(srb); 176f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul} 177f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul 178f6a3979a0444a14c198c10501e9ff13f24625443Brian Paul 179ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulvoid 180379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul_swrast_map_soft_renderbuffer(struct gl_context *ctx, 181379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul struct gl_renderbuffer *rb, 182379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLuint x, GLuint y, GLuint w, GLuint h, 183379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLbitfield mode, 184379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLubyte **out_map, 185379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLint *out_stride) 186ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 1870c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 1880c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul GLubyte *map = srb->Buffer; 189ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul int cpp = _mesa_get_format_bytes(rb->Format); 1901e1b5cb01a10e39d01923e3c7e989c44210950cdBrian Paul int stride = rb->Width * cpp; 191ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 1927a36345f70a0b8ac2d480bb52eb2c74c2be5a978Brian Paul if (!map) { 1937a36345f70a0b8ac2d480bb52eb2c74c2be5a978Brian Paul *out_map = NULL; 1947a36345f70a0b8ac2d480bb52eb2c74c2be5a978Brian Paul *out_stride = 0; 1957a36345f70a0b8ac2d480bb52eb2c74c2be5a978Brian Paul } 196ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 197ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul map += y * stride; 198ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul map += x * cpp; 199ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 200ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul *out_map = map; 201ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul *out_stride = stride; 202ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 203ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 204ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 205ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulvoid 206379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul_swrast_unmap_soft_renderbuffer(struct gl_context *ctx, 207379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul struct gl_renderbuffer *rb) 208ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 209ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 210ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 211ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 212ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 213ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 214ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Allocate a software-based renderbuffer. This is called via the 215ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * ctx->Driver.NewRenderbuffer() function when the user creates a new 216ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer. 217ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This would not be used for hardware-based renderbuffers. 218ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 219ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstruct gl_renderbuffer * 220379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) 221ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 2220c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer); 2230c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul if (srb) { 2240c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul _mesa_init_renderbuffer(&srb->Base, name); 2250c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->Base.AllocStorage = soft_renderbuffer_storage; 2260c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul srb->Base.Delete = soft_renderbuffer_delete; 227ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 2280c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul return &srb->Base; 229ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 230ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 231ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 232ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 233ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Add software-based color renderbuffers to the given framebuffer. 234ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers when creating a 235ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * window system framebuffer (not a user-created render/framebuffer). 236ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Once this function is called, you can basically forget about this 237ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer; core Mesa will handle all the buffer management and 238ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering! 239ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 240ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 241ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Pauladd_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 242ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint rgbBits, GLuint alphaBits, 243ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean frontLeft, GLboolean backLeft, 244ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean frontRight, GLboolean backRight) 245ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 246ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul gl_buffer_index b; 247ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 248ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (rgbBits > 16 || alphaBits > 16) { 249ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_problem(ctx, 250ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "Unsupported bit depth in add_color_renderbuffers"); 251ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 252ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 253ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 254ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(MAX_COLOR_ATTACHMENTS >= 4); 255ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 256ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 257ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul struct gl_renderbuffer *rb; 258ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 259ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (b == BUFFER_FRONT_LEFT && !frontLeft) 260ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul continue; 261ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else if (b == BUFFER_BACK_LEFT && !backLeft) 262ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul continue; 263ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else if (b == BUFFER_FRONT_RIGHT && !frontRight) 264ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul continue; 265ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else if (b == BUFFER_BACK_RIGHT && !backRight) 266ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul continue; 267ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 268ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Attachment[b].Renderbuffer == NULL); 269ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 270f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul rb = ctx->Driver.NewRenderbuffer(ctx, 0); 271ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (!rb) { 272ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 273ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 274ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 275ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 276ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_RGBA; 277ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 278ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 279ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_add_renderbuffer(fb, b, rb); 280ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 281ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 282ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 283ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 284ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 285ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 286ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 287ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Add a software-based depth renderbuffer to the given framebuffer. 288ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers when creating a 289ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * window system framebuffer (not a user-created render/framebuffer). 290ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Once this function is called, you can basically forget about this 291ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer; core Mesa will handle all the buffer management and 292ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering! 293ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 294ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 295ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Pauladd_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 296ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint depthBits) 297ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 298ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul struct gl_renderbuffer *rb; 299ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 300ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (depthBits > 32) { 301ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_problem(ctx, 302ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "Unsupported depthBits in add_depth_renderbuffer"); 303ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 304ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 305ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 306ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 307ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 308f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul rb = _swrast_new_soft_renderbuffer(ctx, 0); 309ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (!rb) { 310ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 311ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 312ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 313ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 314ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (depthBits <= 16) { 315ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_DEPTH_COMPONENT16; 316ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 317ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else if (depthBits <= 24) { 318ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_DEPTH_COMPONENT24; 319ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 320ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul else { 321ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_DEPTH_COMPONENT32; 322ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 323ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 324ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 325ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 326ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 327ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 328ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 329ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 330ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 331ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 332ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Add a software-based stencil renderbuffer to the given framebuffer. 333ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers when creating a 334ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * window system framebuffer (not a user-created render/framebuffer). 335ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Once this function is called, you can basically forget about this 336ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer; core Mesa will handle all the buffer management and 337ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering! 338ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 339ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 340ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Pauladd_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 341ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint stencilBits) 342ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 343ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul struct gl_renderbuffer *rb; 344ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 345ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (stencilBits > 16) { 346ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_problem(ctx, 347ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "Unsupported stencilBits in add_stencil_renderbuffer"); 348ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 349ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 350ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 351ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 352ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 353f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul rb = _swrast_new_soft_renderbuffer(ctx, 0); 354ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (!rb) { 355ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 356ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 357ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 358ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 359ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(stencilBits <= 8); 360ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_STENCIL_INDEX8; 361ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 362ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 363ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 364ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 365ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 366ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 367ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 368ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 369d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paulstatic GLboolean 370d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Pauladd_depth_stencil_renderbuffer(struct gl_context *ctx, 371d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul struct gl_framebuffer *fb) 372d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul{ 373d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul struct gl_renderbuffer *rb; 374d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 375d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 376d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 377d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 378f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul rb = _swrast_new_soft_renderbuffer(ctx, 0); 379d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul if (!rb) { 380d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer"); 381d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul return GL_FALSE; 382d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul } 383d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 384d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul rb->InternalFormat = GL_DEPTH_STENCIL; 385d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 386d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 387d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 388d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 389d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 390d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul return GL_TRUE; 391d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul} 392d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 393d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul 394ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 395ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Add a software-based accumulation renderbuffer to the given framebuffer. 396ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers when creating a 397ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * window system framebuffer (not a user-created render/framebuffer). 398ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Once this function is called, you can basically forget about this 399ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer; core Mesa will handle all the buffer management and 400ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering! 401ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 402ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 403ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Pauladd_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 404ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint redBits, GLuint greenBits, 405ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint blueBits, GLuint alphaBits) 406ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 407ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul struct gl_renderbuffer *rb; 408ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 409ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 410ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_problem(ctx, 411ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "Unsupported accumBits in add_accum_renderbuffer"); 412ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 413ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 414ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 415ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 416ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 417f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul rb = _swrast_new_soft_renderbuffer(ctx, 0); 418ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (!rb) { 419ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 420ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 421ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 422ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 423ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_RGBA16_SNORM; 424ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 425ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 426ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 427ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 428ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 429ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 430ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 431ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 432ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 433ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Add a software-based aux renderbuffer to the given framebuffer. 434ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers when creating a 435ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * window system framebuffer (not a user-created render/framebuffer). 436ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Once this function is called, you can basically forget about this 437ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * renderbuffer; core Mesa will handle all the buffer management and 438ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * rendering! 439ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * 440ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * NOTE: color-index aux buffers not supported. 441ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 442ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulstatic GLboolean 443ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Pauladd_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 444ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint colorBits, GLuint numBuffers) 445ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 446ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLuint i; 447ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 448ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (colorBits > 16) { 449ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_problem(ctx, 450ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul "Unsupported colorBits in add_aux_renderbuffers"); 451ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 452ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 453ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 454ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(numBuffers <= MAX_AUX_BUFFERS); 455ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 456ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul for (i = 0; i < numBuffers; i++) { 457f2479530b8be3866c234ac759a7fa84e634dd1aaBrian Paul struct gl_renderbuffer *rb = _swrast_new_soft_renderbuffer(ctx, 0); 458ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 459ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 460ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 461ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (!rb) { 462ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); 463ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_FALSE; 464ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 465ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 466ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert (colorBits <= 8); 467ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->InternalFormat = GL_RGBA; 468ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 469ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul rb->AllocStorage = soft_renderbuffer_storage; 470ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 471ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 472ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul return GL_TRUE; 473ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 474ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 475ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 476ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul/** 477ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * Create/attach software-based renderbuffers to the given framebuffer. 478ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * This is a helper routine for device drivers. Drivers can just as well 479ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul * call the individual _mesa_add_*_renderbuffer() routines directly. 480ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul */ 481ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paulvoid 482379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, 483379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean color, 484379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean depth, 485379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean stencil, 486379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean accum, 487379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean alpha, 488379e0a3ada995b4cf57d142e0dd4618022e0aadcBrian Paul GLboolean aux) 489ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul{ 490ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean frontLeft = GL_TRUE; 491ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean backLeft = fb->Visual.doubleBufferMode; 492ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean frontRight = fb->Visual.stereoMode; 493ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 494ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 495ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (color) { 496ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.redBits == fb->Visual.greenBits); 497ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.redBits == fb->Visual.blueBits); 498ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul add_color_renderbuffers(NULL, fb, 499ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.redBits, 500ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.alphaBits, 501ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul frontLeft, backLeft, 502ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul frontRight, backRight); 503ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 504ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 505d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul#if 0 506d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul /* This is pretty much for debugging purposes only since there's a perf 507d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul * hit for using combined depth/stencil in swrast. 508d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul */ 509d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul if (depth && fb->Visual.depthBits == 24 && 510d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul stencil && fb->Visual.stencilBits == 8) { 511d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul /* use combined depth/stencil buffer */ 512d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul add_depth_stencil_renderbuffer(NULL, fb); 513d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul } 514d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul else 515d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul#else 516d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul (void) add_depth_stencil_renderbuffer; 517d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul#endif 518d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul { 519d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul if (depth) { 520d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul assert(fb->Visual.depthBits > 0); 521d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 522d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul } 523ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 524d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul if (stencil) { 525d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul assert(fb->Visual.stencilBits > 0); 526d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 527d7c0fac90b1fe550df3d75777747c1ae9be41fc0Brian Paul } 528ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 529ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 530ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (accum) { 531ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.accumRedBits > 0); 532ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.accumGreenBits > 0); 533ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.accumBlueBits > 0); 534ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul add_accum_renderbuffer(NULL, fb, 535ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.accumRedBits, 536ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.accumGreenBits, 537ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.accumBlueBits, 538ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.accumAlphaBits); 539ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 540ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 541ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (aux) { 542ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul assert(fb->Visual.numAuxBuffers > 0); 543ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 544ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul fb->Visual.numAuxBuffers); 545ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 546ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul 547ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul#if 0 548ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul if (multisample) { 549ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul /* maybe someday */ 550ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul } 551ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul#endif 552ff8e6420fbbbd80c8fd7327f2f2b68e016b7f5c0Brian Paul} 553