From 464c2d80834e4ccf7f28fb62b82a2fa13e6445fb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 13 May 2016 14:35:33 +1000 Subject: [PATCH] r600: add cull distance support This passes all the tests in piglit. Signed-off-by: Dave Airlie --- docs/features.txt | 2 +- docs/relnotes/17.4.0.html | 1 + src/gallium/drivers/r600/evergreen_state.c | 4 ++-- src/gallium/drivers/r600/r600_pipe.c | 3 ++- src/gallium/drivers/r600/r600_pipe.h | 2 ++ src/gallium/drivers/r600/r600_shader.c | 14 ++++++++++++-- src/gallium/drivers/r600/r600_shader.h | 2 ++ src/gallium/drivers/r600/r600_state_common.c | 5 ++++- 8 files changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index 25a0e754609..d4ec38a236b 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -211,7 +211,7 @@ GL 4.5, GLSL 4.50 -- all DONE: nvc0, radeonsi GL_ARB_ES3_1_compatibility DONE (i965/hsw+) GL_ARB_clip_control DONE (freedreno, i965, nv50, r600, llvmpipe, softpipe, swr) GL_ARB_conditional_render_inverted DONE (freedreno, i965, nv50, r600, llvmpipe, softpipe, swr) - GL_ARB_cull_distance DONE (i965, nv50, llvmpipe, softpipe, swr) + GL_ARB_cull_distance DONE (i965, nv50, r600, llvmpipe, softpipe, swr) GL_ARB_derivative_control DONE (i965, nv50, r600) GL_ARB_direct_state_access DONE (all drivers) GL_ARB_get_texture_sub_image DONE (all drivers) diff --git a/docs/relnotes/17.4.0.html b/docs/relnotes/17.4.0.html index 12a48643654..ec2386b3305 100644 --- a/docs/relnotes/17.4.0.html +++ b/docs/relnotes/17.4.0.html @@ -47,6 +47,7 @@ Note: some of the new features are only available with certain drivers.
  • Disk shader cache support for i965 when MESA_GLSL_CACHE_DISABLE environment variable is set to "0" or "false"
  • GL_ARB_shader_atomic_counters and GL_ARB_shader_atomic_counter_ops on r600/evergreen+
  • GL_ARB_shader_image_load_store and GL_ARB_shader_image_size on r600/evergreen+
  • +
  • GL_ARB_cull_distance on r600/evergreen+
  • OpenGL 4.2 on r600/evergreen with hw fp64 support
  • diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 5a3a8514abb..dcbc6862832 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -3495,8 +3495,8 @@ void evergreen_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */ shader->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_CCDIST0_VEC_ENA((rshader->cc_dist_mask & 0x0F) != 0) | + S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->cc_dist_mask & 0xF0) != 0) | S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write) | S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size) | S_02881C_USE_VTX_EDGE_FLAG(rshader->vs_out_edgeflag) | diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index a232ee46a86..9cdef10e480 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -387,7 +387,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_STRING_MARKER: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: - case PIPE_CAP_CULL_DISTANCE: case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: case PIPE_CAP_TGSI_VOTE: case PIPE_CAP_MAX_WINDOW_RECTANGLES: @@ -422,6 +421,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) rscreen->b.family == CHIP_HEMLOCK) return 1; return 0; + case PIPE_CAP_CULL_DISTANCE: + return 1; case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: if (family >= CHIP_CEDAR) diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ad7e499be21..f651d66e070 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -154,7 +154,9 @@ struct r600_clip_misc_state { unsigned pa_cl_clip_cntl; /* from rasterizer */ unsigned pa_cl_vs_out_cntl; /* from vertex shader */ unsigned clip_plane_enable; /* from rasterizer */ + unsigned cc_dist_mask; /* from vertex shader */ unsigned clip_dist_write; /* from vertex shader */ + unsigned cull_dist_write; /* from vertex shader */ boolean clip_disable; /* from vertex shader */ boolean vs_out_viewport; /* from vertex shader */ }; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 9d0e6252957..1422abf6fa9 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -917,8 +917,6 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]); switch (d->Semantic.Name) { case TGSI_SEMANTIC_CLIPDIST: - ctx->shader->clip_dist_write |= d->Declaration.UsageMask << - ((d->Semantic.Index + j) << 2); break; case TGSI_SEMANTIC_PSIZE: ctx->shader->vs_out_misc_write = 1; @@ -2372,6 +2370,8 @@ static int generate_gs_copy_shader(struct r600_context *rctx, /* spi_sid is 0 for clipdistance outputs that were generated * for clipvertex - we don't need to pass them to PS */ ctx.shader->clip_dist_write = gs->shader.clip_dist_write; + ctx.shader->cull_dist_write = gs->shader.cull_dist_write; + ctx.shader->cc_dist_mask = gs->shader.cc_dist_mask; if (out->spi_sid) { /* duplicate it as PARAM to pass to the pixel shader */ output.array_base = next_param++; @@ -3238,6 +3238,15 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, shader->vs_position_window_space = ctx.info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION]; shader->ps_conservative_z = (uint8_t)ctx.info.properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT]; + if (ctx.type == PIPE_SHADER_VERTEX || + ctx.type == PIPE_SHADER_GEOMETRY || + ctx.type == PIPE_SHADER_TESS_EVAL) { + shader->cc_dist_mask = (1 << (ctx.info.properties[TGSI_PROPERTY_NUM_CULLDIST_ENABLED] + + ctx.info.properties[TGSI_PROPERTY_NUM_CLIPDIST_ENABLED])) - 1; + shader->clip_dist_write = (1 << ctx.info.properties[TGSI_PROPERTY_NUM_CLIPDIST_ENABLED]) - 1; + shader->cull_dist_write = ((1 << ctx.info.properties[TGSI_PROPERTY_NUM_CULLDIST_ENABLED]) - 1) << ctx.info.properties[TGSI_PROPERTY_NUM_CLIPDIST_ENABLED]; + } + if (shader->vs_as_gs_a) vs_add_primid_output(&ctx, key.vs.prim_id_out); @@ -3490,6 +3499,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, shader->output[ctx.cv_output].spi_sid = 0; shader->clip_dist_write = 0xFF; + shader->cc_dist_mask = 0xFF; for (i = 0; i < 8; i++) { int oreg = i >> 2; diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 5d6501c8d38..84449078839 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -85,7 +85,9 @@ struct r600_shader { /* Real number of ps color exports compiled in the bytecode */ unsigned nr_ps_color_exports; /* bit n is set if the shader writes gl_ClipDistance[n] */ + unsigned cc_dist_mask; unsigned clip_dist_write; + unsigned cull_dist_write; boolean vs_position_window_space; /* flag is set if the shader writes VS_OUT_MISC_VEC (e.g. for PSIZE) */ boolean vs_out_misc_write; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index b8d4b8f70fa..a977cdc30d2 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1465,10 +1465,12 @@ static void r600_update_clip_state(struct r600_context *rctx, { if (current->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl || current->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write || + current->shader.cull_dist_write != rctx->clip_misc_state.cull_dist_write || current->shader.vs_position_window_space != rctx->clip_misc_state.clip_disable || current->shader.vs_out_viewport != rctx->clip_misc_state.vs_out_viewport) { rctx->clip_misc_state.pa_cl_vs_out_cntl = current->pa_cl_vs_out_cntl; rctx->clip_misc_state.clip_dist_write = current->shader.clip_dist_write; + rctx->clip_misc_state.cull_dist_write = current->shader.cull_dist_write; rctx->clip_misc_state.clip_disable = current->shader.vs_position_window_space; rctx->clip_misc_state.vs_out_viewport = current->shader.vs_out_viewport; r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom); @@ -1769,7 +1771,8 @@ void r600_emit_clip_misc_state(struct r600_context *rctx, struct r600_atom *atom S_028810_CLIP_DISABLE(state->clip_disable)); radeon_set_context_reg(cs, R_02881C_PA_CL_VS_OUT_CNTL, state->pa_cl_vs_out_cntl | - (state->clip_plane_enable & state->clip_dist_write)); + (state->clip_plane_enable & state->clip_dist_write) | + (state->cull_dist_write << 8)); /* reuse needs to be set off if we write oViewport */ if (rctx->b.chip_class >= EVERGREEN) radeon_set_context_reg(cs, R_028AB4_VGT_REUSE_OFF, -- 2.30.2