lp_bld_depth.c revision 1fc41002252419f4688c24ea8c3814553b3d76ad
1/************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 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 VMWARE 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 * @file 30 * Depth/stencil testing to LLVM IR translation. 31 * 32 * To be done accurately/efficiently the depth/stencil test must be done with 33 * the same type/format of the depth/stencil buffer, which implies massaging 34 * the incoming depths to fit into place. Using a more straightforward 35 * type/format for depth/stencil values internally and only convert when 36 * flushing would avoid this, but it would most likely result in depth fighting 37 * artifacts. 38 * 39 * We are free to use a different pixel layout though. Since our basic 40 * processing unit is a quad (2x2 pixel block) we store the depth/stencil 41 * values tiled, a quad at time. That is, a depth buffer containing 42 * 43 * Z11 Z12 Z13 Z14 ... 44 * Z21 Z22 Z23 Z24 ... 45 * Z31 Z32 Z33 Z34 ... 46 * Z41 Z42 Z43 Z44 ... 47 * ... ... ... ... ... 48 * 49 * will actually be stored in memory as 50 * 51 * Z11 Z12 Z21 Z22 Z13 Z14 Z23 Z24 ... 52 * Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ... 53 * ... ... ... ... ... ... ... ... ... 54 * 55 * FIXME: Code generate stencil test 56 * 57 * @author Jose Fonseca <jfonseca@vmware.com> 58 */ 59 60#include "pipe/p_state.h" 61#include "util/u_format.h" 62 63#include "lp_bld_type.h" 64#include "lp_bld_const.h" 65#include "lp_bld_logic.h" 66#include "lp_bld_flow.h" 67#include "lp_bld_debug.h" 68#include "lp_bld_depth.h" 69 70 71/** 72 * Return a type appropriate for depth/stencil testing. 73 */ 74union lp_type 75lp_depth_type(const struct util_format_description *format_desc, 76 unsigned length) 77{ 78 union lp_type type; 79 unsigned swizzle; 80 81 assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 82 assert(format_desc->block.width == 1); 83 assert(format_desc->block.height == 1); 84 85 swizzle = format_desc->swizzle[0]; 86 assert(swizzle < 4); 87 88 type.value = 0; 89 type.width = format_desc->block.bits; 90 91 if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) { 92 type.floating = TRUE; 93 assert(swizzle = 0); 94 assert(format_desc->channel[swizzle].size == format_desc->block.bits); 95 } 96 else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) { 97 assert(format_desc->block.bits <= 32); 98 if(format_desc->channel[swizzle].normalized) 99 type.norm = TRUE; 100 } 101 else 102 assert(0); 103 104 assert(type.width <= length); 105 type.length = length / type.width; 106 107 return type; 108} 109 110 111/** 112 * Depth test. 113 */ 114void 115lp_build_depth_test(LLVMBuilderRef builder, 116 const struct pipe_depth_state *state, 117 union lp_type type, 118 const struct util_format_description *format_desc, 119 struct lp_build_mask_context *mask, 120 LLVMValueRef src, 121 LLVMValueRef dst_ptr) 122{ 123 struct lp_build_context bld; 124 unsigned z_swizzle; 125 LLVMValueRef dst; 126 LLVMValueRef z_bitmask = NULL; 127 LLVMValueRef test; 128 129 if(!state->enabled) 130 return; 131 132 assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 133 assert(format_desc->block.width == 1); 134 assert(format_desc->block.height == 1); 135 136 z_swizzle = format_desc->swizzle[0]; 137 if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE) 138 return; 139 140 /* Sanity checking */ 141 assert(z_swizzle < 4); 142 assert(format_desc->block.bits == type.width); 143 if(type.floating) { 144 assert(z_swizzle == 0); 145 assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT); 146 assert(format_desc->channel[z_swizzle].size == format_desc->block.bits); 147 } 148 else { 149 assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); 150 assert(format_desc->channel[z_swizzle].normalized); 151 assert(!type.fixed); 152 assert(!type.sign); 153 assert(type.norm); 154 } 155 156 /* Setup build context */ 157 lp_build_context_init(&bld, builder, type); 158 159 dst = LLVMBuildLoad(builder, dst_ptr, ""); 160 161 lp_build_name(dst, "zsbuf"); 162 163 /* Align the source depth bits with the destination's, and mask out any 164 * stencil or padding bits from both */ 165 if(format_desc->channel[z_swizzle].size == format_desc->block.bits) { 166 assert(z_swizzle == 0); 167 /* nothing to do */ 168 } 169 else { 170 unsigned padding_left; 171 unsigned padding_right; 172 unsigned chan; 173 174 assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH); 175 assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); 176 assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits); 177 assert(format_desc->channel[z_swizzle].normalized); 178 179 padding_right = 0; 180 for(chan = 0; chan < z_swizzle; ++chan) 181 padding_right += format_desc->channel[chan].size; 182 padding_left = format_desc->block.bits - 183 (padding_right + format_desc->channel[z_swizzle].size); 184 185 if(padding_left || padding_right) { 186 const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1; 187 const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1; 188 z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right); 189 } 190 191 if(padding_left) 192 src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), ""); 193 if(padding_right) 194 src = LLVMBuildAnd(builder, src, z_bitmask, ""); 195 if(padding_left || padding_right) 196 dst = LLVMBuildAnd(builder, dst, z_bitmask, ""); 197 } 198 199 lp_build_name(dst, "zsbuf.z"); 200 201 test = lp_build_cmp(&bld, state->func, src, dst); 202 lp_build_mask_update(mask, test); 203 204 if(state->writemask) { 205 if(z_bitmask) 206 z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, ""); 207 else 208 z_bitmask = mask->value; 209 210 dst = lp_build_select(&bld, z_bitmask, src, dst); 211 LLVMBuildStore(builder, dst, dst_ptr); 212 } 213 214 /* FIXME */ 215 assert(!state->occlusion_count); 216} 217