summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-10-15 15:25:57 +0100
committerEric Anholt <[email protected]>2014-10-15 18:11:46 +0100
commit201d4c0b2a6f7f0c1d59c4fd5cce4916fc48a2d2 (patch)
tree85ae3991ed5f24aac3d0993c912e38e4068b1135
parent6a0bf67048d508f907db6bb05e5e367308c21511 (diff)
vc4: Add support for user clip plane and gl_ClipVertex.
Fixes about 15 piglit tests about interpolation and clipping.
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h2
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c84
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.c2
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h3
-rw-r--r--src/gallium/drivers/vc4/vc4_state.c4
5 files changed, 91 insertions, 4 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 56cfc7b51fa..45dfa020551 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -58,6 +58,7 @@
#define VC4_DIRTY_SCISSOR (1 << 17)
#define VC4_DIRTY_FLAT_SHADE_FLAGS (1 << 18)
#define VC4_DIRTY_PRIM_MODE (1 << 19)
+#define VC4_DIRTY_CLIP (1 << 20)
#define VC4_SHADER_DIRTY_VP (1 << 0)
#define VC4_SHADER_DIRTY_FP (1 << 1)
@@ -207,6 +208,7 @@ struct vc4_context {
unsigned sample_mask;
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple stipple;
+ struct pipe_clip_state clip;
struct pipe_viewport_state viewport;
struct vc4_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
struct vc4_vertexbuf_stateobj vertexbuf;
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index a79e354fd81..f4b723ae820 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -53,6 +53,7 @@ struct vc4_key {
unsigned wrap_t:3;
uint8_t swizzle[4];
} tex[VC4_MAX_TEXTURE_SAMPLERS];
+ uint8_t ucp_enables;
};
struct vc4_fs_key {
@@ -1097,6 +1098,9 @@ emit_tgsi_declaration(struct vc4_compile *c,
case TGSI_SEMANTIC_POSITION:
c->output_position_index = decl->Range.First * 4;
break;
+ case TGSI_SEMANTIC_CLIPVERTEX:
+ c->output_clipvertex_index = decl->Range.First * 4;
+ break;
case TGSI_SEMANTIC_COLOR:
c->output_color_index = decl->Range.First * 4;
break;
@@ -1398,6 +1402,28 @@ vc4_blend(struct vc4_compile *c, struct qreg *result,
}
static void
+clip_distance_discard(struct vc4_compile *c)
+{
+ for (int i = 0; i < PIPE_MAX_CLIP_PLANES; i++) {
+ if (!(c->key->ucp_enables & (1 << i)))
+ continue;
+
+ struct qreg dist = emit_fragment_varying(c,
+ TGSI_SEMANTIC_CLIPDIST,
+ i,
+ TGSI_SWIZZLE_X);
+
+ qir_SF(c, dist);
+
+ if (c->discard.file == QFILE_NULL)
+ c->discard = qir_uniform_f(c, 0.0);
+
+ c->discard = qir_SEL_X_Y_NS(c, qir_uniform_f(c, 1.0),
+ c->discard);
+ }
+}
+
+static void
alpha_test_discard(struct vc4_compile *c)
{
struct qreg src_alpha;
@@ -1456,6 +1482,7 @@ alpha_test_discard(struct vc4_compile *c)
static void
emit_frag_end(struct vc4_compile *c)
{
+ clip_distance_discard(c);
alpha_test_discard(c);
enum pipe_format color_format = c->fs_key->color_format;
@@ -1655,6 +1682,45 @@ emit_stub_vpm_read(struct vc4_compile *c)
}
static void
+emit_ucp_clipdistance(struct vc4_compile *c)
+{
+ struct qreg *clipvertex;
+
+ if (c->output_clipvertex_index != -1)
+ clipvertex = &c->outputs[c->output_clipvertex_index];
+ else if (c->output_position_index != -1)
+ clipvertex = &c->outputs[c->output_position_index];
+ else
+ return;
+
+ for (int plane = 0; plane < PIPE_MAX_CLIP_PLANES; plane++) {
+ if (!(c->key->ucp_enables & (1 << plane)))
+ continue;
+
+ /* Pick the next outputs[] that hasn't been written to, since
+ * there are no other program writes left to be processed at
+ * this point. If something had been declared but not written
+ * (like a w component), we'll just smash over the top of it.
+ */
+ uint32_t output_index = c->num_outputs++;
+ add_output(c, output_index,
+ TGSI_SEMANTIC_CLIPDIST,
+ plane,
+ TGSI_SWIZZLE_X);
+
+ struct qreg dist = qir_uniform_f(c, 0.0);
+ for (int i = 0; i < 4; i++) {
+ struct qreg ucp =
+ add_uniform(c, QUNIFORM_USER_CLIP_PLANE,
+ plane * 4 + i);
+ dist = qir_FADD(c, dist, qir_FMUL(c, clipvertex[i], ucp));
+ }
+
+ c->outputs[output_index] = dist;
+ }
+}
+
+static void
emit_vert_end(struct vc4_compile *c,
struct vc4_varying_semantic *fs_inputs,
uint32_t num_fs_inputs)
@@ -1662,6 +1728,8 @@ emit_vert_end(struct vc4_compile *c,
struct qreg rcp_w = qir_RCP(c, c->outputs[3]);
emit_stub_vpm_read(c);
+ emit_ucp_clipdistance(c);
+
emit_scaled_viewport_write(c, rcp_w);
emit_zs_write(c, rcp_w);
emit_rcp_wc_write(c, rcp_w);
@@ -1671,9 +1739,11 @@ emit_vert_end(struct vc4_compile *c,
for (int i = 0; i < num_fs_inputs; i++) {
struct vc4_varying_semantic *input = &fs_inputs[i];
int j;
+
for (j = 0; j < c->num_outputs; j++) {
struct vc4_varying_semantic *output =
&c->output_semantics[j];
+
if (input->semantic == output->semantic &&
input->index == output->index &&
input->swizzle == output->swizzle) {
@@ -1930,7 +2000,8 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
}
static void
-vc4_setup_shared_key(struct vc4_key *key, struct vc4_texture_stateobj *texstate)
+vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key,
+ struct vc4_texture_stateobj *texstate)
{
for (int i = 0; i < texstate->num_textures; i++) {
struct pipe_sampler_view *sampler = texstate->textures[i];
@@ -1949,6 +2020,8 @@ vc4_setup_shared_key(struct vc4_key *key, struct vc4_texture_stateobj *texstate)
key->tex[i].wrap_t = sampler_state->wrap_t;
}
}
+
+ key->ucp_enables = vc4->rasterizer->base.clip_plane_enable;
}
static void
@@ -1969,7 +2042,7 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
}
memset(key, 0, sizeof(*key));
- vc4_setup_shared_key(&key->base, &vc4->fragtex);
+ vc4_setup_shared_key(vc4, &key->base, &vc4->fragtex);
key->base.shader_state = vc4->prog.bind_fs;
key->is_points = (prim_mode == PIPE_PRIM_POINTS);
key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
@@ -2026,7 +2099,7 @@ vc4_update_compiled_vs(struct vc4_context *vc4, uint8_t prim_mode)
}
memset(key, 0, sizeof(*key));
- vc4_setup_shared_key(&key->base, &vc4->verttex);
+ vc4_setup_shared_key(vc4, &key->base, &vc4->verttex);
key->base.shader_state = vc4->prog.bind_vs;
key->compiled_fs_id = vc4->prog.fs->program_id;
@@ -2345,6 +2418,11 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
cl_f(&vc4->uniforms, vc4->viewport.scale[2]);
break;
+ case QUNIFORM_USER_CLIP_PLANE:
+ cl_f(&vc4->uniforms,
+ vc4->clip.ucp[uinfo->data[i] / 4][uinfo->data[i] % 4]);
+ break;
+
case QUNIFORM_TEXTURE_CONFIG_P0:
write_texture_p0(vc4, texstate, uinfo->data[i]);
break;
diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c
index 432fb1bf555..9c7c15e4924 100644
--- a/src/gallium/drivers/vc4/vc4_qir.c
+++ b/src/gallium/drivers/vc4/vc4_qir.c
@@ -292,7 +292,9 @@ qir_compile_init(void)
make_empty_list(&c->instructions);
c->output_position_index = -1;
+ c->output_clipvertex_index = -1;
c->output_color_index = -1;
+ c->output_point_size_index = -1;
return c;
}
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index 0e4b78c02b6..b95dbc33d51 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -183,6 +183,8 @@ enum quniform_contents {
QUNIFORM_VIEWPORT_Z_OFFSET,
QUNIFORM_VIEWPORT_Z_SCALE,
+ QUNIFORM_USER_CLIP_PLANE,
+
/**
* A reference to a texture config parameter 0 uniform.
*
@@ -272,6 +274,7 @@ struct vc4_compile {
uint32_t num_outputs;
uint32_t num_texture_samples;
uint32_t output_position_index;
+ uint32_t output_clipvertex_index;
uint32_t output_color_index;
uint32_t output_point_size_index;
diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c
index 7ccffebe12e..099006b3e57 100644
--- a/src/gallium/drivers/vc4/vc4_state.c
+++ b/src/gallium/drivers/vc4/vc4_state.c
@@ -68,7 +68,9 @@ static void
vc4_set_clip_state(struct pipe_context *pctx,
const struct pipe_clip_state *clip)
{
- fprintf(stderr, "clip todo\n");
+ struct vc4_context *vc4 = vc4_context(pctx);
+ vc4->clip = *clip;
+ vc4->dirty |= VC4_DIRTY_CLIP;
}
static void