1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @file
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Code generate the whole fragment pipeline.
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The fragment pipeline consists of the following stages:
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - early depth test
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - fragment shader
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - alpha test
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - depth/stencil test
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - blending
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This file has only the glue to assemble the fragment pipeline.  The actual
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * plumbing of converting Gallium state into LLVM IR is done elsewhere, in the
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lp_bld_*.[ch] files, and in a complete generic and reusable way. Here we
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * muster the LLVM JIT execution engine to create a function that follows an
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * established binary interface and that can be called from C directly.
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A big source of complexity here is that we often want to run different
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stages with different precisions and data types and precisions. For example,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the fragment shader needs typically to be done in floats, but the
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * depth/stencil test and blending is better done in the type that most closely
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * matches the depth/stencil and color buffer respectively.
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Since the width of a SIMD vector register stays the same regardless of the
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * element type, different types imply different number of elements, so we must
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code generate more instances of the stages with larger types to be able to
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * feed/consume the stages with smaller types.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author Jose Fonseca <jfonseca@vmware.com>
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <limits.h>
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h"
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_pointer.h"
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_dump.h"
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_string.h"
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_simple_list.h"
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_time.h"
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h"
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw/draw_context.h"
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h"
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_scan.h"
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h"
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_type.h"
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_const.h"
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_conv.h"
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_init.h"
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_intr.h"
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_logic.h"
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_tgsi.h"
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_swizzle.h"
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_flow.h"
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_debug.h"
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_alpha.h"
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_blend.h"
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_depth.h"
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_interp.h"
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_context.h"
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_debug.h"
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_perf.h"
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_setup.h"
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_state.h"
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_tex_sample.h"
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_flush.h"
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_state_fs.h"
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Fragment shader number (for debugging) */
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned fs_no = 0;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Expand the relevant bits of mask_input to a n*4-dword mask for the
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * n*four pixels in n 2x2 quads.  This will set the n*four elements of the
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * quad mask vector to 0 or ~0.
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Grouping is 01, 23 for 2 quad mode hence only 0 and 2 are valid
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * quad arguments with fs length 8.
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param first_quad  which quad(s) of the quad group to test, in [0,3]
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param mask_input  bitwise mask for the whole 4x4 stamp
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_quad_mask(struct gallivm_state *gallivm,
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   struct lp_type fs_type,
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   unsigned first_quad,
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef mask_input) /* int32 */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = gallivm->builder;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_type mask_type;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef bits[16];
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef mask;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int shift, i;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * XXX: We'll need a different path for 16 x u8
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fs_type.width == 32);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fs_type.length <= Elements(bits));
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_type = lp_int_type(fs_type);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * mask_input >>= (quad * 4)
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (first_quad) {
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 0:
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shift = 0;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 1:
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(fs_type.length == 4);
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shift = 2;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 2:
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shift = 8;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 3:
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(fs_type.length == 4);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shift = 10;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shift = 0;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_input = LLVMBuildLShr(builder,
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              mask_input,
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMConstInt(i32t, shift, 0),
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              "");
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * mask = { mask_input & (1 << i), for i in [0,3] }
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask = lp_build_broadcast(gallivm,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             lp_build_vec_type(gallivm, mask_type),
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             mask_input);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < fs_type.length / 4; i++) {
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned j = 2 * (i % 2) + (i / 2) * 8;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits[4*i + 0] = LLVMConstInt(i32t, 1 << (j + 0), 0);
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits[4*i + 1] = LLVMConstInt(i32t, 1 << (j + 1), 0);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits[4*i + 2] = LLVMConstInt(i32t, 1 << (j + 4), 0);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits[4*i + 3] = LLVMConstInt(i32t, 1 << (j + 5), 0);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask = LLVMBuildAnd(builder, mask, LLVMConstVector(bits, fs_type.length), "");
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * mask = mask != 0 ? ~0 : 0
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask = lp_build_compare(gallivm,
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           mask_type, PIPE_FUNC_NOTEQUAL,
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           mask,
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           lp_build_const_int_vec(gallivm, mask_type, 0));
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return mask;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define EARLY_DEPTH_TEST  0x1
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LATE_DEPTH_TEST   0x2
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define EARLY_DEPTH_WRITE 0x4
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LATE_DEPTH_WRITE  0x8
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfind_output_by_semantic( const struct tgsi_shader_info *info,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 unsigned semantic,
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 unsigned index )
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < info->num_outputs; i++)
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (info->output_semantic_name[i] == semantic &&
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  info->output_semantic_index[i] == index)
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return i;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -1;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate the fragment shader, depth/stencil test, and alpha tests.
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param i  which quad in the tile, in range [0,3]
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param partial_mask  if 1, do mask_input testing
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_fs(struct gallivm_state *gallivm,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_fragment_shader *shader,
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct lp_fragment_shader_variant_key *key,
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMBuilderRef builder,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_type type,
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef context_ptr,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned i,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_build_interp_soa_context *interp,
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_build_sampler_soa *sampler,
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef *pmask,
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef (*color)[4],
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef depth_ptr,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef facing,
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned partial_mask,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef mask_input,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef counter)
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *zs_format_desc = NULL;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct tgsi_token *tokens = shader->base.tokens;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef vec_type;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef consts_ptr;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef z;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef zs_value = NULL;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef stencil_refs[2];
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_mask_context mask;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean simple_shader = (shader->info.base.file_count[TGSI_FILE_SAMPLER] == 0 &&
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shader->info.base.num_inputs < 3 &&
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shader->info.base.num_instructions < 8);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned attrib;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned cbuf;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned depth_mode;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_bld_tgsi_system_values system_values;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&system_values, 0, sizeof(system_values));
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->depth.enabled ||
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       key->stencil[0].enabled ||
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       key->stencil[1].enabled) {
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      zs_format_desc = util_format_description(key->zsbuf_format);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(zs_format_desc);
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!shader->info.base.writes_z) {
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (key->alpha.enabled || shader->info.base.uses_kill)
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* With alpha test and kill, can do the depth test early
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * and hopefully eliminate some quads.  But need to do a
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * special deferred depth write once the final mask value
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * is known.
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(key->depth.enabled && key->depth.writemask) &&
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !(key->stencil[0].enabled && key->stencil[0].writemask))
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth_mode &= ~(LATE_DEPTH_WRITE | EARLY_DEPTH_WRITE);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      depth_mode = 0;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(i < 4);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vec_type = lp_build_vec_type(gallivm, type);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(outputs, 0, sizeof outputs);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Declare the color and z variables */
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         color[cbuf][chan] = lp_build_alloca(gallivm, vec_type, "color");
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do triangle edge testing */
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (partial_mask) {
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *pmask = generate_quad_mask(gallivm, type,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  i*type.length/4, mask_input);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *pmask = lp_build_const_int_vec(gallivm, type, ~0);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* 'mask' will control execution based on quad's pixel alive/killed state */
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_mask_begin(&mask, gallivm, type, *pmask);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_mask_check(&mask);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_interp_soa_update_pos(interp, gallivm, i*type.length/4);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   z = interp->pos[2];
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (depth_mode & EARLY_DEPTH_TEST) {
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_depth_stencil_test(gallivm,
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &key->depth,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  key->stencil,
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  type,
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  zs_format_desc,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &mask,
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  stencil_refs,
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  z,
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  depth_ptr, facing,
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &zs_value,
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  !simple_shader);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (depth_mode & EARLY_DEPTH_WRITE) {
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_depth_write(builder, zs_format_desc, depth_ptr, zs_value);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_interp_soa_update_inputs(interp, gallivm, i*type.length/4);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Build the actual shader */
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_tgsi_soa(gallivm, tokens, type, &mask,
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     consts_ptr, &system_values,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     interp->pos, interp->inputs,
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     outputs, sampler, &shader->info.base);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Alpha test */
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->alpha.enabled) {
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int color0 = find_output_by_semantic(&shader->info.base,
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           TGSI_SEMANTIC_COLOR,
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           0);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (color0 != -1 && outputs[color0][3]) {
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct util_format_description *cbuf_format_desc;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef alpha_ref_value;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         alpha_ref_value = lp_jit_context_alpha_ref_value(gallivm, context_ptr);
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         alpha_ref_value = lp_build_broadcast(gallivm, vec_type, alpha_ref_value);
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cbuf_format_desc = util_format_description(key->cbuf_format[0]);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_alpha_test(gallivm, key->alpha.func, type, cbuf_format_desc,
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &mask, alpha, alpha_ref_value,
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             (depth_mode & LATE_DEPTH_TEST) != 0);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Late Z test */
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (depth_mode & LATE_DEPTH_TEST) {
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int pos0 = find_output_by_semantic(&shader->info.base,
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         TGSI_SEMANTIC_POSITION,
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         0);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pos0 != -1 && outputs[pos0][2]) {
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_depth_stencil_test(gallivm,
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &key->depth,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  key->stencil,
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  type,
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  zs_format_desc,
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &mask,
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  stencil_refs,
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  z,
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  depth_ptr, facing,
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &zs_value,
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  !simple_shader);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Late Z write */
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (depth_mode & LATE_DEPTH_WRITE) {
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_depth_write(builder, zs_format_desc, depth_ptr, zs_value);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((depth_mode & EARLY_DEPTH_TEST) &&
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            (depth_mode & LATE_DEPTH_WRITE))
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need to apply a reduced mask to the depth write.  Reload the
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * depth value, update from zs_value with the new mask value and
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * write that out.
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_deferred_depth_write(gallivm,
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    type,
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    zs_format_desc,
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    &mask,
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    depth_ptr,
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    zs_value);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Color write  */
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_COLOR &&
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          shader->info.base.output_semantic_index[attrib] < key->nr_cbufs)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned cbuf = shader->info.base.output_semantic_index[attrib];
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if(outputs[attrib][chan]) {
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* XXX: just initialize outputs to point at colors[] and
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * skip this.
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_name(out, "color%u.%u.%c", i, attrib, "rgba"[chan]);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMBuildStore(builder, out, color[cbuf][chan]);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (counter)
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_occlusion_count(gallivm, type,
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               lp_build_mask_value(&mask), counter);
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *pmask = lp_build_mask_end(&mask);
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate the fragment shader, depth/stencil test, and alpha tests.
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_fs_loop(struct gallivm_state *gallivm,
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_fragment_shader *shader,
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct lp_fragment_shader_variant_key *key,
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMBuilderRef builder,
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_type type,
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef context_ptr,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef num_loop,
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_build_interp_soa_context *interp,
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_build_sampler_soa *sampler,
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef mask_store,
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef (*out_color)[4],
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef depth_ptr,
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 unsigned depth_bits,
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef facing,
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 LLVMValueRef counter)
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *zs_format_desc = NULL;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct tgsi_token *tokens = shader->base.tokens;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef vec_type;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef mask_ptr, mask_val;
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef consts_ptr;
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef z;
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef zs_value = NULL;
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef stencil_refs[2];
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef depth_ptr_i;
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef depth_offset;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_for_loop_state loop_state;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_mask_context mask;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean simple_shader = (shader->info.base.file_count[TGSI_FILE_SAMPLER] == 0 &&
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shader->info.base.num_inputs < 3 &&
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            shader->info.base.num_instructions < 8);
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned attrib;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned cbuf;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned depth_mode;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_bld_tgsi_system_values system_values;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&system_values, 0, sizeof(system_values));
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->depth.enabled ||
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       key->stencil[0].enabled ||
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       key->stencil[1].enabled) {
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      zs_format_desc = util_format_description(key->zsbuf_format);
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(zs_format_desc);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!shader->info.base.writes_z) {
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (key->alpha.enabled || shader->info.base.uses_kill)
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* With alpha test and kill, can do the depth test early
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * and hopefully eliminate some quads.  But need to do a
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * special deferred depth write once the final mask value
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * is known.
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(key->depth.enabled && key->depth.writemask) &&
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !(key->stencil[0].enabled && key->stencil[0].writemask))
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth_mode &= ~(LATE_DEPTH_WRITE | EARLY_DEPTH_WRITE);
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      depth_mode = 0;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr);
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vec_type = lp_build_vec_type(gallivm, type);
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_for_loop_begin(&loop_state, gallivm,
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           lp_build_const_int32(gallivm, 0),
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           LLVMIntULT,
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           num_loop,
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           lp_build_const_int32(gallivm, 1));
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_ptr = LLVMBuildGEP(builder, mask_store,
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           &loop_state.counter, 1, "mask_ptr");
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_val = LLVMBuildLoad(builder, mask_ptr, "");
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   depth_offset = LLVMBuildMul(builder, loop_state.counter,
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               lp_build_const_int32(gallivm, depth_bits * type.length),
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               "");
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &depth_offset, 1, "");
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(outputs, 0, sizeof outputs);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         out_color[cbuf][chan] = lp_build_array_alloca(gallivm,
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                       lp_build_vec_type(gallivm,
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                                         type),
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                       num_loop, "color");
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* 'mask' will control execution based on quad's pixel alive/killed state */
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_mask_begin(&mask, gallivm, type, mask_val);
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_mask_check(&mask);
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_interp_soa_update_pos_dyn(interp, gallivm, loop_state.counter);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   z = interp->pos[2];
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (depth_mode & EARLY_DEPTH_TEST) {
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_depth_stencil_test(gallivm,
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &key->depth,
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  key->stencil,
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  type,
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  zs_format_desc,
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &mask,
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  stencil_refs,
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  z,
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  depth_ptr_i, facing,
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &zs_value,
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  !simple_shader);
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (depth_mode & EARLY_DEPTH_WRITE) {
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_depth_write(builder, zs_format_desc, depth_ptr_i, zs_value);
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_interp_soa_update_inputs_dyn(interp, gallivm, loop_state.counter);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Build the actual shader */
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_tgsi_soa(gallivm, tokens, type, &mask,
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     consts_ptr, &system_values,
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     interp->pos, interp->inputs,
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     outputs, sampler, &shader->info.base);
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Alpha test */
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->alpha.enabled) {
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int color0 = find_output_by_semantic(&shader->info.base,
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           TGSI_SEMANTIC_COLOR,
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           0);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (color0 != -1 && outputs[color0][3]) {
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct util_format_description *cbuf_format_desc;
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef alpha_ref_value;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         alpha_ref_value = lp_jit_context_alpha_ref_value(gallivm, context_ptr);
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         alpha_ref_value = lp_build_broadcast(gallivm, vec_type, alpha_ref_value);
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cbuf_format_desc = util_format_description(key->cbuf_format[0]);
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_alpha_test(gallivm, key->alpha.func, type, cbuf_format_desc,
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &mask, alpha, alpha_ref_value,
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             (depth_mode & LATE_DEPTH_TEST) != 0);
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Late Z test */
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (depth_mode & LATE_DEPTH_TEST) {
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int pos0 = find_output_by_semantic(&shader->info.base,
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         TGSI_SEMANTIC_POSITION,
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         0);
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pos0 != -1 && outputs[pos0][2]) {
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_depth_stencil_test(gallivm,
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &key->depth,
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  key->stencil,
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  type,
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  zs_format_desc,
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &mask,
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  stencil_refs,
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  z,
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  depth_ptr_i, facing,
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &zs_value,
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  !simple_shader);
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Late Z write */
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (depth_mode & LATE_DEPTH_WRITE) {
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_depth_write(builder, zs_format_desc, depth_ptr_i, zs_value);
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((depth_mode & EARLY_DEPTH_TEST) &&
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            (depth_mode & LATE_DEPTH_WRITE))
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need to apply a reduced mask to the depth write.  Reload the
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * depth value, update from zs_value with the new mask value and
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * write that out.
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_deferred_depth_write(gallivm,
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    type,
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    zs_format_desc,
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    &mask,
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    depth_ptr_i,
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    zs_value);
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Color write  */
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_COLOR &&
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          shader->info.base.output_semantic_index[attrib] < key->nr_cbufs)
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned cbuf = shader->info.base.output_semantic_index[attrib];
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if(outputs[attrib][chan]) {
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* XXX: just initialize outputs to point at colors[] and
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * skip this.
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef color_ptr;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               color_ptr = LLVMBuildGEP(builder, out_color[cbuf][chan],
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &loop_state.counter, 1, "");
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_name(out, "color%u.%c", attrib, "rgba"[chan]);
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMBuildStore(builder, out, color_ptr);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->occlusion_count) {
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(counter, "counter");
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_occlusion_count(gallivm, type,
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               lp_build_mask_value(&mask), counter);
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_val = lp_build_mask_end(&mask);
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuildStore(builder, mask_val, mask_ptr);
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_for_loop_end(&loop_state);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate color blending and color output.
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param rt  the render target index (to index blend, colormask state)
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type  the pixel color type
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param context_ptr  pointer to the runtime JIT context
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param mask  execution mask (active fragment/pixel mask)
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param src  colors from the fragment shader
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param dst_ptr  the destination color buffer pointer
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_blend(struct gallivm_state *gallivm,
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const struct pipe_blend_state *blend,
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               unsigned rt,
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMBuilderRef builder,
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               struct lp_type type,
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef context_ptr,
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef mask,
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef *src,
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef dst_ptr,
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               boolean do_branch)
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context bld;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_mask_context mask_ctx;
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef vec_type;
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef const_ptr;
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef con[4];
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef dst[4];
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef res[4];
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&bld, gallivm, type);
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_mask_begin(&mask_ctx, gallivm, type, mask);
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (do_branch)
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_mask_check(&mask_ctx);
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vec_type = lp_build_vec_type(gallivm, type);
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const_ptr = lp_jit_context_blend_color(gallivm, context_ptr);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const_ptr = LLVMBuildBitCast(builder, const_ptr,
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMPointerType(vec_type, 0), "");
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* load constant blend color and colors from the dest color buffer */
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(chan = 0; chan < 4; ++chan) {
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef index = lp_build_const_int32(gallivm, chan);
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(con[chan], "con.%c", "rgba"[chan]);
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(dst[chan], "dst.%c", "rgba"[chan]);
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do blend */
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_blend_soa(gallivm, blend, type, rt, src, dst, con, res);
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* store results to color buffer */
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(chan = 0; chan < 4; ++chan) {
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(blend->rt[rt].colormask & (1 << chan)) {
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef index = lp_build_const_int32(gallivm, chan);
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_name(res[chan], "res.%c", "rgba"[chan]);
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMBuildStore(builder, res[chan], LLVMBuildGEP(builder, dst_ptr, &index, 1, ""));
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_mask_end(&mask_ctx);
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate the runtime callable function for the whole fragment pipeline.
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that the function which we generate operates on a block of 16
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pixels at at time.  The block contains 2x2 quads.  Each quad contains
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2x2 pixels.
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_fragment(struct llvmpipe_context *lp,
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  struct lp_fragment_shader *shader,
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  struct lp_fragment_shader_variant *variant,
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  unsigned partial_mask)
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gallivm_state *gallivm = variant->gallivm;
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct lp_fragment_shader_variant_key *key = &variant->key;
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char func_name[256];
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_type fs_type;
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_type blend_type;
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef fs_elem_type;
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef blend_vec_type;
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef arg_types[11];
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef func_type;
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context);
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef int8_type = LLVMInt8TypeInContext(gallivm->context);
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef context_ptr;
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef y;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef a0_ptr;
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef dadx_ptr;
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef dady_ptr;
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef color_ptr_ptr;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef depth_ptr;
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef mask_input;
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef counter = NULL;
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBasicBlockRef block;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder;
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_sampler_soa *sampler;
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_interp_soa_context interp;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef fs_mask[16 / 4];
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS][16 / 4];
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef blend_mask;
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef function;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef facing;
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *zs_format_desc;
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_fs;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned cbuf;
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean cbuf0_write_all;
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean try_loop = TRUE;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(lp_native_vector_width / 32 >= 4);
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Adjust color input interpolation according to flatshade state:
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(inputs, shader->inputs, shader->info.base.num_inputs * sizeof inputs[0]);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < shader->info.base.num_inputs; i++) {
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inputs[i].interp == LP_INTERP_COLOR) {
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (key->flatshade)
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    inputs[i].interp = LP_INTERP_CONSTANT;
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    inputs[i].interp = LP_INTERP_PERSPECTIVE;
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* check if writes to cbuf[0] are to be copied to all cbufs */
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cbuf0_write_all = FALSE;
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0;i < shader->info.base.num_properties; i++) {
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shader->info.base.properties[i].name ==
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) {
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cbuf0_write_all = TRUE;
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* TODO: actually pick these based on the fs and color buffer
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * characteristics. */
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&fs_type, 0, sizeof fs_type);
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_type.floating = TRUE;      /* floating point values */
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_type.sign = TRUE;          /* values are signed */
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_type.norm = FALSE;         /* values are not limited to [0,1] or [-1,1] */
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_type.width = 32;           /* 32-bit float */
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_type.length = MIN2(lp_native_vector_width / 32, 16); /* n*4 elements per vector */
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_fs = 16 / fs_type.length; /* number of loops per 4x4 stamp */
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&blend_type, 0, sizeof blend_type);
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_type.floating = FALSE; /* values are integers */
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_type.sign = FALSE;     /* values are unsigned */
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_type.norm = TRUE;      /* values are in [0,1] or [-1,1] */
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_type.width = 8;        /* 8-bit ubyte values */
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_type.length = 16;      /* 16 elements per vector */
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Generate the function prototype. Any change here must be reflected in
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * lp_jit.h's lp_jit_frag_func function pointer type, and vice-versa.
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs_elem_type = lp_build_elem_type(gallivm, fs_type);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   blend_vec_type = lp_build_vec_type(gallivm, blend_type);
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   util_snprintf(func_name, sizeof(func_name), "fs%u_variant%u_%s",
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 shader->no, variant->no, partial_mask ? "partial" : "whole");
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[0] = variant->jit_context_ptr_type;       /* context */
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[1] = int32_type;                          /* x */
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[2] = int32_type;                          /* y */
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[3] = int32_type;                          /* facing */
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[4] = LLVMPointerType(fs_elem_type, 0);    /* a0 */
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[5] = LLVMPointerType(fs_elem_type, 0);    /* dadx */
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[6] = LLVMPointerType(fs_elem_type, 0);    /* dady */
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0);  /* color */
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[8] = LLVMPointerType(int8_type, 0);       /* depth */
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[9] = int32_type;                          /* mask_input */
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg_types[10] = LLVMPointerType(int32_type, 0);     /* counter */
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   func_type = LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context),
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                arg_types, Elements(arg_types), 0);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function = LLVMAddFunction(gallivm->module, func_name, func_type);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMSetFunctionCallConv(function, LLVMCCallConv);
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->function[partial_mask] = function;
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX: need to propagate noalias down into color param now we are
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * passing a pointer-to-pointer?
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(i = 0; i < Elements(arg_types); ++i)
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMAddAttribute(LLVMGetParam(function, i), LLVMNoAliasAttribute);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_ptr  = LLVMGetParam(function, 0);
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   x            = LLVMGetParam(function, 1);
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   y            = LLVMGetParam(function, 2);
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   facing       = LLVMGetParam(function, 3);
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   a0_ptr       = LLVMGetParam(function, 4);
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dadx_ptr     = LLVMGetParam(function, 5);
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dady_ptr     = LLVMGetParam(function, 6);
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   color_ptr_ptr = LLVMGetParam(function, 7);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   depth_ptr    = LLVMGetParam(function, 8);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask_input   = LLVMGetParam(function, 9);
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(context_ptr, "context");
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(x, "x");
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(y, "y");
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(a0_ptr, "a0");
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(dadx_ptr, "dadx");
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(dady_ptr, "dady");
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(color_ptr_ptr, "color_ptr_ptr");
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(depth_ptr, "depth");
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_name(mask_input, "mask_input");
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->occlusion_count) {
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      counter = LLVMGetParam(function, 10);
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(counter, "counter");
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Function body
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   builder = gallivm->builder;
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(builder);
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMPositionBuilderAtEnd(builder, block);
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* code generated texture sampling */
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zs_format_desc = util_format_description(key->zsbuf_format);
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!try_loop) {
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The shader input interpolation info is not explicitely baked in the
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * shader key, but everything it derives from (TGSI, and flatshade) is
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * already included in the shader key.
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_interp_soa_init(&interp,
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               gallivm,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               shader->info.base.num_inputs,
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               inputs,
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               builder, fs_type,
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               FALSE,
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               a0_ptr, dadx_ptr, dady_ptr,
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               x, y);
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* loop over quads in the block */
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(i = 0; i < num_fs; ++i) {
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef depth_offset = LLVMConstInt(int32_type,
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  i*fs_type.length*zs_format_desc->block.bits/8,
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  0);
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS];
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef depth_ptr_i;
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &depth_offset, 1, "");
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         generate_fs(gallivm,
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     shader, key,
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     builder,
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     fs_type,
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     context_ptr,
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     i,
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     &interp,
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     sampler,
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     &fs_mask[i], /* output */
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     out_color,
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     depth_ptr_i,
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     facing,
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     partial_mask,
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     mask_input,
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     counter);
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (cbuf = 0; cbuf < key->nr_cbufs; cbuf++)
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan)
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               fs_out_color[cbuf][chan][i] =
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  out_color[cbuf * !cbuf0_write_all][chan];
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned depth_bits = zs_format_desc->block.bits/8;
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef num_loop = lp_build_const_int32(gallivm, num_fs);
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef mask_type = lp_build_int_vec_type(gallivm, fs_type);
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef mask_store = lp_build_array_alloca(gallivm, mask_type,
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                      num_loop, "mask_store");
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef color_store[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS];
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The shader input interpolation info is not explicitely baked in the
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * shader key, but everything it derives from (TGSI, and flatshade) is
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * already included in the shader key.
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_interp_soa_init(&interp,
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               gallivm,
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               shader->info.base.num_inputs,
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               inputs,
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               builder, fs_type,
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               TRUE,
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               a0_ptr, dadx_ptr, dady_ptr,
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               x, y);
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < num_fs; i++) {
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef mask;
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef mask_ptr = LLVMBuildGEP(builder, mask_store,
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              &indexi, 1, "mask_ptr");
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (partial_mask) {
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mask = generate_quad_mask(gallivm, fs_type,
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      i*fs_type.length/4, mask_input);
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mask = lp_build_const_int_vec(gallivm, fs_type, ~0);
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMBuildStore(builder, mask, mask_ptr);
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      generate_fs_loop(gallivm,
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       shader, key,
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       builder,
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       fs_type,
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       context_ptr,
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       num_loop,
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       &interp,
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       sampler,
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       mask_store, /* output */
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       color_store,
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       depth_ptr,
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       depth_bits,
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       facing,
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       counter);
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < num_fs; i++) {
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef ptr = LLVMBuildGEP(builder, mask_store,
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         &indexi, 1, "");
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fs_mask[i] = LLVMBuildLoad(builder, ptr, "mask");
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* This is fucked up need to reorganize things */
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               ptr = LLVMBuildGEP(builder,
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  color_store[cbuf * !cbuf0_write_all][chan],
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &indexi, 1, "");
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               fs_out_color[cbuf][chan][i] = ptr;
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler->destroy(sampler);
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Loop over color outputs / color buffers to do blending.
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef color_ptr;
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef index = lp_build_const_int32(gallivm, cbuf);
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef blend_in_color[TGSI_NUM_CHANNELS];
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned rt;
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Convert the fs's output color and mask to fit to the blending type.
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef fs_color_vals[LP_MAX_VECTOR_LENGTH];
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < num_fs; i++) {
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fs_color_vals[i] =
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMBuildLoad(builder, fs_out_color[cbuf][chan][i], "fs_color_vals");
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_conv(gallivm, fs_type, blend_type,
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       fs_color_vals,
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       num_fs,
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       &blend_in_color[chan], 1);
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_name(blend_in_color[chan], "color%d.%c", cbuf, "rgba"[chan]);
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (partial_mask || !variant->opaque) {
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_conv_mask(variant->gallivm, fs_type, blend_type,
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            fs_mask, num_fs,
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            &blend_mask, 1);
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_mask = lp_build_const_int_vec(variant->gallivm, blend_type, ~0);
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      color_ptr = LLVMBuildLoad(builder,
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMBuildGEP(builder, color_ptr_ptr, &index, 1, ""),
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "");
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(color_ptr, "color_ptr%d", cbuf);
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* which blend/colormask state to use */
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rt = key->blend.independent_blend_enable ? cbuf : 0;
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Blending.
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Could the 4x4 have been killed?
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         boolean do_branch = ((key->depth.enabled || key->stencil[0].enabled) &&
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              !key->alpha.enabled &&
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              !shader->info.base.uses_kill);
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         generate_blend(variant->gallivm,
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        &key->blend,
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        rt,
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        builder,
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        blend_type,
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        context_ptr,
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        blend_mask,
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        blend_in_color,
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        color_ptr,
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        do_branch);
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuildRetVoid(builder);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gallivm_verify_function(gallivm, function);
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->nr_instrs += lp_build_count_instructions(function);
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_printf("fs variant %p:\n", (void *) key);
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->flatshade) {
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("flatshade = 1\n");
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < key->nr_cbufs; ++i) {
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("cbuf_format[%u] = %s\n", i, util_format_name(key->cbuf_format[i]));
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->depth.enabled) {
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format));
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE));
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("depth.writemask = %u\n", key->depth.writemask);
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 2; ++i) {
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (key->stencil[i].enabled) {
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].func = %s\n", i, util_dump_func(key->stencil[i].func, TRUE));
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].fail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].fail_op, TRUE));
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].zpass_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zpass_op, TRUE));
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].zfail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zfail_op, TRUE));
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].valuemask = 0x%x\n", i, key->stencil[i].valuemask);
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("stencil[%u].writemask = 0x%x\n", i, key->stencil[i].writemask);
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->alpha.enabled) {
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE));
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->occlusion_count) {
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("occlusion_count = 1\n");
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->blend.logicop_enable) {
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.logicop_func = %s\n", util_dump_logicop(key->blend.logicop_func, TRUE));
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (key->blend.rt[0].blend_enable) {
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.rgb_func = %s\n",   util_dump_blend_func  (key->blend.rt[0].rgb_func, TRUE));
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.rgb_src_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE));
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.rgb_dst_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE));
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.alpha_func = %s\n",       util_dump_blend_func  (key->blend.rt[0].alpha_func, TRUE));
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE));
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("blend.alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE));
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask);
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < key->nr_samplers; ++i) {
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("sampler[%u] = \n", i);
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .format = %s\n",
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_format_name(key->sampler[i].format));
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .target = %s\n",
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_target(key->sampler[i].target, TRUE));
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .pot = %u %u %u\n",
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   key->sampler[i].pot_width,
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   key->sampler[i].pot_height,
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   key->sampler[i].pot_depth);
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .wrap = %s %s %s\n",
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .min_img_filter = %s\n",
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .min_mip_filter = %s\n",
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .mag_img_filter = %s\n",
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE)
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("  .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE));
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .min_max_lod_equal = %u\n", key->sampler[i].min_max_lod_equal);
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .lod_bias_non_zero = %u\n", key->sampler[i].lod_bias_non_zero);
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .apply_min_lod = %u\n", key->sampler[i].apply_min_lod);
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("  .apply_max_lod = %u\n", key->sampler[i].apply_max_lod);
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_debug_fs_variant(const struct lp_fragment_shader_variant *variant)
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_printf("llvmpipe: Fragment shader #%u variant #%u:\n",
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                variant->shader->no, variant->no);
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_dump(variant->shader->base.tokens, 0);
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dump_fs_variant_key(&variant->key);
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_printf("variant->opaque = %u\n", variant->opaque);
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_printf("\n");
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate a new fragment shader variant from the shader code and
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other state indicated by the key.
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct lp_fragment_shader_variant *
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_variant(struct llvmpipe_context *lp,
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_fragment_shader *shader,
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct lp_fragment_shader_variant_key *key)
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader_variant *variant;
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *cbuf0_format_desc;
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean fullcolormask;
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant = CALLOC_STRUCT(lp_fragment_shader_variant);
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!variant)
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->gallivm = gallivm_create();
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!variant->gallivm) {
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(variant);
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->shader = shader;
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->list_item_global.base = variant;
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->list_item_local.base = variant;
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->no = shader->variants_created++;
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&variant->key, key, shader->variant_key_size);
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Determine whether we are touching all channels in the color buffer.
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fullcolormask = FALSE;
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (key->nr_cbufs == 1) {
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cbuf0_format_desc = util_format_description(key->cbuf_format[0]);
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fullcolormask = util_format_colormask_full(cbuf0_format_desc, key->blend.rt[0].colormask);
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->opaque =
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !key->blend.logicop_enable &&
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !key->blend.rt[0].blend_enable &&
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fullcolormask &&
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !key->stencil[0].enabled &&
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !key->alpha.enabled &&
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !key->depth.enabled &&
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         !shader->info.base.uses_kill
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ? TRUE : FALSE;
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((LP_DEBUG & DEBUG_FS) || (gallivm_debug & GALLIVM_DEBUG_IR)) {
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_debug_fs_variant(variant);
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_jit_init_types(variant);
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variant->jit_function[RAST_EDGE_TEST] == NULL)
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variant->jit_function[RAST_WHOLE] == NULL) {
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (variant->opaque) {
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Specialized shader, which doesn't need to read the color buffer. */
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         generate_fragment(lp, shader, variant, RAST_WHOLE);
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Compile everything
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gallivm_compile_module(variant->gallivm);
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variant->function[RAST_EDGE_TEST]) {
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variant->jit_function[RAST_EDGE_TEST] = (lp_jit_frag_func)
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            gallivm_jit_function(variant->gallivm,
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 variant->function[RAST_EDGE_TEST]);
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variant->function[RAST_WHOLE]) {
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         variant->jit_function[RAST_WHOLE] = (lp_jit_frag_func)
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gallivm_jit_function(variant->gallivm,
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    variant->function[RAST_WHOLE]);
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (!variant->jit_function[RAST_WHOLE]) {
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variant->jit_function[RAST_WHOLE] = variant->jit_function[RAST_EDGE_TEST];
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return variant;
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_create_fs_state(struct pipe_context *pipe,
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct pipe_shader_state *templ)
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader *shader;
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int nr_samplers;
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader = CALLOC_STRUCT(lp_fragment_shader);
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!shader)
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->no = fs_no++;
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   make_empty_list(&shader->variants);
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* get/save the summary info for this shader */
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_tgsi_info(templ->tokens, &shader->info);
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we need to keep a local copy of the tokens */
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->base.tokens = tgsi_dup_tokens(templ->tokens);
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->draw_data = draw_create_fragment_shader(llvmpipe->draw, templ);
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader->draw_data == NULL) {
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE((void *) shader->base.tokens);
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(shader);
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1;
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key,
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     sampler[nr_samplers]);
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < shader->info.base.num_inputs; i++) {
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->inputs[i].usage_mask = shader->info.base.input_usage_mask[i];
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->inputs[i].cyl_wrap = shader->info.base.input_cylindrical_wrap[i];
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (shader->info.base.input_interpolate[i]) {
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_INTERPOLATE_CONSTANT:
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_CONSTANT;
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_INTERPOLATE_LINEAR:
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_LINEAR;
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_INTERPOLATE_PERSPECTIVE:
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_PERSPECTIVE;
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_INTERPOLATE_COLOR:
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_COLOR;
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(0);
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (shader->info.base.input_semantic_name[i]) {
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_SEMANTIC_FACE:
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_FACING;
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_SEMANTIC_POSITION:
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Position was already emitted above
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].interp = LP_INTERP_POSITION;
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 shader->inputs[i].src_index = 0;
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 continue;
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->inputs[i].src_index = i+1;
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (LP_DEBUG & DEBUG_TGSI) {
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned attrib;
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("llvmpipe: Create fragment shader #%u %p:\n",
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   shader->no, (void *) shader);
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tgsi_dump(templ->tokens, 0);
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("usage masks:\n");
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (attrib = 0; attrib < shader->info.base.num_inputs; ++attrib) {
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned usage_mask = shader->info.base.input_usage_mask[attrib];
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("  IN[%u].%s%s%s%s\n",
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      attrib,
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      usage_mask & TGSI_WRITEMASK_X ? "x" : "",
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      usage_mask & TGSI_WRITEMASK_Y ? "y" : "",
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      usage_mask & TGSI_WRITEMASK_Z ? "z" : "",
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      usage_mask & TGSI_WRITEMASK_W ? "w" : "");
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("\n");
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader;
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (llvmpipe->fs == fs)
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw_flush(llvmpipe->draw);
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->fs = (struct lp_fragment_shader *) fs;
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw_bind_fragment_shader(llvmpipe->draw,
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             (llvmpipe->fs ? llvmpipe->fs->draw_data : NULL));
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->dirty |= LP_NEW_FS;
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Remove shader variant from two lists: the shader's variant list
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and the context's variant list.
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_remove_shader_variant(struct llvmpipe_context *lp,
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               struct lp_fragment_shader_variant *variant)
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gallivm_debug & GALLIVM_DEBUG_IR) {
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("llvmpipe: del fs #%u var #%u v created #%u v cached"
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   " #%u v total cached #%u\n",
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   variant->shader->no,
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   variant->no,
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   variant->shader->variants_created,
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   variant->shader->variants_cached,
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   lp->nr_fs_variants);
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* free all the variant's JIT'd functions */
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < Elements(variant->function); i++) {
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (variant->function[i]) {
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         gallivm_free_function(variant->gallivm,
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               variant->function[i],
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               variant->jit_function[i]);
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gallivm_destroy(variant->gallivm);
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* remove from shader's list */
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   remove_from_list(&variant->list_item_local);
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variant->shader->variants_cached--;
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* remove from context's list */
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   remove_from_list(&variant->list_item_global);
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp->nr_fs_variants--;
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp->nr_fs_instrs -= variant->nr_instrs;
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(variant);
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader *shader = fs;
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fs_variant_list_item *li;
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fs != llvmpipe->fs);
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * XXX: we need to flush the context until we have some sort of reference
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * counting in fragment shaders as they may still be binned
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Flushing alone might not sufficient we need to wait on it too.
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe_finish(pipe, __FUNCTION__);
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Delete all the variants */
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   li = first_elem(&shader->variants);
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(!at_end(&shader->variants, li)) {
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_fs_variant_list_item *next = next_elem(li);
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvmpipe_remove_shader_variant(llvmpipe, li->base);
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      li = next;
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Delete draw module's data */
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw_delete_fragment_shader(llvmpipe->draw, shader->draw_data);
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(shader->variants_cached == 0);
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE((void *) shader->base.tokens);
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(shader);
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_set_constant_buffer(struct pipe_context *pipe,
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             uint shader, uint index,
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct pipe_constant_buffer *cb)
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *constants = cb ? cb->buffer : NULL;
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned size;
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const void *data;
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cb && cb->user_buffer) {
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      constants = llvmpipe_user_buffer_create(pipe->screen,
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              (void *) cb->user_buffer,
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              cb->buffer_size,
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              PIPE_BIND_CONSTANT_BUFFER);
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   size = constants ? constants->width0 : 0;
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   data = constants ? llvmpipe_resource_data(constants) : NULL;
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(shader < PIPE_SHADER_TYPES);
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(index < PIPE_MAX_CONSTANT_BUFFERS);
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(llvmpipe->constants[shader][index] == constants)
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw_flush(llvmpipe->draw);
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* note: reference counting */
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&llvmpipe->constants[shader][index], constants);
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(shader == PIPE_SHADER_VERTEX ||
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader == PIPE_SHADER_GEOMETRY) {
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      draw_set_mapped_constant_buffer(llvmpipe->draw, shader,
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      index, data, size);
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->dirty |= LP_NEW_CONSTANTS;
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cb && cb->user_buffer) {
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&constants, NULL);
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the blend factor equivalent to a destination alpha of one.
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgforce_dst_alpha_one(unsigned factor)
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(factor) {
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_DST_ALPHA:
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return PIPE_BLENDFACTOR_ONE;
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return PIPE_BLENDFACTOR_ZERO;
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return PIPE_BLENDFACTOR_ZERO;
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return factor;
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We need to generate several variants of the fragment pipeline to match
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * all the combinations of the contributing state atoms.
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO: there is actually no reason to tie this to context state -- the
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generated code could be cached globally in the screen.
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmake_variant_key(struct llvmpipe_context *lp,
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_fragment_shader *shader,
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct lp_fragment_shader_variant_key *key)
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(key, 0, shader->variant_key_size);
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lp->framebuffer.zsbuf) {
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lp->depth_stencil->depth.enabled) {
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         key->zsbuf_format = lp->framebuffer.zsbuf->format;
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lp->depth_stencil->stencil[0].enabled) {
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         key->zsbuf_format = lp->framebuffer.zsbuf->format;
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memcpy(&key->stencil, &lp->depth_stencil->stencil, sizeof key->stencil);
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   key->alpha.enabled = lp->depth_stencil->alpha.enabled;
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(key->alpha.enabled)
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      key->alpha.func = lp->depth_stencil->alpha.func;
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* alpha.ref_value is passed in jit_context */
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   key->flatshade = lp->rasterizer->flatshade;
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lp->active_query_count) {
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      key->occlusion_count = TRUE;
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lp->framebuffer.nr_cbufs) {
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(&key->blend, lp->blend, sizeof key->blend);
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   key->nr_cbufs = lp->framebuffer.nr_cbufs;
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum pipe_format format = lp->framebuffer.cbufs[i]->format;
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct pipe_rt_blend_state *blend_rt = &key->blend.rt[i];
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct util_format_description *format_desc;
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      key->cbuf_format[i] = format;
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      format_desc = util_format_description(format);
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blend_rt->colormask = lp->blend->rt[i].colormask;
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Mask out color channels not present in the color buffer.
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blend_rt->colormask &= util_format_colormask(format_desc);
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Our swizzled render tiles always have an alpha channel, but the linear
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * render target format often does not, so force here the dst alpha to be
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * one.
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This is not a mere optimization. Wrong results will be produced if the
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * dst alpha is used, the dst format does not have alpha, and the previous
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * rendering was not flushed from the swizzled to linear buffer. For
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * example, NonPowTwo DCT.
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * TODO: This should be generalized to all channels for better
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * performance, but only alpha causes correctness issues.
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Also, force rgb/alpha func/factors match, to make AoS blending easier.
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W ||
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  format_desc->swizzle[3] == format_desc->swizzle[0]) {
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_rt->rgb_src_factor   = force_dst_alpha_one(blend_rt->rgb_src_factor);
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_rt->rgb_dst_factor   = force_dst_alpha_one(blend_rt->rgb_dst_factor);
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_rt->alpha_func       = blend_rt->rgb_func;
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_rt->alpha_src_factor = blend_rt->rgb_src_factor;
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blend_rt->alpha_dst_factor = blend_rt->rgb_dst_factor;
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This value will be the same for all the variants of a given shader:
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   key->nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1;
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(i = 0; i < key->nr_samplers; ++i) {
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(shader->info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) {
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_sampler_static_state(&key->sampler[i],
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 lp->sampler_views[PIPE_SHADER_FRAGMENT][i],
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 lp->samplers[PIPE_SHADER_FRAGMENT][i]);
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update fragment shader state.  This is called just prior to drawing
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * something when some fragment-related state has changed.
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_update_fs(struct llvmpipe_context *lp)
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader *shader = lp->fs;
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader_variant_key key;
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fragment_shader_variant *variant = NULL;
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fs_variant_list_item *li;
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   make_variant_key(lp, shader, &key);
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Search the variants for one which matches the key */
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   li = first_elem(&shader->variants);
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(!at_end(&shader->variants, li)) {
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(memcmp(&li->base->key, &key, shader->variant_key_size) == 0) {
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         variant = li->base;
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      li = next_elem(li);
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variant) {
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Move this variant to the head of the list to implement LRU
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * deletion of shader's when we have too many.
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      move_to_head(&lp->fs_variants_list, &variant->list_item_global);
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* variant not found, create it now */
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int64_t t0, t1, dt;
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i;
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned variants_to_cull;
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (0) {
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      lp->nr_fs_variants,
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      lp->nr_fs_instrs,
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      lp->nr_fs_variants ? lp->nr_fs_instrs / lp->nr_fs_variants : 0);
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* First, check if we've exceeded the max number of shader variants.
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * If so, free 25% of them (the least recently used ones).
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 4 : 0;
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (variants_to_cull ||
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS) {
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct pipe_context *pipe = &lp->pipe;
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * XXX: we need to flush the context until we have some sort of
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * reference counting in fragment shaders as they may still be binned
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Flushing alone might not be sufficient we need to wait on it too.
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         llvmpipe_finish(pipe, __FUNCTION__);
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * We need to re-check lp->nr_fs_variants because an arbitrarliy large
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * number of shader variants (potentially all of them) could be
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * pending for destruction on flush.
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < variants_to_cull || lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS; i++) {
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_fs_variant_list_item *item;
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (is_empty_list(&lp->fs_variants_list)) {
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            item = last_elem(&lp->fs_variants_list);
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(item);
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(item->base);
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            llvmpipe_remove_shader_variant(lp, item->base);
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Generate the new variant.
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t0 = os_time_get();
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variant = generate_variant(lp, shader, &key);
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t1 = os_time_get();
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dt = t1 - t0;
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LP_COUNT_ADD(llvm_compile_time, dt);
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LP_COUNT_ADD(nr_llvm_compiles, 2);  /* emit vs. omit in/out test */
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      llvmpipe_variant_count++;
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Put the new variant into the list */
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (variant) {
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         insert_at_head(&shader->variants, &variant->list_item_local);
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         insert_at_head(&lp->fs_variants_list, &variant->list_item_global);
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp->nr_fs_variants++;
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp->nr_fs_instrs += variant->nr_instrs;
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shader->variants_cached++;
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Bind this variant */
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_setup_set_fs_variant(lp->setup, variant);
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe)
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->pipe.bind_fs_state   = llvmpipe_bind_fs_state;
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1774