Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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