nv50/ir: generalize interp fixups to be able to fixup anything

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin 2016-05-07 16:14:01 -04:00
parent 66a442687f
commit f5fe903002
10 changed files with 71 additions and 60 deletions

View file

@ -100,7 +100,7 @@ struct nv50_ir_prog_info
uint8_t sourceRep; /* NV50_PROGRAM_IR */ uint8_t sourceRep; /* NV50_PROGRAM_IR */
const void *source; const void *source;
void *relocData; void *relocData;
void *interpData; void *fixupData;
struct nv50_ir_prog_symbol *syms; struct nv50_ir_prog_symbol *syms;
uint16_t numSyms; uint16_t numSyms;
} bin; } bin;
@ -202,7 +202,7 @@ extern void nv50_ir_relocate_code(void *relocData, uint32_t *code,
uint32_t dataPos); uint32_t dataPos);
extern void extern void
nv50_ir_change_interp(void *interpData, uint32_t *code, nv50_ir_apply_fixups(void *fixupData, uint32_t *code,
bool force_per_sample, bool flatshade); bool force_per_sample, bool flatshade);
/* obtain code that will be shared among programs */ /* obtain code that will be shared among programs */

View file

@ -1854,18 +1854,17 @@ CodeEmitterGK110::emitInterpMode(const Instruction *i)
} }
static void static void
interpApply(const InterpEntry *entry, uint32_t *code, interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
bool force_persample_interp, bool flatshade)
{ {
int ipa = entry->ipa; int ipa = entry->ipa;
int reg = entry->reg; int reg = entry->reg;
int loc = entry->loc; int loc = entry->loc;
if (flatshade && if (data.flatshade &&
(ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) { (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
ipa = NV50_IR_INTERP_FLAT; ipa = NV50_IR_INTERP_FLAT;
reg = 0xff; 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_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
(ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) { (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
ipa |= NV50_IR_INTERP_CENTROID; ipa |= NV50_IR_INTERP_CENTROID;

View file

@ -2288,18 +2288,17 @@ CodeEmitterGM107::emitAL2P()
} }
static void static void
interpApply(const InterpEntry *entry, uint32_t *code, interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
bool force_persample_interp, bool flatshade)
{ {
int ipa = entry->ipa; int ipa = entry->ipa;
int reg = entry->reg; int reg = entry->reg;
int loc = entry->loc; int loc = entry->loc;
if (flatshade && if (data.flatshade &&
(ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) { (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
ipa = NV50_IR_INTERP_FLAT; ipa = NV50_IR_INTERP_FLAT;
reg = 0xff; 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_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
(ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) { (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
ipa |= NV50_IR_INTERP_CENTROID; ipa |= NV50_IR_INTERP_CENTROID;

View file

@ -882,8 +882,7 @@ CodeEmitterNV50::emitPFETCH(const Instruction *i)
} }
static void static void
interpApply(const InterpEntry *entry, uint32_t *code, interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
bool force_persample_interp, bool flatshade)
{ {
int ipa = entry->ipa; int ipa = entry->ipa;
int encSize = entry->reg; 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 && if ((ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
(ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) { (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
if (force_persample_interp) { if (data.force_persample_interp) {
if (encSize == 8) if (encSize == 8)
code[loc + 1] |= 1 << 16; code[loc + 1] |= 1 << 16;
else else

View file

@ -1638,18 +1638,17 @@ CodeEmitterNVC0::emitInterpMode(const Instruction *i)
} }
static void static void
interpApply(const InterpEntry *entry, uint32_t *code, interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
bool force_persample_interp, bool flatshade)
{ {
int ipa = entry->ipa; int ipa = entry->ipa;
int reg = entry->reg; int reg = entry->reg;
int loc = entry->loc; int loc = entry->loc;
if (flatshade && if (data.flatshade &&
(ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) { (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
ipa = NV50_IR_INTERP_FLAT; ipa = NV50_IR_INTERP_FLAT;
reg = 0x3f; 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_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
(ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) { (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
ipa |= NV50_IR_INTERP_CENTROID; ipa |= NV50_IR_INTERP_CENTROID;

View file

@ -173,7 +173,7 @@ void Target::destroy(Target *targ)
delete 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.relocData = emit->getRelocInfo();
info->bin.interpData = emit->getInterpInfo(); info->bin.fixupData = emit->getFixupInfo();
emitSymbolTable(info); emitSymbolTable(info);
@ -439,24 +439,23 @@ CodeEmitter::addReloc(RelocEntry::Type ty, int w, uint32_t data, uint32_t m,
} }
bool 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)) { if (!(n % RELOC_ALLOC_INCREMENT)) {
size_t size = sizeof(InterpInfo) + n * sizeof(InterpEntry); size_t size = sizeof(FixupInfo) + n * sizeof(FixupEntry);
interpInfo = reinterpret_cast<InterpInfo *>( fixupInfo = reinterpret_cast<FixupInfo *>(
REALLOC(interpInfo, n ? size : 0, REALLOC(fixupInfo, n ? size : 0,
size + RELOC_ALLOC_INCREMENT * sizeof(InterpEntry))); size + RELOC_ALLOC_INCREMENT * sizeof(FixupEntry)));
if (!interpInfo) if (!fixupInfo)
return false; return false;
if (n == 0) 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); fixupInfo->entry[n] = FixupEntry(apply, ipa, reg, codeSize >> 2);
interpInfo->apply = apply;
return true; return true;
} }
@ -505,16 +504,17 @@ nv50_ir_relocate_code(void *relocData, uint32_t *code,
} }
void void
nv50_ir_change_interp(void *interpData, uint32_t *code, nv50_ir_apply_fixups(void *fixupData, uint32_t *code,
bool force_persample_interp, bool flatshade) bool force_persample_interp, bool flatshade)
{ {
nv50_ir::InterpInfo *info = reinterpret_cast<nv50_ir::InterpInfo *>( nv50_ir::FixupInfo *info = reinterpret_cast<nv50_ir::FixupInfo *>(
interpData); fixupData);
// force_persample_interp: all non-flat -> per-sample // force_persample_interp: all non-flat -> per-sample
// flatshade: all color -> flat // flatshade: all color -> flat
nv50_ir::FixupData data(force_persample_interp, flatshade);
for (unsigned i = 0; i < info->count; ++i) 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 void

View file

@ -58,21 +58,36 @@ struct RelocInfo
RelocEntry entry[0]; RelocEntry entry[0];
}; };
struct InterpEntry struct FixupData {
FixupData(bool force, bool flat) :
force_persample_interp(force), flatshade(flat) {}
bool force_persample_interp;
bool flatshade;
};
struct FixupEntry;
typedef void (*FixupApply)(const FixupEntry*, uint32_t*, const FixupData&);
struct FixupEntry
{ {
InterpEntry(int ipa, int reg, int loc) : ipa(ipa), reg(reg), loc(loc) {} 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 ipa:4; // SC mode used to identify colors
uint32_t reg:8; // The reg used for perspective division 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 loc:20; // Let's hope we don't have more than 1M-sized shaders
}; };
uint32_t val;
};
};
typedef void (*InterpApply)(const InterpEntry*, uint32_t*, bool, bool); struct FixupInfo
struct InterpInfo
{ {
uint32_t count; uint32_t count;
InterpApply apply; FixupEntry entry[0];
InterpEntry entry[0];
}; };
class CodeEmitter class CodeEmitter
@ -95,8 +110,8 @@ public:
inline void *getRelocInfo() const { return relocInfo; } inline void *getRelocInfo() const { return relocInfo; }
bool addInterp(int ipa, int reg, InterpApply apply); bool addInterp(int ipa, int reg, FixupApply apply);
inline void *getInterpInfo() const { return interpInfo; } inline void *getFixupInfo() const { return fixupInfo; }
virtual void prepareEmission(Program *); virtual void prepareEmission(Program *);
virtual void prepareEmission(Function *); virtual void prepareEmission(Function *);
@ -112,7 +127,7 @@ protected:
uint32_t codeSizeLimit; uint32_t codeSizeLimit;
RelocInfo *relocInfo; RelocInfo *relocInfo;
InterpInfo *interpInfo; FixupInfo *fixupInfo;
}; };

View file

@ -372,7 +372,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
prog->code = info->bin.code; prog->code = info->bin.code;
prog->code_size = info->bin.codeSize; prog->code_size = info->bin.codeSize;
prog->fixups = info->bin.relocData; 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->max_gpr = MAX2(4, (info->bin.maxGPR >> 1) + 1);
prog->tls_space = info->bin.tlsSpace; prog->tls_space = info->bin.tlsSpace;
@ -479,7 +479,7 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
if (prog->fixups) if (prog->fixups)
nv50_ir_relocate_code(prog->fixups, prog->code, prog->code_base, 0, 0); nv50_ir_relocate_code(prog->fixups, prog->code, prog->code_base, 0, 0);
if (prog->interps) if (prog->interps)
nv50_ir_change_interp(prog->interps, prog->code, nv50_ir_apply_fixups(prog->interps, prog->code,
prog->fp.force_persample_interp, prog->fp.force_persample_interp,
false /* flatshade */); false /* flatshade */);

View file

@ -593,7 +593,7 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
prog->immd_data = info->immd.buf; prog->immd_data = info->immd.buf;
prog->immd_size = info->immd.bufSize; prog->immd_size = info->immd.bufSize;
prog->relocs = info->bin.relocData; 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_gprs = MAX2(4, (info->bin.maxGPR + 1));
prog->num_barriers = info->numBarriers; prog->num_barriers = info->numBarriers;
@ -740,8 +740,8 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
if (prog->relocs) if (prog->relocs)
nv50_ir_relocate_code(prog->relocs, prog->code, code_pos, lib_pos, 0); nv50_ir_relocate_code(prog->relocs, prog->code, code_pos, lib_pos, 0);
if (prog->interps) { if (prog->fixups) {
nv50_ir_change_interp(prog->interps, prog->code, nv50_ir_apply_fixups(prog->fixups, prog->code,
prog->fp.force_persample_interp, prog->fp.force_persample_interp,
prog->fp.flatshade); prog->fp.flatshade);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -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->code); /* may be 0 for hardcoded shaders */
FREE(prog->immd_data); FREE(prog->immd_data);
FREE(prog->relocs); FREE(prog->relocs);
FREE(prog->interps); FREE(prog->fixups);
if (prog->type == PIPE_SHADER_COMPUTE && prog->cp.syms) if (prog->type == PIPE_SHADER_COMPUTE && prog->cp.syms)
FREE(prog->cp.syms); FREE(prog->cp.syms);
if (prog->tfb) { if (prog->tfb) {

View file

@ -64,7 +64,7 @@ struct nvc0_program {
uint8_t num_barriers; uint8_t num_barriers;
void *relocs; void *relocs;
void *interps; void *fixups;
struct nvc0_transform_feedback_state *tfb; struct nvc0_transform_feedback_state *tfb;