1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.1 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/format_pack.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/format_unpack.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_context.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_depth.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_stencil.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_span.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Stencil Logic: 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgIF stencil test fails THEN 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Apply fail-op to stencil value 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Don't write the pixel (RGBA,Z) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgELSE 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IF doing depth test && depth test fails THEN 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Apply zfail-op to stencil value 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Write RGBA and Z to appropriate buffers 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ELSE 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Apply zpass-op to stencil value 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgENDIF 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute/return the offset of the stencil value in a pixel. 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For example, if the format is Z24+S8, the position of the stencil bits 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * within the 4-byte pixel will be either 0 or 3. 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLint 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_stencil_offset(gl_format format) 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte one = 1; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte pixel[MAX_PIXEL_BYTES]; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint bpp = _mesa_get_format_bytes(format); 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint i; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(_mesa_get_format_bits(format, GL_STENCIL_BITS) == 8); 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(pixel, 0, sizeof(pixel)); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_ubyte_stencil_row(format, 1, &one, pixel); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < bpp; i++) { 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pixel[i]) 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return i; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(NULL, "get_stencil_offset() failed\n"); 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Clamp the stencil value to [0, 255] */ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLubyte 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclamp(GLint val) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (val < 0) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (val > 255) 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 255; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return val; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define STENCIL_OP(NEW_VAL) \ 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (invmask == 0) { \ 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = j = 0; i < n; i++, j += stride) { \ 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask[i]) { \ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte s = stencil[j]; \ 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) s; \ 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil[j] = (GLubyte) (NEW_VAL); \ 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { \ 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = j = 0; i < n; i++, j += stride) { \ 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask[i]) { \ 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte s = stencil[j]; \ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil[j] = (GLubyte) ((invmask & s) | (wrtmask & (NEW_VAL))); \ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply the given stencil operator to the array of stencil values. 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Don't touch stencil[i] if mask[i] is zero. 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param n number of stencil values 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param oper the stencil buffer operator 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param face 0 or 1 for front or back face operation 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param stencil array of stencil values (in/out) 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param mask array [n] of flag: 1=apply operator, 0=don't apply operator 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param stride stride between stencil values 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_stencil_op(const struct gl_context *ctx, GLenum oper, GLuint face, 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint n, GLubyte stencil[], const GLubyte mask[], 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint stride) 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte ref = ctx->Stencil.Ref[face]; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte wrtmask = ctx->Stencil.WriteMask[face]; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte invmask = (GLubyte) (~wrtmask); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i, j; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (oper) { 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_KEEP: 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do nothing */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_ZERO: 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* replace stencil buf values with zero */ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(0); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_REPLACE: 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* replace stencil buf values with ref value */ 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(ref); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_INCR: 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* increment stencil buf values, with clamping */ 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(clamp(s + 1)); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DECR: 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* increment stencil buf values, with clamping */ 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(clamp(s - 1)); 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_INCR_WRAP_EXT: 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* increment stencil buf values, without clamping */ 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(s + 1); 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DECR_WRAP_EXT: 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* increment stencil buf values, without clamping */ 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(s - 1); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_INVERT: 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* replace stencil buf values with inverted value */ 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_OP(~s); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "Bad stencil op in apply_stencil_op"); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define STENCIL_TEST(FUNC) \ 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = j = 0; i < n; i++, j += stride) { \ 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask[i]) { \ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s = (GLubyte) (stencil[j] & valueMask); \ 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FUNC) { \ 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* stencil pass */ \ 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail[i] = 0; \ 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { \ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* stencil fail */ \ 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail[i] = 1; \ 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask[i] = 0; \ 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { \ 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail[i] = 0; \ 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply stencil test to an array of stencil values (before depth buffering). 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For the values that fail, we'll apply the GL_STENCIL_FAIL operator to 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the stencil values. 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param face 0 or 1 for front or back-face polygons 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param n number of pixels in the array 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param stencil array of [n] stencil values (in/out) 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param mask array [n] of flag: 0=skip the pixel, 1=stencil the pixel, 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * values are set to zero where the stencil test fails. 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param stride stride between stencil values 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_stencil_test(struct gl_context *ctx, GLuint face, GLuint n, 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte stencil[], GLubyte mask[], GLint stride) 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWcontext *swrast = SWRAST_CONTEXT(ctx); 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *fail = swrast->stencil_temp.buf2; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean allfail = GL_FALSE; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i, j; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint valueMask = ctx->Stencil.ValueMask[face]; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte ref = (GLubyte) (ctx->Stencil.Ref[face] & valueMask); 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte s; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Perform stencil test. The results of this operation are stored 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in the fail[] array: 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IF fail[i] is non-zero THEN 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the stencil fail operator is to be applied 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ELSE 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the stencil fail operator is not to be applied 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ENDIF 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ctx->Stencil.Function[face]) { 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_NEVER: 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(0); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org allfail = GL_TRUE; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_LESS: 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref < s); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_LEQUAL: 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref <= s); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_GREATER: 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref > s); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_GEQUAL: 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref >= s); 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_EQUAL: 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref == s); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_NOTEQUAL: 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(ref != s); 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_ALWAYS: 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org STENCIL_TEST(1); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "Bad stencil func in gl_stencil_span"); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Stencil.FailFunc[face] != GL_KEEP) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_stencil_op(ctx, ctx->Stencil.FailFunc[face], face, n, stencil, 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail, stride); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return !allfail; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute the zpass/zfail masks by comparing the pre- and post-depth test 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * masks. 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompute_pass_fail_masks(GLuint n, const GLubyte origMask[], 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte newMask[], 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte passMask[], GLubyte failMask[]) 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < n; i++) { 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(newMask[i] == 0 || newMask[i] == 1); 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passMask[i] = origMask[i] & newMask[i]; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org failMask[i] = origMask[i] & (newMask[i] ^ 1); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get 8-bit stencil values from random locations in the stencil buffer. 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_s8_values(struct gl_context *ctx, struct gl_renderbuffer *rb, 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint count, const GLint x[], const GLint y[], 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte stencil[]) 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint w = rb->Width, h = rb->Height; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *map = _swrast_pixel_address(rb, 0, 0); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rb->Format == MESA_FORMAT_S8) { 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint rowStride = srb->RowStride; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < count; i++) { 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil[i] = *(map + y[i] * rowStride + x[i]); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint bpp = _mesa_get_format_bytes(rb->Format); 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint rowStride = srb->RowStride; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < count; i++) { 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *src = map + y[i] * rowStride + x[i] * bpp; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_ubyte_stencil_row(rb->Format, 1, src, &stencil[i]); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Put 8-bit stencil values at random locations into the stencil buffer. 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgput_s8_values(struct gl_context *ctx, struct gl_renderbuffer *rb, 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint count, const GLint x[], const GLint y[], 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte stencil[]) 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint w = rb->Width, h = rb->Height; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_pack_ubyte_stencil_func pack_stencil = 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_pack_ubyte_stencil_func(rb->Format); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < count; i++) { 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pack_stencil(&stencil[i], dst); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * /return GL_TRUE = one or more fragments passed, 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_FALSE = all fragments failed. 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_stencil_and_ztest_span(struct gl_context *ctx, SWspan *span) 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWcontext *swrast = SWRAST_CONTEXT(ctx); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->DrawBuffer; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint stencilOffset = get_stencil_offset(rb->Format); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint stencilStride = _mesa_get_format_bytes(rb->Format); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint face = (span->facing == 0) ? 0 : ctx->Stencil._BackFace; 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint count = span->end; 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *mask = span->array->mask; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *stencilTemp = swrast->stencil_temp.buf1; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *stencilBuf; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (span->arrayMask & SPAN_XY) { 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* read stencil values from random locations */ 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_s8_values(ctx, rb, count, span->array->x, span->array->y, 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilTemp); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilBuf = stencilTemp; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Processing a horizontal run of pixels. Since stencil is always 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 8 bits for all MESA_FORMATs, we just need to use the right offset 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and stride to access them. 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilBuf = _swrast_pixel_address(rb, span->x, span->y) + stencilOffset; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply the stencil test to the fragments. 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * failMask[i] is 1 if the stencil test failed. 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!do_stencil_test(ctx, face, count, stencilBuf, mask, stencilStride)) { 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* all fragments failed the stencil test, we're done. */ 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span->writeAll = GL_FALSE; 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (span->arrayMask & SPAN_XY) { 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to write the updated stencil values back to the buffer */ 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org put_s8_values(ctx, rb, count, span->array->x, span->array->y, 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilTemp); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some fragments passed the stencil test, apply depth test to them 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and apply Zpass and Zfail stencil ops. 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Depth.Test == GL_FALSE || 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer == NULL) { 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * No depth buffer, just apply zpass stencil function to active pixels. 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, count, 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilBuf, mask, stencilStride); 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Perform depth buffering, then apply zpass or zfail stencil function. 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWcontext *swrast = SWRAST_CONTEXT(ctx); 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *passMask = swrast->stencil_temp.buf2; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *failMask = swrast->stencil_temp.buf3; 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *origMask = swrast->stencil_temp.buf4; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* save the current mask bits */ 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(origMask, mask, count * sizeof(GLubyte)); 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* apply the depth test */ 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_depth_test_span(ctx, span); 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compute_pass_fail_masks(count, origMask, mask, passMask, failMask); 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* apply the pass and fail operations */ 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face, 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count, stencilBuf, failMask, stencilStride); 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count, stencilBuf, passMask, stencilStride); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Write updated stencil values back into hardware stencil buffer */ 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (span->arrayMask & SPAN_XY) { 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org put_s8_values(ctx, rb, count, span->array->x, span->array->y, 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilBuf); 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span->writeAll = GL_FALSE; 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* one or more fragments passed both tests */ 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return a span of stencil values from the stencil buffer. 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used for glRead/CopyPixels 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Input: n - how many pixels 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * x,y - location of first pixel 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Output: stencil - the array of stencil values 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb, 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint n, GLint x, GLint y, GLubyte stencil[]) 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *src; 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (y < 0 || y >= (GLint) rb->Height || 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x + n <= 0 || x >= (GLint) rb->Width) { 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* span is completely outside framebuffer */ 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; /* undefined values OK */ 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x < 0) { 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dx = -x; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = 0; 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n -= dx; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil += dx; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x + n > (GLint) rb->Width) { 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dx = x + n - rb->Width; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n -= dx; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n <= 0) { 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = _swrast_pixel_address(rb, x, y); 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_ubyte_stencil_row(rb->Format, n, src, stencil); 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Write a span of stencil values to the stencil buffer. This function 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applies the stencil write mask when needed. 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used for glDraw/CopyPixels 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Input: n - how many pixels 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * x, y - location of first pixel 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stencil - the array of stencil values 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_write_stencil_span(struct gl_context *ctx, GLint n, GLint x, GLint y, 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte stencil[] ) 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWcontext *swrast = SWRAST_CONTEXT(ctx); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->DrawBuffer; 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint stencilMax = (1 << fb->Visual.stencilBits) - 1; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint stencilMask = ctx->Stencil.WriteMask[0]; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *stencilBuf; 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (y < 0 || y >= (GLint) rb->Height || 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x + n <= 0 || x >= (GLint) rb->Width) { 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* span is completely outside framebuffer */ 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; /* undefined values OK */ 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x < 0) { 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dx = -x; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = 0; 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n -= dx; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil += dx; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x + n > (GLint) rb->Width) { 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dx = x + n - rb->Width; 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n -= dx; 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n <= 0) { 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencilBuf = _swrast_pixel_address(rb, x, y); 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((stencilMask & stencilMax) != stencilMax) { 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to apply writemask */ 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *destVals = swrast->stencil_temp.buf1; 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *newVals = swrast->stencil_temp.buf2; 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint i; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_ubyte_stencil_row(rb->Format, n, stencilBuf, destVals); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < n; i++) { 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newVals[i] 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = (stencil[i] & stencilMask) | (destVals[i] & ~stencilMask); 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_ubyte_stencil_row(rb->Format, n, newVals, stencilBuf); 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_ubyte_stencil_row(rb->Format, n, stencil, stencilBuf); 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Clear the stencil buffer. If the buffer is a combined 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * depth+stencil buffer, only the stencil bits will be touched. 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_clear_stencil_buffer(struct gl_context *ctx) 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb = 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits; 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint writeMask = ctx->Stencil.WriteMask[0]; 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint stencilMax = (1 << stencilBits) - 1; 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint x, y, width, height; 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *map; 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint rowStride, i, j; 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield mapMode; 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!rb || writeMask == 0) 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute region to clear */ 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = ctx->DrawBuffer->_Xmin; 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y = ctx->DrawBuffer->_Ymin; 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mapMode = GL_MAP_WRITE_BIT; 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((writeMask & stencilMax) != stencilMax) { 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to mask stencil values */ 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mapMode |= GL_MAP_READ_BIT; 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (_mesa_get_format_bits(rb->Format, GL_DEPTH_BITS) > 0) { 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* combined depth+stencil, need to mask Z values */ 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mapMode |= GL_MAP_READ_BIT; 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mapMode, &map, &rowStride); 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!map) { 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(stencil)"); 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (rb->Format) { 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case MESA_FORMAT_S8: 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte clear = ctx->Stencil.Clear & writeMask & 0xff; 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte mask = (~writeMask) & 0xff; 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask != 0) { 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* masked clear */ 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < height; i++) { 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *row = map; 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < width; j++) { 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org row[j] = (row[j] & mask) | clear; 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map += rowStride; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (rowStride == width) { 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* clear whole buffer */ 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(map, clear, width * height); 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* clear scissored */ 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < height; i++) { 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(map, clear, width); 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map += rowStride; 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case MESA_FORMAT_S8_Z24: 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint clear = (ctx->Stencil.Clear & writeMask & 0xff) << 24; 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint mask = (((~writeMask) & 0xff) << 24) | 0xffffff; 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < height; i++) { 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint *row = (GLuint *) map; 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < width; j++) { 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org row[j] = (row[j] & mask) | clear; 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map += rowStride; 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case MESA_FORMAT_Z24_S8: 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint clear = ctx->Stencil.Clear & writeMask & 0xff; 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint mask = 0xffffff00 | ((~writeMask) & 0xff); 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < height; i++) { 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint *row = (GLuint *) map; 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < width; j++) { 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org row[j] = (row[j] & mask) | clear; 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map += rowStride; 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "Unexpected stencil buffer format %s" 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " in _swrast_clear_stencil_buffer()", 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_format_name(rb->Format)); 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapRenderbuffer(ctx, rb); 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 649