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