On Mon, Feb 17, 2020 at 6:41 PM Mark Menzynski <mmenz...@redhat.com> wrote: > > Adds functions for serializing and deserializing > nv50_ir_prog_info_out structure, which are needed for shader caching. > > Signed-off-by: Mark Menzynski <mmenz...@redhat.com> > --- > .../drivers/nouveau/codegen/nv50_ir_driver.h | 44 ++++ > .../nouveau/codegen/nv50_ir_emit_gk110.cpp | 14 +- > .../nouveau/codegen/nv50_ir_emit_gm107.cpp | 14 +- > .../nouveau/codegen/nv50_ir_emit_nv50.cpp | 6 +- > .../nouveau/codegen/nv50_ir_emit_nvc0.cpp | 14 +- > .../nouveau/codegen/nv50_ir_serialize.cpp | 196 ++++++++++++++++++ > src/gallium/drivers/nouveau/meson.build | 1 + > 7 files changed, 265 insertions(+), 24 deletions(-) > create mode 100644 src/gallium/drivers/nouveau/codegen/nv50_ir_serialize.cpp > > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > index f6b5415bc95..bc92a3bc4ee 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > @@ -25,6 +25,7 @@ > > #include "pipe/p_shader_tokens.h" > > +#include "util/blob.h" > #include "tgsi/tgsi_util.h" > #include "tgsi/tgsi_parse.h" > #include "tgsi/tgsi_scan.h" > @@ -242,6 +243,49 @@ nv50_ir_apply_fixups(void *fixupData, uint32_t *code, > extern void nv50_ir_get_target_library(uint32_t chipset, > const uint32_t **code, uint32_t > *size); > > + > +#ifdef __cplusplus > +namespace nv50_ir > +{ > + class FixupEntry; > + class FixupData; > + > + void > + gk110_interpApply(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + gm107_interpApply(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + nv50_interpApply(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + nvc0_interpApply(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + gk110_selpFlip(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + gm107_selpFlip(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + void > + nvc0_selpFlip(const nv50_ir::FixupEntry *entry, uint32_t *code, > + const nv50_ir::FixupData& data); > + > +} > +#endif > + > +/* Serialize a nv50_ir_prog_info_out structure and save it into blob */ > +extern bool > +nv50_ir_prog_info_out_serialize(struct blob *, struct nv50_ir_prog_info_out > *); > + > +/* Deserialize from data and save into a nv50_ir_prog_info_out structure > + * using a pointer. Size is a total size of the serialized data. > + * Offset points to where info_out in data is located. */ > +extern bool > +nv50_ir_prog_info_out_deserialize(void *data, size_t size, size_t offset, > + struct nv50_ir_prog_info_out *);
some spaces missing. Also I'd drop the offset argument and require the callee to pass in an adjusted pointer already. > + > #ifdef __cplusplus > } > #endif > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp > index 2118c3153f7..e651d7fdcb0 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp > @@ -1209,8 +1209,8 @@ CodeEmitterGK110::emitSLCT(const CmpInstruction *i) > } > } > > -static void > -selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +gk110_selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& > data) > { > int loc = entry->loc; > if (data.force_persample_interp) > @@ -1227,7 +1227,7 @@ void CodeEmitterGK110::emitSELP(const Instruction *i) > code[1] |= 1 << 13; > > if (i->subOp == 1) { > - addInterp(0, 0, selpFlip); > + addInterp(0, 0, gk110_selpFlip); > } > } > > @@ -2042,8 +2042,8 @@ CodeEmitterGK110::emitInterpMode(const Instruction *i) > code[1] |= (i->ipa & 0xc) << (19 - 2); > } > > -static void > -interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +gk110_interpApply(const struct FixupEntry *entry, uint32_t *code, const > FixupData& data) > { > int ipa = entry->ipa; > int reg = entry->reg; > @@ -2078,10 +2078,10 @@ CodeEmitterGK110::emitINTERP(const Instruction *i) > > if (i->op == OP_PINTERP) { > srcId(i->src(1), 23); > - addInterp(i->ipa, SDATA(i->src(1)).id, interpApply); > + addInterp(i->ipa, SDATA(i->src(1)).id, gk110_interpApply); > } else { > code[0] |= 0xff << 23; > - addInterp(i->ipa, 0xff, interpApply); > + addInterp(i->ipa, 0xff, gk110_interpApply); > } > > srcId(i->src(0).getIndirect(0), 10); > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp > index e244bd0d610..4970f14cb33 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp > @@ -947,8 +947,8 @@ CodeEmitterGM107::emitI2I() > emitGPR (0x00, insn->def(0)); > } > > -static void > -selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +gm107_selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& > data) > { > int loc = entry->loc; > if (data.force_persample_interp) > @@ -984,7 +984,7 @@ CodeEmitterGM107::emitSEL() > emitGPR (0x00, insn->def(0)); > > if (insn->subOp == 1) { > - addInterp(0, 0, selpFlip); > + addInterp(0, 0, gm107_selpFlip); > } > } > > @@ -2527,8 +2527,8 @@ CodeEmitterGM107::emitAL2P() > emitGPR (0x00, insn->def(0)); > } > > -static void > -interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +gm107_interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& > data) > { > int ipa = entry->ipa; > int reg = entry->reg; > @@ -2588,12 +2588,12 @@ CodeEmitterGM107::emitIPA() > emitGPR(0x14, insn->src(1)); > if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET) > emitGPR(0x27, insn->src(2)); > - addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply); > + addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, gm107_interpApply); > } else { > if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET) > emitGPR(0x27, insn->src(1)); > emitGPR(0x14); > - addInterp(insn->ipa, 0xff, interpApply); > + addInterp(insn->ipa, 0xff, gm107_interpApply); > } > > if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET) > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp > index 03fada1415e..60e800ad502 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp > @@ -881,8 +881,8 @@ CodeEmitterNV50::emitPFETCH(const Instruction *i) > emitFlagsRd(i); > } > > -static void > -interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +nv50_interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& > data) > { > int ipa = entry->ipa; > int encSize = entry->reg; > @@ -934,7 +934,7 @@ CodeEmitterNV50::emitINTERP(const Instruction *i) > emitFlagsRd(i); > } > > - addInterp(i->ipa, i->encSize, interpApply); > + addInterp(i->ipa, i->encSize, nv50_interpApply); > } > > void > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp > index b6e35dd0ee4..0a82c6de20d 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp > @@ -1255,8 +1255,8 @@ CodeEmitterNVC0::emitSLCT(const CmpInstruction *i) > code[0] |= 1 << 5; > } > > -static void > -selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +nvc0_selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data) > { > int loc = entry->loc; > if (data.force_persample_interp) > @@ -1273,7 +1273,7 @@ void CodeEmitterNVC0::emitSELP(const Instruction *i) > code[1] |= 1 << 20; > > if (i->subOp == 1) { > - addInterp(0, 0, selpFlip); > + addInterp(0, 0, nvc0_selpFlip); > } > } > > @@ -1726,8 +1726,8 @@ CodeEmitterNVC0::emitInterpMode(const Instruction *i) > } > } > > -static void > -interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data) > +void > +nvc0_interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& > data) > { > int ipa = entry->ipa; > int reg = entry->reg; > @@ -1762,10 +1762,10 @@ CodeEmitterNVC0::emitINTERP(const Instruction *i) > > if (i->op == OP_PINTERP) { > srcId(i->src(1), 26); > - addInterp(i->ipa, SDATA(i->src(1)).id, interpApply); > + addInterp(i->ipa, SDATA(i->src(1)).id, nvc0_interpApply); > } else { > code[0] |= 0x3f << 26; > - addInterp(i->ipa, 0x3f, interpApply); > + addInterp(i->ipa, 0x3f, nvc0_interpApply); > } > > srcId(i->src(0).getIndirect(0), 20); > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_serialize.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_serialize.cpp > new file mode 100644 > index 00000000000..077f3eba6c8 > --- /dev/null > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_serialize.cpp > @@ -0,0 +1,196 @@ > +#include "util/blob.h" > +#include "codegen/nv50_ir_driver.h" > +#include "codegen/nv50_ir.h" > +#include "codegen/nv50_ir_target.h" > +#include "nv50_ir_driver.h" > +#include "tgsi/tgsi_parse.h" > +#include "compiler/nir/nir_serialize.h" > + > +enum InterpApply { maybe call it FixupFuncPointer or something instead? > + APPLY_UNDEFINED = 0, > + APPLY_NV50 = 1, > + APPLY_NVC0 = 2, > + APPLY_GK110 = 3, > + APPLY_GM107 = 4, > + FLIP_NVC0 = 5, > + FLIP_GK110 = 6, > + FLIP_GM107 = 7 > +}; > + > +extern bool > +nv50_ir_prog_info_out_serialize(struct blob *blob, > + struct nv50_ir_prog_info_out *info_out) more spaces > +{ > + blob_write_uint16(blob, info_out->target); > + blob_write_uint8(blob, info_out->type); > + > + 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); > + > + /* Writing byte suggesting if RelocInfo is contained */ > + blob_write_uint8(blob, info_out->bin.relocData != NULL); > + if (info_out->bin.relocData) { > + 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); > + } > + > + /* Writing byte suggesting FixupInfo is contained */ > + blob_write_uint8(blob, info_out->bin.fixupData != NULL); > + if (info_out->bin.fixupData) { > + 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].ipa); > + blob_write_uint32(blob, fixup->entry[i].reg); > + blob_write_uint32(blob, fixup->entry[i].loc); > + > + /* Compare function pointers, for when at serializing > + * to know which function to apply */ > + if (fixup->entry[i].apply == NULL) > + blob_write_uint8(blob, APPLY_UNDEFINED); > + else 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::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 { > + blob_write_uint8(blob, APPLY_UNDEFINED); > + assert(!"unhandled fixup apply function pointer"); > + return false; > + } > + } > + } > + > + blob_write_bytes(blob, info_out->sv, sizeof(info_out->sv)); > + blob_write_bytes(blob, info_out->in, sizeof(info_out->in)); > + blob_write_bytes(blob, info_out->out, sizeof(info_out->out)); > + > + blob_write_uint8(blob, info_out->numInputs); > + blob_write_uint8(blob, info_out->numOutputs); > + blob_write_uint8(blob, info_out->numPatchConstants); > + blob_write_uint8(blob, info_out->numSysVals); > + blob_write_bytes(blob, &(info_out->prop), sizeof(info_out->prop)); > + blob_write_bytes(blob, &(info_out->io), sizeof(info_out->io)); you can drop the brackets around prop and 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) missing spaces > +{ > + 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->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 */ > + if (blob_read_uint8(&reader) == true) { > + uint32_t count = blob_read_uint32(&reader); > + > + 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 */ > + if (blob_read_uint8(&reader) == true) { you can drop the "== true" here and further below > + uint32_t count = blob_read_uint32(&reader); > + > + 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].ipa = blob_read_uint32(&reader); > + fixup->entry[i].reg = blob_read_uint32(&reader); > + fixup->entry[i].loc = blob_read_uint32(&reader); > + > + /* Assign back function pointer depending on stored enum */ > + enum InterpApply apply = (enum InterpApply)blob_read_uint8(&reader); > + switch(apply) { > + case APPLY_UNDEFINED: > + fixup->entry[i].apply = NULL; > + break; > + 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 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; > + default: > + assert(!"unhandled apply function switch case"); > + return false; you don't need to add a default case if all enum values are handled. > + } > + } > + info_out->bin.fixupData = fixup; > + } > + > + blob_copy_bytes(&reader, info_out->sv, sizeof(info_out->sv)); > + blob_copy_bytes(&reader, info_out->in, sizeof(info_out->in)); > + blob_copy_bytes(&reader, info_out->out, sizeof(info_out->out)); > + info_out->numInputs = blob_read_uint8(&reader); > + info_out->numOutputs = blob_read_uint8(&reader); > + info_out->numPatchConstants = blob_read_uint8(&reader); > + info_out->numSysVals = blob_read_uint8(&reader); > + blob_copy_bytes(&reader, &(info_out->prop), sizeof(info_out->prop)); > + blob_copy_bytes(&reader, &(info_out->io), sizeof(info_out->io)); > + info_out->numBarriers = blob_read_uint8(&reader); > + > + return true; > +} > diff --git a/src/gallium/drivers/nouveau/meson.build > b/src/gallium/drivers/nouveau/meson.build > index e48b61b8955..21793e86b38 100644 > --- a/src/gallium/drivers/nouveau/meson.build > +++ b/src/gallium/drivers/nouveau/meson.build > @@ -142,6 +142,7 @@ files_libnouveau = files( > 'codegen/nv50_ir_peephole.cpp', > 'codegen/nv50_ir_print.cpp', > 'codegen/nv50_ir_ra.cpp', > + 'codegen/nv50_ir_serialize.cpp', > 'codegen/nv50_ir_ssa.cpp', > 'codegen/nv50_ir_target.cpp', > 'codegen/nv50_ir_target.h', > -- > 2.21.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev