if (!emit->binning_pass)
ir3_emit_fs_consts(fp, ring, ctx);
- struct pipe_stream_output_info *info = &vp->shader->stream_output;
+ struct ir3_stream_output_info *info = &vp->shader->stream_output;
if (info->num_outputs) {
struct fd_streamout_stateobj *so = &ctx->streamout;
static void
link_stream_out(struct ir3_shader_linkage *l, const struct ir3_shader_variant *v)
{
- const struct pipe_stream_output_info *strmout = &v->shader->stream_output;
+ const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
/*
* First, any stream-out varyings not already in linkage map (ie. also
* consumed by frag shader) need to be added:
*/
for (unsigned i = 0; i < strmout->num_outputs; i++) {
- const struct pipe_stream_output *out = &strmout->output[i];
+ const struct ir3_stream_output *out = &strmout->output[i];
unsigned k = out->register_index;
unsigned compmask =
(1 << (out->num_components + out->start_component)) - 1;
emit_stream_out(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
struct ir3_shader_linkage *l)
{
- const struct pipe_stream_output_info *strmout = &v->shader->stream_output;
+ const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
unsigned ncomp[PIPE_MAX_SO_BUFFERS] = {0};
unsigned prog[align(l->max_loc, 2) / 2];
memset(prog, 0, sizeof(prog));
for (unsigned i = 0; i < strmout->num_outputs; i++) {
- const struct pipe_stream_output *out = &strmout->output[i];
+ const struct ir3_stream_output *out = &strmout->output[i];
unsigned k = out->register_index;
unsigned idx;
fd_ringbuffer_del(fsconstobj);
}
- struct pipe_stream_output_info *info = &vp->shader->stream_output;
+ struct ir3_stream_output_info *info = &vp->shader->stream_output;
if (info->num_outputs) {
struct fd_streamout_stateobj *so = &ctx->streamout;
static void
link_stream_out(struct ir3_shader_linkage *l, const struct ir3_shader_variant *v)
{
- const struct pipe_stream_output_info *strmout = &v->shader->stream_output;
+ const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
/*
* First, any stream-out varyings not already in linkage map (ie. also
* consumed by frag shader) need to be added:
*/
for (unsigned i = 0; i < strmout->num_outputs; i++) {
- const struct pipe_stream_output *out = &strmout->output[i];
+ const struct ir3_stream_output *out = &strmout->output[i];
unsigned k = out->register_index;
unsigned compmask =
(1 << (out->num_components + out->start_component)) - 1;
setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_variant *v,
struct ir3_shader_linkage *l)
{
- const struct pipe_stream_output_info *strmout = &v->shader->stream_output;
+ const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
struct fd6_streamout_state *tf = &state->tf;
memset(tf, 0, sizeof(*tf));
debug_assert(tf->prog_count < ARRAY_SIZE(tf->prog));
for (unsigned i = 0; i < strmout->num_outputs; i++) {
- const struct pipe_stream_output *out = &strmout->output[i];
+ const struct ir3_stream_output *out = &strmout->output[i];
unsigned k = out->register_index;
unsigned idx;
}
if (!strcmp(argv[n], "--stream-out")) {
- struct pipe_stream_output_info *so = &s.stream_output;
+ struct ir3_stream_output_info *so = &s.stream_output;
debug_printf(" %s", argv[n]);
/* TODO more dynamic config based on number of outputs, etc
* rather than just hard-code for first output:
#include <stdarg.h>
-#include "pipe/p_state.h"
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
{
struct ir3_shader_variant *v = ctx->so;
struct ir3 *ir = ctx->ir;
- struct pipe_stream_output_info *strmout =
+ struct ir3_stream_output_info *strmout =
&ctx->so->shader->stream_output;
struct ir3_block *orig_end_block, *stream_out_block, *new_end_block;
struct ir3_instruction *vtxcnt, *maxvtxcnt, *cond;
free(shader);
}
+static void
+copy_stream_out(struct ir3_stream_output_info *i,
+ const struct pipe_stream_output_info *p)
+{
+ STATIC_ASSERT(ARRAY_SIZE(i->stride) == ARRAY_SIZE(p->stride));
+ STATIC_ASSERT(ARRAY_SIZE(i->output) == ARRAY_SIZE(p->output));
+
+ i->num_outputs = p->num_outputs;
+ for (int n = 0; n < ARRAY_SIZE(i->stride); n++)
+ i->stride[n] = p->stride[n];
+
+ for (int n = 0; n < ARRAY_SIZE(i->output); n++) {
+ i->output[n].register_index = p->output[n].register_index;
+ i->output[n].start_component = p->output[n].start_component;
+ i->output[n].num_components = p->output[n].num_components;
+ i->output[n].output_buffer = p->output[n].output_buffer;
+ i->output[n].dst_offset = p->output[n].dst_offset;
+ i->output[n].stream = p->output[n].stream;
+ }
+}
+
struct ir3_shader *
ir3_shader_create(struct ir3_compiler *compiler,
const struct pipe_shader_state *cso, gl_shader_stage type,
nir_print_shader(shader->nir, stdout);
}
- shader->stream_output = cso->stream_output;
+ copy_stream_out(&shader->stream_output, &cso->stream_output);
+
if (fd_mesa_debug & FD_DBG_SHADERDB) {
/* if shader-db run, create a standard variant immediately
* (as otherwise nothing will trigger the shader to be
uint32_t offset = v->constbase.tfbo;
if (v->constlen > offset) {
struct fd_streamout_stateobj *so = &ctx->streamout;
- struct pipe_stream_output_info *info = &v->shader->stream_output;
+ struct ir3_stream_output_info *info = &v->shader->stream_output;
uint32_t params = 4;
uint32_t offsets[params];
struct pipe_resource *prscs[params];
max_tf_vtx(struct fd_context *ctx, const struct ir3_shader_variant *v)
{
struct fd_streamout_stateobj *so = &ctx->streamout;
- struct pipe_stream_output_info *info = &v->shader->stream_output;
+ struct ir3_stream_output_info *info = &v->shader->stream_output;
uint32_t maxvtxcnt = 0x7fffffff;
if (ctx->screen->gpu_id >= 500)
IR3_DP_VS_COUNT = 36 /* must be aligned to vec4 */
};
+#define IR3_MAX_SO_BUFFERS 4
+#define IR3_MAX_SO_OUTPUTS 64
+
/**
* For consts needed to pass internal values to shader which may or may not
* be required, rather than allocating worst-case const space, we scan the
} image_dims;
};
+/**
+ * A single output for vertex transform feedback.
+ */
+struct ir3_stream_output {
+ unsigned register_index:6; /**< 0 to 63 (OUT index) */
+ unsigned start_component:2; /** 0 to 3 */
+ unsigned num_components:3; /** 1 to 4 */
+ unsigned output_buffer:3; /**< 0 to PIPE_MAX_SO_BUFFERS */
+ unsigned dst_offset:16; /**< offset into the buffer in dwords */
+ unsigned stream:2; /**< 0 to 3 */
+};
+
+/**
+ * Stream output for vertex transform feedback.
+ */
+struct ir3_stream_output_info {
+ unsigned num_outputs;
+ /** stride for an entire vertex for each buffer in dwords */
+ uint16_t stride[IR3_MAX_SO_BUFFERS];
+
+ /**
+ * Array of stream outputs, in the order they are to be written in.
+ * Selected components are tightly packed into the output buffer.
+ */
+ struct ir3_stream_output output[IR3_MAX_SO_OUTPUTS];
+};
+
/* Configuration key used to identify a shader variant.. different
* shader variants can be used to implement features not supported
* in hw (two sided color), binning-pass vertex shader, etc.
struct ir3_compiler *compiler;
struct nir_shader *nir;
- struct pipe_stream_output_info stream_output;
+ struct ir3_stream_output_info stream_output;
struct ir3_shader_variant *variants;
};