diff options
author | Ilia Mirkin <[email protected]> | 2016-05-07 16:14:01 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2016-05-11 20:39:26 -0400 |
commit | f5fe9030021af830e6c4453f4ad1521cbb697c81 (patch) | |
tree | a72b5f07df3b79ba860f1b86ed91890695da7bb3 /src/gallium/drivers/nouveau/codegen | |
parent | 66a442687f72ccf92ce50bb414565cb80ed2ab53 (diff) |
nv50/ir: generalize interp fixups to be able to fixup anything
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
7 files changed, 60 insertions, 49 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h index c7f8567cadb..16dc1d12282 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h @@ -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, 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 3d0e9842de5..83009c5222e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -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; 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 35930e3da4f..9dc2e309e04 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -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; 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 bd6200687ed..5d68e990207 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -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 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 6a795e71359..8819e3b3f5e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -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; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp index b5541005f5e..b147baf3d62 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp @@ -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 diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h index e6e1912adae..674bdc6964e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h @@ -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; }; |