diff options
author | Christoph Bumiller <[email protected]> | 2011-12-09 18:46:09 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-12-15 18:51:48 +0100 |
commit | 14bd9d764802b5fedb652c791faafe4d13b65262 (patch) | |
tree | 4dba8e6abb0d7d6914fa7f265b5f81127c86c262 /src/gallium/drivers/nvc0/nvc0_program.c | |
parent | 14193da589275969be31dbdb3280bb48cd24d0c0 (diff) |
nvc0: implement new stream output interface
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_program.c')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_program.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index f3185b488e8..605bca5e6ba 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -480,6 +480,40 @@ nvc0_fp_gen_header(struct nvc0_program *fp, struct nv50_ir_prog_info *info) return 0; } +static struct nvc0_transform_feedback_state * +nvc0_program_create_tfb_state(const struct nv50_ir_prog_info *info, + const struct pipe_stream_output_info *pso) +{ + struct nvc0_transform_feedback_state *tfb; + int n = 0; + int i, c, b; + + tfb = MALLOC(sizeof(*tfb) + pso->num_outputs * 4 * sizeof(uint8_t)); + if (!tfb) + return NULL; + + for (b = 0; b < 4; ++b) { + tfb->varying_count[b] = 0; + + for (i = 0; i < pso->num_outputs; ++i) { + if (pso->output[i].output_buffer != b) + continue; + for (c = 0; c < 4; ++c) { + if (!(pso->output[i].register_mask & (1 << c))) + continue; + tfb->varying_count[b]++; + tfb->varying_index[n++] = + info->out[pso->output[i].register_index].slot[c]; + } + } + tfb->stride[b] = tfb->varying_count[b] * 4; + } + if (pso->stride) + tfb->stride[0] = pso->stride; + + return tfb; +} + #ifdef DEBUG static void nvc0_program_dump(struct nvc0_program *prog) @@ -577,6 +611,10 @@ nvc0_program_translate(struct nvc0_program *prog) if (info->io.globalAccess) prog->hdr[0] |= 1 << 16; + if (prog->pipe.stream_output.num_outputs) + prog->tfb = nvc0_program_create_tfb_state(info, + &prog->pipe.stream_output); + out: FREE(info); return !ret; @@ -675,6 +713,11 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog) FREE(prog->immd_data); if (prog->relocs) FREE(prog->relocs); + if (prog->tfb) { + if (nvc0->state.tfb == prog->tfb) + nvc0->state.tfb = NULL; + FREE(prog->tfb); + } memset(prog->hdr, 0, sizeof(prog->hdr)); |