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