lp_bld_sample.h revision 3469715a8a171512cf9b528702e70393f01c6041
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
46struct pipe_resource;
47struct pipe_sampler_view;
48struct pipe_sampler_state;
49struct util_format_description;
50struct lp_type;
51struct lp_build_context;
52
53
54/**
55 * Helper struct holding all derivatives needed for sampling
56 */
57struct 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 */
69struct 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 */
115struct 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 */
191struct 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 */
261static INLINE boolean
262lp_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
274static INLINE void
275apply_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
289static INLINE unsigned
290texture_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
308boolean
309lp_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 */
316void
317lp_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
322void
323lp_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
332void
333lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
334                           unsigned unit,
335                           LLVMValueRef lod,
336                           LLVMValueRef *level_out);
337
338void
339lp_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
346LLVMValueRef
347lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
348                          LLVMValueRef level);
349
350
351void
352lp_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
359void
360lp_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
369void
370lp_build_unnormalized_coords(struct lp_build_sample_context *bld,
371                             LLVMValueRef flt_size,
372                             LLVMValueRef *s,
373                             LLVMValueRef *t,
374                             LLVMValueRef *r);
375
376
377void
378lp_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
387void
388lp_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
396void
397lp_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
409void
410lp_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
423void
424lp_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
432void
433lp_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
441void
442lp_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
449LLVMValueRef
450lp_build_minify(struct lp_build_context *bld,
451                LLVMValueRef base_size,
452                LLVMValueRef level);
453
454
455#endif /* LP_BLD_SAMPLE_H */
456