[Mesa-dev] [PATCH] r600: add cull distance support

Dave Airlie airlied at gmail.com
Sun Nov 19 23:32:07 UTC 2017


From: Dave Airlie <airlied at redhat.com>

This passes all the tests in piglit.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 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 633d259..d26bf0e 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 12a4864..ec2386b 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.
 <li>Disk shader cache support for i965 when MESA_GLSL_CACHE_DISABLE environment variable is set to "0" or "false"</li>
 <li>GL_ARB_shader_atomic_counters and GL_ARB_shader_atomic_counter_ops on r600/evergreen+</li>
 <li>GL_ARB_shader_image_load_store and GL_ARB_shader_image_size on r600/evergreen+</li>
+<li>GL_ARB_cull_distance on r600/evergreen+</li>
 <li>OpenGL 4.2 on r600/evergreen with hw fp64 support</li>
 </ul>
 
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 5a3a851..dcbc686 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 a232ee4..9cdef10 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 ad7e499..f651d66 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 9d0e625..1422abf 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 5d6501c..8444907 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 b8d4b8f..a977cdc 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.1.0



More information about the mesa-dev mailing list