freedreno/ir3: handle arrays of images
[mesa.git] / src / gallium / drivers / freedreno / a2xx / fd2_emit.c
index 4f667ab7d5706a6e612f274a79e10659e7f801d4..a787b71e379ae8af99faf663918efaaa650a32fb 100644 (file)
@@ -125,8 +125,9 @@ emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
 {
        unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
        static const struct fd2_sampler_stateobj dummy_sampler = {};
+       static const struct fd2_pipe_sampler_view dummy_view = {};
        const struct fd2_sampler_stateobj *sampler;
-       struct fd2_pipe_sampler_view *view;
+       const struct fd2_pipe_sampler_view *view;
 
        if (emitted & (1 << const_idx))
                return 0;
@@ -134,13 +135,19 @@ emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
        sampler = tex->samplers[samp_id] ?
                        fd2_sampler_stateobj(tex->samplers[samp_id]) :
                        &dummy_sampler;
-       view = fd2_pipe_sampler_view(tex->textures[samp_id]);
+       view = tex->textures[samp_id] ?
+                       fd2_pipe_sampler_view(tex->textures[samp_id]) :
+                       &dummy_view;
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 7);
        OUT_RING(ring, 0x00010000 + (0x6 * const_idx));
 
        OUT_RING(ring, sampler->tex0 | view->tex0);
-       OUT_RELOC(ring, fd_resource(view->base.texture)->bo, 0, view->fmt, 0);
+       if (view->base.texture)
+               OUT_RELOC(ring, fd_resource(view->base.texture)->bo, 0, view->fmt, 0);
+       else
+               OUT_RING(ring, 0);
+
        OUT_RING(ring, view->tex2);
        OUT_RING(ring, sampler->tex3 | view->tex3);
        OUT_RING(ring, sampler->tex4);
@@ -152,16 +159,18 @@ emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
 static void
 emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx)
 {
+       struct fd_texture_stateobj *fragtex = &ctx->tex[PIPE_SHADER_FRAGMENT];
+       struct fd_texture_stateobj *verttex = &ctx->tex[PIPE_SHADER_VERTEX];
        texmask emitted = 0;
        unsigned i;
 
-       for (i = 0; i < ctx->verttex.num_samplers; i++)
-               if (ctx->verttex.samplers[i])
-                       emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted);
+       for (i = 0; i < verttex->num_samplers; i++)
+               if (verttex->samplers[i])
+                       emitted |= emit_texture(ring, ctx, verttex, i, emitted);
 
-       for (i = 0; i < ctx->fragtex.num_samplers; i++)
-               if (ctx->fragtex.samplers[i])
-                       emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted);
+       for (i = 0; i < fragtex->num_samplers; i++)
+               if (fragtex->samplers[i])
+                       emitted |= emit_texture(ring, ctx, fragtex, i, emitted);
 }
 
 void
@@ -180,11 +189,11 @@ fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
 }
 
 void
-fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
+fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
 {
        struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
        struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
-       struct fd_ringbuffer *ring = ctx->ring;
+       struct fd_ringbuffer *ring = ctx->batch->draw;
 
        /* NOTE: we probably want to eventually refactor this so each state
         * object handles emitting it's own state..  although the mapping of
@@ -215,7 +224,7 @@ fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
                OUT_RING(ring, zsa->rb_alpha_ref);
        }
 
-       if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
+       if (ctx->rasterizer && dirty & FD_DIRTY_RASTERIZER) {
                struct fd2_rasterizer_stateobj *rasterizer =
                                fd2_rasterizer_stateobj(ctx->rasterizer);
                OUT_PKT3(ring, CP_SET_CONSTANT, 3);
@@ -250,10 +259,10 @@ fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
                OUT_RING(ring, xy2d(scissor->maxx,       /* PA_SC_WINDOW_SCISSOR_BR */
                                scissor->maxy));
 
-               ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, scissor->minx);
-               ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, scissor->miny);
-               ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, scissor->maxx);
-               ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, scissor->maxy);
+               ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
+               ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
+               ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
+               ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
        }
 
        if (dirty & FD_DIRTY_VIEWPORT) {
@@ -282,7 +291,7 @@ fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
                fd2_program_emit(ring, &ctx->prog);
        }
 
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONST)) {
                emit_constants(ring,  VS_CONST_BASE * 4,
                                &ctx->constbuf[PIPE_SHADER_VERTEX],
                                (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
@@ -297,29 +306,40 @@ fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
                OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol);
        }
 
-       if (dirty & FD_DIRTY_BLEND) {
+       if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) {
+               enum pipe_format format =
+                       pipe_surface_format(ctx->batch->framebuffer.cbufs[0]);
+               bool has_alpha = util_format_has_alpha(format);
+
                OUT_PKT3(ring, CP_SET_CONSTANT, 2);
                OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
-               OUT_RING(ring, blend->rb_blendcontrol);
+               OUT_RING(ring, blend->rb_blendcontrol_alpha |
+                       COND(has_alpha, blend->rb_blendcontrol_rgb) |
+                       COND(!has_alpha, blend->rb_blendcontrol_no_alpha_rgb));
 
                OUT_PKT3(ring, CP_SET_CONSTANT, 2);
                OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
                OUT_RING(ring, blend->rb_colormask);
        }
 
-       if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
-               emit_textures(ring, ctx);
+       if (dirty & FD_DIRTY_BLEND_COLOR) {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+               OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
+               OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[0]));
+               OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[1]));
+               OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[2]));
+               OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[3]));
+       }
 
-       ctx->dirty &= ~dirty;
+       if (dirty & (FD_DIRTY_TEX | FD_DIRTY_PROG))
+               emit_textures(ring, ctx);
 }
 
 /* emit per-context initialization:
  */
 void
-fd2_emit_setup(struct fd_context *ctx)
+fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring)
 {
-       struct fd_ringbuffer *ring = ctx->ring;
-
        OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1);
        OUT_RING(ring, 0x00000002);
 
@@ -442,16 +462,12 @@ fd2_emit_setup(struct fd_context *ctx)
        OUT_RING(ring, 0x00000000);        /* RB_BLEND_GREEN */
        OUT_RING(ring, 0x00000000);        /* RB_BLEND_BLUE */
        OUT_RING(ring, 0x000000ff);        /* RB_BLEND_ALPHA */
-
-       fd_ringbuffer_flush(ring);
-       fd_ringmarker_mark(ctx->draw_start);
 }
 
 static void
-fd2_emit_ib(struct fd_ringbuffer *ring, struct fd_ringmarker *start,
-               struct fd_ringmarker *end)
+fd2_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)
 {
-       __OUT_IB(ring, false, start, end);
+       __OUT_IB(ring, false, target);
 }
 
 void