#define SI_SGPR_CONST 0
#define SI_SGPR_SAMPLER 2
#define SI_SGPR_RESOURCE 4
-#define SI_SGPR_VERTEX_BUFFER 6
-#define SI_SGPR_START_INSTANCE 8
+#define SI_SGPR_VERTEX_BUFFER 6 /* VS only */
+#define SI_SGPR_SO_BUFFER 8 /* VS only, stream-out */
+#define SI_SGPR_START_INSTANCE 10 /* VS only */
-#define SI_VS_NUM_USER_SGPR 9
+#define SI_VS_NUM_USER_SGPR 11
#define SI_PS_NUM_USER_SGPR 6
/* LLVM function parameter indices */
/* VS only parameters */
#define SI_PARAM_VERTEX_BUFFER 3
-#define SI_PARAM_START_INSTANCE 4
-#define SI_PARAM_VERTEX_ID 5
-#define SI_PARAM_DUMMY_0 6
-#define SI_PARAM_DUMMY_1 7
-#define SI_PARAM_INSTANCE_ID 8
+#define SI_PARAM_SO_BUFFER 4
+#define SI_PARAM_START_INSTANCE 5
+#define SI_PARAM_VERTEX_ID 6
+#define SI_PARAM_DUMMY_0 7
+#define SI_PARAM_DUMMY_1 8
+#define SI_PARAM_INSTANCE_ID 9
/* PS only parameters */
#define SI_PARAM_PRIM_MASK 3
si_update_descriptors(rctx, &buffers->desc);
}
+/* STREAMOUT BUFFERS */
+
+static void si_set_streamout_targets(struct pipe_context *ctx,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_bitmask)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_buffer_resources *buffers = &rctx->streamout_buffers;
+ unsigned old_num_targets = rctx->b.streamout.num_targets;
+ unsigned i;
+
+ /* Streamout buffers must be bound in 2 places:
+ * 1) in VGT by setting the VGT_STRMOUT registers
+ * 2) as shader resources
+ */
+
+ /* Set the VGT regs. */
+ r600_set_streamout_targets(ctx, num_targets, targets, append_bitmask);
+
+ /* Set the shader resources.*/
+ for (i = 0; i < num_targets; i++) {
+ if (targets[i]) {
+ struct pipe_resource *buffer = targets[i]->buffer;
+ uint64_t va = r600_resource_va(ctx->screen, buffer);
+
+ /* Set the descriptor. */
+ uint32_t *desc = buffers->desc_data[i];
+ desc[0] = va;
+ desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
+ desc[2] = 0xffffffff;
+ desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+ S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+ S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+ S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
+
+ /* Set the resource. */
+ pipe_resource_reference(&buffers->buffers[i], buffer);
+ r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx,
+ (struct r600_resource*)buffer,
+ buffers->shader_usage);
+ buffers->desc.enabled_mask |= 1 << i;
+ } else {
+ /* Clear the descriptor and unset the resource. */
+ memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4);
+ pipe_resource_reference(&buffers->buffers[i], NULL);
+ buffers->desc.enabled_mask &= ~(1 << i);
+ }
+ buffers->desc.dirty_mask |= 1 << i;
+ }
+ for (; i < old_num_targets; i++) {
+ /* Clear the descriptor and unset the resource. */
+ memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4);
+ pipe_resource_reference(&buffers->buffers[i], NULL);
+ buffers->desc.enabled_mask &= ~(1 << i);
+ buffers->desc.dirty_mask |= 1 << i;
+ }
+
+ si_update_descriptors(rctx, &buffers->desc);
+}
+
/* INIT/DEINIT */
void si_init_all_descriptors(struct r600_context *rctx)
rctx->atoms.sampler_views[i] = &rctx->samplers[i].views.desc.atom;
}
+ si_init_buffer_resources(rctx, &rctx->streamout_buffers, 4, PIPE_SHADER_VERTEX,
+ SI_SGPR_SO_BUFFER, RADEON_USAGE_WRITE);
+ rctx->atoms.streamout_buffers = &rctx->streamout_buffers.desc.atom;
+
/* Set pipe_context functions. */
rctx->b.b.set_constant_buffer = si_set_constant_buffer;
+ rctx->b.b.set_stream_output_targets = si_set_streamout_targets;
}
void si_release_all_descriptors(struct r600_context *rctx)
si_release_buffer_resources(&rctx->const_buffers[i]);
si_release_sampler_views(&rctx->samplers[i].views);
}
+ si_release_buffer_resources(&rctx->streamout_buffers);
}
void si_all_descriptors_begin_new_cs(struct r600_context *rctx)
si_buffer_resources_begin_new_cs(rctx, &rctx->const_buffers[i]);
si_sampler_views_begin_new_cs(rctx, &rctx->samplers[i].views);
}
+ si_buffer_resources_begin_new_cs(rctx, &rctx->streamout_buffers);
}