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