static void fd4_clear(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { struct fd4_context *fd4_ctx = fd4_context(ctx); struct fd_ringbuffer *ring = ctx->ring; struct pipe_framebuffer_state *pfb = &ctx->framebuffer; unsigned dirty = ctx->dirty; unsigned ce, i; struct fd4_emit emit = { .vtx = &fd4_ctx->solid_vbuf_state, .prog = &ctx->solid_prog, .key = { .half_precision = true, }, }; uint32_t colr = 0; if ((buffers & PIPE_CLEAR_COLOR) && pfb->nr_cbufs) colr = pack_rgba(pfb->cbufs[0]->format, color->f); dirty &= FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR; dirty |= FD_DIRTY_PROG; emit.dirty = dirty; OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1); OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST); /* emit generic state now: */ fd4_emit_state(ctx, ring, &emit); reset_viewport(ring, pfb); if (buffers & PIPE_CLEAR_DEPTH) { OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1); OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE | A4XX_RB_DEPTH_CONTROL_Z_ENABLE | A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS)); fd_wfi(ctx, ring); OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_ZOFFSET_0, 2); OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(depth)); ctx->dirty |= FD_DIRTY_VIEWPORT; } else { OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1); OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER)); } if (buffers & PIPE_CLEAR_STENCIL) { OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2); OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(stencil) | A4XX_RB_STENCILREFMASK_STENCILMASK(stencil) | A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff)); OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) | A4XX_RB_STENCILREFMASK_STENCILMASK(0) | 0xff000000 | // XXX ??? A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff)); OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2); OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE | A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) | A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_REPLACE) | A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) | A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP)); OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */ } else { OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2); OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) | A4XX_RB_STENCILREFMASK_STENCILMASK(0) | A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0)); OUT_RING(ring, A4XX_RB_STENCILREFMASK_BF_STENCILREF(0) | A4XX_RB_STENCILREFMASK_BF_STENCILMASK(0) | A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0)); OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2); OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) | A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) | A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) | A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP)); OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */ } if (buffers & PIPE_CLEAR_COLOR) { OUT_PKT0(ring, REG_A4XX_RB_ALPHA_CONTROL, 1); OUT_RING(ring, A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER)); ce = 0xf; } else { ce = 0x0; } for (i = 0; i < 8; i++) { OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1); OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR | A4XX_RB_MRT_CONTROL_B11 | A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(ce)); OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1); OUT_RING(ring, A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) | A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) | A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) | A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) | A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) | A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO)); } fd4_emit_vertex_bufs(ring, &emit); OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1); OUT_RING(ring, 0x0); /* XXX GRAS_ALPHA_CONTROL */ OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_RB_CLEAR_COLOR_DW0, 4); OUT_RING(ring, colr); /* RB_CLEAR_COLOR_DW0 */ OUT_RING(ring, colr); /* RB_CLEAR_COLOR_DW1 */ OUT_RING(ring, colr); /* RB_CLEAR_COLOR_DW2 */ OUT_RING(ring, colr); /* RB_CLEAR_COLOR_DW3 */ /* until fastclear works: */ fd4_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL); OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2); OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */ OUT_RING(ring, 0); /* ??? UNKNOWN_2209 */ OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1); OUT_RING(ring, 0xffffffff); /* PC_RESTART_INDEX */ OUT_PKT3(ring, CP_UNKNOWN_1A, 1); OUT_RING(ring, 0x00000001); fd4_draw(ctx, ring, DI_PT_RECTLIST, USE_VISIBILITY, DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL); OUT_PKT3(ring, CP_UNKNOWN_1A, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1); OUT_RING(ring, A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR); OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1); OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | A4XX_GRAS_SC_CONTROL_MSAA_DISABLE | A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | A4XX_GRAS_SC_CONTROL_RASTER_MODE(0)); }
/* emit setup at begin of new cmdstream buffer (don't rely on previous * state, there could have been a context switch between ioctls): */ void fd4_emit_restore(struct fd_context *ctx) { struct fd4_context *fd4_ctx = fd4_context(ctx); struct fd_ringbuffer *ring = ctx->ring; OUT_PKT0(ring, REG_A4XX_RBBM_PERFCTR_CTL, 1); OUT_RING(ring, 0x00000001); OUT_PKT0(ring, REG_A4XX_GRAS_DEBUG_ECO_CONTROL, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0EC3, 1); OUT_RING(ring, 0x00000006); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0F03, 1); OUT_RING(ring, 0x0000003a); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0D01, 1); OUT_RING(ring, 0x00000001); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0E42, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UCHE_CACHE_WAYS_VFD, 1); OUT_RING(ring, 0x00000007); OUT_PKT0(ring, REG_A4XX_UCHE_CACHE_MODE_CONTROL, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UCHE_INVALIDATE0, 2); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000012); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0E05, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0CC5, 1); OUT_RING(ring, 0x00000006); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0CC6, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_0EC2, 1); OUT_RING(ring, 0x00040000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2001, 1); OUT_RING(ring, 0x00000000); OUT_PKT3(ring, CP_INVALIDATE_STATE, 1); OUT_RING(ring, 0x00001000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_20EF, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_20F0, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_20F1, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_20F2, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_RB_BLEND_RED, 4); OUT_RING(ring, A4XX_RB_BLEND_RED_UINT(0) | A4XX_RB_BLEND_RED_FLOAT(0.0)); OUT_RING(ring, A4XX_RB_BLEND_GREEN_UINT(0) | A4XX_RB_BLEND_GREEN_FLOAT(0.0)); OUT_RING(ring, A4XX_RB_BLEND_BLUE_UINT(0) | A4XX_RB_BLEND_BLUE_FLOAT(0.0)); OUT_RING(ring, A4XX_RB_BLEND_ALPHA_UINT(0x7fff) | A4XX_RB_BLEND_ALPHA_FLOAT(1.0)); OUT_PKT0(ring, REG_A4XX_UNKNOWN_20F7, 1); OUT_RING(ring, 0x3f800000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2152, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2153, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2154, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2155, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2156, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_2157, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_21C3, 1); OUT_RING(ring, 0x0000001d); OUT_PKT0(ring, REG_A4XX_PC_GS_PARAM, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_21E6, 1); OUT_RING(ring, 0x00000001); OUT_PKT0(ring, REG_A4XX_PC_HS_PARAM, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_UNKNOWN_22D7, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_TPL1_TP_TEX_OFFSET, 1); OUT_RING(ring, 0x00000000); OUT_PKT0(ring, REG_A4XX_TPL1_TP_TEX_COUNT, 1); OUT_RING(ring, A4XX_TPL1_TP_TEX_COUNT_VS(16) | A4XX_TPL1_TP_TEX_COUNT_HS(0) | A4XX_TPL1_TP_TEX_COUNT_DS(0) | A4XX_TPL1_TP_TEX_COUNT_GS(0)); OUT_PKT0(ring, REG_A4XX_TPL1_TP_FS_TEX_COUNT, 1); OUT_RING(ring, 16); /* we don't use this yet.. probably best to disable.. */ OUT_PKT3(ring, CP_SET_DRAW_STATE, 2); OUT_RING(ring, CP_SET_DRAW_STATE_0_COUNT(0) | CP_SET_DRAW_STATE_0_DISABLE_ALL_GROUPS | CP_SET_DRAW_STATE_0_GROUP_ID(0)); OUT_RING(ring, CP_SET_DRAW_STATE_1_ADDR(0)); OUT_PKT0(ring, REG_A4XX_SP_VS_PVT_MEM_PARAM, 2); OUT_RING(ring, 0x08000001); /* SP_VS_PVT_MEM_PARAM */ OUT_RELOC(ring, fd4_ctx->vs_pvt_mem, 0,0,0); /* SP_VS_PVT_MEM_ADDR */ OUT_PKT0(ring, REG_A4XX_SP_FS_PVT_MEM_PARAM, 2); OUT_RING(ring, 0x08000001); /* SP_FS_PVT_MEM_PARAM */ OUT_RELOC(ring, fd4_ctx->fs_pvt_mem, 0,0,0); /* SP_FS_PVT_MEM_ADDR */ OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1); OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | A4XX_GRAS_SC_CONTROL_MSAA_DISABLE | A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | A4XX_GRAS_SC_CONTROL_RASTER_MODE(0)); OUT_PKT0(ring, REG_A4XX_RB_MSAA_CONTROL, 1); OUT_RING(ring, A4XX_RB_MSAA_CONTROL_DISABLE | A4XX_RB_MSAA_CONTROL_SAMPLES(MSAA_ONE)); OUT_PKT0(ring, REG_A4XX_GRAS_CL_GB_CLIP_ADJ, 1); OUT_RING(ring, A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ(0) | A4XX_GRAS_CL_GB_CLIP_ADJ_VERT(0)); OUT_PKT0(ring, REG_A4XX_RB_ALPHA_CONTROL, 1); OUT_RING(ring, A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS)); OUT_PKT0(ring, REG_A4XX_RB_FS_OUTPUT, 1); OUT_RING(ring, A4XX_RB_FS_OUTPUT_SAMPLE_MASK(0xffff)); OUT_PKT0(ring, REG_A4XX_RB_RENDER_COMPONENTS, 1); OUT_RING(ring, A4XX_RB_RENDER_COMPONENTS_RT0(0xf)); OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1); OUT_RING(ring, A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR); OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1); OUT_RING(ring, 0x0); ctx->needs_rb_fbd = true; }
void * fd4_zsa_state_create(struct pipe_context *pctx, const struct pipe_depth_stencil_alpha_state *cso) { struct fd4_zsa_stateobj *so; so = CALLOC_STRUCT(fd4_zsa_stateobj); if (!so) return NULL; so->base = *cso; so->rb_depth_control |= A4XX_RB_DEPTH_CONTROL_ZFUNC(cso->depth.func); /* maps 1:1 */ if (cso->depth.enabled) so->rb_depth_control |= A4XX_RB_DEPTH_CONTROL_Z_ENABLE | A4XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE; if (cso->depth.writemask) so->rb_depth_control |= A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE; if (cso->stencil[0].enabled) { const struct pipe_stencil_state *s = &cso->stencil[0]; so->rb_stencil_control |= A4XX_RB_STENCIL_CONTROL_STENCIL_READ | A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE | A4XX_RB_STENCIL_CONTROL_FUNC(s->func) | /* maps 1:1 */ A4XX_RB_STENCIL_CONTROL_FAIL(fd_stencil_op(s->fail_op)) | A4XX_RB_STENCIL_CONTROL_ZPASS(fd_stencil_op(s->zpass_op)) | A4XX_RB_STENCIL_CONTROL_ZFAIL(fd_stencil_op(s->zfail_op)); so->rb_stencil_control2 |= A4XX_RB_STENCIL_CONTROL2_STENCIL_BUFFER; so->rb_stencilrefmask |= 0xff000000 | /* ??? */ A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(s->writemask) | A4XX_RB_STENCILREFMASK_STENCILMASK(s->valuemask); if (cso->stencil[1].enabled) { const struct pipe_stencil_state *bs = &cso->stencil[1]; so->rb_stencil_control |= A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF | A4XX_RB_STENCIL_CONTROL_FUNC_BF(bs->func) | /* maps 1:1 */ A4XX_RB_STENCIL_CONTROL_FAIL_BF(fd_stencil_op(bs->fail_op)) | A4XX_RB_STENCIL_CONTROL_ZPASS_BF(fd_stencil_op(bs->zpass_op)) | A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(fd_stencil_op(bs->zfail_op)); so->rb_stencilrefmask_bf |= 0xff000000 | /* ??? */ A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(bs->writemask) | A4XX_RB_STENCILREFMASK_BF_STENCILMASK(bs->valuemask); } } if (cso->alpha.enabled) { uint32_t ref = cso->alpha.ref_value * 255.0; so->gras_alpha_control = A4XX_GRAS_ALPHA_CONTROL_ALPHA_TEST_ENABLE; so->rb_alpha_control = A4XX_RB_ALPHA_CONTROL_ALPHA_TEST | A4XX_RB_ALPHA_CONTROL_ALPHA_REF(ref) | A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(cso->alpha.func); so->rb_depth_control |= A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE; } return so; }