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