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@imkreisrum.de>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13213>
This commit is contained in:
Vasily Khoruzhick
2021-10-05 23:12:28 -07:00
committed by Marge Bot
parent 97b92c9c32
commit fa86a2a94d
10 changed files with 56 additions and 35 deletions

View File

@@ -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;

View File

@@ -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__)) {

View File

@@ -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");

View File

@@ -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;

View File

@@ -266,6 +266,7 @@ typedef struct {
ppir_src src;
int num_src;
ppir_perspective perspective;
int sampler_dim;
} ppir_load_node;
typedef struct {

View File

@@ -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;

View File

@@ -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",

View File

@@ -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,

View File

@@ -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))

View File

@@ -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;