freedreno: introduce fd_batch
[mesa.git] / src / gallium / drivers / freedreno / a4xx / fd4_emit.c
index ba5d48909faaf573b0d3350507e59034d4f93cec..5bb712c755c14c50dd5ff43d677e52bcfa8be8da 100644 (file)
@@ -93,7 +93,7 @@ fd4_emit_const(struct fd_ringbuffer *ring, enum shader_t type,
 
 static void
 fd4_emit_const_bo(struct fd_ringbuffer *ring, enum shader_t type, boolean write,
-               uint32_t regid, uint32_t num, struct fd_bo **bos, uint32_t *offsets)
+               uint32_t regid, uint32_t num, struct pipe_resource **prscs, uint32_t *offsets)
 {
        uint32_t i;
 
@@ -109,11 +109,11 @@ fd4_emit_const_bo(struct fd_ringbuffer *ring, enum shader_t type, boolean write,
                        CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
 
        for (i = 0; i < num; i++) {
-               if (bos[i]) {
+               if (prscs[i]) {
                        if (write) {
-                               OUT_RELOCW(ring, bos[i], offsets[i], 0, 0);
+                               OUT_RELOCW(ring, fd_resource(prscs[i])->bo, offsets[i], 0, 0);
                        } else {
-                               OUT_RELOC(ring, bos[i], offsets[i], 0, 0);
+                               OUT_RELOC(ring, fd_resource(prscs[i])->bo, offsets[i], 0, 0);
                        }
                } else {
                        OUT_RING(ring, 0xbad00000 | (i << 16));
@@ -123,23 +123,16 @@ fd4_emit_const_bo(struct fd_ringbuffer *ring, enum shader_t type, boolean write,
 
 static void
 emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
-               enum adreno_state_block sb, struct fd_texture_stateobj *tex)
+               enum adreno_state_block sb, struct fd_texture_stateobj *tex,
+               const struct ir3_shader_variant *v)
 {
        static const uint32_t bcolor_reg[] = {
                        [SB_VERT_TEX] = REG_A4XX_TPL1_TP_VS_BORDER_COLOR_BASE_ADDR,
                        [SB_FRAG_TEX] = REG_A4XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR,
        };
        struct fd4_context *fd4_ctx = fd4_context(ctx);
-       unsigned i, off;
-       void *ptr;
-
-       u_upload_alloc(fd4_ctx->border_color_uploader,
-                       0, BORDER_COLOR_UPLOAD_SIZE,
-                      BORDER_COLOR_UPLOAD_SIZE, &off,
-                       &fd4_ctx->border_color_buf,
-                       &ptr);
-
-       fd_setup_border_colors(tex, ptr, 0);
+       bool needs_border = false;
+       unsigned i;
 
        if (tex->num_samplers > 0) {
                int num_samplers;
@@ -165,6 +158,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                        &dummy_sampler;
                        OUT_RING(ring, sampler->texsamp0);
                        OUT_RING(ring, sampler->texsamp1);
+
+                       needs_border |= sampler->needs_border;
                }
 
                for (; i < num_samplers; i++) {
@@ -174,12 +169,14 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
        }
 
        if (tex->num_textures > 0) {
+               unsigned num_textures = tex->num_textures + v->astc_srgb.count;
+
                /* emit texture state: */
-               OUT_PKT3(ring, CP_LOAD_STATE, 2 + (8 * tex->num_textures));
+               OUT_PKT3(ring, CP_LOAD_STATE, 2 + (8 * num_textures));
                OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) |
                                CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
                                CP_LOAD_STATE_0_STATE_BLOCK(sb) |
-                               CP_LOAD_STATE_0_NUM_UNIT(tex->num_textures));
+                               CP_LOAD_STATE_0_NUM_UNIT(num_textures));
                OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
                                CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
                for (i = 0; i < tex->num_textures; i++) {
@@ -202,12 +199,52 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        OUT_RING(ring, 0x00000000);
                        OUT_RING(ring, 0x00000000);
                }
+
+               for (i = 0; i < v->astc_srgb.count; i++) {
+                       static const struct fd4_pipe_sampler_view dummy_view = {};
+                       const struct fd4_pipe_sampler_view *view;
+                       unsigned idx = v->astc_srgb.orig_idx[i];
+
+                       view = tex->textures[idx] ?
+                                       fd4_pipe_sampler_view(tex->textures[idx]) :
+                                       &dummy_view;
+
+                       debug_assert(view->texconst0 & A4XX_TEX_CONST_0_SRGB);
+
+                       OUT_RING(ring, view->texconst0 & ~A4XX_TEX_CONST_0_SRGB);
+                       OUT_RING(ring, view->texconst1);
+                       OUT_RING(ring, view->texconst2);
+                       OUT_RING(ring, view->texconst3);
+                       if (view->base.texture) {
+                               struct fd_resource *rsc = fd_resource(view->base.texture);
+                               OUT_RELOC(ring, rsc->bo, view->offset, view->texconst4, 0);
+                       } else {
+                               OUT_RING(ring, 0x00000000);
+                       }
+                       OUT_RING(ring, 0x00000000);
+                       OUT_RING(ring, 0x00000000);
+                       OUT_RING(ring, 0x00000000);
+               }
+       } else {
+               debug_assert(v->astc_srgb.count == 0);
        }
 
-       OUT_PKT0(ring, bcolor_reg[sb], 1);
-       OUT_RELOC(ring, fd_resource(fd4_ctx->border_color_buf)->bo, off, 0, 0);
+       if (needs_border) {
+               unsigned off;
+               void *ptr;
+
+               u_upload_alloc(fd4_ctx->border_color_uploader,
+                               0, BORDER_COLOR_UPLOAD_SIZE,
+                               BORDER_COLOR_UPLOAD_SIZE, &off,
+                               &fd4_ctx->border_color_buf,
+                               &ptr);
+
+               fd_setup_border_colors(tex, ptr, 0);
+               OUT_PKT0(ring, bcolor_reg[sb], 1);
+               OUT_RELOC(ring, fd_resource(fd4_ctx->border_color_buf)->bo, off, 0, 0);
 
-       u_upload_unmap(fd4_ctx->border_color_uploader);
+               u_upload_unmap(fd4_ctx->border_color_uploader);
+       }
 }
 
 /* emit texture state for mem->gmem restore operation.. eventually it would
@@ -253,10 +290,6 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs,
        for (i = 0; i < nr_bufs; i++) {
                if (bufs[i]) {
                        struct fd_resource *rsc = fd_resource(bufs[i]->texture);
-                       /* note: PIPE_BUFFER disallowed for surfaces */
-                       unsigned lvl = bufs[i]->u.tex.level;
-                       struct fd_resource_slice *slice = fd_resource_slice(rsc, lvl);
-                       uint32_t offset = fd_resource_offset(rsc, lvl, bufs[i]->u.tex.first_layer);
                        enum pipe_format format = fd4_gmem_restore_format(bufs[i]->format);
 
                        /* The restore blit_zs shader expects stencil in sampler 0,
@@ -267,6 +300,11 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs,
                                format = fd4_gmem_restore_format(rsc->base.b.format);
                        }
 
+                       /* note: PIPE_BUFFER disallowed for surfaces */
+                       unsigned lvl = bufs[i]->u.tex.level;
+                       struct fd_resource_slice *slice = fd_resource_slice(rsc, lvl);
+                       unsigned offset = fd_resource_offset(rsc, lvl, bufs[i]->u.tex.first_layer);
+
                        /* z32 restore is accomplished using depth write.  If there is
                         * no stencil component (ie. PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
                         * then no render target:
@@ -617,8 +655,6 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                ir3_emit_consts(vp, ring, ctx, emit->info, dirty);
                if (!emit->key.binning_pass)
                        ir3_emit_consts(fp, ring, ctx, emit->info, dirty);
-               /* mark clean after emitting consts: */
-               ctx->prog.dirty = 0;
        }
 
        if ((dirty & FD_DIRTY_BLEND)) {
@@ -681,14 +717,14 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 
        if (dirty & FD_DIRTY_VERTTEX) {
                if (vp->has_samp)
-                       emit_textures(ctx, ring, SB_VERT_TEX, &ctx->verttex);
+                       emit_textures(ctx, ring, SB_VERT_TEX, &ctx->verttex, vp);
                else
                        dirty &= ~FD_DIRTY_VERTTEX;
        }
 
        if (dirty & FD_DIRTY_FRAGTEX) {
                if (fp->has_samp)
-                       emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->fragtex);
+                       emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->fragtex, fp);
                else
                        dirty &= ~FD_DIRTY_FRAGTEX;
        }
@@ -700,10 +736,9 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
  * state, there could have been a context switch between ioctls):
  */
 void
-fd4_emit_restore(struct fd_context *ctx)
+fd4_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring)
 {
        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);
@@ -856,10 +891,9 @@ fd4_emit_restore(struct fd_context *ctx)
 }
 
 static void
-fd4_emit_ib(struct fd_ringbuffer *ring, struct fd_ringmarker *start,
-               struct fd_ringmarker *end)
+fd4_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)
 {
-       __OUT_IB(ring, true, start, end);
+       __OUT_IB(ring, true, target);
 }
 
 void