1 /*
2 * Copyright © 2014 Broadcom
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifndef VC4_CL_H
25 #define VC4_CL_H
26
27 #include <stdint.h>
28
29 #include "util/u_math.h"
30 #include "util/macros.h"
31
32 #include "kernel/vc4_packet.h"
33
34 struct vc4_bo;
35 struct vc4_job;
36
37 /**
38 * Undefined structure, used for typechecking that you're passing the pointers
39 * to these functions correctly.
40 */
41 struct vc4_cl_out;
42
43 struct vc4_cl {
44 void *base;
45 struct vc4_cl_out *next;
46 struct vc4_cl_out *reloc_next;
47 uint32_t size;
48 #ifdef DEBUG
49 uint32_t reloc_count;
50 #endif
51 };
52
53 void vc4_init_cl(void *mem_ctx, struct vc4_cl *cl);
54 void vc4_reset_cl(struct vc4_cl *cl);
55 void vc4_dump_cl(void *cl, uint32_t size, bool is_render);
56 uint32_t vc4_gem_hindex(struct vc4_job *job, struct vc4_bo *bo);
57
58 struct PACKED unaligned_16 { uint16_t x; };
59 struct PACKED unaligned_32 { uint32_t x; };
60
cl_offset(struct vc4_cl * cl)61 static inline uint32_t cl_offset(struct vc4_cl *cl)
62 {
63 return (char *)cl->next - (char *)cl->base;
64 }
65
66 static inline void
cl_advance(struct vc4_cl_out ** cl,uint32_t n)67 cl_advance(struct vc4_cl_out **cl, uint32_t n)
68 {
69 (*cl) = (struct vc4_cl_out *)((char *)(*cl) + n);
70 }
71
72 static inline struct vc4_cl_out *
cl_start(struct vc4_cl * cl)73 cl_start(struct vc4_cl *cl)
74 {
75 return cl->next;
76 }
77
78 static inline void
cl_end(struct vc4_cl * cl,struct vc4_cl_out * next)79 cl_end(struct vc4_cl *cl, struct vc4_cl_out *next)
80 {
81 cl->next = next;
82 assert(cl_offset(cl) <= cl->size);
83 }
84
85
86 static inline void
put_unaligned_32(struct vc4_cl_out * ptr,uint32_t val)87 put_unaligned_32(struct vc4_cl_out *ptr, uint32_t val)
88 {
89 struct unaligned_32 *p = (void *)ptr;
90 p->x = val;
91 }
92
93 static inline void
put_unaligned_16(struct vc4_cl_out * ptr,uint16_t val)94 put_unaligned_16(struct vc4_cl_out *ptr, uint16_t val)
95 {
96 struct unaligned_16 *p = (void *)ptr;
97 p->x = val;
98 }
99
100 static inline void
cl_u8(struct vc4_cl_out ** cl,uint8_t n)101 cl_u8(struct vc4_cl_out **cl, uint8_t n)
102 {
103 *(uint8_t *)(*cl) = n;
104 cl_advance(cl, 1);
105 }
106
107 static inline void
cl_u16(struct vc4_cl_out ** cl,uint16_t n)108 cl_u16(struct vc4_cl_out **cl, uint16_t n)
109 {
110 put_unaligned_16(*cl, n);
111 cl_advance(cl, 2);
112 }
113
114 static inline void
cl_u32(struct vc4_cl_out ** cl,uint32_t n)115 cl_u32(struct vc4_cl_out **cl, uint32_t n)
116 {
117 put_unaligned_32(*cl, n);
118 cl_advance(cl, 4);
119 }
120
121 static inline void
cl_aligned_u32(struct vc4_cl_out ** cl,uint32_t n)122 cl_aligned_u32(struct vc4_cl_out **cl, uint32_t n)
123 {
124 *(uint32_t *)(*cl) = n;
125 cl_advance(cl, 4);
126 }
127
128 static inline void
cl_ptr(struct vc4_cl_out ** cl,void * ptr)129 cl_ptr(struct vc4_cl_out **cl, void *ptr)
130 {
131 *(struct vc4_cl_out **)(*cl) = ptr;
132 cl_advance(cl, sizeof(void *));
133 }
134
135 static inline void
cl_f(struct vc4_cl_out ** cl,float f)136 cl_f(struct vc4_cl_out **cl, float f)
137 {
138 cl_u32(cl, fui(f));
139 }
140
141 static inline void
cl_aligned_f(struct vc4_cl_out ** cl,float f)142 cl_aligned_f(struct vc4_cl_out **cl, float f)
143 {
144 cl_aligned_u32(cl, fui(f));
145 }
146
147 static inline void
cl_start_reloc(struct vc4_cl * cl,struct vc4_cl_out ** out,uint32_t n)148 cl_start_reloc(struct vc4_cl *cl, struct vc4_cl_out **out, uint32_t n)
149 {
150 assert(n == 1 || n == 2);
151 #ifdef DEBUG
152 assert(cl->reloc_count == 0);
153 cl->reloc_count = n;
154 #endif
155
156 cl_u8(out, VC4_PACKET_GEM_HANDLES);
157 cl->reloc_next = *out;
158 cl_u32(out, 0); /* Space where hindex will be written. */
159 cl_u32(out, 0); /* Space where hindex will be written. */
160 }
161
162 static inline struct vc4_cl_out *
cl_start_shader_reloc(struct vc4_cl * cl,uint32_t n)163 cl_start_shader_reloc(struct vc4_cl *cl, uint32_t n)
164 {
165 #ifdef DEBUG
166 assert(cl->reloc_count == 0);
167 cl->reloc_count = n;
168 #endif
169 cl->reloc_next = cl->next;
170
171 /* Reserve the space where hindex will be written. */
172 cl_advance(&cl->next, n * 4);
173
174 return cl->next;
175 }
176
177 static inline void
cl_reloc(struct vc4_job * job,struct vc4_cl * cl,struct vc4_cl_out ** cl_out,struct vc4_bo * bo,uint32_t offset)178 cl_reloc(struct vc4_job *job, struct vc4_cl *cl, struct vc4_cl_out **cl_out,
179 struct vc4_bo *bo, uint32_t offset)
180 {
181 *(uint32_t *)cl->reloc_next = vc4_gem_hindex(job, bo);
182 cl_advance(&cl->reloc_next, 4);
183
184 #ifdef DEBUG
185 cl->reloc_count--;
186 #endif
187
188 cl_u32(cl_out, offset);
189 }
190
191 static inline void
cl_aligned_reloc(struct vc4_job * job,struct vc4_cl * cl,struct vc4_cl_out ** cl_out,struct vc4_bo * bo,uint32_t offset)192 cl_aligned_reloc(struct vc4_job *job, struct vc4_cl *cl,
193 struct vc4_cl_out **cl_out,
194 struct vc4_bo *bo, uint32_t offset)
195 {
196 *(uint32_t *)cl->reloc_next = vc4_gem_hindex(job, bo);
197 cl_advance(&cl->reloc_next, 4);
198
199 #ifdef DEBUG
200 cl->reloc_count--;
201 #endif
202
203 cl_aligned_u32(cl_out, offset);
204 }
205
206 void cl_ensure_space(struct vc4_cl *cl, uint32_t size);
207
208 #endif /* VC4_CL_H */
209