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 9enum 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 21extern bool 22nv50_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 60extern bool 61nv50_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 157extern bool 158nv50_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