1#include "crocus_context.h"
2#include "crocus_fine_fence.h"
3#include "util/u_upload_mgr.h"
4
5static void
6crocus_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
16void
17crocus_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
25static uint32_t
26crocus_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
39void
40crocus_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
48struct crocus_fine_fence *
49crocus_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