Re: [Mesa-dev] [PATCH 3/3] etnaviv: Implement ICACHE

2017-08-05 Thread Christian Gmeiner
2017-07-24 10:28 GMT+02:00 Wladimir J. van der Laan :
> This patch adds support for large shaders on GC3000. For example the "terrain"
> glmark benchmark with a large fragment shader will work after this.
>
> If the GPU supports ICACHE, shaders larger than the available state area will
> be uploaded to a bo of their own and instructed to be loaded from memory on
> demand. Small shaders will be uploaded in the usual way. This mimics the
> behavior of the blob.
>
> On GPUs that don't support ICACHE, this patch should make no difference.
>
> Signed-off-by: Wladimir J. van der Laan 

Reviewed-by: Christian Gmeiner 

> ---
>  src/gallium/drivers/etnaviv/etnaviv_compiler.c |  3 +-
>  src/gallium/drivers/etnaviv/etnaviv_compiler.h |  5 +++
>  src/gallium/drivers/etnaviv/etnaviv_emit.c | 52 
> ++
>  src/gallium/drivers/etnaviv/etnaviv_internal.h |  4 ++
>  src/gallium/drivers/etnaviv/etnaviv_screen.c   |  4 +-
>  src/gallium/drivers/etnaviv/etnaviv_shader.c   | 45 +-
>  6 files changed, 95 insertions(+), 18 deletions(-)
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c 
> b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
> index fbe66d0..0664d52 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
> @@ -2277,7 +2277,7 @@ etna_compile_check_limits(struct etna_compile *c)
> /* round up number of uniforms, including immediates, in units of four */
> int num_uniforms = c->imm_base / 4 + (c->imm_size + 3) / 4;
>
> -   if (c->inst_ptr > c->specs->max_instructions) {
> +   if (!c->specs->has_icache && c->inst_ptr > c->specs->max_instructions) {
>DBG("Number of instructions (%d) exceeds maximum %d", c->inst_ptr,
>c->specs->max_instructions);
>return false;
> @@ -2501,6 +2501,7 @@ etna_compile_shader(struct etna_shader_variant *v)
> v->vs_pointsize_out_reg = -1;
> v->ps_color_out_reg = -1;
> v->ps_depth_out_reg = -1;
> +   v->needs_icache = c->inst_ptr > c->specs->max_instructions;
> copy_uniform_state_to_shader(c, v);
>
> if (c->info.processor == PIPE_SHADER_VERTEX) {
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.h 
> b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
> index 88a093f..f5c1689 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.h
> +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
> @@ -94,12 +94,17 @@ struct etna_shader_variant {
> /* unknown input property (XX_INPUT_COUNT, field UNK8) */
> uint32_t input_count_unk8;
>
> +   /* shader is larger than GPU instruction limit, thus needs icache */
> +   bool needs_icache;
> +
> /* shader variants form a linked list */
> struct etna_shader_variant *next;
>
> /* replicated here to avoid passing extra ptrs everywhere */
> struct etna_shader *shader;
> struct etna_shader_key key;
> +
> +   struct etna_bo *bo; /* cached code memory bo handle (for icache) */
>  };
>
>  struct etna_varying {
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c 
> b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> index 273b3d0..c2117d5 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> @@ -421,9 +421,6 @@ etna_emit_state(struct etna_context *ctx)
> if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
>/*00830*/ EMIT_STATE(VS_LOAD_BALANCING, 
> ctx->shader_state.VS_LOAD_BALANCING);
>/*00838*/ EMIT_STATE(VS_START_PC, ctx->shader_state.VS_START_PC);
> -  if (ctx->specs.has_shader_range_registers) {
> - /*0085C*/ EMIT_STATE(VS_RANGE, (ctx->shader_state.vs_inst_mem_size 
> / 4 - 1) << 16);
> -  }
> }
> if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) {
>/*00A00*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_X, 
> ctx->viewport.PA_VIEWPORT_SCALE_X);
> @@ -534,10 +531,6 @@ etna_emit_state(struct etna_context *ctx)
>: ctx->shader_state.PS_TEMP_REGISTER_CONTROL);
>/*01010*/ EMIT_STATE(PS_CONTROL, ctx->shader_state.PS_CONTROL);
>/*01018*/ EMIT_STATE(PS_START_PC, ctx->shader_state.PS_START_PC);
> -  if (ctx->specs.has_shader_range_registers) {
> - /*0101C*/ EMIT_STATE(PS_RANGE, ((ctx->shader_state.ps_inst_mem_size 
> / 4 - 1 + 0x100) << 16) |
> -0x100);
> -  }
> }
> if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_FRAMEBUFFER))) {
>uint32_t val = etna_zsa_state(ctx->zsa)->PE_DEPTH_CONFIG;
> @@ -739,14 +732,43 @@ etna_emit_state(struct etna_context *ctx)
> if (dirty & (ETNA_DIRTY_SHADER)) {
>/* Special case: a new shader was loaded; simply re-load all uniforms 
> and
> * shader code at once */
> -  /*04000 or 0C000*/
> -  etna_set_state_multi(stream, ctx->specs.vs_offset,
> -   ctx->shader_state.vs_inst_mem_size,
> -   

[Mesa-dev] [PATCH 3/3] etnaviv: Implement ICACHE

2017-07-24 Thread Wladimir J. van der Laan
This patch adds support for large shaders on GC3000. For example the "terrain"
glmark benchmark with a large fragment shader will work after this.

If the GPU supports ICACHE, shaders larger than the available state area will
be uploaded to a bo of their own and instructed to be loaded from memory on
demand. Small shaders will be uploaded in the usual way. This mimics the
behavior of the blob.

On GPUs that don't support ICACHE, this patch should make no difference.

Signed-off-by: Wladimir J. van der Laan 
---
 src/gallium/drivers/etnaviv/etnaviv_compiler.c |  3 +-
 src/gallium/drivers/etnaviv/etnaviv_compiler.h |  5 +++
 src/gallium/drivers/etnaviv/etnaviv_emit.c | 52 ++
 src/gallium/drivers/etnaviv/etnaviv_internal.h |  4 ++
 src/gallium/drivers/etnaviv/etnaviv_screen.c   |  4 +-
 src/gallium/drivers/etnaviv/etnaviv_shader.c   | 45 +-
 6 files changed, 95 insertions(+), 18 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c 
b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
index fbe66d0..0664d52 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
@@ -2277,7 +2277,7 @@ etna_compile_check_limits(struct etna_compile *c)
/* round up number of uniforms, including immediates, in units of four */
int num_uniforms = c->imm_base / 4 + (c->imm_size + 3) / 4;
 
-   if (c->inst_ptr > c->specs->max_instructions) {
+   if (!c->specs->has_icache && c->inst_ptr > c->specs->max_instructions) {
   DBG("Number of instructions (%d) exceeds maximum %d", c->inst_ptr,
   c->specs->max_instructions);
   return false;
@@ -2501,6 +2501,7 @@ etna_compile_shader(struct etna_shader_variant *v)
v->vs_pointsize_out_reg = -1;
v->ps_color_out_reg = -1;
v->ps_depth_out_reg = -1;
+   v->needs_icache = c->inst_ptr > c->specs->max_instructions;
copy_uniform_state_to_shader(c, v);
 
if (c->info.processor == PIPE_SHADER_VERTEX) {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.h 
b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
index 88a093f..f5c1689 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
@@ -94,12 +94,17 @@ struct etna_shader_variant {
/* unknown input property (XX_INPUT_COUNT, field UNK8) */
uint32_t input_count_unk8;
 
+   /* shader is larger than GPU instruction limit, thus needs icache */
+   bool needs_icache;
+
/* shader variants form a linked list */
struct etna_shader_variant *next;
 
/* replicated here to avoid passing extra ptrs everywhere */
struct etna_shader *shader;
struct etna_shader_key key;
+
+   struct etna_bo *bo; /* cached code memory bo handle (for icache) */
 };
 
 struct etna_varying {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c 
b/src/gallium/drivers/etnaviv/etnaviv_emit.c
index 273b3d0..c2117d5 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
@@ -421,9 +421,6 @@ etna_emit_state(struct etna_context *ctx)
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
   /*00830*/ EMIT_STATE(VS_LOAD_BALANCING, 
ctx->shader_state.VS_LOAD_BALANCING);
   /*00838*/ EMIT_STATE(VS_START_PC, ctx->shader_state.VS_START_PC);
-  if (ctx->specs.has_shader_range_registers) {
- /*0085C*/ EMIT_STATE(VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 
4 - 1) << 16);
-  }
}
if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) {
   /*00A00*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_X, 
ctx->viewport.PA_VIEWPORT_SCALE_X);
@@ -534,10 +531,6 @@ etna_emit_state(struct etna_context *ctx)
   : ctx->shader_state.PS_TEMP_REGISTER_CONTROL);
   /*01010*/ EMIT_STATE(PS_CONTROL, ctx->shader_state.PS_CONTROL);
   /*01018*/ EMIT_STATE(PS_START_PC, ctx->shader_state.PS_START_PC);
-  if (ctx->specs.has_shader_range_registers) {
- /*0101C*/ EMIT_STATE(PS_RANGE, ((ctx->shader_state.ps_inst_mem_size / 
4 - 1 + 0x100) << 16) |
-0x100);
-  }
}
if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_FRAMEBUFFER))) {
   uint32_t val = etna_zsa_state(ctx->zsa)->PE_DEPTH_CONFIG;
@@ -739,14 +732,43 @@ etna_emit_state(struct etna_context *ctx)
if (dirty & (ETNA_DIRTY_SHADER)) {
   /* Special case: a new shader was loaded; simply re-load all uniforms and
* shader code at once */
-  /*04000 or 0C000*/
-  etna_set_state_multi(stream, ctx->specs.vs_offset,
-   ctx->shader_state.vs_inst_mem_size,
-   ctx->shader_state.VS_INST_MEM);
-  /*06000 or 0D000*/
-  etna_set_state_multi(stream, ctx->specs.ps_offset,
-   ctx->shader_state.ps_inst_mem_size,
-   ctx->shader_state.PS_INST_MEM);
+  if (ctx->shader_state.VS_INST_ADDR.bo || 
ctx->shader_state.PS_INST_ADDR.bo) {
+