Bug 96408

Summary: [PERF] SSO: dirty all stages when only one is updated. Trigger extra validations.
Product: Mesa Reporter: gregory.hainaut
Component: Mesa coreAssignee: mesa-dev
Status: RESOLVED FIXED QA Contact: mesa-dev
Severity: normal    
Priority: medium    
Version: git   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description gregory.hainaut 2016-06-06 16:56:02 UTC
Hello,

Profile my app (PCSX2), I found that NEW_VERTEX_PROGRAM validation is often called whereas my program barely switch the vertex shader.

It was detected on Gallium Nouveau but it could impact others (gallium) drivers


Potential issue 1:
_mesa_UseProgramStages (aka glUseProgramStages) will always call _mesa_use_shader_program which call in turn ctx->Driver.UseProgram

If I'm correct it is allowed to attach a stage to any pipeline (i.e. not bound pipeline). In this case, it doesn't make sense to call UseProgram.

Potential issue 2:
ctx->Driver.UseProgram (aka st_use_program in gallium word) will dirty all stages (see code below). I'm not sure it is mandatory. It feels like the API need to be extended with an st_use_program_stage.

static void
st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
{
   struct st_context *st = st_context(ctx);

   st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
   st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
   st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
   st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
   st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
   st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
}

Potential issue 3:
I don't know if we need to revalidate everything when the pipeline is switched. 

In order to reduce pipeline validate one could create severals pipeline that contains same programs.

Example:
pipe0 contains VS and FS0
pipe1 contains VS and FS1

Do we need to revalidate all the VS resources, if pipe1 is bound after pipe0?

Any opinions ?

Gregory
Comment 1 gregory.hainaut 2016-06-07 08:10:49 UTC
Note for item 2/

Maybe the dirty bit is already set by update_program (from main/state.c)
/**
 * Update the ctx->*Program._Current pointers to point to the
 * current/active programs.  Then call ctx->Driver.BindProgram() to
 * tell the driver which programs to use.
 */

At least it seems some code could be reused.
Comment 2 gregory.hainaut 2016-06-08 08:20:37 UTC
Hum, when a new program is set, use_shader_program is called and the _NEW_PROGRAM flag will be set.

use_shader_program(....)
{
  ....
  if (*target != shProg) {
      /* Program is current, flush it */
      if (shTarget == ctx->_Shader) {
         FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
      }
  ....
}

During the draw, the program update will be checked if _NEW_PROGRAM is enabled. And new program will be bound accordingly

#0  st_bind_program (ctx=0x8801f88, target=34820, prog=0x8acfbf0) at state_tracker/st_cb_program.c:59
#1  0xf460bd3c in update_program (ctx=0x8801f88) at main/state.c:262
#2  _mesa_update_state_locked (ctx=0x8801f88) at main/state.c:468
#3  0xf460c0c4 in _mesa_update_state (ctx=0x8801f88) at main/state.c:499
#4  0xf4501739 in _mesa_valid_to_render (ctx=0x8801f88, where=0xf4a901be "glDrawArrays") at main/context.c:1935
#5  0xf44db08f in check_valid_to_render (function=0xf4a901be "glDrawArrays", ctx=0x8801f88) at main/api_validate.c:44

So I have the feeling that "ctx->Driver.UseProgram" is kind of useless. Indeed, I didn't manage to find the code for dri (not-gallium) drivers. So it is probably undefined.

Perf wise, the removal of Driver.UseProgram yields a 10-15% speed increase on my use case.
Comment 3 gregory.hainaut 2016-07-30 17:36:21 UTC
I'm closing the bug

Marek's rewrite of Gallium state management resolved the issue :)

For the record, the last commit of the serie is:

author	Marek Olšák <marek.olsak@amd.com>	2016-07-17 18:54:51 (GMT)
committer	Marek Olšák <marek.olsak@amd.com>	2016-07-30 13:02:14 (GMT)
commit	12aec78993edface7f530eede9e018b5fa1897b7 (patch)
tree	efbe72650dedbb30702a14c31ec4ff967de7a1b8
parent	b47839ad8361ef42a0f38c52fe24307b865c5489 (diff)

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.