freedreno: Move register constant files to src/freedreno.
[mesa.git] / src / gallium / drivers / freedreno / a2xx / fd2_gmem.c
index 89f5a4d5259c2c8a4439b431d2c58ec2bbe9e769..e98ae7334ace4fb462f5b492942082d3e9327218 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
 /*
  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
  *
@@ -31,6 +29,7 @@
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
 
+#include "freedreno_draw.h"
 #include "freedreno_state.h"
 #include "freedreno_resource.h"
 
@@ -45,6 +44,12 @@ static uint32_t fmt2swap(enum pipe_format format)
 {
        switch (format) {
        case PIPE_FORMAT_B8G8R8A8_UNORM:
+       case PIPE_FORMAT_B8G8R8X8_UNORM:
+       case PIPE_FORMAT_B5G6R5_UNORM:
+       case PIPE_FORMAT_B5G5R5A1_UNORM:
+       case PIPE_FORMAT_B5G5R5X1_UNORM:
+       case PIPE_FORMAT_B4G4R4A4_UNORM:
+       case PIPE_FORMAT_B4G4R4X4_UNORM:
        /* TODO probably some more.. */
                return 1;
        default:
@@ -55,11 +60,22 @@ static uint32_t fmt2swap(enum pipe_format format)
 /* transfer from gmem to system memory (ie. normal RAM) */
 
 static void
-emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
+emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
                struct pipe_surface *psurf)
 {
+       struct fd_ringbuffer *ring = batch->gmem;
        struct fd_resource *rsc = fd_resource(psurf->texture);
        uint32_t swap = fmt2swap(psurf->format);
+       struct fd_resource_slice *slice =
+               fd_resource_slice(rsc, psurf->u.tex.level);
+       uint32_t offset =
+               fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer);
+
+       assert((slice->pitch & 31) == 0);
+       assert((offset & 0xfff) == 0);
+
+       if (!rsc->valid)
+               return;
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
@@ -70,8 +86,8 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
        OUT_PKT3(ring, CP_SET_CONSTANT, 5);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
        OUT_RING(ring, 0x00000000);             /* RB_COPY_CONTROL */
-       OUT_RELOCW(ring, rsc->bo, 0, 0, 0);     /* RB_COPY_DEST_BASE */
-       OUT_RING(ring, rsc->pitch >> 5);        /* RB_COPY_DEST_PITCH */
+       OUT_RELOCW(ring, rsc->bo, offset, 0, 0);     /* RB_COPY_DEST_BASE */
+       OUT_RING(ring, slice->pitch >> 5); /* RB_COPY_DEST_PITCH */
        OUT_RING(ring,                          /* RB_COPY_DEST_INFO */
                        A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) |
                        A2XX_RB_COPY_DEST_INFO_LINEAR |
@@ -81,28 +97,27 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
                        A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
                        A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
 
-       OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
-       OUT_RING(ring, 0x0000000);
+       if (!is_a20x(batch->ctx->screen)) {
+               OUT_WFI (ring);
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       }
 
-       OUT_PKT3(ring, CP_DRAW_INDX, 3);
-       OUT_RING(ring, 0x00000000);
-       OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
-                       INDEX_SIZE_IGN, IGNORE_VISIBILITY));
-       OUT_RING(ring, 3);                                      /* NumIndices */
+       fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
+                       DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
 }
 
 static void
-fd2_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
-               uint32_t bin_w, uint32_t bin_h)
+fd2_emit_tile_gmem2mem(struct fd_batch *batch, struct fd_tile *tile)
 {
+       struct fd_context *ctx = batch->ctx;
        struct fd2_context *fd2_ctx = fd2_context(ctx);
-       struct fd_ringbuffer *ring = ctx->ring;
-       struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+       struct fd_gmem_stateobj *gmem = &ctx->gmem;
+       struct fd_ringbuffer *ring = batch->gmem;
+       struct pipe_framebuffer_state *pfb = &batch->framebuffer;
 
        fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
                        { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
@@ -159,14 +174,14 @@ fd2_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET));
-       OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(xoff) |
-                       A2XX_RB_COPY_DEST_OFFSET_Y(yoff));
+       OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) |
+                       A2XX_RB_COPY_DEST_OFFSET_Y(tile->yoff));
 
-       if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
-               emit_gmem2mem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+       if (batch->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+               emit_gmem2mem_surf(batch, gmem->zsbuf_base[0], pfb->zsbuf);
 
-       if (ctx->resolve & FD_BUFFER_COLOR)
-               emit_gmem2mem_surf(ring, 0, pfb->cbufs[0]);
+       if (batch->resolve & FD_BUFFER_COLOR)
+               emit_gmem2mem_surf(batch, gmem->cbuf_base[0], pfb->cbufs[0]);
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
@@ -176,10 +191,15 @@ fd2_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
 /* transfer from system memory to gmem */
 
 static void
-emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
+emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
                struct pipe_surface *psurf)
 {
+       struct fd_ringbuffer *ring = batch->gmem;
        struct fd_resource *rsc = fd_resource(psurf->texture);
+       struct fd_resource_slice *slice =
+               fd_resource_slice(rsc, psurf->u.tex.level);
+       uint32_t offset =
+               fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer);
        uint32_t swiz;
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
@@ -188,8 +208,8 @@ emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
                        A2XX_RB_COLOR_INFO_BASE(base) |
                        A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
 
-       swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
-                       PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA);
+       swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+                       PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W);
 
        /* emit fb as a texture: */
        OUT_PKT3(ring, CP_SET_CONSTANT, 7);
@@ -197,37 +217,40 @@ emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
        OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
                        A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
                        A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
-                       A2XX_SQ_TEX_0_PITCH(rsc->pitch));
-       OUT_RELOC(ring, rsc->bo, 0,
-                       fd2_pipe2surface(psurf->format) | 0x800, 0);
+                       A2XX_SQ_TEX_0_PITCH(slice->pitch));
+       OUT_RELOC(ring, rsc->bo, offset,
+                       fd2_pipe2surface(psurf->format) |
+                       A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0);
        OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
                        A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
-       OUT_RING(ring, 0x01000000 | // XXX
+       OUT_RING(ring, A2XX_SQ_TEX_3_MIP_FILTER(SQ_TEX_FILTER_BASEMAP) |
                        swiz |
                        A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) |
                        A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT));
        OUT_RING(ring, 0x00000000);
-       OUT_RING(ring, 0x00000200);
+       OUT_RING(ring, A2XX_SQ_TEX_5_DIMENSION(SQ_TEX_DIMENSION_2D));
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       if (!is_a20x(batch->ctx->screen)) {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       }
 
-       OUT_PKT3(ring, CP_DRAW_INDX, 3);
-       OUT_RING(ring, 0x00000000);
-       OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
-                       INDEX_SIZE_IGN, IGNORE_VISIBILITY));
-       OUT_RING(ring, 3);                                      /* NumIndices */
+       fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
+                       DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
 }
 
 static void
-fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
-               uint32_t bin_w, uint32_t bin_h)
+fd2_emit_tile_mem2gmem(struct fd_batch *batch, struct fd_tile *tile)
 {
+       struct fd_context *ctx = batch->ctx;
        struct fd2_context *fd2_ctx = fd2_context(ctx);
-       struct fd_ringbuffer *ring = ctx->ring;
-       struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+       struct fd_gmem_stateobj *gmem = &ctx->gmem;
+       struct fd_ringbuffer *ring = batch->gmem;
+       struct pipe_framebuffer_state *pfb = &batch->framebuffer;
+       unsigned bin_w = tile->bin_w;
+       unsigned bin_h = tile->bin_h;
        float x0, y0, x1, y1;
 
        fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
@@ -236,10 +259,10 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
                }, 2);
 
        /* write texture coordinates to vertexbuf: */
-       x0 = ((float)xoff) / ((float)pfb->width);
-       x1 = ((float)xoff + bin_w) / ((float)pfb->width);
-       y0 = ((float)yoff) / ((float)pfb->height);
-       y1 = ((float)yoff + bin_h) / ((float)pfb->height);
+       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, 9);
        OUT_RELOC(ring, fd_resource(fd2_ctx->solid_vertexbuf)->bo, 0x60, 0, 0);
        OUT_RING(ring, fui(x0));
@@ -259,7 +282,7 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
        OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
        OUT_RING(ring, 0x0000003b);
 
-       fd2_program_emit(ring, &ctx->blit_prog);
+       fd2_program_emit(ring, &ctx->blit_prog[0]);
 
        OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
        OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
@@ -289,10 +312,10 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
        OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) |
-                       A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) |
+                       A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND2_DST_PLUS_SRC) |
                        A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) |
                        A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) |
-                       A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) |
+                       A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND2_DST_PLUS_SRC) |
                        A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO));
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 3);
@@ -321,31 +344,34 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
        OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
        OUT_RING(ring, 0x00000000);
 
-       if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
-               emit_mem2gmem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+       if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+               emit_mem2gmem_surf(batch, gmem->zsbuf_base[0], pfb->zsbuf);
 
-       if (ctx->restore & FD_BUFFER_COLOR)
-               emit_mem2gmem_surf(ring, 0, pfb->cbufs[0]);
+       if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_COLOR))
+               emit_mem2gmem_surf(batch, gmem->cbuf_base[0], pfb->cbufs[0]);
 
        /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
 }
 
 /* before first tile */
 static void
-fd2_emit_tile_init(struct fd_context *ctx)
+fd2_emit_tile_init(struct fd_batch *batch)
 {
-       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;
        enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
        uint32_t reg;
 
+       fd2_emit_restore(ctx, ring);
+
        OUT_PKT3(ring, CP_SET_CONSTANT, 4);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO));
        OUT_RING(ring, gmem->bin_w);                 /* RB_SURFACE_INFO */
        OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
                        A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
-       reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4));
+       reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(gmem->zsbuf_base[0]);
        if (pfb->zsbuf)
                reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
        OUT_RING(ring, reg);                         /* RB_DEPTH_INFO */
@@ -353,11 +379,10 @@ fd2_emit_tile_init(struct fd_context *ctx)
 
 /* before mem2gmem */
 static void
-fd2_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
-               uint32_t bin_w, uint32_t bin_h)
+fd2_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_ringbuffer *ring = batch->gmem;
+       struct pipe_framebuffer_state *pfb = &batch->framebuffer;
        enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
@@ -368,17 +393,18 @@ fd2_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
        /* setup screen scissor for current tile (same for mem2gmem): */
        OUT_PKT3(ring, CP_SET_CONSTANT, 3);
        OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL));
-       OUT_RING(ring, xy2d(0,0));           /* PA_SC_SCREEN_SCISSOR_TL */
-       OUT_RING(ring, xy2d(bin_w, bin_h));  /* PA_SC_SCREEN_SCISSOR_BR */
+       OUT_RING(ring, A2XX_PA_SC_SCREEN_SCISSOR_TL_X(0) |
+                       A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(0));
+       OUT_RING(ring, A2XX_PA_SC_SCREEN_SCISSOR_BR_X(tile->bin_w) |
+                       A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(tile->bin_h));
 }
 
 /* before IB to rendering cmds: */
 static void
-fd2_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
-               uint32_t bin_w, uint32_t bin_h)
+fd2_emit_tile_renderprep(struct fd_batch *batch, struct fd_tile *tile)
 {
-       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;
        enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
@@ -391,8 +417,8 @@ fd2_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
         */
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
-       OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-xoff) |
-                       A2XX_PA_SC_WINDOW_OFFSET_Y(-yoff));
+       OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-tile->xoff) |
+                       A2XX_PA_SC_WINDOW_OFFSET_Y(-tile->yoff));
 }
 
 void