From: Vadim Girlin Date: Sun, 15 Jan 2012 14:29:50 +0000 (-0500) Subject: r600g: implement clip distances X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91d47296967ebfaf685f3870998ea0a1450ecf55;p=mesa.git r600g: implement clip distances Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 59328b959cf..2f7046bcba6 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -907,6 +907,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; rs->two_side = state->light_twoside; + rs->clip_plane_enable = state->clip_plane_enable; clip_rule = state->scissor ? 0xAAAA : 0xFFFF; @@ -944,8 +945,8 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) | S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)), 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_02881C_PA_CL_VS_OUT_CNTL, - S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) | - S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex), 0xFFFFFFFF, NULL, 0); + S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex), + S_02881C_USE_VTX_POINT_SIZE(1), NULL, 0); r600_pipe_state_add_reg(rstate, R_028820_PA_CL_NANINF_CNTL, 0x00000000, 0xFFFFFFFF, NULL, 0); /* point size 12.4 fixed point */ tmp = (unsigned)(state->point_size * 8.0); @@ -992,9 +993,10 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp), 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, - S_028810_PS_UCP_MODE(3) | (state->clip_plane_enable & 63) | - S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) | - S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), 0xFFFFFFFF, NULL, 0); + S_028810_PS_UCP_MODE(3) | S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) | + S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), + S_028810_PS_UCP_MODE(3) | S_028810_ZCLIP_NEAR_DISABLE(1) | + S_028810_ZCLIP_FAR_DISABLE(1), NULL, 0); return rstate; } @@ -2479,6 +2481,16 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader r600_pipe_state_add_reg(rstate, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, 0xFFFFFFFF, NULL, 0); + + r600_pipe_state_add_reg(rstate, + R_02881C_PA_CL_VS_OUT_CNTL, + S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 0x0F) != 0) | + S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) | + S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write), + S_02881C_VS_OUT_CCDIST0_VEC_ENA(1) | + S_02881C_VS_OUT_CCDIST1_VEC_ENA(1) | + S_02881C_VS_OUT_MISC_VEC_ENA(1), + NULL, 0); } void evergreen_fetch_shader(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 87a710b9831..8df03108c78 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -110,6 +110,7 @@ struct r600_pipe_rasterizer { boolean flatshade; boolean two_side; unsigned sprite_coord_enable; + unsigned clip_plane_enable; float offset_units; float offset_scale; }; @@ -219,6 +220,8 @@ struct r600_pipe_context { boolean clamp_vertex_color; boolean clamp_fragment_color; boolean two_side; + unsigned user_clip_plane_enable; + unsigned clip_dist_enable; unsigned sprite_coord_enable; boolean export_16bpc; unsigned alpha_ref; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 6b3d4ef436b..493ebbea98a 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -470,6 +470,17 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]); ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + d->Range.First; ctx->shader->output[i].interpolate = d->Declaration.Interpolate; + ctx->shader->output[i].write_mask = d->Declaration.UsageMask; + if (ctx->type == TGSI_PROCESSOR_VERTEX) { + switch (d->Semantic.Name) { + case TGSI_SEMANTIC_CLIPDIST: + ctx->shader->clip_dist_write |= d->Declaration.UsageMask << (d->Semantic.Index << 2); + break; + case TGSI_SEMANTIC_PSIZE: + ctx->shader->vs_out_misc_write = 1; + break; + } + } break; case TGSI_FILE_CONSTANT: case TGSI_FILE_TEMPORARY: @@ -891,9 +902,15 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi break; case TGSI_TOKEN_TYPE_PROPERTY: property = &ctx.parse.FullToken.FullProperty; - if (property->Property.PropertyName == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) { + switch (property->Property.PropertyName) { + case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS: if (property->u[0].Data == 1) shader->fs_write_all = TRUE; + break; + case TGSI_PROPERTY_VS_PROHIBIT_UCPS: + if (property->u[0].Data == 1) + shader->vs_prohibit_ucps = TRUE; + break; } break; default: @@ -1038,8 +1055,9 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi /* export output */ j = 0; + for (i = 0, pos0 = 0; i < noutput; i++) { - memset(&output[i], 0, sizeof(struct r600_bytecode_output)); + memset(&output[i+j], 0, sizeof(struct r600_bytecode_output)); output[i + j].gpr = shader->output[i].gpr; output[i + j].elem_size = 3; output[i + j].swizzle_x = 0; @@ -1049,21 +1067,41 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi output[i + j].burst_count = 1; output[i + j].barrier = 1; output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; - output[i + j].array_base = i - pos0; + output[i + j].array_base = i+j - pos0; output[i + j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT); switch (ctx.type) { case TGSI_PROCESSOR_VERTEX: - if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + switch (shader->output[i].name) { + case TGSI_SEMANTIC_POSITION: output[i + j].array_base = 60; output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; /* position doesn't count in array_base */ pos0++; - } - if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) { + break; + + case TGSI_SEMANTIC_PSIZE: output[i + j].array_base = 61; output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; /* position doesn't count in array_base */ pos0++; + break; + + case TGSI_SEMANTIC_CLIPDIST: + /* array base for enabled OUT_MISC_VEC & CCDIST[0|1]_VEC + * vectors is allocated sequentially, starting from 61 */ + output[i + j].array_base = 61 + shader->output[i].sid + /* +1 if OUT_MISC_VEC is enabled */ + + shader->vs_out_misc_write + /* -1 if OUT_CCDIST0_VEC is disabled */ + - (((shader->clip_dist_write & 0xF) == 0)? 1 : 0); + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + j++; + pos0++; + /* duplicate it as PARAM to pass to the pixel shader */ + memcpy(&output[i+j], &output[i+j-1], sizeof(struct r600_bytecode_output)); + output[i + j].array_base = i+j-pos0; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + break; } break; case TGSI_PROCESSOR_FRAGMENT: diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 530a77604fe..323f94810f6 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -34,6 +34,7 @@ struct r600_shader_io { unsigned interpolate; boolean centroid; unsigned lds_pos; /* for evergreen */ + unsigned write_mask; }; struct r600_shader { @@ -46,9 +47,14 @@ struct r600_shader { struct r600_shader_io output[32]; boolean uses_kill; boolean fs_write_all; + boolean vs_prohibit_ucps; boolean clamp_color; boolean two_side; unsigned nr_cbufs; + /* bit n is set if the shader writes gl_ClipDistance[n] */ + unsigned clip_dist_write; + /* flag is set if the shader writes VS_OUT_MISC_VEC (e.g. for PSIZE) */ + boolean vs_out_misc_write; }; #endif diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index afe6fb0e8be..81edc4a227f 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -959,6 +959,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; rs->two_side = state->light_twoside; + rs->clip_plane_enable = state->clip_plane_enable; clip_rule = state->scissor ? 0xAAAA : 0xFFFF; /* offset */ @@ -995,8 +996,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx, S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) | S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)), 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_02881C_PA_CL_VS_OUT_CNTL, - S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) | - S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex), 0xFFFFFFFF, NULL, 0); + S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex), + S_02881C_USE_VTX_POINT_SIZE(1), NULL, 0); r600_pipe_state_add_reg(rstate, R_028820_PA_CL_NANINF_CNTL, 0x00000000, 0xFFFFFFFF, NULL, 0); /* point size 12.4 fixed point */ tmp = (unsigned)(state->point_size * 8.0); @@ -1035,10 +1036,10 @@ static void *r600_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp), 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, - S_028810_PS_UCP_MODE(3) | (state->clip_plane_enable & 63) | - S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) | - S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), 0xFFFFFFFF, NULL, 0); - + S_028810_PS_UCP_MODE(3) | S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) | + S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), + S_028810_PS_UCP_MODE(3) | S_028810_ZCLIP_NEAR_DISABLE(1) | + S_028810_ZCLIP_FAR_DISABLE(1), NULL, 0); return rstate; } @@ -2239,6 +2240,16 @@ void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shad r600_pipe_state_add_reg(rstate, R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, 0xFFFFFFFF, NULL, 0); + + r600_pipe_state_add_reg(rstate, + R_02881C_PA_CL_VS_OUT_CNTL, + S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 0x0F) != 0) | + S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) | + S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write), + S_02881C_VS_OUT_CCDIST0_VEC_ENA(1) | + S_02881C_VS_OUT_CCDIST1_VEC_ENA(1) | + S_02881C_VS_OUT_MISC_VEC_ENA(1), + NULL, 0); } void r600_fetch_shader(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index eb32d5153a2..4bc4b97a5d7 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -554,6 +554,30 @@ static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shade static void r600_update_derived_state(struct r600_pipe_context *rctx) { struct pipe_context * ctx = (struct pipe_context*)rctx; + struct r600_pipe_state rstate; + unsigned user_clip_plane_enable; + unsigned clip_dist_enable; + + if (rctx->vs_shader->shader.clip_dist_write || rctx->vs_shader->shader.vs_prohibit_ucps) + user_clip_plane_enable = 0; + else + user_clip_plane_enable = rctx->rasterizer->clip_plane_enable & 0x3F; + + clip_dist_enable = rctx->rasterizer->clip_plane_enable & rctx->vs_shader->shader.clip_dist_write & 0xFF; + rstate.nregs = 0; + + if (user_clip_plane_enable != rctx->user_clip_plane_enable) { + r600_pipe_state_add_reg(&rstate, R_028810_PA_CL_CLIP_CNTL, user_clip_plane_enable , 0x3F, NULL, 0); + rctx->user_clip_plane_enable = user_clip_plane_enable; + } + + if (clip_dist_enable != rctx->clip_dist_enable) { + r600_pipe_state_add_reg(&rstate, R_02881C_PA_CL_VS_OUT_CNTL, clip_dist_enable, 0xFF, NULL, 0); + rctx->clip_dist_enable = clip_dist_enable; + } + + if (rstate.nregs) + r600_context_pipe_state_set(&rctx->ctx, &rstate); if (!rctx->blitter->running) { if (rctx->have_depth_fb || rctx->have_depth_texture)