panfrost: Document MALI_WRITES_GLOBAL bit
[mesa.git] / src / gallium / drivers / freedreno / a6xx / fd6_program.c
index 651d9da781d747c6e19bcc2086143f6831ded945..98774a2cfe56de2ede7a507463b7ae109ceda3b8 100644 (file)
@@ -90,7 +90,7 @@ fd6_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so)
                        CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) |
                        CP_LOAD_STATE6_0_STATE_BLOCK(sb) |
                        CP_LOAD_STATE6_0_NUM_UNIT(so->instrlen));
-       OUT_RELOCD(ring, so->bo, 0, 0, 0);
+       OUT_RELOC(ring, so->bo, 0, 0, 0);
 }
 
 /* Add any missing varyings needed for stream-out.  Otherwise varyings not
@@ -145,20 +145,24 @@ setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_varian
                struct ir3_shader_linkage *l)
 {
        const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
-       struct fd6_streamout_state *tf = &state->tf;
 
-       memset(tf, 0, sizeof(*tf));
+       uint32_t ncomp[PIPE_MAX_SO_BUFFERS];
+       uint32_t prog[256/2];
+       uint32_t prog_count;
+
+       memset(ncomp, 0, sizeof(ncomp));
+       memset(prog, 0, sizeof(prog));
 
-       tf->prog_count = align(l->max_loc, 2) / 2;
+       prog_count = align(l->max_loc, 2) / 2;
 
-       debug_assert(tf->prog_count < ARRAY_SIZE(tf->prog));
+       debug_assert(prog_count < ARRAY_SIZE(prog));
 
        for (unsigned i = 0; i < strmout->num_outputs; i++) {
                const struct ir3_stream_output *out = &strmout->output[i];
                unsigned k = out->register_index;
                unsigned idx;
 
-               tf->ncomp[out->output_buffer] += out->num_components;
+               ncomp[out->output_buffer] += out->num_components;
 
                /* linkage map sorted by order frag shader wants things, so
                 * a bit less ideal here..
@@ -175,22 +179,40 @@ setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_varian
                        unsigned off = j + out->dst_offset;  /* in dwords */
 
                        if (loc & 1) {
-                               tf->prog[loc/2] |= A6XX_VPC_SO_PROG_B_EN |
+                               prog[loc/2] |= A6XX_VPC_SO_PROG_B_EN |
                                                A6XX_VPC_SO_PROG_B_BUF(out->output_buffer) |
                                                A6XX_VPC_SO_PROG_B_OFF(off * 4);
                        } else {
-                               tf->prog[loc/2] |= A6XX_VPC_SO_PROG_A_EN |
+                               prog[loc/2] |= A6XX_VPC_SO_PROG_A_EN |
                                                A6XX_VPC_SO_PROG_A_BUF(out->output_buffer) |
                                                A6XX_VPC_SO_PROG_A_OFF(off * 4);
                        }
                }
        }
 
-       tf->vpc_so_buf_cntl = A6XX_VPC_SO_BUF_CNTL_ENABLE |
-                       COND(tf->ncomp[0] > 0, A6XX_VPC_SO_BUF_CNTL_BUF0) |
-                       COND(tf->ncomp[1] > 0, A6XX_VPC_SO_BUF_CNTL_BUF1) |
-                       COND(tf->ncomp[2] > 0, A6XX_VPC_SO_BUF_CNTL_BUF2) |
-                       COND(tf->ncomp[3] > 0, A6XX_VPC_SO_BUF_CNTL_BUF3);
+       struct fd_ringbuffer *ring = state->streamout_stateobj;
+
+       OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 12 + (2 * prog_count));
+       OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL);
+       OUT_RING(ring, A6XX_VPC_SO_BUF_CNTL_ENABLE |
+                       COND(ncomp[0] > 0, A6XX_VPC_SO_BUF_CNTL_BUF0) |
+                       COND(ncomp[1] > 0, A6XX_VPC_SO_BUF_CNTL_BUF1) |
+                       COND(ncomp[2] > 0, A6XX_VPC_SO_BUF_CNTL_BUF2) |
+                       COND(ncomp[3] > 0, A6XX_VPC_SO_BUF_CNTL_BUF3));
+       OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(0));
+       OUT_RING(ring, ncomp[0]);
+       OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(1));
+       OUT_RING(ring, ncomp[1]);
+       OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(2));
+       OUT_RING(ring, ncomp[2]);
+       OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(3));
+       OUT_RING(ring, ncomp[3]);
+       OUT_RING(ring, REG_A6XX_VPC_SO_CNTL);
+       OUT_RING(ring, A6XX_VPC_SO_CNTL_ENABLE);
+       for (unsigned i = 0; i < prog_count; i++) {
+               OUT_RING(ring, REG_A6XX_VPC_SO_PROG);
+               OUT_RING(ring, prog[i]);
+       }
 }
 
 static void
@@ -784,6 +806,18 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen,
        OUT_PKT4(ring, REG_A6XX_PC_PRIMID_CNTL, 1);
        OUT_RING(ring, COND(primid_passthru, A6XX_PC_PRIMID_CNTL_PRIMID_PASSTHRU));
 
+       uint32_t non_sysval_input_count = 0;
+       for (uint32_t i = 0; i < vs->inputs_count; i++)
+               if (!vs->inputs[i].sysval)
+                       non_sysval_input_count++;
+
+       OUT_PKT4(ring, REG_A6XX_VFD_DEST_CNTL(0), non_sysval_input_count);
+       for (uint32_t i = 0; i < non_sysval_input_count; i++) {
+               assert(vs->inputs[i].compmask);
+               OUT_RING(ring, A6XX_VFD_DEST_CNTL_INSTR_WRITEMASK(vs->inputs[i].compmask) |
+                               A6XX_VFD_DEST_CNTL_INSTR_REGID(vs->inputs[i].regid));
+       }
+
        OUT_PKT4(ring, REG_A6XX_VFD_CONTROL_1, 6);
        OUT_RING(ring, A6XX_VFD_CONTROL_1_REGID4VTX(vertex_regid) |
                        A6XX_VFD_CONTROL_1_REGID4INST(instance_regid) |
@@ -973,6 +1007,8 @@ fd6_program_create(void *data, struct ir3_shader_variant *bs,
        state->config_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
        state->binning_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
        state->stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
+       state->streamout_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
+
 
 #ifdef DEBUG
        if (!ds) {
@@ -1000,6 +1036,7 @@ fd6_program_destroy(void *data, struct ir3_program_state *state)
        fd_ringbuffer_del(so->binning_stateobj);
        fd_ringbuffer_del(so->config_stateobj);
        fd_ringbuffer_del(so->interp_stateobj);
+       fd_ringbuffer_del(so->streamout_stateobj);
        free(so);
 }
 
@@ -1022,7 +1059,7 @@ fd6_shader_state_create(struct pipe_context *pctx, const struct pipe_shader_stat
 
        /* also account for UBO addresses: */
        packets += 1;
-       size += 2 * align(shader->const_state.num_ubos, 2);
+       size += 2 * shader->num_ubos;
 
        unsigned sizedwords = (4 * packets) + size;
        shader->ubo_state.cmdstream_size = sizedwords * 4;