From f5fe9030021af830e6c4453f4ad1521cbb697c81 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sat, 7 May 2016 16:14:01 -0400 Subject: [PATCH] nv50/ir: generalize interp fixups to be able to fixup anything Signed-off-by: Ilia Mirkin --- .../drivers/nouveau/codegen/nv50_ir_driver.h | 6 +-- .../nouveau/codegen/nv50_ir_emit_gk110.cpp | 7 ++-- .../nouveau/codegen/nv50_ir_emit_gm107.cpp | 7 ++-- .../nouveau/codegen/nv50_ir_emit_nv50.cpp | 5 +-- .../nouveau/codegen/nv50_ir_emit_nvc0.cpp | 7 ++-- .../nouveau/codegen/nv50_ir_target.cpp | 36 ++++++++-------- .../drivers/nouveau/codegen/nv50_ir_target.h | 41 +++++++++++++------ .../drivers/nouveau/nv50/nv50_program.c | 8 ++-- .../drivers/nouveau/nvc0/nvc0_program.c | 12 +++--- .../drivers/nouveau/nvc0/nvc0_program.h | 2 +- 10 files changed, 71 insertions(+), 60 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( - REALLOC(interpInfo, n ? size : 0, - size + RELOC_ALLOC_INCREMENT * sizeof(InterpEntry))); - if (!interpInfo) + size_t size = sizeof(FixupInfo) + n * sizeof(FixupEntry); + fixupInfo = reinterpret_cast( + 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( - interpData); + nv50_ir::FixupInfo *info = reinterpret_cast( + 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; }; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index 3444b3110de..89db67f0524 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c @@ -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, diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c index ca6349cb09e..944efa042bf 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c @@ -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) { diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h index 8b8d221edfc..bd852e27c36 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h @@ -64,7 +64,7 @@ struct nvc0_program { uint8_t num_barriers; void *relocs; - void *interps; + void *fixups; struct nvc0_transform_feedback_state *tfb; -- 2.30.2