Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>tags/mesa-10.2-rc1
@@ -354,6 +354,7 @@ enum SVSemantic | |||
SV_POINT_COORD, | |||
SV_CLIP_DISTANCE, | |||
SV_SAMPLE_INDEX, | |||
SV_SAMPLE_POS, | |||
SV_TESS_FACTOR, | |||
SV_TESS_COORD, | |||
SV_TID, |
@@ -74,7 +74,6 @@ struct nv50_ir_varying | |||
#define NV50_SEMANTIC_INVOCATIONID (TGSI_SEMANTIC_COUNT + 6) | |||
#define NV50_SEMANTIC_TESSFACTOR (TGSI_SEMANTIC_COUNT + 7) | |||
#define NV50_SEMANTIC_TESSCOORD (TGSI_SEMANTIC_COUNT + 8) | |||
#define NV50_SEMANTIC_SAMPLEMASK (TGSI_SEMANTIC_COUNT + 9) | |||
#define NV50_SEMANTIC_COUNT (TGSI_SEMANTIC_COUNT + 10) | |||
#define NV50_TESS_PART_FRACT_ODD 0 | |||
@@ -181,12 +180,14 @@ struct nv50_ir_prog_info | |||
uint8_t edgeFlagOut; | |||
uint8_t fragDepth; /* output index of FragDepth */ | |||
uint8_t sampleMask; /* output index of SampleMask */ | |||
boolean 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 */ | |||
boolean nv50styleSurfaces; /* generate gX[] access for raw buffers */ | |||
uint8_t resInfoCBSlot; /* cX[] used for tex handles, surface info */ | |||
uint16_t texBindBase; /* base address for tex handles (nve4) */ | |||
uint16_t suInfoBase; /* base address for surface info (nve4) */ | |||
uint16_t sampleInfoBase; /* base address for sample positions */ | |||
uint8_t msInfoCBSlot; /* cX[] used for multisample info */ | |||
uint16_t msInfoBase; /* base address for multisample info */ | |||
} io; |
@@ -346,6 +346,8 @@ static nv50_ir::SVSemantic translateSysVal(uint sysval) | |||
case TGSI_SEMANTIC_BLOCK_ID: return nv50_ir::SV_CTAID; | |||
case TGSI_SEMANTIC_BLOCK_SIZE: return nv50_ir::SV_NTID; | |||
case TGSI_SEMANTIC_THREAD_ID: return nv50_ir::SV_TID; | |||
case TGSI_SEMANTIC_SAMPLEID: return nv50_ir::SV_SAMPLE_INDEX; | |||
case TGSI_SEMANTIC_SAMPLEPOS: return nv50_ir::SV_SAMPLE_POS; | |||
default: | |||
assert(0); | |||
return nv50_ir::SV_CLOCK; | |||
@@ -925,7 +927,7 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl) | |||
default: | |||
break; | |||
} | |||
if (decl->Interp.Centroid) | |||
if (decl->Interp.Centroid || info->io.sampleInterp) | |||
info->in[i].centroid = 1; | |||
} | |||
} | |||
@@ -956,6 +958,9 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl) | |||
decl->Declaration.UsageMask << (si * 4); | |||
info->io.genUserClip = -1; | |||
break; | |||
case TGSI_SEMANTIC_SAMPLEMASK: | |||
info->io.sampleMask = i; | |||
break; | |||
default: | |||
break; | |||
} |
@@ -1032,6 +1032,18 @@ NV50LoweringPreSSA::handleRDSV(Instruction *i) | |||
bld.mkMov(def, bld.mkImm(0)); | |||
} | |||
break; | |||
case SV_SAMPLE_POS: { | |||
Value *off = new_LValue(func, FILE_ADDRESS); | |||
bld.mkOp1(OP_RDSV, TYPE_U32, def, bld.mkSysVal(SV_SAMPLE_INDEX, 0)); | |||
bld.mkOp2(OP_SHL, TYPE_U32, off, def, bld.mkImm(3)); | |||
bld.mkLoad(TYPE_F32, | |||
def, | |||
bld.mkSymbol( | |||
FILE_MEMORY_CONST, prog->driver->io.resInfoCBSlot, | |||
TYPE_U32, prog->driver->io.sampleInfoBase + 4 * idx), | |||
off); | |||
break; | |||
} | |||
default: | |||
bld.mkFetch(i->getDef(0), i->dType, | |||
FILE_SHADER_INPUT, addr, i->getIndirect(0, 0), NULL); |
@@ -253,6 +253,7 @@ static const char *SemanticStr[SV_LAST + 1] = | |||
"POINT_COORD", | |||
"CLIP_DISTANCE", | |||
"SAMPLE_INDEX", | |||
"SAMPLE_POS", | |||
"TESS_FACTOR", | |||
"TESS_COORD", | |||
"TID", |
@@ -249,6 +249,8 @@ TargetNV50::getSVAddress(DataFile shaderFile, const Symbol *sym) const | |||
return 0x2 + 2 * sym->reg.data.sv.index; | |||
case SV_TID: | |||
return 0; | |||
case SV_SAMPLE_POS: | |||
return 0; /* sample position is handled differently */ | |||
default: | |||
return sysvalLocation[sym->reg.data.sv.sv]; | |||
} |
@@ -49,6 +49,7 @@ | |||
#define NV50_NEW_TEXTURES (1 << 19) | |||
#define NV50_NEW_SAMPLERS (1 << 20) | |||
#define NV50_NEW_STRMOUT (1 << 21) | |||
#define NV50_NEW_MIN_SAMPLES (1 << 22) | |||
#define NV50_NEW_CONTEXT (1 << 31) | |||
#define NV50_BIND_FB 0 | |||
@@ -83,7 +84,10 @@ | |||
/* For each MS level (4), 8 sets of 32-bit integer pairs sample offsets */ | |||
#define NV50_CB_AUX_MS_OFFSET 0x880 | |||
#define NV50_CB_AUX_MS_SIZE (4 * 8 * 4 * 2) | |||
/* next spot: 0x980 */ | |||
/* Sample position pairs for the current output MS level */ | |||
#define NV50_CB_AUX_SAMPLE_OFFSET 0x980 | |||
#define NV50_CB_AUX_SAMPLE_OFFSET_SIZE (4 * 8 * 2) | |||
/* next spot: 0x9c0 */ | |||
/* 4 32-bit floats for the vertex runout, put at the end */ | |||
#define NV50_CB_AUX_RUNOUT_OFFSET (NV50_CB_AUX_SIZE - 0x10) | |||
@@ -170,6 +174,7 @@ struct nv50_context { | |||
struct pipe_clip_state clip; | |||
unsigned sample_mask; | |||
unsigned min_samples; | |||
boolean vbo_push_hint; | |||
@@ -234,8 +234,10 @@ nv50_fragprog_assign_slots(struct nv50_ir_prog_info *info) | |||
prog->max_out = MAX2(prog->max_out, prog->out[i].hw + 4); | |||
} | |||
if (info->io.sampleMask < PIPE_MAX_SHADER_OUTPUTS) | |||
if (info->io.sampleMask < PIPE_MAX_SHADER_OUTPUTS) { | |||
info->out[info->io.sampleMask].slot[0] = prog->max_out++; | |||
prog->fp.has_samplemask = 1; | |||
} | |||
if (info->io.fragDepth < PIPE_MAX_SHADER_OUTPUTS) | |||
info->out[info->io.fragDepth].slot[2] = prog->max_out++; | |||
@@ -333,9 +335,11 @@ 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; | |||
info->io.sampleInfoBase = NV50_CB_AUX_SAMPLE_OFFSET; | |||
info->io.msInfoCBSlot = 15; | |||
info->io.msInfoBase = NV50_CB_AUX_MS_OFFSET; | |||
@@ -84,6 +84,8 @@ struct nv50_program { | |||
uint32_t flags[2]; /* 0x19a8, 196c */ | |||
uint32_t interp; /* 0x1988 */ | |||
uint32_t colors; /* 0x1904 */ | |||
uint8_t has_samplemask; | |||
uint8_t sample_interp; | |||
} fp; | |||
struct { |
@@ -198,13 +198,13 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) | |||
case PIPE_CAP_TEXTURE_GATHER_SM5: | |||
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: | |||
case PIPE_CAP_FAKE_SW_MSAA: | |||
case PIPE_CAP_SAMPLE_SHADING: | |||
return 0; | |||
case PIPE_CAP_MAX_VIEWPORTS: | |||
return NV50_MAX_VIEWPORTS; | |||
case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: | |||
return (class_3d >= NVA3_3D_CLASS) ? 4 : 0; | |||
case PIPE_CAP_TEXTURE_QUERY_LOD: | |||
case PIPE_CAP_SAMPLE_SHADING: | |||
return class_3d >= NVA3_3D_CLASS; | |||
default: | |||
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); |
@@ -172,6 +172,8 @@ nv50_fragprog_validate(struct nv50_context *nv50) | |||
struct nouveau_pushbuf *push = nv50->base.pushbuf; | |||
struct nv50_program *fp = nv50->fragprog; | |||
fp->fp.sample_interp = nv50->min_samples > 1; | |||
if (!nv50_program_validate(nv50, fp)) | |||
return; | |||
nv50_program_update_context_state(nv50, fp, 1); | |||
@@ -186,6 +188,17 @@ nv50_fragprog_validate(struct nv50_context *nv50) | |||
PUSH_DATA (push, fp->fp.flags[1]); | |||
BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); | |||
PUSH_DATA (push, fp->code_base); | |||
if (nv50->screen->tesla->oclass >= NVA3_3D_CLASS) { | |||
BEGIN_NV04(push, SUBC_3D(NVA3_3D_FP_MULTISAMPLE), 1); | |||
if (nv50->min_samples > 1 || fp->fp.has_samplemask) | |||
PUSH_DATA(push, | |||
NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE | | |||
(NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK * | |||
fp->fp.has_samplemask)); | |||
else | |||
PUSH_DATA(push, 0); | |||
} | |||
} | |||
void |
@@ -864,6 +864,16 @@ nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) | |||
nv50->dirty |= NV50_NEW_SAMPLE_MASK; | |||
} | |||
static void | |||
nv50_set_min_samples(struct pipe_context *pipe, unsigned min_samples) | |||
{ | |||
struct nv50_context *nv50 = nv50_context(pipe); | |||
if (nv50->min_samples != min_samples) { | |||
nv50->min_samples = min_samples; | |||
nv50->dirty |= NV50_NEW_MIN_SAMPLES; | |||
} | |||
} | |||
static void | |||
nv50_set_framebuffer_state(struct pipe_context *pipe, | |||
@@ -1135,6 +1145,7 @@ nv50_init_state_functions(struct nv50_context *nv50) | |||
pipe->set_stencil_ref = nv50_set_stencil_ref; | |||
pipe->set_clip_state = nv50_set_clip_state; | |||
pipe->set_sample_mask = nv50_set_sample_mask; | |||
pipe->set_min_samples = nv50_set_min_samples; | |||
pipe->set_constant_buffer = nv50_set_constant_buffer; | |||
pipe->set_framebuffer_state = nv50_set_framebuffer_state; | |||
pipe->set_polygon_stipple = nv50_set_polygon_stipple; | |||
@@ -1153,4 +1164,5 @@ nv50_init_state_functions(struct nv50_context *nv50) | |||
pipe->set_stream_output_targets = nv50_set_stream_output_targets; | |||
nv50->sample_mask = ~0; | |||
nv50->min_samples = 1; | |||
} |
@@ -129,6 +129,19 @@ nv50_validate_fb(struct nv50_context *nv50) | |||
BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); | |||
PUSH_DATA (push, fb->width << 16); | |||
PUSH_DATA (push, fb->height << 16); | |||
if (nv50->screen->tesla->oclass >= NVA3_3D_CLASS) { | |||
unsigned ms = 1 << ms_mode; | |||
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); | |||
PUSH_DATA (push, (NV50_CB_AUX_SAMPLE_OFFSET << (8 - 2)) | NV50_CB_AUX); | |||
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 2 * ms); | |||
for (i = 0; i < ms; i++) { | |||
float xy[2]; | |||
nv50->base.pipe.get_sample_position(&nv50->base.pipe, ms, i, xy); | |||
PUSH_DATAf(push, xy[0]); | |||
PUSH_DATAf(push, xy[1]); | |||
} | |||
} | |||
} | |||
static void | |||
@@ -358,6 +371,23 @@ nv50_validate_sample_mask(struct nv50_context *nv50) | |||
PUSH_DATA (push, mask[3]); | |||
} | |||
static void | |||
nv50_validate_min_samples(struct nv50_context *nv50) | |||
{ | |||
struct nouveau_pushbuf *push = nv50->base.pushbuf; | |||
int samples; | |||
if (nv50->screen->tesla->oclass < NVA3_3D_CLASS) | |||
return; | |||
samples = util_next_power_of_two(nv50->min_samples); | |||
if (samples > 1) | |||
samples |= NVA3_3D_SAMPLE_SHADING_ENABLE; | |||
BEGIN_NV04(push, SUBC_3D(NVA3_3D_SAMPLE_SHADING), 1); | |||
PUSH_DATA (push, samples); | |||
} | |||
static void | |||
nv50_switch_pipe_context(struct nv50_context *ctx_to) | |||
{ | |||
@@ -414,7 +444,8 @@ 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_MIN_SAMPLES }, | |||
{ nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | | |||
NV50_NEW_GMTYPROG | NV50_NEW_RASTERIZER }, | |||
{ nv50_gp_linkage_validate, NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG }, | |||
@@ -427,7 +458,8 @@ static struct state_validate { | |||
{ nv50_validate_samplers, NV50_NEW_SAMPLERS }, | |||
{ nv50_stream_output_validate, NV50_NEW_STRMOUT | | |||
NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG }, | |||
{ nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS } | |||
{ nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }, | |||
{ nv50_validate_min_samples, NV50_NEW_MIN_SAMPLES }, | |||
}; | |||
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) | |||
@@ -622,6 +622,7 @@ struct nv50_blitctx | |||
unsigned num_samplers[3]; | |||
struct pipe_sampler_view *texture[2]; | |||
struct nv50_tsc_entry *sampler[2]; | |||
unsigned min_samples; | |||
uint32_t dirty; | |||
} saved; | |||
struct nv50_rasterizer_stateobj rast; | |||
@@ -1000,6 +1001,8 @@ nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) | |||
ctx->saved.gp = nv50->gmtyprog; | |||
ctx->saved.fp = nv50->fragprog; | |||
ctx->saved.min_samples = nv50->min_samples; | |||
nv50->rast = &ctx->rast; | |||
nv50->vertprog = &blitter->vp; | |||
@@ -1021,13 +1024,15 @@ nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) | |||
nv50->num_samplers[0] = nv50->num_samplers[1] = 0; | |||
nv50->num_samplers[2] = 2; | |||
nv50->min_samples = 1; | |||
ctx->saved.dirty = nv50->dirty; | |||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); | |||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); | |||
nv50->dirty = | |||
NV50_NEW_FRAMEBUFFER | | |||
NV50_NEW_FRAMEBUFFER | NV50_NEW_MIN_SAMPLES | | |||
NV50_NEW_VERTPROG | NV50_NEW_FRAGPROG | NV50_NEW_GMTYPROG | | |||
NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS; | |||
} | |||
@@ -1052,6 +1057,8 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit) | |||
nv50->gmtyprog = blit->saved.gp; | |||
nv50->fragprog = blit->saved.fp; | |||
nv50->min_samples = blit->saved.min_samples; | |||
pipe_sampler_view_reference(&nv50->textures[2][0], NULL); | |||
pipe_sampler_view_reference(&nv50->textures[2][1], NULL); | |||
@@ -1076,6 +1083,8 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit) | |||
NV50_NEW_RASTERIZER | NV50_NEW_ZSA | NV50_NEW_BLEND | | |||
NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS | | |||
NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG | NV50_NEW_FRAGPROG); | |||
nv50->base.pipe.set_min_samples(&nv50->base.pipe, blit->saved.min_samples); | |||
} | |||