llvmpipe: make min/max lod and lod bias dynamic state
authorBrian Paul <brianp@vmware.com>
Fri, 24 Sep 2010 00:18:40 +0000 (18:18 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 24 Sep 2010 15:47:37 +0000 (09:47 -0600)
Before, changing any of these sampler values triggered generation
of new JIT code.  Added a new flag for the special case of
min_lod == max_lod which is hit during auto mipmap generation.

src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c

index e89ee7c2302f2617e1a0ad78a28ce93febe93e7a..caf1c7e86569946c7c911f502c0fe7a2f1657733 100644 (file)
@@ -99,21 +99,21 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
       state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
    }
 
+   /* If min_lod == max_lod we can greatly simplify mipmap selection.
+    * This is a case that occurs during automatic mipmap generation.
+    */
+   if (sampler->min_lod == sampler->max_lod) {
+      state->min_max_lod_equal = 1;
+      state->min_max_lod = sampler->min_lod;
+   }
+
    state->compare_mode      = sampler->compare_mode;
    if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
       state->compare_func   = sampler->compare_func;
    }
 
    state->normalized_coords = sampler->normalized_coords;
-   state->lod_bias          = sampler->lod_bias;
-   if (!view->last_level &&
-       sampler->min_img_filter == sampler->mag_img_filter) {
-      state->min_lod        = 0.0f;
-      state->max_lod        = 0.0f;
-   } else {
-      state->min_lod        = MAX2(sampler->min_lod, 0.0f);
-      state->max_lod        = sampler->max_lod;
-   }
+
    state->border_color[0]   = sampler->border_color[0];
    state->border_color[1]   = sampler->border_color[1];
    state->border_color[2]   = sampler->border_color[2];
@@ -140,6 +140,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
  */
 LLVMValueRef
 lp_build_lod_selector(struct lp_build_sample_context *bld,
+                      unsigned unit,
                       const LLVMValueRef ddx[4],
                       const LLVMValueRef ddy[4],
                       LLVMValueRef lod_bias, /* optional */
@@ -149,20 +150,20 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
                       LLVMValueRef depth)
 
 {
-   if (bld->static_state->min_lod == bld->static_state->max_lod) {
+   if (bld->static_state->min_max_lod_equal) {
       /* User is forcing sampling from a particular mipmap level.
        * This is hit during mipmap generation.
        */
-      return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
+      return LLVMConstReal(LLVMFloatType(), bld->static_state->min_max_lod);
    }
    else {
       struct lp_build_context *float_bld = &bld->float_bld;
-      LLVMValueRef sampler_lod_bias = LLVMConstReal(LLVMFloatType(),
-                                                    bld->static_state->lod_bias);
-      LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(),
-                                           bld->static_state->min_lod);
-      LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(),
-                                           bld->static_state->max_lod);
+      LLVMValueRef sampler_lod_bias =
+         bld->dynamic_state->lod_bias(bld->dynamic_state, bld->builder, unit);
+      LLVMValueRef min_lod =
+         bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+      LLVMValueRef max_lod =
+         bld->dynamic_state->max_lod(bld->dynamic_state, bld->builder, unit);
       LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
       LLVMValueRef lod;
 
index 8b042d5242e15ee5a14baba68a9f393ce6438dfe..661f35f6debff827449ddf4f3b06e6c440a3692c 100644 (file)
@@ -82,8 +82,9 @@ struct lp_sampler_static_state
    unsigned compare_mode:1;
    unsigned compare_func:3;
    unsigned normalized_coords:1;
-   float lod_bias, min_lod, max_lod;
    float border_color[4];
+   unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
+   float min_max_lod;             /**< only valid when min_max_lod_equal=1 */
 
    /* Aero hacks */
    unsigned force_nearest_s:1;
@@ -143,6 +144,20 @@ struct lp_sampler_dynamic_state
                 LLVMBuilderRef builder,
                 unsigned unit);
 
+   /** Obtain texture min lod */
+   LLVMValueRef
+   (*min_lod)(const struct lp_sampler_dynamic_state *state,
+              LLVMBuilderRef builder, unsigned unit);
+
+   /** Obtain texture max lod */
+   LLVMValueRef
+   (*max_lod)(const struct lp_sampler_dynamic_state *state,
+              LLVMBuilderRef builder, unsigned unit);
+
+   /** Obtain texture lod bias */
+   LLVMValueRef
+   (*lod_bias)(const struct lp_sampler_dynamic_state *state,
+               LLVMBuilderRef builder, unsigned unit);
 };
 
 
@@ -248,6 +263,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
 
 LLVMValueRef
 lp_build_lod_selector(struct lp_build_sample_context *bld,
+                      unsigned unit,
                       const LLVMValueRef ddx[4],
                       const LLVMValueRef ddy[4],
                       LLVMValueRef lod_bias, /* optional */
index 7e064900e77fed6aa686c4f59ac0f4fa03a2b2fc..000d4938a039ee3fb5408fdff7ad253f27be44ab 100644 (file)
@@ -970,7 +970,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
       /* Need to compute lod either to choose mipmap levels or to
        * distinguish between minification/magnification with one mipmap level.
        */
-      lod = lp_build_lod_selector(bld, ddx, ddy,
+      lod = lp_build_lod_selector(bld, unit, ddx, ddy,
                                   lod_bias, explicit_lod,
                                   width, height, depth);
    }
index 91fab18e4e6fd4773cb2680b1447a07df2995491..cbae1188a593dab0905b78134f07b956e616f48a 100644 (file)
@@ -937,7 +937,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       /* Need to compute lod either to choose mipmap levels or to
        * distinguish between minification/magnification with one mipmap level.
        */
-      lod = lp_build_lod_selector(bld, ddx, ddy,
+      lod = lp_build_lod_selector(bld, unit, ddx, ddy,
                                   lod_bias, explicit_lod,
                                   width, height, depth);
    }
index 8e6dfb293d04326b67470971648703ff8a3bb617..4c7089892ef2b50eeae6215cc55ba64e5d289ed3 100644 (file)
@@ -65,6 +65,11 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
          LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
                        LP_MAX_TEXTURE_LEVELS);
 
+      elem_types[LP_JIT_TEXTURE_MIN_LOD] = LLVMFloatType();
+      elem_types[LP_JIT_TEXTURE_MAX_LOD] = LLVMFloatType();
+      elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatType();
+
+
       texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
@@ -88,6 +93,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
                              screen->target, texture_type,
                              LP_JIT_TEXTURE_DATA);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod,
+                             screen->target, texture_type,
+                             LP_JIT_TEXTURE_MIN_LOD);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, max_lod,
+                             screen->target, texture_type,
+                             LP_JIT_TEXTURE_MAX_LOD);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, lod_bias,
+                             screen->target, texture_type,
+                             LP_JIT_TEXTURE_LOD_BIAS);
+
       LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
                            screen->target, texture_type);
 
index c94189413abde9637a5815fe59e9b7bfa021f486..e94d758e2001f7d7986adcb041a9012f7147b084 100644 (file)
@@ -54,6 +54,10 @@ struct lp_jit_texture
    uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
    const void *data[LP_MAX_TEXTURE_LEVELS];
+   /* sampler state, actually */
+   float min_lod;
+   float max_lod;
+   float lod_bias;
 };
 
 
@@ -65,6 +69,9 @@ enum {
    LP_JIT_TEXTURE_ROW_STRIDE,
    LP_JIT_TEXTURE_IMG_STRIDE,
    LP_JIT_TEXTURE_DATA,
+   LP_JIT_TEXTURE_MIN_LOD,
+   LP_JIT_TEXTURE_MAX_LOD,
+   LP_JIT_TEXTURE_LOD_BIAS,
    LP_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
 };
 
index ea7002aafcf472adecf123dcb97e714c10e446aa..28d202bd6555a78a9680fe59b97b0263987a72fa 100644 (file)
@@ -617,7 +617,8 @@ lp_setup_set_vertex_info( struct lp_setup_context *setup,
 void
 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                     unsigned num,
-                                    struct pipe_sampler_view **views)
+                                    struct pipe_sampler_view **views,
+                                    const struct pipe_sampler_state **samplers)
 {
    unsigned i;
 
@@ -638,6 +639,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
          jit_tex->depth = tex->depth0;
          jit_tex->last_level = tex->last_level;
 
+         /* sampler state */
+         jit_tex->min_lod = samplers[i]->min_lod;
+         jit_tex->max_lod = samplers[i]->max_lod;
+         jit_tex->lod_bias = samplers[i]->lod_bias;
+
          /* We're referencing the texture's internal data, so save a
           * reference to it.
           */
index 81ff43f8adc7da9e8f51de091d9bb0042c952978..868bd3ad2f146218a125f16f9f4f58b4a7a9e4be 100644 (file)
@@ -143,7 +143,8 @@ lp_setup_set_scissor( struct lp_setup_context *setup,
 void
 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                     unsigned num,
-                                    struct pipe_sampler_view **views);
+                                    struct pipe_sampler_view **views,
+                                    const struct pipe_sampler_state **samplers);
 
 unsigned
 lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
index edd723f65f28700bad18f187bb340efa1d3a708b..d2be22d7fc588e84fef758ec8a8551b79634dadc 100644 (file)
@@ -208,10 +208,12 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
       lp_setup_set_fs_constants(llvmpipe->setup, 
                                 llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
 
-   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
+   if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW |
+                          LP_NEW_SAMPLER))
       lp_setup_set_fragment_sampler_views(llvmpipe->setup,
                                           llvmpipe->num_fragment_sampler_views,
-                                          llvmpipe->fragment_sampler_views);
+                                          llvmpipe->fragment_sampler_views,
+                                          llvmpipe->sampler);
 
    llvmpipe->dirty = 0;
 }
index 4e026cc8ffbbbd7810603d0dcabf507754dd5187..151fe93cfbbc0908032f7db843aaee26c4cf86b1 100644 (file)
@@ -151,6 +151,9 @@ LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
 LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(data_ptr,   LP_JIT_TEXTURE_DATA, FALSE)
+LP_LLVM_TEXTURE_MEMBER(min_lod,    LP_JIT_TEXTURE_MIN_LOD, TRUE)
+LP_LLVM_TEXTURE_MEMBER(max_lod,    LP_JIT_TEXTURE_MAX_LOD, TRUE)
+LP_LLVM_TEXTURE_MEMBER(lod_bias,   LP_JIT_TEXTURE_LOD_BIAS, TRUE)
 
 
 static void
@@ -217,6 +220,10 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
    sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;
    sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
+   sampler->dynamic_state.base.min_lod = lp_llvm_texture_min_lod;
+   sampler->dynamic_state.base.max_lod = lp_llvm_texture_max_lod;
+   sampler->dynamic_state.base.lod_bias = lp_llvm_texture_lod_bias;
+
    sampler->dynamic_state.static_state = static_state;
    sampler->dynamic_state.context_ptr = context_ptr;