17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 47117f1b4Smrg * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg */ 247117f1b4Smrg 257117f1b4Smrg 267117f1b4Smrg/* 277117f1b4Smrg * Implement the effect of glColorMask and glIndexMask in software. 287117f1b4Smrg */ 297117f1b4Smrg 307117f1b4Smrg 31c1f859d4Smrg#include "main/glheader.h" 32c1f859d4Smrg#include "main/macros.h" 337117f1b4Smrg 347117f1b4Smrg#include "s_context.h" 357117f1b4Smrg#include "s_masking.h" 367117f1b4Smrg#include "s_span.h" 377117f1b4Smrg 387117f1b4Smrg 397117f1b4Smrg/** 407117f1b4Smrg * Apply the color mask to a span of rgba values. 417117f1b4Smrg */ 427117f1b4Smrgvoid 433464ebd5Sriastradh_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, 44cdc920a0Smrg SWspan *span, GLuint buf) 457117f1b4Smrg{ 467117f1b4Smrg const GLuint n = span->end; 477117f1b4Smrg void *rbPixels; 487117f1b4Smrg 4901e04c3fSmrg assert(n < SWRAST_MAX_WIDTH); 5001e04c3fSmrg assert(span->arrayMask & SPAN_RGBA); 517117f1b4Smrg 527117f1b4Smrg rbPixels = _swrast_get_dest_rgba(ctx, rb, span); 537117f1b4Smrg 547117f1b4Smrg /* 557117f1b4Smrg * Do component masking. 567117f1b4Smrg * Note that we're not using span->array->mask[] here. We could... 577117f1b4Smrg */ 587117f1b4Smrg if (span->array->ChanType == GL_UNSIGNED_BYTE) { 5901e04c3fSmrg const GLubyte colormask[4] = { 6001e04c3fSmrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, 6101e04c3fSmrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, 6201e04c3fSmrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, 6301e04c3fSmrg GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, 6401e04c3fSmrg }; 6501e04c3fSmrg GLuint srcMask; 6601e04c3fSmrg memcpy(&srcMask, colormask, sizeof(srcMask)); 677117f1b4Smrg const GLuint dstMask = ~srcMask; 687117f1b4Smrg const GLuint *dst = (const GLuint *) rbPixels; 69c1f859d4Smrg GLuint *src = (GLuint *) span->array->rgba8; 707117f1b4Smrg GLuint i; 717117f1b4Smrg for (i = 0; i < n; i++) { 727117f1b4Smrg src[i] = (src[i] & srcMask) | (dst[i] & dstMask); 737117f1b4Smrg } 747117f1b4Smrg } 757117f1b4Smrg else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 767117f1b4Smrg /* 2-byte components */ 777117f1b4Smrg /* XXX try to use 64-bit arithmetic someday */ 7801e04c3fSmrg const GLushort rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xffff : 0x0; 7901e04c3fSmrg const GLushort gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xffff : 0x0; 8001e04c3fSmrg const GLushort bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xffff : 0x0; 8101e04c3fSmrg const GLushort aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xffff : 0x0; 827117f1b4Smrg const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels; 83c1f859d4Smrg GLushort (*src)[4] = span->array->rgba16; 847117f1b4Smrg GLuint i; 857117f1b4Smrg for (i = 0; i < n; i++) { 867117f1b4Smrg src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); 877117f1b4Smrg src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask); 887117f1b4Smrg src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask); 897117f1b4Smrg src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask); 907117f1b4Smrg } 917117f1b4Smrg } 927117f1b4Smrg else { 937117f1b4Smrg /* 4-byte components */ 9401e04c3fSmrg const GLuint rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? ~0x0 : 0x0; 9501e04c3fSmrg const GLuint gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? ~0x0 : 0x0; 9601e04c3fSmrg const GLuint bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? ~0x0 : 0x0; 9701e04c3fSmrg const GLuint aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? ~0x0 : 0x0; 987117f1b4Smrg const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels; 99af69d88dSmrg GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[VARYING_SLOT_COL0]; 1007117f1b4Smrg GLuint i; 1017117f1b4Smrg for (i = 0; i < n; i++) { 1027117f1b4Smrg src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); 1037117f1b4Smrg src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask); 1047117f1b4Smrg src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask); 1057117f1b4Smrg src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask); 1067117f1b4Smrg } 1077117f1b4Smrg } 1087117f1b4Smrg} 109