lima: add new findings to texture descriptor
authorVasily Khoruzhick <anarsoul@gmail.com>
Sun, 12 Jan 2020 06:23:36 +0000 (22:23 -0800)
committerVasily Khoruzhick <anarsoul@gmail.com>
Tue, 14 Jan 2020 06:50:36 +0000 (22:50 -0800)
Lower 8 bits of unknown_1_3 seems to be min_lod,
rest of 4 bits + miplevels are max_lod and min_mipfilter seems to be
lod bias. All are in fixed format with 4 bit integer and 4 bit fraction,
lod_bias also has sign bit.

Blob also seems to do some magic with lod_bias if min filter is nearest --
it adds 0.5 to lod_bias in this case. Same story when all filters are
nearest and mipmapping is enabled, but in this case it subtracts 1/16
from lod_bias.

Fixes 134 dEQP tests in dEQP-GLES2.functional.texture.*

Reviewed-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3359>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3359>

src/gallium/drivers/lima/lima_parser.c
src/gallium/drivers/lima/lima_screen.c
src/gallium/drivers/lima/lima_texture.c
src/gallium/drivers/lima/lima_texture.h

index c96e080a0cebb0693a506d5ea602fcf03c3505f6..87f8a47f50a55a9ba0ca28578c9ee669499042ba 100644 (file)
@@ -631,9 +631,9 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    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);
@@ -667,7 +667,9 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    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");
 
@@ -687,7 +689,7 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    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;
index 8a933951c062efaf674fe355ba8ed16777fd0508..b5dac6150419e84cf8f03c93521fe65b9eb8180f 100644 (file)
@@ -166,7 +166,7 @@ lima_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
    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;
index b5a6103093c81b793d3dffc89108844ae6ec9b23..7f2f81266b667ba0003c7aff9e0651a353904ec2 100644 (file)
@@ -118,9 +118,12 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
                      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);
 
@@ -144,18 +147,22 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
    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;
    }
@@ -177,6 +184,7 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
       break;
    case PIPE_TEX_FILTER_NEAREST:
    default:
+      lod_bias_delta = 8;
       desc->min_img_filter_nearest = 1;
       break;
    }
@@ -215,6 +223,13 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
       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);
 }
index 7f4b9ee53304247b85061837a7cb41b9b8de5381..0a4afd9ed5a5767425481d0a7929e601073af3bf 100644 (file)
@@ -44,9 +44,9 @@ typedef struct __attribute__((__packed__)) {
    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 */
@@ -95,4 +95,22 @@ void lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc,
                                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