{ .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
}, 1);
+ fd_wfi(ctx, ring);
fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
src = SS_DIRECT;
}
- /* we have this sometimes, not others.. perhaps we could be clever
- * and figure out actually when we need to invalidate cache:
- */
- OUT_PKT0(ring, REG_A3XX_UCHE_CACHE_INVALIDATE0_REG, 2);
- OUT_RING(ring, A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR(0));
- OUT_RING(ring, A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR(0) |
- A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(INVALIDATE) |
- A3XX_UCHE_CACHE_INVALIDATE1_REG_ENTIRE_CACHE);
-
OUT_PKT3(ring, CP_LOAD_STATE, 2 + sz);
OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
CP_LOAD_STATE_0_STATE_SRC(src) |
OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2]));
}
- if (dirty & FD_DIRTY_PROG)
+ if (dirty & FD_DIRTY_PROG) {
+ fd_wfi(ctx, ring);
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)) &&
/* evil hack to deal sanely with clear path: */
(prog == &ctx->prog)) {
+ fd_wfi(ctx, ring);
emit_constants(ring, SB_VERT_SHADER,
&ctx->constbuf[PIPE_SHADER_VERTEX],
(prog->dirty & FD_SHADER_DIRTY_VP) ? prog->vp : NULL);
A3XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3]));
}
+ if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX))
+ fd_wfi(ctx, ring);
+
if (dirty & FD_DIRTY_VERTTEX)
emit_textures(ring, SB_VERT_TEX, &ctx->verttex);
OUT_RING(ring, 0x00000000);
emit_cache_flush(ring);
- fd_rmw_wfi(ctx, ring);
+ fd_wfi(ctx, ring);
}
A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
+ fd_wfi(ctx, ring);
fd3_program_emit(ring, &ctx->solid_prog, false);
fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
OUT_RING(ring, 2); /* NumIndices */
OUT_RING(ring, 2);
OUT_RING(ring, 1);
+ fd_reset_wfi(ctx);
OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 1);
OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(TWO_QUADS));
OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
OUT_RING(ring, 0x00000000);
- OUT_WFI(ring);
-
+ fd_wfi(ctx, ring);
OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
+ fd_wfi(ctx, ring);
fd3_program_emit(ring, &ctx->solid_prog, false);
fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
emit_mrt(ring, 1, &psurf, &base, bin_w);
+ fd_wfi(ctx, ring);
fd3_emit_gmem_restore_tex(ring, psurf);
fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
+ fd_wfi(ctx, ring);
fd3_program_emit(ring, &ctx->blit_prog, false);
fd3_emit_vertex_bufs(ring, &ctx->blit_prog, (struct fd3_vertex_buf[]) {
/* emit IB to binning drawcmds: */
OUT_IB(ring, ctx->binning_start, ctx->binning_end);
+ fd_reset_wfi(ctx);
+
+ fd_wfi(ctx, ring);
/* and then put stuff back the way it was: */
OUT_RING(ring, DRAW(1, DI_SRC_SEL_AUTO_INDEX,
INDEX_SIZE_IGN, IGNORE_VISIBILITY));
OUT_RING(ring, 0); /* NumIndices */
+ fd_reset_wfi(ctx);
}
OUT_PKT3(ring, CP_NOP, 4);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
- OUT_WFI(ring);
+ fd_wfi(ctx, ring);
if (ctx->screen->gpu_id == 320) {
emit_binning_workaround(ctx);
}
fd_context_next_rb(pctx);
- fd_reset_rmw_state(ctx);
+ fd_reset_wfi(ctx);
util_dynarray_init(&ctx->draw_patches);
/* Keep track if WAIT_FOR_IDLE is needed for registers we need
* to update via RMW:
*/
- bool rmw_needs_wfi;
+ bool needs_wfi;
/* Keep track of DRAW initiators that need to be patched up depending
* on whether we using binning or not:
}
static INLINE void
-fd_reset_rmw_state(struct fd_context *ctx)
+fd_reset_wfi(struct fd_context *ctx)
{
- ctx->rmw_needs_wfi = true;
+ ctx->needs_wfi = true;
}
-/* emit before a RMW a WAIT_FOR_IDLE only if needed: */
+/* emit a WAIT_FOR_IDLE only if needed, ie. if there has not already
+ * been one since last draw:
+ */
static inline void
-fd_rmw_wfi(struct fd_context *ctx, struct fd_ringbuffer *ring)
+fd_wfi(struct fd_context *ctx, struct fd_ringbuffer *ring)
{
- if (ctx->rmw_needs_wfi) {
+ if (ctx->needs_wfi) {
OUT_WFI(ring);
- ctx->rmw_needs_wfi = false;
+ ctx->needs_wfi = false;
}
}
emit_marker(ring, 7);
- ctx->rmw_needs_wfi = true;
+ fd_reset_wfi(ctx);
}
#endif /* FREEDRENO_DRAW_H_ */
/* emit IB to drawcmds: */
OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end);
+ fd_reset_wfi(ctx);
/* emit gmem2mem to transfer tile back to system memory: */
ctx->emit_tile_gmem2mem(ctx, tile);
/* emit IB to drawcmds: */
OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end);
+ fd_reset_wfi(ctx);
}
void
fd_ringmarker_mark(ctx->draw_end);
fd_ringmarker_mark(ctx->binning_end);
+ fd_reset_wfi(ctx);
+
ctx->stats.batch_total++;
if (sysmem) {
fd_ringmarker_mark(ctx->draw_start);
fd_ringmarker_mark(ctx->binning_start);
- fd_reset_rmw_state(ctx);
+ fd_reset_wfi(ctx);
/* update timestamps on render targets: */
timestamp = fd_ringbuffer_timestamp(ctx->ring);