aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Yoo2017-05-09 00:32:30 -0500
committerRichard Yoo2017-05-09 01:08:15 -0500
commitd8ed3020112ded2e210e652f5a8f367d5f847157 (patch)
treea56c761e21902ba6b24df5c5b8168372ab995162 /amdgpu/amdgpu_cs.c
parent0da99b8ab0f691ad7ec7f4c5c8a09c5df92486a1 (diff)
parentd4b8344363b4e0f0e831e5722b6df5cc0bb08df8 (diff)
downloadexternal-libdrm-69f814d8c4a25e029ff2719e5e6b0afa4b78ba1f.tar.gz
external-libdrm-69f814d8c4a25e029ff2719e5e6b0afa4b78ba1f.tar.xz
external-libdrm-69f814d8c4a25e029ff2719e5e6b0afa4b78ba1f.zip
Merge tag libdrm-2.4.75 into aosp/masterandroid-n-iot-preview-4
Below is a brief summary of patches pulled in: 0da99b8a (m/master, aosp/master) Move libdrm.so to vendor partition d4b83443 (tag: libdrm-2.4.75) Bump version for 2.4.75 release dae413e4 (tag: libdrm-2.4.74) Bump version for release 317bdff1 (tag: libdrm-2.4.73) Bump version for release 8cf43127 (tag: libdrm-2.4.72) Bump version for release a44c9c31 (tag: libdrm-2.4.71) Bump version for release 20208455 (tag: android-o-preview-1, tag: android-n-mr2-preview-2, tag: android-n-mr2-preview-1, aosp/sdk-release, aosp/o-preview) add a flag control that private libdrm can be chosen Bug: 35871718 Test: aosp_arm-eng compiles Change-Id: I81985fd41d5c0d8a732705dc2a4bee8eb5d459bb
Diffstat (limited to 'amdgpu/amdgpu_cs.c')
-rw-r--r--amdgpu/amdgpu_cs.c181
1 files changed, 177 insertions, 4 deletions
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 6747158c..fb5b3a8c 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -40,6 +40,9 @@
40#include "amdgpu_drm.h" 40#include "amdgpu_drm.h"
41#include "amdgpu_internal.h" 41#include "amdgpu_internal.h"
42 42
43static int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem);
44static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem);
45
43/** 46/**
44 * Create command submission context 47 * Create command submission context
45 * 48 *
@@ -53,6 +56,7 @@ int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
53{ 56{
54 struct amdgpu_context *gpu_context; 57 struct amdgpu_context *gpu_context;
55 union drm_amdgpu_ctx args; 58 union drm_amdgpu_ctx args;
59 int i, j, k;
56 int r; 60 int r;
57 61
58 if (NULL == dev) 62 if (NULL == dev)
@@ -66,6 +70,10 @@ int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
66 70
67 gpu_context->dev = dev; 71 gpu_context->dev = dev;
68 72
73 r = pthread_mutex_init(&gpu_context->sequence_mutex, NULL);
74 if (r)
75 goto error;
76
69 /* Create the context */ 77 /* Create the context */
70 memset(&args, 0, sizeof(args)); 78 memset(&args, 0, sizeof(args));
71 args.in.op = AMDGPU_CTX_OP_ALLOC_CTX; 79 args.in.op = AMDGPU_CTX_OP_ALLOC_CTX;
@@ -74,11 +82,16 @@ int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
74 goto error; 82 goto error;
75 83
76 gpu_context->id = args.out.alloc.ctx_id; 84 gpu_context->id = args.out.alloc.ctx_id;
85 for (i = 0; i < AMDGPU_HW_IP_NUM; i++)
86 for (j = 0; j < AMDGPU_HW_IP_INSTANCE_MAX_COUNT; j++)
87 for (k = 0; k < AMDGPU_CS_MAX_RINGS; k++)
88 list_inithead(&gpu_context->sem_list[i][j][k]);
77 *context = (amdgpu_context_handle)gpu_context; 89 *context = (amdgpu_context_handle)gpu_context;
78 90
79 return 0; 91 return 0;
80 92
81error: 93error:
94 pthread_mutex_destroy(&gpu_context->sequence_mutex);
82 free(gpu_context); 95 free(gpu_context);
83 return r; 96 return r;
84} 97}
@@ -94,18 +107,32 @@ error:
94int amdgpu_cs_ctx_free(amdgpu_context_handle context) 107int amdgpu_cs_ctx_free(amdgpu_context_handle context)
95{ 108{
96 union drm_amdgpu_ctx args; 109 union drm_amdgpu_ctx args;
110 int i, j, k;
97 int r; 111 int r;
98 112
99 if (NULL == context) 113 if (NULL == context)
100 return -EINVAL; 114 return -EINVAL;
101 115
116 pthread_mutex_destroy(&context->sequence_mutex);
117
102 /* now deal with kernel side */ 118 /* now deal with kernel side */
103 memset(&args, 0, sizeof(args)); 119 memset(&args, 0, sizeof(args));
104 args.in.op = AMDGPU_CTX_OP_FREE_CTX; 120 args.in.op = AMDGPU_CTX_OP_FREE_CTX;
105 args.in.ctx_id = context->id; 121 args.in.ctx_id = context->id;
106 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX, 122 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX,
107 &args, sizeof(args)); 123 &args, sizeof(args));
108 124 for (i = 0; i < AMDGPU_HW_IP_NUM; i++) {
125 for (j = 0; j < AMDGPU_HW_IP_INSTANCE_MAX_COUNT; j++) {
126 for (k = 0; k < AMDGPU_CS_MAX_RINGS; k++) {
127 amdgpu_semaphore_handle sem;
128 LIST_FOR_EACH_ENTRY(sem, &context->sem_list[i][j][k], list) {
129 list_del(&sem->list);
130 amdgpu_cs_reset_sem(sem);
131 amdgpu_cs_unreference_sem(sem);
132 }
133 }
134 }
135 }
109 free(context); 136 free(context);
110 137
111 return r; 138 return r;
@@ -150,7 +177,10 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
150 struct drm_amdgpu_cs_chunk *chunks; 177 struct drm_amdgpu_cs_chunk *chunks;
151 struct drm_amdgpu_cs_chunk_data *chunk_data; 178 struct drm_amdgpu_cs_chunk_data *chunk_data;
152 struct drm_amdgpu_cs_chunk_dep *dependencies = NULL; 179 struct drm_amdgpu_cs_chunk_dep *dependencies = NULL;
153 uint32_t i, size; 180 struct drm_amdgpu_cs_chunk_dep *sem_dependencies = NULL;
181 struct list_head *sem_list;
182 amdgpu_semaphore_handle sem, tmp;
183 uint32_t i, size, sem_count = 0;
154 bool user_fence; 184 bool user_fence;
155 int r = 0; 185 int r = 0;
156 186
@@ -160,9 +190,13 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
160 return -EINVAL; 190 return -EINVAL;
161 if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT) 191 if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT)
162 return -EINVAL; 192 return -EINVAL;
193 if (ibs_request->number_of_ibs == 0) {
194 ibs_request->seq_no = AMDGPU_NULL_SUBMIT_SEQ;
195 return 0;
196 }
163 user_fence = (ibs_request->fence_info.handle != NULL); 197 user_fence = (ibs_request->fence_info.handle != NULL);
164 198
165 size = ibs_request->number_of_ibs + (user_fence ? 2 : 1); 199 size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1;
166 200
167 chunk_array = alloca(sizeof(uint64_t) * size); 201 chunk_array = alloca(sizeof(uint64_t) * size);
168 chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size); 202 chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size);
@@ -196,6 +230,8 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
196 chunk_data[i].ib_data.flags = ib->flags; 230 chunk_data[i].ib_data.flags = ib->flags;
197 } 231 }
198 232
233 pthread_mutex_lock(&context->sequence_mutex);
234
199 if (user_fence) { 235 if (user_fence) {
200 i = cs.in.num_chunks++; 236 i = cs.in.num_chunks++;
201 237
@@ -240,15 +276,49 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
240 chunks[i].chunk_data = (uint64_t)(uintptr_t)dependencies; 276 chunks[i].chunk_data = (uint64_t)(uintptr_t)dependencies;
241 } 277 }
242 278
279 sem_list = &context->sem_list[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring];
280 LIST_FOR_EACH_ENTRY(sem, sem_list, list)
281 sem_count++;
282 if (sem_count) {
283 sem_dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count);
284 if (!sem_dependencies) {
285 r = -ENOMEM;
286 goto error_unlock;
287 }
288 sem_count = 0;
289 LIST_FOR_EACH_ENTRY_SAFE(sem, tmp, sem_list, list) {
290 struct amdgpu_cs_fence *info = &sem->signal_fence;
291 struct drm_amdgpu_cs_chunk_dep *dep = &sem_dependencies[sem_count++];
292 dep->ip_type = info->ip_type;
293 dep->ip_instance = info->ip_instance;
294 dep->ring = info->ring;
295 dep->ctx_id = info->context->id;
296 dep->handle = info->fence;
297
298 list_del(&sem->list);
299 amdgpu_cs_reset_sem(sem);
300 amdgpu_cs_unreference_sem(sem);
301 }
302 i = cs.in.num_chunks++;
303
304 /* dependencies chunk */
305 chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
306 chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES;
307 chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 * sem_count;
308 chunks[i].chunk_data = (uint64_t)(uintptr_t)sem_dependencies;
309 }
310
243 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CS, 311 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CS,
244 &cs, sizeof(cs)); 312 &cs, sizeof(cs));
245 if (r) 313 if (r)
246 goto error_unlock; 314 goto error_unlock;
247 315
248 ibs_request->seq_no = cs.out.handle; 316 ibs_request->seq_no = cs.out.handle;
249 317 context->last_seq[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring] = ibs_request->seq_no;
250error_unlock: 318error_unlock:
319 pthread_mutex_unlock(&context->sequence_mutex);
251 free(dependencies); 320 free(dependencies);
321 free(sem_dependencies);
252 return r; 322 return r;
253} 323}
254 324
@@ -356,6 +426,10 @@ int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
356 return -EINVAL; 426 return -EINVAL;
357 if (fence->ring >= AMDGPU_CS_MAX_RINGS) 427 if (fence->ring >= AMDGPU_CS_MAX_RINGS)
358 return -EINVAL; 428 return -EINVAL;
429 if (fence->fence == AMDGPU_NULL_SUBMIT_SEQ) {
430 *expired = true;
431 return 0;
432 }
359 433
360 *expired = false; 434 *expired = false;
361 435
@@ -369,3 +443,102 @@ int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
369 return r; 443 return r;
370} 444}
371 445
446int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem)
447{
448 struct amdgpu_semaphore *gpu_semaphore;
449
450 if (NULL == sem)
451 return -EINVAL;
452
453 gpu_semaphore = calloc(1, sizeof(struct amdgpu_semaphore));
454 if (NULL == gpu_semaphore)
455 return -ENOMEM;
456
457 atomic_set(&gpu_semaphore->refcount, 1);
458 *sem = gpu_semaphore;
459
460 return 0;
461}
462
463int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx,
464 uint32_t ip_type,
465 uint32_t ip_instance,
466 uint32_t ring,
467 amdgpu_semaphore_handle sem)
468{
469 if (NULL == ctx)
470 return -EINVAL;
471 if (ip_type >= AMDGPU_HW_IP_NUM)
472 return -EINVAL;
473 if (ring >= AMDGPU_CS_MAX_RINGS)
474 return -EINVAL;
475 if (NULL == sem)
476 return -EINVAL;
477 /* sem has been signaled */
478 if (sem->signal_fence.context)
479 return -EINVAL;
480 pthread_mutex_lock(&ctx->sequence_mutex);
481 sem->signal_fence.context = ctx;
482 sem->signal_fence.ip_type = ip_type;
483 sem->signal_fence.ip_instance = ip_instance;
484 sem->signal_fence.ring = ring;
485 sem->signal_fence.fence = ctx->last_seq[ip_type][ip_instance][ring];
486 update_references(NULL, &sem->refcount);
487 pthread_mutex_unlock(&ctx->sequence_mutex);
488 return 0;
489}
490
491int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx,
492 uint32_t ip_type,
493 uint32_t ip_instance,
494 uint32_t ring,
495 amdgpu_semaphore_handle sem)
496{
497 if (NULL == ctx)
498 return -EINVAL;
499 if (ip_type >= AMDGPU_HW_IP_NUM)
500 return -EINVAL;
501 if (ring >= AMDGPU_CS_MAX_RINGS)
502 return -EINVAL;
503 if (NULL == sem)
504 return -EINVAL;
505 /* must signal first */
506 if (NULL == sem->signal_fence.context)
507 return -EINVAL;
508
509 pthread_mutex_lock(&ctx->sequence_mutex);
510 list_add(&sem->list, &ctx->sem_list[ip_type][ip_instance][ring]);
511 pthread_mutex_unlock(&ctx->sequence_mutex);
512 return 0;
513}
514
515static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem)
516{
517 if (NULL == sem)
518 return -EINVAL;
519 if (NULL == sem->signal_fence.context)
520 return -EINVAL;
521
522 sem->signal_fence.context = NULL;;
523 sem->signal_fence.ip_type = 0;
524 sem->signal_fence.ip_instance = 0;
525 sem->signal_fence.ring = 0;
526 sem->signal_fence.fence = 0;
527
528 return 0;
529}
530
531static int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem)
532{
533 if (NULL == sem)
534 return -EINVAL;
535
536 if (update_references(&sem->refcount, NULL))
537 free(sem);
538 return 0;
539}
540
541int amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem)
542{
543 return amdgpu_cs_unreference_sem(sem);
544}