1 /*
2 * Copyright © 2024 Collabora Ltd.
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "panvk_cmd_buffer.h"
7 #include "panvk_entrypoints.h"
8 #include "panvk_event.h"
9
10 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdResetEvent2)11 panvk_per_arch(CmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event,
12 VkPipelineStageFlags2 stageMask)
13 {
14 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
15 VK_FROM_HANDLE(panvk_event, event, _event);
16
17 /* Wrap stageMask with a VkDependencyInfo object so we can re-use
18 * get_cs_deps(). */
19 const VkMemoryBarrier2 barrier = {
20 .srcStageMask = stageMask,
21 };
22 const VkDependencyInfo info = {
23 .memoryBarrierCount = 1,
24 .pMemoryBarriers = &barrier,
25 };
26 struct panvk_cs_deps deps;
27
28 panvk_per_arch(get_cs_deps)(cmdbuf, &info, &deps);
29
30 for (uint32_t i = 0; i < PANVK_SUBQUEUE_COUNT; i++) {
31 struct cs_builder *b = panvk_get_cs_builder(cmdbuf, i);
32 uint32_t sb_mask = deps.src[i].wait_sb_mask;
33 struct cs_index sync_addr = cs_scratch_reg64(b, 0);
34 struct cs_index seqno = cs_scratch_reg32(b, 2);
35 struct cs_index cmp_scratch = cs_scratch_reg32(b, 3);
36
37 cs_move64_to(b, sync_addr,
38 panvk_priv_mem_dev_addr(event->syncobjs) +
39 (i * sizeof(struct panvk_cs_sync32)));
40 cs_load32_to(b, seqno, sync_addr,
41 offsetof(struct panvk_cs_sync32, seqno));
42 cs_wait_slot(b, SB_ID(LS), false);
43
44 cs_match(b, seqno, cmp_scratch) {
45 cs_case(b, 0) {
46 /* Nothing to do, we just need it defined for the default case. */
47 }
48
49 cs_default(b) {
50 cs_move32_to(b, seqno, 0);
51 cs_sync32_set(b, false, MALI_CS_SYNC_SCOPE_SYSTEM, seqno, sync_addr,
52 cs_defer(sb_mask | SB_MASK(DEFERRED_FLUSH),
53 SB_ID(DEFERRED_SYNC)));
54 }
55 }
56 }
57 }
58
59 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdSetEvent2)60 panvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event,
61 const VkDependencyInfo *pDependencyInfo)
62 {
63 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
64 VK_FROM_HANDLE(panvk_event, event, _event);
65 struct panvk_cs_deps deps;
66
67 panvk_per_arch(get_cs_deps)(cmdbuf, pDependencyInfo, &deps);
68
69 if (deps.needs_draw_flush)
70 panvk_per_arch(cmd_flush_draws)(cmdbuf);
71
72 for (uint32_t i = 0; i < PANVK_SUBQUEUE_COUNT; i++) {
73 struct cs_builder *b = panvk_get_cs_builder(cmdbuf, i);
74 uint16_t sb_mask = deps.src[i].wait_sb_mask;
75 struct cs_index sync_addr = cs_scratch_reg64(b, 0);
76 struct cs_index seqno = cs_scratch_reg32(b, 2);
77 struct cs_index cmp_scratch = cs_scratch_reg32(b, 3);
78
79 cs_move64_to(b, sync_addr,
80 panvk_priv_mem_dev_addr(event->syncobjs) +
81 (i * sizeof(struct panvk_cs_sync32)));
82 cs_load32_to(b, seqno, sync_addr,
83 offsetof(struct panvk_cs_sync32, seqno));
84 cs_wait_slot(b, SB_ID(LS), false);
85
86 cs_match(b, seqno, cmp_scratch) {
87 cs_case(b, 0) {
88 struct panvk_cache_flush_info cache_flush = deps.src[i].cache_flush;
89
90 if (cache_flush.l2 != MALI_CS_FLUSH_MODE_NONE ||
91 cache_flush.lsc != MALI_CS_FLUSH_MODE_NONE ||
92 cache_flush.others) {
93 /* We rely on r88 being zero since we're in the if (r88 == 0)
94 * branch. */
95 cs_flush_caches(b, cache_flush.l2, cache_flush.lsc,
96 cache_flush.others, seqno,
97 cs_defer(sb_mask, SB_ID(DEFERRED_FLUSH)));
98 }
99
100 cs_move32_to(b, seqno, 1);
101 cs_sync32_set(b, false, MALI_CS_SYNC_SCOPE_SYSTEM, seqno, sync_addr,
102 cs_defer(sb_mask | SB_MASK(DEFERRED_FLUSH),
103 SB_ID(DEFERRED_SYNC)));
104 }
105 }
106 }
107 }
108
109 static void
cmd_wait_event(struct panvk_cmd_buffer * cmdbuf,struct panvk_event * event,const VkDependencyInfo * info)110 cmd_wait_event(struct panvk_cmd_buffer *cmdbuf, struct panvk_event *event,
111 const VkDependencyInfo *info)
112 {
113 struct panvk_cs_deps deps;
114
115 panvk_per_arch(get_cs_deps)(cmdbuf, info, &deps);
116
117 for (uint32_t i = 0; i < PANVK_SUBQUEUE_COUNT; i++) {
118 if (!deps.dst[i].wait_subqueue_mask)
119 continue;
120
121 struct cs_builder *b = panvk_get_cs_builder(cmdbuf, i);
122
123 for (uint32_t j = 0; j < PANVK_SUBQUEUE_COUNT; j++) {
124 if (!(deps.dst[i].wait_subqueue_mask & BITFIELD_BIT(j)))
125 continue;
126
127 struct cs_index sync_addr = cs_scratch_reg64(b, 0);
128 struct cs_index seqno = cs_scratch_reg32(b, 2);
129
130 cs_move64_to(b, sync_addr,
131 panvk_priv_mem_dev_addr(event->syncobjs) +
132 (j * sizeof(struct panvk_cs_sync32)));
133
134 cs_move32_to(b, seqno, 0);
135 cs_sync32_wait(b, false, MALI_CS_CONDITION_GREATER, seqno, sync_addr);
136 }
137 }
138 }
139
140 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdWaitEvents2)141 panvk_per_arch(CmdWaitEvents2)(VkCommandBuffer commandBuffer,
142 uint32_t eventCount, const VkEvent *pEvents,
143 const VkDependencyInfo *pDependencyInfos)
144 {
145 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
146
147 for (uint32_t i = 0; i < eventCount; i++) {
148 VK_FROM_HANDLE(panvk_event, event, pEvents[i]);
149
150 cmd_wait_event(cmdbuf, event, &pDependencyInfos[i]);
151 }
152 }
153