X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Fa4xx%2Ffd4_gmem.c;h=663a49c69c88822c9cf2d8d412821186ad3cedb3;hb=2dc4d6c6921ce21ff379696f151fb18434800fee;hp=c6fbf1c1d39fd46b07fccbd0f4d81ec5feebf0de;hpb=2578e3edcb83511d46427591343369b1bdfbcaf3;p=mesa.git diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c index c6fbf1c1d39..663a49c69c8 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c @@ -1,5 +1,3 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - /* * Copyright (C) 2014 Rob Clark * @@ -79,8 +77,9 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, */ if (rsc->stencil) { rsc = rsc->stencil; - pformat = rsc->base.b.format; - bases++; + pformat = rsc->base.format; + if (bases) + bases++; } slice = fd_resource_slice(rsc, psurf->u.tex.level); @@ -131,13 +130,14 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, } static bool -use_hw_binning(struct fd_context *ctx) +use_hw_binning(struct fd_batch *batch) { - struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + struct fd_gmem_stateobj *gmem = &batch->ctx->gmem; + + if ((gmem->maxpw * gmem->maxph) > 32) + return false; - /* this seems to be a hw bug.. but this hack fixes piglit fbo-maxsize: */ - if ((pfb->width > 4096) && (pfb->height > 4096)) + if ((gmem->maxpw > 15) || (gmem->maxph > 15)) return false; return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2); @@ -146,19 +146,22 @@ use_hw_binning(struct fd_context *ctx) /* transfer from gmem to system memory (ie. normal RAM) */ static void -emit_gmem2mem_surf(struct fd_context *ctx, bool stencil, +emit_gmem2mem_surf(struct fd_batch *batch, bool stencil, uint32_t base, struct pipe_surface *psurf) { - struct fd_ringbuffer *ring = ctx->ring; + struct fd_ringbuffer *ring = batch->gmem; struct fd_resource *rsc = fd_resource(psurf->texture); enum pipe_format pformat = psurf->format; struct fd_resource_slice *slice; uint32_t offset; + if (!rsc->valid) + return; + if (stencil) { debug_assert(rsc->stencil); rsc = rsc->stencil; - pformat = rsc->base.b.format; + pformat = rsc->base.format; } slice = &rsc->slices[psurf->u.tex.level]; @@ -179,20 +182,20 @@ emit_gmem2mem_surf(struct fd_context *ctx, bool stencil, A4XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) | A4XX_RB_COPY_DEST_INFO_SWAP(fd4_pipe2swap(pformat))); - fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, - DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL); + fd4_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, + DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX4_SIZE_8_BIT, 0, 0, NULL); } static void -fd4_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile) +fd4_emit_tile_gmem2mem(struct fd_batch *batch, struct fd_tile *tile) { - struct fd4_context *fd4_ctx = fd4_context(ctx); + struct fd_context *ctx = batch->ctx; struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct fd_ringbuffer *ring = ctx->ring; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + struct fd_ringbuffer *ring = batch->gmem; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; struct fd4_emit emit = { .debug = &ctx->debug, - .vtx = &fd4_ctx->solid_vbuf_state, + .vtx = &ctx->solid_vbuf_state, .prog = &ctx->solid_prog, .key = { .half_precision = true, @@ -226,7 +229,7 @@ fd4_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile) OUT_PKT0(ring, REG_A4XX_GRAS_SU_MODE_CONTROL, 1); OUT_RING(ring, A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0)); - fd_wfi(ctx, ring); + fd_wfi(batch, ring); OUT_PKT0(ring, REG_A4XX_GRAS_CL_CLIP_CNTL, 1); OUT_RING(ring, 0x80000); /* GRAS_CL_CLIP_CNTL */ @@ -268,22 +271,22 @@ fd4_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile) fd4_program_emit(ring, &emit, 0, NULL); fd4_emit_vertex_bufs(ring, &emit); - if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { + if (batch->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture); - if (!rsc->stencil || (ctx->resolve & FD_BUFFER_DEPTH)) - emit_gmem2mem_surf(ctx, false, ctx->gmem.zsbuf_base[0], pfb->zsbuf); - if (rsc->stencil && (ctx->resolve & FD_BUFFER_STENCIL)) - emit_gmem2mem_surf(ctx, true, ctx->gmem.zsbuf_base[1], pfb->zsbuf); + if (!rsc->stencil || (batch->resolve & FD_BUFFER_DEPTH)) + emit_gmem2mem_surf(batch, false, ctx->gmem.zsbuf_base[0], pfb->zsbuf); + if (rsc->stencil && (batch->resolve & FD_BUFFER_STENCIL)) + emit_gmem2mem_surf(batch, true, ctx->gmem.zsbuf_base[1], pfb->zsbuf); } - if (ctx->resolve & FD_BUFFER_COLOR) { + if (batch->resolve & FD_BUFFER_COLOR) { unsigned i; for (i = 0; i < pfb->nr_cbufs; i++) { if (!pfb->cbufs[i]) continue; - if (!(ctx->resolve & (PIPE_CLEAR_COLOR0 << i))) + if (!(batch->resolve & (PIPE_CLEAR_COLOR0 << i))) continue; - emit_gmem2mem_surf(ctx, false, gmem->cbuf_base[i], pfb->cbufs[i]); + emit_gmem2mem_surf(batch, false, gmem->cbuf_base[i], pfb->cbufs[i]); } } @@ -297,10 +300,10 @@ fd4_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile) /* transfer from system memory to gmem */ static void -emit_mem2gmem_surf(struct fd_context *ctx, uint32_t *bases, +emit_mem2gmem_surf(struct fd_batch *batch, uint32_t *bases, struct pipe_surface **bufs, uint32_t nr_bufs, uint32_t bin_w) { - struct fd_ringbuffer *ring = ctx->ring; + struct fd_ringbuffer *ring = batch->gmem; struct pipe_surface *zsbufs[2]; emit_mrt(ring, nr_bufs, bufs, bases, bin_w, false); @@ -317,20 +320,20 @@ emit_mem2gmem_surf(struct fd_context *ctx, uint32_t *bases, fd4_emit_gmem_restore_tex(ring, nr_bufs, bufs); - fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, - DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL); + fd4_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, + DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX4_SIZE_8_BIT, 0, 0, NULL); } static void -fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) +fd4_emit_tile_mem2gmem(struct fd_batch *batch, struct fd_tile *tile) { - struct fd4_context *fd4_ctx = fd4_context(ctx); + struct fd_context *ctx = batch->ctx; struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct fd_ringbuffer *ring = ctx->ring; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + struct fd_ringbuffer *ring = batch->gmem; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; struct fd4_emit emit = { .debug = &ctx->debug, - .vtx = &fd4_ctx->blit_vbuf_state, + .vtx = &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], @@ -352,7 +355,7 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) 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_RELOCW(ring, fd_resource(ctx->blit_texcoord_vbuf)->bo, 0, 0, 0); OUT_RING(ring, fui(x0)); OUT_RING(ring, fui(y0)); OUT_RING(ring, fui(x1)); @@ -454,14 +457,14 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) bin_w = gmem->bin_w; bin_h = gmem->bin_h; - if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR)) { + if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_COLOR)) { emit.prog = &ctx->blit_prog[pfb->nr_cbufs - 1]; - emit.fp = NULL; /* frag shader changed so clear cache */ + emit.fs = 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); + emit_mem2gmem_surf(batch, gmem->cbuf_base, pfb->cbufs, pfb->nr_cbufs, bin_w); } - if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { + if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { switch (pfb->zsbuf->format) { case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: case PIPE_FORMAT_Z32_FLOAT: @@ -490,9 +493,9 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) emit.key.half_precision = true; break; } - emit.fp = NULL; /* frag shader changed so clear cache */ + emit.fs = 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); + emit_mem2gmem_surf(batch, gmem->zsbuf_base, &pfb->zsbuf, 1, bin_w); } OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1); @@ -507,24 +510,24 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) } static void -patch_draws(struct fd_context *ctx, enum pc_di_vis_cull_mode vismode) +patch_draws(struct fd_batch *batch, enum pc_di_vis_cull_mode vismode) { unsigned i; - for (i = 0; i < fd_patch_num_elements(&ctx->draw_patches); i++) { - struct fd_cs_patch *patch = fd_patch_element(&ctx->draw_patches, i); + for (i = 0; i < fd_patch_num_elements(&batch->draw_patches); i++) { + struct fd_cs_patch *patch = fd_patch_element(&batch->draw_patches, i); *patch->cs = patch->val | DRAW4(0, 0, 0, vismode); } - util_dynarray_resize(&ctx->draw_patches, 0); + util_dynarray_clear(&batch->draw_patches); } /* for rendering directly to system memory: */ static void -fd4_emit_sysmem_prep(struct fd_context *ctx) +fd4_emit_sysmem_prep(struct fd_batch *batch) { - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - struct fd_ringbuffer *ring = ctx->ring; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; + struct fd_ringbuffer *ring = batch->gmem; - fd4_emit_restore(ctx); + fd4_emit_restore(batch, ring); OUT_PKT0(ring, REG_A4XX_RB_FRAME_BUFFER_DIMENSION, 1); OUT_RING(ring, A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) | @@ -551,14 +554,15 @@ fd4_emit_sysmem_prep(struct fd_context *ctx) OUT_PKT0(ring, REG_A4XX_RB_RENDER_CONTROL, 1); OUT_RING(ring, 0x8); - patch_draws(ctx, IGNORE_VISIBILITY); + patch_draws(batch, IGNORE_VISIBILITY); } static void -update_vsc_pipe(struct fd_context *ctx) +update_vsc_pipe(struct fd_batch *batch) { + struct fd_context *ctx = batch->ctx; struct fd4_context *fd4_ctx = fd4_context(ctx); - struct fd_ringbuffer *ring = ctx->ring; + struct fd_ringbuffer *ring = batch->gmem; int i; OUT_PKT0(ring, REG_A4XX_VSC_SIZE_ADDRESS, 1); @@ -566,7 +570,7 @@ update_vsc_pipe(struct fd_context *ctx) OUT_PKT0(ring, REG_A4XX_VSC_PIPE_CONFIG_REG(0), 8); for (i = 0; i < 8; i++) { - struct fd_vsc_pipe *pipe = &ctx->pipe[i]; + struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i]; OUT_RING(ring, A4XX_VSC_PIPE_CONFIG_REG_X(pipe->x) | A4XX_VSC_PIPE_CONFIG_REG_Y(pipe->y) | A4XX_VSC_PIPE_CONFIG_REG_W(pipe->w) | @@ -575,27 +579,28 @@ update_vsc_pipe(struct fd_context *ctx) OUT_PKT0(ring, REG_A4XX_VSC_PIPE_DATA_ADDRESS_REG(0), 8); for (i = 0; i < 8; i++) { - struct fd_vsc_pipe *pipe = &ctx->pipe[i]; + struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i]; if (!pipe->bo) { pipe->bo = fd_bo_new(ctx->dev, 0x40000, - DRM_FREEDRENO_GEM_TYPE_KMEM); + DRM_FREEDRENO_GEM_TYPE_KMEM, "vsc_pipe[%u]", i); } OUT_RELOCW(ring, pipe->bo, 0, 0, 0); /* VSC_PIPE_DATA_ADDRESS[i] */ } OUT_PKT0(ring, REG_A4XX_VSC_PIPE_DATA_LENGTH_REG(0), 8); for (i = 0; i < 8; i++) { - struct fd_vsc_pipe *pipe = &ctx->pipe[i]; + struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i]; OUT_RING(ring, fd_bo_size(pipe->bo) - 32); /* VSC_PIPE_DATA_LENGTH[i] */ } } static void -emit_binning_pass(struct fd_context *ctx) +emit_binning_pass(struct fd_batch *batch) { + struct fd_context *ctx = batch->ctx; struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - struct fd_ringbuffer *ring = ctx->ring; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; + struct fd_ringbuffer *ring = batch->gmem; int i; uint32_t x1 = gmem->minx; @@ -634,10 +639,10 @@ emit_binning_pass(struct fd_context *ctx) } /* emit IB to binning drawcmds: */ - ctx->emit_ib(ring, ctx->binning_start, ctx->binning_end); + fd4_emit_ib(ring, batch->binning); - fd_reset_wfi(ctx); - fd_wfi(ctx, ring); + fd_reset_wfi(batch); + fd_wfi(batch, ring); /* and then put stuff back the way it was: */ @@ -650,26 +655,32 @@ emit_binning_pass(struct fd_context *ctx) A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | A4XX_GRAS_SC_CONTROL_RASTER_MODE(0)); - fd_event_write(ctx, ring, CACHE_FLUSH); - fd_wfi(ctx, ring); + fd_event_write(batch, ring, CACHE_FLUSH); + fd_wfi(batch, ring); } /* before first tile */ static void -fd4_emit_tile_init(struct fd_context *ctx) +fd4_emit_tile_init(struct fd_batch *batch) { - struct fd_ringbuffer *ring = ctx->ring; - struct fd_gmem_stateobj *gmem = &ctx->gmem; + struct fd_ringbuffer *ring = batch->gmem; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; + struct fd_gmem_stateobj *gmem = &batch->ctx->gmem; - fd4_emit_restore(ctx); + fd4_emit_restore(batch, ring); OUT_PKT0(ring, REG_A4XX_VSC_BIN_SIZE, 1); OUT_RING(ring, A4XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) | A4XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h)); - update_vsc_pipe(ctx); + update_vsc_pipe(batch); - if (use_hw_binning(ctx)) { + fd_wfi(batch, ring); + OUT_PKT0(ring, REG_A4XX_RB_FRAME_BUFFER_DIMENSION, 1); + OUT_RING(ring, A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) | + A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height)); + + if (use_hw_binning(batch)) { 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)); @@ -680,11 +691,11 @@ fd4_emit_tile_init(struct fd_context *ctx) 0x8); /* emit hw binning pass: */ - emit_binning_pass(ctx); + emit_binning_pass(batch); - patch_draws(ctx, USE_VISIBILITY); + patch_draws(batch, USE_VISIBILITY); } else { - patch_draws(ctx, IGNORE_VISIBILITY); + patch_draws(batch, IGNORE_VISIBILITY); } OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1); @@ -695,10 +706,11 @@ fd4_emit_tile_init(struct fd_context *ctx) /* before mem2gmem */ static void -fd4_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile) +fd4_emit_tile_prep(struct fd_batch *batch, struct fd_tile *tile) { - struct fd_ringbuffer *ring = ctx->ring; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + struct fd_context *ctx = batch->ctx; + struct fd_ringbuffer *ring = batch->gmem; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; struct fd_gmem_stateobj *gmem = &ctx->gmem; if (pfb->zsbuf) { @@ -738,37 +750,30 @@ fd4_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile) } else { OUT_RING(ring, A4XX_GRAS_DEPTH_CONTROL_FORMAT(DEPTH4_NONE)); } - - if (ctx->needs_rb_fbd) { - fd_wfi(ctx, ring); - OUT_PKT0(ring, REG_A4XX_RB_FRAME_BUFFER_DIMENSION, 1); - OUT_RING(ring, A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) | - A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height)); - ctx->needs_rb_fbd = false; - } } /* before IB to rendering cmds: */ static void -fd4_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile) +fd4_emit_tile_renderprep(struct fd_batch *batch, struct fd_tile *tile) { + struct fd_context *ctx = batch->ctx; struct fd4_context *fd4_ctx = fd4_context(ctx); - struct fd_ringbuffer *ring = ctx->ring; + struct fd_ringbuffer *ring = batch->gmem; struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + struct pipe_framebuffer_state *pfb = &batch->framebuffer; uint32_t x1 = tile->xoff; uint32_t y1 = tile->yoff; uint32_t x2 = tile->xoff + tile->bin_w - 1; uint32_t y2 = tile->yoff + tile->bin_h - 1; - if (use_hw_binning(ctx)) { - struct fd_vsc_pipe *pipe = &ctx->pipe[tile->p]; + if (use_hw_binning(batch)) { + struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[tile->p]; - assert(pipe->w * pipe->h); + assert(pipe->w && pipe->h); - fd_event_write(ctx, ring, HLSQ_FLUSH); - fd_wfi(ctx, ring); + fd_event_write(batch, ring, HLSQ_FLUSH); + fd_wfi(batch, ring); OUT_PKT0(ring, REG_A4XX_PC_VSTREAM_CONTROL, 1); OUT_RING(ring, A4XX_PC_VSTREAM_CONTROL_SIZE(pipe->w * pipe->h) |