From 45cd75cdad3f6b34a47b3cb930db2dfb04669722 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 7 Apr 2023 09:23:04 +0200 Subject: [PATCH] winsys/amdgpu: add a helper function to submit a no-op job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used in the next commit. Reviewed-by: André Almeida Reviewed-by: Marek Olšák Part-of: --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 24a2bb021f3..f9c24287e4e 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -347,6 +347,89 @@ static void amdgpu_ctx_destroy(struct radeon_winsys_ctx *rwctx) amdgpu_ctx_unref((struct amdgpu_ctx*)rwctx); } +static int amdgpu_submit_gfx_nop(amdgpu_device_handle dev) +{ + struct amdgpu_bo_alloc_request request = {0}; + struct drm_amdgpu_bo_list_in bo_list_in; + struct drm_amdgpu_cs_chunk_ib ib_in = {0}; + amdgpu_bo_handle buf_handle; + amdgpu_va_handle va_handle = NULL; + struct drm_amdgpu_cs_chunk chunks[2]; + void *cpu = NULL; + uint64_t seq_no; + uint64_t va; + int r; + + /* Older amdgpu doesn't report if the reset is complete or not. Detect + * it by submitting a no-op job. If it reports an error, then assume + * that the reset is not complete. + */ + amdgpu_context_handle temp_ctx; + r = amdgpu_cs_ctx_create2(dev, AMDGPU_CTX_PRIORITY_NORMAL, &temp_ctx); + if (r) + return r; + + request.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM; + request.alloc_size = 4096; + request.phys_alignment = 4096; + r = amdgpu_bo_alloc(dev, &request, &buf_handle); + if (r) + goto destroy_ctx; + + r = amdgpu_va_range_alloc(dev, amdgpu_gpu_va_range_general, + request.alloc_size, request.phys_alignment, + 0, &va, &va_handle, + AMDGPU_VA_RANGE_32_BIT | AMDGPU_VA_RANGE_HIGH); + if (r) + goto destroy_bo; + r = amdgpu_bo_va_op_raw(dev, buf_handle, 0, request.alloc_size, va, + AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE, + AMDGPU_VA_OP_MAP); + if (r) + goto destroy_bo; + + r = amdgpu_bo_cpu_map(buf_handle, &cpu); + if (r) + goto destroy_bo; + + /* Use a single NOP. */ + ((uint32_t*)cpu)[0] = PKT3_NOP_PAD; + + amdgpu_bo_cpu_unmap(buf_handle); + + struct drm_amdgpu_bo_list_entry list; + amdgpu_bo_export(buf_handle, amdgpu_bo_handle_type_kms, &list.bo_handle); + list.bo_priority = 0; + + bo_list_in.list_handle = ~0; + bo_list_in.bo_number = 1; + bo_list_in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry); + bo_list_in.bo_info_ptr = (uint64_t)(uintptr_t)&list; + + ib_in.ip_type = AMD_IP_GFX; + ib_in.ib_bytes = 4; + ib_in.va_start = va; + + chunks[0].chunk_id = AMDGPU_CHUNK_ID_BO_HANDLES; + chunks[0].length_dw = sizeof(struct drm_amdgpu_bo_list_in) / 4; + chunks[0].chunk_data = (uintptr_t)&bo_list_in; + + chunks[1].chunk_id = AMDGPU_CHUNK_ID_IB; + chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4; + chunks[1].chunk_data = (uintptr_t)&ib_in; + + r = amdgpu_cs_submit_raw2(dev, temp_ctx, 0, 2, chunks, &seq_no); + +destroy_bo: + if (va_handle) + amdgpu_va_range_free(va_handle); + amdgpu_bo_free(buf_handle); +destroy_ctx: + amdgpu_cs_ctx_free(temp_ctx); + + return r; +} + static enum pipe_reset_status amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool full_reset_only, bool *needs_reset, bool *reset_completed)