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 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 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 * 73 cl_start(struct vc4_cl *cl) 74 { 75 return cl->next; 76 } 77 78 static inline void 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 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 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 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 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 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 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 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 136 cl_f(struct vc4_cl_out **cl, float f) 137 { 138 cl_u32(cl, fui(f)); 139 } 140 141 static inline void 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 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 * 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 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 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