Re: [RFC] amdgpu: Add a context flag to disable implicit sync

2024-08-19 Thread Bas Nieuwenhuizen
On Mon, Aug 19, 2024 at 4:51 PM Christian König <
ckoenig.leichtzumer...@gmail.com> wrote:

> Am 07.08.24 um 22:33 schrieb Bas Nieuwenhuizen:
>
> On Wed, Aug 7, 2024 at 10:25 PM Faith Ekstrand 
> wrote:
>
>> On Wed, Aug 7, 2024 at 2:23 PM Joshua Ashton  wrote:
>>
>>> I was thinking about this more recently. I was initially considering
>>> "maybe this should be a per-BO import," but I couldn't think of anything in
>>> the GL model that would actually benefit given its not "true" bindless and
>>> there's no update-after-bind there.
>>>
>>
>> That's also an option and it's the way it works on i915. However, then
>> you have to pass lists of things to the kernel and that's kinda gross. If
>> we need it, we can do that. Otherwise, I think a more global thing is
>> fine.  I think Bas is currently investigating a per-submit approach which
>> is a tad different from either but should also work okay.
>>
>>
>
> Yeah, I'm working on a per-submit thing (also using BOOKKEEP fences
> instead of using the EXPLICIT wait mode to ensure we also don't add
> implicit fences).
>
>
> Yeah agree. Your implementation with the per submission flag and using
> BOOKKEEP actually sounds like the right thing to do to me as well.
>
> We need to keep in mind that synchronization goes in both ways, e.g.
> explicit->implicit as well as implicit->explicit.
>
> I would rather like to keep the implicit->explicit handling (which this
> patch here completely disables) and only allow the explicit->implicit
> handling (which by using BOOKKEEP fences).
>
> This way it is possible that we still over synchronize for example for a
> double buffered BO is re-used by an explicit client and implicit display
> server, but that's probably not something we should optimize in the first
> place.
>

This oversynchronization actually happens easily as in bindless Vulkan we
have to mark all buffers as "used". We have some hacks to avoid the worst
of it but it can be pretty meh.

In my series on the ML[1] I think I actually got both sides by waiting on
KERNEL fences only and setting BOOKKEEP fences. (Yeah it actually ends up
kinda orthogonal on the sync mode but it is what it is ...).

- Bas

[1]https://patchwork.freedesktop.org/series/137014/


> Regards,
> Christian.
>
>
> We do have a per-BO list on submission already, so we could add things
> there, it is just very annoying to implement as currently at the point we
> do fence wait/signal we lost the association with the BO list. Given that
> I  don't see an use case anytime soon (there are some theoreticals like
> radeonsi might start doing READ usage instead of RW usage with extra
> tracking) I feel it isn't worth that added implementation complexity
>
>
> Worth others more familiar with GL asking that question to themselves
>>> also. I am definitely not totally up on what's possible there.
>>>
>>> Overall, I think I am OK with this approach, even though I think mixing
>>> implicit and explicit sync is gross, and I want the pain that is implicit
>>> sync to just go away forever. :-)
>>>
>>
>> So say we all...
>>
>> ~Faith
>>
>>
>>
>>> - Joshie 🐸✨
>>>
>>>
>>> On August 7, 2024 4:39:32 PM GMT+01:00, Faith Ekstrand <
>>> fa...@gfxstrand.net> wrote:
>>> >Previously, AMDGPU_GEM_CREATE_EXPLICIT_SYNC was used to disable implicit
>>> >synchronization on BOs when explicit synchronization can be used.  The
>>> >problem is that this flag is per-BO and affects all amdgpu users in the
>>> >system, not just the usermode drver which sets it.  This can lead to
>>> >some unintended consequences for userspace if not used carefully.
>>> >
>>> >Since the introduction of DMA_BUF_IOCTL_EXPORT_SYNC_FILE and
>>> >DMA_BUF_IOCTL_IMPORT_SYNC_FILE, many userspace window system components
>>> >have grown the ability to convert between the Vulkan explicit sync model
>>> >and the legacy implicit sync model used by X11 and Wayland in the past.
>>> >This allows both old and new components to exist simultaneously and talk
>>> >to each other.  In particular, XWayland is able to convert between the
>>> >two to let Vulkan apps work seamlessly with older X11 compositors that
>>> >aren't aware of explicit synchronizaiton.  This is rapidly becoming the
>>> >backbone of synchronization in the Linux window system space.
>>> >
>>> >Unfortunately, AMDGPU_GEM_CREATE_EXPLICIT_S

[PATCH] drm/amdgpu: Actually check flags for all context ops.

2024-08-06 Thread Bas Nieuwenhuizen
Missing validation ...

Checked libdrm and it clears all the structs, so we should be
safe to just check everything.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 5cb33ac99f70..c43d1b6e5d66 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -685,16 +685,24 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
 
switch (args->in.op) {
case AMDGPU_CTX_OP_ALLOC_CTX:
+   if (args->in.flags)
+   return -EINVAL;
r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
args->out.alloc.ctx_id = id;
break;
case AMDGPU_CTX_OP_FREE_CTX:
+   if (args->in.flags)
+   return -EINVAL;
r = amdgpu_ctx_free(fpriv, id);
break;
case AMDGPU_CTX_OP_QUERY_STATE:
+   if (args->in.flags)
+   return -EINVAL;
r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
break;
case AMDGPU_CTX_OP_QUERY_STATE2:
+   if (args->in.flags)
+   return -EINVAL;
r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
break;
case AMDGPU_CTX_OP_GET_STABLE_PSTATE:
-- 
2.45.2



Re: [PATCH] drm/amdgpu: Actually check flags for all context ops.

2024-08-07 Thread Bas Nieuwenhuizen
Yeah, I also found that one. Will send it out this evening if you don't get
to it.

On Wed, Aug 7, 2024, 5:03 PM Michel Dänzer 
wrote:

> On 2024-08-06 22:27, Bas Nieuwenhuizen wrote:
> > Missing validation ...
> >
> > Checked libdrm and it clears all the structs, so we should be
> > safe to just check everything.
>
> Thanks for fixing this.
>
> FWIW, amdgpu_cs_ioctl has the same issue AFAICT. Haven't checked any
> others, there might be more.
>
>
> --
> Earthling Michel Dänzer   \GNOME / Xwayland / Mesa developer
> https://redhat.com \   Libre software enthusiast
>
>


Re: [RFC] amdgpu: Add a context flag to disable implicit sync

2024-08-07 Thread Bas Nieuwenhuizen
-sync components.  This is the
>> >approach we've taken with NVK/nouveau, ANV/xe, and similar to the
>> >approach taken by ANV/i915 and it works well for those drivers.
>> >
>> >Ideally, I would like to see something like this back-ported to at least
>> >the kernel where DMA_BUF_IOCTL_IMPORT/EXPORT_SYNC_FILE were introduced
>> >so that we don't have to wait another year for the fix to reach users.
>> >However, I understand that back-porting UAPI is problematic and I'll
>> >leave that decision up to the amdgpu maintainers.  Michel suggested that
>> >a new CTX_OP would make more sense if we want to back-port it but the
>> >create flag made more sense to me from an API design PoV.
>> >
>> >Signed-off-by: Faith Ekstrand 
>> >Cc: Alex Deucher 
>> >Cc: Christian König 
>> >Cc: David Airlie 
>> >Cc: Michel Dänzer 
>> >Cc: Bas Nieuwenhuizen 
>> >---
>> > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  3 ++-
>> > drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 12 
>> > drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h |  7 +++
>> > include/uapi/drm/amdgpu_drm.h   | 12 +++-
>> > 4 files changed, 28 insertions(+), 6 deletions(-)
>> >
>> >diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> >index ec888fc6ead8..8410b4426541 100644
>> >--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> >+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> >@@ -1196,7 +1196,8 @@ static int amdgpu_cs_sync_rings(struct
>> amdgpu_cs_parser *p)
>> >   struct dma_resv *resv = bo->tbo.base.resv;
>> >   enum amdgpu_sync_mode sync_mode;
>> >
>> >-  sync_mode = amdgpu_bo_explicit_sync(bo) ?
>> >+  sync_mode = (amdgpu_ctx_explicit_sync(p->ctx) ||
>> >+   amdgpu_bo_explicit_sync(bo)) ?
>> >   AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
>> >   r = amdgpu_sync_resv(p->adev, &p->sync, resv, sync_mode,
>> >&fpriv->vm);
>> >diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
>> >index 5cb33ac99f70..a304740ccedf 100644
>> >--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
>> >+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
>> >@@ -318,7 +318,8 @@ static int amdgpu_ctx_get_stable_pstate(struct
>> amdgpu_ctx *ctx,
>> > }
>> >
>> > static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
>> >- struct drm_file *filp, struct amdgpu_ctx *ctx)
>> >+ uint32_t flags, struct drm_file *filp,
>> >+ struct amdgpu_ctx *ctx)
>> > {
>> >   struct amdgpu_fpriv *fpriv = filp->driver_priv;
>> >   u32 current_stable_pstate;
>> >@@ -334,6 +335,7 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr
>> *mgr, int32_t priority,
>> >   ctx->mgr = mgr;
>> >   spin_lock_init(&ctx->ring_lock);
>> >
>> >+  ctx->flags = flags;
>> >   ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
>> >   ctx->reset_counter_query = ctx->reset_counter;
>> >   ctx->generation = amdgpu_vm_generation(mgr->adev, &fpriv->vm);
>> >@@ -474,6 +476,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device
>> *adev,
>> >   struct amdgpu_fpriv *fpriv,
>> >   struct drm_file *filp,
>> >   int32_t priority,
>> >+  uint32_t flags,
>> >   uint32_t *id)
>> > {
>> >   struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
>> >@@ -493,7 +496,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device
>> *adev,
>> >   }
>> >
>> >   *id = (uint32_t)r;
>> >-  r = amdgpu_ctx_init(mgr, priority, filp, ctx);
>> >+  r = amdgpu_ctx_init(mgr, priority, flags, filp, ctx);
>> >   if (r) {
>> >   idr_remove(&mgr->ctx_handles, *id);
>> >   *id = 0;
>> >@@ -666,7 +669,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void
>> *data,
>> >struct drm_file *filp)
>> > {
>> >   int r;
>> >-  uint32_t id, stable_pstate;
>> &

[PATCH 0/6] Add submission flag to disable implicit sync.

2024-08-07 Thread Bas Nieuwenhuizen
For the rationale see the earlier RFC by Faith: 
https://lists.freedesktop.org/archives/amd-gfx/2024-August/112273.html

This mainly makes two changes:

1. Uses a submission flag rather than a context creation flag.
2. Uses DMA_RESV_USAGE_BOOKKEEP to avoid adding implicit fences still.

Note that this doesn't disable implicit sync wrt VM ops (map/unmap), I know we 
have series for that going around,
but I believe doing just submissions here is less involved and doesn't really 
complicate doing VM ops later.

As of now this has received a limited set of testing, no full CTS runs etc yet.

For Userspace see:

libdrm: 
https://gitlab.freedesktop.org/bnieuwenhuizen/drm/-/commits/basic-explicit-sync

mesa: 
https://gitlab.freedesktop.org/bnieuwenhuizen/mesa/-/commits/basic-explicit-sync

(Still missing a bunch of the version bumps & version checks, would like to 
postpone that till we know the actual version)

Bas Nieuwenhuizen (6):
  amdgpu: Add usage argument to amdgpu_sync_resv.
  amdgpu: Ignore BOOKKEEP fences for submissions.
  drm/amdgpu: Check cs flags.
  drm/amdgpu: Add UAPI for disabling implicit sync per submission.
  drm/amdgpu: Implement disabling implicit sync per submission.
  drm/amdgpu: Bump the driver version for the new flag.

 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 21 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h|  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c  |  7 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h  |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c   |  3 ++-
 include/uapi/drm/amdgpu_drm.h |  6 ++
 9 files changed, 37 insertions(+), 12 deletions(-)

-- 
2.45.2



[PATCH 1/6] amdgpu: Add usage argument to amdgpu_sync_resv.

2024-08-07 Thread Bas Nieuwenhuizen
Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   | 3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c   | 3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 7 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h | 4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c  | 3 ++-
 6 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 48ad0c04aa72..a5f517f18903 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1341,6 +1341,7 @@ static int process_sync_pds_resv(struct 
amdkfd_process_info *process_info,
struct amdgpu_bo *pd = peer_vm->root.bo;
 
ret = amdgpu_sync_resv(NULL, sync, pd->tbo.base.resv,
+  DMA_RESV_USAGE_BOOKKEEP,
   AMDGPU_SYNC_NE_OWNER,
   AMDGPU_FENCE_OWNER_KFD);
if (ret)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index ec888fc6ead8..a578da8e2da5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1198,7 +1198,8 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser 
*p)
 
sync_mode = amdgpu_bo_explicit_sync(bo) ?
AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
-   r = amdgpu_sync_resv(p->adev, &p->sync, resv, sync_mode,
+   r = amdgpu_sync_resv(p->adev, &p->sync, resv,
+DMA_RESV_USAGE_BOOKKEEP, sync_mode,
 &fpriv->vm);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index c556c8b653fa..66d666c03aed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -1484,7 +1484,8 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, 
struct dma_resv *resv,
int r;
 
amdgpu_sync_create(&sync);
-   amdgpu_sync_resv(adev, &sync, resv, sync_mode, owner);
+   amdgpu_sync_resv(adev, &sync, resv, DMA_RESV_USAGE_BOOKKEEP, sync_mode,
+owner);
r = amdgpu_sync_wait(&sync, intr);
amdgpu_sync_free(&sync);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index bdf1ef825d89..429602d6b65a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -233,8 +233,8 @@ static bool amdgpu_sync_test_fence(struct amdgpu_device 
*adev,
  * Sync to the fence
  */
 int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
-struct dma_resv *resv, enum amdgpu_sync_mode mode,
-void *owner)
+struct dma_resv *resv, enum dma_resv_usage usage,
+enum amdgpu_sync_mode mode, void *owner)
 {
struct dma_resv_iter cursor;
struct dma_fence *f;
@@ -243,8 +243,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct 
amdgpu_sync *sync,
if (resv == NULL)
return -EINVAL;
 
-   /* TODO: Use DMA_RESV_USAGE_READ here */
-   dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_BOOKKEEP, f) {
+   dma_resv_for_each_fence(&cursor, resv, usage, f) {
dma_fence_chain_for_each(f, f) {
struct dma_fence *tmp = dma_fence_chain_contained(f);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
index cf1e9e858efd..a6fa8e1e8e17 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
@@ -49,8 +49,8 @@ struct amdgpu_sync {
 void amdgpu_sync_create(struct amdgpu_sync *sync);
 int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f);
 int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
-struct dma_resv *resv, enum amdgpu_sync_mode mode,
-void *owner);
+struct dma_resv *resv, enum dma_resv_usage usage,
+enum amdgpu_sync_mode mode, void *owner);
 struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
 struct amdgpu_ring *ring);
 struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 66e8a016126b..259c241f55a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -98,7 +98,8 @@ stat

[PATCH 2/6] amdgpu: Ignore BOOKKEEP fences for submissions.

2024-08-07 Thread Bas Nieuwenhuizen
Should be safe to do. Writers of BOOKKEEP fences:

- amdgpu_vm_tlb_flush: Per the comments, only to prevent frees.

- amdgpu_vm_sdma_commit: Uses AMDGPU_FENCE_OWNER_VM, which was
   already ignored by amdgpu_sync_test_fence for cs submissions.

- amdgpu_amdkfd_remove_eviction_fence: Adds a stub fence, so always
   signaled.

- amdgpu_amdkfd_bo_validate_and_fence: This is used for eviction
   fences which shouldn't interact with amdgpu userspace submissions,
   as we detect owner as AMDGPU_FENCE_OWNER_KFD and then it should be
   ignored by amdgpu_sync_test_fence for userspace submissions.

I've done this for just submissions instead of all dma_sync_resv
users as there are some that need to wait for BOOKKEEP fences, at
least for now, like the VM update operations.

(Yes, I know there is a series to make VM updates less implicit,
 which currently works through AMDGPU_SYNC_EQ_OWNER/EXPLICIT. I
 think this doesn't conflict and would like to leave the VM side
 out of it as much as possible in this series to land something
 to resolve some radv/radeonsi issues for cross process sharing)

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index a578da8e2da5..b4f55f40ce0e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1199,7 +1199,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser 
*p)
sync_mode = amdgpu_bo_explicit_sync(bo) ?
AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
r = amdgpu_sync_resv(p->adev, &p->sync, resv,
-DMA_RESV_USAGE_BOOKKEEP, sync_mode,
+DMA_RESV_USAGE_READ, sync_mode,
 &fpriv->vm);
if (r)
return r;
-- 
2.45.2



[PATCH 4/6] drm/amdgpu: Add UAPI for disabling implicit sync per submission.

2024-08-07 Thread Bas Nieuwenhuizen
Per submission flag because:

1) Slightly simpler & more flexible than per context flag.
2) We'd need to extend the per-BO struct if we want to put
   it there.
3) Doing it per BO is annoying implementation wise as we
   disassociate it from the BO list before doing the fences.
4) I don't really anticipate an usecase for doing it per BO.
   (e.g. I don't think we need to selectively do implicit in
radv and I don't see radeonsi tracking READ vs. WRITE at
this point.)

Signed-off-by: Bas Nieuwenhuizen 
---
 include/uapi/drm/amdgpu_drm.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 96e32dafd4f0..d91fa707575c 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -610,6 +610,12 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 #define AMDGPU_CHUNK_ID_CP_GFX_SHADOW   0x0a
 
+
+#define AMDGPU_CS_FLAGS_MASK   0x1
+/* Disable implicit sync on BOs wrt other
+ * submissions. */
+#define AMDGPU_CS_NO_IMPLICIT_SYNC 1
+
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
__u32   length_dw;
-- 
2.45.2



[PATCH 3/6] drm/amdgpu: Check cs flags.

2024-08-07 Thread Bas Nieuwenhuizen
Had no validation before. libdrm_amdgpu memsets this, even
for the raw/raw2 functions.

We have a lot of functions touching the ioctl struct, no
strong opinion on where this is placed, but I thought
early would be good.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index b4f55f40ce0e..8d6f42e308fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -185,6 +185,9 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
int ret;
int i;
 
+   if (cs->in.flags)
+   return -EINVAL;
+
chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t),
 GFP_KERNEL);
if (!chunk_array)
-- 
2.45.2



[PATCH 5/6] drm/amdgpu: Implement disabling implicit sync per submission.

2024-08-07 Thread Bas Nieuwenhuizen
Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 21 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h |  1 +
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 8d6f42e308fb..e1ba48644a0c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -185,9 +185,11 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
int ret;
int i;
 
-   if (cs->in.flags)
+   if (cs->in.flags & ~AMDGPU_CS_FLAGS_MASK)
return -EINVAL;
 
+   p->flags = cs->in.flags;
+
chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t),
 GFP_KERNEL);
if (!chunk_array)
@@ -1194,15 +1196,18 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser 
*p)
}
 
drm_exec_for_each_locked_object(&p->exec, index, obj) {
+   enum dma_resv_usage usage = DMA_RESV_USAGE_READ;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 
struct dma_resv *resv = bo->tbo.base.resv;
enum amdgpu_sync_mode sync_mode;
 
+   if (p->flags & AMDGPU_CS_NO_IMPLICIT_SYNC)
+   usage = DMA_RESV_USAGE_KERNEL;
+
sync_mode = amdgpu_bo_explicit_sync(bo) ?
AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
-   r = amdgpu_sync_resv(p->adev, &p->sync, resv,
-DMA_RESV_USAGE_READ, sync_mode,
+   r = amdgpu_sync_resv(p->adev, &p->sync, resv, usage, sync_mode,
 &fpriv->vm);
if (r)
return r;
@@ -1259,6 +1264,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 {
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_job *leader = p->gang_leader;
+   enum dma_resv_usage read_usage = DMA_RESV_USAGE_READ;
+   enum dma_resv_usage write_usage = DMA_RESV_USAGE_WRITE;
struct amdgpu_bo_list_entry *e;
struct drm_gem_object *gobj;
unsigned long index;
@@ -1310,6 +1317,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
return r;
}
 
+   if (p->flags & AMDGPU_CS_NO_IMPLICIT_SYNC) {
+   read_usage = write_usage = DMA_RESV_USAGE_BOOKKEEP;
+   }
+
p->fence = dma_fence_get(&leader->base.s_fence->finished);
drm_exec_for_each_locked_object(&p->exec, index, gobj) {
 
@@ -1322,11 +1333,11 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
dma_resv_add_fence(gobj->resv,
   &p->jobs[i]->base.s_fence->finished,
-  DMA_RESV_USAGE_READ);
+  read_usage);
}
 
/* The gang leader as remembered as writer */
-   dma_resv_add_fence(gobj->resv, p->fence, DMA_RESV_USAGE_WRITE);
+   dma_resv_add_fence(gobj->resv, p->fence, write_usage);
}
 
seq = amdgpu_ctx_add_fence(p->ctx, p->entities[p->gang_leader_idx],
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h
index 39c33ad100cb..683c6eca4f1a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h
@@ -50,6 +50,7 @@ struct amdgpu_cs_parser {
struct amdgpu_device*adev;
struct drm_file *filp;
struct amdgpu_ctx   *ctx;
+   uint32_tflags;
 
/* chunks */
unsignednchunks;
-- 
2.45.2



[PATCH 6/6] drm/amdgpu: Bump the driver version for the new flag.

2024-08-07 Thread Bas Nieuwenhuizen
AMDGPU_CS_NO_IMPLICIT_SYNC.

Probably wildly out of date because amd-staging-drm-next
didn't boot for me.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index ea14f1c8f430..bf36b7d8929f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -116,9 +116,10 @@
  * - 3.55.0 - Add AMDGPU_INFO_GPUVM_FAULT query
  * - 3.56.0 - Update IB start address and size alignment for decode and encode
  * - 3.57.0 - Compute tunneling on GFX10+
+ * - 3.58.0 - Support AMDGPU_CS_NO_IMPLICIT_SYNC.
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   57
+#define KMS_DRIVER_MINOR   58
 #define KMS_DRIVER_PATCHLEVEL  0
 
 /*
-- 
2.45.2



Re: [PATCH 2/2] drm/amdgpu: Mark ctx as guilty in ring_soft_recovery path

2024-01-15 Thread Bas Nieuwenhuizen
On Mon, Jan 15, 2024 at 7:14 PM Friedrich Vock 
wrote:

> Re-sending as plaintext, sorry about that
>
> On 15.01.24 18:54, Michel Dänzer wrote:
> > On 2024-01-15 18:26, Friedrich Vock wrote:
> >> [snip]
> >> The fundamental problem here is that not telling applications that
> >> something went wrong when you just canceled their work midway is an
> >> out-of-spec hack.
> >> When there is a report of real-world apps breaking because of that hack,
> >> reports of different apps working (even if it's convenient that they
> >> work) doesn't justify keeping the broken code.
> > If the breaking apps hit multiple soft resets in a row, I've laid out a
> pragmatic solution which covers both cases.
> Hitting soft reset every time is the lucky path. Once GPU work is
> interrupted out of nowhere, all bets are off and it might as well
> trigger a full system hang next time. No hang recovery should be able to
> cause that under any circumstance.
>

I think the more insidious situation is no further hangs but wrong results
because we skipped some work. That we skipped work may e.g. result in some
texture not being uploaded or some GPGPU work not being done and causing
further errors downstream (say if a game is doing AI/physics on the GPU not
to say anything of actual GPGPU work one might be doing like AI)


> >
> >
> >> If mutter needs to be robust against faults it caused itself, it should
> be robust
> >> against GPU resets.
> > It's unlikely that the hangs I've seen were caused by mutter itself,
> more likely Mesa or amdgpu.
> >
> > Anyway, this will happen at some point, the reality is it hasn't yet
> though.
> >
> >
>


Re: [PATCH 3/3] drm/amd/display: Add modifiers capable of DCC image stores for gfx10_3

2021-09-15 Thread Bas Nieuwenhuizen
On Thu, Sep 16, 2021, 2:12 AM Marek Olšák  wrote:

> Based on the discussions we had about displayable DCC internally, only
> MAX_COMPRESSED_BLOCK = 64B with both DCC_INDEPENDENT_64B_BLOCKS and
> DCC_INDEPENDENT_128B_BLOCKS is supported by DCN on RDNA 2.
>
> Is there something new on the hardware side that I missed?
>

Per the comments you put in mesa that was only needed for 4k?

https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/amd/common/ac_surface.c#L1444


> Marek
>
> On Tue, Sep 14, 2021 at 7:59 PM Joshua Ashton  wrote:
>
>> Some games, ie. Doom Eternal, present from compute following compute
>> post-fx and would benefit from having DCC image stores available.
>>
>> DCN on gfx10_3 doesn't need INDEPENDENT_128B_BLOCKS = 0 so we can expose
>> these modifiers capable of DCC image stores.
>>
>> Signed-off-by: Joshua Ashton 
>> Reviewed-by: Bas Nieuwenhuizen 
>> ---
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +++
>>  1 file changed, 21 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 2a24e43623cb..a4e33a4336a0 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -4817,6 +4817,16 @@ add_gfx10_3_modifiers(const struct amdgpu_device
>> *adev,
>> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
>> AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
>> AMD_FMT_MOD_DCC_BLOCK_64B));
>>
>> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
>> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
>> +   AMD_FMT_MOD_SET(TILE_VERSION,
>> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
>> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
>> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
>> +   AMD_FMT_MOD_SET(DCC, 1) |
>> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
>> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
>> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
>> AMD_FMT_MOD_DCC_BLOCK_128B));
>> +
>> add_modifier(mods, size, capacity, AMD_FMT_MOD |
>> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
>> AMD_FMT_MOD_SET(TILE_VERSION,
>> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
>> @@ -4829,6 +4839,17 @@ add_gfx10_3_modifiers(const struct amdgpu_device
>> *adev,
>> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
>> AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
>> AMD_FMT_MOD_DCC_BLOCK_64B));
>>
>> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
>> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
>> +   AMD_FMT_MOD_SET(TILE_VERSION,
>> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
>> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
>> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
>> +   AMD_FMT_MOD_SET(DCC, 1) |
>> +   AMD_FMT_MOD_SET(DCC_RETILE, 1) |
>> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
>> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
>> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
>> AMD_FMT_MOD_DCC_BLOCK_128B));
>> +
>> add_modifier(mods, size, capacity, AMD_FMT_MOD |
>> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
>> AMD_FMT_MOD_SET(TILE_VERSION,
>> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
>> --
>> 2.33.0
>>
>>


Re: [PATCH] drm/amdgpu: Ensure that the modifier requested is supported by plane.

2021-03-23 Thread Bas Nieuwenhuizen
On Wed, Mar 10, 2021 at 5:14 PM Mark Yacoub  wrote:

> From: Mark Yacoub 
>
> On initializing the framebuffer, call drm_any_plane_has_format to do a
> check if the modifier is supported. drm_any_plane_has_format calls
> dm_plane_format_mod_supported which is extended to validate that the
> modifier is on the list of the plane's supported modifiers.
>
> The bug was caught using igt-gpu-tools test:
> kms_addfb_basic.addfb25-bad-modifier
>
> Tested on ChromeOS Zork by turning on the display, running an overlay
> test, and running a YT video.
>
> Cc: Alex Deucher 
> Cc: Bas Nieuwenhuizen 
> Signed-off-by: default avatarMark Yacoub 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 13 +
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index afa5f8ad0f563..a947b5aa420d2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
>  &amdgpu_fb_funcs);
> if (ret)
> goto err;
> +   /* Verify that the modifier is supported. */
> +   if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
> + mode_cmd->modifier[0])) {
> +   struct drm_format_name_buf format_name;
> +   drm_dbg_kms(dev,
> +   "unsupported pixel format %s / modifier
> 0x%llx\n",
> +   drm_get_format_name(mode_cmd->pixel_format,
> +   &format_name),
> +   mode_cmd->modifier[0]);
> +
> +   ret = -EINVAL;
> +   goto err;
> +   }
>

Why is this needed?


> ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
> if (ret)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 961abf1cf040c..21314024a83ce 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
>  {
> struct amdgpu_device *adev = drm_to_adev(plane->dev);
> const struct drm_format_info *info = drm_format_info(format);
> +   int i;
>
> enum dm_micro_swizzle microtile =
> modifier_gfx9_swizzle_mode(modifier) & 3;
>
> @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
> if (modifier == DRM_FORMAT_MOD_LINEAR)
> return true;
>
> +   /* Check that the modifier is on the list of the plane's supported
> modifiers. */
> +   for (i = 0; i < plane->modifier_count; i++) {
> +   if (modifier == plane->modifiers[i])
> +   break;
> +   }
> +   if (i == plane->modifier_count)
> +   return false;
> +
>

This part seems fine by me.

> /*
>  * The arbitrary tiling support for multiplane formats has not
> been hooked
>  * up.
> --
> 2.30.1.766.gb4fecdf3b7-goog
>
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amdgpu: Ensure that the modifier requested is supported by plane.

2021-03-24 Thread Bas Nieuwenhuizen
On Wed, Mar 24, 2021 at 11:13 AM Michel Dänzer  wrote:

> On 2021-03-23 4:32 p.m., Mark Yacoub wrote:
> > On Tue, Mar 23, 2021 at 11:02 AM Alex Deucher 
> wrote:
> >>
> >> On Wed, Mar 10, 2021 at 11:15 AM Mark Yacoub 
> wrote:
> >>>
> >>> From: Mark Yacoub 
> >>>
> >>> On initializing the framebuffer, call drm_any_plane_has_format to do a
> >>> check if the modifier is supported. drm_any_plane_has_format calls
> >>> dm_plane_format_mod_supported which is extended to validate that the
> >>> modifier is on the list of the plane's supported modifiers.
> >>>
> >>> The bug was caught using igt-gpu-tools test:
> kms_addfb_basic.addfb25-bad-modifier
> >>>
> >>> Tested on ChromeOS Zork by turning on the display, running an overlay
> >>> test, and running a YT video.
> >>>
> >>> Cc: Alex Deucher 
> >>> Cc: Bas Nieuwenhuizen 
> >>> Signed-off-by: default avatarMark Yacoub 
> >>
> >> I'm not an expert with modifiers yet.  Will this break chips which
> >> don't currently support modifiers?
> > No it shouldn't. When you don't support modifiers yet, your will
> > default to Linear Modifier (DRM_FORMAT_MOD_LINEAR),
> > [...]
> No modifier support does not imply linear. It's generally signalled via
> DRM_FORMAT_MOD_INVALID, which roughly means "tiling is determined by driver
> specific mechanisms".
>

Doesn't quite work that way in the kernel sadly. If you don't set
DRM_MODE_FB_MODIFIERS then the modifier fields have to be 0 (which happens
to alias DRM_FORMAT_MOD_LINEAR and then now deprecated
DRM_FORMAT_MOD_NONE). This is verified in shared drm code.

(and all userspace code I've seen simply doesn't set DRM_MODE_FB_MODIFIERS
if the incoming modifier is DRM_FORMAT_MOD_INVALID)

>
>
> --
> Earthling Michel Dänzer   |   https://redhat.com
> Libre software enthusiast | Mesa and X developer
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: amd/display: allow non-linear multi-planar formats

2021-04-11 Thread Bas Nieuwenhuizen
Reviewed-by: Bas Nieuwenhuizen 

On Fri, Apr 9, 2021 at 3:19 PM Simon Ser  wrote:

> Hi,
>
> Can you have a look at this patch?
>
> Thanks,
>
> Simon
>
> On Friday, March 26th, 2021 at 5:59 PM, Simon Ser 
> wrote:
>
> > Accept non-linear buffers which use a multi-planar format, as long
> > as they don't use DCC.
> >
> > Tested on GFX9 with NV12.
> >
> > Signed-off-by: Simon Ser 
> > Cc: Alex Deucher 
> > Cc: Harry Wentland 
> > Cc: Nicholas Kazlauskas 
> > Cc: Bas Nieuwenhuizen 
> > ---
> >  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ---
> >  1 file changed, 4 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 36ee52104007..66e3ecf123d1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -4216,13 +4216,6 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
> >   if (modifier == DRM_FORMAT_MOD_LINEAR)
> >   return true;
> >
> > - /*
> > -  * The arbitrary tiling support for multiplane formats has not
> been hooked
> > -  * up.
> > -  */
> > - if (info->num_planes > 1)
> > - return false;
> > -
> >   /*
> >* For D swizzle the canonical modifier depends on the bpp, so
> check
> >* it here.
> > @@ -4241,6 +4234,10 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
> >   /* Per radeonsi comments 16/64 bpp are more complicated. */
> >   if (info->cpp[0] != 4)
> >   return false;
> > + /* We support multi-planar formats, but not when combined
> with
> > +  * additional DCC metadata planes. */
> > + if (info->num_planes > 1)
> > + return false;
> >   }
> >
> >   return true;
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/2] drm/amd/display: Update modifier list for gfx10_3

2021-04-15 Thread Bas Nieuwenhuizen
On Thu, Apr 15, 2021 at 1:35 AM Qingqing Zhuo  wrote:

> [Why]
> Current list only includes modifiers where DCC_MAX_COMPRESSED_BLOCK
> is set to AMD_FMT_MOD_DCC_BLOCK_128B, while AMD_FMT_MOD_DCC_BLOCK_64B
> is also supported and used by userspace.
>
> [How]
> Add AMD_FMT_MOD_DCC_BLOCK_64B to modifiers with DCC supported.
>
> Signed-off-by: Qingqing Zhuo 
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index e29cb2e956db..c3cbc3d298e7 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4535,6 +4535,17 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> int pipe_xor_bits =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
> int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
>
> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> +   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> +   AMD_FMT_MOD_SET(DCC, 1) |
> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
>

Thanks for finding this issue. Looking at it it looks to me like the
original entries are mistaken. Can we just change the
DCC_MAX_COMPRESSED_BLOCK in the already existing DCC entries? Looks like
Mesa always uses the AMD_FMT_MOD_DCC_BLOCK_64B anyway, and I don't think
DCC_INDEPENDENT_64B=1 + DCC_MAX_COMPRESSED_BLOCK=AMD_FMT_MOD_DCC_BLOCK_128B
makes sense.

+
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> @@ -4546,6 +4557,18 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
>
> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> +   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> +   AMD_FMT_MOD_SET(DCC, 1) |
> +   AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
> +
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> --
> 2.17.1
>
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/2] drm/amd/display: Update modifier list for gfx10_3

2021-04-15 Thread Bas Nieuwenhuizen
Btw please add a fixes tag so it gets directed to stable releases.

Thanks!

On Thu, Apr 15, 2021, 6:06 PM Zhuo, Qingqing  wrote:

> [AMD Public Use]
>
>
>
> Inline.
>
>
>
> *From:* Bas Nieuwenhuizen 
> *Sent:* Thursday, April 15, 2021 7:26 AM
> *To:* Zhuo, Qingqing 
> *Cc:* amd-gfx mailing list ; Mark Yacoub <
> markyac...@chromium.org>; Deucher, Alexander ;
> Wheeler, Daniel ; Siqueira, Rodrigo <
> rodrigo.sique...@amd.com>; Kazlauskas, Nicholas <
> nicholas.kazlaus...@amd.com>
> *Subject:* Re: [PATCH 1/2] drm/amd/display: Update modifier list for
> gfx10_3
>
>
>
>
>
>
>
> On Thu, Apr 15, 2021 at 1:35 AM Qingqing Zhuo 
> wrote:
>
> [Why]
> Current list only includes modifiers where DCC_MAX_COMPRESSED_BLOCK
> is set to AMD_FMT_MOD_DCC_BLOCK_128B, while AMD_FMT_MOD_DCC_BLOCK_64B
> is also supported and used by userspace.
>
> [How]
> Add AMD_FMT_MOD_DCC_BLOCK_64B to modifiers with DCC supported.
>
> Signed-off-by: Qingqing Zhuo 
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index e29cb2e956db..c3cbc3d298e7 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4535,6 +4535,17 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> int pipe_xor_bits =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
> int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
>
> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> +   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> +   AMD_FMT_MOD_SET(DCC, 1) |
> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
>
>
>
> Thanks for finding this issue. Looking at it it looks to me like the
> original entries are mistaken. Can we just change the
> DCC_MAX_COMPRESSED_BLOCK in the already existing DCC entries? Looks like
> Mesa always uses the AMD_FMT_MOD_DCC_BLOCK_64B anyway, and I don't think
> DCC_INDEPENDENT_64B=1 + DCC_MAX_COMPRESSED_BLOCK=AMD_FMT_MOD_DCC_BLOCK_128B
> makes sense.
>
>
>
> Thanks for the suggestion. Will send out an updated version soon.
>
>
>
> +
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> @@ -4546,6 +4557,18 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
>
> +   add_modifier(mods, size, capacity, AMD_FMT_MOD |
> +   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> +   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> +   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> +   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> +   AMD_FMT_MOD_SET(DCC, 1) |
> +   AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> +   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> +   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
> +
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> --
> 2.17.1
>
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH v2] drm/amd/display: Update modifier list for gfx10_3

2021-04-15 Thread Bas Nieuwenhuizen
Reviewed-by: Bas Nieuwenhuizen 
Tested-by: Bas Nieuwenhuizen 

(Checked that Weston on SIENNA_CICHLID now gets DCC)

Thanks!

On Thu, Apr 15, 2021 at 7:35 PM Qingqing Zhuo  wrote:

> [Why]
> Current list supports modifiers that have DCC_MAX_COMPRESSED_BLOCK
> set to AMD_FMT_MOD_DCC_BLOCK_128B, while AMD_FMT_MOD_DCC_BLOCK_64B
> is used instead by userspace.
>
> [How]
> Replace AMD_FMT_MOD_DCC_BLOCK_128B with AMD_FMT_MOD_DCC_BLOCK_64B
> for modifiers with DCC supported.
>
> Fixes: 91e54fd70c6a ("drm/amd/display: Expose modifiers")
> Signed-off-by: Qingqing Zhuo 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index e29cb2e956db..9fded25d2363 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4544,7 +4544,7 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> -   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
>
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> @@ -4556,7 +4556,7 @@ add_gfx10_3_modifiers(const struct amdgpu_device
> *adev,
> AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> -   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
> +   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
>
> add_modifier(mods, size, capacity, AMD_FMT_MOD |
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> --
> 2.17.1
>
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH] Revert "drm/amdgpu: Verify bo size can fit framebuffer size on init."

2021-04-29 Thread Bas Nieuwenhuizen
This reverts commit f258907fdd835e1aed6d666b00cdd0f186676b7c.

Same problem as "drm/amdgpu: Verify bo size can fit framebuffer size",
but because it gets checked earlier it now only triggers on the
modifiers case.

There are a couple of reasons why the DRM core BO size check won't
work for AMDGPU, especially around DCC planes.

Signed-off-by: Bas Nieuwenhuizen 
---

For -fixes. Might have some conflicts with
"drm/amdgpu: Ensure that the modifier requested is supported by plane"
for amd-staging-drm-next

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 68 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c  |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h|  8 ---
 3 files changed, 15 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 9a2f811450ed..cbe050436c7b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -870,62 +870,17 @@ static int amdgpu_display_get_fb_info(const struct 
amdgpu_framebuffer *amdgpu_fb
return r;
 }
 
-int amdgpu_display_gem_fb_init(struct drm_device *dev,
-  struct amdgpu_framebuffer *rfb,
-  const struct drm_mode_fb_cmd2 *mode_cmd,
-  struct drm_gem_object *obj)
-{
-   int ret;
-
-   rfb->base.obj[0] = obj;
-   drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
-   ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
-   if (ret)
-   goto err;
-
-   ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
-   if (ret)
-   goto err;
-
-   return 0;
-err:
-   drm_err(dev, "Failed to init gem fb: %d\n", ret);
-   rfb->base.obj[0] = NULL;
-   return ret;
-}
-
-int amdgpu_display_gem_fb_verify_and_init(
-   struct drm_device *dev, struct amdgpu_framebuffer *rfb,
-   struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
-   struct drm_gem_object *obj)
-{
-   int ret;
-
-   rfb->base.obj[0] = obj;
-
-   /* Verify that bo size can fit the fb size. */
-   ret = drm_gem_fb_init_with_funcs(dev, &rfb->base, file_priv, mode_cmd,
-&amdgpu_fb_funcs);
-   if (ret)
-   goto err;
-
-   ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
-   if (ret)
-   goto err;
-
-   return 0;
-err:
-   drm_err(dev, "Failed to verify and init gem fb: %d\n", ret);
-   rfb->base.obj[0] = NULL;
-   return ret;
-}
-
 int amdgpu_display_framebuffer_init(struct drm_device *dev,
struct amdgpu_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
 {
int ret, i;
+   rfb->base.obj[0] = obj;
+   drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
+   ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
+   if (ret)
+   goto fail;
 
/*
 * This needs to happen before modifier conversion as that might change
@@ -936,13 +891,13 @@ int amdgpu_display_framebuffer_init(struct drm_device 
*dev,
drm_dbg_kms(dev, "Plane 0 and %d have different BOs: %u 
vs. %u\n",
i, mode_cmd->handles[0], 
mode_cmd->handles[i]);
ret = -EINVAL;
-   return ret;
+   goto fail;
}
}
 
ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, 
&rfb->tmz_surface);
if (ret)
-   return ret;
+   goto fail;
 
if (dev->mode_config.allow_fb_modifiers &&
!(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
@@ -950,7 +905,7 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
if (ret) {
drm_dbg_kms(dev, "Failed to convert tiling flags 0x%llX 
to a modifier",
rfb->tiling_flags);
-   return ret;
+   goto fail;
}
}
 
@@ -961,6 +916,10 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
}
 
return 0;
+
+fail:
+   rfb->base.obj[0] = NULL;
+   return ret;
 }
 
 struct drm_framebuffer *
@@ -995,8 +954,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device 
*dev,
return ERR_PTR(-ENOMEM);
}
 
-   ret = amdgpu_display_gem_fb_verify_and_init(dev, amdgpu_fb, file_priv,
-   mode_cmd, obj);
+   ret = amdgpu_display_framebuffer_init(dev, amdgpu_fb, mode_

Re: [PATCH] Revert "drm/amdgpu: Verify bo size can fit framebuffer size on init."

2021-04-29 Thread Bas Nieuwenhuizen
On Thu, Apr 29, 2021 at 11:27 PM Mark Yacoub  wrote:
>
> On Thu, Apr 29, 2021 at 4:50 PM Bas Nieuwenhuizen
>  wrote:
> >
> > This reverts commit f258907fdd835e1aed6d666b00cdd0f186676b7c.
> >
> > Same problem as "drm/amdgpu: Verify bo size can fit framebuffer size",
> > but because it gets checked earlier it now only triggers on the
> > modifiers case.
> >
> > There are a couple of reasons why the DRM core BO size check won't
> > work for AMDGPU, especially around DCC planes.
> >
> Can you tell us more about those reasons? Last time this was reverted
> due to a failure on ubuntu was due to a userspace bug that was fixed.
> So I'm thinking we might wanna fix what broke instead of removing the
> check.

Agree on having the check in the end, just wasn't sure if fixes (or
when I started looking at it, I thought stable) was the right place
given some of the tiling complexity.

So the core problems:

1) In the format structs we don't do set any of the tilesize / blocks
etc. to avoid having format arrays per modifier/GPU
2) The pitch on the main plane is pixel_pitch * bytes_per_pixel even
for tiled ...
3) The pitch for the DCC planes is really the pixel pitch of the main
surface that would be covered by it ...

1 is changeable by refactoring but sadly 2 and 3 are hard to change by
now (would need to bump the modifier version). And all 3 mean that the
default computation in the core drm helper is not the right check for
BO size.

> > Signed-off-by: Bas Nieuwenhuizen 
> > ---
> >
> > For -fixes. Might have some conflicts with
> > "drm/amdgpu: Ensure that the modifier requested is supported by plane"
> > for amd-staging-drm-next
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 68 -
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c  |  4 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h|  8 ---
> >  3 files changed, 15 insertions(+), 65 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 9a2f811450ed..cbe050436c7b 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -870,62 +870,17 @@ static int amdgpu_display_get_fb_info(const struct 
> > amdgpu_framebuffer *amdgpu_fb
> > return r;
> >  }
> >
> > -int amdgpu_display_gem_fb_init(struct drm_device *dev,
> > -  struct amdgpu_framebuffer *rfb,
> > -  const struct drm_mode_fb_cmd2 *mode_cmd,
> > -  struct drm_gem_object *obj)
> > -{
> > -   int ret;
> > -
> > -   rfb->base.obj[0] = obj;
> > -   drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
> > -   ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
> > -   if (ret)
> > -   goto err;
> > -
> > -   ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
> > -   if (ret)
> > -   goto err;
> > -
> > -   return 0;
> > -err:
> > -   drm_err(dev, "Failed to init gem fb: %d\n", ret);
> > -   rfb->base.obj[0] = NULL;
> > -   return ret;
> > -}
> > -
> > -int amdgpu_display_gem_fb_verify_and_init(
> > -   struct drm_device *dev, struct amdgpu_framebuffer *rfb,
> > -   struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
> > -   struct drm_gem_object *obj)
> > -{
> > -   int ret;
> > -
> > -   rfb->base.obj[0] = obj;
> > -
> > -   /* Verify that bo size can fit the fb size. */
> > -   ret = drm_gem_fb_init_with_funcs(dev, &rfb->base, file_priv, 
> > mode_cmd,
> > -&amdgpu_fb_funcs);
> > -   if (ret)
> > -   goto err;
> > -
> > -   ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
> > -   if (ret)
> > -   goto err;
> > -
> > -   return 0;
> > -err:
> > -   drm_err(dev, "Failed to verify and init gem fb: %d\n", ret);
> > -   rfb->base.obj[0] = NULL;
> > -   return ret;
> > -}
> > -
> >  int amdgpu_display_framebuffer_init(struct drm_device *dev,
> > struct amdgpu_framebuffer *rfb,
> > const struct drm_mode_fb_cmd2 *mode_cmd,
> > struct drm_gem_object *obj)
> >

[PATCH] drm/amdgpu: Use device specific BO size & stride check.

2021-05-04 Thread Bas Nieuwenhuizen
The builtin size check isn't really the right thing for AMD
modifiers due to a couple of reasons:

1) In the format structs we don't do set any of the tilesize / blocks
etc. to avoid having format arrays per modifier/GPU
2) The pitch on the main plane is pixel_pitch * bytes_per_pixel even
for tiled ...
3) The pitch for the DCC planes is really the pixel pitch of the main
surface that would be covered by it ...

Note that we only handle GFX9+ case but we do this after converting
the implicit modifier to an explicit modifier, so on GFX9+ all
framebuffers should be checked here.

There is a TODO about DCC alignment, but it isn't worse than before
and I'd need to dig a bunch into the specifics. Getting this out in
a reasonable timeframe to make sure it gets the appropriate testing
seemed more important.

Finally as I've found that debugging addfb2 failures is a pita I was
generous adding explicit error messages to every failure case.

Fixes: f258907fdd83 ("drm/amdgpu: Verify bo size can fit framebuffer size on 
init.")
Signed-off-by: Bas Nieuwenhuizen 
---

For drm-fixes, replaces the 'Revert "drm/amdgpu: Verify bo size can fit 
framebuffer size on init."'
revert on the ML, intended for -fixes.
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 181 +++-
 1 file changed, 175 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2e622c1675d7..80d81774fda8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -837,6 +837,174 @@ static int convert_tiling_flags_to_modifier(struct 
amdgpu_framebuffer *afb)
return 0;
 }
 
+static void get_block_dimensions(unsigned int block_log2, unsigned int cpp,
+unsigned int *width, unsigned int *height)
+{
+   unsigned int cpp_log2 = ilog2(cpp);
+   unsigned int pixel_log2 = block_log2 - cpp_log2;
+   unsigned int width_log2 = (pixel_log2 + 1) / 2;
+   unsigned int height_log2 = pixel_log2 - width_log2;
+
+   *width = 1 << width_log2;
+   *height = 1 << height_log2;
+}
+
+static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned,
+  bool pipe_aligned)
+{
+   unsigned int ver = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
+
+   switch (ver) {
+   case AMD_FMT_MOD_TILE_VER_GFX9: {
+   /*
+* TODO: for pipe aligned we may need to check the alignment of 
the
+* total size of the surface, which may need to be bigger than 
the
+* natural alignment due to some HW workarounds
+*/
+   return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, 
modifier) : 0), 12);
+   }
+   case AMD_FMT_MOD_TILE_VER_GFX10:
+   case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: {
+   int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
+
+   if (ver == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 
&&
+   AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2)
+   ++pipes_log2;
+
+   return max(8 + (pipe_aligned ? pipes_log2 : 0), 12);
+   }
+   default:
+   return 0;
+   }
+}
+
+static int amdgpu_display_verify_plane(struct amdgpu_framebuffer *rfb, int 
plane,
+  const struct drm_format_info *format,
+  unsigned int block_width, unsigned int 
block_height,
+  unsigned int block_size_log2)
+{
+   unsigned int width = rfb->base.width /
+   ((plane && plane < format->num_planes) ? format->hsub : 1);
+   unsigned int height = rfb->base.height /
+   ((plane && plane < format->num_planes) ? format->vsub : 1);
+   unsigned int cpp = plane < format->num_planes ? format->cpp[plane] : 1;
+   unsigned int block_pitch = block_width * cpp;
+   unsigned int min_pitch = ALIGN(width * cpp, block_pitch);
+   unsigned int block_size = 1 << block_size_log2;
+   uint64_t size;
+
+   if (rfb->base.pitches[plane] % block_pitch) {
+   drm_dbg_kms(rfb->base.dev,
+   "pitch %d for plane %d is not a multiple of block 
pitch %d\n",
+   rfb->base.pitches[plane], plane, block_pitch);
+   return -EINVAL;
+   }
+   if (rfb->base.pitches[plane] < min_pitch) {
+   drm_dbg_kms(rfb->base.dev,
+   "pitch %d for plane %d is less than minimum pitch 
%d\n",
+   rfb->base.pitches[plane], plane, min_pitch);
+   return -EINVAL;
+   }
+
+   /* Force at least natural alignment. */
+   

[PATCH] drm/amdgpu: Init GFX10_ADDR_CONFIG for VCN v3 in DPG mode.

2021-05-04 Thread Bas Nieuwenhuizen
Otherwise tiling modes that require the values form this field
(In particular _*_X) would be corrupted upon video decode.

Copied from the VCN v2 code.

Fixes: 99541f392b4d ("drm/amdgpu: add mc resume DPG mode for VCN3.0")
Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index 3f15bf34123a..cf165ab5dd26 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -589,6 +589,10 @@ static void vcn_v3_0_mc_resume_dpg_mode(struct 
amdgpu_device *adev, int inst_idx
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0),
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 
0, indirect);
+
+   /* VCN global tiling registers */
+   WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
+   UVD, 0, mmUVD_GFX10_ADDR_CONFIG), 
adev->gfx.config.gb_addr_config, 0, indirect);
 }
 
 static void vcn_v3_0_disable_static_power_gating(struct amdgpu_device *adev, 
int inst)
-- 
2.31.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 2/2] Revert "Revert "drm/amdgpu: Ensure that the modifier requested is supported by plane.""

2021-05-09 Thread Bas Nieuwenhuizen
It would be very helpful if you could enable drm.debug=0x4 and then
take the dmesg to figure out what modifier was rejected

On Sun, May 9, 2021 at 10:51 PM youling 257  wrote:
>
> look this video,
> https://drive.google.com/file/d/1QklH_H2AlOTu8W1D3yl6_3rtZ7IqbjR_/view?usp=sharing
>
> 2021-05-09 23:52 GMT+08:00, Alex Deucher :
> > On Sun, May 9, 2021 at 11:42 AM youling257  wrote:
> >>
> >> I using amd 3400g running with android-x86, this patch is a bad commit
> >> when i use android-x86 on amdgpu.
> >
> > Can you provide more details?  What sort of problem are you seeing?
> > Please provide your dmesg output.
> >
> > Alex
> >
> >
> >> ___
> >> amd-gfx mailing list
> >> amd-gfx@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> >
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [RFC PATCH v2 2/3] drm: set fb_modifiers_not_supported flag in legacy drivers

2022-01-13 Thread Bas Nieuwenhuizen
I think we'll also want to do a conditional disable for DC
(drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c) since it only
enables modifiers on newer HW.  Something like "if (modifiers == NULL)
fb_modifiers_not_supported = true;" in amdgpu_dm_plane_init.

On Thu, Jan 13, 2022 at 10:44 AM Tomohito Esaki  wrote:
>
> Set fb_modifiers_not_supported flag in legacy drivers whose planes
> support non-linear layouts but does not support modifiers, and replace
> allow_fb_modifiers with fb_modifiers_not_supported.
>
> Signed-off-by: Tomohito Esaki 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 6 +++---
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.c  | 2 ++
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.c  | 2 ++
>  drivers/gpu/drm/amd/amdgpu/dce_v6_0.c   | 1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.c   | 2 ++
>  drivers/gpu/drm/nouveau/nouveau_display.c   | 6 --
>  drivers/gpu/drm/radeon/radeon_display.c | 2 ++
>  7 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index dc50c05f23fc..cbaea9c6cfda 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -958,7 +958,7 @@ static int amdgpu_display_verify_sizes(struct 
> amdgpu_framebuffer *rfb)
> int ret;
> unsigned int i, block_width, block_height, block_size_log2;
>
> -   if (!rfb->base.dev->mode_config.allow_fb_modifiers)
> +   if (rfb->base.dev->mode_config.fb_modifiers_not_supported)
> return 0;
>
> for (i = 0; i < format_info->num_planes; ++i) {
> @@ -1145,7 +1145,7 @@ int amdgpu_display_framebuffer_init(struct drm_device 
> *dev,
> if (ret)
> return ret;
>
> -   if (!dev->mode_config.allow_fb_modifiers) {
> +   if (dev->mode_config.fb_modifiers_not_supported) {
> drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI,
>   "GFX9+ requires FB check based on format 
> modifier\n");
> ret = check_tiling_flags_gfx6(rfb);
> @@ -1153,7 +1153,7 @@ int amdgpu_display_framebuffer_init(struct drm_device 
> *dev,
> return ret;
> }
>
> -   if (dev->mode_config.allow_fb_modifiers &&
> +   if (!dev->mode_config.fb_modifiers_not_supported &&
> !(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
> ret = convert_tiling_flags_to_modifier(rfb);
> if (ret) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> index d1570a462a51..fb61c0814115 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> @@ -2798,6 +2798,8 @@ static int dce_v10_0_sw_init(void *handle)
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1;
>
> +   adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
> +
> adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
>
> r = amdgpu_display_modeset_create_props(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> index 18a7b3bd633b..17942a11366d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> @@ -2916,6 +2916,8 @@ static int dce_v11_0_sw_init(void *handle)
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1;
>
> +   adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
> +
> adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
>
> r = amdgpu_display_modeset_create_props(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> index c7803dc2b2d5..2ec99ec8e1a3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> @@ -2674,6 +2674,7 @@ static int dce_v6_0_sw_init(void *handle)
> adev_to_drm(adev)->mode_config.max_height = 16384;
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> +   adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
> adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
>
> r = amdgpu_display_modeset_create_props(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> index b200b9e722d9..8369336cec90 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> @@ -2699,6 +2699,8 @@ static int dce_v8_0_sw_init(void *handle)
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1;
>
> +   adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
> +
> 

[PATCH] drm/amdgpu/display: Remove t_srx_delay_us.

2022-01-22 Thread Bas Nieuwenhuizen
Unused. Convert the divisions into asserts on the divisor, to
debug why it is zero. The divide by zero is suspected of causing
kernel panics.

While I have no idea where the zero is coming from I think this
patch is a positive either way.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c  | 1 -
 .../gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c | 2 --
 .../drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c   | 2 --
 .../gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 2 --
 .../gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c | 2 --
 drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h | 1 -
 drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c   | 3 ---
 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 4 
 8 files changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c 
b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
index ec19678a0702..e447c74be713 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -503,7 +503,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
//input[in_idx].dout.output_standard;
 
/*todo: soc->sr_enter_plus_exit_time??*/
-   dlg_sys_param->t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / 
v->dcf_clk_deep_sleep;
 
dml1_rq_dlg_get_rq_params(dml, rq_param, &input->pipe.src);
dml1_extract_rq_regs(dml, rq_regs, rq_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 246071c72f6b..548cdef8a8ad 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -1576,8 +1576,6 @@ void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib 
*mode_lib,
dlg_sys_param.total_flip_bytes = 
get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
-   dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
-   / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: 
Deprecated
 
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index 015e7f2c0b16..0fc9f3e3ffae 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -1577,8 +1577,6 @@ void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib 
*mode_lib,
dlg_sys_param.total_flip_bytes = 
get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
-   dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
-   / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: 
Deprecated
 
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
index 8bc27de4c104..618f4b682ab1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
@@ -1688,8 +1688,6 @@ void dml21_rq_dlg_get_dlg_reg(
mode_lib,
e2e_pipe_param,
num_pipes);
-   dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
-   / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: 
Deprecated
 
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
index aef854270054..747167083dea 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
@@ -1858,8 +1858,6 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib 
*mode_lib,
dlg_sys_param.total_flip_bytes = 
get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
-   dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
-   / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
 
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h 
b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index d46a2733024c..8f9f1d607f7c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -546,7 +

[PATCH 2/2] drm/amd/display: Wrap dcn301_calculate_wm_and_dlg for FPU.

2022-01-23 Thread Bas Nieuwenhuizen
Mirrors the logic for dcn30. Cue lots of WARNs and some
kernel panics without this fix.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/dc/dcn301/dcn301_resource.c   | 11 +++
 .../gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c|  2 +-
 .../gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h|  2 +-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index b4001233867c..5d9637b07429 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -1380,6 +1380,17 @@ static void set_wm_ranges(
pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges);
 }
 
+static void dcn301_calculate_wm_and_dlg(
+   struct dc *dc, struct dc_state *context,
+   display_e2e_pipe_params_st *pipes,
+   int pipe_cnt,
+   int vlevel)
+{
+   DC_FP_START();
+   dcn301_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel);
+   DC_FP_END();
+}
+
 static struct resource_funcs dcn301_res_pool_funcs = {
.destroy = dcn301_destroy_resource_pool,
.link_enc_create = dcn301_link_encoder_create,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
index 94c32832a0e7..0a7a33864973 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
@@ -327,7 +327,7 @@ void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info 
bb_info)
dcn3_01_soc.sr_exit_time_us = 
bb_info.dram_sr_exit_latency_100ns * 10;
 }
 
-void dcn301_calculate_wm_and_dlg(struct dc *dc,
+void dcn301_calculate_wm_and_dlg_fp(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h 
b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
index fc7065d17842..774b0fdfc80b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
@@ -34,7 +34,7 @@ void dcn301_fpu_set_wm_ranges(int i,
 
 void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
 
-void dcn301_calculate_wm_and_dlg(struct dc *dc,
+void dcn301_calculate_wm_and_dlg_fp(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
-- 
2.34.1



[PATCH 1/2] drm/amd/display: Fix FP start/end for dcn30_internal_validate_bw.

2022-01-23 Thread Bas Nieuwenhuizen
It calls populate_dml_pipes which uses doubles to initialize the
scale_ratio_depth params. Mirrors the dcn20 logic.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 602ec9a08549..8ca26383b568 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1878,7 +1878,6 @@ noinline bool dcn30_internal_validate_bw(
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, 
fast_validate);
 
-   DC_FP_START();
if (!pipe_cnt) {
out = true;
goto validate_out;
@@ -2104,7 +2103,6 @@ noinline bool dcn30_internal_validate_bw(
out = false;
 
 validate_out:
-   DC_FP_END();
return out;
 }
 
@@ -2306,7 +2304,9 @@ bool dcn30_validate_bandwidth(struct dc *dc,
 
BW_VAL_TRACE_COUNT();
 
+   DC_FP_START();
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, 
&vlevel, fast_validate);
+   DC_FP_END();
 
if (pipe_cnt == 0)
goto validate_out;
-- 
2.34.1



[PATCH] drm/amd/display: Protect update_bw_bounding_box FPU code.

2022-02-12 Thread Bas Nieuwenhuizen
For DCN3/3.01/3.02 at least these use the fpu.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 2 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c | 5 -
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
index 589131d415fd..220682e45b8d 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -474,8 +474,10 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr 
*clk_mgr_base)
clk_mgr_base->bw_params->dc_mode_softmax_memclk = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK);
 
/* Refresh bounding box */
+   DC_FP_START();
clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
clk_mgr->base.ctx->dc, clk_mgr_base->bw_params);
+   DC_FP_END();
 }
 
 static bool dcn3_is_smu_present(struct clk_mgr *clk_mgr_base)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 467f606ba2c7..e46ec8cc2d0a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -987,8 +987,11 @@ static bool dc_construct(struct dc *dc,
dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
 #endif
 
-   if (dc->res_pool->funcs->update_bw_bounding_box)
+   if (dc->res_pool->funcs->update_bw_bounding_box) {
+   DC_FP_START();
dc->res_pool->funcs->update_bw_bounding_box(dc, 
dc->clk_mgr->bw_params);
+   DC_FP_END();
+   }
 
/* Creation of current_state must occur after dc->dml
 * is initialized in dc_create_resource_pool because
-- 
2.35.1



Re: [PATCH RESEND] amd/display: convert DRM_DEBUG_ATOMIC to drm_dbg_atomic

2021-05-26 Thread Bas Nieuwenhuizen
Reviewed-by: Bas Nieuwenhuizen 

I think there are plenty more occurrences too or did I miss the
cleanup of those?

On Wed, May 26, 2021 at 3:56 PM Simon Ser  wrote:
>
> This allows to tie the log message to a specific DRM device.
>
> Signed-off-by: Simon Ser 
> Cc: Alex Deucher 
> Cc: Harry Wentland 
> Cc: Nicholas Kazlauskas 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 2c9d099adfc2..4dd811816cba 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10089,7 +10089,7 @@ static int dm_check_crtc_cursor(struct 
> drm_atomic_state *state,
>
> if (cursor_scale_w != primary_scale_w ||
> cursor_scale_h != primary_scale_h) {
> -   DRM_DEBUG_ATOMIC("Cursor plane scaling doesn't match primary 
> plane\n");
> +   drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match 
> primary plane\n");
> return -EINVAL;
> }
>
> --
> 2.31.1
>
>
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Enabling AMDGPU by default for SI & CIK

2020-08-02 Thread Bas Nieuwenhuizen
Hi all,

Now that we have recently made some progress on getting feature parity
with the Radeon driver for SI, I'm wondering what it would take to
make AMDGPU the default driver for these generations.

As far as I understand AMDGPU has had these features for CIK for a
while already but it is still not the default driver. What would it
take to make it the default? What is missing and/or broken?

- Bas

(I did some statistics on the Steam Survey, and both SI and CIK have
around 9% marketshare for Linux+ AMD there:
https://gitlab.freedesktop.org/snippets/1128 Would be cool if we could
enable Vulkan and VR out of the box on these cards)
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 4/8] drm/fourcc: Add AMD DRM modifiers.

2020-08-04 Thread Bas Nieuwenhuizen
This adds modifiers for GFX9+ AMD GPUs.

As the modifiers need a lot of parameters I split things out in
getters and setters.
  - Advantage: simplifies the code a lot
  - Disadvantage: Makes it harder to check that you're setting all
  the required fields.

The tiling modes seem to change every generatio, but the structure
of what each tiling mode is good for stays really similar. As such
the core of the modifier is
 - the tiling mode
 - a version. Not explicitly a GPU generation, but splitting out
   a new set of tiling equations.

Sometimes one or two tiling modes stay the same and for those we
specify a canonical version.

Then we have a bunch of parameters on how the compression works.
Different HW units have different requirements for these and we
actually have some conflicts here.

e.g. the render backends need a specific alignment but the display
unit only works with unaligned compression surfaces. To work around
that we have a DCC_RETILE option where both an aligned and unaligned
compression surface are allocated and a writer has to sync the
aligned surface to the unaligned surface on handoff.

Finally there are some GPU parameters that participate in the tiling
equations. These are constant for each GPU on the rendering/texturing
side. The display unit is very flexible however and supports all
of them :|

Some estimates:
 - Single GPU, render+texture: ~10 modifiers
 - All possible configs in a gen, display: ~1000 modifiers
 - Configs of actually existing GPUs in a gen: ~100 modifiers

For formats with a single plane everything gets put in a separate
DRM plane. However, this doesn't fit for some YUV formats, so if
the format has >1 plane, we let the driver pack the surfaces into
1 DRM plane per format plane.

This way we avoid X11 rendering onto the frontbuffer with DCC, but
still fit into 4 DRM planes.

Signed-off-by: Bas Nieuwenhuizen 
---
 include/uapi/drm/drm_fourcc.h | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 8bc0b31597d8..2f8d2b717285 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -804,6 +804,121 @@ extern "C" {
  */
 #define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1)
 
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ *   - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ *   - main surface in plane 0
+ *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is 
set)
+ *
+ * with DCC & DCC_RETILE:
+ *   - main surface in plane 0
+ *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each for format plane, based on the required alignment only.
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as 
canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastclear
+ * eliminate operation before a process transfers c

[PATCH 7/8] drm/amd/display: Add formats for DCC with 2/3 planes.

2020-08-04 Thread Bas Nieuwenhuizen
For DCC we will use 2/3 planes to avoid X rendering to the frontbuffer
with DCC compressed images. To make this work with the core KMS
validation we need to add extra formats with the extra planes.

However, due to flexibility we set bpp = 0 for the extra planes and
do the validation ourselves.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 95 +++
 1 file changed, 95 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ac913b8f10ef..c38257081868 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -170,6 +170,8 @@ static bool amdgpu_dm_psr_enable(struct dc_stream_state 
*stream);
 static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 
+static const struct drm_format_info *
+amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
 
 /*
  * dm_vblank_get_counter
@@ -2007,6 +2009,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
 
 static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
+   .get_format_info = amd_get_format_info,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
@@ -3769,6 +3772,98 @@ modifier_gfx9_swizzle_mode(uint64_t modifier)
return AMD_FMT_MOD_GET(TILE, modifier);
 }
 
+static const struct drm_format_info dcc_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+ .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1

[PATCH 2/8] drm/amd: Init modifier field of helper fb.

2020-08-04 Thread Bas Nieuwenhuizen
Otherwise the field ends up being used uninitialized when
enabling modifiers, failing validation with high likelihood.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 25ddb482466a..c2d6952d0a7d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -201,7 +201,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
struct amdgpu_device *adev = rfbdev->adev;
struct fb_info *info;
struct drm_framebuffer *fb = NULL;
-   struct drm_mode_fb_cmd2 mode_cmd;
+   struct drm_mode_fb_cmd2 mode_cmd = {0};
struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *abo = NULL;
int ret;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 3/8] drm/amd/display: Honor the offset for plane 0.

2020-08-04 Thread Bas Nieuwenhuizen
With modifiers I'd like to support non-dedicated buffers for
images.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 005331c772b7..abc70fbe176d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3623,6 +3623,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
+   uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
uint64_t dcc_address;
@@ -3666,7 +3667,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
dcc->independent_64b_blks = i64b;
 
-   dcc_address = get_dcc_address(afb->address, info);
+   dcc_address = get_dcc_address(plane_address, info);
address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
 
@@ -3697,6 +3698,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
address->tmz_surface = tmz_surface;
 
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+   uint64_t addr = afb->address + fb->offsets[0];
+
plane_size->surface_size.x = 0;
plane_size->surface_size.y = 0;
plane_size->surface_size.width = fb->width;
@@ -3705,9 +3708,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
fb->pitches[0] / fb->format->cpp[0];
 
address->type = PLN_ADDR_TYPE_GRAPHICS;
-   address->grph.addr.low_part = lower_32_bits(afb->address);
-   address->grph.addr.high_part = upper_32_bits(afb->address);
+   address->grph.addr.low_part = lower_32_bits(addr);
+   address->grph.addr.high_part = upper_32_bits(addr);
} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
+   uint64_t luma_addr = afb->address + fb->offsets[0];
uint64_t chroma_addr = afb->address + fb->offsets[1];
 
plane_size->surface_size.x = 0;
@@ -3728,9 +3732,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
address->video_progressive.luma_addr.low_part =
-   lower_32_bits(afb->address);
+   lower_32_bits(luma_addr);
address->video_progressive.luma_addr.high_part =
-   upper_32_bits(afb->address);
+   upper_32_bits(luma_addr);
address->video_progressive.chroma_addr.low_part =
lower_32_bits(chroma_addr);
address->video_progressive.chroma_addr.high_part =
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 8/8] drm/amd/display: Expose modifiers.

2020-08-04 Thread Bas Nieuwenhuizen
This expose modifier support on GFX9+.

Only modifiers that can be rendered on the current GPU are
added. This is to reduce the number of modifiers exposed.

The HW could expose more, but the best mechanism to decide
what to expose without an explosion in modifiers is still
to be decided, and in the meantime this should not regress
things from pre-modifiers and does not risk regressions as
we make up our mind in the future.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 343 +-
 1 file changed, 342 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c38257081868..6594cbe625f9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3891,6 +3891,340 @@ fill_gfx9_tiling_info_from_modifier(const struct 
amdgpu_device *adev,
}
 }
 
+enum dm_micro_swizzle {
+   MICRO_SWIZZLE_Z = 0,
+   MICRO_SWIZZLE_S = 1,
+   MICRO_SWIZZLE_D = 2,
+   MICRO_SWIZZLE_R = 3
+};
+
+static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+   struct amdgpu_device *adev = plane->dev->dev_private;
+   const struct drm_format_info *info = drm_format_info(format);
+
+   enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) 
& 3;
+
+   if (!info)
+   return false;
+
+   /*
+* We always have to allow this modifier, because core DRM still
+* checks LINEAR support if userspace does not provide modifers.
+*/
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return true;
+
+   /*
+* The arbitrary tiling support for multiplane formats has not been 
hooked
+* up.
+*/
+   if (info->num_planes > 1)
+   return false;
+
+   /*
+* For D swizzle the canonical modifier depends on the bpp, so check
+* it here.
+*/
+   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
AMD_FMT_MOD_TILE_VER_GFX9 &&
+   adev->family >= AMDGPU_FAMILY_NV) {
+   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
+   return false;
+   }
+
+   if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
+   info->cpp[0] < 8)
+   return false;
+
+   if (modifier_has_dcc(modifier)) {
+   /* Per radeonsi comments 16/64 bpp are more complicated. */
+   if (info->cpp[0] != 4)
+   return false;
+   }
+
+   return true;
+}
+
+static void
+add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
+{
+   if (!*mods)
+   return;
+
+   if (*cap - *size < 1) {
+   uint64_t new_cap = *cap * 2;
+   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
GFP_KERNEL);
+
+   if (!new_mods) {
+   kfree(*mods);
+   *mods = NULL;
+   return;
+   }
+
+   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
+   kfree(*mods);
+   *mods = new_mods;
+   *cap = new_cap;
+   }
+
+   (*mods)[*size] = mod;
+   *size += 1;
+}
+
+static void
+add_gfx9_modifiers(const struct amdgpu_device *adev,
+ uint64_t **mods, uint64_t *size, uint64_t *capacity)
+{
+   int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
+   int pipe_xor_bits = min(8, pipes +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   int bank_xor_bits = min(8 - pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
+ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
+
+
+   if (adev->family == AMDGPU_FAMILY_RV) {
+   /*
+* No _D DCC swizzles yet because we only allow 32bpp, which
+* doesn't support _D on DCN
+*/
+
+   /*
+* Always enable constant encoding, because the only unit that
+* didn't support it was CB. But on texture/display we can
+* always interpret it.
+*/
+   add_modifier(mods, size, capacity, AMD_FMT_MOD |
+   AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+   AMD_FMT_MOD_SET(TILE_VERSION, 
AMD_FMT_MOD_TILE_VER_GFX9) |
+   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+  

[PATCH 0/8] amd/display: Add GFX9+ modifier support.

2020-08-04 Thread Bas Nieuwenhuizen
This adds modifier support to radeonsi.
It has been tested on

- VEGA10, RAVEN, NAVI14
- weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)

and includes some basic testing of the layout code.

The main goal is to keep it somewhat simple and regression free, so
on the display side this series only exposes what the current GPU
can render to. While we could expose more I think that is more
suitable for follow-up work as the benefit would be minimal and
there are some more design discussion there to discuss that are
orthogonal from the initial implementation.

Similarly this series only exposes 32-bpp displayable DCC in the cases
that radeonsi would use it and any extra capabilities here should be
future work.

I believe these are by far the most complicated modifiers we've seen
up till now, mostly related to

- GPU identification for cases where it matters wrt tiling.
- Every generation having tiling layout changes
- Compression settings.

I believe the complexity is necessary as every layout should be different
and all layouts should be the best in some situation (though not all
combinations of GPU parameters will actually have an existing GPU).

That said, on the render side the number of modifiers actually listed for
a given GPU is ~10, and in the current implementation that is the same
for the display side. (we could expose more actually differing layouts
on the display side for cross-GPU compatibility, but I consider that
out of scope for this initial work).

This series can be found on
https://github.com/BNieuwenhuizen/linux/tree/modifiers

An userspace implementation in radeonsi can be found on
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176

Bas Nieuwenhuizen (8):
  drm/amd/display: Do not silently accept DCC for multiplane formats.
  drm/amd: Init modifier field of helper fb.
  drm/amd/display: Honor the offset for plane 0.
  drm/fourcc:  Add AMD DRM modifiers.
  drm/amd/display: Refactor surface tiling setup.
  drm/amd/display: Set DC options from modifiers.
  drm/amd/display: Add formats for DCC with 2/3 planes.
  drm/amd/display: Expose modifiers.

 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c|   2 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 758 +++---
 include/uapi/drm/drm_fourcc.h | 115 +++
 3 files changed, 775 insertions(+), 100 deletions(-)

-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 1/8] drm/amd/display: Do not silently accept DCC for multiplane formats.

2020-08-04 Thread Bas Nieuwenhuizen
Silently accepting it could result in corruption.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f348693217d8..005331c772b7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3637,7 +3637,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
return 0;
 
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-   return 0;
+   return -EINVAL;
 
if (!dc->cap_funcs.get_dcc_compression_cap)
return -EINVAL;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 5/8] drm/amd/display: Refactor surface tiling setup.

2020-08-04 Thread Bas Nieuwenhuizen
Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 209 ++
 1 file changed, 116 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index abc70fbe176d..6ef7f2f8acab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3601,46 +3601,83 @@ static int get_fb_info(const struct amdgpu_framebuffer 
*amdgpu_fb,
return r;
 }
 
-static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+static void
+fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+uint64_t tiling_flags)
 {
-   uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+   /* Fill GFX8 params */
+   if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
+   unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
+
+   bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+   bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+   mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+   tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
+   num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
 
-   return offset ? (address + offset * 256) : 0;
+   /* XXX fix me for VI */
+   tiling_info->gfx8.num_banks = num_banks;
+   tiling_info->gfx8.array_mode =
+   DC_ARRAY_2D_TILED_THIN1;
+   tiling_info->gfx8.tile_split = tile_split;
+   tiling_info->gfx8.bank_width = bankw;
+   tiling_info->gfx8.bank_height = bankh;
+   tiling_info->gfx8.tile_aspect = mtaspect;
+   tiling_info->gfx8.tile_mode =
+   DC_ADDR_SURF_MICRO_TILING_DISPLAY;
+   } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
+   == DC_ARRAY_1D_TILED_THIN1) {
+   tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
+   }
+
+   tiling_info->gfx8.pipe_config =
+   AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+}
+
+static void
+fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info)
+{
+   tiling_info->gfx9.num_pipes =
+   adev->gfx.config.gb_addr_config_fields.num_pipes;
+   tiling_info->gfx9.num_banks =
+   adev->gfx.config.gb_addr_config_fields.num_banks;
+   tiling_info->gfx9.pipe_interleave =
+   adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
+   tiling_info->gfx9.num_shader_engines =
+   adev->gfx.config.gb_addr_config_fields.num_se;
+   tiling_info->gfx9.max_compressed_frags =
+   adev->gfx.config.gb_addr_config_fields.max_compress_frags;
+   tiling_info->gfx9.num_rb_per_se =
+   adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
+   tiling_info->gfx9.shaderEnable = 1;
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+   if (adev->asic_type == CHIP_SIENNA_CICHLID)
+   tiling_info->gfx9.num_pkrs = 
adev->gfx.config.gb_addr_config_fields.num_pkrs;
+#endif
 }
 
 static int
-fill_plane_dcc_attributes(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- const union dc_tiling_info *tiling_info,
- const uint64_t info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- bool force_disable_dcc)
+validate_dcc(struct amdgpu_device *adev,
+const enum surface_pixel_format format,
+const enum dc_rotation_angle rotation,
+const union dc_tiling_info *tiling_info,
+const struct dc_plane_dcc_param *dcc,
+const struct dc_plane_address *address,
+const struct plane_size *plane_size)
 {
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
-   uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
-   uint64_t dcc_address;
 
memset(&input, 0, sizeof(input));
m

[PATCH 6/8] drm/amd/display: Set DC options from modifiers.

2020-08-04 Thread Bas Nieuwenhuizen
This sets the DC tiling options from the modifier, if modifiers
are used for the FB. This patch by itself does not expose the
support yet though.

There is not much validation yet to limit the scope of this
patch, but the current validation is at the same level as
the BO metadata path.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 109 +-
 1 file changed, 103 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6ef7f2f8acab..ac913b8f10ef 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3754,6 +3754,93 @@ fill_gfx9_plane_attributes_from_flags(struct 
amdgpu_device *adev,
return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+   return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return 0;
+
+   return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info,
+ uint64_t modifier)
+{
+   unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, 
modifier);
+   unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, 
modifier);
+   unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+   unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+   fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+   if (!IS_AMD_FMT_MOD(modifier))
+   return;
+
+   tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+   tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - 
pipes_log2);
+
+   if (adev->family >= AMDGPU_FAMILY_NV) {
+   tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+   } else {
+   tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+   /* for DCC we know it isn't rb aligned, so rb_per_se doesn't 
matter. */
+   }
+}
+
+static void
+block_alignment(unsigned int blocksize_log2, unsigned int *width, unsigned int 
*height)
+{
+   unsigned int height_log2 = blocksize_log2 / 2;
+   unsigned int width_log2 = blocksize_log2 - height_log2;
+
+   *width = 1u << width_log2;
+   *height = 1u << height_log2;
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ const enum surface_pixel_format format,
+ const enum dc_rotation_angle rotation,
+ const struct plane_size *plane_size,
+ union dc_tiling_info *tiling_info,
+ struct dc_plane_dcc_param *dcc,
+ struct dc_plane_address *address,
+ const bool force_disable_dcc)
+{
+   const uint64_t modifier = afb->base.modifier;
+   int ret;
+
+   fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+   tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+   if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+   uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+   dcc->enable = 1;
+   dcc->meta_pitch = afb->base.pitches[1];
+   dcc->independent_64b_blks = 
AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+   }
+
+   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
 const struct amdgpu_framebuffer *afb,
@@ -3823,12 +3910,22 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, 
rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   force_disable_dcc);
-   if (ret)
-   return ret;
+   if (afb->base.flag

Re: [PATCH 6/8] drm/amd/display: Set DC options from modifiers.

2020-08-10 Thread Bas Nieuwenhuizen
On Mon, Aug 10, 2020 at 3:09 PM Daniel Vetter  wrote:
>
> On Mon, Aug 10, 2020 at 02:49:00PM +0200, Michel Dänzer wrote:
> > On 2020-08-10 2:28 p.m., Daniel Vetter wrote:
> > >
> > > Ok just learned that amdgpu hat set/get_tiling, so I'm upgrading my idea
> > > here to a very strong recommendation, i.e. please do this except if
> > > there's and amd ddx which somehow wants to change tiling mode while a fb
> > > exists, and expects this to propagate.
> > >
> > > In i915 we even disallow the set_tiling ioctl with an error if an fb
> > > exists, just to make sure userspace behaves. Even if userspace uses
> > > set_tiling, this way we can at least enforce the same semantics of "client
> > > can't pull compositor over the table with a set_tiling at the wrong time"
> > > of modifiers.
> >
> > FWIW, xf86-video-amdgpu doesn't have any code to set the tiling
> > metadata, only Mesa and presumably AMD's Vulkan/OpenGL UMDs do.
>
> Ah right you do everything with glamour, so this should never show up as a
> problem.

I think it is a good idea to do so, but cannot do it completely in
this series as we don't define modifiers for GFX6-GFX8 GPU generations
yet. (wanted to leave these out for a bit to reduce the scope for the
initial version)

That said, there is a series that captures the tiling flags on FB
creation: https://patchwork.freedesktop.org/series/80109/

> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 8/8] drm/amd/display: Expose modifiers.

2020-09-02 Thread Bas Nieuwenhuizen
On Fri, Aug 7, 2020 at 9:43 PM Marek Olšák  wrote:
>
> On Tue, Aug 4, 2020 at 5:32 PM Bas Nieuwenhuizen  
> wrote:
>>
>> This expose modifier support on GFX9+.
>>
>> Only modifiers that can be rendered on the current GPU are
>> added. This is to reduce the number of modifiers exposed.
>>
>> The HW could expose more, but the best mechanism to decide
>> what to expose without an explosion in modifiers is still
>> to be decided, and in the meantime this should not regress
>> things from pre-modifiers and does not risk regressions as
>> we make up our mind in the future.
>>
>> Signed-off-by: Bas Nieuwenhuizen 
>> ---
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 343 +-
>>  1 file changed, 342 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index c38257081868..6594cbe625f9 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -3891,6 +3891,340 @@ fill_gfx9_tiling_info_from_modifier(const struct 
>> amdgpu_device *adev,
>> }
>>  }
>>
>> +enum dm_micro_swizzle {
>> +   MICRO_SWIZZLE_Z = 0,
>> +   MICRO_SWIZZLE_S = 1,
>> +   MICRO_SWIZZLE_D = 2,
>> +   MICRO_SWIZZLE_R = 3
>> +};
>> +
>> +static bool dm_plane_format_mod_supported(struct drm_plane *plane,
>> + uint32_t format,
>> + uint64_t modifier)
>> +{
>> +   struct amdgpu_device *adev = plane->dev->dev_private;
>> +   const struct drm_format_info *info = drm_format_info(format);
>> +
>> +   enum dm_micro_swizzle microtile = 
>> modifier_gfx9_swizzle_mode(modifier) & 3;
>> +
>> +   if (!info)
>> +   return false;
>> +
>> +   /*
>> +* We always have to allow this modifier, because core DRM still
>> +* checks LINEAR support if userspace does not provide modifers.
>> +*/
>> +   if (modifier == DRM_FORMAT_MOD_LINEAR)
>> +   return true;
>> +
>> +   /*
>> +* The arbitrary tiling support for multiplane formats has not been 
>> hooked
>> +* up.
>> +*/
>> +   if (info->num_planes > 1)
>> +   return false;
>> +
>> +   /*
>> +* For D swizzle the canonical modifier depends on the bpp, so check
>> +* it here.
>> +*/
>> +   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
>> AMD_FMT_MOD_TILE_VER_GFX9 &&
>> +   adev->family >= AMDGPU_FAMILY_NV) {
>> +   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
>> +   return false;
>> +   }
>> +
>> +   if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D 
>> &&
>> +   info->cpp[0] < 8)
>> +   return false;
>> +
>> +   if (modifier_has_dcc(modifier)) {
>> +   /* Per radeonsi comments 16/64 bpp are more complicated. */
>> +   if (info->cpp[0] != 4)
>> +   return false;
>> +   }
>> +
>> +   return true;
>> +}
>> +
>> +static void
>> +add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
>> +{
>> +   if (!*mods)
>> +   return;
>> +
>> +   if (*cap - *size < 1) {
>> +   uint64_t new_cap = *cap * 2;
>> +   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
>> GFP_KERNEL);
>> +
>> +   if (!new_mods) {
>> +   kfree(*mods);
>> +   *mods = NULL;
>> +   return;
>> +   }
>> +
>> +   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
>> +   kfree(*mods);
>> +   *mods = new_mods;
>> +   *cap = new_cap;
>> +   }
>> +
>> +   (*mods)[*size] = mod;
>> +   *size += 1;
>> +}
>> +
>> +static void
>> +add_gfx9_modifiers(const struct amdgpu_device *adev,
>> + uint64_t **mods, uint64_t *size, uint64_t *capacity)
>> +{
>> +   int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
>> +   int pipe_xor_bits = min(8, pipes +
>

[PATCH v2 00/11] amd/display: Add GFX9+ modifier support.

2020-09-04 Thread Bas Nieuwenhuizen
This adds modifier support to radeonsi.
It has been tested on

- VEGA10, RAVEN, NAVI14
- weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)

and includes some basic testing of the layout code.

The main goal is to keep it somewhat simple and regression free, so
on the display side this series only exposes what the current GPU
can render to. While we could expose more I think that is more
suitable for follow-up work as the benefit would be minimal and
there are some more design discussion there to discuss that are
orthogonal from the initial implementation.

Similarly this series only exposes 32-bpp displayable DCC in the cases
that radeonsi would use it and any extra capabilities here should be
future work.

I believe these are by far the most complicated modifiers we've seen
up till now, mostly related to

- GPU identification for cases where it matters wrt tiling.
- Every generation having tiling layout changes
- Compression settings.

I believe the complexity is necessary as every layout should be different
and all layouts should be the best in some situation (though not all
combinations of GPU parameters will actually have an existing GPU).

That said, on the render side the number of modifiers actually listed for
a given GPU is ~10, and in the current implementation that is the same
for the display side. (we could expose more actually differing layouts
on the display side for cross-GPU compatibility, but I consider that
out of scope for this initial work).

This series can be found on
https://github.com/BNieuwenhuizen/linux/tree/modifiers

An userspace implementation in radeonsi can be found on
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176

v2:

Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
constant econding modifers only get exposed on RAVEN2 and newer.

Bas Nieuwenhuizen (11):
  drm/amd/display: Do not silently accept DCC for multiplane formats.
  drm/amd: Init modifier field of helper fb.
  drm/amd/display: Honor the offset for plane 0.
  drm/fourcc:  Add AMD DRM modifiers.
  drm/amd/display: Store tiling_flags in the framebuffer.
  drm/amd/display: Convert tiling_flags to modifiers.
  drm/amd/display: Refactor surface tiling setup.
  drm/amd/display: Set DC options from modifiers.
  drm/amd/display: Add formats for DCC with 2/3 planes.
  drm/amd/display: Expose modifiers.
  drm/amd/display: Clean up GFX9 tiling_flags path.

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
 include/uapi/drm/drm_fourcc.h | 115 +++
 6 files changed, 880 insertions(+), 165 deletions(-)

-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2 02/11] drm/amd: Init modifier field of helper fb.

2020-09-04 Thread Bas Nieuwenhuizen
Otherwise the field ends up being used uninitialized when
enabling modifiers, failing validation with high likelyhood.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 88ebdb3b3c7d..efc31bd6121d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -201,7 +201,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
struct amdgpu_device *adev = rfbdev->adev;
struct fb_info *info;
struct drm_framebuffer *fb = NULL;
-   struct drm_mode_fb_cmd2 mode_cmd;
+   struct drm_mode_fb_cmd2 mode_cmd = {0};
struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *abo = NULL;
int ret;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2 06/11] drm/amd/display: Convert tiling_flags to modifiers.

2020-09-04 Thread Bas Nieuwenhuizen
This way the modifier path gets exercised all the time, improving
testing. Furthermore, for modifiers this is required as getfb2
will always return the modifier if the driver sets allow_fb_modifiers.

This only triggers once allow_fb_modifiers is set.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 123 
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 638ce7528d30..af45cc6d8ec1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static void amdgpu_display_flip_callback(struct dma_fence *f,
@@ -537,6 +538,121 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
+{
+   struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
+   uint64_t modifier = 0;
+
+   if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE)) {
+   modifier = DRM_FORMAT_MOD_LINEAR;
+   } else {
+   int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE);
+   bool has_xor = swizzle >= 16;
+   int block_size_bits;
+   int version;
+   int pipe_xor_bits = 0;
+   int bank_xor_bits = 0;
+   int packers = 0;
+   uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, 
DCC_OFFSET_256B);
+
+   switch (swizzle >> 2) {
+   case 0: /* 256B */
+   block_size_bits = 8;
+   break;
+   case 1: /* 4KiB */
+   case 5: /* 4KiB _X */
+   block_size_bits = 12;
+   break;
+   case 2: /* 64KiB */
+   case 4: /* 64 KiB _T */
+   case 6: /* 64 KiB _X */
+   block_size_bits = 16;
+   break;
+   default:
+   /* RESERVED or VAR */
+   return -EINVAL;
+   }
+
+   if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+   version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
+   else if (adev->family == AMDGPU_FAMILY_NV)
+   version = AMD_FMT_MOD_TILE_VER_GFX10;
+   else
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+
+   switch (swizzle & 3) {
+   case 0: /* Z microtiling */
+   return -EINVAL;
+   case 1: /* S microtiling */
+   if (!has_xor)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 2:
+   if (!has_xor && afb->base.format->cpp[0] != 4)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 3:
+   break;
+   }
+
+   if (has_xor) {
+   switch (version) {
+   case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   packers = min(block_size_bits - 8 - 
pipe_xor_bits,
+ 
ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX10:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX9:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   bank_xor_bits = min(block_size_bits - 8 - 
pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   break;
+   }
+   }
+
+   modifier = AMD_FMT_MOD |
+  AMD_FMT_MOD_SET(TILE, 
AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
+  AMD_FMT_MOD_SET(TILE_VERSION, version) |
+  AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |

[PATCH v2 11/11] drm/amd/display: Clean up GFX9 tiling_flags path.

2020-09-04 Thread Bas Nieuwenhuizen
We're unconditionally using modifiers internally for GFX9+ now.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 ++-
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 25b1c7c821d2..f4a4ca84485a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3793,57 +3793,6 @@ validate_dcc(struct amdgpu_device *adev,
return 0;
 }
 
-static void
-fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
-  struct dc_plane_dcc_param *dcc,
-  struct dc_plane_address *address,
-  const uint64_t flags, bool force_disable_dcc)
-{
-   uint64_t dcc_address;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
-   uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
-
-   if (!offset || force_disable_dcc)
-   return;
-
-   dcc->enable = 1;
-   dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
-   dcc->independent_64b_blks = i64b;
-
-   dcc_address = plane_address + (uint64_t)offset * 256;
-   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
-   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
-}
-
-
-static int
-fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- union dc_tiling_info *tiling_info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- uint64_t tiling_flags,
- bool force_disable_dcc)
-{
-   int ret;
-
-   fill_gfx9_tiling_info_from_device(adev, tiling_info);
-
-   tiling_info->gfx9.swizzle =
-   AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-
-   fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, 
force_disable_dcc);
-   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
 static bool
 modifier_has_dcc(uint64_t modifier)
 {
@@ -4410,22 +4359,13 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
-   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
-   
rotation, plane_size,
-   
tiling_info, dcc,
-   address,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   } else {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, 
format, rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   }
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, 
format,
+   rotation, 
plane_size,
+   tiling_info, 
dcc,
+   address,
+   
force_disable_dcc);
+   if (ret)
+   return ret;
} else {
fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
}
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2 10/11] drm/amd/display: Expose modifiers.

2020-09-04 Thread Bas Nieuwenhuizen
This expose modifier support on GFX9+.

Only modifiers that can be rendered on the current GPU are
added. This is to reduce the number of modifiers exposed.

The HW could expose more, but the best mechanism to decide
what to expose without an explosion in modifiers is still
to be decided, and in the meantime this should not regress
things from pre-modifiers and does not risk regressions as
we make up our mind in the future.

v2:
  - Added comment that D on Raven is only valid for 64bpp
and will be filtered based on format later.
  - Removed D tiling modes that weren't useful for 64bpp
on GFX10+.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +-
 1 file changed, 337 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ceb92a0dccdc..25b1c7c821d2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3978,6 +3978,335 @@ fill_gfx9_tiling_info_from_modifier(const struct 
amdgpu_device *adev,
}
 }
 
+enum dm_micro_swizzle {
+   MICRO_SWIZZLE_Z = 0,
+   MICRO_SWIZZLE_S = 1,
+   MICRO_SWIZZLE_D = 2,
+   MICRO_SWIZZLE_R = 3
+};
+
+static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+   struct amdgpu_device *adev = drm_to_adev(plane->dev);
+   const struct drm_format_info *info = drm_format_info(format);
+
+   enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) 
& 3;
+
+   if (!info)
+   return false;
+
+   /*
+* We always have to allow this modifier, because core DRM still
+* checks LINEAR support if userspace does not provide modifers.
+*/
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return true;
+
+   /*
+* The arbitrary tiling support for multiplane formats has not been 
hooked
+* up.
+*/
+   if (info->num_planes > 1)
+   return false;
+
+   /*
+* For D swizzle the canonical modifier depends on the bpp, so check
+* it here.
+*/
+   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
AMD_FMT_MOD_TILE_VER_GFX9 &&
+   adev->family >= AMDGPU_FAMILY_NV) {
+   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
+   return false;
+   }
+
+   if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
+   info->cpp[0] < 8)
+   return false;
+
+   if (modifier_has_dcc(modifier)) {
+   /* Per radeonsi comments 16/64 bpp are more complicated. */
+   if (info->cpp[0] != 4)
+   return false;
+   }
+
+   return true;
+}
+
+static void
+add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
+{
+   if (!*mods)
+   return;
+
+   if (*cap - *size < 1) {
+   uint64_t new_cap = *cap * 2;
+   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
GFP_KERNEL);
+
+   if (!new_mods) {
+   kfree(*mods);
+   *mods = NULL;
+   return;
+   }
+
+   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
+   kfree(*mods);
+   *mods = new_mods;
+   *cap = new_cap;
+   }
+
+   (*mods)[*size] = mod;
+   *size += 1;
+}
+
+static void
+add_gfx9_modifiers(const struct amdgpu_device *adev,
+  uint64_t **mods, uint64_t *size, uint64_t *capacity)
+{
+   int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
+   int pipe_xor_bits = min(8, pipes +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   int bank_xor_bits = min(8 - pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
+ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
+
+
+   if (adev->family == AMDGPU_FAMILY_RV) {
+   /* Raven2 and later */
+   bool has_constant_encode = adev->asic_type > CHIP_RAVEN || 
adev->external_rev_id >= 0x81;
+
+   /*
+* No _D DCC swizzles yet because we only allow 32bpp, which
+* doesn't support _D on DCN
+*/
+
+   if (has_constant_encode) {
+   add_modifier(mods, size, capacity, AMD_FMT_MOD |
+   AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_T

[PATCH v2 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats.

2020-09-04 Thread Bas Nieuwenhuizen
Silently accepting it could result in corruption.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a025897e2962..cb31b5ed19f7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3756,7 +3756,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
return 0;
 
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-   return 0;
+   return -EINVAL;
 
if (!dc->cap_funcs.get_dcc_compression_cap)
return -EINVAL;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2 03/11] drm/amd/display: Honor the offset for plane 0.

2020-09-04 Thread Bas Nieuwenhuizen
With modifiers I'd like to support non-dedicated buffers for
images.

Signed-off-by: Bas Nieuwenhuizen 
Cc: sta...@vger.kernel.org
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index cb31b5ed19f7..d06acaea16e8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3742,6 +3742,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
+   uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
uint64_t dcc_address;
@@ -3785,7 +3786,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
dcc->independent_64b_blks = i64b;
 
-   dcc_address = get_dcc_address(afb->address, info);
+   dcc_address = get_dcc_address(plane_address, info);
address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
 
@@ -3816,6 +3817,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
address->tmz_surface = tmz_surface;
 
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+   uint64_t addr = afb->address + fb->offsets[0];
+
plane_size->surface_size.x = 0;
plane_size->surface_size.y = 0;
plane_size->surface_size.width = fb->width;
@@ -3824,9 +3827,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
fb->pitches[0] / fb->format->cpp[0];
 
address->type = PLN_ADDR_TYPE_GRAPHICS;
-   address->grph.addr.low_part = lower_32_bits(afb->address);
-   address->grph.addr.high_part = upper_32_bits(afb->address);
+   address->grph.addr.low_part = lower_32_bits(addr);
+   address->grph.addr.high_part = upper_32_bits(addr);
} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
+   uint64_t luma_addr = afb->address + fb->offsets[0];
uint64_t chroma_addr = afb->address + fb->offsets[1];
 
plane_size->surface_size.x = 0;
@@ -3847,9 +3851,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
address->video_progressive.luma_addr.low_part =
-   lower_32_bits(afb->address);
+   lower_32_bits(luma_addr);
address->video_progressive.luma_addr.high_part =
-   upper_32_bits(afb->address);
+   upper_32_bits(luma_addr);
address->video_progressive.chroma_addr.low_part =
lower_32_bits(chroma_addr);
address->video_progressive.chroma_addr.high_part =
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2 04/11] drm/fourcc: Add AMD DRM modifiers.

2020-09-04 Thread Bas Nieuwenhuizen
This adds modifiers for GFX9+ AMD GPUs.

As the modifiers need a lot of parameters I split things out in
getters and setters.
  - Advantage: simplifies the code a lot
  - Disadvantage: Makes it harder to check that you're setting all
  the required fields.

The tiling modes seem to change every generatio, but the structure
of what each tiling mode is good for stays really similar. As such
the core of the modifier is
 - the tiling mode
 - a version. Not explicitly a GPU generation, but splitting out
   a new set of tiling equations.

Sometimes one or two tiling modes stay the same and for those we
specify a canonical version.

Then we have a bunch of parameters on how the compression works.
Different HW units have different requirements for these and we
actually have some conflicts here.

e.g. the render backends need a specific alignment but the display
unit only works with unaligned compression surfaces. To work around
that we have a DCC_RETILE option where both an aligned and unaligned
compression surface are allocated and a writer has to sync the
aligned surface to the unaligned surface on handoff.

Finally there are some GPU parameters that participate in the tiling
equations. These are constant for each GPU on the rendering/texturing
side. The display unit is very flexible however and supports all
of them :|

Some estimates:
 - Single GPU, render+texture: ~10 modifiers
 - All possible configs in a gen, display: ~1000 modifiers
 - Configs of actually existing GPUs in a gen: ~100 modifiers

For formats with a single plane everything gets put in a separate
DRM plane. However, this doesn't fit for some YUV formats, so if
the format has >1 plane, we let the driver pack the surfaces into
1 DRM plane per format plane.

This way we avoid X11 rendering onto the frontbuffer with DCC, but
still fit into 4 DRM planes.

Signed-off-by: Bas Nieuwenhuizen 
---
 include/uapi/drm/drm_fourcc.h | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 8bc0b31597d8..2f8d2b717285 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -804,6 +804,121 @@ extern "C" {
  */
 #define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1)
 
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ *   - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ *   - main surface in plane 0
+ *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is 
set)
+ *
+ * with DCC & DCC_RETILE:
+ *   - main surface in plane 0
+ *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each for format plane, based on the required alignment only.
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as 
canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastclear
+ * eliminate operation before a process transfers c

[PATCH v2 07/11] drm/amd/display: Refactor surface tiling setup.

2020-09-04 Thread Bas Nieuwenhuizen
Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 211 ++
 1 file changed, 116 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 72e16aa03504..4fb77b25e28c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3687,46 +3687,83 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+static void
+fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+uint64_t tiling_flags)
 {
-   uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+   /* Fill GFX8 params */
+   if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
+   unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
+
+   bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+   bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+   mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+   tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
+   num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
 
-   return offset ? (address + offset * 256) : 0;
+   /* XXX fix me for VI */
+   tiling_info->gfx8.num_banks = num_banks;
+   tiling_info->gfx8.array_mode =
+   DC_ARRAY_2D_TILED_THIN1;
+   tiling_info->gfx8.tile_split = tile_split;
+   tiling_info->gfx8.bank_width = bankw;
+   tiling_info->gfx8.bank_height = bankh;
+   tiling_info->gfx8.tile_aspect = mtaspect;
+   tiling_info->gfx8.tile_mode =
+   DC_ADDR_SURF_MICRO_TILING_DISPLAY;
+   } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
+   == DC_ARRAY_1D_TILED_THIN1) {
+   tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
+   }
+
+   tiling_info->gfx8.pipe_config =
+   AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+}
+
+static void
+fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info)
+{
+   tiling_info->gfx9.num_pipes =
+   adev->gfx.config.gb_addr_config_fields.num_pipes;
+   tiling_info->gfx9.num_banks =
+   adev->gfx.config.gb_addr_config_fields.num_banks;
+   tiling_info->gfx9.pipe_interleave =
+   adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
+   tiling_info->gfx9.num_shader_engines =
+   adev->gfx.config.gb_addr_config_fields.num_se;
+   tiling_info->gfx9.max_compressed_frags =
+   adev->gfx.config.gb_addr_config_fields.max_compress_frags;
+   tiling_info->gfx9.num_rb_per_se =
+   adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
+   tiling_info->gfx9.shaderEnable = 1;
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+   if (adev->asic_type == CHIP_SIENNA_CICHLID)
+   tiling_info->gfx9.num_pkrs = 
adev->gfx.config.gb_addr_config_fields.num_pkrs;
+#endif
 }
 
 static int
-fill_plane_dcc_attributes(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- const union dc_tiling_info *tiling_info,
- const uint64_t info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- bool force_disable_dcc)
+validate_dcc(struct amdgpu_device *adev,
+const enum surface_pixel_format format,
+const enum dc_rotation_angle rotation,
+const union dc_tiling_info *tiling_info,
+const struct dc_plane_dcc_param *dcc,
+const struct dc_plane_address *address,
+const struct plane_size *plane_size)
 {
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
-   uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
-   uint64_t dcc_address;
 
memset(&input, 0, sizeof(input));
   

[PATCH v2 09/11] drm/amd/display: Add formats for DCC with 2/3 planes.

2020-09-04 Thread Bas Nieuwenhuizen
For DCC we will use 2/3 planes to avoid X rendering to the frontbuffer
with DCC compressed images. To make this work with the core KMS
validation we need to add extra formats with the extra planes.

However, due to flexibility we set bpp = 0 for the extra planes and
do the validation ourselves.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 545d177bf703..ceb92a0dccdc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -173,6 +173,9 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state 
*stream);
 static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
 
+static const struct drm_format_info *
+amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
+
 /*
  * dm_vblank_get_counter
  *
@@ -2021,6 +2024,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
 
 static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
+   .get_format_info = amd_get_format_info,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
@@ -3855,6 +3859,98 @@ modifier_gfx9_swizzle_mode(uint64_t modifier)
return AMD_FMT_MOD_GET(TILE, modifier);
 }
 
+static const struct drm_format_info dcc_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+ .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1

[PATCH v2 08/11] drm/amd/display: Set DC options from modifiers.

2020-09-04 Thread Bas Nieuwenhuizen
This sets the DC tiling options from the modifier, if modifiers
are used for the FB. This patch by itself does not expose the
support yet though.

There is not much validation yet to limit the scope of this
patch, but the current validation is at the same level as
the BO metadata path.

v2: Add modifier check to should_reset_plane.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 102 --
 1 file changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 4fb77b25e28c..545d177bf703 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3840,6 +3840,83 @@ fill_gfx9_plane_attributes_from_flags(struct 
amdgpu_device *adev,
return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+   return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return 0;
+
+   return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+   union dc_tiling_info *tiling_info,
+   uint64_t modifier)
+{
+   unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, 
modifier);
+   unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, 
modifier);
+   unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+   unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+   fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+   if (!IS_AMD_FMT_MOD(modifier))
+   return;
+
+   tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+   tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - 
pipes_log2);
+
+   if (adev->family >= AMDGPU_FAMILY_NV) {
+   tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+   } else {
+   tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+   /* for DCC we know it isn't rb aligned, so rb_per_se doesn't 
matter. */
+   }
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ const enum surface_pixel_format 
format,
+ const enum dc_rotation_angle rotation,
+ const struct plane_size *plane_size,
+ union dc_tiling_info *tiling_info,
+ struct dc_plane_dcc_param *dcc,
+ struct dc_plane_address *address,
+ const bool force_disable_dcc)
+{
+   const uint64_t modifier = afb->base.modifier;
+   int ret;
+
+   fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+   tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+   if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+   uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+   dcc->enable = 1;
+   dcc->meta_pitch = afb->base.pitches[1];
+   dcc->independent_64b_blks = 
AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+   }
+
+   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
 const struct amdgpu_framebuffer *afb,
@@ -3908,12 +3985,22 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, 
rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   force_disable_dcc);
-   if (ret)
-   return ret;
+   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
+   
rotation, plane_size,
+  

[PATCH v2 05/11] drm/amd/display: Store tiling_flags in the framebuffer.

2020-09-04 Thread Bas Nieuwenhuizen
This moves the tiling_flags to the framebuffer creation.
This way the time of the "tiling" decision is the same as it
would be with modifiers.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 48 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
 4 files changed, 59 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 68e658998b55..638ce7528d30 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -537,6 +537,39 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer 
*amdgpu_fb,
+ uint64_t *tiling_flags, bool *tmz_surface)
+{
+   struct amdgpu_bo *rbo;
+   int r;
+
+   if (!amdgpu_fb) {
+   *tiling_flags = 0;
+   *tmz_surface = false;
+   return 0;
+   }
+
+   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
+   r = amdgpu_bo_reserve(rbo, false);
+
+   if (unlikely(r)) {
+   /* Don't show error message when returning -ERESTARTSYS */
+   if (r != -ERESTARTSYS)
+   DRM_ERROR("Unable to reserve buffer: %d\n", r);
+   return r;
+   }
+
+   if (tiling_flags)
+   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
+
+   if (tmz_surface)
+   *tmz_surface = amdgpu_bo_encrypted(rbo);
+
+   amdgpu_bo_unreserve(rbo);
+
+   return r;
+}
+
 int amdgpu_display_framebuffer_init(struct drm_device *dev,
struct amdgpu_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -546,11 +579,18 @@ int amdgpu_display_framebuffer_init(struct drm_device 
*dev,
rfb->base.obj[0] = obj;
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
-   if (ret) {
-   rfb->base.obj[0] = NULL;
-   return ret;
-   }
+   if (ret)
+   goto fail;
+
+   ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, 
&rfb->tmz_surface);
+   if (ret)
+   goto fail;
+
return 0;
+
+fail:
+   rfb->base.obj[0] = NULL;
+   return ret;
 }
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index aa3e22be4f2d..b0d57e3c8c6a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -303,6 +303,9 @@ struct amdgpu_display_funcs {
 struct amdgpu_framebuffer {
struct drm_framebuffer base;
 
+   uint64_t tiling_flags;
+   bool tmz_surface;
+
/* caching for later use */
uint64_t address;
 };
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d06acaea16e8..72e16aa03504 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3687,39 +3687,6 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
-  uint64_t *tiling_flags, bool *tmz_surface)
-{
-   struct amdgpu_bo *rbo;
-   int r;
-
-   if (!amdgpu_fb) {
-   *tiling_flags = 0;
-   *tmz_surface = false;
-   return 0;
-   }
-
-   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
-   r = amdgpu_bo_reserve(rbo, false);
-
-   if (unlikely(r)) {
-   /* Don't show error message when returning -ERESTARTSYS */
-   if (r != -ERESTARTSYS)
-   DRM_ERROR("Unable to reserve buffer: %d\n", r);
-   return r;
-   }
-
-   if (tiling_flags)
-   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
-
-   if (tmz_surface)
-   *tmz_surface = amdgpu_bo_encrypted(rbo);
-
-   amdgpu_bo_unreserve(rbo);
-
-   return r;
-}
-
 static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
 {
uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
@@ -4127,7 +4094,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
struct drm_crtc_state *crtc_state)
 {
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
-   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   struct amdgpu_framebuff

Re: [PATCH v2 00/11] amd/display: Add GFX9+ modifier support.

2020-09-07 Thread Bas Nieuwenhuizen
On Mon, Sep 7, 2020 at 10:51 AM Ernst Sjöstrand  wrote:
>
>
>
> Den fre 4 sep. 2020 kl 18:07 skrev Bas Nieuwenhuizen 
> :
>>
>> This adds modifier support to radeonsi.
>
>
> Wouldn't it be more correct to say that this adds modifier support to amdgpu 
> (and enables it to work with radeonsi OpenGL)
> or something like that?

Yep, this was copy pasted from the userspace MR ...

>
> //E
>
>>
>> It has been tested on
>>
>> - VEGA10, RAVEN, NAVI14
>> - weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)
>>
>> and includes some basic testing of the layout code.
>>
>> The main goal is to keep it somewhat simple and regression free, so
>> on the display side this series only exposes what the current GPU
>> can render to. While we could expose more I think that is more
>> suitable for follow-up work as the benefit would be minimal and
>> there are some more design discussion there to discuss that are
>> orthogonal from the initial implementation.
>>
>> Similarly this series only exposes 32-bpp displayable DCC in the cases
>> that radeonsi would use it and any extra capabilities here should be
>> future work.
>>
>> I believe these are by far the most complicated modifiers we've seen
>> up till now, mostly related to
>>
>> - GPU identification for cases where it matters wrt tiling.
>> - Every generation having tiling layout changes
>> - Compression settings.
>>
>> I believe the complexity is necessary as every layout should be different
>> and all layouts should be the best in some situation (though not all
>> combinations of GPU parameters will actually have an existing GPU).
>>
>> That said, on the render side the number of modifiers actually listed for
>> a given GPU is ~10, and in the current implementation that is the same
>> for the display side. (we could expose more actually differing layouts
>> on the display side for cross-GPU compatibility, but I consider that
>> out of scope for this initial work).
>>
>> This series can be found on
>> https://github.com/BNieuwenhuizen/linux/tree/modifiers
>>
>> An userspace implementation in radeonsi can be found on
>> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176
>>
>> v2:
>>
>> Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
>> addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
>> constant econding modifers only get exposed on RAVEN2 and newer.
>>
>> Bas Nieuwenhuizen (11):
>>   drm/amd/display: Do not silently accept DCC for multiplane formats.
>>   drm/amd: Init modifier field of helper fb.
>>   drm/amd/display: Honor the offset for plane 0.
>>   drm/fourcc:  Add AMD DRM modifiers.
>>   drm/amd/display: Store tiling_flags in the framebuffer.
>>   drm/amd/display: Convert tiling_flags to modifiers.
>>   drm/amd/display: Refactor surface tiling setup.
>>   drm/amd/display: Set DC options from modifiers.
>>   drm/amd/display: Add formats for DCC with 2/3 planes.
>>   drm/amd/display: Expose modifiers.
>>   drm/amd/display: Clean up GFX9 tiling_flags path.
>>
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c|   2 +-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   3 +
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
>>  include/uapi/drm/drm_fourcc.h | 115 +++
>>  6 files changed, 880 insertions(+), 165 deletions(-)
>>
>> --
>> 2.28.0
>>
>> ___
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH v2 04/11] drm/fourcc: Add AMD DRM modifiers.

2020-09-07 Thread Bas Nieuwenhuizen
Thanks, fixed both locally.

On Mon, Sep 7, 2020 at 10:44 AM Pierre-Eric Pelloux-Prayer
 wrote:
>
> Hi Bas,
>
> 2 small typos you may want to fix:
>
> On 04/09/2020 18:07, Bas Nieuwenhuizen wrote:
> > This adds modifiers for GFX9+ AMD GPUs.
> >
> > As the modifiers need a lot of parameters I split things out in
> > getters and setters.
> >   - Advantage: simplifies the code a lot
> >   - Disadvantage: Makes it harder to check that you're setting all
> >   the required fields.
> >
> > The tiling modes seem to change every generatio, but the structure
>
> "generatio" -> "generation"
>
> > of what each tiling mode is good for stays really similar. As such
> > the core of the modifier is
> >  - the tiling mode
> >  - a version. Not explicitly a GPU generation, but splitting out
> >a new set of tiling equations.
>
> [...]
> > + * with DCC & DCC_RETILE:
> > + *   - main surface in plane 0
> > + *   - displayable DCC surface in plane 1 (not RB-aligned & not 
> > pipe-aligned)
> > + *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
> > + *
> > + * For multi-plane formats the above surfaces get merged into one plane for
> > + * each for format plane, based on the required alignment only.
>
> "for each for format plane" => "for each format plane"?
>
>
> Pierre-Eric
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amdgpu/display: initialize the variable 'i'

2021-02-22 Thread Bas Nieuwenhuizen
I think Alex moved to gitlab for his branches

On Tue, Feb 23, 2021, 12:50 AM Simon Ser  wrote:

> On Tuesday, February 23rd, 2021 at 12:44 AM, Nathan Chancellor <
> nat...@kernel.org> wrote:
>
> > On Mon, Feb 22, 2021 at 11:05:17PM +, Simon Ser wrote:
> > > On Monday, February 22nd, 2021 at 8:25 PM, Souptick Joarder <
> jrdr.li...@gmail.com> wrote:
> > >
> > > > >>
> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:9804:38:
> > > > >> warning: variable 'i' is uninitialized when used here
> > > > >> [-Wuninitialized]
> > > >timing  = &edid->detailed_timings[i];
> > > >  ^
> > > >
> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:9714:7:
> > > > note: initialize the variable 'i' to silence this warning
> > > >int i;
> > > > ^
> > > >  = 0
> > > >1 warning generated.
> > > >
> > > > Initialize the variable 'i'.
> > >
> > > Hm, I see this variable already initialized in the loop:
> > >
> > > for (i = 0; i < 4; i++) {
> > >
> > > This is the branch agd5f/drm-next.
> >
> > That is in the
> >
> >   if (amdgpu_dm_connector->dc_sink->sink_signal ==
> SIGNAL_TYPE_DISPLAY_PORT
> >   || amdgpu_dm_connector->dc_sink->sink_signal ==
> SIGNAL_TYPE_EDP) {
> >
> > branch not the
> >
> >   } else if (edid && amdgpu_dm_connector->dc_sink->sink_signal ==
> SIGNAL_TYPE_HDMI_TYPE_A) {
> >
> > branch, where i is indeed used uninitialized like clang complains about.
> >
> > I am not at all familiar with the code so I cannot say if this fix is
> > the proper one but it is definitely a legitimate issue.
>
> I think you have an outdated branch. In my checkout, i is not used in the
> first
> branch, and is initialized in the second one.
>
>
> https://cgit.freedesktop.org/~agd5f/linux/tree/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c?h=drm-next#n9700
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH] drm/amd/display: Initialize num_pkrs on VANGOGH.

2020-10-20 Thread Bas Nieuwenhuizen
As far a I can tell uses a variant of DCN3xx which uses num_pkrs.

If we do not initialize the variable we will set the register field
to ilog2(0) = -1, though the mask will reduce that to 7. Pretty sure
7 is not the value we want here.

Signed-off-by: Bas Nieuwenhuizen 
---

Found while rebasing my modifiers series. Not tested on HW.

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6855aad7f312..2713caac4f2a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4074,7 +4074,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 #ifdef CONFIG_DRM_AMD_DC_DCN3_0
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
adev->asic_type == CHIP_NAVY_FLOUNDER ||
-   adev->asic_type == CHIP_DIMGREY_CAVEFISH)
+   adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
+   adev->asic_type == CHIP_VANGOGH)
tiling_info->gfx9.num_pkrs = 
adev->gfx.config.gb_addr_config_fields.num_pkrs;
 #endif
ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amd/display: Interpret log_2(0) as 0

2020-10-21 Thread Bas Nieuwenhuizen
On Wed, Oct 21, 2020 at 6:09 PM Harry Wentland  wrote:
>
> Even though log(0) is technically undefined our code assumes that
> log_2(0) is 0. This mirrors the current behavior of our log_2
> implementation on non-Linux platforms.
>
> Signed-off-by: Harry Wentland 
> ---
>
> What's num_pkrs value is upstream Mesa providing for CHIP_VANGOGH?

So mesa isn't quite providing a num_pkrs value to the HW as the render
HW doesn't require you to set one, it assumes something.

In practice mesa still uses num_pkrs, which is provided by a readback
of the GB_ADDR_CFG(CONFIG?) register info provided by the kernel. This
can be used for e.g. determining texture coordinates (like we do for
the displayable DCC transform) but otherwise isn't really needed,
since the tile size for texture allocation is not dependent on
num_pkrs.

so outside of displayable DCC I think you'd be able to get far in mesa
with a wrong num_pkrs.

>
> I saw that problem at bringup with an internal Mesa and had this fix
> for it.
>
> Harry
>
>  drivers/gpu/drm/amd/display/dc/basics/conversion.h | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.h 
> b/drivers/gpu/drm/amd/display/dc/basics/conversion.h
> index ade785c4fdc7..da9883ec7b1c 100644
> --- a/drivers/gpu/drm/amd/display/dc/basics/conversion.h
> +++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.h
> @@ -40,7 +40,11 @@ void convert_float_matrix(
>
>  static inline unsigned int log_2(unsigned int num)
>  {
> -   return ilog2(num);
> +   /*
> +* Technically log(0) is undefined, but our code is structured
> +* in a way that assumes log(0) = 0
> +*/
> +   return num ? ilog2(num) : num;
>  }
>
>  #endif
> --
> 2.28.0
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 00/11] amd/display: Add GFX9+ modifier support.

2020-10-21 Thread Bas Nieuwenhuizen
This adds modifier support to the amdgpu kernel drivers for GFX9 and
later GPUs. It has been tested on

- VEGA10, RAVEN, NAVI14
- weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)

and includes some basic testing of the layout code.

The main goal is to keep it somewhat simple and regression free, so
on the display side this series only exposes what the current GPU
can render to. While we could expose more I think that is more
suitable for follow-up work as the benefit would be minimal and
there are some more design discussion there to discuss that are
orthogonal from the initial implementation.

Similarly this series only exposes 32-bpp displayable DCC in the cases
that radeonsi would use it and any extra capabilities here should be
future work.

I believe these are by far the most complicated modifiers we've seen
up till now, mostly related to

- GPU identification for cases where it matters wrt tiling.
- Every generation having tiling layout changes
- Compression settings.

I believe the complexity is necessary as every layout should be different
and all layouts should be the best in some situation (though not all
combinations of GPU parameters will actually have an existing GPU).

That said, on the render side the number of modifiers actually listed for
a given GPU is ~10, and in the current implementation that is the same
for the display side. (we could expose more actually differing layouts
on the display side for cross-GPU compatibility, but I consider that
out of scope for this initial work).

This series can be found on
https://github.com/BNieuwenhuizen/linux/tree/modifiers

An userspace implementation in radeonsi can be found on
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176

which has been reviewed and is ready for submission once these kernel
patches land.

v2:

Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
constant econding modifers only get exposed on RAVEN2 and newer.

v3:

Fixed some typos, rebased and CCing more people to actually get a review.

Bas Nieuwenhuizen (11):
  drm/amd/display: Do not silently accept DCC for multiplane formats.
  drm/amd: Init modifier field of helper fb.
  drm/amd/display: Honor the offset for plane 0.
  drm/fourcc:  Add AMD DRM modifiers.
  drm/amd/display: Store tiling_flags in the framebuffer.
  drm/amd/display: Convert tiling_flags to modifiers.
  drm/amd/display: Refactor surface tiling setup.
  drm/amd/display: Set DC options from modifiers.
  drm/amd/display: Add formats for DCC with 2/3 planes.
  drm/amd/display: Expose modifiers.
  drm/amd/display: Clean up GFX9 tiling_flags path.

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
 include/uapi/drm/drm_fourcc.h | 115 +++
 6 files changed, 880 insertions(+), 165 deletions(-)

-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers.

2020-10-21 Thread Bas Nieuwenhuizen
This adds modifiers for GFX9+ AMD GPUs.

As the modifiers need a lot of parameters I split things out in
getters and setters.
  - Advantage: simplifies the code a lot
  - Disadvantage: Makes it harder to check that you're setting all
  the required fields.

The tiling modes seem to change every generation, but the structure
of what each tiling mode is good for stays really similar. As such
the core of the modifier is
 - the tiling mode
 - a version. Not explicitly a GPU generation, but splitting out
   a new set of tiling equations.

Sometimes one or two tiling modes stay the same and for those we
specify a canonical version.

Then we have a bunch of parameters on how the compression works.
Different HW units have different requirements for these and we
actually have some conflicts here.

e.g. the render backends need a specific alignment but the display
unit only works with unaligned compression surfaces. To work around
that we have a DCC_RETILE option where both an aligned and unaligned
compression surface are allocated and a writer has to sync the
aligned surface to the unaligned surface on handoff.

Finally there are some GPU parameters that participate in the tiling
equations. These are constant for each GPU on the rendering/texturing
side. The display unit is very flexible however and supports all
of them :|

Some estimates:
 - Single GPU, render+texture: ~10 modifiers
 - All possible configs in a gen, display: ~1000 modifiers
 - Configs of actually existing GPUs in a gen: ~100 modifiers

For formats with a single plane everything gets put in a separate
DRM plane. However, this doesn't fit for some YUV formats, so if
the format has >1 plane, we let the driver pack the surfaces into
1 DRM plane per format plane.

This way we avoid X11 rendering onto the frontbuffer with DCC, but
still fit into 4 DRM planes.

Signed-off-by: Bas Nieuwenhuizen 
---
 include/uapi/drm/drm_fourcc.h | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 82f327801267..df56e71a7380 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
modifier)
  */
 #define AMLOGIC_FBC_OPTION_MEM_SAVING  (1ULL << 0)
 
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ *   - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ *   - main surface in plane 0
+ *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is 
set)
+ *
+ * with DCC & DCC_RETILE:
+ *   - main surface in plane 0
+ *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each format plane, based on the required alignment only.
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as 
canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastclear
+ * eliminate operation b

[PATCH v3 02/11] drm/amd: Init modifier field of helper fb.

2020-10-21 Thread Bas Nieuwenhuizen
Otherwise the field ends up being used uninitialized when
enabling modifiers, failing validation with high likelyhood.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index e2c2eb45a793..77dd2a189746 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -201,7 +201,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
struct amdgpu_device *adev = rfbdev->adev;
struct fb_info *info;
struct drm_framebuffer *fb = NULL;
-   struct drm_mode_fb_cmd2 mode_cmd;
+   struct drm_mode_fb_cmd2 mode_cmd = {0};
struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *abo = NULL;
int ret;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0.

2020-10-21 Thread Bas Nieuwenhuizen
With modifiers I'd like to support non-dedicated buffers for
images.

Signed-off-by: Bas Nieuwenhuizen 
Cc: sta...@vger.kernel.org # 5.1.0
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 73987fdb6a09..833887b9b0ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3894,6 +3894,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
+   uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
uint64_t dcc_address;
@@ -3937,7 +3938,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
dcc->independent_64b_blks = i64b;
 
-   dcc_address = get_dcc_address(afb->address, info);
+   dcc_address = get_dcc_address(plane_address, info);
address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
 
@@ -3968,6 +3969,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
address->tmz_surface = tmz_surface;
 
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+   uint64_t addr = afb->address + fb->offsets[0];
+
plane_size->surface_size.x = 0;
plane_size->surface_size.y = 0;
plane_size->surface_size.width = fb->width;
@@ -3976,9 +3979,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
fb->pitches[0] / fb->format->cpp[0];
 
address->type = PLN_ADDR_TYPE_GRAPHICS;
-   address->grph.addr.low_part = lower_32_bits(afb->address);
-   address->grph.addr.high_part = upper_32_bits(afb->address);
+   address->grph.addr.low_part = lower_32_bits(addr);
+   address->grph.addr.high_part = upper_32_bits(addr);
} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
+   uint64_t luma_addr = afb->address + fb->offsets[0];
uint64_t chroma_addr = afb->address + fb->offsets[1];
 
plane_size->surface_size.x = 0;
@@ -3999,9 +4003,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
address->video_progressive.luma_addr.low_part =
-   lower_32_bits(afb->address);
+   lower_32_bits(luma_addr);
address->video_progressive.luma_addr.high_part =
-   upper_32_bits(afb->address);
+   upper_32_bits(luma_addr);
address->video_progressive.chroma_addr.low_part =
lower_32_bits(chroma_addr);
address->video_progressive.chroma_addr.high_part =
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 11/11] drm/amd/display: Clean up GFX9 tiling_flags path.

2020-10-21 Thread Bas Nieuwenhuizen
We're unconditionally using modifiers internally for GFX9+ now.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 ++-
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a1ce325f2fd1..ed7215737b22 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3948,57 +3948,6 @@ validate_dcc(struct amdgpu_device *adev,
return 0;
 }
 
-static void
-fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
-  struct dc_plane_dcc_param *dcc,
-  struct dc_plane_address *address,
-  const uint64_t flags, bool force_disable_dcc)
-{
-   uint64_t dcc_address;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
-   uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
-
-   if (!offset || force_disable_dcc)
-   return;
-
-   dcc->enable = 1;
-   dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
-   dcc->independent_64b_blks = i64b;
-
-   dcc_address = plane_address + (uint64_t)offset * 256;
-   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
-   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
-}
-
-
-static int
-fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- union dc_tiling_info *tiling_info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- uint64_t tiling_flags,
- bool force_disable_dcc)
-{
-   int ret;
-
-   fill_gfx9_tiling_info_from_device(adev, tiling_info);
-
-   tiling_info->gfx9.swizzle =
-   AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-
-   fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, 
force_disable_dcc);
-   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
 static bool
 modifier_has_dcc(uint64_t modifier)
 {
@@ -4565,22 +4514,13 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
-   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
-   
rotation, plane_size,
-   
tiling_info, dcc,
-   address,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   } else {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, 
format, rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   }
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, 
format,
+   rotation, 
plane_size,
+   tiling_info, 
dcc,
+   address,
+   
force_disable_dcc);
+   if (ret)
+   return ret;
} else {
fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
}
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer.

2020-10-21 Thread Bas Nieuwenhuizen
This moves the tiling_flags to the framebuffer creation.
This way the time of the "tiling" decision is the same as it
would be with modifiers.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 48 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
 4 files changed, 59 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 9e92d2a070ac..1a2664c3fc26 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -541,6 +541,39 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer 
*amdgpu_fb,
+ uint64_t *tiling_flags, bool *tmz_surface)
+{
+   struct amdgpu_bo *rbo;
+   int r;
+
+   if (!amdgpu_fb) {
+   *tiling_flags = 0;
+   *tmz_surface = false;
+   return 0;
+   }
+
+   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
+   r = amdgpu_bo_reserve(rbo, false);
+
+   if (unlikely(r)) {
+   /* Don't show error message when returning -ERESTARTSYS */
+   if (r != -ERESTARTSYS)
+   DRM_ERROR("Unable to reserve buffer: %d\n", r);
+   return r;
+   }
+
+   if (tiling_flags)
+   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
+
+   if (tmz_surface)
+   *tmz_surface = amdgpu_bo_encrypted(rbo);
+
+   amdgpu_bo_unreserve(rbo);
+
+   return r;
+}
+
 int amdgpu_display_framebuffer_init(struct drm_device *dev,
struct amdgpu_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -550,11 +583,18 @@ int amdgpu_display_framebuffer_init(struct drm_device 
*dev,
rfb->base.obj[0] = obj;
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
-   if (ret) {
-   rfb->base.obj[0] = NULL;
-   return ret;
-   }
+   if (ret)
+   goto fail;
+
+   ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, 
&rfb->tmz_surface);
+   if (ret)
+   goto fail;
+
return 0;
+
+fail:
+   rfb->base.obj[0] = NULL;
+   return ret;
 }
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 345cb0464370..39866ed81c16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -304,6 +304,9 @@ struct amdgpu_display_funcs {
 struct amdgpu_framebuffer {
struct drm_framebuffer base;
 
+   uint64_t tiling_flags;
+   bool tmz_surface;
+
/* caching for later use */
uint64_t address;
 };
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 833887b9b0ad..5a0efaefbd7f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,39 +3839,6 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
-  uint64_t *tiling_flags, bool *tmz_surface)
-{
-   struct amdgpu_bo *rbo;
-   int r;
-
-   if (!amdgpu_fb) {
-   *tiling_flags = 0;
-   *tmz_surface = false;
-   return 0;
-   }
-
-   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
-   r = amdgpu_bo_reserve(rbo, false);
-
-   if (unlikely(r)) {
-   /* Don't show error message when returning -ERESTARTSYS */
-   if (r != -ERESTARTSYS)
-   DRM_ERROR("Unable to reserve buffer: %d\n", r);
-   return r;
-   }
-
-   if (tiling_flags)
-   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
-
-   if (tmz_surface)
-   *tmz_surface = amdgpu_bo_encrypted(rbo);
-
-   amdgpu_bo_unreserve(rbo);
-
-   return r;
-}
-
 static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
 {
uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
@@ -4287,7 +4254,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
struct drm_crtc_state *crtc_state)
 {
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
-   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   struct amdgpu_framebuff

[PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats.

2020-10-21 Thread Bas Nieuwenhuizen
Silently accepting it could result in corruption.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2713caac4f2a..73987fdb6a09 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3908,7 +3908,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
return 0;
 
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-   return 0;
+   return -EINVAL;
 
if (!dc->cap_funcs.get_dcc_compression_cap)
return -EINVAL;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v3 06/11] drm/amd/display: Convert tiling_flags to modifiers.

2020-10-21 Thread Bas Nieuwenhuizen
This way the modifier path gets exercised all the time, improving
testing. Furthermore, for modifiers this is required as getfb2
will always return the modifier if the driver sets allow_fb_modifiers.

This only triggers once allow_fb_modifiers is set.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 123 
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1a2664c3fc26..89c3ead36501 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static void amdgpu_display_flip_callback(struct dma_fence *f,
@@ -541,6 +542,121 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
+{
+   struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
+   uint64_t modifier = 0;
+
+   if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE)) {
+   modifier = DRM_FORMAT_MOD_LINEAR;
+   } else {
+   int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE);
+   bool has_xor = swizzle >= 16;
+   int block_size_bits;
+   int version;
+   int pipe_xor_bits = 0;
+   int bank_xor_bits = 0;
+   int packers = 0;
+   uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, 
DCC_OFFSET_256B);
+
+   switch (swizzle >> 2) {
+   case 0: /* 256B */
+   block_size_bits = 8;
+   break;
+   case 1: /* 4KiB */
+   case 5: /* 4KiB _X */
+   block_size_bits = 12;
+   break;
+   case 2: /* 64KiB */
+   case 4: /* 64 KiB _T */
+   case 6: /* 64 KiB _X */
+   block_size_bits = 16;
+   break;
+   default:
+   /* RESERVED or VAR */
+   return -EINVAL;
+   }
+
+   if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+   version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
+   else if (adev->family == AMDGPU_FAMILY_NV)
+   version = AMD_FMT_MOD_TILE_VER_GFX10;
+   else
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+
+   switch (swizzle & 3) {
+   case 0: /* Z microtiling */
+   return -EINVAL;
+   case 1: /* S microtiling */
+   if (!has_xor)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 2:
+   if (!has_xor && afb->base.format->cpp[0] != 4)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 3:
+   break;
+   }
+
+   if (has_xor) {
+   switch (version) {
+   case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   packers = min(block_size_bits - 8 - 
pipe_xor_bits,
+ 
ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX10:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX9:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   bank_xor_bits = min(block_size_bits - 8 - 
pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   break;
+   }
+   }
+
+   modifier = AMD_FMT_MOD |
+  AMD_FMT_MOD_SET(TILE, 
AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
+  AMD_FMT_MOD_SET(TILE_VERSION, version) |
+  AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |

[PATCH v3 08/11] drm/amd/display: Set DC options from modifiers.

2020-10-21 Thread Bas Nieuwenhuizen
This sets the DC tiling options from the modifier, if modifiers
are used for the FB. This patch by itself does not expose the
support yet though.

There is not much validation yet to limit the scope of this
patch, but the current validation is at the same level as
the BO metadata path.

v2: Add modifier check to should_reset_plane.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 102 --
 1 file changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 479c886816d9..034397c1f2b1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3995,6 +3995,83 @@ fill_gfx9_plane_attributes_from_flags(struct 
amdgpu_device *adev,
return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+   return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return 0;
+
+   return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+   union dc_tiling_info *tiling_info,
+   uint64_t modifier)
+{
+   unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, 
modifier);
+   unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, 
modifier);
+   unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+   unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+   fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+   if (!IS_AMD_FMT_MOD(modifier))
+   return;
+
+   tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+   tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - 
pipes_log2);
+
+   if (adev->family >= AMDGPU_FAMILY_NV) {
+   tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+   } else {
+   tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+   /* for DCC we know it isn't rb aligned, so rb_per_se doesn't 
matter. */
+   }
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ const enum surface_pixel_format 
format,
+ const enum dc_rotation_angle rotation,
+ const struct plane_size *plane_size,
+ union dc_tiling_info *tiling_info,
+ struct dc_plane_dcc_param *dcc,
+ struct dc_plane_address *address,
+ const bool force_disable_dcc)
+{
+   const uint64_t modifier = afb->base.modifier;
+   int ret;
+
+   fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+   tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+   if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+   uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+   dcc->enable = 1;
+   dcc->meta_pitch = afb->base.pitches[1];
+   dcc->independent_64b_blks = 
AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+   }
+
+   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
 const struct amdgpu_framebuffer *afb,
@@ -4063,12 +4140,22 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, 
rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   force_disable_dcc);
-   if (ret)
-   return ret;
+   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
+   
rotation, plane_size,
+  

[PATCH v3 10/11] drm/amd/display: Expose modifiers.

2020-10-21 Thread Bas Nieuwenhuizen
This expose modifier support on GFX9+.

Only modifiers that can be rendered on the current GPU are
added. This is to reduce the number of modifiers exposed.

The HW could expose more, but the best mechanism to decide
what to expose without an explosion in modifiers is still
to be decided, and in the meantime this should not regress
things from pre-modifiers and does not risk regressions as
we make up our mind in the future.

v2:
  - Added comment that D on Raven is only valid for 64bpp
and will be filtered based on format later.
  - Removed D tiling modes that weren't useful for 64bpp
on GFX10+.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +-
 1 file changed, 337 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6b33e030fe20..a1ce325f2fd1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4133,6 +4133,335 @@ fill_gfx9_tiling_info_from_modifier(const struct 
amdgpu_device *adev,
}
 }
 
+enum dm_micro_swizzle {
+   MICRO_SWIZZLE_Z = 0,
+   MICRO_SWIZZLE_S = 1,
+   MICRO_SWIZZLE_D = 2,
+   MICRO_SWIZZLE_R = 3
+};
+
+static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+   struct amdgpu_device *adev = drm_to_adev(plane->dev);
+   const struct drm_format_info *info = drm_format_info(format);
+
+   enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) 
& 3;
+
+   if (!info)
+   return false;
+
+   /*
+* We always have to allow this modifier, because core DRM still
+* checks LINEAR support if userspace does not provide modifers.
+*/
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return true;
+
+   /*
+* The arbitrary tiling support for multiplane formats has not been 
hooked
+* up.
+*/
+   if (info->num_planes > 1)
+   return false;
+
+   /*
+* For D swizzle the canonical modifier depends on the bpp, so check
+* it here.
+*/
+   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
AMD_FMT_MOD_TILE_VER_GFX9 &&
+   adev->family >= AMDGPU_FAMILY_NV) {
+   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
+   return false;
+   }
+
+   if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
+   info->cpp[0] < 8)
+   return false;
+
+   if (modifier_has_dcc(modifier)) {
+   /* Per radeonsi comments 16/64 bpp are more complicated. */
+   if (info->cpp[0] != 4)
+   return false;
+   }
+
+   return true;
+}
+
+static void
+add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
+{
+   if (!*mods)
+   return;
+
+   if (*cap - *size < 1) {
+   uint64_t new_cap = *cap * 2;
+   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
GFP_KERNEL);
+
+   if (!new_mods) {
+   kfree(*mods);
+   *mods = NULL;
+   return;
+   }
+
+   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
+   kfree(*mods);
+   *mods = new_mods;
+   *cap = new_cap;
+   }
+
+   (*mods)[*size] = mod;
+   *size += 1;
+}
+
+static void
+add_gfx9_modifiers(const struct amdgpu_device *adev,
+  uint64_t **mods, uint64_t *size, uint64_t *capacity)
+{
+   int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
+   int pipe_xor_bits = min(8, pipes +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   int bank_xor_bits = min(8 - pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
+ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
+
+
+   if (adev->family == AMDGPU_FAMILY_RV) {
+   /* Raven2 and later */
+   bool has_constant_encode = adev->asic_type > CHIP_RAVEN || 
adev->external_rev_id >= 0x81;
+
+   /*
+* No _D DCC swizzles yet because we only allow 32bpp, which
+* doesn't support _D on DCN
+*/
+
+   if (has_constant_encode) {
+   add_modifier(mods, size, capacity, AMD_FMT_MOD |
+   AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_T

[PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup.

2020-10-21 Thread Bas Nieuwenhuizen
Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 222 ++
 1 file changed, 119 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5a0efaefbd7f..479c886816d9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,46 +3839,86 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+static void
+fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+uint64_t tiling_flags)
 {
-   uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+   /* Fill GFX8 params */
+   if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
+   unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
+
+   bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+   bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+   mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+   tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
+   num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
+
+   /* XXX fix me for VI */
+   tiling_info->gfx8.num_banks = num_banks;
+   tiling_info->gfx8.array_mode =
+   DC_ARRAY_2D_TILED_THIN1;
+   tiling_info->gfx8.tile_split = tile_split;
+   tiling_info->gfx8.bank_width = bankw;
+   tiling_info->gfx8.bank_height = bankh;
+   tiling_info->gfx8.tile_aspect = mtaspect;
+   tiling_info->gfx8.tile_mode =
+   DC_ADDR_SURF_MICRO_TILING_DISPLAY;
+   } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
+   == DC_ARRAY_1D_TILED_THIN1) {
+   tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
+   }
 
-   return offset ? (address + offset * 256) : 0;
+   tiling_info->gfx8.pipe_config =
+   AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+}
+
+static void
+fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info)
+{
+   tiling_info->gfx9.num_pipes =
+   adev->gfx.config.gb_addr_config_fields.num_pipes;
+   tiling_info->gfx9.num_banks =
+   adev->gfx.config.gb_addr_config_fields.num_banks;
+   tiling_info->gfx9.pipe_interleave =
+   adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
+   tiling_info->gfx9.num_shader_engines =
+   adev->gfx.config.gb_addr_config_fields.num_se;
+   tiling_info->gfx9.max_compressed_frags =
+   adev->gfx.config.gb_addr_config_fields.max_compress_frags;
+   tiling_info->gfx9.num_rb_per_se =
+   adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
+   tiling_info->gfx9.shaderEnable = 1;
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+   if (adev->asic_type == CHIP_SIENNA_CICHLID ||
+   adev->asic_type == CHIP_NAVY_FLOUNDER ||
+   adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
+   adev->asic_type == CHIP_VANGOGH)
+   tiling_info->gfx9.num_pkrs = 
adev->gfx.config.gb_addr_config_fields.num_pkrs;
+#endif
 }
 
 static int
-fill_plane_dcc_attributes(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- const union dc_tiling_info *tiling_info,
- const uint64_t info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- bool force_disable_dcc)
+validate_dcc(struct amdgpu_device *adev,
+const enum surface_pixel_format format,
+const enum dc_rotation_angle rotation,
+const union dc_tiling_info *tiling_info,
+const struct dc_plane_dcc_param *dcc,
+const struct dc_plane_address *address,
+const struct plane_size *plane_size)
 {
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_2

[PATCH v3 09/11] drm/amd/display: Add formats for DCC with 2/3 planes.

2020-10-21 Thread Bas Nieuwenhuizen
For DCC we will use 2/3 planes to avoid X rendering to the frontbuffer
with DCC compressed images. To make this work with the core KMS
validation we need to add extra formats with the extra planes.

However, due to flexibility we set bpp = 0 for the extra planes and
do the validation ourselves.

Signed-off-by: Bas Nieuwenhuizen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 034397c1f2b1..6b33e030fe20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -185,6 +185,9 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state 
*stream);
 static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
 
+static const struct drm_format_info *
+amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
+
 /*
  * dm_vblank_get_counter
  *
@@ -2160,6 +2163,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
 
 static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
+   .get_format_info = amd_get_format_info,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
@@ -4010,6 +4014,98 @@ modifier_gfx9_swizzle_mode(uint64_t modifier)
return AMD_FMT_MOD_GET(TILE, modifier);
 }
 
+static const struct drm_format_info dcc_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+ .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1

Re: [PATCH v3 10/11] drm/amd/display: Expose modifiers.

2020-10-22 Thread Bas Nieuwenhuizen
You are totally right! Added that locally.

Thanks!

On Thu, Oct 22, 2020 at 7:51 AM Alex Deucher  wrote:
>
> On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
>  wrote:
> >
> > This expose modifier support on GFX9+.
> >
> > Only modifiers that can be rendered on the current GPU are
> > added. This is to reduce the number of modifiers exposed.
> >
> > The HW could expose more, but the best mechanism to decide
> > what to expose without an explosion in modifiers is still
> > to be decided, and in the meantime this should not regress
> > things from pre-modifiers and does not risk regressions as
> > we make up our mind in the future.
> >
> > v2:
> >   - Added comment that D on Raven is only valid for 64bpp
> > and will be filtered based on format later.
> >   - Removed D tiling modes that weren't useful for 64bpp
> > on GFX10+.
> >
> > Signed-off-by: Bas Nieuwenhuizen 
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +-
> >  1 file changed, 337 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 6b33e030fe20..a1ce325f2fd1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -4133,6 +4133,335 @@ fill_gfx9_tiling_info_from_modifier(const struct 
> > amdgpu_device *adev,
> > }
> >  }
> >
> > +enum dm_micro_swizzle {
> > +   MICRO_SWIZZLE_Z = 0,
> > +   MICRO_SWIZZLE_S = 1,
> > +   MICRO_SWIZZLE_D = 2,
> > +   MICRO_SWIZZLE_R = 3
> > +};
> > +
> > +static bool dm_plane_format_mod_supported(struct drm_plane *plane,
> > + uint32_t format,
> > + uint64_t modifier)
> > +{
> > +   struct amdgpu_device *adev = drm_to_adev(plane->dev);
> > +   const struct drm_format_info *info = drm_format_info(format);
> > +
> > +   enum dm_micro_swizzle microtile = 
> > modifier_gfx9_swizzle_mode(modifier) & 3;
> > +
> > +   if (!info)
> > +   return false;
> > +
> > +   /*
> > +* We always have to allow this modifier, because core DRM still
> > +* checks LINEAR support if userspace does not provide modifers.
> > +*/
> > +   if (modifier == DRM_FORMAT_MOD_LINEAR)
> > +   return true;
> > +
> > +   /*
> > +* The arbitrary tiling support for multiplane formats has not been 
> > hooked
> > +* up.
> > +*/
> > +   if (info->num_planes > 1)
> > +   return false;
> > +
> > +   /*
> > +* For D swizzle the canonical modifier depends on the bpp, so check
> > +* it here.
> > +*/
> > +   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
> > AMD_FMT_MOD_TILE_VER_GFX9 &&
> > +   adev->family >= AMDGPU_FAMILY_NV) {
> > +   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
> > +   return false;
> > +   }
> > +
> > +   if (adev->family >= AMDGPU_FAMILY_RV && microtile == 
> > MICRO_SWIZZLE_D &&
> > +   info->cpp[0] < 8)
> > +   return false;
> > +
> > +   if (modifier_has_dcc(modifier)) {
> > +   /* Per radeonsi comments 16/64 bpp are more complicated. */
> > +   if (info->cpp[0] != 4)
> > +   return false;
> > +   }
> > +
> > +   return true;
> > +}
> > +
> > +static void
> > +add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
> > +{
> > +   if (!*mods)
> > +   return;
> > +
> > +   if (*cap - *size < 1) {
> > +   uint64_t new_cap = *cap * 2;
> > +   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
> > GFP_KERNEL);
> > +
> > +   if (!new_mods) {
> > +   kfree(*mods);
> > +   *mods = NULL;
> > +   return;
> > +   }
> > +
> > +   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
> > +   kfree(*mods);
> > +   *mods = new_mods;
> > +   *cap = new_cap;
> > +  

Re: [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers.

2020-10-22 Thread Bas Nieuwenhuizen
On Thu, Oct 22, 2020 at 5:41 PM Alex Deucher  wrote:
>
> On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
>  wrote:
> >
> > This adds modifiers for GFX9+ AMD GPUs.
> >
> > As the modifiers need a lot of parameters I split things out in
> > getters and setters.
> >   - Advantage: simplifies the code a lot
> >   - Disadvantage: Makes it harder to check that you're setting all
> >   the required fields.
> >
> > The tiling modes seem to change every generation, but the structure
> > of what each tiling mode is good for stays really similar. As such
> > the core of the modifier is
> >  - the tiling mode
> >  - a version. Not explicitly a GPU generation, but splitting out
> >a new set of tiling equations.
> >
> > Sometimes one or two tiling modes stay the same and for those we
> > specify a canonical version.
> >
> > Then we have a bunch of parameters on how the compression works.
> > Different HW units have different requirements for these and we
> > actually have some conflicts here.
> >
> > e.g. the render backends need a specific alignment but the display
> > unit only works with unaligned compression surfaces. To work around
> > that we have a DCC_RETILE option where both an aligned and unaligned
> > compression surface are allocated and a writer has to sync the
> > aligned surface to the unaligned surface on handoff.
> >
> > Finally there are some GPU parameters that participate in the tiling
> > equations. These are constant for each GPU on the rendering/texturing
> > side. The display unit is very flexible however and supports all
> > of them :|
>
> I think the idea is that the display engine can scanout just about
> anything thrown at it (e.g., if you have multiple GPUs in a system).
> E.g., you may have a laptop with a navi14 dGPU and a renoir APU.
> You'd want the APU to be able to scanout from whatever format the dGPU
> gave you.

I think this agrees with what I wrote in the commit description?

This encoding should support that in a reasonably scalable way, though
in the rest of the patches I don't enable this yet and mostly keep
feature parity with existing PRIME paths.

>
> Alex
>
>
> >
> > Some estimates:
> >  - Single GPU, render+texture: ~10 modifiers
> >  - All possible configs in a gen, display: ~1000 modifiers
> >  - Configs of actually existing GPUs in a gen: ~100 modifiers
> >
> > For formats with a single plane everything gets put in a separate
> > DRM plane. However, this doesn't fit for some YUV formats, so if
> > the format has >1 plane, we let the driver pack the surfaces into
> > 1 DRM plane per format plane.
> >
> > This way we avoid X11 rendering onto the frontbuffer with DCC, but
> > still fit into 4 DRM planes.
> >
> > Signed-off-by: Bas Nieuwenhuizen 
> > ---
> >  include/uapi/drm/drm_fourcc.h | 115 ++
> >  1 file changed, 115 insertions(+)
> >
> > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> > index 82f327801267..df56e71a7380 100644
> > --- a/include/uapi/drm/drm_fourcc.h
> > +++ b/include/uapi/drm/drm_fourcc.h
> > @@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
> > modifier)
> >   */
> >  #define AMLOGIC_FBC_OPTION_MEM_SAVING  (1ULL << 0)
> >
> > +/*
> > + * AMD modifiers
> > + *
> > + * Memory layout:
> > + *
> > + * without DCC:
> > + *   - main surface
> > + *
> > + * with DCC & without DCC_RETILE:
> > + *   - main surface in plane 0
> > + *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN 
> > is set)
> > + *
> > + * with DCC & DCC_RETILE:
> > + *   - main surface in plane 0
> > + *   - displayable DCC surface in plane 1 (not RB-aligned & not 
> > pipe-aligned)
> > + *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
> > + *
> > + * For multi-plane formats the above surfaces get merged into one plane for
> > + * each format plane, based on the required alignment only.
> > + */
> > +#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
> > +
> > +#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
> > +
> > +/* Reserve 0 for GFX8 and older */
> > +#define AMD_FMT_MOD_TILE_VER_GFX9 1
> > +#define AMD_FMT_MOD_TILE_VER_GFX10 2
> > +#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
> > +
> > +/*
> > + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as 

Re: [PATCH 3/3] drm/amdgpu/display: add MALL support

2020-10-26 Thread Bas Nieuwenhuizen
On Tue, Oct 20, 2020 at 10:26 PM Alex Deucher  wrote:
>
> From: Bhawanpreet Lakha 
>
> Enable Memory Access at Last Level (MALL) feature for display.
>
> Signed-off-by: Bhawanpreet Lakha 
> Signed-off-by: Alex Deucher 
> ---
>  .../drm/amd/display/dc/clk_mgr/dcn30/dalsmc.h |  1 +
>  .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c  | 10 +++
>  .../dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c  |  9 +++
>  .../dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h  |  2 +
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 65 +++
>  .../drm/amd/display/dc/dcn30/dcn30_resource.c |  2 +-
>  .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 20 ++
>  7 files changed, 108 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dalsmc.h 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dalsmc.h
> index 5ed03287aaaf..fa09c594fd36 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dalsmc.h
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dalsmc.h
> @@ -53,6 +53,7 @@
>  #define DALSMC_MSG_GetDcModeMaxDpmFreq0xC
>  #define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD
>  #define DALSMC_MSG_NumOfDisplays  0xE
> +#define DALSMC_MSG_SetDisplayRefreshFromMall  0xF
>  #define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10
>  #define DALSMC_MSG_BacoAudioD3PME 0x11
>  #define DALSMC_Message_Count  0x12
> diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
> index b0e9b0509568..7bad73b2d146 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
> @@ -145,6 +145,16 @@ static void dcn3_build_wm_range_table(struct 
> clk_mgr_internal *clk_mgr)
> 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = 
> min_uclk_mhz;
> 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 
> 0x;
>
> +   /* Set D - MALL - SR enter and exit times adjusted for MALL */
> +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us
>  = pstate_latency_us;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us 
> = 2;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us
>  = 4;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = 
> WATERMARKS_MALL;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk 
> = 0;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk 
> = 0x;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = 
> min_uclk_mhz;
> +// 
> clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 
> 0x;
>  }
>
>  void dcn3_init_clocks(struct clk_mgr *clk_mgr_base)
> diff --git 
> a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
> index 7ee3ec5a8af8..8ecc708bcd9e 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
> @@ -297,6 +297,15 @@ void dcn30_smu_set_num_of_displays(struct 
> clk_mgr_internal *clk_mgr, uint32_t nu
> DALSMC_MSG_NumOfDisplays, num_displays, NULL);
>  }
>
> +void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal 
> *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale)
> +{
> +   /* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, 
> bit 0 = 1 for enable, = 0 for disable */
> +   uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) 
> | (enable ? 1 : 0);
> +
> +   dcn30_smu_send_msg_with_param(clk_mgr,
> +   DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL);
> +}
> +
>  void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal 
> *clk_mgr, bool enable)
>  {
> smu_print("SMU Set external client df cstate allow: enable = %d\n", 
> enable);
> diff --git 
> a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
> index 236f20ec90d4..dd2640a3ce5d 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
> @@ -70,6 +70,7 @@ typedef enum {
>  typedef enum {
> WATERMARKS_CLOCK_RANGE = 0,
> WATERMARKS_DUMMY_PSTATE,
> +   WATERMARKS_MALL,
> WATERMARKS_COUNT,
>  } WATERMARKS_FLAGS_e;
>
> @@ -102,6 +103,7 @@ unsigned int dcn30_smu_get_dpm_freq_by_index(struct 

[PATCH v4 09/11] drm/amd/display: Add formats for DCC with 2/3 planes.

2020-10-28 Thread Bas Nieuwenhuizen
For DCC we will use 2/3 planes to avoid X rendering to the frontbuffer
with DCC compressed images. To make this work with the core KMS
validation we need to add extra formats with the extra planes.

However, due to flexibility we set bpp = 0 for the extra planes and
do the validation ourselves.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 034397c1f2b1..6b33e030fe20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -185,6 +185,9 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state 
*stream);
 static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
 
+static const struct drm_format_info *
+amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
+
 /*
  * dm_vblank_get_counter
  *
@@ -2160,6 +2163,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
 
 static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
+   .get_format_info = amd_get_format_info,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
@@ -4010,6 +4014,98 @@ modifier_gfx9_swizzle_mode(uint64_t modifier)
return AMD_FMT_MOD_GET(TILE, modifier);
 }
 
+static const struct drm_format_info dcc_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+ .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .cpp

[PATCH v4 04/11] drm/fourcc: Add AMD DRM modifiers.

2020-10-28 Thread Bas Nieuwenhuizen
This adds modifiers for GFX9+ AMD GPUs.

As the modifiers need a lot of parameters I split things out in
getters and setters.
  - Advantage: simplifies the code a lot
  - Disadvantage: Makes it harder to check that you're setting all
  the required fields.

The tiling modes seem to change every generation, but the structure
of what each tiling mode is good for stays really similar. As such
the core of the modifier is
 - the tiling mode
 - a version. Not explicitly a GPU generation, but splitting out
   a new set of tiling equations.

Sometimes one or two tiling modes stay the same and for those we
specify a canonical version.

Then we have a bunch of parameters on how the compression works.
Different HW units have different requirements for these and we
actually have some conflicts here.

e.g. the render backends need a specific alignment but the display
unit only works with unaligned compression surfaces. To work around
that we have a DCC_RETILE option where both an aligned and unaligned
compression surface are allocated and a writer has to sync the
aligned surface to the unaligned surface on handoff.

Finally there are some GPU parameters that participate in the tiling
equations. These are constant for each GPU on the rendering/texturing
side. The display unit is very flexible however and supports all
of them :|

Some estimates:
 - Single GPU, render+texture: ~10 modifiers
 - All possible configs in a gen, display: ~1000 modifiers
 - Configs of actually existing GPUs in a gen: ~100 modifiers

For formats with a single plane everything gets put in a separate
DRM plane. However, this doesn't fit for some YUV formats, so if
the format has >1 plane, we let the driver pack the surfaces into
1 DRM plane per format plane.

This way we avoid X11 rendering onto the frontbuffer with DCC, but
still fit into 4 DRM planes.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 include/uapi/drm/drm_fourcc.h | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 82f327801267..df56e71a7380 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
modifier)
  */
 #define AMLOGIC_FBC_OPTION_MEM_SAVING  (1ULL << 0)
 
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ *   - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ *   - main surface in plane 0
+ *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is 
set)
+ *
+ * with DCC & DCC_RETILE:
+ *   - main surface in plane 0
+ *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each format plane, based on the required alignment only.
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as 
canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastc

[PATCH v4 08/11] drm/amd/display: Set DC options from modifiers.

2020-10-28 Thread Bas Nieuwenhuizen
This sets the DC tiling options from the modifier, if modifiers
are used for the FB. This patch by itself does not expose the
support yet though.

There is not much validation yet to limit the scope of this
patch, but the current validation is at the same level as
the BO metadata path.

v2: Add modifier check to should_reset_plane.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 102 --
 1 file changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 479c886816d9..034397c1f2b1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3995,6 +3995,83 @@ fill_gfx9_plane_attributes_from_flags(struct 
amdgpu_device *adev,
return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+   return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return 0;
+
+   return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+   union dc_tiling_info *tiling_info,
+   uint64_t modifier)
+{
+   unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, 
modifier);
+   unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, 
modifier);
+   unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+   unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+   fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+   if (!IS_AMD_FMT_MOD(modifier))
+   return;
+
+   tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+   tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - 
pipes_log2);
+
+   if (adev->family >= AMDGPU_FAMILY_NV) {
+   tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+   } else {
+   tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+   /* for DCC we know it isn't rb aligned, so rb_per_se doesn't 
matter. */
+   }
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ const enum surface_pixel_format 
format,
+ const enum dc_rotation_angle rotation,
+ const struct plane_size *plane_size,
+ union dc_tiling_info *tiling_info,
+ struct dc_plane_dcc_param *dcc,
+ struct dc_plane_address *address,
+ const bool force_disable_dcc)
+{
+   const uint64_t modifier = afb->base.modifier;
+   int ret;
+
+   fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+   tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+   if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+   uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+   dcc->enable = 1;
+   dcc->meta_pitch = afb->base.pitches[1];
+   dcc->independent_64b_blks = 
AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+   }
+
+   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
 const struct amdgpu_framebuffer *afb,
@@ -4063,12 +4140,22 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, 
rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   force_disable_dcc);
-   if (ret)
-   return ret;
+   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
+   

[PATCH v4 03/11] drm/amd/display: Honor the offset for plane 0.

2020-10-28 Thread Bas Nieuwenhuizen
With modifiers I'd like to support non-dedicated buffers for
images.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
Reviewed-by: Nicholas Kazlauskas 
Cc: sta...@vger.kernel.org # 5.1.0
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 73987fdb6a09..833887b9b0ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3894,6 +3894,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
+   uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
uint64_t dcc_address;
@@ -3937,7 +3938,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
dcc->independent_64b_blks = i64b;
 
-   dcc_address = get_dcc_address(afb->address, info);
+   dcc_address = get_dcc_address(plane_address, info);
address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
 
@@ -3968,6 +3969,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
address->tmz_surface = tmz_surface;
 
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+   uint64_t addr = afb->address + fb->offsets[0];
+
plane_size->surface_size.x = 0;
plane_size->surface_size.y = 0;
plane_size->surface_size.width = fb->width;
@@ -3976,9 +3979,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
fb->pitches[0] / fb->format->cpp[0];
 
address->type = PLN_ADDR_TYPE_GRAPHICS;
-   address->grph.addr.low_part = lower_32_bits(afb->address);
-   address->grph.addr.high_part = upper_32_bits(afb->address);
+   address->grph.addr.low_part = lower_32_bits(addr);
+   address->grph.addr.high_part = upper_32_bits(addr);
} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
+   uint64_t luma_addr = afb->address + fb->offsets[0];
uint64_t chroma_addr = afb->address + fb->offsets[1];
 
plane_size->surface_size.x = 0;
@@ -3999,9 +4003,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
address->video_progressive.luma_addr.low_part =
-   lower_32_bits(afb->address);
+   lower_32_bits(luma_addr);
address->video_progressive.luma_addr.high_part =
-   upper_32_bits(afb->address);
+   upper_32_bits(luma_addr);
address->video_progressive.chroma_addr.low_part =
lower_32_bits(chroma_addr);
address->video_progressive.chroma_addr.high_part =
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v4 11/11] drm/amd/display: Clean up GFX9 tiling_flags path.

2020-10-28 Thread Bas Nieuwenhuizen
We're unconditionally using modifiers internally for GFX9+ now.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 ++-
 1 file changed, 7 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2202c0060b5c..423f6f07a070 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3948,57 +3948,6 @@ validate_dcc(struct amdgpu_device *adev,
return 0;
 }
 
-static void
-fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
-  struct dc_plane_dcc_param *dcc,
-  struct dc_plane_address *address,
-  const uint64_t flags, bool force_disable_dcc)
-{
-   uint64_t dcc_address;
-   uint64_t plane_address = afb->address + afb->base.offsets[0];
-   uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
-   uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
-
-   if (!offset || force_disable_dcc)
-   return;
-
-   dcc->enable = 1;
-   dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
-   dcc->independent_64b_blks = i64b;
-
-   dcc_address = plane_address + (uint64_t)offset * 256;
-   address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
-   address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
-}
-
-
-static int
-fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- union dc_tiling_info *tiling_info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- uint64_t tiling_flags,
- bool force_disable_dcc)
-{
-   int ret;
-
-   fill_gfx9_tiling_info_from_device(adev, tiling_info);
-
-   tiling_info->gfx9.swizzle =
-   AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-
-   fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, 
force_disable_dcc);
-   ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, 
plane_size);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
 static bool
 modifier_has_dcc(uint64_t modifier)
 {
@@ -4566,22 +4515,13 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
 
if (adev->family >= AMDGPU_FAMILY_AI) {
-   if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
-   ret = fill_gfx9_plane_attributes_from_modifiers(adev, 
afb, format,
-   
rotation, plane_size,
-   
tiling_info, dcc,
-   address,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   } else {
-   ret = fill_gfx9_plane_attributes_from_flags(adev, afb, 
format, rotation,
-   plane_size, 
tiling_info, dcc,
-   address, 
tiling_flags,
-   
force_disable_dcc);
-   if (ret)
-   return ret;
-   }
+   ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, 
format,
+   rotation, 
plane_size,
+   tiling_info, 
dcc,
+   address,
+   
force_disable_dcc);
+   if (ret)
+   return ret;
} else {
fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
}
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v4 00/11] amd/display: Add GFX9+ modifier support.

2020-10-28 Thread Bas Nieuwenhuizen
This adds modifier support to the amdgpu kernel drivers for GFX9 and
later GPUs. It has been tested on

- VEGA10, RAVEN, NAVI14
- weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)

and includes some basic testing of the layout code.

The main goal is to keep it somewhat simple and regression free, so
on the display side this series only exposes what the current GPU
can render to. While we could expose more I think that is more
suitable for follow-up work as the benefit would be minimal and
there are some more design discussion there to discuss that are
orthogonal from the initial implementation.

Similarly this series only exposes 32-bpp displayable DCC in the cases
that radeonsi would use it and any extra capabilities here should be
future work.

I believe these are by far the most complicated modifiers we've seen
up till now, mostly related to

- GPU identification for cases where it matters wrt tiling.
- Every generation having tiling layout changes
- Compression settings.

I believe the complexity is necessary as every layout should be different
and all layouts should be the best in some situation (though not all
combinations of GPU parameters will actually have an existing GPU).

That said, on the render side the number of modifiers actually listed for
a given GPU is ~10, and in the current implementation that is the same
for the display side. (we could expose more actually differing layouts
on the display side for cross-GPU compatibility, but I consider that
out of scope for this initial work).

This series can be found on
https://github.com/BNieuwenhuizen/linux/tree/modifiers

An userspace implementation in radeonsi can be found on
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176

which has been reviewed and is ready for submission once these kernel
patches land.

v2:

Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
constant econding modifers only get exposed on RAVEN2 and newer.

v3:

Fixed some typos, rebased and CCing more people to actually get a review.

v4:

Changed an initialization from {0} to memset, fixed a missing switch case
in the modifier enumeration and added review tags.

Bas Nieuwenhuizen (11):
  drm/amd/display: Do not silently accept DCC for multiplane formats.
  drm/amd: Init modifier field of helper fb.
  drm/amd/display: Honor the offset for plane 0.
  drm/fourcc:  Add AMD DRM modifiers.
  drm/amd/display: Store tiling_flags in the framebuffer.
  drm/amd/display: Convert tiling_flags to modifiers.
  drm/amd/display: Refactor surface tiling setup.
  drm/amd/display: Set DC options from modifiers.
  drm/amd/display: Add formats for DCC with 2/3 planes.
  drm/amd/display: Expose modifiers.
  drm/amd/display: Clean up GFX9 tiling_flags path.

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
 include/uapi/drm/drm_fourcc.h | 115 +++
 6 files changed, 880 insertions(+), 165 deletions(-)

-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v4 05/11] drm/amd/display: Store tiling_flags in the framebuffer.

2020-10-28 Thread Bas Nieuwenhuizen
This moves the tiling_flags to the framebuffer creation.
This way the time of the "tiling" decision is the same as it
would be with modifiers.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
Reviewed-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 48 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
 4 files changed, 59 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 9e92d2a070ac..1a2664c3fc26 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -541,6 +541,39 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer 
*amdgpu_fb,
+ uint64_t *tiling_flags, bool *tmz_surface)
+{
+   struct amdgpu_bo *rbo;
+   int r;
+
+   if (!amdgpu_fb) {
+   *tiling_flags = 0;
+   *tmz_surface = false;
+   return 0;
+   }
+
+   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
+   r = amdgpu_bo_reserve(rbo, false);
+
+   if (unlikely(r)) {
+   /* Don't show error message when returning -ERESTARTSYS */
+   if (r != -ERESTARTSYS)
+   DRM_ERROR("Unable to reserve buffer: %d\n", r);
+   return r;
+   }
+
+   if (tiling_flags)
+   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
+
+   if (tmz_surface)
+   *tmz_surface = amdgpu_bo_encrypted(rbo);
+
+   amdgpu_bo_unreserve(rbo);
+
+   return r;
+}
+
 int amdgpu_display_framebuffer_init(struct drm_device *dev,
struct amdgpu_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -550,11 +583,18 @@ int amdgpu_display_framebuffer_init(struct drm_device 
*dev,
rfb->base.obj[0] = obj;
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
-   if (ret) {
-   rfb->base.obj[0] = NULL;
-   return ret;
-   }
+   if (ret)
+   goto fail;
+
+   ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, 
&rfb->tmz_surface);
+   if (ret)
+   goto fail;
+
return 0;
+
+fail:
+   rfb->base.obj[0] = NULL;
+   return ret;
 }
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 345cb0464370..39866ed81c16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -304,6 +304,9 @@ struct amdgpu_display_funcs {
 struct amdgpu_framebuffer {
struct drm_framebuffer base;
 
+   uint64_t tiling_flags;
+   bool tmz_surface;
+
/* caching for later use */
uint64_t address;
 };
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 833887b9b0ad..5a0efaefbd7f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,39 +3839,6 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
-  uint64_t *tiling_flags, bool *tmz_surface)
-{
-   struct amdgpu_bo *rbo;
-   int r;
-
-   if (!amdgpu_fb) {
-   *tiling_flags = 0;
-   *tmz_surface = false;
-   return 0;
-   }
-
-   rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
-   r = amdgpu_bo_reserve(rbo, false);
-
-   if (unlikely(r)) {
-   /* Don't show error message when returning -ERESTARTSYS */
-   if (r != -ERESTARTSYS)
-   DRM_ERROR("Unable to reserve buffer: %d\n", r);
-   return r;
-   }
-
-   if (tiling_flags)
-   amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
-
-   if (tmz_surface)
-   *tmz_surface = amdgpu_bo_encrypted(rbo);
-
-   amdgpu_bo_unreserve(rbo);
-
-   return r;
-}
-
 static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
 {
uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
@@ -4287,7 +4254,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
struct drm_crtc_state *crtc_state)
 {
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
-   struct dm_plane_state *dm_plane_s

[PATCH v4 10/11] drm/amd/display: Expose modifiers.

2020-10-28 Thread Bas Nieuwenhuizen
This expose modifier support on GFX9+.

Only modifiers that can be rendered on the current GPU are
added. This is to reduce the number of modifiers exposed.

The HW could expose more, but the best mechanism to decide
what to expose without an explosion in modifiers is still
to be decided, and in the meantime this should not regress
things from pre-modifiers and does not risk regressions as
we make up our mind in the future.

v2:
  - Added comment that D on Raven is only valid for 64bpp
and will be filtered based on format later.
  - Removed D tiling modes that weren't useful for 64bpp
on GFX10+.

v4: Add AMDGPU_FAMILY_VGH case.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 339 +-
 1 file changed, 338 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6b33e030fe20..2202c0060b5c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4133,6 +4133,336 @@ fill_gfx9_tiling_info_from_modifier(const struct 
amdgpu_device *adev,
}
 }
 
+enum dm_micro_swizzle {
+   MICRO_SWIZZLE_Z = 0,
+   MICRO_SWIZZLE_S = 1,
+   MICRO_SWIZZLE_D = 2,
+   MICRO_SWIZZLE_R = 3
+};
+
+static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+   struct amdgpu_device *adev = drm_to_adev(plane->dev);
+   const struct drm_format_info *info = drm_format_info(format);
+
+   enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) 
& 3;
+
+   if (!info)
+   return false;
+
+   /*
+* We always have to allow this modifier, because core DRM still
+* checks LINEAR support if userspace does not provide modifers.
+*/
+   if (modifier == DRM_FORMAT_MOD_LINEAR)
+   return true;
+
+   /*
+* The arbitrary tiling support for multiplane formats has not been 
hooked
+* up.
+*/
+   if (info->num_planes > 1)
+   return false;
+
+   /*
+* For D swizzle the canonical modifier depends on the bpp, so check
+* it here.
+*/
+   if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == 
AMD_FMT_MOD_TILE_VER_GFX9 &&
+   adev->family >= AMDGPU_FAMILY_NV) {
+   if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
+   return false;
+   }
+
+   if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
+   info->cpp[0] < 8)
+   return false;
+
+   if (modifier_has_dcc(modifier)) {
+   /* Per radeonsi comments 16/64 bpp are more complicated. */
+   if (info->cpp[0] != 4)
+   return false;
+   }
+
+   return true;
+}
+
+static void
+add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
+{
+   if (!*mods)
+   return;
+
+   if (*cap - *size < 1) {
+   uint64_t new_cap = *cap * 2;
+   uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), 
GFP_KERNEL);
+
+   if (!new_mods) {
+   kfree(*mods);
+   *mods = NULL;
+   return;
+   }
+
+   memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
+   kfree(*mods);
+   *mods = new_mods;
+   *cap = new_cap;
+   }
+
+   (*mods)[*size] = mod;
+   *size += 1;
+}
+
+static void
+add_gfx9_modifiers(const struct amdgpu_device *adev,
+  uint64_t **mods, uint64_t *size, uint64_t *capacity)
+{
+   int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
+   int pipe_xor_bits = min(8, pipes +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   int bank_xor_bits = min(8 - pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
+ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
+
+
+   if (adev->family == AMDGPU_FAMILY_RV) {
+   /* Raven2 and later */
+   bool has_constant_encode = adev->asic_type > CHIP_RAVEN || 
adev->external_rev_id >= 0x81;
+
+   /*
+* No _D DCC swizzles yet because we only allow 32bpp, which
+* doesn't support _D on DCN
+*/
+
+   if (has_constant_encode) {
+   add_modifier(mods, size, capacity, AMD_FMT_MOD |
+   AMD_FMT_

[PATCH v4 06/11] drm/amd/display: Convert tiling_flags to modifiers.

2020-10-28 Thread Bas Nieuwenhuizen
This way the modifier path gets exercised all the time, improving
testing. Furthermore, for modifiers this is required as getfb2
will always return the modifier if the driver sets allow_fb_modifiers.

This only triggers once allow_fb_modifiers is set.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 123 
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1a2664c3fc26..89c3ead36501 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static void amdgpu_display_flip_callback(struct dma_fence *f,
@@ -541,6 +542,121 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
+{
+   struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
+   uint64_t modifier = 0;
+
+   if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE)) {
+   modifier = DRM_FORMAT_MOD_LINEAR;
+   } else {
+   int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, 
SWIZZLE_MODE);
+   bool has_xor = swizzle >= 16;
+   int block_size_bits;
+   int version;
+   int pipe_xor_bits = 0;
+   int bank_xor_bits = 0;
+   int packers = 0;
+   uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, 
DCC_OFFSET_256B);
+
+   switch (swizzle >> 2) {
+   case 0: /* 256B */
+   block_size_bits = 8;
+   break;
+   case 1: /* 4KiB */
+   case 5: /* 4KiB _X */
+   block_size_bits = 12;
+   break;
+   case 2: /* 64KiB */
+   case 4: /* 64 KiB _T */
+   case 6: /* 64 KiB _X */
+   block_size_bits = 16;
+   break;
+   default:
+   /* RESERVED or VAR */
+   return -EINVAL;
+   }
+
+   if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+   version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
+   else if (adev->family == AMDGPU_FAMILY_NV)
+   version = AMD_FMT_MOD_TILE_VER_GFX10;
+   else
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+
+   switch (swizzle & 3) {
+   case 0: /* Z microtiling */
+   return -EINVAL;
+   case 1: /* S microtiling */
+   if (!has_xor)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 2:
+   if (!has_xor && afb->base.format->cpp[0] != 4)
+   version = AMD_FMT_MOD_TILE_VER_GFX9;
+   break;
+   case 3:
+   break;
+   }
+
+   if (has_xor) {
+   switch (version) {
+   case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   packers = min(block_size_bits - 8 - 
pipe_xor_bits,
+ 
ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX10:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   break;
+   case AMD_FMT_MOD_TILE_VER_GFX9:
+   pipe_xor_bits = min(block_size_bits - 8,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+   bank_xor_bits = min(block_size_bits - 8 - 
pipe_xor_bits,
+   
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+   break;
+   }
+   }
+
+   modifier = AMD_FMT_MOD |
+  AMD_FMT_MOD_SET(TILE, 
AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
+  AMD_FMT_MOD_SET(TILE_VERSION, version) |
+  AMD_FMT_MOD_SET(PI

[PATCH v4 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats.

2020-10-28 Thread Bas Nieuwenhuizen
Silently accepting it could result in corruption.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
Reviewed-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2713caac4f2a..73987fdb6a09 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3908,7 +3908,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
return 0;
 
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-   return 0;
+   return -EINVAL;
 
if (!dc->cap_funcs.get_dcc_compression_cap)
return -EINVAL;
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v4 02/11] drm/amd: Init modifier field of helper fb.

2020-10-28 Thread Bas Nieuwenhuizen
Otherwise the field ends up being used uninitialized when
enabling modifiers, failing validation with high likelyhood.

v4: Use memset

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
(for v1)
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index e2c2eb45a793..0bf7d36c6686 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -207,6 +207,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
int ret;
unsigned long tmp;
 
+   memset(&mode_cmd, 0, sizeof(mode_cmd));
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
 
-- 
2.28.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v4 07/11] drm/amd/display: Refactor surface tiling setup.

2020-10-28 Thread Bas Nieuwenhuizen
Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.

Signed-off-by: Bas Nieuwenhuizen 
Reviewed-by: Alex Deucher 
Reviewed-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 222 ++
 1 file changed, 119 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5a0efaefbd7f..479c886816d9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,46 +3839,86 @@ static int fill_dc_scaling_info(const struct 
drm_plane_state *state,
return 0;
 }
 
-static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+static void
+fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+uint64_t tiling_flags)
 {
-   uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+   /* Fill GFX8 params */
+   if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
+   unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
+
+   bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+   bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+   mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+   tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
+   num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
+
+   /* XXX fix me for VI */
+   tiling_info->gfx8.num_banks = num_banks;
+   tiling_info->gfx8.array_mode =
+   DC_ARRAY_2D_TILED_THIN1;
+   tiling_info->gfx8.tile_split = tile_split;
+   tiling_info->gfx8.bank_width = bankw;
+   tiling_info->gfx8.bank_height = bankh;
+   tiling_info->gfx8.tile_aspect = mtaspect;
+   tiling_info->gfx8.tile_mode =
+   DC_ADDR_SURF_MICRO_TILING_DISPLAY;
+   } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
+   == DC_ARRAY_1D_TILED_THIN1) {
+   tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
+   }
 
-   return offset ? (address + offset * 256) : 0;
+   tiling_info->gfx8.pipe_config =
+   AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+}
+
+static void
+fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info)
+{
+   tiling_info->gfx9.num_pipes =
+   adev->gfx.config.gb_addr_config_fields.num_pipes;
+   tiling_info->gfx9.num_banks =
+   adev->gfx.config.gb_addr_config_fields.num_banks;
+   tiling_info->gfx9.pipe_interleave =
+   adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
+   tiling_info->gfx9.num_shader_engines =
+   adev->gfx.config.gb_addr_config_fields.num_se;
+   tiling_info->gfx9.max_compressed_frags =
+   adev->gfx.config.gb_addr_config_fields.max_compress_frags;
+   tiling_info->gfx9.num_rb_per_se =
+   adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
+   tiling_info->gfx9.shaderEnable = 1;
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+   if (adev->asic_type == CHIP_SIENNA_CICHLID ||
+   adev->asic_type == CHIP_NAVY_FLOUNDER ||
+   adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
+   adev->asic_type == CHIP_VANGOGH)
+   tiling_info->gfx9.num_pkrs = 
adev->gfx.config.gb_addr_config_fields.num_pkrs;
+#endif
 }
 
 static int
-fill_plane_dcc_attributes(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- const union dc_tiling_info *tiling_info,
- const uint64_t info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- bool force_disable_dcc)
+validate_dcc(struct amdgpu_device *adev,
+const enum surface_pixel_format format,
+const enum dc_rotation_angle rotation,
+const union dc_tiling_info *tiling_info,
+const struct dc_plane_dcc_param *dcc,
+const struct dc_plane_address *address,
+const struct plane_size *plane_size)
 {
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
-   uint64_t plane_address = afb->address + afb->base.offs

[PATCH 2/3] drm/amd/display: Set new format info for converted metadata.

2020-11-10 Thread Bas Nieuwenhuizen
If we use DCC modifiers this can increase the number of planes from
the initial 1 plane with metadata, so that we get a valid modifier
from getfb2.

Since the code didn't update the format_info getfb2 would only ever
return 1 plane with a modifier for which userspace expects > 1.

This moves the format lookup to amdgpu_display.c so we do not have
issues when DC is not compiled.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 97 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.h   |  2 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 88 +
 3 files changed, 100 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index e33acc3de286..f66ce6ec4843 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -542,6 +542,95 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
return domain;
 }
 
+static const struct drm_format_info dcc_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+ .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+{ .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+  .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_BGRA, .depth = 32, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+   { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
+ .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+ .has_alpha = true, },
+   { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 3,
+ .cpp = { 2, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+};
+
+static const struct drm_format_info *
+lookup_format_info(const struct drm_format_info formats[],
+

[PATCH 1/3] drm/amd/display: Store gem objects for planes 1-3

2020-11-10 Thread Bas Nieuwenhuizen
Also do the proper validation which was missed.

Besides the missing validation, not storing the objects in the
framebuffer led to wrong results in the getfb2 ioctl.

Note that this should really have been done for multi-plane
formats like NV12 already before modifiers landed.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 89c3ead36501..e33acc3de286 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -695,13 +695,26 @@ int amdgpu_display_framebuffer_init(struct drm_device 
*dev,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
 {
-   int ret;
+   int ret, i;
rfb->base.obj[0] = obj;
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
if (ret)
goto fail;
 
+   /*
+* This needs to happen before modifier conversion as that might change
+* the number of planes.
+*/
+   for (i = 1; i < rfb->base.format->num_planes; ++i) {
+   if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
+   dev_err(&dev->pdev->dev, "Plane 0 and %d have different 
BOs: %u vs. %u\n",
+   i, mode_cmd->handles[0], mode_cmd->handles[i]);
+   ret = -EINVAL;
+   goto fail;
+   }
+   }
+
ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, 
&rfb->tmz_surface);
if (ret)
goto fail;
@@ -713,6 +726,11 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
goto fail;
}
 
+   for (i = 1; i < rfb->base.format->num_planes; ++i) {
+   rfb->base.obj[i] = rfb->base.obj[0];
+   drm_gem_object_get(rfb->base.obj[i]);
+   }
+
return 0;
 
 fail:
-- 
2.29.2

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 0/3] amdgpu getfb2+modifier improvements

2020-11-10 Thread Bas Nieuwenhuizen
This has some more improvements for the addfb2 code in amdgpu.

These patches make ffmpeg work with DCC compressed and YUV surfaces
with kmsgrab, both in the modifier and non-modifier case.

Bas Nieuwenhuizen (3):
  drm/amd/display: Store gem objects for planes 1-3
  drm/amd/display: Set new format info for converted metadata.
  drm/amd/display: Extract 3rd plane from metadata

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 211 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.h   |   2 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  88 +---
 3 files changed, 207 insertions(+), 94 deletions(-)

-- 
2.29.2

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 3/3] drm/amd/display: Extract 3rd plane from metadata

2020-11-10 Thread Bas Nieuwenhuizen
Now that we actually expose the right number of planes we get
problems with modifier aware libva if we use an unsupported modifier.

So this ensures that we as much as possible use a modifier that
radeonsi can actually render to without going to extreme difficulty
to synchronize an extra DCC metadata plane with implicit sync.

Looking into the opaque metadata isn't ideal but this converts to
something mainly for the purpose of the userspace driver and falls
back properly if it isn't what we expect.

Signed-off-by: Bas Nieuwenhuizen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 106 ++--
 1 file changed, 98 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index f66ce6ec4843..c9e98499b8a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -631,6 +631,57 @@ amdgpu_lookup_format_info(u32 format, uint64_t modifier)
return NULL;
 }
 
+
+/*
+ * Tries to extract the renderable DCC offset from the opaque metadata attached
+ * to the buffer.
+ */
+static int
+extract_render_dcc_offset(struct amdgpu_device *adev,
+ struct drm_gem_object *obj,
+ uint64_t *offset)
+{
+   struct amdgpu_bo *rbo;
+   int r = 0;
+   uint32_t metadata[10]; /* Something that fits a descriptor + header. */
+   uint32_t size;
+
+   rbo = gem_to_amdgpu_bo(obj);
+   r = amdgpu_bo_reserve(rbo, false);
+
+   if (unlikely(r)) {
+   /* Don't show error message when returning -ERESTARTSYS */
+   if (r != -ERESTARTSYS)
+   DRM_ERROR("Unable to reserve buffer: %d\n", r);
+   return r;
+   }
+
+   r = amdgpu_bo_get_metadata(rbo, metadata, sizeof(metadata), &size, 
NULL);
+   amdgpu_bo_unreserve(rbo);
+
+   if (r)
+   return r;
+
+   /*
+* The first word is the metadata version, and we need space for at 
least
+* the version + pci vendor+device id + 8 words for a descriptor.
+*/
+   if (size < 40  || metadata[0] != 1)
+   return -EINVAL;
+
+   if (adev->family >= AMDGPU_FAMILY_NV) {
+   /* resource word 6/7 META_DATA_ADDRESS{_LO} */
+   *offset = ((u64)metadata[9] << 16u) |
+ ((metadata[8] & 0xFF00u) >> 16);
+   } else {
+   /* resource word 5/7 META_DATA_ADDRESS */
+   *offset = ((u64)metadata[9] << 8u) |
+ ((u64)(metadata[7] & 0x1FEu) << 23);
+   }
+
+   return 0;
+}
+
 static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
 {
struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
@@ -646,6 +697,8 @@ static int convert_tiling_flags_to_modifier(struct 
amdgpu_framebuffer *afb)
int pipe_xor_bits = 0;
int bank_xor_bits = 0;
int packers = 0;
+   int rb = 0;
+   int pipes = 
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, 
DCC_OFFSET_256B);
 
switch (swizzle >> 2) {
@@ -691,18 +744,17 @@ static int convert_tiling_flags_to_modifier(struct 
amdgpu_framebuffer *afb)
if (has_xor) {
switch (version) {
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
-   pipe_xor_bits = min(block_size_bits - 8,
-   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   pipe_xor_bits = min(block_size_bits - 8, pipes);
packers = min(block_size_bits - 8 - 
pipe_xor_bits,
  
ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
break;
case AMD_FMT_MOD_TILE_VER_GFX10:
-   pipe_xor_bits = min(block_size_bits - 8,
-   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+   pipe_xor_bits = min(block_size_bits - 8, pipes);
break;
case AMD_FMT_MOD_TILE_VER_GFX9:
-   pipe_xor_bits = min(block_size_bits - 8,
-   
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
+   rb = 
ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
+
ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
+   pipe_xor_bits = min(block_size_bits - 8, pipes +
 

[PATCH] drm/fourcc: Fix modifier field mask for AMD modifiers.

2020-11-13 Thread Bas Nieuwenhuizen
The DCC_MAX_COMPRESSED_BLOCK has to contain one of
AMD_FMT_MOD_DCC_BLOCK_* and with 3 values this doesn't
fit in 1 bit.

Fix this cleanly while it is only in drm-next.

Fixes: 8ba16d5993749c3f31fd2b49e16f0dc1e1770b9c
---

Found while reviewing Simon's drm_info PR: 
https://github.com/ascent12/drm_info/pull/63/commits/eaeae6ee78764a03d959cbc97c8b514f81a94c63

 include/uapi/drm/drm_fourcc.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index df56e71a7380..a878664ba41c 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1129,7 +1129,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
 #define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
 #define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
 #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
-#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3
 
 /*
  * DCC supports embedding some clear colors directly in the DCC surface.
@@ -1140,7 +1140,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
  * If this bit is set that means the fastclear eliminate is not needed for 
these
  * embeddable colors.
  */
-#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 19
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 20
 #define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
 
 /*
@@ -1153,15 +1153,15 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
modifier)
  * RB = only for TILE_VER_GFX9 & DCC
  * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
  */
-#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 20
+#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 21
 #define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
-#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
+#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 24
 #define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
-#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
+#define AMD_FMT_MOD_PACKERS_SHIFT 27 /* aliases with BANK_XOR_BITS */
 #define AMD_FMT_MOD_PACKERS_MASK 0x7
-#define AMD_FMT_MOD_RB_SHIFT 29
+#define AMD_FMT_MOD_RB_SHIFT 30
 #define AMD_FMT_MOD_RB_MASK 0x7
-#define AMD_FMT_MOD_PIPE_SHIFT 32
+#define AMD_FMT_MOD_PIPE_SHIFT 33
 #define AMD_FMT_MOD_PIPE_MASK 0x7
 
 #define AMD_FMT_MOD_SET(field, value) \
-- 
2.29.2

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v2] drm/fourcc: Fix modifier field mask for AMD modifiers.

2020-11-13 Thread Bas Nieuwenhuizen
The DCC_MAX_COMPRESSED_BLOCK has to contain one of
AMD_FMT_MOD_DCC_BLOCK_* and with 3 values this doesn't
fit in 1 bit.

Fix this cleanly while it is only in drm-next.

Fixes: 8ba16d599374 ("drm/fourcc: Add AMD DRM modifiers.")
Reviewed-by: Alex Deucher 
Signed-off-by: Bas Nieuwenhuizen 
---
 include/uapi/drm/drm_fourcc.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index df56e71a7380..a878664ba41c 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1129,7 +1129,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
 #define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
 #define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
 #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
-#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3
 
 /*
  * DCC supports embedding some clear colors directly in the DCC surface.
@@ -1140,7 +1140,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
  * If this bit is set that means the fastclear eliminate is not needed for 
these
  * embeddable colors.
  */
-#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 19
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 20
 #define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
 
 /*
@@ -1153,15 +1153,15 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
modifier)
  * RB = only for TILE_VER_GFX9 & DCC
  * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
  */
-#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 20
+#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 21
 #define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
-#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
+#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 24
 #define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
-#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
+#define AMD_FMT_MOD_PACKERS_SHIFT 27 /* aliases with BANK_XOR_BITS */
 #define AMD_FMT_MOD_PACKERS_MASK 0x7
-#define AMD_FMT_MOD_RB_SHIFT 29
+#define AMD_FMT_MOD_RB_SHIFT 30
 #define AMD_FMT_MOD_RB_MASK 0x7
-#define AMD_FMT_MOD_PIPE_SHIFT 32
+#define AMD_FMT_MOD_PIPE_SHIFT 33
 #define AMD_FMT_MOD_PIPE_MASK 0x7
 
 #define AMD_FMT_MOD_SET(field, value) \
-- 
2.29.2

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 0/3] amdgpu getfb2+modifier improvements

2020-11-13 Thread Bas Nieuwenhuizen
On Fri, Nov 13, 2020 at 6:53 PM Alex Deucher  wrote:
>
> On Tue, Nov 10, 2020 at 9:48 PM Bas Nieuwenhuizen
>  wrote:
> >
> > This has some more improvements for the addfb2 code in amdgpu.
> >
> > These patches make ffmpeg work with DCC compressed and YUV surfaces
> > with kmsgrab, both in the modifier and non-modifier case.
>
> Looks good to me.  Series is:
> Reviewed-by: Alex Deucher 

Thanks! Do you need me to apply the r-b tags or can you apply as is?
>
> >
> > Bas Nieuwenhuizen (3):
> >   drm/amd/display: Store gem objects for planes 1-3
> >   drm/amd/display: Set new format info for converted metadata.
> >   drm/amd/display: Extract 3rd plane from metadata
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 211 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.h   |   2 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  88 +---
> >  3 files changed, 207 insertions(+), 94 deletions(-)
> >
> > --
> > 2.29.2
> >
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/fourcc: fix AMD modifiers PACKERS field doc

2020-11-15 Thread Bas Nieuwenhuizen
Reviewed-by: Bas Nieuwenhuizen 

On Sun, Nov 15, 2020 at 10:39 AM Simon Ser  wrote:
>
> This field doesn't alias with BANK_XOR_BITS: PACKERS is bits 26:28 while
> BANK_XOR_BITS is bits 23:25.
>
> Fixes: 8ba16d599374 ("drm/fourcc: Add AMD DRM modifiers.")
> Signed-off-by: Simon Ser 
> Cc: Bas Nieuwenhuizen 
> Cc: Alex Deucher 
> Cc: Daniel Vetter 
> ---
>  include/uapi/drm/drm_fourcc.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index ca48ed0e6bc1..29c7a8694479 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -1196,7 +1196,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 
> modifier)
>  #define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
>  #define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
>  #define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
> -#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
> +#define AMD_FMT_MOD_PACKERS_SHIFT 26
>  #define AMD_FMT_MOD_PACKERS_MASK 0x7
>  #define AMD_FMT_MOD_RB_SHIFT 29
>  #define AMD_FMT_MOD_RB_MASK 0x7
> --
> 2.29.2
>
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH v3] drm/amd/amdgpu: set the default value of noretry to 1 for some dGPUs

2020-11-28 Thread Bas Nieuwenhuizen
Can we revert this patch to fix
https://gitlab.freedesktop.org/drm/amd/-/issues/1374 ?

On Thu, Oct 15, 2020 at 4:30 PM Felix Kuehling  wrote:
>
> Am 2020-10-14 um 11:35 p.m. schrieb Chengming Gui:
> > noretry = 0 cause some dGPU's kfd page fault tests fail,
> > so set noretry to 1 for these special ASICs:
> > vega20/navi10/navi14/ARCTURUS
> >
> > v2: merge raven and default case due to the same setting
> > v3: remove ARCTURUS
> >
> > Signed-off-by: Chengming Gui 
> > Change-Id: I3be70f463a49b0cd5c56456431d6c2cb98b13872
>
> Acked-by: Felix Kuhling 
>
>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 23 +++
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> > index 36604d751d62..f26eb4e54b12 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> > @@ -425,20 +425,27 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device 
> > *adev)
> >   struct amdgpu_gmc *gmc = &adev->gmc;
> >
> >   switch (adev->asic_type) {
> > - case CHIP_RAVEN:
> > - /* Raven currently has issues with noretry
> > -  * regardless of what we decide for other
> > -  * asics, we should leave raven with
> > -  * noretry = 0 until we root cause the
> > -  * issues.
> > + case CHIP_VEGA20:
> > + case CHIP_NAVI10:
> > + case CHIP_NAVI14:
> > + /*
> > +  * noretry = 0 will cause kfd page fault tests fail
> > +  * for some ASICs, so set default to 1 for these ASICs.
> >*/
> >   if (amdgpu_noretry == -1)
> > - gmc->noretry = 0;
> > + gmc->noretry = 1;
> >   else
> >   gmc->noretry = amdgpu_noretry;
> >   break;
> > + case CHIP_RAVEN:
> >   default:
> > - /* default this to 0 for now, but we may want
> > + /* Raven currently has issues with noretry
> > +  * regardless of what we decide for other
> > +  * asics, we should leave raven with
> > +  * noretry = 0 until we root cause the
> > +  * issues.
> > +  *
> > +  * default this to 0 for now, but we may want
> >* to change this in the future for certain
> >* GPUs as it can increase performance in
> >* certain cases.
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amdgpu: Do not change amdgpu framebuffer format during page flip

2020-12-22 Thread Bas Nieuwenhuizen
On Tue, Dec 22, 2020 at 9:55 PM Kazlauskas, Nicholas
 wrote:
>
> On 2020-12-21 10:18 p.m., Zhan Liu wrote:
> > [Why]
> > Driver cannot change amdgpu framebuffer (afb) format while doing
> > page flip. Force system doing so will cause ioctl error, and result in
> > breaking several functionalities including FreeSync.
> >
> > If afb format is forced to change during page flip, following message
> > will appear in dmesg.log:
> >
> > "[drm:drm_mode_page_flip_ioctl [drm]]
> > Page flip is not allowed to change frame buffer format."
> >
> > [How]
> > Do not change afb format while doing page flip. It is okay to check
> > whether afb format is valid here, however, forcing afb format change
> > shouldn't happen here.
> >
> > Signed-off-by: Zhan Liu 
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 --
> >   1 file changed, 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index a638709e9c92..0efebd592b65 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -831,8 +831,6 @@ static int convert_tiling_flags_to_modifier(struct 
> > amdgpu_framebuffer *afb)
> >   modifier);
> >   if (!format_info)
> >   return -EINVAL;
> > -
> > - afb->base.format = format_info;
>
> Adding Bas for comment since he added the modifiers conversion, but I'll
> leave my own thoughts below.
>
> This patch is a NAK from me - the framebuffer is still expected to be in
> a specific format/tiling configuration and ignoring the incoming format
> doesn't resolve the problem.
>
> The problem is that the legacy page IOCTL has this check in the first
> place expecting that no driver is capable of performing this action.
>
> This is not the case for amdgpu (be it DC enabled or not), so I think
> it's best to have a driver cap here or some new driver hook to validate
> that the flip is valid.
>
> This is legacy code, and in the shared path, so I don't know how others
> in the list feel about modifying this but I think we do expect that
> legacy userspace can do this from the X side of things.

I think the "new" thing is that we can have different format_info
structs for the same drm fourcc (as we need a different number of
planes depending on modifier). It would probably make sense to relax
this check to check the actual drm fourcc (i.e. fb->format->format)
instead of the format_info pointer. This case would likely only be hit
in the AMDGPU driver anyway (with intel being the other possibility).


>
> I recall seeing this happen going from DCC disabled to non DCC enabled
> buffers and some of this functionality being behind a version check in
> xf86-video-amdgpu.
>
> Regards,
> Nicholas Kazlauskas
>
> >   }
> >   }
> >
> >
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH] drm: Check actual format for legacy pageflip.

2021-01-02 Thread Bas Nieuwenhuizen
With modifiers one can actually have different format_info structs
for the same format, which now matters for AMDGPU since we convert
implicit modifiers to explicit modifiers with multiple planes.

I checked other drivers and it doesn't look like they end up triggering
this case so I think this is safe to relax.

Signed-off-by: Bas Nieuwenhuizen 
Fixes: 816853f9dc40 ("drm/amd/display: Set new format info for converted 
metadata.")
---
 drivers/gpu/drm/drm_plane.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index e6231947f987..f5085990cfac 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -1163,7 +1163,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (ret)
goto out;
 
-   if (old_fb->format != fb->format) {
+   if (old_fb->format->format != fb->format->format) {
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer 
format.\n");
ret = -EINVAL;
goto out;
-- 
2.29.2

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amdgpu: Do not change amdgpu framebuffer format during page flip

2021-01-02 Thread Bas Nieuwenhuizen
https://lists.freedesktop.org/archives/dri-devel/2021-January/292761.html
is my alternative patch.

On Tue, Dec 22, 2020 at 4:18 AM Zhan Liu  wrote:
>
> [Why]
> Driver cannot change amdgpu framebuffer (afb) format while doing
> page flip. Force system doing so will cause ioctl error, and result in
> breaking several functionalities including FreeSync.
>
> If afb format is forced to change during page flip, following message
> will appear in dmesg.log:
>
> "[drm:drm_mode_page_flip_ioctl [drm]]
> Page flip is not allowed to change frame buffer format."
>
> [How]
> Do not change afb format while doing page flip. It is okay to check
> whether afb format is valid here, however, forcing afb format change
> shouldn't happen here.
>
> Signed-off-by: Zhan Liu 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index a638709e9c92..0efebd592b65 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -831,8 +831,6 @@ static int convert_tiling_flags_to_modifier(struct 
> amdgpu_framebuffer *afb)
> modifier);
> if (!format_info)
> return -EINVAL;
> -
> -   afb->base.format = format_info;
> }
> }
>
> --
> 2.25.1
>
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amd/display: Fix pageflipping for XOrg in Linux 5.11+

2021-01-02 Thread Bas Nieuwenhuizen
I think the problem here is that application A can set the FB and then
application B can use getfb2 (say ffmpeg).

https://lists.freedesktop.org/archives/dri-devel/2021-January/292761.html
would be my alternative patch.

(I'm not good at detecting the effects of tearing  apparently but
tested this avoids the pageflip failure by debug-prints)

On Thu, Dec 31, 2020 at 9:52 PM Mario Kleiner
 wrote:
>
> Commit 816853f9dc4057b6c7ee3c45ca9bd5905 ("drm/amd/display: Set new
> format info for converted metadata.") may fix the getfb2 ioctl, but
> in exchange it completely breaks all pageflipping for classic user
> space, e.g., XOrg, as tested with both amdgpu-ddx and modesetting-ddx.
> This leads to massive tearing, broken visual timing/timestamping etc.
>
> Reason is that the classic pageflip ioctl doesn't allow a fb format
> change during flip, and at least X uses classic pageflip ioctl and no
> atomic modesetting api at all.
>
> As one attempted workaround, only set the new format info for converted
> metadata if the calling client isn't X. Not sure if this is the best
> way, or if a better check would not be "not all atomic clients" or
> similar? In any case it works for XOrg X-Server. Checking the ddx
> code of intel-ddx/modesetting-ddx/amdgpu-ddx as well as grepping over
> Mesa doesn't show any users of the getfb2 ioctl(), so the need for this
> format info assignment seems to be more the exception than the rule?
>
> Fixes: 816853f9dc40 ("drm/amd/display: Set new format info for converted 
> metadata.")
> Cc: Bas Nieuwenhuizen 
> Cc: Alex Deucher 
> Signed-off-by: Mario Kleiner 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index f764803c53a4..cb414b3d327a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -828,7 +828,8 @@ static int convert_tiling_flags_to_modifier(struct 
> amdgpu_framebuffer *afb)
> if (!format_info)
> return -EINVAL;
>
> -   afb->base.format = format_info;
> +   if (afb->base.comm[0] != 'X')
> +   afb->base.format = format_info;
> }
> }
>
> --
> 2.25.1
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH] drm/amd/display: Fix pageflipping for XOrg in Linux 5.11+

2021-01-02 Thread Bas Nieuwenhuizen
On Sat, Jan 2, 2021 at 4:05 PM Mario Kleiner  wrote:
>
> On Sat, Jan 2, 2021 at 3:05 PM Bas Nieuwenhuizen
>  wrote:
> >
> > I think the problem here is that application A can set the FB and then
> > application B can use getfb2 (say ffmpeg).
>
>
> Yes. That, and also the check for 'X' won't get us far, because if i
> use my own software Psychtoolbox under Vulkan in direct display mode
> (leased RandR outputs), e.g., under radv or amdvlk, then the ->comm
> name will be "PTB mainthread" and 'P' != 'X'. But the Vulkan drivers
> all use legacy pageflips as well in der WSI/drm, so if Vulkan gets
> framebuffers with DCC modifiers, it would just fail the same way.
>
> Neither would it work to check for atomic client, as they sometimes
> use atomic commit ioctl only for certain use cases, e.g., setting HDR
> metadata, but still use the legacy pageflip ioctl for flipping.
>
> So that patch of mine is not the proper solution for anything non-X.
>
> >
> > https://lists.freedesktop.org/archives/dri-devel/2021-January/292761.html
> > would be my alternative patch.
> >
>
> I also produced and tested hopefully better alternative to my original
> one yesterday, but was too tired to send it. I just sent it out to
> you:
> https://lists.freedesktop.org/archives/dri-devel/2021-January/292763.html
>
> This one keeps the format_info check as is for non-atomic drivers, but
> no longer rejects pageflip if the underlying kms driver is atomic. I
> checked, and current atomic drivers use the drm_atomic... helper for
> implementing legacy pageflips, and that helper just wraps the pageflip
> into a "set new fb on plane" + atomic check + atomic commit.
>
> My understanding is that one can do these format changes safely under
> atomic commit, so i hope this would be safe and future proof.

So I think the difference between your patch and mine seem to boil
down to whether we want any uabi extension, since AFAICT none of the
pre-atomic drivers support modifiers.

>
> > (I'm not good at detecting the effects of tearing  apparently but
> > tested this avoids the pageflip failure by debug-prints)
>
>
> XOrg log (e.g., ~/.local/share/xorg/XOrg0.log on current Ubuntu's) is
> a good place on native XOrg, where the amdgpu-ddx was flooding the log
> with present flip failures. Or drm.debug=4 for the kernel log.
>
> Piglit has the OML_sync_control tests for timing correctness, although
> they are mostly pointless if not run in fullscreen mode, which they
> are not by default.
>
> I can also highly recommend (sudo apt install octave-psychtoolbox-3)
> on Debian/Ubutu based systems for X11. It is used for neuroscience and
> medical research and critically depends on properly working pageflips
> and timestamping on native X11/GLX under OpenGL and recently also
> under Vulkan/WSI (radv,anv,amdvlk) in direct display mode. Working
> FOSS AMD and Intel are especially critical for this research, so far
> under X11+Mesa/OpenGL, but lately also under Vulkan direct display
> mode. It has many built-in correctness tests and will shout angrily if
> something software-detectable is broken wrt. pageflipping or timing.
> E.g., octave-cli --eval PerceptualVBLSyncTest
> PerceptualVBLSyncTest creates a flicker pattern that will tear like
> crazy under Mesa if pageflipping isn't used. Also good to test
> synchronization on dual-display setups, e.g., for udal-display stereo
> presentation.
>
> I was actually surprised that this patch made it through the various
> test suites and into drm-next. I thought page-flipping was covered
> well enough somewhere.

I don't think there are any tests using the AMDGPU implicit modifiers
(not in IGT for anything except linear at least)

>
> Happy new year!
> -mario
>
> >
> > On Thu, Dec 31, 2020 at 9:52 PM Mario Kleiner
> >  wrote:
> > >
> > > Commit 816853f9dc4057b6c7ee3c45ca9bd5905 ("drm/amd/display: Set new
> > > format info for converted metadata.") may fix the getfb2 ioctl, but
> > > in exchange it completely breaks all pageflipping for classic user
> > > space, e.g., XOrg, as tested with both amdgpu-ddx and modesetting-ddx.
> > > This leads to massive tearing, broken visual timing/timestamping etc.
> > >
> > > Reason is that the classic pageflip ioctl doesn't allow a fb format
> > > change during flip, and at least X uses classic pageflip ioctl and no
> > > atomic modesetting api at all.
> > >
> > > As one attempted workaround, only set the new format info for converted
> > > metadata if the calling client isn't X. Not sure if this is the best
> >

  1   2   3   >