1/**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28
29#ifndef LP_STATE_FS_H_
30#define LP_STATE_FS_H_
31
32
33#include "util/list.h"
34#include "pipe/p_compiler.h"
35#include "pipe/p_state.h"
36#include "tgsi/tgsi_scan.h" /* for tgsi_shader_info */
37#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */
38#include "gallivm/lp_bld_tgsi.h" /* for lp_tgsi_info */
39#include "lp_bld_interp.h" /* for struct lp_shader_input */
40#include "util/u_inlines.h"
41#include "lp_jit.h"
42
43struct tgsi_token;
44struct lp_fragment_shader;
45
46
47/** Indexes into jit_function[] array */
48#define RAST_WHOLE 0
49#define RAST_EDGE_TEST 1
50
51
52enum lp_fs_kind
53{
54   LP_FS_KIND_GENERAL = 0,
55   LP_FS_KIND_BLIT_RGBA,
56   LP_FS_KIND_BLIT_RGB1,
57   LP_FS_KIND_AERO_MINIFICATION,
58   LP_FS_KIND_LLVM_LINEAR
59};
60
61
62struct lp_sampler_static_state
63{
64   /*
65    * These attributes are effectively interleaved for more sane key handling.
66    * However, there might be lots of null space if the amount of samplers and
67    * textures isn't the same.
68    */
69   struct lp_static_sampler_state sampler_state;
70   struct lp_static_texture_state texture_state;
71};
72
73
74struct lp_image_static_state
75{
76   struct lp_static_texture_state image_state;
77};
78
79struct lp_depth_state
80{
81   unsigned enabled:1;         /**< depth test enabled? */
82   unsigned writemask:1;       /**< allow depth buffer writes? */
83   unsigned func:3;            /**< depth test func (PIPE_FUNC_x) */
84};
85
86struct lp_fragment_shader_variant_key
87{
88   struct lp_depth_state depth;
89   struct pipe_stencil_state stencil[2];
90   struct pipe_blend_state blend;
91
92   struct {
93      unsigned enabled:1;
94      unsigned func:3;
95   } alpha;
96
97   unsigned nr_cbufs:8;
98   unsigned nr_samplers:8;      /* actually derivable from just the shader */
99   unsigned nr_sampler_views:8; /* actually derivable from just the shader */
100   unsigned nr_images:8;        /* actually derivable from just the shader */
101   unsigned flatshade:1;
102   unsigned occlusion_count:1;
103   unsigned resource_1d:1;
104   unsigned depth_clamp:1;
105   unsigned multisample:1;
106   unsigned no_ms_sample_mask_out:1;
107   unsigned restrict_depth_values:1;
108
109   enum pipe_format zsbuf_format;
110   enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];
111
112   uint8_t cbuf_nr_samples[PIPE_MAX_COLOR_BUFS];
113   uint8_t zsbuf_nr_samples;
114   uint8_t coverage_samples;
115   uint8_t min_samples;
116   /* followed by variable number of samplers + images */
117};
118
119#define LP_FS_MAX_VARIANT_KEY_SIZE                                      \
120   (sizeof(struct lp_fragment_shader_variant_key) +                     \
121    PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct lp_sampler_static_state) +\
122    PIPE_MAX_SHADER_IMAGES * sizeof(struct lp_image_static_state))
123
124static inline size_t
125lp_fs_variant_key_size(unsigned nr_samplers, unsigned nr_images)
126{
127   return (sizeof(struct lp_fragment_shader_variant_key) +
128           nr_samplers * sizeof(struct lp_sampler_static_state) +
129           nr_images * sizeof(struct lp_image_static_state));
130}
131
132static inline struct lp_sampler_static_state *
133lp_fs_variant_key_samplers(const struct lp_fragment_shader_variant_key *key)
134{
135   return (struct lp_sampler_static_state *)&(key[1]);
136}
137
138static inline struct lp_sampler_static_state *
139lp_fs_variant_key_sampler_idx(const struct lp_fragment_shader_variant_key *key, int idx)
140{
141   if (idx >= key->nr_samplers)
142      return NULL;
143   return &lp_fs_variant_key_samplers(key)[idx];
144}
145
146static inline struct lp_image_static_state *
147lp_fs_variant_key_images(struct lp_fragment_shader_variant_key *key)
148{
149   return (struct lp_image_static_state *)
150      &(lp_fs_variant_key_samplers(key)[MAX2(key->nr_samplers,
151                                             key->nr_sampler_views)]);
152}
153
154/** doubly-linked list item */
155struct lp_fs_variant_list_item
156{
157   struct list_head list;
158   struct lp_fragment_shader_variant *base;
159};
160
161
162struct lp_fragment_shader_variant
163{
164   /*
165    * Whether some primitives can be opaque.
166    */
167   unsigned potentially_opaque:1;
168
169   unsigned opaque:1;
170   unsigned blit:1;
171   unsigned linear_input_mask:16;
172   struct pipe_reference reference;
173
174   struct gallivm_state *gallivm;
175
176   LLVMTypeRef jit_context_ptr_type;
177   LLVMTypeRef jit_thread_data_ptr_type;
178   LLVMTypeRef jit_linear_context_ptr_type;
179
180   LLVMValueRef function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST]
181
182   lp_jit_frag_func jit_function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST]
183
184   lp_jit_linear_func jit_linear;
185   lp_jit_linear_func jit_linear_blit;
186
187   /* Functions within the linear path:
188    */
189   LLVMValueRef linear_function;
190   lp_jit_linear_llvm_func jit_linear_llvm;
191
192   /* Bitmask to say what cbufs are unswizzled */
193   unsigned unswizzled_cbufs;
194
195   /* Total number of LLVM instructions generated */
196   unsigned nr_instrs;
197
198   struct lp_fs_variant_list_item list_item_global, list_item_local;
199   struct lp_fragment_shader *shader;
200
201   /* For debugging/profiling purposes */
202   unsigned no;
203
204   /* key is variable-sized, must be last */
205   struct lp_fragment_shader_variant_key key;
206};
207
208
209/** Subclass of pipe_shader_state */
210struct lp_fragment_shader
211{
212   struct pipe_shader_state base;
213
214   struct pipe_reference reference;
215   struct lp_tgsi_info info;
216
217   /* Analysis results */
218   enum lp_fs_kind kind;
219
220   struct lp_fs_variant_list_item variants;
221
222   struct draw_fragment_shader *draw_data;
223
224   /* For debugging/profiling purposes */
225   unsigned variant_key_size;
226   unsigned no;
227   unsigned variants_created;
228   unsigned variants_cached;
229
230   /** Fragment shader input interpolation info */
231   struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
232};
233
234
235void
236llvmpipe_fs_analyse_nir(struct lp_fragment_shader *shader);
237
238void
239llvmpipe_fs_analyse(struct lp_fragment_shader *shader,
240                    const struct tgsi_token *tokens);
241
242void
243llvmpipe_fs_variant_fastpath(struct lp_fragment_shader_variant *variant);
244
245void
246llvmpipe_fs_variant_linear_fastpath(struct lp_fragment_shader_variant *variant);
247
248void
249llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp,
250                                struct lp_fragment_shader *shader,
251                                struct lp_fragment_shader_variant *variant);
252
253void
254lp_debug_fs_variant(struct lp_fragment_shader_variant *variant);
255
256const char *
257lp_debug_fs_kind(enum lp_fs_kind kind);
258
259void
260lp_linear_check_variant(struct lp_fragment_shader_variant *variant);
261
262void
263llvmpipe_destroy_fs(struct llvmpipe_context *llvmpipe,
264                    struct lp_fragment_shader *shader);
265
266static inline void
267lp_fs_reference(struct llvmpipe_context *llvmpipe,
268                struct lp_fragment_shader **ptr,
269                struct lp_fragment_shader *shader)
270{
271   struct lp_fragment_shader *old_ptr = *ptr;
272   if (pipe_reference(old_ptr ? &(*ptr)->reference : NULL,
273                      shader ? &shader->reference : NULL)) {
274      llvmpipe_destroy_fs(llvmpipe, old_ptr);
275   }
276   *ptr = shader;
277}
278
279void
280llvmpipe_destroy_shader_variant(struct llvmpipe_context *lp,
281                                struct lp_fragment_shader_variant *variant);
282
283static inline void
284lp_fs_variant_reference(struct llvmpipe_context *llvmpipe,
285                        struct lp_fragment_shader_variant **ptr,
286                        struct lp_fragment_shader_variant *variant)
287{
288   struct lp_fragment_shader_variant *old_ptr = *ptr;
289   if (pipe_reference(old_ptr ? &(*ptr)->reference : NULL,
290                      variant ? &variant->reference : NULL)) {
291      llvmpipe_destroy_shader_variant(llvmpipe, old_ptr);
292   }
293   *ptr = variant;
294}
295
296#endif /* LP_STATE_FS_H_ */
297