1343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca/************************************************************************** 2343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * 3b18fecbd0ea33c9db7e3fd676ed7b5877ebb1bd5José Fonseca * Copyright 2009-2010 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 * 56343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca * @author Jose Fonseca <jfonseca@vmware.com> 57b18fecbd0ea33c9db7e3fd676ed7b5877ebb1bd5José Fonseca * @author Brian Paul <jfonseca@vmware.com> 58343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca */ 59343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 60343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "pipe/p_state.h" 61343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "util/u_format.h" 623469715a8a171512cf9b528702e70393f01c6041José Fonseca#include "util/u_cpu_detect.h" 63343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 64f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_type.h" 65f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_arit.h" 66795eb3d64a001a65d677e3168bdd056cc5385b7eJosé Fonseca#include "gallivm/lp_bld_bitarit.h" 67f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_const.h" 68d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell#include "gallivm/lp_bld_conv.h" 69f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_logic.h" 70f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_flow.h" 7186afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li#include "gallivm/lp_bld_intr.h" 72f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_debug.h" 73f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul#include "gallivm/lp_bld_swizzle.h" 74f17d1513ac1912d8cc090bba9206a08ff991f64fBrian Paul 75343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca#include "lp_bld_depth.h" 76cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 77cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 78ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** Used to select fields from pipe_stencil_state */ 79ecf85c7d750478e433e640897bb25a18069f14deBrian Paulenum stencil_op { 80ecf85c7d750478e433e640897bb25a18069f14deBrian Paul S_FAIL_OP, 81ecf85c7d750478e433e640897bb25a18069f14deBrian Paul Z_FAIL_OP, 82ecf85c7d750478e433e640897bb25a18069f14deBrian Paul Z_PASS_OP 83ecf85c7d750478e433e640897bb25a18069f14deBrian Paul}; 84ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 85ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 86cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 87cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul/** 88ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the stencil test comparison (compare FB stencil values against ref value). 89ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * This will be used twice when generating two-sided stencil code. 90ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \param stencil the front/back stencil state 91cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param stencilRef the stencil reference value, replicated as a vector 92ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \param stencilVals vector of stencil values from framebuffer 93ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \return vector mask of pass/fail values (~0 or 0) 94cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul */ 95cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paulstatic LLVMValueRef 96ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_test_single(struct lp_build_context *bld, 97ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state *stencil, 98ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRef, 99ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals) 100cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul{ 1016299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul LLVMBuilderRef builder = bld->gallivm->builder; 102cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul const unsigned stencilMax = 255; /* XXX fix */ 103cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul struct lp_type type = bld->type; 104cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef res; 105cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 1063469715a8a171512cf9b528702e70393f01c6041José Fonseca /* 1073469715a8a171512cf9b528702e70393f01c6041José Fonseca * SSE2 has intrinsics for signed comparisons, but not unsigned ones. Values 1083469715a8a171512cf9b528702e70393f01c6041José Fonseca * are between 0..255 so ensure we generate the fastest comparisons for 1093469715a8a171512cf9b528702e70393f01c6041José Fonseca * wider elements. 1103469715a8a171512cf9b528702e70393f01c6041José Fonseca */ 1113469715a8a171512cf9b528702e70393f01c6041José Fonseca if (type.width <= 8) { 1123469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(!type.sign); 1133469715a8a171512cf9b528702e70393f01c6041José Fonseca } else { 1143469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(type.sign); 1153469715a8a171512cf9b528702e70393f01c6041José Fonseca } 11666b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 117cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul assert(stencil->enabled); 118cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 119cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul if (stencil->valuemask != stencilMax) { 120cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul /* compute stencilRef = stencilRef & valuemask */ 121efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef valuemask = lp_build_const_int_vec(bld->gallivm, type, stencil->valuemask); 1226299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul stencilRef = LLVMBuildAnd(builder, stencilRef, valuemask, ""); 123cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul /* compute stencilVals = stencilVals & valuemask */ 1246299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul stencilVals = LLVMBuildAnd(builder, stencilVals, valuemask, ""); 125cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul } 126cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 1277a01b13324f9d25a67f81ac370eb50e36c032ad4Brian Paul res = lp_build_cmp(bld, stencil->func, stencilRef, stencilVals); 128cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 129cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul return res; 130cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul} 131cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 132cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 133cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul/** 134ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the one or two-sided stencil test comparison. 135ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * \sa lp_build_stencil_test_single 136d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca * \param front_facing an integer vector mask, indicating front (~0) or back 137d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca * (0) facing polygon. If NULL, assume front-facing. 138ecf85c7d750478e433e640897bb25a18069f14deBrian Paul */ 139ecf85c7d750478e433e640897bb25a18069f14deBrian Paulstatic LLVMValueRef 140ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_test(struct lp_build_context *bld, 141ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state stencil[2], 142ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRefs[2], 143ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals, 144d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef front_facing) 145ecf85c7d750478e433e640897bb25a18069f14deBrian Paul{ 146ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef res; 147ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 148ecf85c7d750478e433e640897bb25a18069f14deBrian Paul assert(stencil[0].enabled); 149ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 150d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* do front face test */ 151d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = lp_build_stencil_test_single(bld, &stencil[0], 152d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca stencilRefs[0], stencilVals); 153ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 154c7aa8da9573f6d505bec894b4738f0521511b9f0Brian Paul if (stencil[1].enabled && front_facing != NULL) { 155d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* do back face test */ 156d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef back_res; 157ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 158d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca back_res = lp_build_stencil_test_single(bld, &stencil[1], 159d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca stencilRefs[1], stencilVals); 160ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 161d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = lp_build_select(bld, front_facing, res, back_res); 162ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 163ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 164ecf85c7d750478e433e640897bb25a18069f14deBrian Paul return res; 165ecf85c7d750478e433e640897bb25a18069f14deBrian Paul} 166ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 167ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 168ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** 169cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * Apply the stencil operator (add/sub/keep/etc) to the given vector 170cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * of stencil values. 171cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \return new stencil values vector 172cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul */ 173cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paulstatic LLVMValueRef 174ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_op_single(struct lp_build_context *bld, 175ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state *stencil, 176ecf85c7d750478e433e640897bb25a18069f14deBrian Paul enum stencil_op op, 177ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRef, 178d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef stencilVals) 179cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 180cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul{ 1816299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul LLVMBuilderRef builder = bld->gallivm->builder; 182cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul struct lp_type type = bld->type; 183cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul LLVMValueRef res; 184efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef max = lp_build_const_int_vec(bld->gallivm, type, 0xff); 185ecf85c7d750478e433e640897bb25a18069f14deBrian Paul unsigned stencil_op; 186ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 18766b6676d141463b8229e62be6249efd1cb6873a8Brian Paul assert(type.sign); 18866b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 189ecf85c7d750478e433e640897bb25a18069f14deBrian Paul switch (op) { 190ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case S_FAIL_OP: 191ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->fail_op; 192ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 193ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case Z_FAIL_OP: 194ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->zfail_op; 195ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 196ecf85c7d750478e433e640897bb25a18069f14deBrian Paul case Z_PASS_OP: 197ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = stencil->zpass_op; 198ecf85c7d750478e433e640897bb25a18069f14deBrian Paul break; 199ecf85c7d750478e433e640897bb25a18069f14deBrian Paul default: 200ecf85c7d750478e433e640897bb25a18069f14deBrian Paul assert(0 && "Invalid stencil_op mode"); 201ecf85c7d750478e433e640897bb25a18069f14deBrian Paul stencil_op = PIPE_STENCIL_OP_KEEP; 202ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 203cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 204cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul switch (stencil_op) { 205cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_KEEP: 206cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = stencilVals; 207fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* we can return early for this case */ 208fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul return res; 209cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_ZERO: 210cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = bld->zero; 211fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 212cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_REPLACE: 213fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul res = stencilRef; 214fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 215cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INCR: 216cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_add(bld, stencilVals, bld->one); 217cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_min(bld, res, max); 218fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 219cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_DECR: 220cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_sub(bld, stencilVals, bld->one); 221cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_max(bld, res, bld->zero); 222fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 223cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INCR_WRAP: 224cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_add(bld, stencilVals, bld->one); 2256299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul res = LLVMBuildAnd(builder, res, max, ""); 226fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 227cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_DECR_WRAP: 228cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul res = lp_build_sub(bld, stencilVals, bld->one); 2296299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul res = LLVMBuildAnd(builder, res, max, ""); 230fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 231cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul case PIPE_STENCIL_OP_INVERT: 2326299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul res = LLVMBuildNot(builder, stencilVals, ""); 2336299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul res = LLVMBuildAnd(builder, res, max, ""); 234fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul break; 235cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul default: 236cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul assert(0 && "bad stencil op mode"); 237d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = bld->undef; 238cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul } 239fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 240cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul return res; 241cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul} 242343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 243343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 2445811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca/** 245ecf85c7d750478e433e640897bb25a18069f14deBrian Paul * Do the one or two-sided stencil test op/update. 246ecf85c7d750478e433e640897bb25a18069f14deBrian Paul */ 247ecf85c7d750478e433e640897bb25a18069f14deBrian Paulstatic LLVMValueRef 248ecf85c7d750478e433e640897bb25a18069f14deBrian Paullp_build_stencil_op(struct lp_build_context *bld, 249ecf85c7d750478e433e640897bb25a18069f14deBrian Paul const struct pipe_stencil_state stencil[2], 250ecf85c7d750478e433e640897bb25a18069f14deBrian Paul enum stencil_op op, 251ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilRefs[2], 252ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef stencilVals, 253ecf85c7d750478e433e640897bb25a18069f14deBrian Paul LLVMValueRef mask, 254d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef front_facing) 255ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 256ecf85c7d750478e433e640897bb25a18069f14deBrian Paul{ 2576299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul LLVMBuilderRef builder = bld->gallivm->builder; 258d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef res; 259ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 260d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca assert(stencil[0].enabled); 261ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 262d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* do front face op */ 263d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = lp_build_stencil_op_single(bld, &stencil[0], op, 264d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca stencilRefs[0], stencilVals); 265ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 266c7aa8da9573f6d505bec894b4738f0521511b9f0Brian Paul if (stencil[1].enabled && front_facing != NULL) { 267d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* do back face op */ 268d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef back_res; 269ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 270d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca back_res = lp_build_stencil_op_single(bld, &stencil[1], op, 271d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca stencilRefs[1], stencilVals); 272ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 273d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = lp_build_select(bld, front_facing, res, back_res); 274d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca } 275ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 2769e1050d72fb78b56b03304727abb122713a90ed1José Fonseca if (stencil[0].writemask != 0xff || 2779e1050d72fb78b56b03304727abb122713a90ed1José Fonseca (stencil[1].enabled && front_facing != NULL && stencil[1].writemask != 0xff)) { 27833abbd4fbdb3149df5ecc296b04a79225962e433Brian Paul /* mask &= stencil[0].writemask */ 279efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef writemask = lp_build_const_int_vec(bld->gallivm, bld->type, 28033abbd4fbdb3149df5ecc296b04a79225962e433Brian Paul stencil[0].writemask); 2819e1050d72fb78b56b03304727abb122713a90ed1José Fonseca if (stencil[1].enabled && stencil[1].writemask != stencil[0].writemask && front_facing != NULL) { 2829e1050d72fb78b56b03304727abb122713a90ed1José Fonseca LLVMValueRef back_writemask = lp_build_const_int_vec(bld->gallivm, bld->type, 2839e1050d72fb78b56b03304727abb122713a90ed1José Fonseca stencil[1].writemask); 2849e1050d72fb78b56b03304727abb122713a90ed1José Fonseca writemask = lp_build_select(bld, front_facing, writemask, back_writemask); 2859e1050d72fb78b56b03304727abb122713a90ed1José Fonseca } 2869e1050d72fb78b56b03304727abb122713a90ed1José Fonseca 2876299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul mask = LLVMBuildAnd(builder, mask, writemask, ""); 288d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* res = (res & mask) | (stencilVals & ~mask) */ 289dbf996f30856c000e18e3700f741d4e92561b4ecBrian Paul res = lp_build_select_bitwise(bld, mask, res, stencilVals); 290ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 291ecf85c7d750478e433e640897bb25a18069f14deBrian Paul else { 292d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca /* res = mask ? res : stencilVals */ 293d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca res = lp_build_select(bld, mask, res, stencilVals); 294ecf85c7d750478e433e640897bb25a18069f14deBrian Paul } 295d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca 296d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca return res; 297ecf85c7d750478e433e640897bb25a18069f14deBrian Paul} 298ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 299ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 300ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 301ecf85c7d750478e433e640897bb25a18069f14deBrian Paul/** 3025811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Return a type appropriate for depth/stencil testing. 3035811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca */ 304b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecastruct lp_type 305343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonsecalp_depth_type(const struct util_format_description *format_desc, 306343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned length) 307343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca{ 308b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca struct lp_type type; 309343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca unsigned swizzle; 310343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 311343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 312343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.width == 1); 313343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.height == 1); 314343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 315343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca swizzle = format_desc->swizzle[0]; 316343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(swizzle < 4); 317343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 318b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca memset(&type, 0, sizeof type); 319343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.width = format_desc->block.bits; 320343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 321343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) { 322343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.floating = TRUE; 32352df532b02594e624bddd58ee60fd25075f8ec42José Fonseca assert(swizzle == 0); 324343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->channel[swizzle].size == format_desc->block.bits); 325343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 326343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) { 327343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(format_desc->block.bits <= 32); 328ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(format_desc->channel[swizzle].normalized); 329ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca if (format_desc->channel[swizzle].size < format_desc->block.bits) { 330ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca /* Prefer signed integers when possible, as SSE has less support 331ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca * for unsigned comparison; 332ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca */ 333ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca type.sign = TRUE; 334ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } 335343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 336343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else 337343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(0); 338343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 339343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca assert(type.width <= length); 340343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca type.length = length / type.width; 341343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 342343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca return type; 343343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca} 344343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 345343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 3465811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca/** 34705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * Compute bitmask and bit shift to apply to the incoming fragment Z values 34805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * and the Z buffer values needed before doing the Z comparison. 34905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * 35005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * Note that we leave the Z bits in the position that we find them 35105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * in the Z buffer (typically 0xffffff00 or 0x00ffffff). That lets us 35205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * get by with fewer bit twiddling steps. 35305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul */ 354914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonsecastatic boolean 35505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paulget_z_shift_and_mask(const struct util_format_description *format_desc, 356ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca unsigned *shift, unsigned *width, unsigned *mask) 35705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul{ 35805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul const unsigned total_bits = format_desc->block.bits; 35905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned z_swizzle; 3604593e0c85e75a274de0092a5b40c624b6a055acbBrian Paul unsigned chan; 36105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned padding_left, padding_right; 36205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 36305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 36405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->block.width == 1); 36505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->block.height == 1); 36605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 36705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul z_swizzle = format_desc->swizzle[0]; 36805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 369914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca if (z_swizzle == UTIL_FORMAT_SWIZZLE_NONE) 370914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca return FALSE; 371ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 372ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca *width = format_desc->channel[z_swizzle].size; 37305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 37405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul padding_right = 0; 37505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul for (chan = 0; chan < z_swizzle; ++chan) 37605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul padding_right += format_desc->channel[chan].size; 37705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 37805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul padding_left = 379ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca total_bits - (padding_right + *width); 38005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 38105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (padding_left || padding_right) { 38205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned long long mask_left = (1ULL << (total_bits - padding_left)) - 1; 38305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned long long mask_right = (1ULL << (padding_right)) - 1; 38405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul *mask = mask_left ^ mask_right; 38505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 38605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul else { 38705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul *mask = 0xffffffff; 38805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 38905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 390ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca *shift = padding_right; 391914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca 392914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca return TRUE; 39305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul} 39405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 39505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 39605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul/** 39705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * Compute bitmask and bit shift to apply to the framebuffer pixel values 39805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * to put the stencil bits in the least significant position. 39905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul * (i.e. 0x000000ff) 40005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul */ 40105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paulstatic boolean 40205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paulget_s_shift_and_mask(const struct util_format_description *format_desc, 40305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned *shift, unsigned *mask) 40405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul{ 40505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned s_swizzle; 4064593e0c85e75a274de0092a5b40c624b6a055acbBrian Paul unsigned chan, sz; 40705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 40805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul s_swizzle = format_desc->swizzle[1]; 40905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 41005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (s_swizzle == UTIL_FORMAT_SWIZZLE_NONE) 41105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul return FALSE; 41205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 41305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul *shift = 0; 41405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul for (chan = 0; chan < s_swizzle; chan++) 41505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul *shift += format_desc->channel[chan].size; 41605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 41705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul sz = format_desc->channel[s_swizzle].size; 41805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul *mask = (1U << sz) - 1U; 41905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 42005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul return TRUE; 42105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul} 42205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 42305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 42486afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li/** 42586afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * Perform the occlusion test and increase the counter. 42686afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * Test the depth mask. Add the number of channel which has none zero mask 42786afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * into the occlusion counter. e.g. maskvalue is {-1, -1, -1, -1}. 42886afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * The counter will add 4. 42986afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * 43086afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * \param type holds element type of the mask vector. 43186afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * \param maskvalue is the depth test mask. 43286afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li * \param counter is a pointer of the uint32 counter. 43386afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li */ 4345b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwellvoid 435efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_occlusion_count(struct gallivm_state *gallivm, 43686afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li struct lp_type type, 43786afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li LLVMValueRef maskvalue, 43886afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li LLVMValueRef counter) 43986afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li{ 440efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMBuilderRef builder = gallivm->builder; 441efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMContextRef context = gallivm->context; 442efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef countmask = lp_build_const_int_vec(gallivm, type, 1); 4433469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef count, newcount; 4443469715a8a171512cf9b528702e70393f01c6041José Fonseca 4453469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(type.length <= 16); 4463469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(type.floating); 4473469715a8a171512cf9b528702e70393f01c6041José Fonseca 4483469715a8a171512cf9b528702e70393f01c6041José Fonseca if(util_cpu_caps.has_sse && type.length == 4) { 4493469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *movmskintr = "llvm.x86.sse.movmsk.ps"; 4503469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *popcntintr = "llvm.ctpop.i32"; 4513469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef bits = LLVMBuildBitCast(builder, maskvalue, 4523469715a8a171512cf9b528702e70393f01c6041José Fonseca lp_build_vec_type(gallivm, type), ""); 4533469715a8a171512cf9b528702e70393f01c6041José Fonseca bits = lp_build_intrinsic_unary(builder, movmskintr, 4543469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMInt32TypeInContext(context), bits); 4553469715a8a171512cf9b528702e70393f01c6041José Fonseca count = lp_build_intrinsic_unary(builder, popcntintr, 4563469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMInt32TypeInContext(context), bits); 4573469715a8a171512cf9b528702e70393f01c6041José Fonseca } 4583469715a8a171512cf9b528702e70393f01c6041José Fonseca else if(util_cpu_caps.has_avx && type.length == 8) { 4593469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *movmskintr = "llvm.x86.avx.movmsk.ps.256"; 4603469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *popcntintr = "llvm.ctpop.i32"; 4613469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef bits = LLVMBuildBitCast(builder, maskvalue, 4623469715a8a171512cf9b528702e70393f01c6041José Fonseca lp_build_vec_type(gallivm, type), ""); 4633469715a8a171512cf9b528702e70393f01c6041José Fonseca bits = lp_build_intrinsic_unary(builder, movmskintr, 4643469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMInt32TypeInContext(context), bits); 4653469715a8a171512cf9b528702e70393f01c6041José Fonseca count = lp_build_intrinsic_unary(builder, popcntintr, 4663469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMInt32TypeInContext(context), bits); 4673469715a8a171512cf9b528702e70393f01c6041José Fonseca } 4683469715a8a171512cf9b528702e70393f01c6041José Fonseca else { 4693469715a8a171512cf9b528702e70393f01c6041José Fonseca unsigned i; 4703469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef countv = LLVMBuildAnd(builder, maskvalue, countmask, "countv"); 4713469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMTypeRef counttype = LLVMIntTypeInContext(context, type.length * 8); 4723469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMTypeRef i8vntype = LLVMVectorType(LLVMInt8TypeInContext(context), type.length * 4); 4733469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef shufflev, countd; 4743469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef shuffles[16]; 4753469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *popcntintr = NULL; 4763469715a8a171512cf9b528702e70393f01c6041José Fonseca 4773469715a8a171512cf9b528702e70393f01c6041José Fonseca countv = LLVMBuildBitCast(builder, countv, i8vntype, ""); 4783469715a8a171512cf9b528702e70393f01c6041José Fonseca 4793469715a8a171512cf9b528702e70393f01c6041José Fonseca for (i = 0; i < type.length; i++) { 4803469715a8a171512cf9b528702e70393f01c6041José Fonseca shuffles[i] = lp_build_const_int32(gallivm, 4*i); 4813469715a8a171512cf9b528702e70393f01c6041José Fonseca } 4823469715a8a171512cf9b528702e70393f01c6041José Fonseca 4833469715a8a171512cf9b528702e70393f01c6041José Fonseca shufflev = LLVMConstVector(shuffles, type.length); 4843469715a8a171512cf9b528702e70393f01c6041José Fonseca countd = LLVMBuildShuffleVector(builder, countv, LLVMGetUndef(i8vntype), shufflev, ""); 4853469715a8a171512cf9b528702e70393f01c6041José Fonseca countd = LLVMBuildBitCast(builder, countd, counttype, "countd"); 4863469715a8a171512cf9b528702e70393f01c6041José Fonseca 4873469715a8a171512cf9b528702e70393f01c6041José Fonseca /* 4883469715a8a171512cf9b528702e70393f01c6041José Fonseca * XXX FIXME 4893469715a8a171512cf9b528702e70393f01c6041José Fonseca * this is bad on cpus without popcount (on x86 supported by intel 4903469715a8a171512cf9b528702e70393f01c6041José Fonseca * nehalem, amd barcelona, and up - not tied to sse42). 4913469715a8a171512cf9b528702e70393f01c6041José Fonseca * Would be much faster to just sum the 4 elements of the vector with 4923469715a8a171512cf9b528702e70393f01c6041José Fonseca * some horizontal add (shuffle/add/shuffle/add after the initial and). 4933469715a8a171512cf9b528702e70393f01c6041José Fonseca */ 4943469715a8a171512cf9b528702e70393f01c6041José Fonseca switch (type.length) { 4953469715a8a171512cf9b528702e70393f01c6041José Fonseca case 4: 4963469715a8a171512cf9b528702e70393f01c6041José Fonseca popcntintr = "llvm.ctpop.i32"; 4973469715a8a171512cf9b528702e70393f01c6041José Fonseca break; 4983469715a8a171512cf9b528702e70393f01c6041José Fonseca case 8: 4993469715a8a171512cf9b528702e70393f01c6041José Fonseca popcntintr = "llvm.ctpop.i64"; 5003469715a8a171512cf9b528702e70393f01c6041José Fonseca break; 5013469715a8a171512cf9b528702e70393f01c6041José Fonseca case 16: 5023469715a8a171512cf9b528702e70393f01c6041José Fonseca popcntintr = "llvm.ctpop.i128"; 5033469715a8a171512cf9b528702e70393f01c6041José Fonseca break; 5043469715a8a171512cf9b528702e70393f01c6041José Fonseca default: 5053469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(0); 5063469715a8a171512cf9b528702e70393f01c6041José Fonseca } 5073469715a8a171512cf9b528702e70393f01c6041José Fonseca count = lp_build_intrinsic_unary(builder, popcntintr, counttype, countd); 5083469715a8a171512cf9b528702e70393f01c6041José Fonseca 5093469715a8a171512cf9b528702e70393f01c6041José Fonseca if (type.length > 4) { 5103469715a8a171512cf9b528702e70393f01c6041José Fonseca count = LLVMBuildTrunc(builder, count, LLVMIntTypeInContext(context, 32), ""); 5113469715a8a171512cf9b528702e70393f01c6041José Fonseca } 5123469715a8a171512cf9b528702e70393f01c6041José Fonseca } 5133469715a8a171512cf9b528702e70393f01c6041José Fonseca newcount = LLVMBuildLoad(builder, counter, "origcount"); 5143469715a8a171512cf9b528702e70393f01c6041José Fonseca newcount = LLVMBuildAdd(builder, newcount, count, "newcount"); 5153469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMBuildStore(builder, newcount, counter); 51686afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li} 51786afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li 51886afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li 51905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 52005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul/** 521cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * Generate code for performing depth and/or stencil tests. 5223469715a8a171512cf9b528702e70393f01c6041José Fonseca * We operate on a vector of values (typically n 2x2 quads). 523cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * 52422e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param depth the depth test state 52522e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param stencil the front/back stencil state 526cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param type the data type of the fragment depth/stencil values 527cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul * \param format_desc description of the depth/stencil surface 52822e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param mask the alive/dead pixel mask for the quad (vector) 52922e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param stencil_refs the front/back stencil ref values (scalar) 5303469715a8a171512cf9b528702e70393f01c6041José Fonseca * \param z_src the incoming depth/stencil values (n 2x2 quad values, float32) 53122e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul * \param zs_dst_ptr pointer to depth/stencil values in framebuffer 5323469715a8a171512cf9b528702e70393f01c6041José Fonseca * \param face contains boolean value indicating front/back facing polygon 5335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca */ 534343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonsecavoid 535efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_depth_stencil_test(struct gallivm_state *gallivm, 536d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct pipe_depth_state *depth, 537d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct pipe_stencil_state stencil[2], 538d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell struct lp_type z_src_type, 539d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul const struct util_format_description *format_desc, 540d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul struct lp_build_mask_context *mask, 541521c61ff017ab15b829abbe9a98b179136a36009Brian Paul LLVMValueRef stencil_refs[2], 542d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul LLVMValueRef z_src, 54322e6dc387039e79f6d1435ae8b7422a6514d5d10Brian Paul LLVMValueRef zs_dst_ptr, 54486afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li LLVMValueRef face, 5455b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell LLVMValueRef *zs_value, 546aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell boolean do_branch) 547343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca{ 548efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMBuilderRef builder = gallivm->builder; 54995c18abb03b035c6fa029cd0852f07fb39951279José Fonseca struct lp_type z_type; 55095c18abb03b035c6fa029cd0852f07fb39951279José Fonseca struct lp_build_context z_bld; 55195c18abb03b035c6fa029cd0852f07fb39951279José Fonseca struct lp_build_context s_bld; 55266b6676d141463b8229e62be6249efd1cb6873a8Brian Paul struct lp_type s_type; 553709699d2e25146ac16af7e939de4398fdc50307eJosé Fonseca unsigned z_shift = 0, z_width = 0, z_mask = 0; 554fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef zs_dst, z_dst = NULL; 555fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef stencil_vals = NULL; 55605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul LLVMValueRef z_bitmask = NULL, stencil_shift = NULL; 557fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef z_pass = NULL, s_pass_mask = NULL; 558cc40abad519cc0f765c6d8f6fad4154bed8dd9c2José Fonseca LLVMValueRef orig_mask = lp_build_mask_value(mask); 559d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca LLVMValueRef front_facing = NULL; 560cb1b0b4bec9a1c05bbb762ed04a78dfdf584e3a6Brian Paul 561d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell 562d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell /* 563d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell * Depths are expected to be between 0 and 1, even if they are stored in 564d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell * floats. Setting these bits here will ensure that the lp_build_conv() call 565d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell * below won't try to unnecessarily clamp the incoming values. 566d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell */ 567d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell if(z_src_type.floating) { 568d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell z_src_type.sign = FALSE; 569d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell z_src_type.norm = TRUE; 570d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell } 571d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell else { 572d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell assert(!z_src_type.sign); 573d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell assert(z_src_type.norm); 574d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell } 575d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell 576d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell /* Pick the depth type. */ 57795c18abb03b035c6fa029cd0852f07fb39951279José Fonseca z_type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length); 578d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell 579d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell /* FIXME: Cope with a depth test type with a different bit width. */ 58095c18abb03b035c6fa029cd0852f07fb39951279José Fonseca assert(z_type.width == z_src_type.width); 58195c18abb03b035c6fa029cd0852f07fb39951279José Fonseca assert(z_type.length == z_src_type.length); 582d2cf757f44f4ee5554243f3279483a25886d9927Keith Whitwell 5833469715a8a171512cf9b528702e70393f01c6041José Fonseca /* FIXME: for non-float depth/stencil might generate better code 5843469715a8a171512cf9b528702e70393f01c6041José Fonseca * if we'd always split it up to use 128bit operations. 5853469715a8a171512cf9b528702e70393f01c6041José Fonseca * For stencil we'd almost certainly want to pack to 8xi16 values, 5863469715a8a171512cf9b528702e70393f01c6041José Fonseca * for z just run twice. 5873469715a8a171512cf9b528702e70393f01c6041José Fonseca */ 5883469715a8a171512cf9b528702e70393f01c6041José Fonseca 58905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul /* Sanity checking */ 59005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul { 59105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul const unsigned z_swizzle = format_desc->swizzle[0]; 59205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul const unsigned s_swizzle = format_desc->swizzle[1]; 593343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 59405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE || 59505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul s_swizzle != UTIL_FORMAT_SWIZZLE_NONE); 596343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 59705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(depth->enabled || stencil[0].enabled); 598d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul 59905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); 60005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->block.width == 1); 60105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->block.height == 1); 602343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 60305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (stencil[0].enabled) { 604866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie assert(format_desc->format == PIPE_FORMAT_Z24_UNORM_S8_UINT || 605866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie format_desc->format == PIPE_FORMAT_S8_UINT_Z24_UNORM); 60605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 6078df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul 60805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(z_swizzle < 4); 60995c18abb03b035c6fa029cd0852f07fb39951279José Fonseca assert(format_desc->block.bits == z_type.width); 61095c18abb03b035c6fa029cd0852f07fb39951279José Fonseca if (z_type.floating) { 61105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(z_swizzle == 0); 61205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->channel[z_swizzle].type == 61305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul UTIL_FORMAT_TYPE_FLOAT); 61405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->channel[z_swizzle].size == 61505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul format_desc->block.bits); 61605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 61705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul else { 61805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->channel[z_swizzle].type == 61905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul UTIL_FORMAT_TYPE_UNSIGNED); 62005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul assert(format_desc->channel[z_swizzle].normalized); 62195c18abb03b035c6fa029cd0852f07fb39951279José Fonseca assert(!z_type.fixed); 62205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 623343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 624343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 62505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 62666b6676d141463b8229e62be6249efd1cb6873a8Brian Paul /* Setup build context for Z vals */ 627efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul lp_build_context_init(&z_bld, gallivm, z_type); 628343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 62966b6676d141463b8229e62be6249efd1cb6873a8Brian Paul /* Setup build context for stencil vals */ 6303469715a8a171512cf9b528702e70393f01c6041José Fonseca s_type = lp_int_type(z_type); 631efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul lp_build_context_init(&s_bld, gallivm, s_type); 63266b6676d141463b8229e62be6249efd1cb6873a8Brian Paul 633fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* Load current z/stencil value from z/stencil buffer */ 63495c18abb03b035c6fa029cd0852f07fb39951279José Fonseca zs_dst_ptr = LLVMBuildBitCast(builder, 63595c18abb03b035c6fa029cd0852f07fb39951279José Fonseca zs_dst_ptr, 63695c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMPointerType(z_bld.vec_type, 0), ""); 637d1c9e598838aeac3c8cb90afee00b2cc683be273Brian Paul zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, ""); 638343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 639ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca lp_build_name(zs_dst, "zs_dst"); 640343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 641343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 64205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul /* Compute and apply the Z/stencil bitmasks and shifts. 64305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul */ 64405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul { 64505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul unsigned s_shift, s_mask; 64605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 647914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca if (get_z_shift_and_mask(format_desc, &z_shift, &z_width, &z_mask)) { 648914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca if (z_mask != 0xffffffff) { 649efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul z_bitmask = lp_build_const_int_vec(gallivm, z_type, z_mask); 650914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca } 651914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca 652914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca /* 653914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca * Align the framebuffer Z 's LSB to the right. 654914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca */ 655914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca if (z_shift) { 656efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_type, z_shift); 657914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca z_dst = LLVMBuildLShr(builder, zs_dst, shift, "z_dst"); 658914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca } else if (z_bitmask) { 659914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca /* TODO: Instead of loading a mask from memory and ANDing, it's 660914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca * probably faster to just shake the bits with two shifts. */ 661914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca z_dst = LLVMBuildAnd(builder, zs_dst, z_bitmask, "z_dst"); 662914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca } else { 663914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca z_dst = zs_dst; 664914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca lp_build_name(z_dst, "z_dst"); 665914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca } 666914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca } 667914b0d34e89ee53ef3d7d8aac4baa794492a2064José Fonseca 66805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (get_s_shift_and_mask(format_desc, &s_shift, &s_mask)) { 66905c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (s_shift) { 670efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef shift = lp_build_const_int_vec(gallivm, s_type, s_shift); 67105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_vals = LLVMBuildLShr(builder, zs_dst, shift, ""); 67205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_shift = shift; /* used below */ 67305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 67405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul else { 67505c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_vals = zs_dst; 67605c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 67705c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 67805c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (s_mask != 0xffffffff) { 679efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef mask = lp_build_const_int_vec(gallivm, s_type, s_mask); 68005c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_vals = LLVMBuildAnd(builder, stencil_vals, mask, ""); 68105c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 68205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul 683ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca lp_build_name(stencil_vals, "s_dst"); 68405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul } 685343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 686343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 687fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (stencil[0].enabled) { 688d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca 689d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca if (face) { 690efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef zero = lp_build_const_int32(gallivm, 0); 691d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca 6920a1c9001037a13b69b157994e7983aa3dee158d3Keith Whitwell /* front_facing = face != 0 ? ~0 : 0 */ 6930a1c9001037a13b69b157994e7983aa3dee158d3Keith Whitwell front_facing = LLVMBuildICmp(builder, LLVMIntNE, face, zero, ""); 694d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca front_facing = LLVMBuildSExt(builder, front_facing, 695efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMIntTypeInContext(gallivm->context, 696efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul s_bld.type.length*s_bld.type.width), 697d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca ""); 698d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca front_facing = LLVMBuildBitCast(builder, front_facing, 69995c18abb03b035c6fa029cd0852f07fb39951279José Fonseca s_bld.int_vec_type, ""); 700d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca } 701d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca 702521c61ff017ab15b829abbe9a98b179136a36009Brian Paul /* convert scalar stencil refs into vectors */ 70395c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_refs[0] = lp_build_broadcast_scalar(&s_bld, stencil_refs[0]); 70495c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_refs[1] = lp_build_broadcast_scalar(&s_bld, stencil_refs[1]); 705ecf85c7d750478e433e640897bb25a18069f14deBrian Paul 70695c18abb03b035c6fa029cd0852f07fb39951279José Fonseca s_pass_mask = lp_build_stencil_test(&s_bld, stencil, 707d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca stencil_refs, stencil_vals, 708d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca front_facing); 709343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 710fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply stencil-fail operator */ 711fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul { 71295c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMValueRef s_fail_mask = lp_build_andnot(&s_bld, orig_mask, s_pass_mask); 71395c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_vals = lp_build_stencil_op(&s_bld, stencil, S_FAIL_OP, 714fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 715d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca s_fail_mask, front_facing); 716fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 717fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 718fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 719fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->enabled) { 720ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca /* 721ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca * Convert fragment Z to the desired type, aligning the LSB to the right. 722ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca */ 723ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 724ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(z_type.width == z_src_type.width); 725ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(z_type.length == z_src_type.length); 726ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(lp_check_value(z_src_type, z_src)); 727ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca if (z_src_type.floating) { 728ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca /* 729ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca * Convert from floating point values 730ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca */ 731ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 732ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca if (!z_type.floating) { 733efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul z_src = lp_build_clamped_float_to_unsigned_norm(gallivm, 734ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_src_type, 735ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_width, 736ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_src); 737ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } 738ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } else { 739ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca /* 740ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca * Convert from unsigned normalized values. 741ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca */ 742ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 743ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(!z_src_type.sign); 744ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(!z_src_type.fixed); 745ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(z_src_type.norm); 746ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(!z_type.floating); 747ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca if (z_src_type.width > z_width) { 748efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_src_type, 749ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_src_type.width - z_width); 750ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_src = LLVMBuildLShr(builder, z_src, shift, ""); 751ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } 752ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } 753ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca assert(lp_check_value(z_type, z_src)); 754ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 755ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca lp_build_name(z_src, "z_src"); 756ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca 757fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* compare src Z to dst Z, returning 'pass' mask */ 75895c18abb03b035c6fa029cd0852f07fb39951279José Fonseca z_pass = lp_build_cmp(&z_bld, depth->func, z_src, z_dst); 759fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 760fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (!stencil[0].enabled) { 761fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* We can potentially skip all remaining operations here, but only 762fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * if stencil is disabled because we still need to update the stencil 763fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * buffer values. Don't need to update Z buffer values. 764fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul */ 765fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, z_pass); 766aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell 767aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell if (do_branch) { 768aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell lp_build_mask_check(mask); 769aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell do_branch = FALSE; 770aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell } 771fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 772fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 773fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->writemask) { 774ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca LLVMValueRef zselectmask; 775fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 776caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul /* mask off bits that failed Z test */ 777ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca zselectmask = LLVMBuildAnd(builder, orig_mask, z_pass, ""); 778caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul 779caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul /* mask off bits that failed stencil test */ 780caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul if (s_pass_mask) { 781caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul zselectmask = LLVMBuildAnd(builder, zselectmask, s_pass_mask, ""); 782caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul } 783caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul 784caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul /* Mix the old and new Z buffer values. 785ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca * z_dst[i] = zselectmask[i] ? z_src[i] : z_dst[i] 786caa05ef41996f7d0ac6b77f2fe86b1771cb10e43Brian Paul */ 787ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_dst = lp_build_select(&z_bld, zselectmask, z_src, z_dst); 788fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 789fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 790fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (stencil[0].enabled) { 791fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* update stencil buffer values according to z pass/fail result */ 792fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul LLVMValueRef z_fail_mask, z_pass_mask; 793fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 794fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply Z-fail operator */ 79595c18abb03b035c6fa029cd0852f07fb39951279José Fonseca z_fail_mask = lp_build_andnot(&z_bld, orig_mask, z_pass); 79695c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_vals = lp_build_stencil_op(&s_bld, stencil, Z_FAIL_OP, 797fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 798d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca z_fail_mask, front_facing); 799fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 800fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* apply Z-pass operator */ 8016299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul z_pass_mask = LLVMBuildAnd(builder, orig_mask, z_pass, ""); 80295c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_vals = lp_build_stencil_op(&s_bld, stencil, Z_PASS_OP, 803fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul stencil_refs, stencil_vals, 804d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca z_pass_mask, front_facing); 805fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 806fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 807fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else { 808fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* No depth test: apply Z-pass operator to stencil buffer values which 809fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul * passed the stencil test. 810fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul */ 8116299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul s_pass_mask = LLVMBuildAnd(builder, orig_mask, s_pass_mask, ""); 81295c18abb03b035c6fa029cd0852f07fb39951279José Fonseca stencil_vals = lp_build_stencil_op(&s_bld, stencil, Z_PASS_OP, 81305c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_refs, stencil_vals, 814d5ef59d8b0ce2ea8f0ad983951e696d1679e3eb7José Fonseca s_pass_mask, front_facing); 815fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul } 816fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 817ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca /* Put Z and ztencil bits in the right place */ 818ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca if (z_dst && z_shift) { 819efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef shift = lp_build_const_int_vec(gallivm, z_type, z_shift); 820ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca z_dst = LLVMBuildShl(builder, z_dst, shift, ""); 821ae00e34e4b0d3be247b0538b60810176397c7915José Fonseca } 82205c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul if (stencil_vals && stencil_shift) 8236299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul stencil_vals = LLVMBuildShl(builder, stencil_vals, 82405c03c6a1bcfb8ad77d3025f166f02ddaa741aa2Brian Paul stencil_shift, ""); 8258df65e98998b4c104db30cbba8a38be7eb2a9acdBrian Paul 826fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul /* Finally, merge/store the z/stencil values */ 827fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if ((depth->enabled && depth->writemask) || 828fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul (stencil[0].enabled && stencil[0].writemask)) { 829fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 830fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (z_dst && stencil_vals) 8316299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul zs_dst = LLVMBuildOr(builder, z_dst, stencil_vals, ""); 832fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul else if (z_dst) 833fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul zs_dst = z_dst; 834343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca else 835fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul zs_dst = stencil_vals; 836343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca 8375b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell *zs_value = zs_dst; 838343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca } 839fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 840fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (s_pass_mask) 841fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, s_pass_mask); 842fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul 843fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul if (depth->enabled && stencil[0].enabled) 844fecd4cde501e8b0b5d057a9cc9d2e3af8d853d9eBrian Paul lp_build_mask_update(mask, z_pass); 84586afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li 846aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell if (do_branch) 847aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell lp_build_mask_check(mask); 848aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell 8495b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell} 8505b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 8515b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 85295c18abb03b035c6fa029cd0852f07fb39951279José Fonsecavoid 85395c18abb03b035c6fa029cd0852f07fb39951279José Fonsecalp_build_depth_write(LLVMBuilderRef builder, 85495c18abb03b035c6fa029cd0852f07fb39951279José Fonseca const struct util_format_description *format_desc, 85595c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMValueRef zs_dst_ptr, 85695c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMValueRef zs_value) 85795c18abb03b035c6fa029cd0852f07fb39951279José Fonseca{ 85895c18abb03b035c6fa029cd0852f07fb39951279José Fonseca zs_dst_ptr = LLVMBuildBitCast(builder, zs_dst_ptr, 85995c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMPointerType(LLVMTypeOf(zs_value), 0), ""); 86095c18abb03b035c6fa029cd0852f07fb39951279José Fonseca 86195c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMBuildStore(builder, zs_value, zs_dst_ptr); 86295c18abb03b035c6fa029cd0852f07fb39951279José Fonseca} 86395c18abb03b035c6fa029cd0852f07fb39951279José Fonseca 8645b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 8655b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwellvoid 866efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_deferred_depth_write(struct gallivm_state *gallivm, 8675b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell struct lp_type z_src_type, 8685b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell const struct util_format_description *format_desc, 8695b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell struct lp_build_mask_context *mask, 8705b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell LLVMValueRef zs_dst_ptr, 8715b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell LLVMValueRef zs_value) 8725b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell{ 87395c18abb03b035c6fa029cd0852f07fb39951279José Fonseca struct lp_type z_type; 87495c18abb03b035c6fa029cd0852f07fb39951279José Fonseca struct lp_build_context z_bld; 8755b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell LLVMValueRef z_dst; 876efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMBuilderRef builder = gallivm->builder; 8775b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 8785b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell /* XXX: pointlessly redo type logic: 8795b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell */ 88095c18abb03b035c6fa029cd0852f07fb39951279José Fonseca z_type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length); 881efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul lp_build_context_init(&z_bld, gallivm, z_type); 88295c18abb03b035c6fa029cd0852f07fb39951279José Fonseca 88395c18abb03b035c6fa029cd0852f07fb39951279José Fonseca zs_dst_ptr = LLVMBuildBitCast(builder, zs_dst_ptr, 88495c18abb03b035c6fa029cd0852f07fb39951279José Fonseca LLVMPointerType(z_bld.vec_type, 0), ""); 8855b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 8865b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell z_dst = LLVMBuildLoad(builder, zs_dst_ptr, "zsbufval"); 88795c18abb03b035c6fa029cd0852f07fb39951279José Fonseca z_dst = lp_build_select(&z_bld, lp_build_mask_value(mask), zs_value, z_dst); 8885b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell 8895b7eb868fde98388d80601d8dea39e679828f42fKeith Whitwell LLVMBuildStore(builder, z_dst, zs_dst_ptr); 890343ccc8dd0d3578aeeb9b635f0933c9f323c7fdaJosé Fonseca} 891