[Mesa-dev] [PATCH] draw: fix draw_llvm_variant_key struct padding to avoid recompiles
Brian Paul
brianp at vmware.com
Mon Jan 28 15:44:27 PST 2013
On 01/28/2013 03:45 PM, sroland at vmware.com wrote:
> From: Roland Scheidegger<sroland at vmware.com>
>
> The struct padding got broken by c789b981b244333cfc903bcd1e2fefc010500013.
> This caused serious performance regression because part of the key was
> unitialized and hence the shader always recompiled (at least on release
> builds...).
> While here also fix key size calculation when the number of samplers
> and the number of sampler views are different.
> ---
> src/gallium/auxiliary/draw/draw_llvm.c | 3 ++-
> src/gallium/auxiliary/draw/draw_llvm.h | 3 ++-
> src/gallium/auxiliary/draw/draw_vs_llvm.c | 5 +++--
> 3 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
> index afb10a6..dc83f80 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -1378,7 +1378,8 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
> key->clip_halfz = !llvm->draw->rasterizer->gl_rasterization_rules;
> key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE);
> key->ucp_enable = llvm->draw->rasterizer->clip_plane_enable;
> - key->pad = 0;
> + key->pad1 = 0;
> + key->pad2 = 0;
>
> /* All variants of this shader will have the same value for
> * nr_samplers. Not yet trying to compact away holes in the
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
> index a664857..8e5bd3c 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.h
> +++ b/src/gallium/auxiliary/draw/draw_llvm.h
> @@ -206,8 +206,9 @@ struct draw_llvm_variant_key
> unsigned clip_halfz:1;
> unsigned bypass_viewport:1;
> unsigned need_edgeflags:1;
> + unsigned pad1:1;
> unsigned ucp_enable:PIPE_MAX_CLIP_PLANES;
> - unsigned pad:33-PIPE_MAX_CLIP_PLANES;
> + unsigned pad2:32-PIPE_MAX_CLIP_PLANES;
There should probably be a prominent comment on this struct about the
importance of zeroing-out any unused bits, adding padding fields, etc.
to help prevent this in the future.
If we wanted to be really safe, during init we could create a dummy
key, set it to all ones, then set all of the fields to zero, then
assert that no bits in the key are still set.
>
> /* Variable number of vertex elements:
> */
> diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
> index 3e46f8c..ac3999e 100644
> --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
> @@ -100,8 +100,9 @@ draw_create_vs_llvm(struct draw_context *draw,
>
> vs->variant_key_size =
> draw_llvm_variant_key_size(
> - vs->base.info.file_max[TGSI_FILE_INPUT]+1,
> - vs->base.info.file_max[TGSI_FILE_SAMPLER]+1);
> + vs->base.info.file_max[TGSI_FILE_INPUT]+1,
> + MAX2(vs->base.info.file_max[TGSI_FILE_SAMPLER]+1,
> + vs->base.info.file_max[TGSI_FILE_SAMPLER_VIEW]+1));
>
> vs->base.state.stream_output = state->stream_output;
> vs->base.draw = draw;
Otherwise,
Reviewed-by: Brian Paul <brianp at vmware.com>
More information about the mesa-dev
mailing list