[PATCH 2/3] etnaviv: Unified uniforms support

Christian Gmeiner christian.gmeiner at gmail.com
Sat Aug 5 16:14:24 UTC 2017


2017-07-24 10:28 GMT+02:00 Wladimir J. van der Laan <laanwj at gmail.com>:
> GC3000 has changed from a separate store for VS and PS uniforms
> to a single, unified one. There is backwards compatibilty functionalty,
> however this does not work correctly together with ICACHE.
>
> This patch adds explicit support, although in the simplest way possible:
> the PS/VS uniforms split is still fixed and hardcoded. It should
> make no difference on hardware that does not have unified uniform
> memory.
>
> Signed-off-by: Wladimir J. van der Laan <laanwj at gmail.com>

Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>

> ---
>  src/gallium/drivers/etnaviv/etnaviv_emit.c     | 19 +++++++++++++++----
>  src/gallium/drivers/etnaviv/etnaviv_internal.h |  6 ++++++
>  src/gallium/drivers/etnaviv/etnaviv_screen.c   | 15 +++++++++++++++
>  3 files changed, 36 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> index bfff699..273b3d0 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> @@ -747,10 +747,17 @@ etna_emit_state(struct etna_context *ctx)
>        etna_set_state_multi(stream, ctx->specs.ps_offset,
>                             ctx->shader_state.ps_inst_mem_size,
>                             ctx->shader_state.PS_INST_MEM);
> -      /*05000*/ etna_set_state_multi(stream, VIVS_VS_UNIFORMS(0),
> +
> +      if (ctx->specs.has_unified_uniforms) {
> +         etna_set_state(stream, VIVS_VS_UNIFORM_BASE, 0);
> +         etna_set_state(stream, VIVS_PS_UNIFORM_BASE, ctx->specs.max_vs_uniforms);
> +      }
> +      etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
> +      etna_set_state_multi(stream, ctx->specs.vs_uniforms_offset,
>                                       ctx->shader_state.vs_uniforms_size,
>                                       ctx->shader_state.VS_UNIFORMS);
> -      /*07000*/ etna_set_state_multi(stream, VIVS_PS_UNIFORMS(0),
> +      etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
> +      etna_set_state_multi(stream, ctx->specs.ps_uniforms_offset,
>                                       ctx->shader_state.ps_uniforms_size,
>                                       ctx->shader_state.PS_UNIFORMS);
>
> @@ -764,19 +771,23 @@ etna_emit_state(struct etna_context *ctx)
>        memcpy(ctx->gpu3d.PS_UNIFORMS, ctx->shader_state.PS_UNIFORMS,
>               ctx->shader_state.ps_uniforms_size * 4);
>     } else {
> +      /* ideally this cache would only be flushed if there are VS uniform changes */
> +      etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
>        etna_coalesce_start(stream, &coalesce);
>        for (int x = 0; x < ctx->shader.vs->uniforms.const_count; ++x) {
>           if (ctx->gpu3d.VS_UNIFORMS[x] != ctx->shader_state.VS_UNIFORMS[x]) {
> -            /*05000*/ EMIT_STATE(VS_UNIFORMS(x), ctx->shader_state.VS_UNIFORMS[x]);
> +            etna_coalsence_emit(stream, &coalesce, ctx->specs.vs_uniforms_offset + x*4, ctx->shader_state.VS_UNIFORMS[x]);
>              ctx->gpu3d.VS_UNIFORMS[x] = ctx->shader_state.VS_UNIFORMS[x];
>           }
>        }
>        etna_coalesce_end(stream, &coalesce);
>
> +      /* ideally this cache would only be flushed if there are PS uniform changes */
> +      etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
>        etna_coalesce_start(stream, &coalesce);
>        for (int x = 0; x < ctx->shader.fs->uniforms.const_count; ++x) {
>           if (ctx->gpu3d.PS_UNIFORMS[x] != ctx->shader_state.PS_UNIFORMS[x]) {
> -            /*07000*/ EMIT_STATE(PS_UNIFORMS(x), ctx->shader_state.PS_UNIFORMS[x]);
> +            etna_coalsence_emit(stream, &coalesce, ctx->specs.ps_uniforms_offset + x*4, ctx->shader_state.PS_UNIFORMS[x]);
>              ctx->gpu3d.PS_UNIFORMS[x] = ctx->shader_state.PS_UNIFORMS[x];
>           }
>        }
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h
> index 8a31167..5c13f23 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h
> +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h
> @@ -74,6 +74,8 @@ struct etna_specs {
>     unsigned has_new_transcendentals : 1;
>     /* supports single-buffer rendering with multiple pixel pipes */
>     unsigned single_buffer : 1;
> +   /* has unified uniforms memory */
> +   unsigned has_unified_uniforms : 1;
>     /* can use any kind of wrapping mode on npot textures */
>     unsigned npot_tex_any_wrap;
>     /* number of bits per TS tile */
> @@ -100,6 +102,10 @@ struct etna_specs {
>     uint32_t vs_offset;
>     /* pixel shader memory address*/
>     uint32_t ps_offset;
> +   /* vertex shader uniforms address*/
> +   uint32_t vs_uniforms_offset;
> +   /* pixel shader uniforms address*/
> +   uint32_t ps_uniforms_offset;
>     /* vertex/fragment shader max instructions */
>     uint32_t max_instructions;
>     /* maximum number of varyings */
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> index 5dc436d..81480e9 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> @@ -703,6 +703,21 @@ etna_get_specs(struct etna_screen *screen)
>        screen->specs.max_vs_uniforms = 256;
>        screen->specs.max_ps_uniforms = 256;
>     }
> +   /* unified uniform memory on GC3000 - HALTI1 feature bit is just a guess
> +   */
> +   if (VIV_FEATURE(screen, chipMinorFeatures2, HALTI1)) {
> +      screen->specs.has_unified_uniforms = true;
> +      screen->specs.vs_uniforms_offset = VIVS_SH_UNIFORMS(0);
> +      /* hardcode PS uniforms to start after end of VS uniforms -
> +       * for more flexibility this offset could be variable based on the
> +       * shader.
> +       */
> +      screen->specs.ps_uniforms_offset = VIVS_SH_UNIFORMS(screen->specs.max_vs_uniforms*4);
> +   } else {
> +      screen->specs.has_unified_uniforms = false;
> +      screen->specs.vs_uniforms_offset = VIVS_VS_UNIFORMS(0);
> +      screen->specs.ps_uniforms_offset = VIVS_PS_UNIFORMS(0);
> +   }
>
>     screen->specs.max_texture_size =
>        VIV_FEATURE(screen, chipMinorFeatures0, TEXTURE_8K) ? 8192 : 2048;
> --
> 2.7.4
>

greets
--
Christian Gmeiner, MSc

https://christian-gmeiner.info


More information about the etnaviv mailing list