diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-07-24 10:28:16 +0200 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2017-08-06 20:43:57 +0200 |
commit | 6c321c8b0b3547b0af0b0939391eef4dc8d2f873 (patch) | |
tree | 2a0243c4ac8bea14a8aca70c918ce0998bb4db6b | |
parent | 9c04c88830bc1001bdb446eef692e925483d73f4 (diff) |
etnaviv: Unified uniforms support
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@gmail.com>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_emit.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_internal.h | 6 | ||||
-rw-r--r-- | 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 bfff699ad88..273b3d05e3f 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 8a311678304..5c13f23b063 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 9aca90642c3..fccb8dccfb8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -748,6 +748,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; |