diff --git a/src/freedreno/decode/cffdec.c b/src/freedreno/decode/cffdec.c
index 5adab1a89bb..9e327c42448 100644
--- a/src/freedreno/decode/cffdec.c
+++ b/src/freedreno/decode/cffdec.c
@@ -1106,6 +1106,21 @@ dump_domain(uint32_t *dwords, uint32_t sizedwords, int level, const char *name)
}
}
+static void
+cp_resource_list(uint32_t *dwords, uint32_t sizedwords, int level)
+{
+ uint32_t bv_resource_count = *dwords++;
+
+ for (unsigned i = 0; i < bv_resource_count; i++, dwords += 2)
+ dump_domain(dwords, 2, level + 1, "CP_BV_RESOURCE");
+
+ dump_domain(dwords, 1, level + 1, "CP_RESOURCE_LIST_BR");
+ uint32_t br_resource_count = *dwords++ & ((1u << 24) - 1);
+
+ for (unsigned i = 0; i < br_resource_count; i++, dwords += 2)
+ dump_domain(dwords, 2, level + 1, "CP_BR_RESOURCE");
+}
+
static uint32_t bin_x1, bin_x2, bin_y1, bin_y2;
static unsigned mode;
static const char *render_mode;
@@ -3106,6 +3121,7 @@ static const struct type3_op {
CP(THREAD_CONTROL, cp_set_thread_control),
CP(NON_CONTEXT_REG_BUNCH, cp_non_context_reg_bunch),
CP(EVENT_WRITE7, cp_event_write),
+ CP(RESOURCE_LIST, cp_resource_list),
};
static void
diff --git a/src/freedreno/registers/adreno/adreno_pm4.xml b/src/freedreno/registers/adreno/adreno_pm4.xml
index 97fc4588f4e..99a5ea2ddfd 100644
--- a/src/freedreno/registers/adreno/adreno_pm4.xml
+++ b/src/freedreno/registers/adreno/adreno_pm4.xml
@@ -2338,5 +2338,99 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
+
+
+ A7xx introduces the "resource table" which is managed by
+ CP_RESOURCE_LIST. It is used to synchronize BR and BV access
+ to resources such as LRZ buffers.
+
+ The resource table consists of resources that are in-use by BR.
+ Each "resource" has a base address, which is
+ usually a pointer but is treated by the HW as an opaque handle,
+ a read/write bit, and a timestamp when it was last used.
+ Resources are removed from the table upon event completion when
+ a special CP_EVENT_WRITE::CLEAR_RENDER_RESOURCE bit is set, which
+ will remove all resources with a timestamp up to the current
+ timestamp.
+
+ CP_RESOURCE_LIST first specifies a list of BV resources. For
+ each BV resource, the HW will check if there is a corresponding
+ BR resource in the table, and if at least one of the BV and BR
+ resources is marked WRITE then it will stall until the BR
+ resource is removed.
+
+ It then specifies a list of BR resources. These will be added to
+ the resource table, unless there is an overflow in which case
+ the designated overflow register will have bit 0 set. Overflow
+ should cause the next binning pass to stall until BR is done,
+ effectively disabling concurrent binning.
+
+ CP_RESOURCE_LIST must be executed by BV. BR resources are added
+ by BV and removed by BR.
+
+ There is a separate table for "LRZ resources." These behave a
+ bit differently: specifying an LRZ resource via BV_RES_LRZ
+ stalls on any matching resource existing and then adds it to the
+ table, making it both a BV and BR resource in one. There is a
+ separate CLEAR_LRZ_RESOURCE bit for removing resources from the
+ LRZ table, and it only removes one resource given by a base
+ address passed to CP_EVENT_WRITE. Therefore timestamps are
+ unnecessary.
+
+
+
+ What follows is a list of CP_BV_RESOURCE and then CP_RESOURCE_LIST_BR.
+
+
+
+
+
+ BV resources don't go in the table. Instead CP waits until any
+ corresponding BR resources with the same base pointer are
+ finished before the packet completes.
+
+
+
+
+ INDIRECT resources are encoded as a 32b offset + 3b
+ bindless base selector. The offset is added to the given
+ BINDLESS_BASE pseudoregister and then the 64b value
+ fetched there is used as the pointer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ What follows is a list of CP_BR_RESOURCE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+