From 94405e9280a257cde38c89123470a840786647ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Wed, 13 Oct 2021 13:15:34 +0200 Subject: [PATCH] libdrm/iris: remove tiling short-cut Instead of ignoring the request, we store the tiling information and apply them when the buffer is mapped via 'MMAP_GTT'. issue #4380 --- repos/libports/src/lib/libdrm/ioctl_iris.cc | 100 ++++++++++++++++++-- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/repos/libports/src/lib/libdrm/ioctl_iris.cc b/repos/libports/src/lib/libdrm/ioctl_iris.cc index f2710baebc..bcd1c69476 100644 --- a/repos/libports/src/lib/libdrm/ioctl_iris.cc +++ b/repos/libports/src/lib/libdrm/ioctl_iris.cc @@ -177,6 +177,31 @@ struct Gpu::Buffer Genode::Dataspace_capability map_cap { }; Offset map_offset { 0 }; + struct Tiling + { + bool _valid; + uint32_t mode; + uint32_t stride; + uint32_t swizzle; + + Tiling(uint32_t mode, uint32_t stride, uint32_t swizzle) + : + _valid { true }, + mode { mode }, + stride { stride }, + swizzle { swizzle } + { } + + Tiling() + : + _valid { false }, mode { 0 }, stride { 0 }, swizzle { 0 } + { } + + bool valid() const { return _valid; } + }; + + Tiling tiling { }; + Gpu_virtual_address gpu_vaddr { }; Gpu::Sequence_number seqno { }; @@ -725,18 +750,42 @@ class Drm_call " offset: ", Genode::Hex(p->offset)); } - /* - * We always map a buffer when the tiling is set. Since Mesa - * sets the filing first and maps the buffer afterwards we might - * already have a mapping at this point. - */ - p->offset = _map_buffer(id); + bool successful = true; + try { + _buffer_space.apply(id, [&] (Buffer &b) { + + p->offset = _map_buffer(b); + if (p->offset == 0) { + successful = false; + return; + } + + /* + * Judging by iris mode == 0 is I915_TILING_NONE for + * which no fencing seems to be necessary. + */ + if (b.tiling.valid() && b.tiling.mode != 0) { + uint32_t const m = (b.tiling.stride << 16) | (b.tiling.mode == 1 ? 1 : 0); + successful = _gpu_session.set_tiling(b.id(), m); + } else { + successful = true; + } + + if (!successful) { + _unmap_buffer(b); + return; + } + + }); + } catch (Genode::Id_space::Unknown_id) { } if (verbose_ioctl) { Genode::error(__func__, ": ", "handle: ", id.value, - " offset: ", Genode::Hex(p->offset), " (mapped)"); + " offset: ", Genode::Hex(p->offset), + successful ? " (mapped)" : " (failed)"); } - return p->offset ? 0 : -1; + + return successful ? 0 : -1; } char const *_domain_name(uint32_t d) @@ -864,8 +913,33 @@ class Drm_call int _device_gem_set_tiling(void *arg) { - (void)arg; - return 0; + auto const p = reinterpret_cast(arg); + Gpu::Buffer_id const id { .value = p->handle }; + uint32_t const mode = p->tiling_mode; + uint32_t const stride = p->stride; + uint32_t const swizzle = p->swizzle_mode; + + if (verbose_ioctl) { + Genode::error(__func__, ": ", + "handle: ", id.value, " " + "mode: ", mode, " " + "stride: ", stride , " " + "swizzle: ", swizzle); + } + + bool ok = false; + try { + _buffer_space.apply(id, [&] (Buffer &b) { + + b.tiling = Gpu::Buffer::Tiling(mode, stride, swizzle); + ok = true; + + }); + } catch (Genode::Id_space::Unknown_id) { + Genode::error(__func__, ": invalid handle: ", id.value); + } + + return ok ? 0 : -1; } int _device_gem_sw_finish(void *) @@ -1334,6 +1408,12 @@ class Drm_call return; } + if (b.tiling.valid()) + b.tiling = Gpu::Buffer::Tiling(); + + if (b.map_cap.valid()) + _unmap_buffer(b); + b.buffer_attached.destruct(); found = true; });