00001 /************************************************************************** 00002 * 00003 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 00004 * All Rights Reserved. 00005 * 00006 * Permission is hereby granted, free of charge, to any person obtaining a 00007 * copy of this software and associated documentation files (the 00008 * "Software"), to deal in the Software without restriction, including 00009 * without limitation the rights to use, copy, modify, merge, publish, 00010 * distribute, sub license, and/or sell copies of the Software, and to 00011 * permit persons to whom the Software is furnished to do so, subject to 00012 * the following conditions: 00013 * 00014 * The above copyright notice and this permission notice (including the 00015 * next paragraph) shall be included in all copies or substantial portions 00016 * of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00019 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00020 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 00021 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 00022 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 00023 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 00024 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00025 * 00026 **************************************************************************/ 00027 00028 /* 00029 * Authors: 00030 * Keith Whitwell <keith@tungstengraphics.com> 00031 * Brian Paul 00032 * Zack Rusin 00033 */ 00034 00035 00036 #include "st_context.h" 00037 #include "st_atom.h" 00038 #include "pipe/p_context.h" 00039 #include "pipe/p_defines.h" 00040 #include "cso_cache/cso_context.h" 00041 00042 00046 GLuint 00047 st_compare_func_to_pipe(GLenum func) 00048 { 00049 /* Same values, just biased */ 00050 assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); 00051 assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); 00052 assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); 00053 assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); 00054 assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); 00055 assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); 00056 assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); 00057 assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); 00058 assert(func >= GL_NEVER); 00059 assert(func <= GL_ALWAYS); 00060 return func - GL_NEVER; 00061 } 00062 00063 00067 static GLuint 00068 gl_stencil_op_to_pipe(GLenum func) 00069 { 00070 switch (func) { 00071 case GL_KEEP: 00072 return PIPE_STENCIL_OP_KEEP; 00073 case GL_ZERO: 00074 return PIPE_STENCIL_OP_ZERO; 00075 case GL_REPLACE: 00076 return PIPE_STENCIL_OP_REPLACE; 00077 case GL_INCR: 00078 return PIPE_STENCIL_OP_INCR; 00079 case GL_DECR: 00080 return PIPE_STENCIL_OP_DECR; 00081 case GL_INCR_WRAP: 00082 return PIPE_STENCIL_OP_INCR_WRAP; 00083 case GL_DECR_WRAP: 00084 return PIPE_STENCIL_OP_DECR_WRAP; 00085 case GL_INVERT: 00086 return PIPE_STENCIL_OP_INVERT; 00087 default: 00088 assert("invalid GL token in gl_stencil_op_to_pipe()" == NULL); 00089 return 0; 00090 } 00091 } 00092 00093 static void 00094 update_depth_stencil_alpha(struct st_context *st) 00095 { 00096 struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil; 00097 00098 memset(dsa, 0, sizeof(*dsa)); 00099 00100 dsa->depth.enabled = st->ctx->Depth.Test; 00101 dsa->depth.writemask = st->ctx->Depth.Mask; 00102 dsa->depth.func = st_compare_func_to_pipe(st->ctx->Depth.Func); 00103 00104 if (st->ctx->Query.CurrentOcclusionObject && 00105 st->ctx->Query.CurrentOcclusionObject->Active) 00106 dsa->depth.occlusion_count = 1; 00107 00108 if (st->ctx->Stencil.Enabled && st->ctx->Visual.stencilBits > 0) { 00109 dsa->stencil[0].enabled = 1; 00110 dsa->stencil[0].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[0]); 00111 dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[0]); 00112 dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[0]); 00113 dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[0]); 00114 dsa->stencil[0].ref_value = st->ctx->Stencil.Ref[0] & 0xff; 00115 dsa->stencil[0].value_mask = st->ctx->Stencil.ValueMask[0] & 0xff; 00116 dsa->stencil[0].write_mask = st->ctx->Stencil.WriteMask[0] & 0xff; 00117 00118 if (st->ctx->Stencil._TestTwoSide) { 00119 dsa->stencil[1].enabled = 1; 00120 dsa->stencil[1].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[1]); 00121 dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[1]); 00122 dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[1]); 00123 dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[1]); 00124 dsa->stencil[1].ref_value = st->ctx->Stencil.Ref[1] & 0xff; 00125 dsa->stencil[1].value_mask = st->ctx->Stencil.ValueMask[1] & 0xff; 00126 dsa->stencil[1].write_mask = st->ctx->Stencil.WriteMask[1] & 0xff; 00127 } 00128 else { 00129 dsa->stencil[1] = dsa->stencil[0]; 00130 dsa->stencil[1].enabled = 0; 00131 } 00132 } 00133 00134 if (st->ctx->Color.AlphaEnabled) { 00135 dsa->alpha.enabled = 1; 00136 dsa->alpha.func = st_compare_func_to_pipe(st->ctx->Color.AlphaFunc); 00137 dsa->alpha.ref = st->ctx->Color.AlphaRef; 00138 } 00139 00140 cso_set_depth_stencil_alpha(st->cso_context, dsa); 00141 } 00142 00143 00144 const struct st_tracked_state st_update_depth_stencil_alpha = { 00145 "st_update_depth_stencil", /* name */ 00146 { /* dirty */ 00147 (_NEW_DEPTH|_NEW_STENCIL|_NEW_COLOR), /* mesa */ 00148 0, /* st */ 00149 }, 00150 update_depth_stencil_alpha /* update */ 00151 };