diff options
author | Dave Airlie <airlied@redhat.com> | 2016-04-26 14:30:31 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-04-26 14:36:37 +1000 |
commit | bc331f5de66f7b78adf1ea8663e7095726f296a5 (patch) | |
tree | 73ae8de1e8c21528cddbe7c719b72f979e0f3259 /src | |
parent | 90d0c6ff93a301c098e9b3c3dfbdf7161f71267e (diff) |
tgsi/exec: implement restartable machine.
This lets us restart the machine at a PC value, and exits
the machine when we hit a barrier.
Compute shaders will then execute all the threads up to the
barrier, then restart the machines after the barrier once
all are done.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 44 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 2 |
2 files changed, 29 insertions, 17 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 7ec30fb0e04..d914ef5d6f0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -4781,7 +4781,7 @@ micro_umsb(union tgsi_exec_channel *dst, dst->i[3] = util_last_bit(src->u[3]) - 1; } -static void +static bool exec_instruction( struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst, @@ -5100,7 +5100,7 @@ exec_instruction( mach->CondStackTop = 0; mach->LoopStackTop = 0; *pc = -1; - return; + return true; } assert(mach->CallStackTop > 0); @@ -5749,10 +5749,12 @@ exec_instruction( break; case TGSI_OPCODE_BARRIER: case TGSI_OPCODE_MEMBAR: + return false; break; default: assert( 0 ); } + return true; } static void @@ -5796,13 +5798,16 @@ uint tgsi_exec_machine_run( struct tgsi_exec_machine *mach, int start_pc ) { uint i; - int pc = 0; - tgsi_exec_machine_setup_masks(mach); + mach->pc = start_pc; + + if (!start_pc) { + tgsi_exec_machine_setup_masks(mach); - /* execute declarations (interpolants) */ - for (i = 0; i < mach->NumDeclarations; i++) { - exec_declaration( mach, mach->Declarations+i ); + /* execute declarations (interpolants) */ + for (i = 0; i < mach->NumDeclarations; i++) { + exec_declaration( mach, mach->Declarations+i ); + } } { @@ -5811,24 +5816,29 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach, int start_pc ) struct tgsi_exec_vector outputs[PIPE_MAX_ATTRIBS]; uint inst = 1; - memset(mach->Temps, 0, sizeof(temps)); - if (mach->Outputs) - memset(mach->Outputs, 0, sizeof(outputs)); - memset(temps, 0, sizeof(temps)); - memset(outputs, 0, sizeof(outputs)); + if (!start_pc) { + memset(mach->Temps, 0, sizeof(temps)); + if (mach->Outputs) + memset(mach->Outputs, 0, sizeof(outputs)); + memset(temps, 0, sizeof(temps)); + memset(outputs, 0, sizeof(outputs)); + } #endif /* execute instructions, until pc is set to -1 */ - while (pc != -1) { - + while (mach->pc != -1) { + bool barrier_hit; #if DEBUG_EXECUTION uint i; - tgsi_dump_instruction(&mach->Instructions[pc], inst++); + tgsi_dump_instruction(&mach->Instructions[mach->pc], inst++); #endif - assert(pc < (int) mach->NumInstructions); - exec_instruction(mach, mach->Instructions + pc, &pc); + assert(mach->pc < (int) mach->NumInstructions); + barrier_hit = !exec_instruction(mach, mach->Instructions + mach->pc, &mach->pc); + + if (barrier_hit && mach->ShaderType == PIPE_SHADER_COMPUTE) + return 0; #if DEBUG_EXECUTION for (i = 0; i < TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS; i++) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 564b3d5d5cc..9343d788db7 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -445,6 +445,8 @@ struct tgsi_exec_machine SamplerViews[PIPE_MAX_SHADER_SAMPLER_VIEWS]; boolean UsedGeometryShader; + + int pc; }; struct tgsi_exec_machine * |