1 #include "util/blob.h"
2 #include "nv50_ir_driver.h"
3 #include "nv50_ir.h"
4 #include "nv50_ir_target.h"
5 #include "nv50_ir_driver.h"
6 #include "tgsi/tgsi_parse.h"
7 #include "compiler/nir/nir_serialize.h"
8
9 enum FixupApplyFunc {
10 APPLY_NV50,
11 APPLY_NVC0,
12 APPLY_GK110,
13 APPLY_GM107,
14 APPLY_GV100,
15 FLIP_NVC0,
16 FLIP_GK110,
17 FLIP_GM107,
18 FLIP_GV100,
19 };
20
21 extern bool
nv50_ir_prog_info_serialize(struct blob * blob,struct nv50_ir_prog_info * info)22 nv50_ir_prog_info_serialize(struct blob *blob, struct nv50_ir_prog_info *info)
23 {
24 blob_write_uint32(blob, info->bin.smemSize);
25 blob_write_uint16(blob, info->target);
26 blob_write_uint8(blob, info->type);
27 blob_write_uint8(blob, info->optLevel);
28 blob_write_uint8(blob, info->dbgFlags);
29 blob_write_uint8(blob, info->omitLineNum);
30 blob_write_uint8(blob, info->bin.sourceRep);
31
32 switch(info->bin.sourceRep) {
33 case PIPE_SHADER_IR_TGSI: {
34 struct tgsi_token *tokens = (struct tgsi_token *)info->bin.source;
35 unsigned int num_tokens = tgsi_num_tokens(tokens);
36
37 blob_write_uint32(blob, num_tokens);
38 blob_write_bytes(blob, tokens, num_tokens * sizeof(struct tgsi_token));
39 break;
40 }
41 case PIPE_SHADER_IR_NIR: {
42 struct nir_shader *nir = (struct nir_shader *)info->bin.source;
43 nir_serialize(blob, nir, true);
44 break;
45 }
46 default:
47 ERROR("unhandled info->bin.sourceRep switch case\n");
48 assert(false);
49 return false;
50 }
51
52 if (info->type == PIPE_SHADER_COMPUTE)
53 blob_write_bytes(blob, &info->prop.cp, sizeof(info->prop.cp));
54
55 blob_write_bytes(blob, &info->io, sizeof(info->io));
56
57 return true;
58 }
59
60 extern bool
nv50_ir_prog_info_out_serialize(struct blob * blob,struct nv50_ir_prog_info_out * info_out)61 nv50_ir_prog_info_out_serialize(struct blob *blob,
62 struct nv50_ir_prog_info_out *info_out)
63 {
64 blob_write_uint16(blob, info_out->target);
65 blob_write_uint8(blob, info_out->type);
66 blob_write_uint8(blob, info_out->numPatchConstants);
67
68 blob_write_uint16(blob, info_out->bin.maxGPR);
69 blob_write_uint32(blob, info_out->bin.tlsSpace);
70 blob_write_uint32(blob, info_out->bin.smemSize);
71 blob_write_uint32(blob, info_out->bin.codeSize);
72 blob_write_bytes(blob, info_out->bin.code, info_out->bin.codeSize);
73 blob_write_uint32(blob, info_out->bin.instructions);
74
75 if (!info_out->bin.relocData) {
76 blob_write_uint32(blob, 0); // reloc count 0
77 } else {
78 nv50_ir::RelocInfo *reloc = (nv50_ir::RelocInfo *)info_out->bin.relocData;
79 blob_write_uint32(blob, reloc->count);
80 blob_write_uint32(blob, reloc->codePos);
81 blob_write_uint32(blob, reloc->libPos);
82 blob_write_uint32(blob, reloc->dataPos);
83 blob_write_bytes(blob, reloc->entry, sizeof(*reloc->entry) * reloc->count);
84 }
85
86 if (!info_out->bin.fixupData) {
87 blob_write_uint32(blob, 0); // fixup count 0
88 } else {
89 nv50_ir::FixupInfo *fixup = (nv50_ir::FixupInfo *)info_out->bin.fixupData;
90 blob_write_uint32(blob, fixup->count);
91
92 /* Going through each entry */
93 for (uint32_t i = 0; i < fixup->count; i++) {
94 blob_write_uint32(blob, fixup->entry[i].val);
95 assert(fixup->entry[i].apply);
96 /* Compare function pointers, for when at serializing
97 * to know which function to apply */
98 if (fixup->entry[i].apply == nv50_ir::nv50_interpApply)
99 blob_write_uint8(blob, APPLY_NV50);
100 else if (fixup->entry[i].apply == nv50_ir::nvc0_interpApply)
101 blob_write_uint8(blob, APPLY_NVC0);
102 else if (fixup->entry[i].apply == nv50_ir::gk110_interpApply)
103 blob_write_uint8(blob, APPLY_GK110);
104 else if (fixup->entry[i].apply == nv50_ir::gm107_interpApply)
105 blob_write_uint8(blob, APPLY_GM107);
106 else if (fixup->entry[i].apply == nv50_ir::gv100_interpApply)
107 blob_write_uint8(blob, APPLY_GV100);
108 else if (fixup->entry[i].apply == nv50_ir::nvc0_selpFlip)
109 blob_write_uint8(blob, FLIP_NVC0);
110 else if (fixup->entry[i].apply == nv50_ir::gk110_selpFlip)
111 blob_write_uint8(blob, FLIP_GK110);
112 else if (fixup->entry[i].apply == nv50_ir::gm107_selpFlip)
113 blob_write_uint8(blob, FLIP_GM107);
114 else if (fixup->entry[i].apply == nv50_ir::gv100_selpFlip)
115 blob_write_uint8(blob, FLIP_GV100);
116 else {
117 ERROR("unhandled fixup apply function pointer\n");
118 assert(false);
119 return false;
120 }
121 }
122 }
123
124 blob_write_uint8(blob, info_out->numInputs);
125 blob_write_uint8(blob, info_out->numOutputs);
126 blob_write_uint8(blob, info_out->numSysVals);
127 blob_write_bytes(blob, info_out->sv, info_out->numSysVals * sizeof(info_out->sv[0]));
128 blob_write_bytes(blob, info_out->in, info_out->numInputs * sizeof(info_out->in[0]));
129 blob_write_bytes(blob, info_out->out, info_out->numOutputs * sizeof(info_out->out[0]));
130
131 switch(info_out->type) {
132 case PIPE_SHADER_VERTEX:
133 blob_write_bytes(blob, &info_out->prop.vp, sizeof(info_out->prop.vp));
134 break;
135 case PIPE_SHADER_TESS_CTRL:
136 case PIPE_SHADER_TESS_EVAL:
137 blob_write_bytes(blob, &info_out->prop.tp, sizeof(info_out->prop.tp));
138 break;
139 case PIPE_SHADER_GEOMETRY:
140 blob_write_bytes(blob, &info_out->prop.gp, sizeof(info_out->prop.gp));
141 break;
142 case PIPE_SHADER_FRAGMENT:
143 blob_write_bytes(blob, &info_out->prop.fp, sizeof(info_out->prop.fp));
144 break;
145 case PIPE_SHADER_COMPUTE:
146 blob_write_bytes(blob, &info_out->prop.cp, sizeof(info_out->prop.cp));
147 break;
148 default:
149 break;
150 }
151 blob_write_bytes(blob, &info_out->io, sizeof(info_out->io));
152 blob_write_uint8(blob, info_out->numBarriers);
153
154 return true;
155 }
156
157 extern bool
nv50_ir_prog_info_out_deserialize(void * data,size_t size,size_t offset,struct nv50_ir_prog_info_out * info_out)158 nv50_ir_prog_info_out_deserialize(void *data, size_t size, size_t offset,
159 struct nv50_ir_prog_info_out *info_out)
160 {
161 struct blob_reader reader;
162 blob_reader_init(&reader, data, size);
163 blob_skip_bytes(&reader, offset);
164
165 info_out->target = blob_read_uint16(&reader);
166 info_out->type = blob_read_uint8(&reader);
167 info_out->numPatchConstants = blob_read_uint8(&reader);
168
169 info_out->bin.maxGPR = blob_read_uint16(&reader);
170 info_out->bin.tlsSpace = blob_read_uint32(&reader);
171 info_out->bin.smemSize = blob_read_uint32(&reader);
172 info_out->bin.codeSize = blob_read_uint32(&reader);
173 info_out->bin.code = (uint32_t *)MALLOC(info_out->bin.codeSize);
174 blob_copy_bytes(&reader, info_out->bin.code, info_out->bin.codeSize);
175 info_out->bin.instructions = blob_read_uint32(&reader);
176
177 info_out->bin.relocData = NULL;
178 /* Check if data contains RelocInfo */
179 uint32_t count = blob_read_uint32(&reader);
180 if (count) {
181 nv50_ir::RelocInfo *reloc =
182 CALLOC_VARIANT_LENGTH_STRUCT(nv50_ir::RelocInfo,
183 count * sizeof(*reloc->entry));
184 reloc->codePos = blob_read_uint32(&reader);
185 reloc->libPos = blob_read_uint32(&reader);
186 reloc->dataPos = blob_read_uint32(&reader);
187 reloc->count = count;
188
189 blob_copy_bytes(&reader, reloc->entry, sizeof(*reloc->entry) * reloc->count);
190 info_out->bin.relocData = reloc;
191 }
192
193 info_out->bin.fixupData = NULL;
194 /* Check if data contains FixupInfo */
195 count = blob_read_uint32(&reader);
196 if (count) {
197 nv50_ir::FixupInfo *fixup =
198 CALLOC_VARIANT_LENGTH_STRUCT(nv50_ir::FixupInfo,
199 count * sizeof(*fixup->entry));
200 fixup->count = count;
201
202 for (uint32_t i = 0; i < count; i++) {
203 fixup->entry[i].val = blob_read_uint32(&reader);
204
205 /* Assign back function pointer depending on stored enum */
206 enum FixupApplyFunc apply = (enum FixupApplyFunc)blob_read_uint8(&reader);
207 switch(apply) {
208 case APPLY_NV50:
209 fixup->entry[i].apply = nv50_ir::nv50_interpApply;
210 break;
211 case APPLY_NVC0:
212 fixup->entry[i].apply = nv50_ir::nvc0_interpApply;
213 break;
214 case APPLY_GK110:
215 fixup->entry[i].apply = nv50_ir::gk110_interpApply;
216 break;
217 case APPLY_GM107:
218 fixup->entry[i].apply = nv50_ir::gm107_interpApply;
219 break;
220 case APPLY_GV100:
221 fixup->entry[i].apply = nv50_ir::gv100_interpApply;
222 break;
223 case FLIP_NVC0:
224 fixup->entry[i].apply = nv50_ir::nvc0_selpFlip;
225 break;
226 case FLIP_GK110:
227 fixup->entry[i].apply = nv50_ir::gk110_selpFlip;
228 break;
229 case FLIP_GM107:
230 fixup->entry[i].apply = nv50_ir::gm107_selpFlip;
231 break;
232 case FLIP_GV100:
233 fixup->entry[i].apply = nv50_ir::gv100_selpFlip;
234 break;
235 default:
236 ERROR("unhandled fixup apply function switch case");
237 assert(false);
238 return false;
239 }
240 }
241 info_out->bin.fixupData = fixup;
242 }
243
244 info_out->numInputs = blob_read_uint8(&reader);
245 info_out->numOutputs = blob_read_uint8(&reader);
246 info_out->numSysVals = blob_read_uint8(&reader);
247 blob_copy_bytes(&reader, info_out->sv, info_out->numSysVals * sizeof(info_out->sv[0]));
248 blob_copy_bytes(&reader, info_out->in, info_out->numInputs * sizeof(info_out->in[0]));
249 blob_copy_bytes(&reader, info_out->out, info_out->numOutputs * sizeof(info_out->out[0]));
250
251 switch(info_out->type) {
252 case PIPE_SHADER_VERTEX:
253 blob_copy_bytes(&reader, &info_out->prop.vp, sizeof(info_out->prop.vp));
254 break;
255 case PIPE_SHADER_TESS_CTRL:
256 case PIPE_SHADER_TESS_EVAL:
257 blob_copy_bytes(&reader, &info_out->prop.tp, sizeof(info_out->prop.tp));
258 break;
259 case PIPE_SHADER_GEOMETRY:
260 blob_copy_bytes(&reader, &info_out->prop.gp, sizeof(info_out->prop.gp));
261 break;
262 case PIPE_SHADER_FRAGMENT:
263 blob_copy_bytes(&reader, &info_out->prop.fp, sizeof(info_out->prop.fp));
264 break;
265 case PIPE_SHADER_COMPUTE:
266 blob_copy_bytes(&reader, &info_out->prop.cp, sizeof(info_out->prop.cp));
267 break;
268 default:
269 break;
270 }
271 blob_copy_bytes(&reader, &(info_out->io), sizeof(info_out->io));
272 info_out->numBarriers = blob_read_uint8(&reader);
273
274 return true;
275 }
276