/* 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; }
static void fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) { struct fd4_context *fd4_ctx = fd4_context(ctx); struct fd_gmem_stateobj *gmem = &ctx->gmem; struct fd_ringbuffer *ring = ctx->ring; struct pipe_framebuffer_state *pfb = &ctx->framebuffer; struct fd4_emit emit = { .vtx = &fd4_ctx->blit_vbuf_state, .sprite_coord_enable = 1, /* NOTE: They all use the same VP, this is for vtx bufs. */ .prog = &ctx->blit_prog[0], .key = { .half_precision = fd_half_precision(pfb), }, .no_decode_srgb = true, }; unsigned char mrt_comp[A4XX_MAX_RENDER_TARGETS] = {0}; float x0, y0, x1, y1; unsigned bin_w = tile->bin_w; unsigned bin_h = tile->bin_h; unsigned i; /* write texture coordinates to vertexbuf: */ x0 = ((float)tile->xoff) / ((float)pfb->width); x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width); y0 = ((float)tile->yoff) / ((float)pfb->height); y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height); OUT_PKT3(ring, CP_MEM_WRITE, 5); OUT_RELOCW(ring, fd_resource(fd4_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0); OUT_RING(ring, fui(x0)); OUT_RING(ring, fui(y0)); OUT_RING(ring, fui(x1)); OUT_RING(ring, fui(y1)); for (i = 0; i < A4XX_MAX_RENDER_TARGETS; i++) { mrt_comp[i] = ((i < pfb->nr_cbufs) && pfb->cbufs[i]) ? 0xf : 0; 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(0xf)); 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)); } OUT_PKT0(ring, REG_A4XX_RB_RENDER_COMPONENTS, 1); OUT_RING(ring, A4XX_RB_RENDER_COMPONENTS_RT0(mrt_comp[0]) | A4XX_RB_RENDER_COMPONENTS_RT1(mrt_comp[1]) | A4XX_RB_RENDER_COMPONENTS_RT2(mrt_comp[2]) | A4XX_RB_RENDER_COMPONENTS_RT3(mrt_comp[3]) | A4XX_RB_RENDER_COMPONENTS_RT4(mrt_comp[4]) | A4XX_RB_RENDER_COMPONENTS_RT5(mrt_comp[5]) | A4XX_RB_RENDER_COMPONENTS_RT6(mrt_comp[6]) | A4XX_RB_RENDER_COMPONENTS_RT7(mrt_comp[7])); OUT_PKT0(ring, REG_A4XX_RB_RENDER_CONTROL, 1); OUT_RING(ring, 0x8); /* XXX RB_RENDER_CONTROL */ OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1); OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS)); OUT_PKT0(ring, REG_A4XX_GRAS_CL_CLIP_CNTL, 1); OUT_RING(ring, 0x280000); /* XXX GRAS_CL_CLIP_CNTL */ OUT_PKT0(ring, REG_A4XX_GRAS_SU_MODE_CONTROL, 1); OUT_RING(ring, A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0) | A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS); OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_XOFFSET_0, 6); OUT_RING(ring, A4XX_GRAS_CL_VPORT_XOFFSET_0((float)bin_w/2.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_XSCALE_0((float)bin_w/2.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_YOFFSET_0((float)bin_h/2.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_YSCALE_0(-(float)bin_h/2.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0)); OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(1.0)); OUT_PKT0(ring, REG_A4XX_GRAS_SC_WINDOW_SCISSOR_BR, 2); OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) | A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1)); OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) | A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0)); OUT_PKT0(ring, REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL, 2); OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) | A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0)); OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) | A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1)); OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1); OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(gmem->bin_w) | A4XX_RB_MODE_CONTROL_HEIGHT(gmem->bin_h)); OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2); OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) | 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_ALWAYS) | 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 */ 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(1)); OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1); OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST | A4XX_PC_PRIM_VTX_CNTL_VAROUT(1)); OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2); OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */ OUT_RING(ring, 0); /* ??? UNKNOWN_2209 */ fd4_emit_vertex_bufs(ring, &emit); /* for gmem pitch/base calculations, we need to use the non- * truncated tile sizes: */ bin_w = gmem->bin_w; bin_h = gmem->bin_h; if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR)) { emit.prog = &ctx->blit_prog[pfb->nr_cbufs - 1]; emit.fp = NULL; /* frag shader changed so clear cache */ fd4_program_emit(ring, &emit, pfb->nr_cbufs, pfb->cbufs); emit_mem2gmem_surf(ctx, gmem->cbuf_base, pfb->cbufs, pfb->nr_cbufs, bin_w); } if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { switch (pfb->zsbuf->format) { case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: case PIPE_FORMAT_Z32_FLOAT: emit.prog = (pfb->zsbuf->format == PIPE_FORMAT_Z32_FLOAT) ? &ctx->blit_z : &ctx->blit_zs; emit.key.half_precision = false; OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1); OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_Z_ENABLE | A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE | A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS) | A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE); OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1); OUT_RING(ring, A4XX_GRAS_ALPHA_CONTROL_ALPHA_TEST_ENABLE); OUT_PKT0(ring, REG_A4XX_GRAS_CL_CLIP_CNTL, 1); OUT_RING(ring, 0x80000); /* GRAS_CL_CLIP_CNTL */ break; default: /* Non-float can use a regular color write. It's split over 8-bit * components, so half precision is always sufficient. */ emit.prog = &ctx->blit_prog[0]; emit.key.half_precision = true; break; } emit.fp = NULL; /* frag shader changed so clear cache */ fd4_program_emit(ring, &emit, 1, &pfb->zsbuf); emit_mem2gmem_surf(ctx, gmem->zsbuf_base, &pfb->zsbuf, 1, bin_w); } 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_SAMPLES(MSAA_ONE) | A4XX_GRAS_SC_CONTROL_RASTER_MODE(0)); OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1); OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(gmem->bin_w) | A4XX_RB_MODE_CONTROL_HEIGHT(gmem->bin_h) | 0x00010000); /* XXX */ }