summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-01-14 13:03:20 -0500
committerRob Clark <[email protected]>2014-02-01 11:58:47 -0500
commit8d27be2633f2fc543a6d00d66dcb033798d44749 (patch)
treebefce651ebc7876dd24cf1943a8dc27f4231b51f /src/gallium
parent083b27a1b125ac286e3d3ae0b42dab4cf773a40f (diff)
freedreno/a3xx: handle frag z write
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_compiler.c9
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_draw.c15
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c38
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.h2
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c11
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c2
7 files changed, 53 insertions, 25 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
index c8e66fc76dd..2c32c0fa2a7 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
@@ -1341,6 +1341,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
struct fd3_shader_stateobj *so = ctx->so;
unsigned base = ctx->base_reg[TGSI_FILE_OUTPUT];
+ unsigned comp = 0;
unsigned name = decl->Semantic.Name;
unsigned i;
@@ -1351,6 +1352,8 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
if (ctx->type == TGSI_PROCESSOR_VERTEX) {
switch (name) {
case TGSI_SEMANTIC_POSITION:
+ so->writes_pos = true;
+ /* fallthrough */
case TGSI_SEMANTIC_PSIZE:
case TGSI_SEMANTIC_COLOR:
case TGSI_SEMANTIC_GENERIC:
@@ -1363,6 +1366,10 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
}
} else {
switch (name) {
+ case TGSI_SEMANTIC_POSITION:
+ comp = 2; /* tgsi will write to .z component */
+ so->writes_pos = true;
+ /* fallthrough */
case TGSI_SEMANTIC_COLOR:
break;
default:
@@ -1374,7 +1381,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
for (i = decl->Range.First; i <= decl->Range.Last; i++) {
unsigned n = so->outputs_count++;
so->outputs[n].semantic = decl_semantic(&decl->Semantic);
- so->outputs[n].regid = regid(i + base, 0);
+ so->outputs[n].regid = regid(i + base, comp);
}
}
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index 4f28b0e0608..a482aec3dec 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -70,7 +70,7 @@ static void
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
struct fd_ringbuffer *ring, unsigned dirty, bool binning)
{
- fd3_emit_state(ctx, ring, dirty, binning);
+ fd3_emit_state(ctx, ring, &ctx->prog, dirty, binning);
if (dirty & FD_DIRTY_VTXBUF)
emit_vertexbufs(ctx, ring);
@@ -114,10 +114,7 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
struct fd3_context *fd3_ctx = fd3_context(ctx);
struct fd_ringbuffer *ring = ctx->binning_ring;
- fd3_emit_state(ctx, ring, dirty & (FD_DIRTY_VIEWPORT |
- FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR), true);
-
- fd3_program_emit(ring, &ctx->solid_prog, true);
+ fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, true);
fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
{ .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
@@ -152,11 +149,13 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
unsigned dirty = ctx->dirty;
unsigned ce, i;
+ dirty &= FD_DIRTY_VIEWPORT | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
+ dirty |= FD_DIRTY_PROG;
+
fd3_clear_binning(ctx, dirty);
/* emit generic state now: */
- fd3_emit_state(ctx, ring, dirty & (FD_DIRTY_VIEWPORT |
- FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR), false);
+ fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, false);
OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
@@ -246,8 +245,6 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
- fd3_program_emit(ring, &ctx->solid_prog, false);
-
fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
{ .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
}, 1);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 543c116ce2f..3ca49ff949b 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -338,7 +338,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
void
fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
- uint32_t dirty, bool binning)
+ struct fd_program_stateobj *prog, uint32_t dirty, bool binning)
{
emit_marker(ring, 5);
@@ -370,9 +370,6 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_PKT0(ring, REG_A3XX_RB_ALPHA_REF, 1);
OUT_RING(ring, zsa->rb_alpha_ref);
- OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
- OUT_RING(ring, zsa->rb_depth_control);
-
OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
OUT_RING(ring, zsa->rb_stencil_control);
@@ -383,6 +380,17 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
A3XX_RB_STENCILREFMASK_BF_STENCILREF(sr->ref_value[1]));
}
+ if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) {
+ struct fd3_shader_stateobj *fp = prog->fp;
+ uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_depth_control;
+ if (fp->writes_pos) {
+ val |= A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z;
+ val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE;
+ }
+ OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
+ OUT_RING(ring, val);
+ }
+
if (dirty & FD_DIRTY_RASTERIZER) {
struct fd3_rasterizer_stateobj *rasterizer =
fd3_rasterizer_stateobj(ctx->rasterizer);
@@ -397,15 +405,23 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_PKT0(ring, REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE, 2);
OUT_RING(ring, rasterizer->gras_su_poly_offset_scale);
OUT_RING(ring, rasterizer->gras_su_poly_offset_offset);
+ }
+ if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
+ struct fd3_shader_stateobj *fp = prog->fp;
+ uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
+ ->gras_cl_clip_cntl;
+ if (fp->writes_pos) {
+ val |= A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE;
+ }
OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
- OUT_RING(ring, rasterizer->gras_cl_clip_cntl);
+ OUT_RING(ring, val);
}
if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
struct fd3_rasterizer_stateobj *rasterizer =
fd3_rasterizer_stateobj(ctx->rasterizer);
- struct fd3_shader_stateobj *fp = ctx->prog.fp;
+ struct fd3_shader_stateobj *fp = prog->fp;
uint32_t stride_in_vpc;
stride_in_vpc = align(fp->total_in, 4) / 4;
@@ -443,14 +459,14 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
}
if (dirty & FD_DIRTY_PROG)
- fd3_program_emit(ring, &ctx->prog, binning);
+ fd3_program_emit(ring, prog, binning);
OUT_PKT3(ring, CP_EVENT_WRITE, 1);
OUT_RING(ring, HLSQ_FLUSH);
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
- struct fd_program_stateobj *prog = &ctx->prog;
-
+ if ((dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) &&
+ /* evil hack to deal sanely with clear path: */
+ (prog == &ctx->prog)) {
emit_constants(ring, SB_VERT_SHADER,
&ctx->constbuf[PIPE_SHADER_VERTEX],
(prog->dirty & FD_SHADER_DIRTY_VP) ? prog->vp : NULL);
@@ -459,7 +475,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
(prog->dirty & FD_SHADER_DIRTY_FP) ? prog->fp : NULL);
}
- if (dirty & FD_DIRTY_BLEND) {
+ if ((dirty & FD_DIRTY_BLEND) && ctx->blend) {
struct fd3_blend_stateobj *blend = fd3_blend_stateobj(ctx->blend);
uint32_t i;
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
index 1b4774d83f9..8584eb5b59b 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
@@ -59,7 +59,7 @@ void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
struct fd_program_stateobj *prog,
struct fd3_vertex_buf *vbufs, uint32_t n);
void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
- uint32_t dirty, bool binning);
+ struct fd_program_stateobj *prog, uint32_t dirty, bool binning);
void fd3_emit_restore(struct fd_context *ctx);
#endif /* FD3_EMIT_H */
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 2d95583666d..3df29ecc911 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -247,7 +247,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
const struct fd3_shader_stateobj *fp = prog->fp;
const struct ir3_shader_info *vsi = &vp->info;
const struct ir3_shader_info *fsi = &fp->info;
- uint32_t pos_regid, psize_regid, color_regid;
+ uint32_t pos_regid, posz_regid, psize_regid, color_regid;
int i;
if (binning) {
@@ -259,6 +259,8 @@ fd3_program_emit(struct fd_ringbuffer *ring,
pos_regid = find_regid(vp,
fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
+ posz_regid = find_regid(fp,
+ fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
psize_regid = find_regid(vp,
fd3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
color_regid = find_regid(fp,
@@ -389,7 +391,12 @@ fd3_program_emit(struct fd_ringbuffer *ring,
OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_1 */
OUT_PKT0(ring, REG_A3XX_SP_FS_OUTPUT_REG, 1);
- OUT_RING(ring, 0x00000000); /* SP_FS_OUTPUT_REG */
+ if (fp->writes_pos) {
+ OUT_RING(ring, A3XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE |
+ A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID(posz_regid));
+ } else {
+ OUT_RING(ring, 0x00000000);
+ }
OUT_PKT0(ring, REG_A3XX_SP_FS_MRT_REG(0), 4);
OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(color_regid) |
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.h b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
index e7aaa476316..4aeeb2e3006 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.h
@@ -81,6 +81,7 @@ struct fd3_shader_stateobj {
fd3_semantic semantic;
uint8_t regid;
} outputs[16];
+ bool writes_pos;
/* vertices/inputs: */
unsigned inputs_count;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index f36bd8be0cd..d6d3c6c3fd9 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -153,7 +153,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_TEXTURE_SWIZZLE:
- case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
@@ -176,6 +175,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+ case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_TGSI_TEXCOORD:
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
return 0;