nv50/ir: generalize interp fixups to be able to fixup anything
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 7 May 2016 20:14:01 +0000 (16:14 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 12 May 2016 00:39:26 +0000 (20:39 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
src/gallium/drivers/nouveau/nv50/nv50_program.c
src/gallium/drivers/nouveau/nvc0/nvc0_program.c
src/gallium/drivers/nouveau/nvc0/nvc0_program.h

index c7f8567cadb8fc3d742203ab9c7b06f206038904..16dc1d1228209d20dcfad9fca15a40073e900b9e 100644 (file)
@@ -100,7 +100,7 @@ struct nv50_ir_prog_info
       uint8_t sourceRep;  /* NV50_PROGRAM_IR */
       const void *source;
       void *relocData;
-      void *interpData;
+      void *fixupData;
       struct nv50_ir_prog_symbol *syms;
       uint16_t numSyms;
    } bin;
@@ -202,8 +202,8 @@ extern void nv50_ir_relocate_code(void *relocData, uint32_t *code,
                                   uint32_t dataPos);
 
 extern void
-nv50_ir_change_interp(void *interpData, uint32_t *code,
-                      bool force_per_sample, bool flatshade);
+nv50_ir_apply_fixups(void *fixupData, uint32_t *code,
+                     bool force_per_sample, bool flatshade);
 
 /* obtain code that will be shared among programs */
 extern void nv50_ir_get_target_library(uint32_t chipset,
index 3d0e9842de5cf5c5dd671d28270e51e11a00251c..83009c5222e6edf970d76bfac5139080de9b307e 100644 (file)
@@ -1854,18 +1854,17 @@ CodeEmitterGK110::emitInterpMode(const Instruction *i)
 }
 
 static void
-interpApply(const InterpEntry *entry, uint32_t *code,
-      bool force_persample_interp, bool flatshade)
+interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
 {
    int ipa = entry->ipa;
    int reg = entry->reg;
    int loc = entry->loc;
 
-   if (flatshade &&
+   if (data.flatshade &&
        (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
       ipa = NV50_IR_INTERP_FLAT;
       reg = 0xff;
-   } else if (force_persample_interp &&
+   } else if (data.force_persample_interp &&
               (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
               (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
       ipa |= NV50_IR_INTERP_CENTROID;
index 35930e3da4f7276b310b76ea01de7049e5b1fc62..9dc2e309e044bfa8718d51c121404a8838e1bda8 100644 (file)
@@ -2288,18 +2288,17 @@ CodeEmitterGM107::emitAL2P()
 }
 
 static void
-interpApply(const InterpEntry *entry, uint32_t *code,
-      bool force_persample_interp, bool flatshade)
+interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
 {
    int ipa = entry->ipa;
    int reg = entry->reg;
    int loc = entry->loc;
 
-   if (flatshade &&
+   if (data.flatshade &&
        (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
       ipa = NV50_IR_INTERP_FLAT;
       reg = 0xff;
-   } else if (force_persample_interp &&
+   } else if (data.force_persample_interp &&
               (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
               (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
       ipa |= NV50_IR_INTERP_CENTROID;
index bd6200687ed8479b0e3bcbdb0086c76912aa288b..5d68e990207e6aec8a60435ec09a4216050bddb0 100644 (file)
@@ -882,8 +882,7 @@ CodeEmitterNV50::emitPFETCH(const Instruction *i)
 }
 
 static void
-interpApply(const InterpEntry *entry, uint32_t *code,
-      bool force_persample_interp, bool flatshade)
+interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
 {
    int ipa = entry->ipa;
    int encSize = entry->reg;
@@ -891,7 +890,7 @@ interpApply(const InterpEntry *entry, uint32_t *code,
 
    if ((ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
        (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
-      if (force_persample_interp) {
+      if (data.force_persample_interp) {
          if (encSize == 8)
             code[loc + 1] |= 1 << 16;
          else
index 6a795e71359a2a811161f85dcde9ee227096ecb4..8819e3b3f5ee2626376227383148664f202f8243 100644 (file)
@@ -1638,18 +1638,17 @@ CodeEmitterNVC0::emitInterpMode(const Instruction *i)
 }
 
 static void
-interpApply(const InterpEntry *entry, uint32_t *code,
-      bool force_persample_interp, bool flatshade)
+interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
 {
    int ipa = entry->ipa;
    int reg = entry->reg;
    int loc = entry->loc;
 
-   if (flatshade &&
+   if (data.flatshade &&
        (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
       ipa = NV50_IR_INTERP_FLAT;
       reg = 0x3f;
-   } else if (force_persample_interp &&
+   } else if (data.force_persample_interp &&
               (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
               (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
       ipa |= NV50_IR_INTERP_CENTROID;
index b5541005f5eeb2295b2202306945a4e52780a346..b147baf3d62149e31c7b37d721d4eeccabd689c9 100644 (file)
@@ -173,7 +173,7 @@ void Target::destroy(Target *targ)
    delete targ;
 }
 
-CodeEmitter::CodeEmitter(const Target *target) : targ(target), interpInfo(NULL)
+CodeEmitter::CodeEmitter(const Target *target) : targ(target), fixupInfo(NULL)
 {
 }
 
@@ -397,7 +397,7 @@ Program::emitBinary(struct nv50_ir_prog_info *info)
       }
    }
    info->bin.relocData = emit->getRelocInfo();
-   info->bin.interpData = emit->getInterpInfo();
+   info->bin.fixupData = emit->getFixupInfo();
 
    emitSymbolTable(info);
 
@@ -439,24 +439,23 @@ CodeEmitter::addReloc(RelocEntry::Type ty, int w, uint32_t data, uint32_t m,
 }
 
 bool
-CodeEmitter::addInterp(int ipa, int reg, InterpApply apply)
+CodeEmitter::addInterp(int ipa, int reg, FixupApply apply)
 {
-   unsigned int n = interpInfo ? interpInfo->count : 0;
+   unsigned int n = fixupInfo ? fixupInfo->count : 0;
 
    if (!(n % RELOC_ALLOC_INCREMENT)) {
-      size_t size = sizeof(InterpInfo) + n * sizeof(InterpEntry);
-      interpInfo = reinterpret_cast<InterpInfo *>(
-         REALLOC(interpInfo, n ? size : 0,
-                 size + RELOC_ALLOC_INCREMENT * sizeof(InterpEntry)));
-      if (!interpInfo)
+      size_t size = sizeof(FixupInfo) + n * sizeof(FixupEntry);
+      fixupInfo = reinterpret_cast<FixupInfo *>(
+         REALLOC(fixupInfo, n ? size : 0,
+                 size + RELOC_ALLOC_INCREMENT * sizeof(FixupEntry)));
+      if (!fixupInfo)
          return false;
       if (n == 0)
-         memset(interpInfo, 0, sizeof(InterpInfo));
+         memset(fixupInfo, 0, sizeof(FixupInfo));
    }
-   ++interpInfo->count;
+   ++fixupInfo->count;
 
-   interpInfo->entry[n] = InterpEntry(ipa, reg, codeSize >> 2);
-   interpInfo->apply = apply;
+   fixupInfo->entry[n] = FixupEntry(apply, ipa, reg, codeSize >> 2);
 
    return true;
 }
@@ -505,16 +504,17 @@ nv50_ir_relocate_code(void *relocData, uint32_t *code,
 }
 
 void
-nv50_ir_change_interp(void *interpData, uint32_t *code,
-                      bool force_persample_interp, bool flatshade)
+nv50_ir_apply_fixups(void *fixupData, uint32_t *code,
+                     bool force_persample_interp, bool flatshade)
 {
-   nv50_ir::InterpInfo *info = reinterpret_cast<nv50_ir::InterpInfo *>(
-      interpData);
+   nv50_ir::FixupInfo *info = reinterpret_cast<nv50_ir::FixupInfo *>(
+      fixupData);
 
    // force_persample_interp: all non-flat -> per-sample
    // flatshade: all color -> flat
+   nv50_ir::FixupData data(force_persample_interp, flatshade);
    for (unsigned i = 0; i < info->count; ++i)
-      info->apply(&info->entry[i], code, force_persample_interp, flatshade);
+      info->entry[i].apply(&info->entry[i], code, data);
 }
 
 void
index e6e1912adae023e3e74b8a49aae9d2d680c73170..674bdc6964e65193cc2a321396bb1b69110aa139 100644 (file)
@@ -58,21 +58,36 @@ struct RelocInfo
    RelocEntry entry[0];
 };
 
-struct InterpEntry
-{
-   InterpEntry(int ipa, int reg, int loc) : ipa(ipa), reg(reg), loc(loc) {}
-   uint32_t ipa:4; // SC mode used to identify colors
-   uint32_t reg:8; // The reg used for perspective division
-   uint32_t loc:20; // Let's hope we don't have more than 1M-sized shaders
+struct FixupData {
+   FixupData(bool force, bool flat) :
+      force_persample_interp(force), flatshade(flat) {}
+   bool force_persample_interp;
+   bool flatshade;
 };
 
-typedef void (*InterpApply)(const InterpEntry*, uint32_t*, bool, bool);
+struct FixupEntry;
+typedef void (*FixupApply)(const FixupEntry*, uint32_t*, const FixupData&);
+
+struct FixupEntry
+{
+   FixupEntry(FixupApply apply, int ipa, int reg, int loc) :
+      apply(apply), ipa(ipa), reg(reg), loc(loc) {}
+
+   FixupApply apply;
+   union {
+      struct {
+         uint32_t ipa:4; // SC mode used to identify colors
+         uint32_t reg:8; // The reg used for perspective division
+         uint32_t loc:20; // Let's hope we don't have more than 1M-sized shaders
+      };
+      uint32_t val;
+   };
+};
 
-struct InterpInfo
+struct FixupInfo
 {
    uint32_t count;
-   InterpApply apply;
-   InterpEntry entry[0];
+   FixupEntry entry[0];
 };
 
 class CodeEmitter
@@ -95,8 +110,8 @@ public:
 
    inline void *getRelocInfo() const { return relocInfo; }
 
-   bool addInterp(int ipa, int reg, InterpApply apply);
-   inline void *getInterpInfo() const { return interpInfo; }
+   bool addInterp(int ipa, int reg, FixupApply apply);
+   inline void *getFixupInfo() const { return fixupInfo; }
 
    virtual void prepareEmission(Program *);
    virtual void prepareEmission(Function *);
@@ -112,7 +127,7 @@ protected:
    uint32_t codeSizeLimit;
 
    RelocInfo *relocInfo;
-   InterpInfo *interpInfo;
+   FixupInfo *fixupInfo;
 };
 
 
index 3444b3110de78728185b5a720eda6602c2526416..89db67f0524a5fd97ac72688cae3ed1db016251f 100644 (file)
@@ -372,7 +372,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
    prog->code = info->bin.code;
    prog->code_size = info->bin.codeSize;
    prog->fixups = info->bin.relocData;
-   prog->interps = info->bin.interpData;
+   prog->interps = info->bin.fixupData;
    prog->max_gpr = MAX2(4, (info->bin.maxGPR >> 1) + 1);
    prog->tls_space = info->bin.tlsSpace;
 
@@ -479,9 +479,9 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
    if (prog->fixups)
       nv50_ir_relocate_code(prog->fixups, prog->code, prog->code_base, 0, 0);
    if (prog->interps)
-      nv50_ir_change_interp(prog->interps, prog->code,
-                            prog->fp.force_persample_interp,
-                            false /* flatshade */);
+      nv50_ir_apply_fixups(prog->interps, prog->code,
+                           prog->fp.force_persample_interp,
+                           false /* flatshade */);
 
    nv50_sifc_linear_u8(&nv50->base, nv50->screen->code,
                        (prog_type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
index ca6349cb09e9d49a8cfe9611864dd6256fda8b68..944efa042bf05e15523e3bd87840a902cb1cd193 100644 (file)
@@ -593,7 +593,7 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
    prog->immd_data = info->immd.buf;
    prog->immd_size = info->immd.bufSize;
    prog->relocs = info->bin.relocData;
-   prog->interps = info->bin.interpData;
+   prog->fixups = info->bin.fixupData;
    prog->num_gprs = MAX2(4, (info->bin.maxGPR + 1));
    prog->num_barriers = info->numBarriers;
 
@@ -740,10 +740,10 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
 
    if (prog->relocs)
       nv50_ir_relocate_code(prog->relocs, prog->code, code_pos, lib_pos, 0);
-   if (prog->interps) {
-      nv50_ir_change_interp(prog->interps, prog->code,
-                            prog->fp.force_persample_interp,
-                            prog->fp.flatshade);
+   if (prog->fixups) {
+      nv50_ir_apply_fixups(prog->fixups, prog->code,
+                           prog->fp.force_persample_interp,
+                           prog->fp.flatshade);
       for (int i = 0; i < 2; i++) {
          unsigned mask = prog->fp.color_interp[i] >> 4;
          unsigned interp = prog->fp.color_interp[i] & 3;
@@ -817,7 +817,7 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
    FREE(prog->code); /* may be 0 for hardcoded shaders */
    FREE(prog->immd_data);
    FREE(prog->relocs);
-   FREE(prog->interps);
+   FREE(prog->fixups);
    if (prog->type == PIPE_SHADER_COMPUTE && prog->cp.syms)
       FREE(prog->cp.syms);
    if (prog->tfb) {
index 8b8d221edfc0dd24a44b3f581d06b7678267ad53..bd852e27c36064651fced87e8d95f2f7e9857f4c 100644 (file)
@@ -64,7 +64,7 @@ struct nvc0_program {
    uint8_t num_barriers;
 
    void *relocs;
-   void *interps;
+   void *fixups;
 
    struct nvc0_transform_feedback_state *tfb;