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. + + + + + + + + + + + + + + + +