mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-20 11:00:24 +01:00
ac,radeonsi: require DRM 3.27+ (kernel 4.20+) same as RADV
The only major change is the code removal of the legacy BO list path in the winsys, which required switching "debug_all_bos" to the new path. Reviewed-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26547>
This commit is contained in:
parent
5cfd659276
commit
390f26eefb
4 changed files with 64 additions and 118 deletions
|
|
@ -624,9 +624,9 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info,
|
|||
assert(info->drm_major == 3);
|
||||
info->is_amdgpu = true;
|
||||
|
||||
if (info->drm_minor < 15) {
|
||||
if (info->drm_minor < 27) {
|
||||
fprintf(stderr, "amdgpu: DRM version is %u.%u.%u, but this driver is "
|
||||
"only compatible with 3.15.0 (kernel 4.12) or later.\n",
|
||||
"only compatible with 3.27.0 (kernel 4.20+) or later.\n",
|
||||
info->drm_major, info->drm_minor, info->drm_patchlevel);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1015,8 +1015,8 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info,
|
|||
info->has_userptr = true;
|
||||
info->has_syncobj = has_syncobj(fd);
|
||||
info->has_timeline_syncobj = has_timeline_syncobj(fd);
|
||||
info->has_fence_to_handle = info->has_syncobj && info->drm_minor >= 21;
|
||||
info->has_local_buffers = info->drm_minor >= 20;
|
||||
info->has_fence_to_handle = info->has_syncobj;
|
||||
info->has_local_buffers = true;
|
||||
info->has_bo_metadata = true;
|
||||
info->has_eqaa_surface_allocator = info->gfx_level < GFX11;
|
||||
/* Disable sparse mappings on GFX6 due to VM faults in CP DMA. Enable them once
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ do_winsys_init(struct radv_amdgpu_winsys *ws, int fd)
|
|||
for (enum amd_ip_type ip_type = AMD_IP_UVD; ip_type <= AMD_IP_VCN_ENC; ip_type++)
|
||||
ws->info.max_submitted_ibs[ip_type] = 1;
|
||||
|
||||
if (ws->info.drm_minor < 27) {
|
||||
fprintf(stderr, "radv/amdgpu: DRM 3.27+ is required (Linux kernel 4.20+)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ws->addrlib = ac_addrlib_create(&ws->info, &ws->info.max_alignment);
|
||||
if (!ws->addrlib) {
|
||||
fprintf(stderr, "radv/amdgpu: Cannot create addrlib.\n");
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ static int si_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
return enable_sparse ? RADEON_SPARSE_PAGE_SIZE : 0;
|
||||
|
||||
case PIPE_CAP_CONTEXT_PRIORITY_MASK:
|
||||
if (!(sscreen->info.is_amdgpu && sscreen->info.drm_minor >= 22))
|
||||
if (!sscreen->info.is_amdgpu)
|
||||
return 0;
|
||||
return PIPE_CONTEXT_PRIORITY_LOW |
|
||||
PIPE_CONTEXT_PRIORITY_MEDIUM |
|
||||
|
|
@ -880,7 +880,7 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
|
|||
}
|
||||
if (sscreen->info.family < CHIP_CARRIZO || sscreen->info.family >= CHIP_VEGA10)
|
||||
return false;
|
||||
if (!(sscreen->info.is_amdgpu && sscreen->info.drm_minor >= 19)) {
|
||||
if (!sscreen->info.is_amdgpu) {
|
||||
RVID_ERR("No MJPEG support for the kernel version\n");
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -476,68 +476,47 @@ amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool full_reset_o
|
|||
*reset_completed = false;
|
||||
|
||||
/* Return a failure due to a GPU hang. */
|
||||
if (ctx->ws->info.drm_minor >= 24) {
|
||||
uint64_t flags;
|
||||
uint64_t flags;
|
||||
|
||||
if (full_reset_only && ctx->sw_status == PIPE_NO_RESET) {
|
||||
/* If the caller is only interested in full reset (= wants to ignore soft
|
||||
* recoveries), we can use the rejected cs count as a quick first check.
|
||||
if (full_reset_only && ctx->sw_status == PIPE_NO_RESET) {
|
||||
/* If the caller is only interested in full reset (= wants to ignore soft
|
||||
* recoveries), we can use the rejected cs count as a quick first check.
|
||||
*/
|
||||
return PIPE_NO_RESET;
|
||||
}
|
||||
|
||||
r = amdgpu_cs_query_reset_state2(ctx->ctx, &flags);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: amdgpu_cs_query_reset_state2 failed. (%i)\n", r);
|
||||
return PIPE_NO_RESET;
|
||||
}
|
||||
|
||||
if (flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) {
|
||||
if (reset_completed) {
|
||||
/* The ARB_robustness spec says:
|
||||
*
|
||||
* If a reset status other than NO_ERROR is returned and subsequent
|
||||
* calls return NO_ERROR, the context reset was encountered and
|
||||
* completed. If a reset status is repeatedly returned, the context may
|
||||
* be in the process of resetting.
|
||||
*
|
||||
* Starting with drm_minor >= 54 amdgpu reports if the reset is complete,
|
||||
* so don't do anything special. On older kernels, submit a no-op cs. If it
|
||||
* succeeds then assume the reset is complete.
|
||||
*/
|
||||
return PIPE_NO_RESET;
|
||||
}
|
||||
if (!(flags & AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS))
|
||||
*reset_completed = true;
|
||||
|
||||
r = amdgpu_cs_query_reset_state2(ctx->ctx, &flags);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: amdgpu_cs_query_reset_state2 failed. (%i)\n", r);
|
||||
return PIPE_NO_RESET;
|
||||
}
|
||||
|
||||
if (flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) {
|
||||
if (reset_completed) {
|
||||
/* The ARB_robustness spec says:
|
||||
*
|
||||
* If a reset status other than NO_ERROR is returned and subsequent
|
||||
* calls return NO_ERROR, the context reset was encountered and
|
||||
* completed. If a reset status is repeatedly returned, the context may
|
||||
* be in the process of resetting.
|
||||
*
|
||||
* Starting with drm_minor >= 54 amdgpu reports if the reset is complete,
|
||||
* so don't do anything special. On older kernels, submit a no-op cs. If it
|
||||
* succeeds then assume the reset is complete.
|
||||
*/
|
||||
if (!(flags & AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS))
|
||||
*reset_completed = true;
|
||||
|
||||
if (ctx->ws->info.drm_minor < 54 && ctx->ws->info.has_graphics)
|
||||
*reset_completed = amdgpu_submit_gfx_nop(ctx) == 0;
|
||||
}
|
||||
|
||||
if (needs_reset)
|
||||
*needs_reset = flags & AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
|
||||
if (flags & AMDGPU_CTX_QUERY2_FLAGS_GUILTY)
|
||||
return PIPE_GUILTY_CONTEXT_RESET;
|
||||
else
|
||||
return PIPE_INNOCENT_CONTEXT_RESET;
|
||||
}
|
||||
} else {
|
||||
uint32_t result, hangs;
|
||||
|
||||
r = amdgpu_cs_query_reset_state(ctx->ctx, &result, &hangs);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: amdgpu_cs_query_reset_state failed. (%i)\n", r);
|
||||
return PIPE_NO_RESET;
|
||||
if (ctx->ws->info.drm_minor < 54 && ctx->ws->info.has_graphics)
|
||||
*reset_completed = amdgpu_submit_gfx_nop(ctx) == 0;
|
||||
}
|
||||
|
||||
if (needs_reset)
|
||||
*needs_reset = true;
|
||||
switch (result) {
|
||||
case AMDGPU_CTX_GUILTY_RESET:
|
||||
*needs_reset = flags & AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
|
||||
if (flags & AMDGPU_CTX_QUERY2_FLAGS_GUILTY)
|
||||
return PIPE_GUILTY_CONTEXT_RESET;
|
||||
case AMDGPU_CTX_INNOCENT_RESET:
|
||||
else
|
||||
return PIPE_INNOCENT_CONTEXT_RESET;
|
||||
case AMDGPU_CTX_UNKNOWN_RESET:
|
||||
return PIPE_UNKNOWN_CONTEXT_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a failure due to SW issues. */
|
||||
|
|
@ -1036,10 +1015,8 @@ static bool amdgpu_init_cs_context(struct amdgpu_winsys *ws,
|
|||
* the next IB starts drawing, and so the cache flush at the end of IB
|
||||
* is always late.
|
||||
*/
|
||||
if (ws->info.drm_minor >= 26) {
|
||||
cs->chunk_ib[IB_PREAMBLE].flags = AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE;
|
||||
cs->chunk_ib[IB_MAIN].flags = AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE;
|
||||
}
|
||||
cs->chunk_ib[IB_PREAMBLE].flags = AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE;
|
||||
cs->chunk_ib[IB_MAIN].flags = AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1535,41 +1512,33 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index)
|
|||
struct amdgpu_winsys *ws = acs->ws;
|
||||
struct amdgpu_cs_context *cs = acs->cst;
|
||||
int i, r;
|
||||
uint32_t bo_list = 0;
|
||||
uint64_t seq_no = 0;
|
||||
bool has_user_fence = amdgpu_cs_has_user_fence(cs);
|
||||
bool use_bo_list_create = ws->info.drm_minor < 27;
|
||||
struct drm_amdgpu_bo_list_in bo_list_in;
|
||||
unsigned initial_num_real_buffers = cs->num_real_buffers;
|
||||
|
||||
simple_mtx_lock(&ws->bo_fence_lock);
|
||||
amdgpu_add_fence_dependencies_bo_lists(acs, cs);
|
||||
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) {
|
||||
/* The buffer list contains all buffers. This is a slow path that
|
||||
* ensures that no buffer is missing in the BO list.
|
||||
*/
|
||||
unsigned num_handles = 0;
|
||||
struct drm_amdgpu_bo_list_entry *list =
|
||||
alloca(ws->num_buffers * sizeof(struct drm_amdgpu_bo_list_entry));
|
||||
bo_list = alloca(ws->num_buffers * sizeof(struct drm_amdgpu_bo_list_entry));
|
||||
struct amdgpu_winsys_bo *bo;
|
||||
|
||||
simple_mtx_lock(&ws->global_bo_list_lock);
|
||||
LIST_FOR_EACH_ENTRY(bo, &ws->global_bo_list, u.real.global_list_item) {
|
||||
list[num_handles].bo_handle = bo->u.real.kms_handle;
|
||||
list[num_handles].bo_priority = 0;
|
||||
++num_handles;
|
||||
bo_list[num_bo_handles].bo_handle = bo->u.real.kms_handle;
|
||||
bo_list[num_bo_handles].bo_priority = 0;
|
||||
++num_bo_handles;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_list_create_raw(ws->dev, ws->num_buffers, list, &bo_list);
|
||||
simple_mtx_unlock(&ws->global_bo_list_lock);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: buffer list creation failed (%d)\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
@ -1579,33 +1548,15 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
struct drm_amdgpu_bo_list_entry *list =
|
||||
alloca((cs->num_real_buffers + 2) * sizeof(struct drm_amdgpu_bo_list_entry));
|
||||
bo_list = alloca((cs->num_real_buffers + 2) * sizeof(struct drm_amdgpu_bo_list_entry));
|
||||
|
||||
unsigned num_handles = 0;
|
||||
for (i = 0; i < cs->num_real_buffers; ++i) {
|
||||
struct amdgpu_cs_buffer *buffer = &cs->real_buffers[i];
|
||||
|
||||
list[num_handles].bo_handle = buffer->bo->u.real.kms_handle;
|
||||
list[num_handles].bo_priority =
|
||||
bo_list[num_bo_handles].bo_handle = buffer->bo->u.real.kms_handle;
|
||||
bo_list[num_bo_handles].bo_priority =
|
||||
(util_last_bit(buffer->usage & RADEON_ALL_PRIORITIES) - 1) / 2;
|
||||
++num_handles;
|
||||
}
|
||||
|
||||
if (use_bo_list_create) {
|
||||
/* Legacy path creating the buffer list handle and passing it to the CS ioctl. */
|
||||
r = amdgpu_bo_list_create_raw(ws->dev, num_handles, list, &bo_list);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: buffer list creation failed (%d)\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
/* Standard path passing the buffer list via the CS ioctl. */
|
||||
bo_list_in.operation = ~0;
|
||||
bo_list_in.list_handle = ~0;
|
||||
bo_list_in.bo_number = num_handles;
|
||||
bo_list_in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
bo_list_in.bo_info_ptr = (uint64_t)(uintptr_t)list;
|
||||
++num_bo_handles;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1616,12 +1567,17 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index)
|
|||
unsigned num_chunks = 0;
|
||||
|
||||
/* BO list */
|
||||
if (!use_bo_list_create) {
|
||||
chunks[num_chunks].chunk_id = AMDGPU_CHUNK_ID_BO_HANDLES;
|
||||
chunks[num_chunks].length_dw = sizeof(struct drm_amdgpu_bo_list_in) / 4;
|
||||
chunks[num_chunks].chunk_data = (uintptr_t)&bo_list_in;
|
||||
num_chunks++;
|
||||
}
|
||||
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_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
bo_list_in.bo_info_ptr = (uint64_t)(uintptr_t)bo_list;
|
||||
|
||||
chunks[num_chunks].chunk_id = AMDGPU_CHUNK_ID_BO_HANDLES;
|
||||
chunks[num_chunks].length_dw = sizeof(struct drm_amdgpu_bo_list_in) / 4;
|
||||
chunks[num_chunks].chunk_data = (uintptr_t)&bo_list_in;
|
||||
num_chunks++;
|
||||
|
||||
/* Fence dependencies. */
|
||||
unsigned num_dependencies = cs->fence_dependencies.num;
|
||||
|
|
@ -1757,8 +1713,7 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index)
|
|||
if (r == -ENOMEM)
|
||||
os_time_sleep(1000);
|
||||
|
||||
r = amdgpu_cs_submit_raw2(ws->dev, acs->ctx->ctx, bo_list,
|
||||
num_chunks, chunks, &seq_no);
|
||||
r = amdgpu_cs_submit_raw2(ws->dev, acs->ctx->ctx, 0, num_chunks, chunks, &seq_no);
|
||||
} while (r == -ENOMEM);
|
||||
|
||||
if (!r) {
|
||||
|
|
@ -1777,10 +1732,6 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index)
|
|||
}
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
if (bo_list)
|
||||
amdgpu_bo_list_destroy_raw(ws->dev, bo_list);
|
||||
|
||||
cleanup:
|
||||
if (unlikely(r)) {
|
||||
amdgpu_ctx_set_sw_reset_status((struct radeon_winsys_ctx*)acs->ctx,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue