• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
43 struct tgsi_token;
44 struct lp_fragment_shader;
45 
46 
47 /** Indexes into jit_function[] array */
48 #define RAST_WHOLE 0
49 #define RAST_EDGE_TEST 1
50 
51 
52 enum 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 
62 struct 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 
74 struct lp_image_static_state
75 {
76    struct lp_static_texture_state image_state;
77 };
78 
79 struct 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 
86 struct 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 
124 static inline size_t
lp_fs_variant_key_size(unsigned nr_samplers,unsigned nr_images)125 lp_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 
132 static inline struct lp_sampler_static_state *
lp_fs_variant_key_samplers(const struct lp_fragment_shader_variant_key * key)133 lp_fs_variant_key_samplers(const struct lp_fragment_shader_variant_key *key)
134 {
135    return (struct lp_sampler_static_state *)&(key[1]);
136 }
137 
138 static inline struct lp_sampler_static_state *
lp_fs_variant_key_sampler_idx(const struct lp_fragment_shader_variant_key * key,int idx)139 lp_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 
146 static inline struct lp_image_static_state *
lp_fs_variant_key_images(struct lp_fragment_shader_variant_key * key)147 lp_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 */
155 struct lp_fs_variant_list_item
156 {
157    struct list_head list;
158    struct lp_fragment_shader_variant *base;
159 };
160 
161 
162 struct 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 */
210 struct 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 
235 void
236 llvmpipe_fs_analyse_nir(struct lp_fragment_shader *shader);
237 
238 void
239 llvmpipe_fs_analyse(struct lp_fragment_shader *shader,
240                     const struct tgsi_token *tokens);
241 
242 void
243 llvmpipe_fs_variant_fastpath(struct lp_fragment_shader_variant *variant);
244 
245 void
246 llvmpipe_fs_variant_linear_fastpath(struct lp_fragment_shader_variant *variant);
247 
248 void
249 llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp,
250                                 struct lp_fragment_shader *shader,
251                                 struct lp_fragment_shader_variant *variant);
252 
253 void
254 lp_debug_fs_variant(struct lp_fragment_shader_variant *variant);
255 
256 const char *
257 lp_debug_fs_kind(enum lp_fs_kind kind);
258 
259 void
260 lp_linear_check_variant(struct lp_fragment_shader_variant *variant);
261 
262 void
263 llvmpipe_destroy_fs(struct llvmpipe_context *llvmpipe,
264                     struct lp_fragment_shader *shader);
265 
266 static inline void
lp_fs_reference(struct llvmpipe_context * llvmpipe,struct lp_fragment_shader ** ptr,struct lp_fragment_shader * shader)267 lp_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 
279 void
280 llvmpipe_destroy_shader_variant(struct llvmpipe_context *lp,
281                                 struct lp_fragment_shader_variant *variant);
282 
283 static inline void
lp_fs_variant_reference(struct llvmpipe_context * llvmpipe,struct lp_fragment_shader_variant ** ptr,struct lp_fragment_shader_variant * variant)284 lp_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