fprintf(fp, "\t unnorm_coords: 0x%x (%d)\n", desc->unnorm_coords, desc->unnorm_coords);
    fprintf(fp, "\t unknown_1_2: 0x%x (%d)\n", desc->unknown_1_2, desc->unknown_1_2);
    fprintf(fp, "\t texture_type: 0x%x (%d)\n", desc->texture_type, desc->texture_type);
-   fprintf(fp, "\t unknown_1_3: 0x%x (%d)\n", desc->unknown_1_3, desc->unknown_1_3);
-   fprintf(fp, "\t miplevels: 0x%x (%d)\n", desc->miplevels, desc->miplevels);
-   fprintf(fp, "\t min_mipfilter_1: 0x%x (%d)\n", desc->min_mipfilter_1, desc->min_mipfilter_1);
+   fprintf(fp, "\t min_lod: 0x%x (%d) (%f)\n", desc->min_lod, desc->min_lod, lima_fixed8_to_float(desc->min_lod));
+   fprintf(fp, "\t max_lod: 0x%x (%d) (%f)\n", desc->max_lod, desc->max_lod, lima_fixed8_to_float(desc->max_lod));
+   fprintf(fp, "\t lod_bias: 0x%x (%d) (%f)\n", desc->lod_bias, desc->lod_bias, lima_fixed8_to_float(desc->lod_bias));
    fprintf(fp, "\t unknown_2_1: 0x%x (%d)\n", desc->unknown_2_1, desc->unknown_2_1);
    fprintf(fp, "\t has_stride: 0x%x (%d)\n", desc->has_stride, desc->has_stride);
    fprintf(fp, "\t min_mipfilter_2: 0x%x (%d)\n", desc->min_mipfilter_2, desc->min_mipfilter_2);
    fprintf(fp, "/* 0x%08x (0x%08x) */",
            start + i * 4, i * 4);
    fprintf(fp, "\t");
-   for (int k = 0; k < ((((desc->miplevels + 1) * 26) + 64) / 32); k++)
+
+   int miplevels = (int)lima_fixed8_to_float(desc->max_lod);
+   for (int k = 0; k < ((((miplevels + 1) * 26) + 64) / 32); k++)
       fprintf(fp, "0x%08x ", *(&data[i + offset + k]));
    fprintf(fp, "\n");
 
    uint32_t va;
    uint32_t va_1;
    uint32_t va_2;
-   for (j = 1; j <= desc->miplevels; j++) {
+   for (j = 1; j <= miplevels; j++) {
       va = 0;
       va_1 = 0;
       va_2 = 0;
 
    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
       return 16.0f;
    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
-      return 16.0f;
+      return 15.0f;
 
    default:
       return 0.0f;
 
                      struct lima_sampler_view *texture, void *pdesc,
                      unsigned desc_size)
 {
+   /* unit is 1/16 since lod_bias is in fixed format */
+   int lod_bias_delta = 0;
    lima_tex_desc *desc = pdesc;
    unsigned first_level;
    unsigned last_level;
+   float max_lod;
 
    memset(desc, 0, desc_size);
 
    if (last_level - first_level >= LIMA_MAX_MIP_LEVELS)
       last_level = first_level + LIMA_MAX_MIP_LEVELS - 1;
 
-   desc->miplevels = (last_level - first_level);
+   desc->min_lod = lima_float_to_fixed8(sampler->base.min_lod);
+   max_lod = MIN2(sampler->base.max_lod, sampler->base.min_lod +
+                                         (last_level - first_level));
+   desc->max_lod = lima_float_to_fixed8(max_lod);
+   desc->lod_bias = lima_float_to_fixed8(sampler->base.lod_bias);
 
    switch (sampler->base.min_mip_filter) {
       case PIPE_TEX_MIPFILTER_LINEAR:
-         desc->min_mipfilter_1 = 0;
          desc->min_mipfilter_2 = 3;
          break;
       case PIPE_TEX_MIPFILTER_NEAREST:
-         desc->min_mipfilter_1 = 0x1ff;
          desc->min_mipfilter_2 = 0;
          break;
       case PIPE_TEX_MIPFILTER_NONE:
+         desc->max_lod = desc->min_lod;
+         break;
       default:
          break;
    }
       break;
    case PIPE_TEX_FILTER_NEAREST:
    default:
+      lod_bias_delta = 8;
       desc->min_img_filter_nearest = 1;
       break;
    }
       break;
    }
 
+   if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest &&
+       desc->min_mipfilter_2 == 0 &&
+       (desc->min_lod != desc->max_lod))
+     lod_bias_delta = -1;
+
+   desc->lod_bias += lod_bias_delta;
+
    lima_texture_desc_set_res(ctx, desc, texture->base.texture,
                              first_level, last_level);
 }
 
    uint32_t unnorm_coords: 1;
    uint32_t unknown_1_2: 1;
    uint32_t texture_type: 3;
-   uint32_t unknown_1_3: 12;
-   uint32_t miplevels: 4;
-   uint32_t min_mipfilter_1: 9; /* 0x0 for linear, 0x1ff for nearest */
+   uint32_t min_lod: 8; /* Fixed point, 4.4, unsigned */
+   uint32_t max_lod: 8; /* Fixed point, 4.4, unsigned */
+   uint32_t lod_bias: 9; /* Fixed point, signed, 1.4.4 */
    uint32_t unknown_2_1: 3;
    uint32_t has_stride: 1;
    uint32_t min_mipfilter_2: 2; /* 0x3 for linear, 0x0 for nearest */
                                unsigned first_level, unsigned last_level);
 void lima_update_textures(struct lima_context *ctx);
 
+
+static inline int16_t lima_float_to_fixed8(float f)
+{
+   return (int)(f * 16.0);
+}
+
+static inline float lima_fixed8_to_float(int16_t i)
+{
+   float sign = 1.0;
+
+   if (i > 0xff) {
+      i = 0x200 - i;
+      sign = -1;
+   }
+
+   return sign * (float)(i / 16.0);
+}
+
 #endif