.sprite_coord_mode = ctx->rasterizer->sprite_coord_mode,
};
+ if (fd3_needs_manual_clipping(ctx->prog.vp, ctx->rasterizer))
+ emit.key.ucp_enables = ctx->rasterizer->clip_plane_enable;
+
fixup_shader_state(ctx, &emit.key);
unsigned dirty = ctx->dirty;
if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
->gras_cl_clip_cntl;
+ uint8_t planes = ctx->rasterizer->clip_plane_enable;
val |= COND(fp->writes_pos, A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE);
val |= COND(fp->frag_coord, A3XX_GRAS_CL_CLIP_CNTL_ZCOORD |
A3XX_GRAS_CL_CLIP_CNTL_WCOORD);
- /* TODO only use if prog doesn't use clipvertex/clipdist */
- val |= A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES(
- MIN2(util_bitcount(ctx->rasterizer->clip_plane_enable), 6));
+ if (!emit->key.ucp_enables)
+ val |= A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES(
+ MIN2(util_bitcount(planes), 6));
OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
OUT_RING(ring, val);
}
- if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_UCP)) {
+ if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG | FD_DIRTY_UCP)) {
uint32_t planes = ctx->rasterizer->clip_plane_enable;
int count = 0;
+ if (emit->key.ucp_enables)
+ planes = 0;
+
while (planes && count < 6) {
int i = ffs(planes) - 1;
#include "pipe/p_state.h"
#include "util/u_string.h"
+#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
delete_shader_stateobj(so);
}
+bool
+fd3_needs_manual_clipping(const struct fd3_shader_stateobj *so,
+ const struct pipe_rasterizer_state *rast)
+{
+ uint64_t outputs = ir3_shader_outputs(so->shader);
+
+ return (!rast->depth_clip ||
+ util_bitcount(rast->clip_plane_enable) > 6 ||
+ outputs & ((1ULL << VARYING_SLOT_CLIP_VERTEX) |
+ (1ULL << VARYING_SLOT_CLIP_DIST0) |
+ (1ULL << VARYING_SLOT_CLIP_DIST1)));
+}
+
+
static void
emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so)
{
void fd3_prog_init(struct pipe_context *pctx);
+bool fd3_needs_manual_clipping(const struct fd3_shader_stateobj *,
+ const struct pipe_rasterizer_state *);
+
#endif /* FD3_PROGRAM_H_ */
debug_printf("\n");
}
+uint64_t
+ir3_shader_outputs(const struct ir3_shader *so)
+{
+ return so->nir->info.outputs_written;
+}
+
/* This has to reach into the fd_context a bit more than the rest of
* ir3, but it needs to be aligned with the compiler, so both agree
* on which const regs hold what. And the logic is identical between
struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
struct ir3_shader_key key, struct pipe_debug_callback *debug);
void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin);
+uint64_t ir3_shader_outputs(const struct ir3_shader *so);
struct fd_ringbuffer;
struct fd_context;