From 0911aea1261167695ce4e0a95a3aea1db65484a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 30 Jan 2024 10:52:42 -0500 Subject: [PATCH] winsys/amdgpu: merge 2 loops iterating over real BOs in amdgpu_cs_submit_ib The first loop updates sequence numbers. The second loop creates the BO list. Do both in the same loop. Each loop has to reload the whole BO list from the L2 cache or higher, so we do it twice. By merging the loops, we only load the BO list from the L2 cache once. The final result is actually 2 loops, but they iterate over different ranges of the BO list, so each element is read only once. If global_bo_list is enabled, it overwrites the BO list after all is done. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 52 ++++++++++++----------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 9b7fffc0913..e143246b244 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -1191,6 +1191,13 @@ static void amdgpu_set_bo_seq_no(unsigned queue_index, struct amdgpu_winsys_bo * bo->fences.valid_fence_mask |= BITFIELD_BIT(queue_index); } +static void amdgpu_add_to_kernel_bo_list(struct drm_amdgpu_bo_list_entry *bo_entry, + struct amdgpu_winsys_bo *bo, unsigned usage) +{ + bo_entry->bo_handle = get_real_bo(bo)->kms_handle; + bo_entry->bo_priority = (util_last_bit(usage & RADEON_ALL_PRIORITIES) - 1) / 2; +} + static void amdgpu_cs_add_syncobj_signal(struct radeon_cmdbuf *rws, struct pipe_fence_handle *fence) { @@ -1333,14 +1340,26 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index) } /* Real BOs: Add fence dependencies, update seq_no in BOs except sparse backing BOs. */ + unsigned num_real_buffers = cs->buffer_lists[AMDGPU_BO_REAL].num_buffers; struct amdgpu_cs_buffer *real_buffers = cs->buffer_lists[AMDGPU_BO_REAL].buffers; + struct drm_amdgpu_bo_list_entry *bo_list = + alloca(num_real_buffers * sizeof(struct drm_amdgpu_bo_list_entry)); + unsigned i; - for (unsigned i = 0; i < num_real_buffers_except_sparse; i++) { + for (i = 0; i < num_real_buffers_except_sparse; i++) { struct amdgpu_cs_buffer *buffer = &real_buffers[i]; struct amdgpu_winsys_bo *bo = buffer->bo; amdgpu_add_fences_to_dependencies(ws, queue_index, &seq_no_dependencies, bo, buffer->usage); amdgpu_set_bo_seq_no(queue_index, bo, next_seq_no); + amdgpu_add_to_kernel_bo_list(&bo_list[i], bo, buffer->usage); + } + + /* Sparse backing BOs are last. Don't update their fences because we don't use them. */ + for (; i < num_real_buffers; ++i) { + struct amdgpu_cs_buffer *buffer = &real_buffers[i]; + + amdgpu_add_to_kernel_bo_list(&bo_list[i], buffer->bo, buffer->usage); } #if 0 /* Debug code. */ @@ -1394,9 +1413,6 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index) amdgpu_ctx_reference(&queue->last_ctx, acs->ctx); simple_mtx_unlock(&ws->bo_fence_lock); - struct drm_amdgpu_bo_list_entry *bo_list = NULL; - unsigned num_bo_handles = 0; - #if DEBUG /* Prepare the buffer list. */ if (ws->debug_all_bos) { @@ -1407,31 +1423,19 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index) bo_list = alloca(ws->num_buffers * sizeof(struct drm_amdgpu_bo_list_entry)); struct amdgpu_bo_real *bo; + num_real_buffers = 0; + LIST_FOR_EACH_ENTRY(bo, &ws->global_bo_list, global_list_item) { - bo_list[num_bo_handles].bo_handle = bo->kms_handle; - bo_list[num_bo_handles].bo_priority = 0; - ++num_bo_handles; + bo_list[num_real_buffers].bo_handle = bo->kms_handle; + bo_list[num_real_buffers].bo_priority = 0; + ++num_real_buffers; } simple_mtx_unlock(&ws->global_bo_list_lock); - } else -#endif - { - struct amdgpu_cs_buffer *real_buffers = cs->buffer_lists[AMDGPU_BO_REAL].buffers; - unsigned num_real_buffers = cs->buffer_lists[AMDGPU_BO_REAL].num_buffers; - bo_list = alloca((num_real_buffers + 2) * sizeof(struct drm_amdgpu_bo_list_entry)); - - for (unsigned i = 0; i < num_real_buffers; ++i) { - struct amdgpu_cs_buffer *buffer = &real_buffers[i]; - - bo_list[num_bo_handles].bo_handle = get_real_bo(buffer->bo)->kms_handle; - bo_list[num_bo_handles].bo_priority = - (util_last_bit(buffer->usage & RADEON_ALL_PRIORITIES) - 1) / 2; - ++num_bo_handles; - } } +#endif if (acs->ip_type == AMD_IP_GFX) - ws->gfx_bo_list_counter += cs->buffer_lists[AMDGPU_BO_REAL].num_buffers; + ws->gfx_bo_list_counter += num_real_buffers; struct drm_amdgpu_cs_chunk chunks[8]; unsigned num_chunks = 0; @@ -1440,7 +1444,7 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index) struct drm_amdgpu_bo_list_in bo_list_in; bo_list_in.operation = ~0; bo_list_in.list_handle = ~0; - bo_list_in.bo_number = num_bo_handles; + bo_list_in.bo_number = num_real_buffers; bo_list_in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry); bo_list_in.bo_info_ptr = (uint64_t)(uintptr_t)bo_list;