summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h2
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp26
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp4
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_program.c6
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_program.h3
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_shader_state.c16
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_state_validate.c2
8 files changed, 52 insertions, 9 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
index 391130e67af..c0cab3299b5 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
@@ -144,6 +144,7 @@ struct nv50_ir_prog_info
bool earlyFragTests;
bool separateFragData;
bool usesDiscard;
+ bool sampleInterp; /* perform sample interp on all fp inputs */
} fp;
struct {
uint32_t inputOffset; /* base address for user args */
@@ -168,7 +169,6 @@ struct nv50_ir_prog_info
int8_t viewportId; /* output index of ViewportIndex */
uint8_t fragDepth; /* output index of FragDepth */
uint8_t sampleMask; /* output index of SampleMask */
- bool sampleInterp; /* perform sample interp on all fp inputs */
uint8_t backFaceColor[2]; /* input/output indices of back face colour */
uint8_t globalAccess; /* 1 for read, 2 for wr, 3 for rw */
bool fp64; /* program uses fp64 math */
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 90147668c91..e9b1cef2aa0 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
@@ -876,6 +876,30 @@ CodeEmitterNV50::emitPFETCH(const Instruction *i)
emitFlagsRd(i);
}
+static void
+interpApply(const InterpEntry *entry, uint32_t *code,
+ bool force_persample_interp, bool flatshade)
+{
+ int ipa = entry->ipa;
+ int encSize = entry->reg;
+ int loc = entry->loc;
+
+ 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 (encSize == 8)
+ code[loc + 1] |= 1 << 16;
+ else
+ code[loc + 0] |= 1 << 24;
+ } else {
+ if (encSize == 8)
+ code[loc + 1] &= ~(1 << 16);
+ else
+ code[loc + 0] &= ~(1 << 24);
+ }
+ }
+}
+
void
CodeEmitterNV50::emitINTERP(const Instruction *i)
{
@@ -904,6 +928,8 @@ CodeEmitterNV50::emitINTERP(const Instruction *i)
code[0] |= 1;
emitFlagsRd(i);
}
+
+ addInterp(i->ipa, i->encSize, interpApply);
}
void
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index eb28622eb59..0031b5e15e8 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -1125,7 +1125,7 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
break;
case TGSI_SEMANTIC_SAMPLEID:
case TGSI_SEMANTIC_SAMPLEPOS:
- info->io.sampleInterp = 1;
+ info->prop.fp.sampleInterp = 1;
break;
default:
break;
@@ -1478,7 +1478,7 @@ Converter::translateInterpMode(const struct nv50_ir_varying *var, operation& op)
op = (mode == NV50_IR_INTERP_PERSPECTIVE || mode == NV50_IR_INTERP_SC)
? OP_PINTERP : OP_LINTERP;
- if (var->centroid || info->io.sampleInterp)
+ if (var->centroid || info->prop.fp.sampleInterp)
mode |= NV50_IR_INTERP_CENTROID;
return mode;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c
index eff4477472c..26ba2c2c380 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_program.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c
@@ -336,7 +336,6 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset)
info->io.ucpCBSlot = 15;
info->io.ucpBase = NV50_CB_AUX_UCP_OFFSET;
info->io.genUserClip = prog->vp.clpd_nr;
- info->io.sampleInterp = prog->fp.sample_interp;
info->io.resInfoCBSlot = 15;
info->io.suInfoBase = NV50_CB_AUX_TEX_MS_OFFSET;
@@ -374,6 +373,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->max_gpr = MAX2(4, (info->bin.maxGPR >> 1) + 1);
prog->tls_space = info->bin.tlsSpace;
@@ -456,6 +456,10 @@ 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_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/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h
index f4e8e9402ca..24cc96567d7 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_program.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h
@@ -86,7 +86,7 @@ struct nv50_program {
uint32_t interp; /* 0x1988 */
uint32_t colors; /* 0x1904 */
uint8_t has_samplemask;
- uint8_t sample_interp;
+ uint8_t force_persample_interp;
} fp;
struct {
@@ -99,6 +99,7 @@ struct nv50_program {
} gp;
void *fixups; /* relocation records */
+ void *interps; /* interpolation records */
struct nouveau_heap *mem;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index bcad90128d2..398abfb97ba 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -192,6 +192,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_INDEP_BLEND_FUNC:
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
+ case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
return class_3d >= NVA3_3D_CLASS;
/* unsupported caps */
@@ -216,7 +217,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
- case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
case PIPE_CAP_SHAREABLE_SHADERS:
return 0;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
index 941555ffbf8..b3fece07c3f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
@@ -168,11 +168,23 @@ nv50_fragprog_validate(struct nv50_context *nv50)
{
struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *fp = nv50->fragprog;
+ struct pipe_rasterizer_state *rast = &nv50->rast->pipe;
- fp->fp.sample_interp = nv50->min_samples > 1;
+ if (fp->fp.force_persample_interp != rast->force_persample_interp) {
+ /* Force the program to be reuploaded, which will trigger interp fixups
+ * to get applied
+ */
+ if (fp->mem)
+ nouveau_heap_free(&fp->mem);
+
+ fp->fp.force_persample_interp = rast->force_persample_interp;
+ }
+
+ if (fp->mem && !(nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_MIN_SAMPLES)))
+ return;
if (!nv50_program_validate(nv50, fp))
- return;
+ return;
nv50_program_update_context_state(nv50, fp, 1);
BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index 66dcf43533b..b6181edf24f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -487,7 +487,7 @@ static struct state_validate {
{ nv50_validate_viewport, NV50_NEW_VIEWPORT },
{ nv50_vertprog_validate, NV50_NEW_VERTPROG },
{ nv50_gmtyprog_validate, NV50_NEW_GMTYPROG },
- { nv50_fragprog_validate, NV50_NEW_FRAGPROG |
+ { nv50_fragprog_validate, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
NV50_NEW_MIN_SAMPLES },
{ nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
NV50_NEW_GMTYPROG | NV50_NEW_RASTERIZER },