Ilia Mirkin
2015-Jul-20 07:26 UTC
[Nouveau] [PATCH] nv50: adjust min/max lod by base level on G80
Make the assumption that there's a 1:1 TIC <-> TSC connection, and increase min/max lod by the relevant texture's base level. Also if there's no mipfilter, we have to enable it while forcing min/max lod to the base level. This fixes many, but not all, tex-miplevel-selection tests on G80. Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- All the textureLod tests fail. If I also adjust the lod_bias by the first_level, then the regular tests start failing. Not sure what the right move is here... need to trace the blob to see what it does here. src/gallium/drivers/nouveau/nv50/nv50_state.c | 1 + .../drivers/nouveau/nv50/nv50_stateobj_tex.h | 1 + src/gallium/drivers/nouveau/nv50/nv50_tex.c | 39 ++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c index d4d41af..98c4c3a 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -464,6 +464,7 @@ nv50_sampler_state_create(struct pipe_context *pipe, struct nv50_tsc_entry *so = MALLOC_STRUCT(nv50_tsc_entry); float f[2]; + so->pipe = *cso; so->id = -1; so->tsc[0] = (0x00026000 | diff --git a/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h b/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h index 99548cb..9a19166 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h @@ -5,6 +5,7 @@ #include "pipe/p_state.h" struct nv50_tsc_entry { + struct pipe_sampler_state pipe; int id; uint32_t tsc[8]; }; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_tex.c b/src/gallium/drivers/nouveau/nv50/nv50_tex.c index 17ae27f..d79c813 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_tex.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_tex.c @@ -344,6 +344,45 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) PUSH_DATA (push, (i << 4) | 0); continue; } + if (nv50->base.screen->class_3d == NV50_3D_CLASS) { + struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]); + + /* We must make sure that the MIN_LOD is at least set to the first + * level for the G80 + */ + bool need_update = false; + float min_lod = CLAMP( + tic->pipe.u.tex.first_level + tsc->pipe.min_lod, 0.0f, 15.0f); + float max_lod = CLAMP( + tic->pipe.u.tex.first_level + tsc->pipe.max_lod, 0.0f, 15.0f); + + if (tsc->pipe.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { + uint32_t old_tsc1 = tsc->tsc[1]; + tsc->tsc[1] &= ~NV50_TSC_1_MIPF__MASK; + if (tic->pipe.u.tex.first_level) { + tsc->tsc[1] |= NV50_TSC_1_MIPF_NEAREST; + max_lod = min_lod = tic->pipe.u.tex.first_level; + } + if (tsc->tsc[1] != old_tsc1) + need_update = true; + } + + uint32_t new_tsc2 + (((int)(max_lod * 256.0f) & 0xfff) << 12) | + ((int)(min_lod * 256.0f) & 0xfff); + if ((tsc->tsc[2] & 0xffffff) != new_tsc2) { + tsc->tsc[2] &= ~0xffffffu; + tsc->tsc[2] |= new_tsc2; + need_update = true; + } + + if (need_update && tsc->id >= 0) { + nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc, + 65536 + tsc->id * 32, + NOUVEAU_BO_VRAM, 32, tsc->tsc); + need_flush = TRUE; + } + } if (tsc->id < 0) { tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); -- 2.3.6
Samuel Pitoiset
2015-Jul-20 14:37 UTC
[Nouveau] [PATCH] nv50: adjust min/max lod by base level on G80
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com> On 07/20/2015 09:26 AM, Ilia Mirkin wrote:> Make the assumption that there's a 1:1 TIC <-> TSC connection, and > increase min/max lod by the relevant texture's base level. Also if > there's no mipfilter, we have to enable it while forcing min/max lod to > the base level. > > This fixes many, but not all, tex-miplevel-selection tests on G80. > > Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> > --- > > All the textureLod tests fail. If I also adjust the lod_bias by the > first_level, then the regular tests start failing. > > Not sure what the right move is here... need to trace the blob to see > what it does here. > > src/gallium/drivers/nouveau/nv50/nv50_state.c | 1 + > .../drivers/nouveau/nv50/nv50_stateobj_tex.h | 1 + > src/gallium/drivers/nouveau/nv50/nv50_tex.c | 39 ++++++++++++++++++++++ > 3 files changed, 41 insertions(+) > > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c > index d4d41af..98c4c3a 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c > +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c > @@ -464,6 +464,7 @@ nv50_sampler_state_create(struct pipe_context *pipe, > struct nv50_tsc_entry *so = MALLOC_STRUCT(nv50_tsc_entry); > float f[2]; > > + so->pipe = *cso; > so->id = -1; > > so->tsc[0] = (0x00026000 | > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h b/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h > index 99548cb..9a19166 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h > +++ b/src/gallium/drivers/nouveau/nv50/nv50_stateobj_tex.h > @@ -5,6 +5,7 @@ > #include "pipe/p_state.h" > > struct nv50_tsc_entry { > + struct pipe_sampler_state pipe; > int id; > uint32_t tsc[8]; > }; > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_tex.c b/src/gallium/drivers/nouveau/nv50/nv50_tex.c > index 17ae27f..d79c813 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_tex.c > +++ b/src/gallium/drivers/nouveau/nv50/nv50_tex.c > @@ -344,6 +344,45 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) > PUSH_DATA (push, (i << 4) | 0); > continue; > } > + if (nv50->base.screen->class_3d == NV50_3D_CLASS) { > + struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]); > + > + /* We must make sure that the MIN_LOD is at least set to the first > + * level for the G80 > + */ > + bool need_update = false; > + float min_lod = CLAMP( > + tic->pipe.u.tex.first_level + tsc->pipe.min_lod, 0.0f, 15.0f); > + float max_lod = CLAMP( > + tic->pipe.u.tex.first_level + tsc->pipe.max_lod, 0.0f, 15.0f); > + > + if (tsc->pipe.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { > + uint32_t old_tsc1 = tsc->tsc[1]; > + tsc->tsc[1] &= ~NV50_TSC_1_MIPF__MASK; > + if (tic->pipe.u.tex.first_level) { > + tsc->tsc[1] |= NV50_TSC_1_MIPF_NEAREST; > + max_lod = min_lod = tic->pipe.u.tex.first_level; > + } > + if (tsc->tsc[1] != old_tsc1) > + need_update = true; > + } > + > + uint32_t new_tsc2 > + (((int)(max_lod * 256.0f) & 0xfff) << 12) | > + ((int)(min_lod * 256.0f) & 0xfff); > + if ((tsc->tsc[2] & 0xffffff) != new_tsc2) { > + tsc->tsc[2] &= ~0xffffffu; > + tsc->tsc[2] |= new_tsc2; > + need_update = true; > + } > + > + if (need_update && tsc->id >= 0) { > + nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc, > + 65536 + tsc->id * 32, > + NOUVEAU_BO_VRAM, 32, tsc->tsc); > + need_flush = TRUE; > + } > + } > if (tsc->id < 0) { > tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); >