diff options
author | Christoph Bumiller <[email protected]> | 2010-01-18 16:22:59 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-01-18 19:53:29 +0100 |
commit | e74db4f20fdc4bd71259480f6f93436c98275cb9 (patch) | |
tree | f3fceabd58bcc2a13acf27a815a9758a447b6fea /src/gallium/drivers/nv50/nv50_program.c | |
parent | 9fb9c9f9ca27fbdb90fc0a7a01bdff64d32c05bb (diff) |
nv50: cannot exit shaders on a control flow instruction
Fixes lockup triggered by this ingenious shader:
1: CALL :3
2: END
3: BGNSUB ...
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_program.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 22fa6e6ae42..20db51070ff 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -477,6 +477,12 @@ is_join(struct nv50_program_exec *e) return FALSE; } +static INLINE boolean +is_control_flow(struct nv50_program_exec *e) +{ + return (e->inst[0] & 2); +} + static INLINE void set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, struct nv50_program_exec *e) @@ -3166,7 +3172,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (!is_long(pc->p->exec_tail)) convert_to_long(pc, pc->p->exec_tail); else - if (is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail)) + if (is_immd(pc->p->exec_tail) || + is_join(pc->p->exec_tail) || + is_control_flow(pc->p->exec_tail)) emit_nop(pc); pc->p->exec_tail->inst[1] |= 1; /* set exit bit */ |