Module: Mesa Branch: main Commit: 02e5f4fb10d6a39ca347f444104b7c56c8d65ab5 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=02e5f4fb10d6a39ca347f444104b7c56c8d65ab5
Author: Vasily Khoruzhick <[email protected]> Date: Wed Oct 6 07:16:33 2021 -0700 lima: add more wrap modes Using 1 bit per wrap mode looked very suspicious and after some experiments it turns out it's 3-bit enum. Border color is also here, it sits right after depth field. For some reason it uses 16 bit per channel just like for clear color in RSW GL_CLAMP mode is broken for nearest filter just as on Midgard, so add the same workaround - use GL_CLAMP_TO_EDGE for nearest filter. Reviewed-by: Andreas Baierl <[email protected]> Signed-off-by: Vasily Khoruzhick <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13213> --- docs/drivers/lima.rst | 2 - src/gallium/drivers/lima/lima_job.c | 6 +-- src/gallium/drivers/lima/lima_parser.c | 42 ++++++---------- src/gallium/drivers/lima/lima_parser.h | 19 +++++++ src/gallium/drivers/lima/lima_texture.c | 89 ++++++++++++++++----------------- src/gallium/drivers/lima/lima_texture.h | 32 ++++++------ 6 files changed, 98 insertions(+), 92 deletions(-) diff --git a/docs/drivers/lima.rst b/docs/drivers/lima.rst index 04b87772f6a..91c16c0c3c5 100644 --- a/docs/drivers/lima.rst +++ b/docs/drivers/lima.rst @@ -110,8 +110,6 @@ Here are some known caveats in OpenGL support: - ``glPolygonMode()`` with ``GL_LINE`` is not supported. This is not part of OpenGL ES 2.0 and so it is not possible to reverse engineer. -- Texture wrapping with ``GL_CLAMP_TO_BORDER`` is not supported. This is not - part of OpenGL ES 2.0 and so it is not possible to reverse engineer. - Precision limitations in fragment shaders: diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c index dfbe67e1062..c3bb29c50ee 100644 --- a/src/gallium/drivers/lima/lima_job.c +++ b/src/gallium/drivers/lima/lima_job.c @@ -398,9 +398,9 @@ lima_pack_reload_plbu_cmd(struct lima_job *job, struct pipe_surface *psurf) 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->wrap_r_clamp_to_edge = 1; + td->wrap_s = LIMA_TEX_WRAP_CLAMP_TO_EDGE; + td->wrap_t = LIMA_TEX_WRAP_CLAMP_TO_EDGE; + td->wrap_r = LIMA_TEX_WRAP_CLAMP_TO_EDGE; 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 6a871170b29..3e69daee1b2 100644 --- a/src/gallium/drivers/lima/lima_parser.c +++ b/src/gallium/drivers/lima/lima_parser.c @@ -728,10 +728,11 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset) fprintf(fp, "\t stride: 0x%x (%d)\n", desc->stride, desc->stride); fprintf(fp, "\t unknown_0_2: 0x%x (%d)\n", desc->unknown_0_2, desc->unknown_0_2); - /* Word 1 - 3 */ - fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x 0x%08x\n", - start + i * 4, i * 4, *(&data[i + offset]), *(&data[i + 1 + offset]), *(&data[i + 2 + offset])); - i += 3; + /* Word 1 - 5 */ + fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + start + i * 4, i * 4, *(&data[i + offset]), *(&data[i + 1 + offset]), + *(&data[i + 2 + offset]), *(&data[i + 3 + offset]), *(&data[i + 4 + offset])); + i += 5; 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); @@ -745,31 +746,20 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset) fprintf(fp, "\t min_mipfilter_2: 0x%x (%d)\n", desc->min_mipfilter_2, desc->min_mipfilter_2); fprintf(fp, "\t min_img_filter_nearest: 0x%x (%d)\n", desc->min_img_filter_nearest, desc->min_img_filter_nearest); fprintf(fp, "\t mag_img_filter_nearest: 0x%x (%d)\n", desc->mag_img_filter_nearest, desc->mag_img_filter_nearest); - fprintf(fp, "\t wrap_s_clamp_to_edge: 0x%x (%d)\n", desc->wrap_s_clamp_to_edge, desc->wrap_s_clamp_to_edge); - fprintf(fp, "\t wrap_s_clamp: 0x%x (%d)\n", desc->wrap_s_clamp, desc->wrap_s_clamp); - fprintf(fp, "\t wrap_s_mirror_repeat: 0x%x (%d)\n", desc->wrap_s_mirror_repeat, desc->wrap_s_mirror_repeat); - 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 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 wrap_s: %d (%s)\n", desc->wrap_s, + lima_get_wrap_mode_string(desc->wrap_s)); + fprintf(fp, "\t wrap_t: %d (%s)\n", desc->wrap_t, + lima_get_wrap_mode_string(desc->wrap_t)); + fprintf(fp, "\t wrap_r: %d (%s)\n", desc->wrap_r, + lima_get_wrap_mode_string(desc->wrap_r)); 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); - - /* Word 4 */ - fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n", - start + i * 4, i * 4, *(&data[i + offset])); - i++; - fprintf(fp, "\t unknown_4: 0x%x (%d)\n", desc->unknown_4, desc->unknown_4); - - /* Word 5 */ - fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n", - start + i * 4, i * 4, *(&data[i + offset])); - i++; - fprintf(fp, "\t unknown_5: 0x%x (%d)\n", desc->unknown_5, desc->unknown_5); + fprintf(fp, "\t border_red: 0x%x (%d)\n", desc->border_red, desc->border_red); + fprintf(fp, "\t border_green: 0x%x (%d)\n", desc->border_green, desc->border_green); + fprintf(fp, "\t border_blue: 0x%x (%d)\n", desc->border_blue, desc->border_blue); + fprintf(fp, "\t border_alpha: 0x%x (%d)\n", desc->border_alpha, desc->border_alpha); + fprintf(fp, "\t unknown_5_1: 0x%x (%d)\n", desc->unknown_5_1, desc->unknown_5_1); /* Word 6 - */ fprintf(fp, "/* 0x%08x (0x%08x) */", diff --git a/src/gallium/drivers/lima/lima_parser.h b/src/gallium/drivers/lima/lima_parser.h index d592c9f8618..dc99d49164b 100644 --- a/src/gallium/drivers/lima/lima_parser.h +++ b/src/gallium/drivers/lima/lima_parser.h @@ -86,6 +86,17 @@ static const char *PIPE_BLENDFACTOR_STRING[] = { }; +static const char *LIMA_WRAP_MODE_STRING[] = { + "TEX_WRAP_REPEAT", /* 0 */ + "TEX_WRAP_CLAMP_TO_EDGE", /* 1 */ + "TEX_WRAP_CLAMP", /* 2 */ + "TEX_WRAP_CLAMP_TO_BORDER", /* 3 */ + "TEX_WRAP_MIRROR_REPEAT", /* 4 */ + "TEX_WRAP_MIRROR_CLAMP_TO_EDGE", /* 5 */ + "TEX_WRAP_MIRROR_CLAMP", /* 6 */ + "TEX_WRAP_MIRROR_CLAMP_TO_BORDER", /* 7 */ +}; + static inline const char *lima_get_compare_func_string(int func) { if ((func >= 0) && (func <= 7)) @@ -118,6 +129,14 @@ static inline const char return "UNKNOWN"; } +static inline const char +*lima_get_wrap_mode_string(int mode) { + if ((mode >= 0) && (mode <= 7)) + return LIMA_WRAP_MODE_STRING[mode]; + else + return "UNKNOWN"; +} + void lima_parse_shader(FILE *fp, uint32_t *data, int size, bool is_frag); void lima_parse_vs(FILE *fp, uint32_t *data, int size, uint32_t start); void lima_parse_plbu(FILE *fp, uint32_t *data, int size, uint32_t start); diff --git a/src/gallium/drivers/lima/lima_texture.c b/src/gallium/drivers/lima/lima_texture.c index 59e30ac3df3..1ec03dea9ff 100644 --- a/src/gallium/drivers/lima/lima_texture.c +++ b/src/gallium/drivers/lima/lima_texture.c @@ -115,6 +115,37 @@ lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc, } } +static unsigned +pipe_wrap_to_lima(unsigned pipe_wrap, bool using_nearest) +{ + switch (pipe_wrap) { + case PIPE_TEX_WRAP_REPEAT: + return LIMA_TEX_WRAP_REPEAT; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return LIMA_TEX_WRAP_CLAMP_TO_EDGE; + case PIPE_TEX_WRAP_CLAMP: + if (using_nearest) + return LIMA_TEX_WRAP_CLAMP_TO_EDGE; + else + return LIMA_TEX_WRAP_CLAMP; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return LIMA_TEX_WRAP_CLAMP_TO_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return LIMA_TEX_WRAP_MIRROR_REPEAT; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + if (using_nearest) + return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; + else + return LIMA_TEX_WRAP_MIRROR_CLAMP; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_BORDER; + default: + return LIMA_TEX_WRAP_REPEAT; + } +} + static void lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sampler, struct lima_sampler_view *texture, void *pdesc, @@ -199,55 +230,19 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample break; } - /* Only clamp, clamp to edge, repeat and mirror repeat are supported */ - switch (sampler->base.wrap_s) { - case PIPE_TEX_WRAP_CLAMP: - desc->wrap_s_clamp = 1; - break; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - desc->wrap_s_clamp_to_edge = 1; - break; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - desc->wrap_s_mirror_repeat = 1; - break; - case PIPE_TEX_WRAP_REPEAT: - default: - break; - } + /* Panfrost mentions that GL_CLAMP is broken for NEAREST filter on Midgard, + * looks like it also broken on Utgard, since it fails in piglit + */ + bool using_nearest = sampler->base.min_img_filter == PIPE_TEX_FILTER_NEAREST; - /* Only clamp, clamp to edge, repeat and mirror repeat are supported */ - switch (sampler->base.wrap_t) { - case PIPE_TEX_WRAP_CLAMP: - desc->wrap_t_clamp = 1; - break; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - desc->wrap_t_clamp_to_edge = 1; - break; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - desc->wrap_t_mirror_repeat = 1; - break; - case PIPE_TEX_WRAP_REPEAT: - default: - break; - } + desc->wrap_s = pipe_wrap_to_lima(sampler->base.wrap_s, using_nearest); + desc->wrap_t = pipe_wrap_to_lima(sampler->base.wrap_t, using_nearest); + desc->wrap_r = pipe_wrap_to_lima(sampler->base.wrap_r, using_nearest); - 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; - } + desc->border_red = float_to_ushort(sampler->base.border_color.f[0]); + desc->border_green = float_to_ushort(sampler->base.border_color.f[1]); + desc->border_blue = float_to_ushort(sampler->base.border_color.f[2]); + desc->border_alpha = float_to_ushort(sampler->base.border_color.f[3]); if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest && desc->min_mipfilter_2 == 0 && diff --git a/src/gallium/drivers/lima/lima_texture.h b/src/gallium/drivers/lima/lima_texture.h index f95dfdfbcc9..6d8dd4d2772 100644 --- a/src/gallium/drivers/lima/lima_texture.h +++ b/src/gallium/drivers/lima/lima_texture.h @@ -31,6 +31,15 @@ #define LIMA_SAMPLER_DIM_2D 1 #define LIMA_SAMPLER_DIM_3D 2 +#define LIMA_TEX_WRAP_REPEAT 0 +#define LIMA_TEX_WRAP_CLAMP_TO_EDGE 1 +#define LIMA_TEX_WRAP_CLAMP 2 +#define LIMA_TEX_WRAP_CLAMP_TO_BORDER 3 +#define LIMA_TEX_WRAP_MIRROR_REPEAT 4 +#define LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE 5 +#define LIMA_TEX_WRAP_MIRROR_CLAMP 6 +#define LIMA_TEX_WRAP_MIRROR_CLAMP_TO_BORDER 7 + typedef struct __attribute__((__packed__)) { /* Word 0 */ uint32_t format : 6; @@ -54,25 +63,20 @@ typedef struct __attribute__((__packed__)) { uint32_t min_mipfilter_2: 2; /* 0x3 for linear, 0x0 for nearest */ uint32_t min_img_filter_nearest: 1; uint32_t mag_img_filter_nearest: 1; - uint32_t wrap_s_clamp_to_edge: 1; - uint32_t wrap_s_clamp: 1; - uint32_t wrap_s_mirror_repeat: 1; - uint32_t wrap_t_clamp_to_edge: 1; - uint32_t wrap_t_clamp: 1; - uint32_t wrap_t_mirror_repeat: 1; - uint32_t wrap_r_clamp_to_edge: 1; - uint32_t wrap_r_clamp: 1; - uint32_t wrap_r_mirror_repeat: 1; + uint32_t wrap_s: 3; + uint32_t wrap_t: 3; + uint32_t wrap_r: 3; uint32_t width: 13; uint32_t height: 13; uint32_t depth: 13; - uint32_t unknown_3_1: 3; - /* Word 4 */ - uint32_t unknown_4; + uint32_t border_red: 16; + uint32_t border_green: 16; + uint32_t border_blue: 16; + uint32_t border_alpha: 16; - /* Word 5 */ - uint32_t unknown_5; + /* Word 5 (last 3 bits) */ + uint32_t unknown_5_1: 3; /* Word 6-15 */ /* layout is in va[0] bit 13-14 */
