Mesa (master): nv50: use 2d blit when m2mf doesn't support the copy
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jan 11 20:13:56 UTC 2021
Module: Mesa
Branch: master
Commit: 14e6f541b1612b847701f09da9d5bf3f6c6c8f44
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=14e6f541b1612b847701f09da9d5bf3f6c6c8f44
Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date: Thu Jan 7 19:19:48 2021 -0500
nv50: use 2d blit when m2mf doesn't support the copy
Looks like m2mf bails if a line is >64k in width for tiled textures
(even if only a sub-section is copied as long as any part is beyond the
64k mark).
Fixes a number of GLES3 accuracy tests which made 8k-wide textures which
were read out as RGBA32_UINT, leading to problems.
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Reviewed-by: Karol Herbst <kherbst at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8396>
---
src/gallium/drivers/nouveau/nv50/nv50_transfer.c | 126 +++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 4a75ea536b3..fad21ba6a5c 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -51,6 +51,115 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect,
}
}
+/* This is very similar to nv50_2d_texture_do_copy, but doesn't require
+ * miptree objects. Maybe refactor? Although it's not straightforward.
+ */
+static void
+nv50_2d_transfer_rect(struct nv50_context *nv50,
+ const struct nv50_m2mf_rect *dst,
+ const struct nv50_m2mf_rect *src,
+ uint32_t nblocksx, uint32_t nblocksy)
+{
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
+ struct nouveau_bufctx *bctx = nv50->bufctx;
+ const int cpp = dst->cpp;
+
+ nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
+ nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
+ nouveau_pushbuf_bufctx(push, bctx);
+ nouveau_pushbuf_validate(push);
+
+ uint32_t format;
+ switch (cpp) {
+ case 1:
+ format = G80_SURFACE_FORMAT_R8_UNORM;
+ break;
+ case 2:
+ format = G80_SURFACE_FORMAT_R16_UNORM;
+ break;
+ case 4:
+ format = G80_SURFACE_FORMAT_BGRA8_UNORM;
+ break;
+ case 8:
+ format = G80_SURFACE_FORMAT_RGBA16_FLOAT;
+ break;
+ case 16:
+ format = G80_SURFACE_FORMAT_RGBA32_FLOAT;
+ break;
+ default:
+ assert(!"Unexpected cpp");
+ format = G80_SURFACE_FORMAT_R8_UNORM;
+ }
+
+ if (nouveau_bo_memtype(src->bo)) {
+ BEGIN_NV04(push, NV50_2D(SRC_FORMAT), 5);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, src->tile_mode);
+ PUSH_DATA (push, src->depth);
+ PUSH_DATA (push, src->z);
+ BEGIN_NV04(push, NV50_2D(SRC_WIDTH), 4);
+ PUSH_DATA (push, src->width);
+ PUSH_DATA (push, src->height);
+ PUSH_DATAh(push, src->bo->offset + src->base);
+ PUSH_DATA (push, src->bo->offset + src->base);
+ } else {
+ BEGIN_NV04(push, NV50_2D(SRC_FORMAT), 2);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(SRC_PITCH), 5);
+ PUSH_DATA (push, src->pitch);
+ PUSH_DATA (push, src->width);
+ PUSH_DATA (push, src->height);
+ PUSH_DATAh(push, src->bo->offset + src->base);
+ PUSH_DATA (push, src->bo->offset + src->base);
+ }
+
+ if (nouveau_bo_memtype(dst->bo)) {
+ BEGIN_NV04(push, NV50_2D(DST_FORMAT), 5);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, dst->tile_mode);
+ PUSH_DATA (push, dst->depth);
+ PUSH_DATA (push, dst->z);
+ BEGIN_NV04(push, NV50_2D(DST_WIDTH), 4);
+ PUSH_DATA (push, dst->width);
+ PUSH_DATA (push, dst->height);
+ PUSH_DATAh(push, dst->bo->offset + dst->base);
+ PUSH_DATA (push, dst->bo->offset + dst->base);
+ } else {
+ BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
+ PUSH_DATA (push, dst->pitch);
+ PUSH_DATA (push, dst->width);
+ PUSH_DATA (push, dst->height);
+ PUSH_DATAh(push, dst->bo->offset + dst->base);
+ PUSH_DATA (push, dst->bo->offset + dst->base);
+ }
+
+ BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
+ PUSH_DATA (push, NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE);
+ BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
+ PUSH_DATA (push, dst->x);
+ PUSH_DATA (push, dst->y);
+ PUSH_DATA (push, nblocksx);
+ PUSH_DATA (push, nblocksy);
+ BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, src->x);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, src->y);
+
+ nouveau_bufctx_reset(bctx, 0);
+}
+
void
nv50_m2mf_transfer_rect(struct nv50_context *nv50,
const struct nv50_m2mf_rect *dst,
@@ -68,6 +177,23 @@ nv50_m2mf_transfer_rect(struct nv50_context *nv50,
assert(dst->cpp == src->cpp);
+ /* Workaround: M2MF appears to break at the 64k boundary for tiled
+ * textures, which can really only happen with RGBA32 formats.
+ */
+ bool eng2d = false;
+ if (nouveau_bo_memtype(src->bo)) {
+ if (src->width * cpp > 65536)
+ eng2d = true;
+ }
+ if (nouveau_bo_memtype(dst->bo)) {
+ if (dst->width * cpp > 65536)
+ eng2d = true;
+ }
+ if (eng2d) {
+ nv50_2d_transfer_rect(nv50, dst, src, nblocksx, nblocksy);
+ return;
+ }
+
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
More information about the mesa-commit
mailing list