[Mesa-dev] [PATCH] i965: Compute VS attribute WA bits earlier and check if they changed.
Ian Romanick
idr at freedesktop.org
Thu Dec 4 20:42:44 PST 2014
On 12/03/2014 05:42 PM, Kenneth Graunke wrote:
> BRW_NEW_VERTICES is flagged every time we draw a primitive. Having
> the brw_vs_prog atom depend on BRW_NEW_VERTICES meant that we had to
> compute the VS program key and do a program cache lookup for every
> single primitive. This is painfully expensive.
>
> The workaround bit computation is almost entirely based on the vertex
> attribute arrays (brw->vb.inputs[i]), which are set by brw_merge_inputs.
> The only thing it uses the VS program for is to see which VS inputs are
> actually read. brw_merge_inputs() happens once per primitive, and can
> safely look at the currently bound vertex program, as it doesn't change
> in the middle of a draw.
>
> This patch moves the workaround bit computation to brw_merge_inputs(),
> right after assigning brw->vb.inputs[i], and stores the previous WA bit
> values in the context. If they've actually changed from the last draw
> (which is uncommon), we signal that we need a new vertex program,
> causing brw_vs_prog to compute a new key.
>
> Logically, it might make sense to create a BRW_NEW_VS_WORKAROUND_BITS
> state flag, but I chose to use BRW_NEW_VERTEX_PROGRAM since it should
> work just as well, and already exists.
>
> Improves performance in Gl32Batch7 by 15.5728% +/- 1.96978% on my
> Haswell GT3e system. I'm told that Baytrail shows similar gains.
I got 9.08476% +/- 0.322829% (n=40) for 32-bit and 10.1315% +/-
0.315496% for 64-bit on my BYT using Fedora 20's Mesa CFLAGS.
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/drivers/dri/i965/brw_context.h | 8 ++++++
> src/mesa/drivers/dri/i965/brw_draw.c | 46 +++++++++++++++++++++++++++++++++
> src/mesa/drivers/dri/i965/brw_vs.c | 42 +++---------------------------
> 3 files changed, 58 insertions(+), 38 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index ec4b3dd..ace29df 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -1129,6 +1129,14 @@ struct brw_context
> * the same VB packed over and over again.
> */
> unsigned int start_vertex_bias;
> +
> + /**
> + * Certain vertex attribute formats aren't natively handled by the
> + * hardware and require special VS code to fix up their values.
> + *
> + * These bitfields indicate which workarounds are needed.
> + */
> + uint8_t attrib_wa_flags[VERT_ATTRIB_MAX];
> } vb;
>
> struct {
> diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
> index 4c2802a..d2ea085 100644
> --- a/src/mesa/drivers/dri/i965/brw_draw.c
> +++ b/src/mesa/drivers/dri/i965/brw_draw.c
> @@ -46,6 +46,7 @@
> #include "brw_defines.h"
> #include "brw_context.h"
> #include "brw_state.h"
> +#include "brw_vs.h"
>
> #include "intel_batchbuffer.h"
> #include "intel_buffers.h"
> @@ -281,6 +282,7 @@ static void brw_emit_prim(struct brw_context *brw,
> static void brw_merge_inputs( struct brw_context *brw,
> const struct gl_client_array *arrays[])
> {
> + const struct gl_context *ctx = &brw->ctx;
> GLuint i;
>
> for (i = 0; i < brw->vb.nr_buffers; i++) {
> @@ -293,6 +295,50 @@ static void brw_merge_inputs( struct brw_context *brw,
> brw->vb.inputs[i].buffer = -1;
> brw->vb.inputs[i].glarray = arrays[i];
> }
> +
> + if (brw->gen < 8 && !brw->is_haswell) {
> + struct gl_program *vp = &ctx->VertexProgram._Current->Base;
> + /* Prior to Haswell, the hardware can't natively support GL_FIXED or
> + * 2_10_10_10_REV vertex formats. Set appropriate workaround flags.
> + */
> + for (i = 0; i < VERT_ATTRIB_MAX; i++) {
> + if (!(vp->InputsRead & BITFIELD64_BIT(i)))
> + continue;
> +
> + uint8_t wa_flags = 0;
> +
> + switch (brw->vb.inputs[i].glarray->Type) {
> +
> + case GL_FIXED:
> + wa_flags = brw->vb.inputs[i].glarray->Size;
> + break;
> +
> + case GL_INT_2_10_10_10_REV:
> + wa_flags |= BRW_ATTRIB_WA_SIGN;
> + /* fallthough */
> +
> + case GL_UNSIGNED_INT_2_10_10_10_REV:
> + if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
> + wa_flags |= BRW_ATTRIB_WA_BGRA;
> +
> + if (brw->vb.inputs[i].glarray->Normalized)
> + wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
> + else if (!brw->vb.inputs[i].glarray->Integer)
> + wa_flags |= BRW_ATTRIB_WA_SCALE;
> +
> + break;
> + }
> +
> + if (brw->vb.attrib_wa_flags[i] != wa_flags) {
> + brw->vb.attrib_wa_flags[i] = wa_flags;
> + /* New workaround flags means we need to compute a new program
> + * key and look up the associated vertex shader. Just flag that
> + * we have a new shader program, since it triggers that effect.
> + */
> + brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
> + }
> + }
> + }
> }
>
> /**
> diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
> index 2f628e5..6dbac1e 100644
> --- a/src/mesa/drivers/dri/i965/brw_vs.c
> +++ b/src/mesa/drivers/dri/i965/brw_vs.c
> @@ -449,42 +449,9 @@ static void brw_upload_vs_prog(struct brw_context *brw)
> brw_populate_sampler_prog_key_data(ctx, prog, brw->vs.base.sampler_count,
> &key.base.tex);
>
> - /* BRW_NEW_VERTICES */
> - if (brw->gen < 8 && !brw->is_haswell) {
> - /* Prior to Haswell, the hardware can't natively support GL_FIXED or
> - * 2_10_10_10_REV vertex formats. Set appropriate workaround flags.
> - */
> - for (i = 0; i < VERT_ATTRIB_MAX; i++) {
> - if (!(vp->program.Base.InputsRead & BITFIELD64_BIT(i)))
> - continue;
> -
> - uint8_t wa_flags = 0;
> -
> - switch (brw->vb.inputs[i].glarray->Type) {
> -
> - case GL_FIXED:
> - wa_flags = brw->vb.inputs[i].glarray->Size;
> - break;
> -
> - case GL_INT_2_10_10_10_REV:
> - wa_flags |= BRW_ATTRIB_WA_SIGN;
> - /* fallthough */
> -
> - case GL_UNSIGNED_INT_2_10_10_10_REV:
> - if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
> - wa_flags |= BRW_ATTRIB_WA_BGRA;
> -
> - if (brw->vb.inputs[i].glarray->Normalized)
> - wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
> - else if (!brw->vb.inputs[i].glarray->Integer)
> - wa_flags |= BRW_ATTRIB_WA_SCALE;
> -
> - break;
> - }
> -
> - key.gl_attrib_wa_flags[i] = wa_flags;
> - }
> - }
> + /* BRW_NEW_VERTEX_PROGRAM */
> + memcpy(key.gl_attrib_wa_flags, brw->vb.attrib_wa_flags,
> + sizeof(brw->vb.attrib_wa_flags));
>
> if (!brw_search_cache(&brw->cache, BRW_CACHE_VS_PROG,
> &key, sizeof(key),
> @@ -521,8 +488,7 @@ const struct brw_tracked_state brw_vs_prog = {
> _NEW_POLYGON |
> _NEW_TEXTURE |
> _NEW_TRANSFORM,
> - .brw = BRW_NEW_VERTEX_PROGRAM |
> - BRW_NEW_VERTICES,
> + .brw = BRW_NEW_VERTEX_PROGRAM,
> },
> .emit = brw_upload_vs_prog
> };
>
More information about the mesa-dev
mailing list