• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 struct pipe_resource;
50 struct pipe_sampler_view;
51 struct pipe_sampler_state;
52 struct util_format_description;
53 struct lp_type;
54 struct lp_build_context;
55 
56 
57 /**
58  * Helper struct holding all derivatives needed for sampling
59  */
60 struct lp_derivatives
61 {
62    LLVMValueRef ddx[3];
63    LLVMValueRef ddy[3];
64 };
65 
66 
67 enum lp_sampler_lod_property {
68    LP_SAMPLER_LOD_SCALAR,
69    LP_SAMPLER_LOD_PER_ELEMENT,
70    LP_SAMPLER_LOD_PER_QUAD
71 };
72 
73 
74 enum lp_sampler_lod_control {
75    LP_SAMPLER_LOD_IMPLICIT,
76    LP_SAMPLER_LOD_BIAS,
77    LP_SAMPLER_LOD_EXPLICIT,
78    LP_SAMPLER_LOD_DERIVATIVES,
79 };
80 
81 
82 enum lp_sampler_op_type {
83    LP_SAMPLER_OP_TEXTURE,
84    LP_SAMPLER_OP_FETCH,
85    LP_SAMPLER_OP_GATHER
86 };
87 
88 
89 #define LP_SAMPLER_SHADOW             (1 << 0)
90 #define LP_SAMPLER_OFFSETS            (1 << 1)
91 #define LP_SAMPLER_OP_TYPE_SHIFT            2
92 #define LP_SAMPLER_OP_TYPE_MASK       (3 << 2)
93 #define LP_SAMPLER_LOD_CONTROL_SHIFT        4
94 #define LP_SAMPLER_LOD_CONTROL_MASK   (3 << 4)
95 #define LP_SAMPLER_LOD_PROPERTY_SHIFT       6
96 #define LP_SAMPLER_LOD_PROPERTY_MASK  (3 << 6)
97 
98 struct lp_sampler_params
99 {
100    struct lp_type type;
101    unsigned texture_index;
102    unsigned sampler_index;
103    unsigned sample_key;
104    LLVMValueRef context_ptr;
105    LLVMValueRef thread_data_ptr;
106    const LLVMValueRef *coords;
107    const LLVMValueRef *offsets;
108    LLVMValueRef lod;
109    const struct lp_derivatives *derivs;
110    LLVMValueRef *texel;
111 };
112 
113 struct lp_sampler_size_query_params
114 {
115    struct lp_type int_type;
116    unsigned texture_unit;
117    unsigned target;
118    LLVMValueRef context_ptr;
119    boolean is_sviewinfo;
120    enum lp_sampler_lod_property lod_property;
121    LLVMValueRef explicit_lod;
122    LLVMValueRef *sizes_out;
123 };
124 /**
125  * Texture static state.
126  *
127  * These are the bits of state from pipe_resource/pipe_sampler_view that
128  * are embedded in the generated code.
129  */
130 struct lp_static_texture_state
131 {
132    /* pipe_sampler_view's state */
133    enum pipe_format format;
134    unsigned swizzle_r:3;     /**< PIPE_SWIZZLE_* */
135    unsigned swizzle_g:3;
136    unsigned swizzle_b:3;
137    unsigned swizzle_a:3;
138 
139    /* pipe_texture's state */
140    unsigned target:4;        /**< PIPE_TEXTURE_* */
141    unsigned pot_width:1;     /**< is the width a power of two? */
142    unsigned pot_height:1;
143    unsigned pot_depth:1;
144    unsigned level_zero_only:1;
145 };
146 
147 
148 /**
149  * Sampler static state.
150  *
151  * These are the bits of state from pipe_sampler_state that
152  * are embedded in the generated code.
153  */
154 struct lp_static_sampler_state
155 {
156    /* pipe_sampler_state's state */
157    unsigned wrap_s:3;
158    unsigned wrap_t:3;
159    unsigned wrap_r:3;
160    unsigned min_img_filter:2;
161    unsigned min_mip_filter:2;
162    unsigned mag_img_filter:2;
163    unsigned compare_mode:1;
164    unsigned compare_func:3;
165    unsigned normalized_coords:1;
166    unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
167    unsigned lod_bias_non_zero:1;
168    unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
169    unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
170    unsigned seamless_cube_map:1;
171 
172    /* Hacks */
173    unsigned force_nearest_s:1;
174    unsigned force_nearest_t:1;
175 };
176 
177 
178 /**
179  * Sampler dynamic state.
180  *
181  * These are the bits of state from pipe_resource/pipe_sampler_view
182  * as well as from sampler state that are computed at runtime.
183  *
184  * There are obtained through callbacks, as we don't want to tie the texture
185  * sampling code generation logic to any particular texture layout or pipe
186  * driver.
187  */
188 struct lp_sampler_dynamic_state
189 {
190    /* First callbacks for sampler view state */
191 
192    /** Obtain the base texture width (or number of elements) (returns int32) */
193    LLVMValueRef
194    (*width)(const struct lp_sampler_dynamic_state *state,
195             struct gallivm_state *gallivm,
196             LLVMValueRef context_ptr,
197             unsigned texture_unit);
198 
199    /** Obtain the base texture height (returns int32) */
200    LLVMValueRef
201    (*height)(const struct lp_sampler_dynamic_state *state,
202              struct gallivm_state *gallivm,
203              LLVMValueRef context_ptr,
204              unsigned texture_unit);
205 
206    /** Obtain the base texture depth (or array size) (returns int32) */
207    LLVMValueRef
208    (*depth)(const struct lp_sampler_dynamic_state *state,
209             struct gallivm_state *gallivm,
210             LLVMValueRef context_ptr,
211             unsigned texture_unit);
212 
213    /** Obtain the first mipmap level (base level) (returns int32) */
214    LLVMValueRef
215    (*first_level)(const struct lp_sampler_dynamic_state *state,
216                   struct gallivm_state *gallivm,
217                   LLVMValueRef context_ptr,
218                   unsigned texture_unit);
219 
220    /** Obtain the number of mipmap levels minus one (returns int32) */
221    LLVMValueRef
222    (*last_level)(const struct lp_sampler_dynamic_state *state,
223                  struct gallivm_state *gallivm,
224                  LLVMValueRef context_ptr,
225                  unsigned texture_unit);
226 
227    /** Obtain stride in bytes between image rows/blocks (returns int32) */
228    LLVMValueRef
229    (*row_stride)(const struct lp_sampler_dynamic_state *state,
230                  struct gallivm_state *gallivm,
231                  LLVMValueRef context_ptr,
232                  unsigned texture_unit);
233 
234    /** Obtain stride in bytes between image slices (returns int32) */
235    LLVMValueRef
236    (*img_stride)(const struct lp_sampler_dynamic_state *state,
237                  struct gallivm_state *gallivm,
238                  LLVMValueRef context_ptr,
239                  unsigned texture_unit);
240 
241    /** Obtain pointer to base of texture */
242    LLVMValueRef
243    (*base_ptr)(const struct lp_sampler_dynamic_state *state,
244                struct gallivm_state *gallivm,
245                LLVMValueRef context_ptr,
246                unsigned texture_unit);
247 
248    /** Obtain pointer to array of mipmap offsets */
249    LLVMValueRef
250    (*mip_offsets)(const struct lp_sampler_dynamic_state *state,
251                   struct gallivm_state *gallivm,
252                   LLVMValueRef context_ptr,
253                   unsigned texture_unit);
254 
255    /* These are callbacks for sampler state */
256 
257    /** Obtain texture min lod (returns float) */
258    LLVMValueRef
259    (*min_lod)(const struct lp_sampler_dynamic_state *state,
260               struct gallivm_state *gallivm,
261               LLVMValueRef context_ptr,
262               unsigned sampler_unit);
263 
264    /** Obtain texture max lod (returns float) */
265    LLVMValueRef
266    (*max_lod)(const struct lp_sampler_dynamic_state *state,
267               struct gallivm_state *gallivm,
268               LLVMValueRef context_ptr,
269               unsigned sampler_unit);
270 
271    /** Obtain texture lod bias (returns float) */
272    LLVMValueRef
273    (*lod_bias)(const struct lp_sampler_dynamic_state *state,
274                struct gallivm_state *gallivm,
275                LLVMValueRef context_ptr,
276                unsigned sampler_unit);
277 
278    /** Obtain texture border color (returns ptr to float[4]) */
279    LLVMValueRef
280    (*border_color)(const struct lp_sampler_dynamic_state *state,
281                    struct gallivm_state *gallivm,
282                    LLVMValueRef context_ptr,
283                    unsigned sampler_unit);
284 
285    /**
286     * Obtain texture cache (returns ptr to lp_build_format_cache).
287     *
288     * It's optional: no caching will be done if it's NULL.
289     */
290    LLVMValueRef
291    (*cache_ptr)(const struct lp_sampler_dynamic_state *state,
292                 struct gallivm_state *gallivm,
293                 LLVMValueRef thread_data_ptr,
294                 unsigned unit);
295 };
296 
297 
298 /**
299  * Keep all information for sampling code generation in a single place.
300  */
301 struct lp_build_sample_context
302 {
303    struct gallivm_state *gallivm;
304 
305    const struct lp_static_texture_state *static_texture_state;
306    const struct lp_static_sampler_state *static_sampler_state;
307 
308    struct lp_sampler_dynamic_state *dynamic_state;
309 
310    const struct util_format_description *format_desc;
311 
312    /* See texture_dims() */
313    unsigned dims;
314 
315    /** SIMD vector width */
316    unsigned vector_width;
317 
318    /** number of mipmaps (valid are 1, length/4, length) */
319    unsigned num_mips;
320 
321    /** number of lod values (valid are 1, length/4, length) */
322    unsigned num_lods;
323 
324    /** regular scalar float type */
325    struct lp_type float_type;
326    struct lp_build_context float_bld;
327 
328    /** float vector type */
329    struct lp_build_context float_vec_bld;
330 
331    /** regular scalar int type */
332    struct lp_type int_type;
333    struct lp_build_context int_bld;
334 
335    /** Incoming coordinates type and build context */
336    struct lp_type coord_type;
337    struct lp_build_context coord_bld;
338 
339    /** Signed integer coordinates */
340    struct lp_type int_coord_type;
341    struct lp_build_context int_coord_bld;
342 
343    /** Unsigned integer texture size */
344    struct lp_type int_size_in_type;
345    struct lp_build_context int_size_in_bld;
346 
347    /** Float incoming texture size */
348    struct lp_type float_size_in_type;
349    struct lp_build_context float_size_in_bld;
350 
351    /** Unsigned integer texture size (might be per quad) */
352    struct lp_type int_size_type;
353    struct lp_build_context int_size_bld;
354 
355    /** Float texture size (might be per quad) */
356    struct lp_type float_size_type;
357    struct lp_build_context float_size_bld;
358 
359    /** Output texels type and build context */
360    struct lp_type texel_type;
361    struct lp_build_context texel_bld;
362 
363    /** Float level type */
364    struct lp_type levelf_type;
365    struct lp_build_context levelf_bld;
366 
367    /** Int level type */
368    struct lp_type leveli_type;
369    struct lp_build_context leveli_bld;
370 
371    /** Float lod type */
372    struct lp_type lodf_type;
373    struct lp_build_context lodf_bld;
374 
375    /** Int lod type */
376    struct lp_type lodi_type;
377    struct lp_build_context lodi_bld;
378 
379    /* Common dynamic state values */
380    LLVMValueRef row_stride_array;
381    LLVMValueRef img_stride_array;
382    LLVMValueRef base_ptr;
383    LLVMValueRef mip_offsets;
384    LLVMValueRef cache;
385 
386    /** Integer vector with texture width, height, depth */
387    LLVMValueRef int_size;
388 
389    LLVMValueRef border_color_clamped;
390 
391    LLVMValueRef context_ptr;
392 };
393 
394 
395 
396 /**
397  * We only support a few wrap modes in lp_build_sample_wrap_linear_int() at
398  * this time.  Return whether the given mode is supported by that function.
399  */
400 static inline boolean
lp_is_simple_wrap_mode(unsigned mode)401 lp_is_simple_wrap_mode(unsigned mode)
402 {
403    switch (mode) {
404    case PIPE_TEX_WRAP_REPEAT:
405    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
406       return TRUE;
407    default:
408       return FALSE;
409    }
410 }
411 
412 
413 static inline void
apply_sampler_swizzle(struct lp_build_sample_context * bld,LLVMValueRef * texel)414 apply_sampler_swizzle(struct lp_build_sample_context *bld,
415                       LLVMValueRef *texel)
416 {
417    unsigned char swizzles[4];
418 
419    swizzles[0] = bld->static_texture_state->swizzle_r;
420    swizzles[1] = bld->static_texture_state->swizzle_g;
421    swizzles[2] = bld->static_texture_state->swizzle_b;
422    swizzles[3] = bld->static_texture_state->swizzle_a;
423 
424    lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
425 }
426 
427 /*
428  * not really dimension as such, this indicates the amount of
429  * "normal" texture coords subject to minification, wrapping etc.
430  */
431 static inline unsigned
texture_dims(enum pipe_texture_target tex)432 texture_dims(enum pipe_texture_target tex)
433 {
434    switch (tex) {
435    case PIPE_TEXTURE_1D:
436    case PIPE_TEXTURE_1D_ARRAY:
437    case PIPE_BUFFER:
438       return 1;
439    case PIPE_TEXTURE_2D:
440    case PIPE_TEXTURE_2D_ARRAY:
441    case PIPE_TEXTURE_RECT:
442    case PIPE_TEXTURE_CUBE:
443    case PIPE_TEXTURE_CUBE_ARRAY:
444       return 2;
445    case PIPE_TEXTURE_3D:
446       return 3;
447    default:
448       assert(0 && "bad texture target in texture_dims()");
449       return 2;
450    }
451 }
452 
453 static inline boolean
has_layer_coord(enum pipe_texture_target tex)454 has_layer_coord(enum pipe_texture_target tex)
455 {
456    switch (tex) {
457    case PIPE_TEXTURE_1D_ARRAY:
458    case PIPE_TEXTURE_2D_ARRAY:
459    /* cube is not layered but 3rd coord (after cube mapping) behaves the same */
460    case PIPE_TEXTURE_CUBE:
461    case PIPE_TEXTURE_CUBE_ARRAY:
462       return TRUE;
463    default:
464       return FALSE;
465    }
466 }
467 
468 
469 boolean
470 lp_sampler_wrap_mode_uses_border_color(unsigned mode,
471                                        unsigned min_img_filter,
472                                        unsigned mag_img_filter);
473 
474 /**
475  * Derive the sampler static state.
476  */
477 void
478 lp_sampler_static_sampler_state(struct lp_static_sampler_state *state,
479                                 const struct pipe_sampler_state *sampler);
480 
481 
482 void
483 lp_sampler_static_texture_state(struct lp_static_texture_state *state,
484                                 const struct pipe_sampler_view *view);
485 
486 
487 void
488 lp_build_lod_selector(struct lp_build_sample_context *bld,
489                       unsigned texture_index,
490                       unsigned sampler_index,
491                       LLVMValueRef s,
492                       LLVMValueRef t,
493                       LLVMValueRef r,
494                       LLVMValueRef cube_rho,
495                       const struct lp_derivatives *derivs,
496                       LLVMValueRef lod_bias, /* optional */
497                       LLVMValueRef explicit_lod, /* optional */
498                       unsigned mip_filter,
499                       LLVMValueRef *out_lod_ipart,
500                       LLVMValueRef *out_lod_fpart,
501                       LLVMValueRef *out_lod_positive);
502 
503 void
504 lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
505                            unsigned texture_unit,
506                            LLVMValueRef lod,
507                            LLVMValueRef *level_out,
508                            LLVMValueRef *out_of_bounds);
509 
510 void
511 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
512                            unsigned texture_unit,
513                            LLVMValueRef lod_ipart,
514                            LLVMValueRef *lod_fpart_inout,
515                            LLVMValueRef *level0_out,
516                            LLVMValueRef *level1_out);
517 
518 LLVMValueRef
519 lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
520                           LLVMValueRef level);
521 
522 
523 LLVMValueRef
524 lp_build_get_mip_offsets(struct lp_build_sample_context *bld,
525                          LLVMValueRef level);
526 
527 
528 void
529 lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
530                             LLVMValueRef ilevel,
531                             LLVMValueRef *out_size_vec,
532                             LLVMValueRef *row_stride_vec,
533                             LLVMValueRef *img_stride_vec);
534 
535 
536 void
537 lp_build_extract_image_sizes(struct lp_build_sample_context *bld,
538                              struct lp_build_context *size_bld,
539                              struct lp_type coord_type,
540                              LLVMValueRef size,
541                              LLVMValueRef *out_width,
542                              LLVMValueRef *out_height,
543                              LLVMValueRef *out_depth);
544 
545 
546 void
547 lp_build_unnormalized_coords(struct lp_build_sample_context *bld,
548                              LLVMValueRef flt_size,
549                              LLVMValueRef *s,
550                              LLVMValueRef *t,
551                              LLVMValueRef *r);
552 
553 
554 void
555 lp_build_cube_lookup(struct lp_build_sample_context *bld,
556                      LLVMValueRef *coords,
557                      const struct lp_derivatives *derivs_in, /* optional */
558                      LLVMValueRef *rho,
559                      struct lp_derivatives *derivs_out, /* optional */
560                      boolean need_derivs);
561 
562 
563 void
564 lp_build_cube_new_coords(struct lp_build_context *ivec_bld,
565                          LLVMValueRef face,
566                          LLVMValueRef x0,
567                          LLVMValueRef x1,
568                          LLVMValueRef y0,
569                          LLVMValueRef y1,
570                          LLVMValueRef max_coord,
571                          LLVMValueRef new_faces[4],
572                          LLVMValueRef new_xcoords[4][2],
573                          LLVMValueRef new_ycoords[4][2]);
574 
575 
576 void
577 lp_build_sample_partial_offset(struct lp_build_context *bld,
578                                unsigned block_length,
579                                LLVMValueRef coord,
580                                LLVMValueRef stride,
581                                LLVMValueRef *out_offset,
582                                LLVMValueRef *out_i);
583 
584 
585 void
586 lp_build_sample_offset(struct lp_build_context *bld,
587                        const struct util_format_description *format_desc,
588                        LLVMValueRef x,
589                        LLVMValueRef y,
590                        LLVMValueRef z,
591                        LLVMValueRef y_stride,
592                        LLVMValueRef z_stride,
593                        LLVMValueRef *out_offset,
594                        LLVMValueRef *out_i,
595                        LLVMValueRef *out_j);
596 
597 
598 void
599 lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state,
600                     const struct lp_static_sampler_state *static_sampler_state,
601                     struct lp_sampler_dynamic_state *dynamic_texture_state,
602                     struct gallivm_state *gallivm,
603                     const struct lp_sampler_params *params);
604 
605 
606 void
607 lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
608                                   LLVMValueRef coord_f,
609                                   LLVMValueRef length_i,
610                                   LLVMValueRef length_f,
611                                   LLVMValueRef *coord0_i,
612                                   LLVMValueRef *weight_f);
613 
614 
615 void
616 lp_build_size_query_soa(struct gallivm_state *gallivm,
617                         const struct lp_static_texture_state *static_state,
618                         struct lp_sampler_dynamic_state *dynamic_state,
619                         const struct lp_sampler_size_query_params *params);
620 
621 void
622 lp_build_sample_nop(struct gallivm_state *gallivm,
623                     struct lp_type type,
624                     const LLVMValueRef *coords,
625                     LLVMValueRef texel_out[4]);
626 
627 
628 LLVMValueRef
629 lp_build_minify(struct lp_build_context *bld,
630                 LLVMValueRef base_size,
631                 LLVMValueRef level,
632                 boolean lod_scalar);
633 
634 #ifdef __cplusplus
635 }
636 #endif
637 
638 #endif /* LP_BLD_SAMPLE_H */
639