1 /**************************************************************************
2  *
3  * Copyright 2009 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 above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * @file
30  * Texture sampling.
31  *
32  * @author Jose Fonseca <jfonseca@vmware.com>
33  */
34 
35 #ifndef LP_BLD_SAMPLE_H
36 #define LP_BLD_SAMPLE_H
37 
38 
39 #include "pipe/p_format.h"
40 #include "util/u_debug.h"
41 #include "gallivm/lp_bld.h"
42 #include "gallivm/lp_bld_type.h"
43 #include "gallivm/lp_bld_swizzle.h"
44 
45 
46 struct pipe_resource;
47 struct pipe_sampler_view;
48 struct pipe_sampler_state;
49 struct util_format_description;
50 struct lp_type;
51 struct lp_build_context;
52 
53 
54 /**
55  * Helper struct holding all derivatives needed for sampling
56  */
57 struct lp_derivatives
58 {
59    LLVMValueRef ddx_ddy[2];
60 };
61 
62 
63 /**
64  * Sampler static state.
65  *
66  * These are the bits of state from pipe_resource and pipe_sampler_state that
67  * are embedded in the generated code.
68  */
69 struct lp_sampler_static_state
70 {
71    /* pipe_sampler_view's state */
72    enum pipe_format format;
73    unsigned swizzle_r:3;     /**< PIPE_SWIZZLE_* */
74    unsigned swizzle_g:3;
75    unsigned swizzle_b:3;
76    unsigned swizzle_a:3;
77 
78    /* pipe_texture's state */
79    unsigned target:3;        /**< PIPE_TEXTURE_* */
80    unsigned pot_width:1;     /**< is the width a power of two? */
81    unsigned pot_height:1;
82    unsigned pot_depth:1;
83 
84    /* pipe_sampler_state's state */
85    unsigned wrap_s:3;
86    unsigned wrap_t:3;
87    unsigned wrap_r:3;
88    unsigned min_img_filter:2;
89    unsigned min_mip_filter:2;
90    unsigned mag_img_filter:2;
91    unsigned compare_mode:1;
92    unsigned compare_func:3;
93    unsigned normalized_coords:1;
94    unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
95    unsigned lod_bias_non_zero:1;
96    unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
97    unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
98 
99    /* Hacks */
100    unsigned force_nearest_s:1;
101    unsigned force_nearest_t:1;
102 };
103 
104 
105 /**
106  * Sampler dynamic state.
107  *
108  * These are the bits of state from pipe_resource and pipe_sampler_state that
109  * are computed in runtime.
110  *
111  * There are obtained through callbacks, as we don't want to tie the texture
112  * sampling code generation logic to any particular texture layout or pipe
113  * driver.
114  */
115 struct lp_sampler_dynamic_state
116 {
117 
118    /** Obtain the base texture width (returns int32) */
119    LLVMValueRef
120    (*width)( const struct lp_sampler_dynamic_state *state,
121              struct gallivm_state *gallivm,
122              unsigned unit);
123 
124    /** Obtain the base texture height (returns int32) */
125    LLVMValueRef
126    (*height)( const struct lp_sampler_dynamic_state *state,
127               struct gallivm_state *gallivm,
128               unsigned unit);
129 
130    /** Obtain the base texture depth (returns int32) */
131    LLVMValueRef
132    (*depth)( const struct lp_sampler_dynamic_state *state,
133              struct gallivm_state *gallivm,
134              unsigned unit);
135 
136    /** Obtain the first mipmap level (base level) (returns int32) */
137    LLVMValueRef
138    (*first_level)( const struct lp_sampler_dynamic_state *state,
139                    struct gallivm_state *gallivm,
140                    unsigned unit);
141 
142    /** Obtain the number of mipmap levels minus one (returns int32) */
143    LLVMValueRef
144    (*last_level)( const struct lp_sampler_dynamic_state *state,
145                   struct gallivm_state *gallivm,
146                   unsigned unit);
147 
148    /** Obtain stride in bytes between image rows/blocks (returns int32) */
149    LLVMValueRef
150    (*row_stride)( const struct lp_sampler_dynamic_state *state,
151                   struct gallivm_state *gallivm,
152                   unsigned unit);
153 
154    /** Obtain stride in bytes between image slices (returns int32) */
155    LLVMValueRef
156    (*img_stride)( const struct lp_sampler_dynamic_state *state,
157                   struct gallivm_state *gallivm,
158                   unsigned unit);
159 
160    /** Obtain pointer to array of pointers to mimpap levels */
161    LLVMValueRef
162    (*data_ptr)( const struct lp_sampler_dynamic_state *state,
163                 struct gallivm_state *gallivm,
164                 unsigned unit);
165 
166    /** Obtain texture min lod (returns float) */
167    LLVMValueRef
168    (*min_lod)(const struct lp_sampler_dynamic_state *state,
169               struct gallivm_state *gallivm, unsigned unit);
170 
171    /** Obtain texture max lod (returns float) */
172    LLVMValueRef
173    (*max_lod)(const struct lp_sampler_dynamic_state *state,
174               struct gallivm_state *gallivm, unsigned unit);
175 
176    /** Obtain texture lod bias (returns float) */
177    LLVMValueRef
178    (*lod_bias)(const struct lp_sampler_dynamic_state *state,
179                struct gallivm_state *gallivm, unsigned unit);
180 
181    /** Obtain texture border color (returns ptr to float[4]) */
182    LLVMValueRef
183    (*border_color)(const struct lp_sampler_dynamic_state *state,
184                    struct gallivm_state *gallivm, unsigned unit);
185 };
186 
187 
188 /**
189  * Keep all information for sampling code generation in a single place.
190  */
191 struct lp_build_sample_context
192 {
193    struct gallivm_state *gallivm;
194 
195    const struct lp_sampler_static_state *static_state;
196 
197    struct lp_sampler_dynamic_state *dynamic_state;
198 
199    const struct util_format_description *format_desc;
200 
201    /* See texture_dims() */
202    unsigned dims;
203 
204    /** SIMD vector width */
205    unsigned vector_width;
206 
207    /** regular scalar float type */
208    struct lp_type float_type;
209    struct lp_build_context float_bld;
210 
211    /** float vector type */
212    struct lp_build_context float_vec_bld;
213 
214    /** regular scalar int type */
215    struct lp_type int_type;
216    struct lp_build_context int_bld;
217 
218    /** Incoming coordinates type and build context */
219    struct lp_type coord_type;
220    struct lp_build_context coord_bld;
221 
222    /** Signed integer coordinates */
223    struct lp_type int_coord_type;
224    struct lp_build_context int_coord_bld;
225 
226    /** Unsigned integer texture size */
227    struct lp_type int_size_type;
228    struct lp_build_context int_size_bld;
229 
230    /** Unsigned integer texture size */
231    struct lp_type float_size_type;
232    struct lp_build_context float_size_bld;
233 
234    /** Output texels type and build context */
235    struct lp_type texel_type;
236    struct lp_build_context texel_bld;
237 
238    /** Float per-quad type */
239    struct lp_type perquadf_type;
240    struct lp_build_context perquadf_bld;
241 
242    /** Int per-quad type */
243    struct lp_type perquadi_type;
244    struct lp_build_context perquadi_bld;
245 
246    /* Common dynamic state values */
247    LLVMValueRef row_stride_array;
248    LLVMValueRef img_stride_array;
249    LLVMValueRef data_array;
250 
251    /** Integer vector with texture width, height, depth */
252    LLVMValueRef int_size;
253 };
254 
255 
256 
257 /**
258  * We only support a few wrap modes in lp_build_sample_wrap_linear_int() at
259  * this time.  Return whether the given mode is supported by that function.
260  */
261 static INLINE boolean
lp_is_simple_wrap_mode(unsigned mode)262 lp_is_simple_wrap_mode(unsigned mode)
263 {
264    switch (mode) {
265    case PIPE_TEX_WRAP_REPEAT:
266    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
267       return TRUE;
268    default:
269       return FALSE;
270    }
271 }
272 
273 
274 static INLINE void
apply_sampler_swizzle(struct lp_build_sample_context * bld,LLVMValueRef * texel)275 apply_sampler_swizzle(struct lp_build_sample_context *bld,
276                       LLVMValueRef *texel)
277 {
278    unsigned char swizzles[4];
279 
280    swizzles[0] = bld->static_state->swizzle_r;
281    swizzles[1] = bld->static_state->swizzle_g;
282    swizzles[2] = bld->static_state->swizzle_b;
283    swizzles[3] = bld->static_state->swizzle_a;
284 
285    lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
286 }
287 
288 
289 static INLINE unsigned
texture_dims(enum pipe_texture_target tex)290 texture_dims(enum pipe_texture_target tex)
291 {
292    switch (tex) {
293    case PIPE_TEXTURE_1D:
294       return 1;
295    case PIPE_TEXTURE_2D:
296    case PIPE_TEXTURE_RECT:
297    case PIPE_TEXTURE_CUBE:
298       return 2;
299    case PIPE_TEXTURE_3D:
300       return 3;
301    default:
302       assert(0 && "bad texture target in texture_dims()");
303       return 2;
304    }
305 }
306 
307 
308 boolean
309 lp_sampler_wrap_mode_uses_border_color(unsigned mode,
310                                        unsigned min_img_filter,
311                                        unsigned mag_img_filter);
312 
313 /**
314  * Derive the sampler static state.
315  */
316 void
317 lp_sampler_static_state(struct lp_sampler_static_state *state,
318                         const struct pipe_sampler_view *view,
319                         const struct pipe_sampler_state *sampler);
320 
321 
322 void
323 lp_build_lod_selector(struct lp_build_sample_context *bld,
324                       unsigned unit,
325                       const struct lp_derivatives *derivs,
326                       LLVMValueRef lod_bias, /* optional */
327                       LLVMValueRef explicit_lod, /* optional */
328                       unsigned mip_filter,
329                       LLVMValueRef *out_lod_ipart,
330                       LLVMValueRef *out_lod_fpart);
331 
332 void
333 lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
334                            unsigned unit,
335                            LLVMValueRef lod,
336                            LLVMValueRef *level_out);
337 
338 void
339 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
340                            unsigned unit,
341                            LLVMValueRef lod_ipart,
342                            LLVMValueRef *lod_fpart_inout,
343                            LLVMValueRef *level0_out,
344                            LLVMValueRef *level1_out);
345 
346 LLVMValueRef
347 lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
348                           LLVMValueRef level);
349 
350 
351 void
352 lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
353                             LLVMValueRef ilevel,
354                             LLVMValueRef *out_size_vec,
355                             LLVMValueRef *row_stride_vec,
356                             LLVMValueRef *img_stride_vec);
357 
358 
359 void
360 lp_build_extract_image_sizes(struct lp_build_sample_context *bld,
361                              struct lp_type size_type,
362                              struct lp_type coord_type,
363                              LLVMValueRef size,
364                              LLVMValueRef *out_width,
365                              LLVMValueRef *out_height,
366                              LLVMValueRef *out_depth);
367 
368 
369 void
370 lp_build_unnormalized_coords(struct lp_build_sample_context *bld,
371                              LLVMValueRef flt_size,
372                              LLVMValueRef *s,
373                              LLVMValueRef *t,
374                              LLVMValueRef *r);
375 
376 
377 void
378 lp_build_cube_lookup(struct lp_build_sample_context *bld,
379                      LLVMValueRef s,
380                      LLVMValueRef t,
381                      LLVMValueRef r,
382                      LLVMValueRef *face,
383                      LLVMValueRef *face_s,
384                      LLVMValueRef *face_t);
385 
386 
387 void
388 lp_build_sample_partial_offset(struct lp_build_context *bld,
389                                unsigned block_length,
390                                LLVMValueRef coord,
391                                LLVMValueRef stride,
392                                LLVMValueRef *out_offset,
393                                LLVMValueRef *out_i);
394 
395 
396 void
397 lp_build_sample_offset(struct lp_build_context *bld,
398                        const struct util_format_description *format_desc,
399                        LLVMValueRef x,
400                        LLVMValueRef y,
401                        LLVMValueRef z,
402                        LLVMValueRef y_stride,
403                        LLVMValueRef z_stride,
404                        LLVMValueRef *out_offset,
405                        LLVMValueRef *out_i,
406                        LLVMValueRef *out_j);
407 
408 
409 void
410 lp_build_sample_soa(struct gallivm_state *gallivm,
411                     const struct lp_sampler_static_state *static_state,
412                     struct lp_sampler_dynamic_state *dynamic_state,
413                     struct lp_type fp_type,
414                     unsigned unit,
415                     unsigned num_coords,
416                     const LLVMValueRef *coords,
417                     const struct lp_derivatives *derivs,
418                     LLVMValueRef lod_bias,
419                     LLVMValueRef explicit_lod,
420                     LLVMValueRef texel_out[4]);
421 
422 
423 void
424 lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
425                                   LLVMValueRef coord_f,
426                                   LLVMValueRef length_i,
427                                   LLVMValueRef length_f,
428                                   LLVMValueRef *coord0_i,
429                                   LLVMValueRef *weight_f);
430 
431 
432 void
433 lp_build_size_query_soa(struct gallivm_state *gallivm,
434                         const struct lp_sampler_static_state *static_state,
435                         struct lp_sampler_dynamic_state *dynamic_state,
436                         struct lp_type int_type,
437                         unsigned unit,
438                         LLVMValueRef explicit_lod,
439                         LLVMValueRef *sizes_out);
440 
441 void
442 lp_build_sample_nop(struct gallivm_state *gallivm,
443                     struct lp_type type,
444                     unsigned num_coords,
445                     const LLVMValueRef *coords,
446                     LLVMValueRef texel_out[4]);
447 
448 
449 LLVMValueRef
450 lp_build_minify(struct lp_build_context *bld,
451                 LLVMValueRef base_size,
452                 LLVMValueRef level);
453 
454 
455 #endif /* LP_BLD_SAMPLE_H */
456