1 #include "crocus_context.h"
2 #include "crocus_fine_fence.h"
3 #include "util/u_upload_mgr.h"
4
5 static void
crocus_fine_fence_reset(struct crocus_batch * batch)6 crocus_fine_fence_reset(struct crocus_batch *batch)
7 {
8 u_upload_alloc(batch->fine_fences.uploader,
9 0, sizeof(uint64_t), sizeof(uint64_t),
10 &batch->fine_fences.ref.offset, &batch->fine_fences.ref.res,
11 (void **)&batch->fine_fences.map);
12 WRITE_ONCE(*batch->fine_fences.map, 0);
13 batch->fine_fences.next++;
14 }
15
16 void
crocus_fine_fence_init(struct crocus_batch * batch)17 crocus_fine_fence_init(struct crocus_batch *batch)
18 {
19 batch->fine_fences.ref.res = NULL;
20 batch->fine_fences.next = 0;
21 if (batch_has_fine_fence(batch))
22 crocus_fine_fence_reset(batch);
23 }
24
25 static uint32_t
crocus_fine_fence_next(struct crocus_batch * batch)26 crocus_fine_fence_next(struct crocus_batch *batch)
27 {
28 if (!batch_has_fine_fence(batch))
29 return UINT32_MAX;
30
31 uint32_t seqno = batch->fine_fences.next++;
32
33 if (batch->fine_fences.next == 0)
34 crocus_fine_fence_reset(batch);
35
36 return seqno;
37 }
38
39 void
crocus_fine_fence_destroy(struct crocus_screen * screen,struct crocus_fine_fence * fine)40 crocus_fine_fence_destroy(struct crocus_screen *screen,
41 struct crocus_fine_fence *fine)
42 {
43 crocus_syncobj_reference(screen, &fine->syncobj, NULL);
44 pipe_resource_reference(&fine->ref.res, NULL);
45 free(fine);
46 }
47
48 struct crocus_fine_fence *
crocus_fine_fence_new(struct crocus_batch * batch,unsigned flags)49 crocus_fine_fence_new(struct crocus_batch *batch, unsigned flags)
50 {
51 struct crocus_fine_fence *fine = calloc(1, sizeof(*fine));
52 if (!fine)
53 return NULL;
54
55 pipe_reference_init(&fine->reference, 1);
56
57 fine->seqno = crocus_fine_fence_next(batch);
58
59 crocus_syncobj_reference(batch->screen, &fine->syncobj,
60 crocus_batch_get_signal_syncobj(batch));
61
62 if (!batch_has_fine_fence(batch))
63 return fine;
64 pipe_resource_reference(&fine->ref.res, batch->fine_fences.ref.res);
65 fine->ref.offset = batch->fine_fences.ref.offset;
66 fine->map = batch->fine_fences.map;
67 fine->flags = flags;
68
69 unsigned pc;
70 if (flags & CROCUS_FENCE_TOP_OF_PIPE) {
71 pc = PIPE_CONTROL_WRITE_IMMEDIATE | PIPE_CONTROL_CS_STALL;
72 } else {
73 pc = PIPE_CONTROL_WRITE_IMMEDIATE |
74 PIPE_CONTROL_RENDER_TARGET_FLUSH |
75 PIPE_CONTROL_TILE_CACHE_FLUSH |
76 PIPE_CONTROL_DEPTH_CACHE_FLUSH |
77 PIPE_CONTROL_DATA_CACHE_FLUSH;
78 }
79 crocus_emit_pipe_control_write(batch, "fence: fine", pc,
80 crocus_resource_bo(fine->ref.res),
81 fine->ref.offset,
82 fine->seqno);
83
84 return fine;
85 }
86