Hans de Goede
2015-Aug-12 12:24 UTC
[Nouveau] [PATCH mesa] nv30: Fix creation of scanout buffers
Scanout buffers on nv30 must always be non-swizzled and have special width alignment constraints. These constrains have been taken from the xf86-video-nouveau src/nv_accel_common.c: nouveau_allocate_surface() function. nouveau_allocate_surface() applies these width constraints only when a tiled attribute is set, which it sets for all surfaces allocated via dri, and this "tiling" is not the same as swizzling, scanout surfaces must be linear / have a uniform_pitch or only complete garbage is shown. This commit fixes dri3 on nv30 showing a garbled display, with dri3 the scanout buffers are allocated by mesa, rather then by the ddx, and the wrong stride of these buffers was causing the garbled display. Signed-off-by: Hans de Goede <hdegoede at redhat.com> --- src/gallium/drivers/nouveau/nv30/nv30_miptree.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c index c75b4b9..2276347 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c @@ -28,6 +28,7 @@ #include "util/u_surface.h" #include "nv_m2mf.xml.h" +#include "nv_object.xml.h" #include "nv30/nv30_screen.h" #include "nv30/nv30_context.h" #include "nv30/nv30_resource.h" @@ -362,6 +363,7 @@ nv30_miptree_create(struct pipe_screen *pscreen, blocksz = util_format_get_blocksize(pt->format); if ((pt->target == PIPE_TEXTURE_RECT) || + (pt->bind & PIPE_BIND_SCANOUT) || !util_is_power_of_two(pt->width0) || !util_is_power_of_two(pt->height0) || !util_is_power_of_two(pt->depth0) || @@ -369,6 +371,14 @@ nv30_miptree_create(struct pipe_screen *pscreen, util_format_is_float(pt->format) || mt->ms_mode) { mt->uniform_pitch = util_format_get_nblocksx(pt->format, w) * blocksz; mt->uniform_pitch = align(mt->uniform_pitch, 64); + if (pt->bind & PIPE_BIND_SCANOUT) { + struct nv30_screen *screen = nv30_screen(pscreen); + int pitch_align = MAX2( + screen->eng3d->oclass >= NV40_3D_CLASS ? 1024 : 256, + /* round_down_pow2(mt->uniform_pitch / 4) */ + 1 << (util_last_bit(mt->uniform_pitch / 4) - 1)); + mt->uniform_pitch = align(mt->uniform_pitch, pitch_align); + } } if (!mt->uniform_pitch) -- 2.4.3
On 12.08.2015 14:24, Hans de Goede wrote:> Scanout buffers on nv30 must always be non-swizzled and have special > width alignment constraints. > > These constrains have been taken from the xf86-video-nouveau > src/nv_accel_common.c: nouveau_allocate_surface() function. > > nouveau_allocate_surface() applies these width constraints only when a > tiled attribute is set, which it sets for all surfaces allocated via > dri, and this "tiling" is not the same as swizzling, scanout surfaces > must be linear / have a uniform_pitch or only complete garbage is shown. > > This commit fixes dri3 on nv30 showing a garbled display, with dri3 the > scanout buffers are allocated by mesa, rather then by the ddx, and the > wrong stride of these buffers was causing the garbled display. > > Signed-off-by: Hans de Goede <hdegoede at redhat.com> > --- > src/gallium/drivers/nouveau/nv30/nv30_miptree.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c > index c75b4b9..2276347 100644 > --- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c > +++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c > @@ -28,6 +28,7 @@ > #include "util/u_surface.h" > > #include "nv_m2mf.xml.h" > +#include "nv_object.xml.h" > #include "nv30/nv30_screen.h" > #include "nv30/nv30_context.h" > #include "nv30/nv30_resource.h" > @@ -362,6 +363,7 @@ nv30_miptree_create(struct pipe_screen *pscreen, > blocksz = util_format_get_blocksize(pt->format); > > if ((pt->target == PIPE_TEXTURE_RECT) || > + (pt->bind & PIPE_BIND_SCANOUT) || > !util_is_power_of_two(pt->width0) || > !util_is_power_of_two(pt->height0) || > !util_is_power_of_two(pt->depth0) || > @@ -369,6 +371,14 @@ nv30_miptree_create(struct pipe_screen *pscreen, > util_format_is_float(pt->format) || mt->ms_mode) { > mt->uniform_pitch = util_format_get_nblocksx(pt->format, w) * blocksz; > mt->uniform_pitch = align(mt->uniform_pitch, 64); > + if (pt->bind & PIPE_BIND_SCANOUT) { > + struct nv30_screen *screen = nv30_screen(pscreen); > + int pitch_align = MAX2( > + screen->eng3d->oclass >= NV40_3D_CLASS ? 1024 : 256, > + /* round_down_pow2(mt->uniform_pitch / 4) */ > + 1 << (util_last_bit(mt->uniform_pitch / 4) - 1)); > + mt->uniform_pitch = align(mt->uniform_pitch, pitch_align); > + } > } > > if (!mt->uniform_pitch) >I patched mesa 10.6.4 with it, did not help to solve https://bugs.freedesktop.org/show_bug.cgi?id=90871