2017-07-24 10:28 GMT+02:00 Wladimir J. van der Laan <laa...@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 <laa...@gmail.com>
Reviewed-by: Christian Gmeiner <christian.gmei...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev