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