struct pipe_context * fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, const uint8_t *primtypes, void *priv) { struct fd_screen *screen = fd_screen(pscreen); struct pipe_context *pctx; int i; ctx->screen = screen; ctx->primtypes = primtypes; ctx->primtype_mask = 0; for (i = 0; i < PIPE_PRIM_MAX; i++) if (primtypes[i]) ctx->primtype_mask |= (1 << i); /* need some sane default in case state tracker doesn't * set some state: */ ctx->sample_mask = 0xffff; pctx = &ctx->base; pctx->screen = pscreen; pctx->priv = priv; pctx->flush = fd_context_flush; for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) { ctx->rings[i] = fd_ringbuffer_new(screen->pipe, 0x100000); if (!ctx->rings[i]) goto fail; } fd_context_next_rb(pctx); fd_reset_wfi(ctx); util_dynarray_init(&ctx->draw_patches); util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); fd_draw_init(pctx); fd_resource_context_init(pctx); fd_query_context_init(pctx); fd_texture_init(pctx); fd_state_init(pctx); ctx->blitter = util_blitter_create(pctx); if (!ctx->blitter) goto fail; ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask); if (!ctx->primconvert) goto fail; return pctx; fail: pctx->destroy(pctx); return NULL; }
struct pipe_context * fd_context_create(struct pipe_screen *pscreen, void *priv) { struct fd_screen *screen = fd_screen(pscreen); struct fd_context *ctx = CALLOC_STRUCT(fd_context); struct pipe_context *pctx; if (!ctx) return NULL; DBG(""); ctx->screen = screen; ctx->ring = fd_ringbuffer_new(screen->pipe, 0x100000); ctx->draw_start = fd_ringmarker_new(ctx->ring); ctx->draw_end = fd_ringmarker_new(ctx->ring); pctx = &ctx->base; pctx->screen = pscreen; pctx->priv = priv; pctx->flush = fd_context_flush; pctx->destroy = fd_context_destroy; util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); fd_vbo_init(pctx); fd_blend_init(pctx); fd_rasterizer_init(pctx); fd_zsa_init(pctx); fd_state_init(pctx); fd_resource_context_init(pctx); fd_clear_init(pctx); fd_prog_init(pctx); fd_texture_init(pctx); ctx->blitter = util_blitter_create(pctx); if (!ctx->blitter) { fd_context_destroy(pctx); return NULL; } /* construct vertex state used for solid ops (clear, and gmem<->mem) */ ctx->solid_vertexbuf = create_solid_vertexbuf(pctx); fd_state_emit_setup(pctx); return pctx; }
struct pipe_context * fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, void *priv) { struct fd_screen *screen = fd_screen(pscreen); struct pipe_context *pctx; ctx->screen = screen; /* need some sane default in case state tracker doesn't * set some state: */ ctx->sample_mask = 0xffff; pctx = &ctx->base; pctx->screen = pscreen; pctx->priv = priv; pctx->flush = fd_context_flush; ctx->ring = fd_ringbuffer_new(screen->pipe, 0x100000); if (!ctx->ring) goto fail; ctx->draw_start = fd_ringmarker_new(ctx->ring); ctx->draw_end = fd_ringmarker_new(ctx->ring); util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); fd_draw_init(pctx); fd_resource_context_init(pctx); fd_texture_init(pctx); fd_state_init(pctx); ctx->blitter = util_blitter_create(pctx); if (!ctx->blitter) goto fail; return pctx; fail: pctx->destroy(pctx); return NULL; }
void next_ring(void) { int idx = ring_idx++ % ARRAY_SIZE(rings); if (rings[idx]) { ring = rings[idx]; fd_ringbuffer_reset(ring); return; } ring = rings[idx] = fd_ringbuffer_new(pipe, 0x5000); memcpy(ring->start, initial_state, STATE_SIZE * sizeof(uint32_t)); ring->cur = &ring->start[120]; OUT_RELOC (ring, context_bos[0]); ring->cur = &ring->start[122]; OUT_RELOC (ring, context_bos[1]); ring->cur = &ring->start[124]; OUT_RELOC (ring, context_bos[2]); fd_ringbuffer_reset(ring); }
static void fd6_clear_lrz(struct fd_batch *batch, struct fd_resource *zsbuf, double depth) { struct fd_ringbuffer *ring; // TODO mid-frame clears (ie. app doing crazy stuff)?? Maybe worth // splitting both clear and lrz clear out into their own rb's. And // just throw away any draws prior to clear. (Anything not fullscreen // clear, just fallback to generic path that treats it as a normal // draw if (!batch->lrz_clear) { batch->lrz_clear = fd_ringbuffer_new(batch->ctx->pipe, 0x1000); fd_ringbuffer_set_parent(batch->lrz_clear, batch->gmem); } ring = batch->lrz_clear; emit_marker6(ring, 7); OUT_PKT7(ring, CP_SET_MARKER, 1); OUT_RING(ring, A2XX_CP_SET_MARKER_0_MODE(RM6_BYPASS)); emit_marker6(ring, 7); OUT_PKT4(ring, REG_A6XX_RB_CCU_CNTL, 1); OUT_RING(ring, 0x10000000); OUT_PKT4(ring, REG_A6XX_HLSQ_UPDATE_CNTL, 1); OUT_RING(ring, 0x7ffff); emit_marker6(ring, 7); OUT_PKT7(ring, CP_SET_MARKER, 1); OUT_RING(ring, A2XX_CP_SET_MARKER_0_MODE(0xc)); emit_marker6(ring, 7); OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1); OUT_RING(ring, 0x0); OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_PKT4(ring, REG_A6XX_SP_UNKNOWN_ACC0, 1); OUT_RING(ring, 0x0000f410); OUT_PKT4(ring, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); OUT_RING(ring, A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT(RB6_R16_UNORM) | 0x4f00080); OUT_PKT4(ring, REG_A6XX_RB_2D_BLIT_CNTL, 1); OUT_RING(ring, A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(RB6_R16_UNORM) | 0x4f00080); fd6_event_write(batch, ring, UNK_1D, true); fd6_event_write(batch, ring, PC_CCU_INVALIDATE_COLOR, false); OUT_PKT4(ring, REG_A6XX_RB_2D_SRC_SOLID_C0, 4); OUT_RING(ring, fui(depth)); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9); OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(RB6_R16_UNORM) | A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) | A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX)); OUT_RELOCW(ring, zsbuf->lrz, 0, 0, 0); OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(zsbuf->lrz_pitch * 2)); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_PKT4(ring, REG_A6XX_GRAS_2D_SRC_TL_X, 4); OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_X_X(0)); OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_X_X(0)); OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_Y_Y(0)); OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_Y_Y(0)); OUT_PKT4(ring, REG_A6XX_GRAS_2D_DST_TL, 2); OUT_RING(ring, A6XX_GRAS_2D_DST_TL_X(0) | A6XX_GRAS_2D_DST_TL_Y(0)); OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(zsbuf->lrz_width - 1) | A6XX_GRAS_2D_DST_BR_Y(zsbuf->lrz_height - 1)); fd6_event_write(batch, ring, 0x3f, false); OUT_WFI5(ring); OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); OUT_RING(ring, 0x1000000); OUT_PKT7(ring, CP_BLIT, 1); OUT_RING(ring, CP_BLIT_0_OP(BLIT_OP_SCALE)); OUT_WFI5(ring); OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); OUT_RING(ring, 0x0); fd6_event_write(batch, ring, UNK_1D, true); fd6_event_write(batch, ring, FACENESS_FLUSH, true); fd6_event_write(batch, ring, CACHE_FLUSH_TS, true); fd6_cache_flush(batch, ring); }
int main(int argc, char *argv[]) { struct fd_device *dev; struct fd_pipe *pipe; struct fd_ringbuffer *ring; struct fd_bo *bo; uint32_t i = 0; uint32_t *ptr; int fd, ret; fd = drmOpen("msm", NULL); if (fd < 0) { printf("failed to initialize DRM\n"); return fd; } dev = fd_device_new(fd); if (!dev) { printf("failed to initialize freedreno device\n"); return -1; } pipe = fd_pipe_new(dev, FD_PIPE_3D); if (!pipe) { printf("failed to initialize freedreno pipe\n"); return -1; } ring = fd_ringbuffer_new(pipe, 4096); if (!ring) { printf("failed to initialize freedreno ring\n"); return -1; } bo = fd_bo_new(dev, 4096, 0); #define BASE REG_A3XX_GRAS_CL_VPORT_XOFFSET #define SIZE 6 OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG4, 1); OUT_RING(ring, 0x123); OUT_PKT0(ring, BASE, SIZE); for (i = 0; i < SIZE; i++) OUT_RING(ring, i); /* this adds the value of CP_SCRATCH_REG4 to 0x111 and writes * to REG_BASE+2 */ OUT_PKT3(ring, CP_SET_CONSTANT, 3); OUT_RING(ring, 0x80000000 | CP_REG(BASE + 2)); OUT_RING(ring, REG_AXXX_CP_SCRATCH_REG4); OUT_RING(ring, 0x111); /* read back all the regs: */ for (i = 0; i < SIZE; i++) { OUT_PKT3(ring, CP_REG_TO_MEM, 2); OUT_RING(ring, BASE + i); OUT_RELOCW(ring, bo, i * 4, 0, 0); } fd_ringbuffer_flush(ring); /* and read back the values: */ fd_bo_cpu_prep(bo, pipe, DRM_FREEDRENO_PREP_READ); ptr = fd_bo_map(bo); for (i = 0; i < SIZE; i++) { printf("%02x: %08x\n", i, ptr[i]); } fd_bo_cpu_fini(bo); return 0; }