From dfe048058fa2492a0b0f8a33ae47c2c02ac200a7 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Fri, 26 Jul 2019 13:53:36 -0400 Subject: [PATCH] etnaviv: support 3D and 2D array textures Signed-off-by: Jonathan Marek Reviewed-by: Christian Gmeiner --- src/gallium/drivers/etnaviv/etnaviv_screen.c | 19 ++++--- .../drivers/etnaviv/etnaviv_texture_state.c | 55 ++++++++++++++----- .../drivers/etnaviv/etnaviv_texture_state.h | 2 + .../drivers/etnaviv/etnaviv_translate.h | 21 +++++++ 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index 88ab1b02249..455ccba790b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -193,15 +193,16 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Texturing. */ case PIPE_CAP_MAX_TEXTURE_2D_SIZE: + case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: /* TODO: verify */ return screen->specs.max_texture_size; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: { int log2_max_tex_size = util_last_bit(screen->specs.max_texture_size); assert(log2_max_tex_size > 0); return log2_max_tex_size; } - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: /* 3D textures not supported - fake it */ - return 5; + case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: case PIPE_CAP_MIN_TEXEL_OFFSET: return -8; @@ -403,12 +404,14 @@ etna_screen_is_format_supported(struct pipe_screen *pscreen, struct etna_screen *screen = etna_screen(pscreen); unsigned allowed = 0; - if (target != PIPE_BUFFER && - target != PIPE_TEXTURE_1D && - target != PIPE_TEXTURE_2D && - target != PIPE_TEXTURE_3D && - target != PIPE_TEXTURE_CUBE && - target != PIPE_TEXTURE_RECT) + if (translate_texture_target(target) == ETNA_NO_MATCH) + return false; + + /* pre-halti has no array/3D */ + if (screen->specs.halti < 0 && + (target == PIPE_TEXTURE_1D_ARRAY || + target == PIPE_TEXTURE_2D_ARRAY || + target == PIPE_TEXTURE_3D)) return false; if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture_state.c b/src/gallium/drivers/etnaviv/etnaviv_texture_state.c index c3c68740f97..5b3fbf46bf4 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_texture_state.c @@ -68,6 +68,9 @@ etna_create_sampler_state_state(struct pipe_context *pipe, COND(ss->lod_bias != 0.0, VIVS_TE_SAMPLER_LOD_CONFIG_BIAS_ENABLE) | VIVS_TE_SAMPLER_LOD_CONFIG_BIAS(etna_float_to_fixp55(ss->lod_bias)); + cs->TE_SAMPLER_3D_CONFIG = + VIVS_TE_SAMPLER_3D_CONFIG_WRAP(translate_texture_wrapmode(ss->wrap_r)); + if (ss->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) { cs->min_lod = etna_float_to_fixp55(ss->min_lod); cs->max_lod = etna_float_to_fixp55(ss->max_lod); @@ -121,27 +124,36 @@ etna_create_sampler_view_state(struct pipe_context *pctx, struct pipe_resource * sv->base.context = pctx; /* merged with sampler state */ - sv->TE_SAMPLER_CONFIG0 = COND(!ext && !astc, VIVS_TE_SAMPLER_CONFIG0_FORMAT(format)); + sv->TE_SAMPLER_CONFIG0 = + VIVS_TE_SAMPLER_CONFIG0_TYPE(translate_texture_target(sv->base.target)) | + COND(!ext && !astc, VIVS_TE_SAMPLER_CONFIG0_FORMAT(format)); sv->TE_SAMPLER_CONFIG0_MASK = 0xffffffff; + uint32_t base_height = res->base.height0; + uint32_t base_depth = res->base.depth0; + bool is_array = false; + switch (sv->base.target) { case PIPE_TEXTURE_1D: - /* For 1D textures, we will have a height of 1, so we can use 2D - * but set T wrap to repeat */ + /* use 2D texture with T wrap to repeat for 1D texture + * TODO: check if old HW supports 1D texture + */ sv->TE_SAMPLER_CONFIG0_MASK = ~VIVS_TE_SAMPLER_CONFIG0_VWRAP__MASK; - sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_REPEAT); - /* fallthrough */ - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: - sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D); + sv->TE_SAMPLER_CONFIG0 &= ~VIVS_TE_SAMPLER_CONFIG0_TYPE__MASK; + sv->TE_SAMPLER_CONFIG0 |= + VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D) | + VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_REPEAT); + break; + case PIPE_TEXTURE_1D_ARRAY: + is_array = true; + base_height = res->base.array_size; break; - case PIPE_TEXTURE_CUBE: - sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_CUBE_MAP); + case PIPE_TEXTURE_2D_ARRAY: + is_array = true; + base_depth = res->base.array_size; break; default: - BUG("Unhandled texture target"); - free(sv); - return NULL; + break; } if (res->addressing_mode == ETNA_ADDRESSING_MODE_LINEAR) { @@ -157,18 +169,22 @@ etna_create_sampler_view_state(struct pipe_context *pctx, struct pipe_resource * sv->TE_SAMPLER_CONFIG1 |= COND(ext, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(format)) | COND(astc, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(TEXTURE_FORMAT_EXT_ASTC)) | + COND(is_array, VIVS_TE_SAMPLER_CONFIG1_TEXTURE_ARRAY) | VIVS_TE_SAMPLER_CONFIG1_HALIGN(res->halign) | swiz; sv->TE_SAMPLER_ASTC0 = COND(astc, VIVS_NTE_SAMPLER_ASTC0_ASTC_FORMAT(format)) | VIVS_NTE_SAMPLER_ASTC0_UNK8(0xc) | VIVS_NTE_SAMPLER_ASTC0_UNK16(0xc) | VIVS_NTE_SAMPLER_ASTC0_UNK24(0xc); sv->TE_SAMPLER_SIZE = VIVS_TE_SAMPLER_SIZE_WIDTH(res->base.width0) | - VIVS_TE_SAMPLER_SIZE_HEIGHT(res->base.height0); + VIVS_TE_SAMPLER_SIZE_HEIGHT(base_height); sv->TE_SAMPLER_LOG_SIZE = VIVS_TE_SAMPLER_LOG_SIZE_WIDTH(etna_log2_fixp55(res->base.width0)) | - VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(etna_log2_fixp55(res->base.height0)) | + VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(etna_log2_fixp55(base_height)) | COND(util_format_is_srgb(so->format) && !astc, VIVS_TE_SAMPLER_LOG_SIZE_SRGB) | COND(astc, VIVS_TE_SAMPLER_LOG_SIZE_ASTC); + sv->TE_SAMPLER_3D_CONFIG = + VIVS_TE_SAMPLER_3D_CONFIG_DEPTH(base_depth) | + VIVS_TE_SAMPLER_3D_CONFIG_LOG_DEPTH(etna_log2_fixp55(base_depth)); /* Set up levels-of-detail */ for (int lod = 0; lod <= res->base.last_level; ++lod) { @@ -304,6 +320,15 @@ etna_emit_texture_state(struct etna_context *ctx) ss = etna_sampler_state(ctx->sampler[x]); sv = etna_sampler_view(ctx->sampler_view[x]); + /*02180*/ EMIT_STATE(TE_SAMPLER_3D_CONFIG(x), ss->TE_SAMPLER_3D_CONFIG | + sv->TE_SAMPLER_3D_CONFIG); + } + } + for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { + if ((1 << x) & active_samplers) { + ss = etna_sampler_state(ctx->sampler[x]); + sv = etna_sampler_view(ctx->sampler_view[x]); + /*021C0*/ EMIT_STATE(TE_SAMPLER_CONFIG1(x), ss->TE_SAMPLER_CONFIG1 | sv->TE_SAMPLER_CONFIG1 | COND(sv->ts.enable, VIVS_TE_SAMPLER_CONFIG1_USE_TS)); diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture_state.h b/src/gallium/drivers/etnaviv/etnaviv_texture_state.h index a426d4b6c1e..879983b8093 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture_state.h +++ b/src/gallium/drivers/etnaviv/etnaviv_texture_state.h @@ -43,6 +43,7 @@ struct etna_sampler_state { uint32_t TE_SAMPLER_CONFIG0; uint32_t TE_SAMPLER_CONFIG1; uint32_t TE_SAMPLER_LOD_CONFIG; + uint32_t TE_SAMPLER_3D_CONFIG; unsigned min_lod, max_lod, max_lod_min; }; @@ -59,6 +60,7 @@ struct etna_sampler_view { uint32_t TE_SAMPLER_CONFIG0; uint32_t TE_SAMPLER_CONFIG0_MASK; uint32_t TE_SAMPLER_CONFIG1; + uint32_t TE_SAMPLER_3D_CONFIG; uint32_t TE_SAMPLER_SIZE; uint32_t TE_SAMPLER_LOG_SIZE; uint32_t TE_SAMPLER_ASTC0; diff --git a/src/gallium/drivers/etnaviv/etnaviv_translate.h b/src/gallium/drivers/etnaviv/etnaviv_translate.h index 72a96ec8391..fd48c60a123 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_translate.h +++ b/src/gallium/drivers/etnaviv/etnaviv_translate.h @@ -476,4 +476,25 @@ translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out, return true; } +static inline uint32_t +translate_texture_target(unsigned target) +{ + switch (target) { + case PIPE_TEXTURE_1D: + return TEXTURE_TYPE_1D; + case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_RECT: + case PIPE_TEXTURE_1D_ARRAY: + return TEXTURE_TYPE_2D; + case PIPE_TEXTURE_CUBE: + return TEXTURE_TYPE_CUBE_MAP; + case PIPE_TEXTURE_3D: + case PIPE_TEXTURE_2D_ARRAY: + return TEXTURE_TYPE_3D; + default: + DBG("Unhandled texture target: %i", target); + return ETNA_NO_MATCH; + } +} + #endif -- 2.30.2