276 lines
10 KiB
C++
276 lines
10 KiB
C++
#include "util/blob.h"
|
|
#include "nv50_ir_driver.h"
|
|
#include "nv50_ir.h"
|
|
#include "nv50_ir_target.h"
|
|
#include "nv50_ir_driver.h"
|
|
#include "tgsi/tgsi_parse.h"
|
|
#include "compiler/nir/nir_serialize.h"
|
|
|
|
enum FixupApplyFunc {
|
|
APPLY_NV50,
|
|
APPLY_NVC0,
|
|
APPLY_GK110,
|
|
APPLY_GM107,
|
|
APPLY_GV100,
|
|
FLIP_NVC0,
|
|
FLIP_GK110,
|
|
FLIP_GM107,
|
|
FLIP_GV100,
|
|
};
|
|
|
|
extern bool
|
|
nv50_ir_prog_info_serialize(struct blob *blob, struct nv50_ir_prog_info *info)
|
|
{
|
|
blob_write_uint32(blob, info->bin.smemSize);
|
|
blob_write_uint16(blob, info->target);
|
|
blob_write_uint8(blob, info->type);
|
|
blob_write_uint8(blob, info->optLevel);
|
|
blob_write_uint8(blob, info->dbgFlags);
|
|
blob_write_uint8(blob, info->omitLineNum);
|
|
blob_write_uint8(blob, info->bin.sourceRep);
|
|
|
|
switch(info->bin.sourceRep) {
|
|
case PIPE_SHADER_IR_TGSI: {
|
|
struct tgsi_token *tokens = (struct tgsi_token *)info->bin.source;
|
|
unsigned int num_tokens = tgsi_num_tokens(tokens);
|
|
|
|
blob_write_uint32(blob, num_tokens);
|
|
blob_write_bytes(blob, tokens, num_tokens * sizeof(struct tgsi_token));
|
|
break;
|
|
}
|
|
case PIPE_SHADER_IR_NIR: {
|
|
struct nir_shader *nir = (struct nir_shader *)info->bin.source;
|
|
nir_serialize(blob, nir, true);
|
|
break;
|
|
}
|
|
default:
|
|
ERROR("unhandled info->bin.sourceRep switch case\n");
|
|
assert(false);
|
|
return false;
|
|
}
|
|
|
|
if (info->type == PIPE_SHADER_COMPUTE)
|
|
blob_write_bytes(blob, &info->prop.cp, sizeof(info->prop.cp));
|
|
|
|
blob_write_bytes(blob, &info->io, sizeof(info->io));
|
|
|
|
return true;
|
|
}
|
|
|
|
extern bool
|
|
nv50_ir_prog_info_out_serialize(struct blob *blob,
|
|
struct nv50_ir_prog_info_out *info_out)
|
|
{
|
|
blob_write_uint16(blob, info_out->target);
|
|
blob_write_uint8(blob, info_out->type);
|
|
blob_write_uint8(blob, info_out->numPatchConstants);
|
|
|
|
blob_write_uint16(blob, info_out->bin.maxGPR);
|
|
blob_write_uint32(blob, info_out->bin.tlsSpace);
|
|
blob_write_uint32(blob, info_out->bin.smemSize);
|
|
blob_write_uint32(blob, info_out->bin.codeSize);
|
|
blob_write_bytes(blob, info_out->bin.code, info_out->bin.codeSize);
|
|
blob_write_uint32(blob, info_out->bin.instructions);
|
|
|
|
if (!info_out->bin.relocData) {
|
|
blob_write_uint32(blob, 0); // reloc count 0
|
|
} else {
|
|
nv50_ir::RelocInfo *reloc = (nv50_ir::RelocInfo *)info_out->bin.relocData;
|
|
blob_write_uint32(blob, reloc->count);
|
|
blob_write_uint32(blob, reloc->codePos);
|
|
blob_write_uint32(blob, reloc->libPos);
|
|
blob_write_uint32(blob, reloc->dataPos);
|
|
blob_write_bytes(blob, reloc->entry, sizeof(*reloc->entry) * reloc->count);
|
|
}
|
|
|
|
if (!info_out->bin.fixupData) {
|
|
blob_write_uint32(blob, 0); // fixup count 0
|
|
} else {
|
|
nv50_ir::FixupInfo *fixup = (nv50_ir::FixupInfo *)info_out->bin.fixupData;
|
|
blob_write_uint32(blob, fixup->count);
|
|
|
|
/* Going through each entry */
|
|
for (uint32_t i = 0; i < fixup->count; i++) {
|
|
blob_write_uint32(blob, fixup->entry[i].val);
|
|
assert(fixup->entry[i].apply);
|
|
/* Compare function pointers, for when at serializing
|
|
* to know which function to apply */
|
|
if (fixup->entry[i].apply == nv50_ir::nv50_interpApply)
|
|
blob_write_uint8(blob, APPLY_NV50);
|
|
else if (fixup->entry[i].apply == nv50_ir::nvc0_interpApply)
|
|
blob_write_uint8(blob, APPLY_NVC0);
|
|
else if (fixup->entry[i].apply == nv50_ir::gk110_interpApply)
|
|
blob_write_uint8(blob, APPLY_GK110);
|
|
else if (fixup->entry[i].apply == nv50_ir::gm107_interpApply)
|
|
blob_write_uint8(blob, APPLY_GM107);
|
|
else if (fixup->entry[i].apply == nv50_ir::gv100_interpApply)
|
|
blob_write_uint8(blob, APPLY_GV100);
|
|
else if (fixup->entry[i].apply == nv50_ir::nvc0_selpFlip)
|
|
blob_write_uint8(blob, FLIP_NVC0);
|
|
else if (fixup->entry[i].apply == nv50_ir::gk110_selpFlip)
|
|
blob_write_uint8(blob, FLIP_GK110);
|
|
else if (fixup->entry[i].apply == nv50_ir::gm107_selpFlip)
|
|
blob_write_uint8(blob, FLIP_GM107);
|
|
else if (fixup->entry[i].apply == nv50_ir::gv100_selpFlip)
|
|
blob_write_uint8(blob, FLIP_GV100);
|
|
else {
|
|
ERROR("unhandled fixup apply function pointer\n");
|
|
assert(false);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
blob_write_uint8(blob, info_out->numInputs);
|
|
blob_write_uint8(blob, info_out->numOutputs);
|
|
blob_write_uint8(blob, info_out->numSysVals);
|
|
blob_write_bytes(blob, info_out->sv, info_out->numSysVals * sizeof(info_out->sv[0]));
|
|
blob_write_bytes(blob, info_out->in, info_out->numInputs * sizeof(info_out->in[0]));
|
|
blob_write_bytes(blob, info_out->out, info_out->numOutputs * sizeof(info_out->out[0]));
|
|
|
|
switch(info_out->type) {
|
|
case PIPE_SHADER_VERTEX:
|
|
blob_write_bytes(blob, &info_out->prop.vp, sizeof(info_out->prop.vp));
|
|
break;
|
|
case PIPE_SHADER_TESS_CTRL:
|
|
case PIPE_SHADER_TESS_EVAL:
|
|
blob_write_bytes(blob, &info_out->prop.tp, sizeof(info_out->prop.tp));
|
|
break;
|
|
case PIPE_SHADER_GEOMETRY:
|
|
blob_write_bytes(blob, &info_out->prop.gp, sizeof(info_out->prop.gp));
|
|
break;
|
|
case PIPE_SHADER_FRAGMENT:
|
|
blob_write_bytes(blob, &info_out->prop.fp, sizeof(info_out->prop.fp));
|
|
break;
|
|
case PIPE_SHADER_COMPUTE:
|
|
blob_write_bytes(blob, &info_out->prop.cp, sizeof(info_out->prop.cp));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
blob_write_bytes(blob, &info_out->io, sizeof(info_out->io));
|
|
blob_write_uint8(blob, info_out->numBarriers);
|
|
|
|
return true;
|
|
}
|
|
|
|
extern bool
|
|
nv50_ir_prog_info_out_deserialize(void *data, size_t size, size_t offset,
|
|
struct nv50_ir_prog_info_out *info_out)
|
|
{
|
|
struct blob_reader reader;
|
|
blob_reader_init(&reader, data, size);
|
|
blob_skip_bytes(&reader, offset);
|
|
|
|
info_out->target = blob_read_uint16(&reader);
|
|
info_out->type = blob_read_uint8(&reader);
|
|
info_out->numPatchConstants = blob_read_uint8(&reader);
|
|
|
|
info_out->bin.maxGPR = blob_read_uint16(&reader);
|
|
info_out->bin.tlsSpace = blob_read_uint32(&reader);
|
|
info_out->bin.smemSize = blob_read_uint32(&reader);
|
|
info_out->bin.codeSize = blob_read_uint32(&reader);
|
|
info_out->bin.code = (uint32_t *)MALLOC(info_out->bin.codeSize);
|
|
blob_copy_bytes(&reader, info_out->bin.code, info_out->bin.codeSize);
|
|
info_out->bin.instructions = blob_read_uint32(&reader);
|
|
|
|
info_out->bin.relocData = NULL;
|
|
/* Check if data contains RelocInfo */
|
|
uint32_t count = blob_read_uint32(&reader);
|
|
if (count) {
|
|
nv50_ir::RelocInfo *reloc =
|
|
CALLOC_VARIANT_LENGTH_STRUCT(nv50_ir::RelocInfo,
|
|
count * sizeof(*reloc->entry));
|
|
reloc->codePos = blob_read_uint32(&reader);
|
|
reloc->libPos = blob_read_uint32(&reader);
|
|
reloc->dataPos = blob_read_uint32(&reader);
|
|
reloc->count = count;
|
|
|
|
blob_copy_bytes(&reader, reloc->entry, sizeof(*reloc->entry) * reloc->count);
|
|
info_out->bin.relocData = reloc;
|
|
}
|
|
|
|
info_out->bin.fixupData = NULL;
|
|
/* Check if data contains FixupInfo */
|
|
count = blob_read_uint32(&reader);
|
|
if (count) {
|
|
nv50_ir::FixupInfo *fixup =
|
|
CALLOC_VARIANT_LENGTH_STRUCT(nv50_ir::FixupInfo,
|
|
count * sizeof(*fixup->entry));
|
|
fixup->count = count;
|
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
fixup->entry[i].val = blob_read_uint32(&reader);
|
|
|
|
/* Assign back function pointer depending on stored enum */
|
|
enum FixupApplyFunc apply = (enum FixupApplyFunc)blob_read_uint8(&reader);
|
|
switch(apply) {
|
|
case APPLY_NV50:
|
|
fixup->entry[i].apply = nv50_ir::nv50_interpApply;
|
|
break;
|
|
case APPLY_NVC0:
|
|
fixup->entry[i].apply = nv50_ir::nvc0_interpApply;
|
|
break;
|
|
case APPLY_GK110:
|
|
fixup->entry[i].apply = nv50_ir::gk110_interpApply;
|
|
break;
|
|
case APPLY_GM107:
|
|
fixup->entry[i].apply = nv50_ir::gm107_interpApply;
|
|
break;
|
|
case APPLY_GV100:
|
|
fixup->entry[i].apply = nv50_ir::gv100_interpApply;
|
|
break;
|
|
case FLIP_NVC0:
|
|
fixup->entry[i].apply = nv50_ir::nvc0_selpFlip;
|
|
break;
|
|
case FLIP_GK110:
|
|
fixup->entry[i].apply = nv50_ir::gk110_selpFlip;
|
|
break;
|
|
case FLIP_GM107:
|
|
fixup->entry[i].apply = nv50_ir::gm107_selpFlip;
|
|
break;
|
|
case FLIP_GV100:
|
|
fixup->entry[i].apply = nv50_ir::gv100_selpFlip;
|
|
break;
|
|
default:
|
|
ERROR("unhandled fixup apply function switch case");
|
|
assert(false);
|
|
return false;
|
|
}
|
|
}
|
|
info_out->bin.fixupData = fixup;
|
|
}
|
|
|
|
info_out->numInputs = blob_read_uint8(&reader);
|
|
info_out->numOutputs = blob_read_uint8(&reader);
|
|
info_out->numSysVals = blob_read_uint8(&reader);
|
|
blob_copy_bytes(&reader, info_out->sv, info_out->numSysVals * sizeof(info_out->sv[0]));
|
|
blob_copy_bytes(&reader, info_out->in, info_out->numInputs * sizeof(info_out->in[0]));
|
|
blob_copy_bytes(&reader, info_out->out, info_out->numOutputs * sizeof(info_out->out[0]));
|
|
|
|
switch(info_out->type) {
|
|
case PIPE_SHADER_VERTEX:
|
|
blob_copy_bytes(&reader, &info_out->prop.vp, sizeof(info_out->prop.vp));
|
|
break;
|
|
case PIPE_SHADER_TESS_CTRL:
|
|
case PIPE_SHADER_TESS_EVAL:
|
|
blob_copy_bytes(&reader, &info_out->prop.tp, sizeof(info_out->prop.tp));
|
|
break;
|
|
case PIPE_SHADER_GEOMETRY:
|
|
blob_copy_bytes(&reader, &info_out->prop.gp, sizeof(info_out->prop.gp));
|
|
break;
|
|
case PIPE_SHADER_FRAGMENT:
|
|
blob_copy_bytes(&reader, &info_out->prop.fp, sizeof(info_out->prop.fp));
|
|
break;
|
|
case PIPE_SHADER_COMPUTE:
|
|
blob_copy_bytes(&reader, &info_out->prop.cp, sizeof(info_out->prop.cp));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
blob_copy_bytes(&reader, &(info_out->io), sizeof(info_out->io));
|
|
info_out->numBarriers = blob_read_uint8(&reader);
|
|
|
|
return true;
|
|
}
|