Mesa (main): lima: add support for 3D textures

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 16 23:13:17 UTC 2021


Module: Mesa
Branch: main
Commit: fa86a2a94dfd090b5854e2aaeca68c8ec4a4e12c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fa86a2a94dfd090b5854e2aaeca68c8ec4a4e12c

Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date:   Tue Oct  5 23:12:28 2021 -0700

lima: add support for 3D textures

It looks like MBS format used by blob doesn't distinguish sampler2D from
sampler3D, so load texture instruction is the same for 2D and 3D
textures.

So all we need to RE is texture descriptor for 3D textures, but blob
doesn't implement it, so we need to do some guesswork:

- unknown_3_1 looks like a depth since it sits after height/width and
  always set to 1
- unknown_2_2 is exactly 3 bits and it follows wrap_t, so it must be
  wrap_r
- missing part is texture type for 3D textures. By trial and error it
  seems to be 4. First bit is only set for cubemap, so it's likely a
  separate flag, and rest 2 bits look like number of tex dimensions akin
  to midgard and later (thanks, panfrost!) with 0 for 1D, 1 for 2D
  and 2 for 3D.

Put it all together and we have working 3D textures on lima!

Reviewed-by: Andreas Baierl <ichgeh at imkreisrum.de>
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13213>

---

 src/gallium/drivers/lima/ir/pp/codegen.c | 15 ++++-----------
 src/gallium/drivers/lima/ir/pp/codegen.h |  4 ++--
 src/gallium/drivers/lima/ir/pp/disasm.c  |  3 +--
 src/gallium/drivers/lima/ir/pp/nir.c     |  7 +++----
 src/gallium/drivers/lima/ir/pp/ppir.h    |  1 +
 src/gallium/drivers/lima/lima_job.c      |  4 ++--
 src/gallium/drivers/lima/lima_parser.c   |  9 ++++++---
 src/gallium/drivers/lima/lima_screen.c   |  3 ++-
 src/gallium/drivers/lima/lima_texture.c  | 30 ++++++++++++++++++++++++++----
 src/gallium/drivers/lima/lima_texture.h  | 15 +++++++++------
 10 files changed, 56 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c
index 8c39c688148..5a5ee14c78e 100644
--- a/src/gallium/drivers/lima/ir/pp/codegen.c
+++ b/src/gallium/drivers/lima/ir/pp/codegen.c
@@ -91,13 +91,8 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code)
             f->imm.perspective = 1;
             break;
          case ppir_op_load_coords:
-            /* num_components == 3 and no perspective implies cubemap
-             * as we don't support 3D textures */
-            if (num_components == 3 &&
-                load->perspective == ppir_perspective_none)
+            if (load->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
                f->imm.source_type = 2;
-            else
-               f->imm.source_type = 0;
 
             switch (load->perspective) {
             case ppir_perspective_none:
@@ -120,10 +115,7 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code)
       f->reg.mask = dest->write_mask << (index & 0x3);
 
       if (load->num_src) {
-         /* num_components == 3 and no perspective implies cubemap
-          * as we don't support 3D textures */
-         if (num_components == 3 &&
-             load->perspective == ppir_perspective_none) {
+         if (load->sampler_dim == GLSL_SAMPLER_DIM_CUBE) {
             f->reg.source_type = 2;
             f->reg.perspective = 1;
          } else {
@@ -164,9 +156,10 @@ static void ppir_codegen_encode_texld(ppir_node *node, void *code)
 
    switch (ldtex->sampler_dim) {
    case GLSL_SAMPLER_DIM_2D:
+   case GLSL_SAMPLER_DIM_3D:
    case GLSL_SAMPLER_DIM_RECT:
    case GLSL_SAMPLER_DIM_EXTERNAL:
-      f->type = ppir_codegen_sampler_type_2d;
+      f->type = ppir_codegen_sampler_type_generic;
       break;
    case GLSL_SAMPLER_DIM_CUBE:
       f->type = ppir_codegen_sampler_type_cube;
diff --git a/src/gallium/drivers/lima/ir/pp/codegen.h b/src/gallium/drivers/lima/ir/pp/codegen.h
index 198517205c8..dbd0c8f654b 100644
--- a/src/gallium/drivers/lima/ir/pp/codegen.h
+++ b/src/gallium/drivers/lima/ir/pp/codegen.h
@@ -104,8 +104,8 @@ typedef union __attribute__((__packed__)) {
 } ppir_codegen_field_varying;
 
 typedef enum {
-   ppir_codegen_sampler_type_2d   = 0x00,
-   ppir_codegen_sampler_type_cube = 0x1F,
+   ppir_codegen_sampler_type_generic = 0x00,
+   ppir_codegen_sampler_type_cube    = 0x1F,
 } ppir_codegen_sampler_type;
 
 typedef struct __attribute__((__packed__)) {
diff --git a/src/gallium/drivers/lima/ir/pp/disasm.c b/src/gallium/drivers/lima/ir/pp/disasm.c
index 8f34d7c3c32..9c641bb9e0f 100644
--- a/src/gallium/drivers/lima/ir/pp/disasm.c
+++ b/src/gallium/drivers/lima/ir/pp/disasm.c
@@ -285,8 +285,7 @@ print_sampler(void *code, unsigned offset, FILE *fp)
       fprintf(fp, ".b");
 
    switch (sampler->type) {
-   case ppir_codegen_sampler_type_2d:
-      fprintf(fp, ".2d");
+   case ppir_codegen_sampler_type_generic:
       break;
    case ppir_codegen_sampler_type_cube:
       fprintf(fp, ".cube");
diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c
index 14f848d175d..4fc6ca4d583 100644
--- a/src/gallium/drivers/lima/ir/pp/nir.c
+++ b/src/gallium/drivers/lima/ir/pp/nir.c
@@ -448,6 +448,7 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
 
    switch (instr->sampler_dim) {
    case GLSL_SAMPLER_DIM_2D:
+   case GLSL_SAMPLER_DIM_3D:
    case GLSL_SAMPLER_DIM_CUBE:
    case GLSL_SAMPLER_DIM_RECT:
    case GLSL_SAMPLER_DIM_EXTERNAL:
@@ -532,10 +533,7 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
 
       load->src = node->src[0];
       load->num_src = 1;
-      if (node->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
-         load->num_components = 3;
-      else
-         load->num_components = 2;
+      load->num_components = instr->coord_components;
 
       ppir_debug("%s create load_coords node %d for %d\n",
                  __FUNCTION__, load->index, node->node.index);
@@ -557,6 +555,7 @@ static bool ppir_emit_tex(ppir_block *block, nir_instr *ni)
          load->perspective = ppir_perspective_w;
    }
 
+   load->sampler_dim = instr->sampler_dim;
    node->src[0].type = load->dest.type = ppir_target_pipeline;
    node->src[0].pipeline = load->dest.pipeline = ppir_pipeline_reg_discard;
 
diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h
index 62ffb0fc2d9..74a508e504e 100644
--- a/src/gallium/drivers/lima/ir/pp/ppir.h
+++ b/src/gallium/drivers/lima/ir/pp/ppir.h
@@ -266,6 +266,7 @@ typedef struct {
    ppir_src src;
    int num_src;
    ppir_perspective perspective;
+   int sampler_dim;
 } ppir_load_node;
 
 typedef struct {
diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c
index ef8a6444cb9..dfbe67e1062 100644
--- a/src/gallium/drivers/lima/lima_job.c
+++ b/src/gallium/drivers/lima/lima_job.c
@@ -395,12 +395,12 @@ lima_pack_reload_plbu_cmd(struct lima_job *job, struct pipe_surface *psurf)
    lima_texture_desc_set_res(ctx, td, psurf->texture, level, level, first_layer);
    td->format = lima_format_get_texel_reload(psurf->format);
    td->unnorm_coords = 1;
-   td->texture_type = LIMA_TEXTURE_TYPE_2D;
+   td->sampler_dim = LIMA_SAMPLER_DIM_2D;
    td->min_img_filter_nearest = 1;
    td->mag_img_filter_nearest = 1;
    td->wrap_s_clamp_to_edge = 1;
    td->wrap_t_clamp_to_edge = 1;
-   td->unknown_2_2 = 0x1;
+   td->wrap_r_clamp_to_edge = 1;
 
    uint32_t *ta = cpu + lima_reload_tex_array_offset;
    ta[0] = va + lima_reload_tex_desc_offset;
diff --git a/src/gallium/drivers/lima/lima_parser.c b/src/gallium/drivers/lima/lima_parser.c
index c3780d94f13..6a871170b29 100644
--- a/src/gallium/drivers/lima/lima_parser.c
+++ b/src/gallium/drivers/lima/lima_parser.c
@@ -735,7 +735,8 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    fprintf(fp, "\t unknown_1_1: 0x%x (%d)\n", desc->unknown_1_1, desc->unknown_1_1);
    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 cube_map: 0x%x (%d)\n", desc->cube_map, desc->cube_map);
+   fprintf(fp, "\t sampler_dim: 0x%x (%d)\n", desc->sampler_dim, desc->sampler_dim);
    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));
@@ -750,11 +751,13 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    fprintf(fp, "\t wrap_t_clamp_to_edge: 0x%x (%d)\n", desc->wrap_t_clamp_to_edge, desc->wrap_t_clamp_to_edge);
    fprintf(fp, "\t wrap_t_clamp: 0x%x (%d)\n", desc->wrap_t_clamp, desc->wrap_t_clamp);
    fprintf(fp, "\t wrap_t_mirror_repeat: 0x%x (%d)\n", desc->wrap_t_mirror_repeat, desc->wrap_t_mirror_repeat);
-   fprintf(fp, "\t unknown_2_2: 0x%x (%d)\n", desc->unknown_2_2, desc->unknown_2_2);
+   fprintf(fp, "\t wrap_r_clamp_to_edge: 0x%x (%d)\n", desc->wrap_r_clamp_to_edge, desc->wrap_r_clamp_to_edge);
+   fprintf(fp, "\t wrap_r_clamp: 0x%x (%d)\n", desc->wrap_r_clamp, desc->wrap_r_clamp);
+   fprintf(fp, "\t wrap_r_mirror_repeat: 0x%x (%d)\n", desc->wrap_r_mirror_repeat, desc->wrap_r_mirror_repeat);
    fprintf(fp, "\t width: 0x%x (%d)\n", desc->width, desc->width);
    fprintf(fp, "\t height: 0x%x (%d)\n", desc->height, desc->height);
+   fprintf(fp, "\t depth: 0x%x (%d)\n", desc->depth, desc->depth);
    fprintf(fp, "\t unknown_3_1: 0x%x (%d)\n", desc->unknown_3_1, desc->unknown_3_1);
-   fprintf(fp, "\t unknown_3_2: 0x%x (%d)\n", desc->unknown_3_2, desc->unknown_3_2);
 
    /* Word 4 */
    fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n",
diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c
index baa1d6be472..9b78345d362 100644
--- a/src/gallium/drivers/lima/lima_screen.c
+++ b/src/gallium/drivers/lima/lima_screen.c
@@ -325,6 +325,7 @@ lima_screen_is_format_supported(struct pipe_screen *pscreen,
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_3D:
    case PIPE_TEXTURE_RECT:
    case PIPE_TEXTURE_CUBE:
       break;
@@ -702,7 +703,7 @@ lima_screen_create(int fd, struct renderonly *ro)
           pp_clear_program, sizeof(pp_clear_program));
 
    /* copy texture to framebuffer, used to reload gpu tile buffer
-    * load.v $1 0.xy, texld_2d 0, mov.v0 $0 ^tex_sampler, sync, stop
+    * load.v $1 0.xy, texld 0, mov.v0 $0 ^tex_sampler, sync, stop
     */
    static const uint32_t pp_reload_program[] = {
       0x000005e6, 0xf1003c20, 0x00000000, 0x39001000,
diff --git a/src/gallium/drivers/lima/lima_texture.c b/src/gallium/drivers/lima/lima_texture.c
index 7079865a3b5..7eacd69c0bb 100644
--- a/src/gallium/drivers/lima/lima_texture.c
+++ b/src/gallium/drivers/lima/lima_texture.c
@@ -23,6 +23,7 @@
  *
  */
 
+#include "util/compiler.h"
 #include "util/u_memory.h"
 #include "util/u_upload_mgr.h"
 #include "util/u_math.h"
@@ -72,21 +73,23 @@ lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc,
                           struct pipe_resource *prsc,
                           unsigned first_level, unsigned last_level, unsigned first_layer)
 {
-   unsigned width, height, layout, i;
+   unsigned width, height, depth, layout, i;
    struct lima_resource *lima_res = lima_resource(prsc);
 
    width = prsc->width0;
    height = prsc->height0;
+   depth = prsc->depth0;
    if (first_level != 0) {
       width = u_minify(width, first_level);
       height = u_minify(height, first_level);
+      depth = u_minify(depth, first_level);
    }
 
    desc->format = lima_format_get_texel(prsc->format);
    desc->swap_r_b = lima_format_get_texel_swap_rb(prsc->format);
    desc->width  = width;
    desc->height = height;
-   desc->unknown_3_1 = 1;
+   desc->depth = depth;
 
    if (lima_res->tiled)
       layout = 3;
@@ -130,10 +133,13 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
    switch (texture->base.target) {
    case PIPE_TEXTURE_2D:
    case PIPE_TEXTURE_RECT:
-      desc->texture_type = LIMA_TEXTURE_TYPE_2D;
+      desc->sampler_dim = LIMA_SAMPLER_DIM_2D;
       break;
    case PIPE_TEXTURE_CUBE:
-      desc->texture_type = LIMA_TEXTURE_TYPE_CUBE;
+      desc->cube_map = 1;
+      FALLTHROUGH;
+   case PIPE_TEXTURE_3D:
+      desc->sampler_dim = LIMA_SAMPLER_DIM_3D;
       break;
    default:
       break;
@@ -224,6 +230,22 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
       break;
    }
 
+   switch (sampler->base.wrap_r) {
+   case PIPE_TEX_WRAP_CLAMP:
+      desc->wrap_r_clamp = 1;
+      break;
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+      desc->wrap_r_clamp_to_edge = 1;
+      break;
+   case PIPE_TEX_WRAP_MIRROR_REPEAT:
+      desc->wrap_r_mirror_repeat = 1;
+      break;
+   case PIPE_TEX_WRAP_REPEAT:
+   default:
+      break;
+   }
+
    if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest &&
        desc->min_mipfilter_2 == 0 &&
        (desc->min_lod != desc->max_lod))
diff --git a/src/gallium/drivers/lima/lima_texture.h b/src/gallium/drivers/lima/lima_texture.h
index 08a961ba4ae..1f41de0f39a 100644
--- a/src/gallium/drivers/lima/lima_texture.h
+++ b/src/gallium/drivers/lima/lima_texture.h
@@ -27,8 +27,8 @@
 
 #define lima_min_tex_desc_size 64
 
-#define LIMA_TEXTURE_TYPE_2D   2
-#define LIMA_TEXTURE_TYPE_CUBE 5
+#define LIMA_SAMPLER_DIM_2D   1
+#define LIMA_SAMPLER_DIM_3D   2
 
 typedef struct __attribute__((__packed__)) {
    /* Word 0 */
@@ -43,7 +43,8 @@ typedef struct __attribute__((__packed__)) {
    uint32_t unknown_1_1: 7;
    uint32_t unnorm_coords: 1;
    uint32_t unknown_1_2: 1;
-   uint32_t texture_type: 3;
+   uint32_t cube_map: 1;
+   uint32_t sampler_dim: 2;
    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 */
@@ -58,11 +59,13 @@ typedef struct __attribute__((__packed__)) {
    uint32_t wrap_t_clamp_to_edge: 1;
    uint32_t wrap_t_clamp: 1;
    uint32_t wrap_t_mirror_repeat: 1;
-   uint32_t unknown_2_2: 3;
+   uint32_t wrap_r_clamp_to_edge: 1;
+   uint32_t wrap_r_clamp: 1;
+   uint32_t wrap_r_mirror_repeat: 1;
    uint32_t width: 13;
    uint32_t height: 13;
-   uint32_t unknown_3_1: 1;
-   uint32_t unknown_3_2: 15;
+   uint32_t depth: 13;
+   uint32_t unknown_3_1: 3;
 
    /* Word 4 */
    uint32_t unknown_4;



More information about the mesa-commit mailing list