aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.c66
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c9
3 files changed, 60 insertions, 17 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
index 2fc28dc24..b8534855b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
@@ -55,8 +55,18 @@ struct st_transform_feedback_object {
unsigned num_targets;
struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
+
+ /* This encapsulates the count that can be used as a source for draw_vbo.
+ * It contains a stream output target from the last call of
+ * EndTransformFeedback. */
+ struct pipe_stream_output_target *draw_count;
};
+static INLINE struct st_transform_feedback_object *
+st_transform_feedback_object(struct gl_transform_feedback_object *obj)
+{
+ return (struct st_transform_feedback_object *) obj;
+}
static struct gl_transform_feedback_object *
st_new_transform_feedback(struct gl_context *ctx, GLuint name)
@@ -78,9 +88,11 @@ st_delete_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj)
{
struct st_transform_feedback_object *sobj =
- (struct st_transform_feedback_object*)obj;
+ st_transform_feedback_object(obj);
unsigned i;
+ pipe_so_target_reference(&sobj->draw_count, NULL);
+
/* Unreference targets. */
for (i = 0; i < sobj->num_targets; i++) {
pipe_so_target_reference(&sobj->targets[i], NULL);
@@ -102,7 +114,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct st_transform_feedback_object *sobj =
- (struct st_transform_feedback_object*)obj;
+ st_transform_feedback_object(obj);
unsigned i, max_num_targets;
max_num_targets = MIN2(Elements(sobj->base.Buffers),
@@ -115,6 +127,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
if (bo) {
/* Check whether we need to recreate the target. */
if (!sobj->targets[i] ||
+ sobj->targets[i] == sobj->draw_count ||
sobj->targets[i]->buffer != bo->buffer ||
sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
@@ -141,7 +154,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
static void
-st_stop_transform_feedback(struct gl_context *ctx,
+st_pause_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj)
{
struct st_context *st = st_context(ctx);
@@ -155,31 +168,54 @@ st_resume_transform_feedback(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct st_transform_feedback_object *sobj =
- (struct st_transform_feedback_object*)obj;
+ st_transform_feedback_object(obj);
cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
~0);
}
-/* Set count_from_stream_output to any stream output target
- * from the transform feedback object. */
-void
-st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
- struct pipe_draw_info *out)
+
+static struct pipe_stream_output_target *
+st_transform_feedback_get_draw_target(struct gl_transform_feedback_object *obj)
{
struct st_transform_feedback_object *sobj =
- (struct st_transform_feedback_object*)obj;
+ st_transform_feedback_object(obj);
unsigned i;
for (i = 0; i < Elements(sobj->targets); i++) {
if (sobj->targets[i]) {
- out->count_from_stream_output = sobj->targets[i];
- return;
+ return sobj->targets[i];
}
}
assert(0);
- out->count_from_stream_output = NULL;
+ return NULL;
+}
+
+
+static void
+st_end_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_transform_feedback_object *sobj =
+ st_transform_feedback_object(obj);
+
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
+
+ pipe_so_target_reference(&sobj->draw_count,
+ st_transform_feedback_get_draw_target(obj));
+}
+
+
+void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out)
+{
+ struct st_transform_feedback_object *sobj =
+ st_transform_feedback_object(obj);
+
+ out->count_from_stream_output = sobj->draw_count;
}
@@ -189,8 +225,8 @@ st_init_xformfb_functions(struct dd_function_table *functions)
functions->NewTransformFeedback = st_new_transform_feedback;
functions->DeleteTransformFeedback = st_delete_transform_feedback;
functions->BeginTransformFeedback = st_begin_transform_feedback;
- functions->EndTransformFeedback = st_stop_transform_feedback;
- functions->PauseTransformFeedback = st_stop_transform_feedback;
+ functions->EndTransformFeedback = st_end_transform_feedback;
+ functions->PauseTransformFeedback = st_pause_transform_feedback;
functions->ResumeTransformFeedback = st_resume_transform_feedback;
}
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index dc17d76a5..4c8c67fca 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -222,7 +222,7 @@ void st_init_limits(struct st_context *st)
c->UniformBooleanTrue = ~0;
c->MaxTransformFeedbackSeparateAttribs =
- screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS);
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS);
c->MaxTransformFeedbackSeparateComponents =
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS);
c->MaxTransformFeedbackInterleavedComponents =
diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c
index 55699e721..828f0d81f 100644
--- a/mesalib/src/mesa/state_tracker/st_manager.c
+++ b/mesalib/src/mesa/state_tracker/st_manager.c
@@ -600,6 +600,7 @@ st_context_destroy(struct st_context_iface *stctxi)
static struct st_context_iface *
st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
const struct st_context_attribs *attribs,
+ enum st_context_error *error,
struct st_context_iface *shared_stctxi)
{
struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
@@ -623,17 +624,21 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
break;
case ST_PROFILE_OPENGL_CORE:
default:
+ *error = ST_CONTEXT_ERROR_BAD_API;
return NULL;
break;
}
pipe = smapi->screen->context_create(smapi->screen, NULL);
- if (!pipe)
+ if (!pipe) {
+ *error = ST_CONTEXT_ERROR_NO_MEMORY;
return NULL;
+ }
st_visual_to_context_mode(&attribs->visual, &mode);
st = st_create_context(api, pipe, &mode, shared_ctx);
if (!st) {
+ *error = ST_CONTEXT_ERROR_NO_MEMORY;
pipe->destroy(pipe);
return NULL;
}
@@ -645,6 +650,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
/* is the actual version less than the requested version? */
if (st->ctx->VersionMajor * 10 + st->ctx->VersionMinor <
attribs->major * 10 + attribs->minor) {
+ *error = ST_CONTEXT_ERROR_BAD_VERSION;
st_destroy_context(st);
return NULL;
}
@@ -660,6 +666,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
st->iface.share = st_context_share;
st->iface.st_context_private = (void *) smapi;
+ *error = ST_CONTEXT_SUCCESS;
return &st->iface;
}