#include "fd6_emit.h"
#include "fd6_texture.h"
#include "fd6_format.h"
+#include "fd6_pack.h"
void
fd6_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so)
static void
setup_config_stateobj(struct fd_ringbuffer *ring, struct fd6_program_state *state)
{
- OUT_PKT4(ring, REG_A6XX_HLSQ_UPDATE_CNTL, 1);
- OUT_RING(ring, 0xff); /* XXX */
+ OUT_REG(ring, A6XX_HLSQ_INVALIDATE_CMD(
+ .vs_state = true,
+ .hs_state = true,
+ .ds_state = true,
+ .gs_state = true,
+ .fs_state = true,
+ .cs_state = true,
+ .gfx_ibo = true,
+ .cs_ibo = true,
+ ));
debug_assert(state->vs->constlen >= state->bs->constlen);
OUT_PKT4(ring, REG_A6XX_SP_UNKNOWN_A9A8, 1);
OUT_RING(ring, 0);
- OUT_PKT4(ring, REG_A6XX_SP_UNKNOWN_AB00, 1);
- OUT_RING(ring, 0x5);
+ OUT_PKT4(ring, REG_A6XX_SP_MODE_CONTROL, 1);
+ OUT_RING(ring, A6XX_SP_MODE_CONTROL_CONSTANT_DEMOTION_ENABLE | 4);
OUT_PKT4(ring, REG_A6XX_SP_FS_OUTPUT_CNTL0, 1);
OUT_RING(ring, A6XX_SP_FS_OUTPUT_CNTL0_DEPTH_REGID(posz_regid) |
struct ir3_shader_linkage l = {0};
const struct ir3_shader_variant *last_shader = fd6_last_shader(state);
- ir3_link_shaders(&l, last_shader, fs, true);
+
+ bool do_streamout = (last_shader->shader->stream_output.num_outputs > 0);
+
+ /* If we have streamout, link against the real FS, rather than the
+ * dummy FS used for binning pass state, to ensure the OUTLOC's
+ * match. Depending on whether we end up doing sysmem or gmem,
+ * the actual streamout could happen with either the binning pass
+ * or draw pass program, but the same streamout stateobj is used
+ * in either case:
+ */
+ ir3_link_shaders(&l, last_shader, do_streamout ? state->fs : fs, true);
bool primid_passthru = l.primid_loc != 0xff;
OUT_RING(ring, ~l.varmask[3]); /* VPC_VAR[3].DISABLE */
/* Add stream out outputs after computing the VPC_VAR_DISABLE bitmask. */
- if (last_shader->shader->stream_output.num_outputs > 0)
- link_stream_out(&l, last_shader);
+ link_stream_out(&l, last_shader);
if (VALIDREG(layer_regid)) {
layer_loc = l.max_loc;
ir3_link_add(&l, psize_regid, 0x1, l.max_loc);
}
- if (last_shader->shader->stream_output.num_outputs > 0) {
+ /* If we have stream-out, we use the full shader for binning
+ * pass, rather than the optimized binning pass one, so that we
+ * have all the varying outputs available for xfb. So streamout
+ * state should always be derived from the non-binning pass
+ * program:
+ */
+ if (do_streamout && !binning_pass) {
setup_stream_out(state, last_shader, &l);
}
OUT_RING(ring, hs_info->tess.tcs_vertices_out);
/* Total attribute slots in HS incoming patch. */
- OUT_PKT4(ring, REG_A6XX_PC_UNKNOWN_9801, 1);
+ OUT_PKT4(ring, REG_A6XX_PC_HS_INPUT_SIZE, 1);
OUT_RING(ring, hs_info->tess.tcs_vertices_out * vs->output_size / 4);
OUT_PKT4(ring, REG_A6XX_SP_HS_UNKNOWN_A831, 1);
if (fs->instrlen)
fd6_emit_shader(ring, fs);
- OUT_PKT4(ring, REG_A6XX_PC_PRIMID_CNTL, 1);
- OUT_RING(ring, COND(primid_passthru, A6XX_PC_PRIMID_CNTL_PRIMID_PASSTHRU));
+ OUT_REG(ring, A6XX_PC_PRIMID_PASSTHRU(primid_passthru));
uint32_t non_sysval_input_count = 0;
for (uint32_t i = 0; i < vs->inputs_count; i++)