freedreno/ir3: introduce ir3_compiler object
[mesa.git] / src / gallium / drivers / freedreno / a4xx / fd4_gmem.c
index ce0a8c14d34320fd0400f6f81ecb18197ea1be38..9a9050620714f8d834f0b153cbcac599ea74a18e 100644 (file)
@@ -41,7 +41,7 @@
 #include "fd4_draw.h"
 #include "fd4_emit.h"
 #include "fd4_program.h"
-#include "fd4_util.h"
+#include "fd4_format.h"
 #include "fd4_zsa.h"
 
 static const struct ir3_shader_key key = {
@@ -54,8 +54,15 @@ static void
 emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
                struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w)
 {
+       enum a4xx_tile_mode tile_mode;
        unsigned i;
 
+       if (bin_w) {
+               tile_mode = 2;
+       } else {
+               tile_mode = TILE4_LINEAR;
+       }
+
        for (i = 0; i < 8; i++) {
                enum a4xx_color_fmt format = 0;
                enum a3xx_color_swap swap = WZYX;
@@ -63,19 +70,20 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
                struct fd_resource_slice *slice = NULL;
                uint32_t stride = 0;
                uint32_t base = 0;
-               uint32_t layer_offset = 0;
+               uint32_t offset = 0;
 
                if ((i < nr_bufs) && bufs[i]) {
                        struct pipe_surface *psurf = bufs[i];
 
                        rsc = fd_resource(psurf->texture);
-                       slice = &rsc->slices[psurf->u.tex.level];
+                       slice = fd_resource_slice(rsc, psurf->u.tex.level);
                        format = fd4_pipe2color(psurf->format);
                        swap = fd4_pipe2swap(psurf->format);
 
                        debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
 
-                       layer_offset = slice->size0 * psurf->u.tex.first_layer;
+                       offset = fd_resource_offset(rsc, psurf->u.tex.level,
+                                       psurf->u.tex.first_layer);
 
                        if (bin_w) {
                                stride = bin_w * rsc->cpp;
@@ -90,16 +98,20 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
 
                OUT_PKT0(ring, REG_A4XX_RB_MRT_BUF_INFO(i), 3);
                OUT_RING(ring, A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
-                               0x80 | /* XXX not on gmem2mem?? tile-mode? */
+                               A4XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
                                A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) |
                                A4XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
                if (bin_w || (i >= nr_bufs)) {
                        OUT_RING(ring, base);
+                       OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(stride));
                } else {
-                       OUT_RELOCW(ring, rsc->bo,
-                                       slice->offset + layer_offset, 0, -1);
+                       OUT_RELOCW(ring, rsc->bo, offset, 0, 0);
+                       /* RB_MRT[i].CONTROL3.STRIDE not emitted by c2d..
+                        * not sure if we need to skip it for bypass or
+                        * not.
+                        */
+                       OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(0));
                }
-               OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(stride));
        }
 }
 
@@ -126,12 +138,16 @@ emit_gmem2mem_surf(struct fd_context *ctx,
        struct fd_ringbuffer *ring = ctx->ring;
        struct fd_resource *rsc = fd_resource(psurf->texture);
        struct fd_resource_slice *slice = &rsc->slices[psurf->u.tex.level];
+       uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level,
+                       psurf->u.tex.first_layer);
+
+       debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
 
        OUT_PKT0(ring, REG_A4XX_RB_COPY_CONTROL, 4);
        OUT_RING(ring, A4XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
                        A4XX_RB_COPY_CONTROL_MODE(RB_COPY_RESOLVE) |
                        A4XX_RB_COPY_CONTROL_GMEM_BASE(base));
-       OUT_RELOCW(ring, rsc->bo, slice->offset, 0, 0);   /* RB_COPY_DEST_BASE */
+       OUT_RELOCW(ring, rsc->bo, offset, 0, 0);   /* RB_COPY_DEST_BASE */
        OUT_RING(ring, A4XX_RB_COPY_DEST_PITCH_PITCH(slice->pitch * rsc->cpp));
        OUT_RING(ring, A4XX_RB_COPY_DEST_INFO_TILE(TILE4_LINEAR) |
                        A4XX_RB_COPY_DEST_INFO_FORMAT(fd4_pipe2color(psurf->format)) |
@@ -140,7 +156,7 @@ emit_gmem2mem_surf(struct fd_context *ctx,
                        A4XX_RB_COPY_DEST_INFO_SWAP(fd4_pipe2swap(psurf->format)));
 
        fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
-                       DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL);
+                       DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL);
 }
 
 static void
@@ -254,7 +270,7 @@ emit_mem2gmem_surf(struct fd_context *ctx, uint32_t base,
        fd4_emit_gmem_restore_tex(ring, psurf);
 
        fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
-                       DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL);
+                       DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL);
 }
 
 static void
@@ -266,7 +282,7 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
        struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
        struct fd4_emit emit = {
                        .vtx = &fd4_ctx->blit_vbuf_state,
-                       .prog = &ctx->blit_prog,
+                       .prog = &ctx->blit_prog[0],
                        .key = key,
                        .format = fd4_emit_format(pfb->cbufs[0]),
        };
@@ -359,7 +375,7 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
 
        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);
+                       A4XX_PC_PRIM_VTX_CNTL_VAROUT(1));
 
        OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
        OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
@@ -414,6 +430,41 @@ patch_rbrc(struct fd_context *ctx, uint32_t val)
        util_dynarray_resize(&fd4_ctx->rbrc_patches, 0);
 }
 
+/* for rendering directly to system memory: */
+static void
+fd4_emit_sysmem_prep(struct fd_context *ctx)
+{
+       struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+       struct fd_ringbuffer *ring = ctx->ring;
+
+       fd4_emit_restore(ctx);
+
+       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));
+
+       emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
+
+       /* setup scissor/offset for current tile: */
+       OUT_PKT0(ring, REG_A4XX_RB_BIN_OFFSET, 1);
+       OUT_RING(ring, A4XX_RB_BIN_OFFSET_X(0) |
+                       A4XX_RB_BIN_OFFSET_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(pfb->width - 1) |
+                       A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
+
+       OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1);
+       OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(0) |
+                       A4XX_RB_MODE_CONTROL_HEIGHT(0) |
+                       0x00c00000);  /* XXX */
+
+       patch_draws(ctx, IGNORE_VISIBILITY);
+       patch_rbrc(ctx, 0);  // XXX
+}
+
 static void
 update_vsc_pipe(struct fd_context *ctx)
 {
@@ -500,10 +551,12 @@ fd4_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
                OUT_RING(ring, 0x00000000);
        }
 
+       OUT_PKT0(ring, REG_A4XX_GRAS_DEPTH_CONTROL, 1);
        if (pfb->zsbuf) {
-               OUT_PKT0(ring, REG_A4XX_GRAS_DEPTH_CONTROL, 1);
                OUT_RING(ring, A4XX_GRAS_DEPTH_CONTROL_FORMAT(
                                fd4_pipe2depth(pfb->zsbuf->format)));
+       } else {
+               OUT_RING(ring, A4XX_GRAS_DEPTH_CONTROL_FORMAT(DEPTH4_NONE));
        }
 
        if (ctx->needs_rb_fbd) {
@@ -552,6 +605,7 @@ fd4_gmem_init(struct pipe_context *pctx)
 {
        struct fd_context *ctx = fd_context(pctx);
 
+       ctx->emit_sysmem_prep = fd4_emit_sysmem_prep;
        ctx->emit_tile_init = fd4_emit_tile_init;
        ctx->emit_tile_prep = fd4_emit_tile_prep;
        ctx->emit_tile_mem2gmem = fd4_emit_tile_mem2gmem;