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:
parent
66a442687f
commit
f5fe903002
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 InterpInfo
|
||||
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 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -64,7 +64,7 @@ struct nvc0_program {
|
|||
uint8_t num_barriers;
|
||||
|
||||
void *relocs;
|
||||
void *interps;
|
||||
void *fixups;
|
||||
|
||||
struct nvc0_transform_feedback_state *tfb;
|
||||
|
||||
|
|
Loading…
Reference in New Issue