1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg#include "main/glheader.h" 26848b8605Smrg#include "main/accum.h" 27848b8605Smrg#include "main/condrender.h" 28848b8605Smrg#include "main/format_pack.h" 29848b8605Smrg#include "main/macros.h" 30848b8605Smrg#include "main/imports.h" 31848b8605Smrg#include "main/mtypes.h" 32848b8605Smrg 33848b8605Smrg#include "s_context.h" 34848b8605Smrg#include "s_depth.h" 35848b8605Smrg#include "s_stencil.h" 36848b8605Smrg 37848b8605Smrg 38848b8605Smrg 39848b8605Smrg/** 40848b8605Smrg * Clear an rgba color buffer with masking if needed. 41848b8605Smrg */ 42848b8605Smrgstatic void 43848b8605Smrgclear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, 44848b8605Smrg const GLubyte colorMask[4]) 45848b8605Smrg{ 46848b8605Smrg const GLint x = ctx->DrawBuffer->_Xmin; 47848b8605Smrg const GLint y = ctx->DrawBuffer->_Ymin; 48848b8605Smrg const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 49848b8605Smrg const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 50848b8605Smrg const GLuint pixelSize = _mesa_get_format_bytes(rb->Format); 51848b8605Smrg const GLboolean doMasking = (colorMask[0] == 0 || 52848b8605Smrg colorMask[1] == 0 || 53848b8605Smrg colorMask[2] == 0 || 54848b8605Smrg colorMask[3] == 0); 55848b8605Smrg const GLfloat (*clearColor)[4] = 56848b8605Smrg (const GLfloat (*)[4]) ctx->Color.ClearColor.f; 57848b8605Smrg GLbitfield mapMode = GL_MAP_WRITE_BIT; 58848b8605Smrg GLubyte *map; 59848b8605Smrg GLint rowStride; 60848b8605Smrg GLint i, j; 61848b8605Smrg 62848b8605Smrg if (doMasking) { 63848b8605Smrg /* we'll need to read buffer values too */ 64848b8605Smrg mapMode |= GL_MAP_READ_BIT; 65848b8605Smrg } 66848b8605Smrg 67848b8605Smrg /* map dest buffer */ 68848b8605Smrg ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 69b8e80941Smrg mapMode, &map, &rowStride, 70b8e80941Smrg ctx->DrawBuffer->FlipY); 71848b8605Smrg if (!map) { 72848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)"); 73848b8605Smrg return; 74848b8605Smrg } 75848b8605Smrg 76848b8605Smrg /* for 1, 2, 4-byte clearing */ 77848b8605Smrg#define SIMPLE_TYPE_CLEAR(TYPE) \ 78848b8605Smrg do { \ 79848b8605Smrg TYPE pixel, pixelMask; \ 80848b8605Smrg _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, &pixel); \ 81848b8605Smrg if (doMasking) { \ 82848b8605Smrg _mesa_pack_colormask(rb->Format, colorMask, &pixelMask); \ 83848b8605Smrg pixel &= pixelMask; \ 84848b8605Smrg pixelMask = ~pixelMask; \ 85848b8605Smrg } \ 86848b8605Smrg for (i = 0; i < height; i++) { \ 87848b8605Smrg TYPE *row = (TYPE *) map; \ 88848b8605Smrg if (doMasking) { \ 89848b8605Smrg for (j = 0; j < width; j++) { \ 90848b8605Smrg row[j] = (row[j] & pixelMask) | pixel; \ 91848b8605Smrg } \ 92848b8605Smrg } \ 93848b8605Smrg else { \ 94848b8605Smrg for (j = 0; j < width; j++) { \ 95848b8605Smrg row[j] = pixel; \ 96848b8605Smrg } \ 97848b8605Smrg } \ 98848b8605Smrg map += rowStride; \ 99848b8605Smrg } \ 100848b8605Smrg } while (0) 101848b8605Smrg 102848b8605Smrg 103848b8605Smrg /* for 3, 6, 8, 12, 16-byte clearing */ 104848b8605Smrg#define MULTI_WORD_CLEAR(TYPE, N) \ 105848b8605Smrg do { \ 106848b8605Smrg TYPE pixel[N], pixelMask[N]; \ 107848b8605Smrg GLuint k; \ 108848b8605Smrg _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, pixel); \ 109848b8605Smrg if (doMasking) { \ 110848b8605Smrg _mesa_pack_colormask(rb->Format, colorMask, pixelMask); \ 111848b8605Smrg for (k = 0; k < N; k++) { \ 112848b8605Smrg pixel[k] &= pixelMask[k]; \ 113848b8605Smrg pixelMask[k] = ~pixelMask[k]; \ 114848b8605Smrg } \ 115848b8605Smrg } \ 116848b8605Smrg for (i = 0; i < height; i++) { \ 117848b8605Smrg TYPE *row = (TYPE *) map; \ 118848b8605Smrg if (doMasking) { \ 119848b8605Smrg for (j = 0; j < width; j++) { \ 120848b8605Smrg for (k = 0; k < N; k++) { \ 121848b8605Smrg row[j * N + k] = \ 122848b8605Smrg (row[j * N + k] & pixelMask[k]) | pixel[k]; \ 123848b8605Smrg } \ 124848b8605Smrg } \ 125848b8605Smrg } \ 126848b8605Smrg else { \ 127848b8605Smrg for (j = 0; j < width; j++) { \ 128848b8605Smrg for (k = 0; k < N; k++) { \ 129848b8605Smrg row[j * N + k] = pixel[k]; \ 130848b8605Smrg } \ 131848b8605Smrg } \ 132848b8605Smrg } \ 133848b8605Smrg map += rowStride; \ 134848b8605Smrg } \ 135848b8605Smrg } while(0) 136848b8605Smrg 137848b8605Smrg switch (pixelSize) { 138848b8605Smrg case 1: 139848b8605Smrg SIMPLE_TYPE_CLEAR(GLubyte); 140848b8605Smrg break; 141848b8605Smrg case 2: 142848b8605Smrg SIMPLE_TYPE_CLEAR(GLushort); 143848b8605Smrg break; 144848b8605Smrg case 3: 145848b8605Smrg MULTI_WORD_CLEAR(GLubyte, 3); 146848b8605Smrg break; 147848b8605Smrg case 4: 148848b8605Smrg SIMPLE_TYPE_CLEAR(GLuint); 149848b8605Smrg break; 150848b8605Smrg case 6: 151848b8605Smrg MULTI_WORD_CLEAR(GLushort, 3); 152848b8605Smrg break; 153848b8605Smrg case 8: 154848b8605Smrg MULTI_WORD_CLEAR(GLuint, 2); 155848b8605Smrg break; 156848b8605Smrg case 12: 157848b8605Smrg MULTI_WORD_CLEAR(GLuint, 3); 158848b8605Smrg break; 159848b8605Smrg case 16: 160848b8605Smrg MULTI_WORD_CLEAR(GLuint, 4); 161848b8605Smrg break; 162848b8605Smrg default: 163848b8605Smrg _mesa_problem(ctx, "bad pixel size in clear_rgba_buffer()"); 164848b8605Smrg } 165848b8605Smrg 166848b8605Smrg /* unmap buffer */ 167848b8605Smrg ctx->Driver.UnmapRenderbuffer(ctx, rb); 168848b8605Smrg} 169848b8605Smrg 170848b8605Smrg 171848b8605Smrg/** 172848b8605Smrg * Clear the front/back/left/right/aux color buffers. 173848b8605Smrg * This function is usually only called if the device driver can't 174848b8605Smrg * clear its own color buffers for some reason (such as with masking). 175848b8605Smrg */ 176848b8605Smrgstatic void 177848b8605Smrgclear_color_buffers(struct gl_context *ctx) 178848b8605Smrg{ 179848b8605Smrg GLuint buf; 180848b8605Smrg 181848b8605Smrg for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) { 182848b8605Smrg struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf]; 183848b8605Smrg 184848b8605Smrg /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported, 185848b8605Smrg * the framebuffer can be complete with some attachments be missing. In 186848b8605Smrg * this case the _ColorDrawBuffers pointer will be NULL. 187848b8605Smrg */ 188848b8605Smrg if (rb == NULL) 189848b8605Smrg continue; 190848b8605Smrg 191b8e80941Smrg const GLubyte colormask[4] = { 192b8e80941Smrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, 193b8e80941Smrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, 194b8e80941Smrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, 195b8e80941Smrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, 196b8e80941Smrg }; 197b8e80941Smrg clear_rgba_buffer(ctx, rb, colormask); 198848b8605Smrg } 199848b8605Smrg} 200848b8605Smrg 201848b8605Smrg 202848b8605Smrg/** 203848b8605Smrg * Called via the device driver's ctx->Driver.Clear() function if the 204848b8605Smrg * device driver can't clear one or more of the buffers itself. 205848b8605Smrg * \param buffers bitfield of BUFFER_BIT_* values indicating which 206848b8605Smrg * renderbuffers are to be cleared. 207848b8605Smrg * \param all if GL_TRUE, clear whole buffer, else clear specified region. 208848b8605Smrg */ 209848b8605Smrgvoid 210848b8605Smrg_swrast_Clear(struct gl_context *ctx, GLbitfield buffers) 211848b8605Smrg{ 212848b8605Smrg const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL; 213848b8605Smrg 214848b8605Smrg#ifdef DEBUG_FOO 215848b8605Smrg { 216848b8605Smrg const GLbitfield legalBits = 217848b8605Smrg BUFFER_BIT_FRONT_LEFT | 218848b8605Smrg BUFFER_BIT_FRONT_RIGHT | 219848b8605Smrg BUFFER_BIT_BACK_LEFT | 220848b8605Smrg BUFFER_BIT_BACK_RIGHT | 221848b8605Smrg BUFFER_BIT_DEPTH | 222848b8605Smrg BUFFER_BIT_STENCIL | 223848b8605Smrg BUFFER_BIT_ACCUM | 224848b8605Smrg BUFFER_BIT_AUX0; 225848b8605Smrg assert((buffers & (~legalBits)) == 0); 226848b8605Smrg } 227848b8605Smrg#endif 228848b8605Smrg 229848b8605Smrg if (!_mesa_check_conditional_render(ctx)) 230848b8605Smrg return; /* don't clear */ 231848b8605Smrg 232848b8605Smrg if (SWRAST_CONTEXT(ctx)->NewState) 233848b8605Smrg _swrast_validate_derived(ctx); 234848b8605Smrg 235848b8605Smrg if ((buffers & BUFFER_BITS_COLOR) 236848b8605Smrg && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) { 237848b8605Smrg clear_color_buffers(ctx); 238848b8605Smrg } 239848b8605Smrg 240848b8605Smrg if (buffers & BUFFER_BIT_ACCUM) { 241848b8605Smrg _mesa_clear_accum_buffer(ctx); 242848b8605Smrg } 243848b8605Smrg 244848b8605Smrg if (buffers & BUFFER_DS) { 245848b8605Smrg struct gl_renderbuffer *depthRb = 246848b8605Smrg ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 247848b8605Smrg struct gl_renderbuffer *stencilRb = 248848b8605Smrg ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 249848b8605Smrg 250848b8605Smrg if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) { 251848b8605Smrg /* clear depth and stencil together */ 252848b8605Smrg _swrast_clear_depth_stencil_buffer(ctx); 253848b8605Smrg } 254848b8605Smrg else { 255848b8605Smrg /* clear depth, stencil separately */ 256848b8605Smrg if (buffers & BUFFER_BIT_DEPTH) { 257848b8605Smrg _swrast_clear_depth_buffer(ctx); 258848b8605Smrg } 259848b8605Smrg if (buffers & BUFFER_BIT_STENCIL) { 260848b8605Smrg _swrast_clear_stencil_buffer(ctx); 261848b8605Smrg } 262848b8605Smrg } 263848b8605Smrg } 264848b8605Smrg} 265