summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0/nvc0_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_state.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c118
1 files changed, 59 insertions, 59 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 63d53ab70d0..1e334a01d87 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -520,7 +520,12 @@ nvc0_sp_state_create(struct pipe_context *pipe,
return NULL;
prog->type = type;
- prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+
+ if (cso->tokens)
+ prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+
+ if (cso->stream_output.num_outputs)
+ prog->pipe.stream_output = cso->stream_output;
return (void *)prog;
}
@@ -747,72 +752,75 @@ nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
nvc0->dirty |= NVC0_NEW_VERTEX;
}
-static void *
-nvc0_tfb_state_create(struct pipe_context *pipe,
- const struct pipe_stream_output_info *pso)
+static struct pipe_stream_output_target *
+nvc0_so_target_create(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ unsigned offset, unsigned size)
{
- struct nvc0_transform_feedback_state *so;
- int n = 0;
- int i, c, b;
-
- so = MALLOC(sizeof(*so) + pso->num_outputs * 4 * sizeof(uint8_t));
- if (!so)
+ struct nvc0_so_target *targ = MALLOC_STRUCT(nvc0_so_target);
+ if (!targ)
return NULL;
- for (b = 0; b < 4; ++b) {
- 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;
- so->varying_count[b]++;
- so->varying_index[n++] = (pso->output[i].register_index << 2) | c;
- }
- }
- so->stride[b] = so->varying_count[b] * 4;
+ targ->pq = pipe->create_query(pipe, NVC0_QUERY_TFB_BUFFER_OFFSET);
+ if (!targ->pq) {
+ FREE(targ);
+ return NULL;
}
- if (pso->stride)
- so->stride[0] = pso->stride;
+ targ->clean = TRUE;
- return so;
-}
+ targ->pipe.buffer_size = size;
+ targ->pipe.buffer_offset = offset;
+ targ->pipe.context = pipe;
+ targ->pipe.buffer = NULL;
+ pipe_resource_reference(&targ->pipe.buffer, res);
+ pipe_reference_init(&targ->pipe.reference, 1);
-static void
-nvc0_tfb_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- FREE(hwcso);
+ return &targ->pipe;
}
static void
-nvc0_tfb_state_bind(struct pipe_context *pipe, void *hwcso)
+nvc0_so_target_destroy(struct pipe_context *pipe,
+ struct pipe_stream_output_target *ptarg)
{
- nvc0_context(pipe)->tfb = hwcso;
- nvc0_context(pipe)->dirty |= NVC0_NEW_TFB;
+ struct nvc0_so_target *targ = nvc0_so_target(ptarg);
+ pipe->destroy_query(pipe, targ->pq);
+ FREE(targ);
}
static void
-nvc0_set_transform_feedback_buffers(struct pipe_context *pipe,
- struct pipe_resource **buffers,
- int *offsets,
- int num_buffers)
+nvc0_set_transform_feedback_targets(struct pipe_context *pipe,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_mask)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- int i;
+ unsigned i;
+ boolean serialize = TRUE;
- assert(num_buffers >= 0 && num_buffers <= 4); /* why signed ? */
+ assert(num_targets <= 4);
- for (i = 0; i < num_buffers; ++i) {
- assert(offsets[i] >= 0);
- nvc0->tfb_offset[i] = offsets[i];
- pipe_resource_reference(&nvc0->tfbbuf[i], buffers[i]);
- }
- for (; i < nvc0->num_tfbbufs; ++i)
- pipe_resource_reference(&nvc0->tfbbuf[i], NULL);
+ for (i = 0; i < num_targets; ++i) {
+ if (nvc0->tfbbuf[i] == targets[i] && (append_mask & (1 << i)))
+ continue;
+ nvc0->tfbbuf_dirty |= 1 << i;
- nvc0->num_tfbbufs = num_buffers;
+ if (nvc0->tfbbuf[i] && nvc0->tfbbuf[i] != targets[i])
+ nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize);
+
+ if (targets[i] && !(append_mask & (1 << i)))
+ nvc0_so_target(targets[i])->clean = TRUE;
+
+ pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]);
+ }
+ for (; i < nvc0->num_tfbbufs; ++i) {
+ nvc0->tfbbuf_dirty |= 1 << i;
+ nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize);
+ pipe_so_target_reference(&nvc0->tfbbuf[i], NULL);
+ }
+ nvc0->num_tfbbufs = num_targets;
- nvc0->dirty |= NVC0_NEW_TFB_BUFFERS;
+ if (nvc0->tfbbuf_dirty)
+ nvc0->dirty |= NVC0_NEW_TFB_TARGETS;
}
void
@@ -871,17 +879,9 @@ nvc0_init_state_functions(struct nvc0_context *nvc0)
pipe->set_vertex_buffers = nvc0_set_vertex_buffers;
pipe->set_index_buffer = nvc0_set_index_buffer;
-#if 0
- pipe->create_stream_output_state = nvc0_tfb_state_create;
- pipe->delete_stream_output_state = nvc0_tfb_state_delete;
- pipe->bind_stream_output_state = nvc0_tfb_state_bind;
- pipe->set_stream_output_buffers = nvc0_set_transform_feedback_buffers;
-#else
- (void)nvc0_tfb_state_create;
- (void)nvc0_tfb_state_delete;
- (void)nvc0_tfb_state_bind;
- (void)nvc0_set_transform_feedback_buffers;
-#endif
+ pipe->create_stream_output_target = nvc0_so_target_create;
+ pipe->stream_output_target_destroy = nvc0_so_target_destroy;
+ pipe->set_stream_output_targets = nvc0_set_transform_feedback_targets;
pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}