diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-09-09 12:38:27 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-09-09 13:51:19 +0200 |
commit | 7d5eafe76d06e6611a6e1e8c175f11a95a4f371f (patch) | |
tree | 8f5ef01813ada37354040d37227adebf27c72ade | |
parent | 199c781c703eb3b4986bd454d29a5049f19290ff (diff) |
driver: fix cousins of MSAA hang bug
- Change the order in `reset_context` as well
- Clobber PS INPUTS state when MSAA samples changed to make sure it's
always written, as we don't know the current value anymore.
-rw-r--r-- | doc/kernel_bugs.md | 22 | ||||
-rw-r--r-- | native/driver/etna_pipe.c | 21 |
2 files changed, 42 insertions, 1 deletions
diff --git a/doc/kernel_bugs.md b/doc/kernel_bugs.md index 0ccb33a..76e5445 100644 --- a/doc/kernel_bugs.md +++ b/doc/kernel_bugs.md @@ -31,3 +31,25 @@ signal causes the kernel to run out of signals. This causes hangs in rendering. Status: workaround found (see `ETNA_MAX_UNSIGNALED_FLUSHES`) +Command buffer memory management on cubox +------------------------------------------- + + <_rmk_> err, this is not good. + <_rmk_> gckCOMMAND_Start: command queue is at 0xe7846000 + <_rmk_> gckCOMMAND_Start: WL 380000c8 0cf6d19f 40000002 10281000 + <_rmk_> that's what the first 4 words should've been at the beginning (and where when the GPU was started) + <_rmk_> they then conveniently become: 4000002C 19CE0000 AAAAAAAA AAAAAAAA + <_rmk_> the first two change because of the wait being converted to a link + <_rmk_> the second two... + <_rmk_> well, 0xaaaaaaaa is the free page poisoning. + <_rmk_> which suggests that the GPU command page was freed while still in use + <_rmk_> ah ha, that'll be how. get lucky with the cache behaviour and this is what happens... + <_rmk_> page poisoning enabled. When a lowmem page is allocated, it's memset() through its lowmem mapping, which is cacheable. + <_rmk_> this data can sit in the CPU cache. + <_rmk_> it is then ioremap()'d (which I've been dead against for years) which creates a *device* mapping. + <_rmk_> we then write the wait/link through the device mapping. + <_rmk_> at some point later, the cache lines get evicted from the _normal memory_ mapping. + <_rmk_> thereby overwriting the original wait/link commands in the GPU stream with 0xAAAAAAAA + <_rmk_> I wonder what that a command word with a bit pattern of 10101 in the top 5 bits tells the GPU to do... + <_rmk_> the only thing I can say is... if people would damn well listen to me when I say "don't do this" then you wouldn't get these bugs. + <_rmk_> this is one of the reasons why my check in ioremap.c exists to prevent system memory being ioremap'd and therefore this kind of issue cropping up diff --git a/native/driver/etna_pipe.c b/native/driver/etna_pipe.c index 24c6eb7..4670355 100644 --- a/native/driver/etna_pipe.c +++ b/native/driver/etna_pipe.c @@ -105,6 +105,11 @@ static void reset_context(struct pipe_context *restrict pipe) uint32_t last_reg, last_fixp, span_start; ETNA_COALESCE_STATE_OPEN(ETNA_3D_CONTEXT_SIZE); + /* multi sample config is set first, and outside of the normal sorting + * order, as changing the multisample state clobbers PS.INPUT_COUNT (and + * possibly PS.TEMP_REGISTER_CONTROL). + */ + /*03818*/ EMIT_STATE(GL_MULTI_SAMPLE_CONFIG, GL_MULTI_SAMPLE_CONFIG); /* below code generated by gen_weave_state.py, keep this in sync with sync_context! */ /* begin only EMIT_STATE -- make sure no new etna_reserve calls are done here directly * or indirectly */ @@ -249,7 +254,6 @@ static void reset_context(struct pipe_context *restrict pipe) } } /*03814*/ EMIT_STATE(GL_VERTEX_ELEMENT_CONFIG, GL_VERTEX_ELEMENT_CONFIG); - /*03818*/ EMIT_STATE(GL_MULTI_SAMPLE_CONFIG, GL_MULTI_SAMPLE_CONFIG); /*0381C*/ EMIT_STATE(GL_VARYING_TOTAL_COMPONENTS, GL_VARYING_TOTAL_COMPONENTS); /*03820*/ EMIT_STATE(GL_VARYING_NUM_COMPONENTS, GL_VARYING_NUM_COMPONENTS); for(int x=0; x<2; ++x) @@ -316,6 +320,21 @@ static void sync_context(struct pipe_context *restrict pipe) e->gpu3d.num_vertex_elements = e->vertex_elements->num_elements; + /* If MULTI_SAMPLE_CONFIG.MSAA_SAMPLES changed, clobber affected shader + * state to make sure it is always rewritten. */ + if(dirty & (ETNA_STATE_FRAMEBUFFER)) + { + if((e->gpu3d.GL_MULTI_SAMPLE_CONFIG & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK) != + (e->framebuffer.GL_MULTI_SAMPLE_CONFIG & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK)) + { + /* XXX what does the GPU set these states to on MSAA samples change? Does it do the right thing? + * (increase/decrease as necessary) or something else? Just set some invalid value until we know for + * sure. */ + e->gpu3d.PS_INPUT_COUNT = 0xffffffff; + e->gpu3d.PS_TEMP_REGISTER_CONTROL = 0xffffffff; + } + } + /* * Cached state update emission. * The etna_3d_state structure e->gpu3d is used to keep the current context. |