diff options
author | Ilia Mirkin <[email protected]> | 2014-03-30 18:25:40 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2014-04-26 11:53:24 -0400 |
commit | f715a0a39a0f7f19443e7721ae792878ba504eed (patch) | |
tree | 596a2c6b6570f921aec2fa915e6c7bc7b7d7c18e /src/gallium/drivers/nouveau/nv50 | |
parent | c5d822dad902b19f06c9be3c6863a51e1881ec5b (diff) |
nv50: add support for PIPE_CAP_SAMPLE_SHADING
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_context.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_program.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_program.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_shader_state.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_state.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_state_validate.c | 36 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_surface.c | 11 |
8 files changed, 83 insertions, 6 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h index 32ca5918f95..b776deed0ea 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_context.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h @@ -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; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index 0e06125df01..4744a3cc650 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c @@ -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; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h index 87b06790d4f..fe6bd6025be 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h @@ -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 { diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 243c7c4c39c..7ffffa67a03 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -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); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c index 28cff8ba913..c698782d8bd 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c @@ -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 diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c index 647c01f1973..d0bc7ff1a2a 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -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; } diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c index 100d02d5603..18451c74f8d 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c @@ -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 @@ -359,6 +372,23 @@ nv50_validate_sample_mask(struct nv50_context *nv50) } 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) { struct nv50_context *ctx_from = ctx_to->screen->cur_ctx; @@ -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])) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index e60aec52e10..6b4dc4d4949 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -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); } |