lp_bld_depth.c revision 8df65e98998b4c104db30cbba8a38be7eb2a9acd
1343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca/************************************************************************** 2343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 3343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * Copyright 2009 VMware, Inc. 4343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * All Rights Reserved. 5343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 6343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * copy of this software and associated documentation files (the 8343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * "Software"), to deal in the Software without restriction, including 9343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to 12343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * the following conditions: 13343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 14343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * The above copyright notice and this permission notice (including the 15343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * next paragraph) shall be included in all copies or substantial portions 16343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * of the Software. 17343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 18343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 26343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca **************************************************************************/ 27343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 28343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca/** 295811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * @file 30343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * Depth/stencil testing to LLVM IR translation. 31343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 325811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * To be done accurately/efficiently the depth/stencil test must be done with 335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * the same type/format of the depth/stencil buffer, which implies massaging 345811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * the incoming depths to fit into place. Using a more straightforward 355811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * type/format for depth/stencil values internally and only convert when 365811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * flushing would avoid this, but it would most likely result in depth fighting 375811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * artifacts. 385811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 395811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * We are free to use a different pixel layout though. Since our basic 405811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * processing unit is a quad (2x2 pixel block) we store the depth/stencil 415811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * values tiled, a quad at time. That is, a depth buffer containing 425811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 435811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z11 Z12 Z13 Z14 ... 445811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z21 Z22 Z23 Z24 ... 455811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z31 Z32 Z33 Z34 ... 465811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z41 Z42 Z43 Z44 ... 475811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * ... ... ... ... ... 485811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 495811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * will actually be stored in memory as 505811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 515811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z11 Z12 Z21 Z22 Z13 Z14 Z23 Z24 ... 525811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ... 535811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * ... ... ... ... ... ... ... ... ... 545811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 55ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * 56ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Stencil test: 57ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Two-sided stencil test is supported but probably not as efficient as 58ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * it could be. Currently, we use if/then/else constructs to do the 59ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * operations for front vs. back-facing polygons. We could probably do 60ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * both the front and back arithmetic then use a Select() instruction to 61ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * choose the result depending on polyon orientation. We'd have to 62ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * measure performance both ways and see which is better. 635811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 64343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * @author Jose Fonseca <jfonseca@vmware.com> 65343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca */ 66343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 67343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "pipe/p_state.h" 68343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "util/u_format.h" 69343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 70343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_type.h" 71cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul#include "lp_bld_arit.h" 72343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_const.h" 73343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_logic.h" 743d7a88674f9eb3320eeff511968f041426e25023José Fonseca#include "lp_bld_flow.h" 75343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_debug.h" 76343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_depth.h" 77cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul#include "lp_bld_swizzle.h" 78cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 79cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 80ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** Used to select fields from pipe_stencil_state */ 81ecf85c7d750478e433e640897bb25a18069f14deBrian Paulenum stencil_op { 82ecf85c7d750478e433e640897bb25a18069f14deBrian Paul S_FAIL_OP, 83ecf85c7d750478e433e640897bb25a18069f14deBrian Paul Z_FAIL_OP, 84ecf85c7d750478e433e640897bb25a18069f14deBrian Paul Z_PASS_OP 85ecf85c7d750478e433e640897bb25a18069f14deBrian Paul}; 86ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 87ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 88cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 89cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul/** 90ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the stencil test comparison (compare FB stencil values against ref value). 91ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * This will be used twice when generating two-sided stencil code. 92ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \param stencil the front/back stencil state 93cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param stencilRef the stencil reference value, replicated as a vector 94ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \param stencilVals vector of stencil values from framebuffer 95ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \return vector mask of pass/fail values (~0 or 0) 96cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul */ 97cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paulstatic LLVMValueRef 98ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_test_single(struct lp_build_context *bld, 99ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state *stencil, 100ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRef, 101ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals) 102cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul{ 103cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul const unsigned stencilMax = 255; /* XXX fix */ 104cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul struct lp_type type = bld->type; 105cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef res; 106cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 10766b6676d141463b8229e62be6249efd1cb6873a8Brian Paul assert(type.sign); 10866b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 109cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul assert(stencil->enabled); 110cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 111cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul if (stencil->valuemask != stencilMax) { 112cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul /* compute stencilRef = stencilRef & valuemask */ 113cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask); 114cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, ""); 115cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul /* compute stencilVals = stencilVals & valuemask */ 116cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, ""); 117cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul } 118cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 119fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul res = lp_build_cmp(bld, stencil->func, stencilVals, stencilRef); 120cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 121cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul return res; 122cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul} 123cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 124cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 125cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul/** 126ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the one or two-sided stencil test comparison. 127ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \sa lp_build_stencil_test_single 128ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \param face an integer indicating front (+) or back (-) facing polygon. 129ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * If NULL, assume front-facing. 130ecf85c7d750478e433e640897bb25a18069f14deBrian Paul */ 131ecf85c7d750478e433e640897bb25a18069f14deBrian Paulstatic LLVMValueRef 132ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_test(struct lp_build_context *bld, 133ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state stencil[2], 134ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRefs[2], 135ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals, 136ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef face) 137ecf85c7d750478e433e640897bb25a18069f14deBrian Paul{ 138ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef res; 139ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 140ecf85c7d750478e433e640897bb25a18069f14deBrian Paul assert(stencil[0].enabled); 141ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 142ecf85c7d750478e433e640897bb25a18069f14deBrian Paul if (stencil[1].enabled && face) { 143ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* do two-sided test */ 144ecf85c7d750478e433e640897bb25a18069f14deBrian Paul struct lp_build_flow_context *flow_ctx; 145ecf85c7d750478e433e640897bb25a18069f14deBrian Paul struct lp_build_if_state if_ctx; 146ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef front_facing; 147ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); 14822e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul LLVMValueRef result = bld->undef; 149ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 150ecf85c7d750478e433e640897bb25a18069f14deBrian Paul flow_ctx = lp_build_flow_create(bld->builder); 151ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_begin(flow_ctx); 152ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 153ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_declare(flow_ctx, &result); 154ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 155ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* front_facing = face > 0.0 */ 15622e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, ""); 157ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 158ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing); 159ecf85c7d750478e433e640897bb25a18069f14deBrian Paul { 160ecf85c7d750478e433e640897bb25a18069f14deBrian Paul result = lp_build_stencil_test_single(bld, &stencil[0], 161ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[0], stencilVals); 162ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 163ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_else(&if_ctx); 164ecf85c7d750478e433e640897bb25a18069f14deBrian Paul { 165ecf85c7d750478e433e640897bb25a18069f14deBrian Paul result = lp_build_stencil_test_single(bld, &stencil[1], 166ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[1], stencilVals); 167ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 168ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_endif(&if_ctx); 169ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 170ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_end(flow_ctx); 171ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_destroy(flow_ctx); 172ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 173ecf85c7d750478e433e640897bb25a18069f14deBrian Paul res = result; 174ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 175ecf85c7d750478e433e640897bb25a18069f14deBrian Paul else { 176ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* do single-side test */ 177ecf85c7d750478e433e640897bb25a18069f14deBrian Paul res = lp_build_stencil_test_single(bld, &stencil[0], 178ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[0], stencilVals); 179ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 180ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 181ecf85c7d750478e433e640897bb25a18069f14deBrian Paul return res; 182ecf85c7d750478e433e640897bb25a18069f14deBrian Paul} 183ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 184ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 185ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** 186cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * Apply the stencil operator (add/sub/keep/etc) to the given vector 187cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * of stencil values. 188cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \return new stencil values vector 189cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul */ 190cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paulstatic LLVMValueRef 191ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_op_single(struct lp_build_context *bld, 192ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state *stencil, 193ecf85c7d750478e433e640897bb25a18069f14deBrian Paul enum stencil_op op, 194ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRef, 195ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals, 196ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef mask) 197cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 198cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul{ 199cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul const unsigned stencilMax = 255; /* XXX fix */ 200cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul struct lp_type type = bld->type; 201cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef res; 202cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef max = lp_build_const_int_vec(type, stencilMax); 203ecf85c7d750478e433e640897bb25a18069f14deBrian Paul unsigned stencil_op; 204ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 20566b6676d141463b8229e62be6249efd1cb6873a8Brian Paul assert(type.sign); 20666b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 207ecf85c7d750478e433e640897bb25a18069f14deBrian Paul switch (op) { 208ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case S_FAIL_OP: 209ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->fail_op; 210ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 211ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case Z_FAIL_OP: 212ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->zfail_op; 213ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 214ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case Z_PASS_OP: 215ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->zpass_op; 216ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 217ecf85c7d750478e433e640897bb25a18069f14deBrian Paul default: 218ecf85c7d750478e433e640897bb25a18069f14deBrian Paul assert(0 && "Invalid stencil_op mode"); 219ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = PIPE_STENCIL_OP_KEEP; 220ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 221cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 222cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul switch (stencil_op) { 223cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_KEEP: 224cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = stencilVals; 225fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* we can return early for this case */ 226fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul return res; 227cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_ZERO: 228cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = bld->zero; 229fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 230cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_REPLACE: 231fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul res = stencilRef; 232fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 233cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INCR: 234cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_add(bld, stencilVals, bld->one); 235cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_min(bld, res, max); 236fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 237cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_DECR: 238cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_sub(bld, stencilVals, bld->one); 239cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_max(bld, res, bld->zero); 240fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 241cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INCR_WRAP: 242cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_add(bld, stencilVals, bld->one); 243cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = LLVMBuildAnd(bld->builder, res, max, ""); 244fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 245cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_DECR_WRAP: 246cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_sub(bld, stencilVals, bld->one); 247cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = LLVMBuildAnd(bld->builder, res, max, ""); 248fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 249cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INVERT: 250cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = LLVMBuildNot(bld->builder, stencilVals, ""); 25166b6676d141463b8229e62be6249efd1cb6873a8Brian Paul res = LLVMBuildAnd(bld->builder, res, max, ""); 252fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 253cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul default: 254cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul assert(0 && "bad stencil op mode"); 255cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = NULL; 256cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul } 257cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 258cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul if (stencil->writemask != stencilMax) { 259cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul /* compute res = (res & mask) | (stencilVals & ~mask) */ 260cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask); 261cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask"); 262cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1"); 263cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2"); 264cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2"); 265cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul } 266cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 267fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* only the update the vector elements enabled by 'mask' */ 268fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul res = lp_build_select(bld, mask, res, stencilVals); 269fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 270cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul return res; 271cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul} 272343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 273343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 2745811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca/** 275ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the one or two-sided stencil test op/update. 276ecf85c7d750478e433e640897bb25a18069f14deBrian Paul */ 277ecf85c7d750478e433e640897bb25a18069f14deBrian Paulstatic LLVMValueRef 278ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_op(struct lp_build_context *bld, 279ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state stencil[2], 280ecf85c7d750478e433e640897bb25a18069f14deBrian Paul enum stencil_op op, 281ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRefs[2], 282ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals, 283ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef mask, 284ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef face) 285ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 286ecf85c7d750478e433e640897bb25a18069f14deBrian Paul{ 287ecf85c7d750478e433e640897bb25a18069f14deBrian Paul assert(stencil[0].enabled); 288ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 289ecf85c7d750478e433e640897bb25a18069f14deBrian Paul if (stencil[1].enabled && face) { 290ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* do two-sided op */ 291ecf85c7d750478e433e640897bb25a18069f14deBrian Paul struct lp_build_flow_context *flow_ctx; 292ecf85c7d750478e433e640897bb25a18069f14deBrian Paul struct lp_build_if_state if_ctx; 293ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef front_facing; 294ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); 29522e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul LLVMValueRef result = bld->undef; 296ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 297ecf85c7d750478e433e640897bb25a18069f14deBrian Paul flow_ctx = lp_build_flow_create(bld->builder); 298ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_begin(flow_ctx); 299ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 300ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_declare(flow_ctx, &result); 301ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 302ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* front_facing = face > 0.0 */ 30322e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, ""); 304ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 305ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing); 306ecf85c7d750478e433e640897bb25a18069f14deBrian Paul { 307ecf85c7d750478e433e640897bb25a18069f14deBrian Paul result = lp_build_stencil_op_single(bld, &stencil[0], op, 308ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[0], stencilVals, mask); 309ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 310ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_else(&if_ctx); 311ecf85c7d750478e433e640897bb25a18069f14deBrian Paul { 312ecf85c7d750478e433e640897bb25a18069f14deBrian Paul result = lp_build_stencil_op_single(bld, &stencil[1], op, 313ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[1], stencilVals, mask); 314ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 315ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_endif(&if_ctx); 316ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 317ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_scope_end(flow_ctx); 318ecf85c7d750478e433e640897bb25a18069f14deBrian Paul lp_build_flow_destroy(flow_ctx); 319ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 320ecf85c7d750478e433e640897bb25a18069f14deBrian Paul return result; 321ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 322ecf85c7d750478e433e640897bb25a18069f14deBrian Paul else { 323ecf85c7d750478e433e640897bb25a18069f14deBrian Paul /* do single-sided op */ 324ecf85c7d750478e433e640897bb25a18069f14deBrian Paul return lp_build_stencil_op_single(bld, &stencil[0], op, 325ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencilRefs[0], stencilVals, mask); 326ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 327ecf85c7d750478e433e640897bb25a18069f14deBrian Paul} 328ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 329ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 330ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 331ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** 3325811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Return a type appropriate for depth/stencil testing. 3335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca */ 334b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecastruct lp_type 335343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonsecalp_depth_type(const struct util_format_description *format_desc, 336343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned length) 337343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca{ 338b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca struct lp_type type; 339343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned swizzle; 340343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 341343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 342343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.width == 1); 343343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.height == 1); 344343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 345343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca swizzle = format_desc->swizzle[0]; 346343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(swizzle < 4); 347343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 348b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca memset(&type, 0, sizeof type); 349343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.width = format_desc->block.bits; 350343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 351343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) { 352343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.floating = TRUE; 35352df532b02594e624bddd58ee60fd25075f8ec42José Fonseca assert(swizzle == 0); 354343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[swizzle].size == format_desc->block.bits); 355343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 356343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) { 357343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.bits <= 32); 358343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(format_desc->channel[swizzle].normalized) 359343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.norm = TRUE; 360343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 361343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else 362343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(0); 363343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 364343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(type.width <= length); 365343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.length = length / type.width; 366343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 367343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca return type; 368343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca} 369343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 370343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 3715811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca/** 372cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * Generate code for performing depth and/or stencil tests. 373cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * We operate on a vector of values (typically a 2x2 quad). 374cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * 37522e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param depth the depth test state 37622e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param stencil the front/back stencil state 377cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param type the data type of the fragment depth/stencil values 378cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param format_desc description of the depth/stencil surface 37922e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param mask the alive/dead pixel mask for the quad (vector) 38022e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param stencil_refs the front/back stencil ref values (scalar) 38122e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param z_src the incoming depth/stencil values (a 2x2 quad) 38222e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param zs_dst_ptr pointer to depth/stencil values in framebuffer 38322e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param facing contains float value indicating front/back facing polygon 3845811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca */ 385343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonsecavoid 386d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paullp_build_depth_stencil_test(LLVMBuilderRef builder, 387d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct pipe_depth_state *depth, 388d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct pipe_stencil_state stencil[2], 389d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul struct lp_type type, 390d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct util_format_description *format_desc, 391d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul struct lp_build_mask_context *mask, 392521c61ff017ab15b829abbe9a98b179136a36009Brian Paul LLVMValueRef stencil_refs[2], 393d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul LLVMValueRef z_src, 39422e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul LLVMValueRef zs_dst_ptr, 39522e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul LLVMValueRef face) 396343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca{ 397343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca struct lp_build_context bld; 39866b6676d141463b8229e62be6249efd1cb6873a8Brian Paul struct lp_build_context sbld; 39966b6676d141463b8229e62be6249efd1cb6873a8Brian Paul struct lp_type s_type; 400d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul unsigned z_swizzle, s_swizzle; 401fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef zs_dst, z_dst = NULL; 402fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef stencil_vals = NULL; 4038df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul LLVMValueRef z_bitmask = NULL, s_bitmask = NULL, s_shift = NULL; 404fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef z_pass = NULL, s_pass_mask = NULL; 405fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef orig_mask = mask->value; 406cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 407d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul assert(depth->enabled || stencil[0].enabled); 408343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 409343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 410343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.width == 1); 411343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.height == 1); 412343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 413343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca z_swizzle = format_desc->swizzle[0]; 414d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul s_swizzle = format_desc->swizzle[1]; 415d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul 416d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE || 417d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul s_swizzle != UTIL_FORMAT_SWIZZLE_NONE); 418343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 4198df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul if (stencil[0].enabled) { 4208df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul assert(format_desc->format == PIPE_FORMAT_Z24S8_UNORM || 4218df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul format_desc->format == PIPE_FORMAT_S8Z24_UNORM); 4228df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul } 4238df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul 424343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca /* Sanity checking */ 425343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(z_swizzle < 4); 426343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.bits == type.width); 427343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(type.floating) { 428343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(z_swizzle == 0); 429343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT); 430343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].size == format_desc->block.bits); 431343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 432343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else { 433343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); 434343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].normalized); 435343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(!type.fixed); 436343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(!type.sign); 437343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(type.norm); 438343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 439343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 44066b6676d141463b8229e62be6249efd1cb6873a8Brian Paul /* Setup build context for Z vals */ 441343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca lp_build_context_init(&bld, builder, type); 442343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 44366b6676d141463b8229e62be6249efd1cb6873a8Brian Paul /* Setup build context for stencil vals */ 44466b6676d141463b8229e62be6249efd1cb6873a8Brian Paul s_type = lp_type_int_vec(type.width); 44566b6676d141463b8229e62be6249efd1cb6873a8Brian Paul lp_build_context_init(&sbld, builder, s_type); 44666b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 447fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* Load current z/stencil value from z/stencil buffer */ 448d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, ""); 449343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 450fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_name(zs_dst, "zsbufval"); 451343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 452343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca /* Align the source depth bits with the destination's, and mask out any 453343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * stencil or padding bits from both */ 454343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(format_desc->channel[z_swizzle].size == format_desc->block.bits) { 455343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(z_swizzle == 0); 456fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_dst = zs_dst; 457343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 458343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else { 459d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul /* shift/mask bits to right-justify the Z bits */ 460343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned padding_left; 461343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned padding_right; 462343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned chan; 463343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 464e5a43ac594e7b4c072b90310f7193c341b015f6bJosé Fonseca assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); 465343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); 466343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits); 467343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[z_swizzle].normalized); 468343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 469343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca padding_right = 0; 470343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca for(chan = 0; chan < z_swizzle; ++chan) 471343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca padding_right += format_desc->channel[chan].size; 472abc160b664c3fbd4c18a2cd3402c9a84f5f2d00fJosé Fonseca padding_left = format_desc->block.bits - 473abc160b664c3fbd4c18a2cd3402c9a84f5f2d00fJosé Fonseca (padding_right + format_desc->channel[z_swizzle].size); 474343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 475343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(padding_left || padding_right) { 476d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const unsigned long long mask_left = (1ULL << (format_desc->block.bits - padding_left)) - 1; 477d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const unsigned long long mask_right = (1ULL << (padding_right)) - 1; 478185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul z_bitmask = lp_build_const_int_vec(type, mask_left ^ mask_right); 479343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 480343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 4818df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul /* If PIPE_FORMAT_Z24S8, we'll shift zs >> 24 to position stencil_vals */ 4828df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul if (format_desc->format == PIPE_FORMAT_Z24S8_UNORM) 4838df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul s_shift = lp_build_const_int_vec(type, 24); 4848df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul else 4858df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul s_shift = lp_build_const_int_vec(type, 0); 4868df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul 4878df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul s_bitmask = lp_build_const_int_vec(s_type, 0xff); 488fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 4898df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul stencil_vals = LLVMBuildLShr(builder, zs_dst, s_shift, ""); 4908df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul stencil_vals = LLVMBuildAnd(builder, stencil_vals, s_bitmask, ""); 491fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 492343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(padding_left) 493d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul z_src = LLVMBuildLShr(builder, z_src, 494d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul lp_build_const_int_vec(type, padding_left), ""); 495343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(padding_right) 496d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul z_src = LLVMBuildAnd(builder, z_src, z_bitmask, ""); 497343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(padding_left || padding_right) 498fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_dst = LLVMBuildAnd(builder, zs_dst, z_bitmask, ""); 499fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else 500fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_dst = zs_dst; 501343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 502343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 503fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_name(z_dst, "zsbuf.z"); 504fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 505521c61ff017ab15b829abbe9a98b179136a36009Brian Paul /* 506fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul printf("build depth %d stencil %d\n", 507fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul depth->enabled, 508fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil[0].enabled); 509521c61ff017ab15b829abbe9a98b179136a36009Brian Paul */ 510fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 511fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (stencil[0].enabled) { 512521c61ff017ab15b829abbe9a98b179136a36009Brian Paul /* convert scalar stencil refs into vectors */ 513521c61ff017ab15b829abbe9a98b179136a36009Brian Paul stencil_refs[0] = lp_build_broadcast_scalar(&bld, stencil_refs[0]); 514521c61ff017ab15b829abbe9a98b179136a36009Brian Paul stencil_refs[1] = lp_build_broadcast_scalar(&bld, stencil_refs[1]); 515ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 516343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 51766b6676d141463b8229e62be6249efd1cb6873a8Brian Paul s_pass_mask = lp_build_stencil_test(&sbld, stencil, 518ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_refs, stencil_vals, face); 519343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 520fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply stencil-fail operator */ 521fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul { 522fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef s_fail_mask = lp_build_andc(&bld, orig_mask, s_pass_mask); 52366b6676d141463b8229e62be6249efd1cb6873a8Brian Paul stencil_vals = lp_build_stencil_op(&sbld, stencil, S_FAIL_OP, 524fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 525ecf85c7d750478e433e640897bb25a18069f14deBrian Paul s_fail_mask, face); 526fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 527fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 528fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 529fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->enabled) { 530fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* compare src Z to dst Z, returning 'pass' mask */ 531fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_pass = lp_build_cmp(&bld, depth->func, z_src, z_dst); 532fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 533fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (!stencil[0].enabled) { 534fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* We can potentially skip all remaining operations here, but only 535fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * if stencil is disabled because we still need to update the stencil 536fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * buffer values. Don't need to update Z buffer values. 537fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul */ 538fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, z_pass); 539fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 540fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 541fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->writemask) { 542fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if(z_bitmask) 543fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, ""); 544fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else 545fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_bitmask = mask->value; 546fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 547fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_dst = lp_build_select(&bld, z_bitmask, z_src, z_dst); 548fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 549fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 550fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (stencil[0].enabled) { 551fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* update stencil buffer values according to z pass/fail result */ 552fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef z_fail_mask, z_pass_mask; 553fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 554fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply Z-fail operator */ 555fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_fail_mask = lp_build_andc(&bld, orig_mask, z_pass); 55666b6676d141463b8229e62be6249efd1cb6873a8Brian Paul stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_FAIL_OP, 557fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 558ecf85c7d750478e433e640897bb25a18069f14deBrian Paul z_fail_mask, face); 559fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 560fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply Z-pass operator */ 561fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul z_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, z_pass, ""); 56266b6676d141463b8229e62be6249efd1cb6873a8Brian Paul stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP, 563fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 564ecf85c7d750478e433e640897bb25a18069f14deBrian Paul z_pass_mask, face); 565fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 566fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 567fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else { 568fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* No depth test: apply Z-pass operator to stencil buffer values which 569fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * passed the stencil test. 570fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul */ 571fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul s_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, s_pass_mask, ""); 57266b6676d141463b8229e62be6249efd1cb6873a8Brian Paul stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP, stencil_refs, 573ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_vals, s_pass_mask, face); 574fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 575fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 5768df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul if (stencil_vals) 5778df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul stencil_vals = LLVMBuildShl(bld.builder, stencil_vals, s_shift, ""); 5788df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul 579fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* Finally, merge/store the z/stencil values */ 580fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if ((depth->enabled && depth->writemask) || 581fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul (stencil[0].enabled && stencil[0].writemask)) { 582fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 583fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (z_dst && stencil_vals) 584fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul zs_dst = LLVMBuildOr(bld.builder, z_dst, stencil_vals, ""); 585fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else if (z_dst) 586fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul zs_dst = z_dst; 587343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else 588fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul zs_dst = stencil_vals; 589343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 590d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul LLVMBuildStore(builder, zs_dst, zs_dst_ptr); 591343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 592fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 593fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (s_pass_mask) 594fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, s_pass_mask); 595fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 596fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->enabled && stencil[0].enabled) 597fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, z_pass); 598343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca} 599