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