• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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