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