lp_bld_sample.h revision c70d539e24c901c54f427b91997f8ca566847f33
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 * Sampler static state.
56 *
57 * These are the bits of state from pipe_resource and pipe_sampler_state that
58 * are embedded in the generated code.
59 */
60struct lp_sampler_static_state
61{
62   /* pipe_sampler_view's state */
63   enum pipe_format format;
64   unsigned swizzle_r:3;     /**< PIPE_SWIZZLE_* */
65   unsigned swizzle_g:3;
66   unsigned swizzle_b:3;
67   unsigned swizzle_a:3;
68
69   /* pipe_texture's state */
70   unsigned target:3;        /**< PIPE_TEXTURE_* */
71   unsigned pot_width:1;     /**< is the width a power of two? */
72   unsigned pot_height:1;
73   unsigned pot_depth:1;
74
75   /* pipe_sampler_state's state */
76   unsigned wrap_s:3;
77   unsigned wrap_t:3;
78   unsigned wrap_r:3;
79   unsigned min_img_filter:2;
80   unsigned min_mip_filter:2;
81   unsigned mag_img_filter:2;
82   unsigned compare_mode:1;
83   unsigned compare_func:3;
84   unsigned normalized_coords:1;
85   float lod_bias, min_lod, max_lod;
86   float border_color[4];
87
88   /* Aero hacks */
89   unsigned force_nearest_s:1;
90   unsigned force_nearest_t:1;
91};
92
93
94/**
95 * Sampler dynamic state.
96 *
97 * These are the bits of state from pipe_resource and pipe_sampler_state that
98 * are computed in runtime.
99 *
100 * There are obtained through callbacks, as we don't want to tie the texture
101 * sampling code generation logic to any particular texture layout or pipe
102 * driver.
103 */
104struct lp_sampler_dynamic_state
105{
106
107   /** Obtain the base texture width. */
108   LLVMValueRef
109   (*width)( const struct lp_sampler_dynamic_state *state,
110             LLVMBuilderRef builder,
111             unsigned unit);
112
113   /** Obtain the base texture height. */
114   LLVMValueRef
115   (*height)( const struct lp_sampler_dynamic_state *state,
116              LLVMBuilderRef builder,
117              unsigned unit);
118
119   /** Obtain the base texture depth. */
120   LLVMValueRef
121   (*depth)( const struct lp_sampler_dynamic_state *state,
122             LLVMBuilderRef builder,
123             unsigned unit);
124
125   /** Obtain the number of mipmap levels (minus one). */
126   LLVMValueRef
127   (*last_level)( const struct lp_sampler_dynamic_state *state,
128                  LLVMBuilderRef builder,
129                  unsigned unit);
130
131   LLVMValueRef
132   (*row_stride)( const struct lp_sampler_dynamic_state *state,
133                  LLVMBuilderRef builder,
134                  unsigned unit);
135
136   LLVMValueRef
137   (*img_stride)( const struct lp_sampler_dynamic_state *state,
138                  LLVMBuilderRef builder,
139                  unsigned unit);
140
141   LLVMValueRef
142   (*data_ptr)( const struct lp_sampler_dynamic_state *state,
143                LLVMBuilderRef builder,
144                unsigned unit);
145
146};
147
148
149/**
150 * Keep all information for sampling code generation in a single place.
151 */
152struct lp_build_sample_context
153{
154   LLVMBuilderRef builder;
155
156   const struct lp_sampler_static_state *static_state;
157
158   struct lp_sampler_dynamic_state *dynamic_state;
159
160   const struct util_format_description *format_desc;
161
162   /** regular scalar float type */
163   struct lp_type float_type;
164   struct lp_build_context float_bld;
165
166   /** regular scalar float type */
167   struct lp_type int_type;
168   struct lp_build_context int_bld;
169
170   /** Incoming coordinates type and build context */
171   struct lp_type coord_type;
172   struct lp_build_context coord_bld;
173
174   /** Unsigned integer coordinates */
175   struct lp_type uint_coord_type;
176   struct lp_build_context uint_coord_bld;
177
178   /** Signed integer coordinates */
179   struct lp_type int_coord_type;
180   struct lp_build_context int_coord_bld;
181
182   /** Output texels type and build context */
183   struct lp_type texel_type;
184   struct lp_build_context texel_bld;
185};
186
187
188
189/**
190 * We only support a few wrap modes in lp_build_sample_wrap_linear_int() at
191 * this time.  Return whether the given mode is supported by that function.
192 */
193static INLINE boolean
194lp_is_simple_wrap_mode(unsigned mode)
195{
196   switch (mode) {
197   case PIPE_TEX_WRAP_REPEAT:
198   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
199      return TRUE;
200   default:
201      return FALSE;
202   }
203}
204
205
206static INLINE void
207apply_sampler_swizzle(struct lp_build_sample_context *bld,
208                      LLVMValueRef *texel)
209{
210   unsigned char swizzles[4];
211
212   swizzles[0] = bld->static_state->swizzle_r;
213   swizzles[1] = bld->static_state->swizzle_g;
214   swizzles[2] = bld->static_state->swizzle_b;
215   swizzles[3] = bld->static_state->swizzle_a;
216
217   lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
218}
219
220
221static INLINE int
222texture_dims(enum pipe_texture_target tex)
223{
224   switch (tex) {
225   case PIPE_TEXTURE_1D:
226      return 1;
227   case PIPE_TEXTURE_2D:
228   case PIPE_TEXTURE_RECT:
229   case PIPE_TEXTURE_CUBE:
230      return 2;
231   case PIPE_TEXTURE_3D:
232      return 3;
233   default:
234      assert(0 && "bad texture target in texture_dims()");
235      return 2;
236   }
237}
238
239
240/**
241 * Derive the sampler static state.
242 */
243void
244lp_sampler_static_state(struct lp_sampler_static_state *state,
245                        const struct pipe_sampler_view *view,
246                        const struct pipe_sampler_state *sampler);
247
248
249LLVMValueRef
250lp_build_lod_selector(struct lp_build_sample_context *bld,
251                      const LLVMValueRef ddx[4],
252                      const LLVMValueRef ddy[4],
253                      LLVMValueRef lod_bias, /* optional */
254                      LLVMValueRef explicit_lod, /* optional */
255                      LLVMValueRef width,
256                      LLVMValueRef height,
257                      LLVMValueRef depth);
258
259void
260lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
261                           unsigned unit,
262                           LLVMValueRef lod,
263                           LLVMValueRef *level_out);
264
265void
266lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
267                           unsigned unit,
268                           LLVMValueRef lod,
269                           LLVMValueRef *level0_out,
270                           LLVMValueRef *level1_out,
271                           LLVMValueRef *weight_out);
272
273LLVMValueRef
274lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
275                          LLVMValueRef data_array, LLVMValueRef level);
276
277LLVMValueRef
278lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
279                                LLVMValueRef data_array, int level);
280
281
282void
283lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
284                            unsigned dims,
285                            LLVMValueRef width_vec,
286                            LLVMValueRef height_vec,
287                            LLVMValueRef depth_vec,
288                            LLVMValueRef ilevel0,
289                            LLVMValueRef ilevel1,
290                            LLVMValueRef row_stride_array,
291                            LLVMValueRef img_stride_array,
292                            LLVMValueRef *width0_vec,
293                            LLVMValueRef *width1_vec,
294                            LLVMValueRef *height0_vec,
295                            LLVMValueRef *height1_vec,
296                            LLVMValueRef *depth0_vec,
297                            LLVMValueRef *depth1_vec,
298                            LLVMValueRef *row_stride0_vec,
299                            LLVMValueRef *row_stride1_vec,
300                            LLVMValueRef *img_stride0_vec,
301                            LLVMValueRef *img_stride1_vec);
302
303
304void
305lp_build_cube_lookup(struct lp_build_sample_context *bld,
306                     LLVMValueRef s,
307                     LLVMValueRef t,
308                     LLVMValueRef r,
309                     LLVMValueRef *face,
310                     LLVMValueRef *face_s,
311                     LLVMValueRef *face_t);
312
313
314void
315lp_build_sample_partial_offset(struct lp_build_context *bld,
316                               unsigned block_length,
317                               LLVMValueRef coord,
318                               LLVMValueRef stride,
319                               LLVMValueRef *out_offset,
320                               LLVMValueRef *out_i);
321
322
323void
324lp_build_sample_offset(struct lp_build_context *bld,
325                       const struct util_format_description *format_desc,
326                       LLVMValueRef x,
327                       LLVMValueRef y,
328                       LLVMValueRef z,
329                       LLVMValueRef y_stride,
330                       LLVMValueRef z_stride,
331                       LLVMValueRef *out_offset,
332                       LLVMValueRef *out_i,
333                       LLVMValueRef *out_j);
334
335
336void
337lp_build_sample_soa(LLVMBuilderRef builder,
338                    const struct lp_sampler_static_state *static_state,
339                    struct lp_sampler_dynamic_state *dynamic_state,
340                    struct lp_type fp_type,
341                    unsigned unit,
342                    unsigned num_coords,
343                    const LLVMValueRef *coords,
344                    const LLVMValueRef *ddx,
345                    const LLVMValueRef *ddy,
346                    LLVMValueRef lod_bias,
347                    LLVMValueRef explicit_lod,
348                    LLVMValueRef texel_out[4]);
349
350void
351lp_build_sample_nop(struct lp_type type,
352                    LLVMValueRef texel_out[4]);
353
354
355#endif /* LP_BLD_SAMPLE_H */
356