gallivm: support array textures
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_sample.h
index 4d2eeaa5eb45dab9c263459942f580647e03195b..ddd450b7be93dadbfbb3aec15147cf4e05732522 100644 (file)
@@ -51,6 +51,15 @@ struct lp_type;
 struct lp_build_context;
 
 
+/**
+ * Helper struct holding all derivatives needed for sampling
+ */
+struct lp_derivatives
+{
+   LLVMValueRef ddx_ddy[2];
+};
+
+
 /**
  * Sampler static state.
  *
@@ -83,6 +92,13 @@ struct lp_sampler_static_state
    unsigned compare_func:3;
    unsigned normalized_coords:1;
    unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
+   unsigned lod_bias_non_zero:1;
+   unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
+   unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
+
+   /* Hacks */
+   unsigned force_nearest_s:1;
+   unsigned force_nearest_t:1;
 };
 
 
@@ -102,64 +118,76 @@ struct lp_sampler_dynamic_state
    /** Obtain the base texture width (returns int32) */
    LLVMValueRef
    (*width)( const struct lp_sampler_dynamic_state *state,
-             LLVMBuilderRef builder,
+             struct gallivm_state *gallivm,
              unsigned unit);
 
    /** Obtain the base texture height (returns int32) */
    LLVMValueRef
    (*height)( const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder,
+              struct gallivm_state *gallivm,
               unsigned unit);
 
    /** Obtain the base texture depth (returns int32) */
    LLVMValueRef
    (*depth)( const struct lp_sampler_dynamic_state *state,
-             LLVMBuilderRef builder,
+             struct gallivm_state *gallivm,
              unsigned unit);
 
+   /** Obtain the first mipmap level (base level) (returns int32) */
+   LLVMValueRef
+   (*first_level)( const struct lp_sampler_dynamic_state *state,
+                   struct gallivm_state *gallivm,
+                   unsigned unit);
+
    /** Obtain the number of mipmap levels minus one (returns int32) */
    LLVMValueRef
    (*last_level)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
    /** Obtain stride in bytes between image rows/blocks (returns int32) */
    LLVMValueRef
    (*row_stride)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
    /** Obtain stride in bytes between image slices (returns int32) */
    LLVMValueRef
    (*img_stride)( const struct lp_sampler_dynamic_state *state,
-                  LLVMBuilderRef builder,
+                  struct gallivm_state *gallivm,
                   unsigned unit);
 
-   /** Obtain pointer to array of pointers to mimpap levels */
+   /** Obtain pointer to base of texture */
    LLVMValueRef
-   (*data_ptr)( const struct lp_sampler_dynamic_state *state,
-                LLVMBuilderRef builder,
+   (*base_ptr)( const struct lp_sampler_dynamic_state *state,
+                struct gallivm_state *gallivm,
                 unsigned unit);
 
+   /** Obtain pointer to array of mipmap offsets */
+   LLVMValueRef
+   (*mip_offsets)( const struct lp_sampler_dynamic_state *state,
+                   struct gallivm_state *gallivm,
+                   unsigned unit);
+
    /** Obtain texture min lod (returns float) */
    LLVMValueRef
    (*min_lod)(const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder, unsigned unit);
+              struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture max lod (returns float) */
    LLVMValueRef
    (*max_lod)(const struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder, unsigned unit);
+              struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture lod bias (returns float) */
    LLVMValueRef
    (*lod_bias)(const struct lp_sampler_dynamic_state *state,
-               LLVMBuilderRef builder, unsigned unit);
+               struct gallivm_state *gallivm, unsigned unit);
 
    /** Obtain texture border color (returns ptr to float[4]) */
    LLVMValueRef
    (*border_color)(const struct lp_sampler_dynamic_state *state,
-                   LLVMBuilderRef builder, unsigned unit);
+                   struct gallivm_state *gallivm, unsigned unit);
 };
 
 
@@ -168,7 +196,7 @@ struct lp_sampler_dynamic_state
  */
 struct lp_build_sample_context
 {
-   LLVMBuilderRef builder;
+   struct gallivm_state *gallivm;
 
    const struct lp_sampler_static_state *static_state;
 
@@ -176,6 +204,15 @@ struct lp_build_sample_context
 
    const struct util_format_description *format_desc;
 
+   /* See texture_dims() */
+   unsigned dims;
+
+   /** SIMD vector width */
+   unsigned vector_width;
+
+   /** number of lod values (valid are 1, length/4, length) */
+   unsigned num_lods;
+
    /** regular scalar float type */
    struct lp_type float_type;
    struct lp_build_context float_bld;
@@ -183,7 +220,7 @@ struct lp_build_sample_context
    /** float vector type */
    struct lp_build_context float_vec_bld;
 
-   /** regular scalar float type */
+   /** regular scalar int type */
    struct lp_type int_type;
    struct lp_build_context int_bld;
 
@@ -191,17 +228,46 @@ struct lp_build_sample_context
    struct lp_type coord_type;
    struct lp_build_context coord_bld;
 
-   /** Unsigned integer coordinates */
-   struct lp_type uint_coord_type;
-   struct lp_build_context uint_coord_bld;
-
    /** Signed integer coordinates */
    struct lp_type int_coord_type;
    struct lp_build_context int_coord_bld;
 
+   /** Unsigned integer texture size */
+   struct lp_type int_size_in_type;
+   struct lp_build_context int_size_in_bld;
+
+   /** Float incoming texture size */
+   struct lp_type float_size_in_type;
+   struct lp_build_context float_size_in_bld;
+
+   /** Unsigned integer texture size (might be per quad) */
+   struct lp_type int_size_type;
+   struct lp_build_context int_size_bld;
+
+   /** Float texture size (might be per quad) */
+   struct lp_type float_size_type;
+   struct lp_build_context float_size_bld;
+
    /** Output texels type and build context */
    struct lp_type texel_type;
    struct lp_build_context texel_bld;
+
+   /** Float per-quad type */
+   struct lp_type perquadf_type;
+   struct lp_build_context perquadf_bld;
+
+   /** Int per-quad type */
+   struct lp_type perquadi_type;
+   struct lp_build_context perquadi_bld;
+
+   /* Common dynamic state values */
+   LLVMValueRef row_stride_array;
+   LLVMValueRef img_stride_array;
+   LLVMValueRef base_ptr;
+   LLVMValueRef mip_offsets;
+
+   /** Integer vector with texture width, height, depth */
+   LLVMValueRef int_size;
 };
 
 
@@ -237,14 +303,20 @@ apply_sampler_swizzle(struct lp_build_sample_context *bld,
    lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
 }
 
-
-static INLINE int
+/*
+ * not really dimension as such, this indicates the amount of
+ * "normal" texture coords subject to minification, wrapping etc.
+ */
+static INLINE unsigned
 texture_dims(enum pipe_texture_target tex)
 {
    switch (tex) {
    case PIPE_TEXTURE_1D:
+   case PIPE_TEXTURE_1D_ARRAY:
+   case PIPE_BUFFER:
       return 1;
    case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_2D_ARRAY:
    case PIPE_TEXTURE_RECT:
    case PIPE_TEXTURE_CUBE:
       return 2;
@@ -271,16 +343,15 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
                         const struct pipe_sampler_state *sampler);
 
 
-LLVMValueRef
+void
 lp_build_lod_selector(struct lp_build_sample_context *bld,
                       unsigned unit,
-                      const LLVMValueRef ddx[4],
-                      const LLVMValueRef ddy[4],
+                      const struct lp_derivatives *derivs,
                       LLVMValueRef lod_bias, /* optional */
                       LLVMValueRef explicit_lod, /* optional */
-                      LLVMValueRef width,
-                      LLVMValueRef height,
-                      LLVMValueRef depth);
+                      unsigned mip_filter,
+                      LLVMValueRef *out_lod_ipart,
+                      LLVMValueRef *out_lod_fpart);
 
 void
 lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
@@ -291,40 +362,45 @@ lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
 void
 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
                            unsigned unit,
-                           LLVMValueRef lod,
+                           LLVMValueRef lod_ipart,
+                           LLVMValueRef *lod_fpart_inout,
                            LLVMValueRef *level0_out,
-                           LLVMValueRef *level1_out,
-                           LLVMValueRef *weight_out);
+                           LLVMValueRef *level1_out);
 
 LLVMValueRef
 lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
-                          LLVMValueRef data_array, LLVMValueRef level);
+                          LLVMValueRef level);
+
 
 LLVMValueRef
-lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
-                                LLVMValueRef data_array, int level);
+lp_build_get_mip_offsets(struct lp_build_sample_context *bld,
+                         LLVMValueRef level);
 
 
 void
 lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
-                            unsigned dims,
-                            LLVMValueRef width_vec,
-                            LLVMValueRef height_vec,
-                            LLVMValueRef depth_vec,
-                            LLVMValueRef ilevel0,
-                            LLVMValueRef ilevel1,
-                            LLVMValueRef row_stride_array,
-                            LLVMValueRef img_stride_array,
-                            LLVMValueRef *width0_vec,
-                            LLVMValueRef *width1_vec,
-                            LLVMValueRef *height0_vec,
-                            LLVMValueRef *height1_vec,
-                            LLVMValueRef *depth0_vec,
-                            LLVMValueRef *depth1_vec,
-                            LLVMValueRef *row_stride0_vec,
-                            LLVMValueRef *row_stride1_vec,
-                            LLVMValueRef *img_stride0_vec,
-                            LLVMValueRef *img_stride1_vec);
+                            LLVMValueRef ilevel,
+                            LLVMValueRef *out_size_vec,
+                            LLVMValueRef *row_stride_vec,
+                            LLVMValueRef *img_stride_vec);
+
+
+void
+lp_build_extract_image_sizes(struct lp_build_sample_context *bld,
+                             struct lp_build_context *size_bld,
+                             struct lp_type coord_type,
+                             LLVMValueRef size,
+                             LLVMValueRef *out_width,
+                             LLVMValueRef *out_height,
+                             LLVMValueRef *out_depth);
+
+
+void
+lp_build_unnormalized_coords(struct lp_build_sample_context *bld,
+                             LLVMValueRef flt_size,
+                             LLVMValueRef *s,
+                             LLVMValueRef *t,
+                             LLVMValueRef *r);
 
 
 void
@@ -360,22 +436,49 @@ lp_build_sample_offset(struct lp_build_context *bld,
 
 
 void
-lp_build_sample_soa(LLVMBuilderRef builder,
+lp_build_sample_soa(struct gallivm_state *gallivm,
                     const struct lp_sampler_static_state *static_state,
                     struct lp_sampler_dynamic_state *dynamic_state,
                     struct lp_type fp_type,
+                    boolean is_fetch,
                     unsigned unit,
-                    unsigned num_coords,
                     const LLVMValueRef *coords,
-                    const LLVMValueRef *ddx,
-                    const LLVMValueRef *ddy,
+                    const LLVMValueRef *offsets,
+                    const struct lp_derivatives *derivs,
                     LLVMValueRef lod_bias,
                     LLVMValueRef explicit_lod,
                     LLVMValueRef texel_out[4]);
 
+
+void
+lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
+                                  LLVMValueRef coord_f,
+                                  LLVMValueRef length_i,
+                                  LLVMValueRef length_f,
+                                  LLVMValueRef *coord0_i,
+                                  LLVMValueRef *weight_f);
+
+
 void
-lp_build_sample_nop(struct lp_type type,
+lp_build_size_query_soa(struct gallivm_state *gallivm,
+                        const struct lp_sampler_static_state *static_state,
+                        struct lp_sampler_dynamic_state *dynamic_state,
+                        struct lp_type int_type,
+                        unsigned unit,
+                        LLVMValueRef explicit_lod,
+                        LLVMValueRef *sizes_out);
+
+void
+lp_build_sample_nop(struct gallivm_state *gallivm, 
+                    struct lp_type type,
+                    const LLVMValueRef *coords,
                     LLVMValueRef texel_out[4]);
 
 
+LLVMValueRef
+lp_build_minify(struct lp_build_context *bld,
+                LLVMValueRef base_size,
+                LLVMValueRef level);
+
+
 #endif /* LP_BLD_SAMPLE_H */