st_atom_depth.c revision bfe79babf99e6b9435195178d1ea64687c60d161
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Keith Whitwell <keith@tungstengraphics.com> 31 * Brian Paul 32 * Zack Rusin 33 */ 34 35 36#include "st_context.h" 37#include "st_cache.h" 38#include "st_atom.h" 39#include "pipe/p_context.h" 40#include "pipe/p_defines.h" 41 42 43/** 44 * Convert an OpenGL compare mode to a pipe tokens. 45 */ 46GLuint 47st_compare_func_to_pipe(GLenum func) 48{ 49 /* Same values, just biased */ 50 assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); 51 assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); 52 assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); 53 assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); 54 assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); 55 assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); 56 assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); 57 assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); 58 assert(func >= GL_NEVER); 59 assert(func <= GL_ALWAYS); 60 return func - GL_NEVER; 61} 62 63 64/** 65 * Convert GLenum stencil op tokens to pipe tokens. 66 */ 67static GLuint 68gl_stencil_op_to_pipe(GLenum func) 69{ 70 switch (func) { 71 case GL_KEEP: 72 return PIPE_STENCIL_OP_KEEP; 73 case GL_ZERO: 74 return PIPE_STENCIL_OP_ZERO; 75 case GL_REPLACE: 76 return PIPE_STENCIL_OP_REPLACE; 77 case GL_INCR: 78 return PIPE_STENCIL_OP_INCR; 79 case GL_DECR: 80 return PIPE_STENCIL_OP_DECR; 81 case GL_INCR_WRAP: 82 return PIPE_STENCIL_OP_INCR_WRAP; 83 case GL_DECR_WRAP: 84 return PIPE_STENCIL_OP_DECR_WRAP; 85 case GL_INVERT: 86 return PIPE_STENCIL_OP_INVERT; 87 default: 88 assert("invalid GL token in gl_stencil_op_to_pipe()" == NULL); 89 return 0; 90 } 91} 92 93static void 94update_depth_stencil_alpha(struct st_context *st) 95{ 96 struct pipe_depth_stencil_alpha_state depth_stencil; 97 const struct cso_depth_stencil_alpha *cso; 98 99 memset(&depth_stencil, 0, sizeof(depth_stencil)); 100 101 depth_stencil.depth.enabled = st->ctx->Depth.Test; 102 depth_stencil.depth.writemask = st->ctx->Depth.Mask; 103 depth_stencil.depth.func = st_compare_func_to_pipe(st->ctx->Depth.Func); 104 105 if (st->ctx->Query.CurrentOcclusionObject && 106 st->ctx->Query.CurrentOcclusionObject->Active) 107 depth_stencil.depth.occlusion_count = 1; 108 109 if (st->ctx->Stencil.Enabled) { 110 depth_stencil.stencil[0].enabled = 1; 111 depth_stencil.stencil[0].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[0]); 112 depth_stencil.stencil[0].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[0]); 113 depth_stencil.stencil[0].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[0]); 114 depth_stencil.stencil[0].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[0]); 115 depth_stencil.stencil[0].ref_value = st->ctx->Stencil.Ref[0] & 0xff; 116 depth_stencil.stencil[0].value_mask = st->ctx->Stencil.ValueMask[0] & 0xff; 117 depth_stencil.stencil[0].write_mask = st->ctx->Stencil.WriteMask[0] & 0xff; 118 119 if (st->ctx->Stencil.TestTwoSide) { 120 depth_stencil.stencil[1].enabled = 1; 121 depth_stencil.stencil[1].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[1]); 122 depth_stencil.stencil[1].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[1]); 123 depth_stencil.stencil[1].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[1]); 124 depth_stencil.stencil[1].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[1]); 125 depth_stencil.stencil[1].ref_value = st->ctx->Stencil.Ref[1] & 0xff; 126 depth_stencil.stencil[1].value_mask = st->ctx->Stencil.ValueMask[1] & 0xff; 127 depth_stencil.stencil[1].write_mask = st->ctx->Stencil.WriteMask[1] & 0xff; 128 } 129 } 130 131 if (st->ctx->Color.AlphaEnabled) { 132 depth_stencil.alpha.enabled = 1; 133 depth_stencil.alpha.func = st_compare_func_to_pipe(st->ctx->Color.AlphaFunc); 134 depth_stencil.alpha.ref = st->ctx->Color.AlphaRef; 135 } 136 137 cso = st_cached_depth_stencil_alpha_state(st, &depth_stencil); 138 if (st->state.depth_stencil != cso) { 139 /* state has changed */ 140 st->state.depth_stencil = cso; 141 st->pipe->bind_depth_stencil_alpha_state(st->pipe, cso->data); /* bind new state */ 142 } 143} 144 145 146const struct st_tracked_state st_update_depth_stencil_alpha = { 147 .name = "st_update_depth_stencil", 148 .dirty = { 149 .mesa = (_NEW_DEPTH|_NEW_STENCIL|_NEW_COLOR), 150 .st = 0, 151 }, 152 .update = update_depth_stencil_alpha 153}; 154