st_atom_depth.c revision a6c0c5532f7bfa50ae54c36cf4d74ad4b9f926f8
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 GLenum stencil func tokens to pipe tokens. 45 */ 46static GLuint 47gl_stencil_func_to_sp(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_sp(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_sp()" == NULL); 89 return 0; 90 } 91} 92 93/** 94 * Convert GLenum depth func tokens to pipe tokens. 95 */ 96static GLuint 97gl_depth_func_to_sp(GLenum func) 98{ 99 /* Same values, just biased */ 100 assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); 101 assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); 102 assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); 103 assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); 104 assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); 105 assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); 106 assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); 107 assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); 108 assert(func >= GL_NEVER); 109 assert(func <= GL_ALWAYS); 110 return func - GL_NEVER; 111} 112 113 114static void 115update_depth_stencil(struct st_context *st) 116{ 117 struct pipe_depth_stencil_state depth_stencil; 118 const struct cso_depth_stencil *cso; 119 120 memset(&depth_stencil, 0, sizeof(depth_stencil)); 121 122 depth_stencil.depth.enabled = st->ctx->Depth.Test; 123 depth_stencil.depth.writemask = st->ctx->Depth.Mask; 124 depth_stencil.depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func); 125 depth_stencil.depth.clear = st->ctx->Depth.Clear; 126 127 if (st->ctx->Query.CurrentOcclusionObject && 128 st->ctx->Query.CurrentOcclusionObject->Active) 129 depth_stencil.depth.occlusion_count = 1; 130 131 if (st->ctx->Stencil.Enabled) { 132 depth_stencil.stencil.front_enabled = 1; 133 depth_stencil.stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]); 134 depth_stencil.stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]); 135 depth_stencil.stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]); 136 depth_stencil.stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]); 137 depth_stencil.stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff; 138 depth_stencil.stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff; 139 depth_stencil.stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff; 140 if (st->ctx->Stencil.TestTwoSide) { 141 depth_stencil.stencil.back_enabled = 1; 142 depth_stencil.stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]); 143 depth_stencil.stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]); 144 depth_stencil.stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]); 145 depth_stencil.stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]); 146 depth_stencil.stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff; 147 depth_stencil.stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff; 148 depth_stencil.stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff; 149 } 150 depth_stencil.stencil.clear_value = st->ctx->Stencil.Clear & 0xff; 151 } 152 153 cso = st_cached_depth_stencil_state(st, &depth_stencil); 154 if (st->state.depth_stencil != cso) { 155 /* state has changed */ 156 st->state.depth_stencil = cso; 157 st->pipe->bind_depth_stencil_state(st->pipe, cso->data); /* bind new state */ 158 } 159} 160 161 162const struct st_tracked_state st_update_depth_stencil = { 163 .name = "st_update_depth_stencil", 164 .dirty = { 165 .mesa = (_NEW_DEPTH|_NEW_STENCIL), 166 .st = 0, 167 }, 168 .update = update_depth_stencil 169}; 170