mesa/st: merge st transform feedback object into gl one.

This just merges the object subclass into the main class,
this was left separate to ease review.

Acked-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14327>
This commit is contained in:
Dave Airlie 2021-12-15 11:03:40 +10:00
parent b6710b6549
commit ecb99724a3
4 changed files with 78 additions and 130 deletions

View File

@ -1808,6 +1808,14 @@ struct gl_transform_feedback_object
* zero.
*/
GLsizeiptr RequestedSize[MAX_FEEDBACK_BUFFERS];
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 stream output targets from the last call of
* EndTransformFeedback for each stream. */
struct pipe_stream_output_target *draw_count[MAX_VERTEX_STREAMS];
};

View File

@ -45,6 +45,7 @@
#include "program/prog_parameter.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "state_tracker/st_cb_xformfb.h"
#include "api_exec_decl.h"
@ -88,6 +89,44 @@ _mesa_transform_feedback_is_using_program(struct gl_context *ctx,
return callback_data.found;
}
static struct gl_transform_feedback_object *
new_transform_feedback(struct gl_context *ctx, GLuint name)
{
struct gl_transform_feedback_object *obj;
obj = CALLOC_STRUCT(gl_transform_feedback_object);
if (!obj)
return NULL;
obj->Name = name;
obj->RefCount = 1;
obj->EverBound = GL_FALSE;
return obj;
}
static void
delete_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(obj->draw_count); i++)
pipe_so_target_reference(&obj->draw_count[i], NULL);
/* Unreference targets. */
for (i = 0; i < obj->num_targets; i++) {
pipe_so_target_reference(&obj->targets[i], NULL);
}
for (unsigned i = 0; i < ARRAY_SIZE(obj->Buffers); i++) {
_mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
}
free(obj->Label);
FREE(obj);
}
/**
* Do reference counting of transform feedback buffers.
*/
@ -108,7 +147,7 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr,
if (oldObj->RefCount == 0) {
GET_CURRENT_CONTEXT(ctx);
if (ctx)
st_delete_transform_feedback(ctx, oldObj);
delete_transform_feedback(ctx, oldObj);
}
*ptr = NULL;
@ -134,7 +173,7 @@ _mesa_init_transform_feedback(struct gl_context *ctx)
{
/* core mesa expects this, even a dummy one, to be available */
ctx->TransformFeedback.DefaultObject =
st_new_transform_feedback(ctx, 0);
new_transform_feedback(ctx, 0);
assert(ctx->TransformFeedback.DefaultObject->RefCount == 1);
@ -161,7 +200,7 @@ delete_cb(void *data, void *userData)
struct gl_transform_feedback_object *obj =
(struct gl_transform_feedback_object *) data;
st_delete_transform_feedback(ctx, obj);
delete_transform_feedback(ctx, obj);
}
@ -181,44 +220,12 @@ _mesa_free_transform_feedback(struct gl_context *ctx)
_mesa_DeleteHashTable(ctx->TransformFeedback.Objects);
/* Delete the default feedback object */
st_delete_transform_feedback(ctx,
ctx->TransformFeedback.DefaultObject);
delete_transform_feedback(ctx,
ctx->TransformFeedback.DefaultObject);
ctx->TransformFeedback.CurrentObject = NULL;
}
/** Initialize the fields of a gl_transform_feedback_object. */
void
_mesa_init_transform_feedback_object(struct gl_transform_feedback_object *obj,
GLuint name)
{
obj->Name = name;
obj->RefCount = 1;
obj->EverBound = GL_FALSE;
}
/**
* Delete a transform feedback object.
* Called from the driver after all driver-specific clean-up
* has been done.
*
* \param ctx GL context to wich transform feedback object belongs.
* \param obj Transform feedback object due to be deleted.
*/
void
_mesa_delete_transform_feedback_object(struct gl_context *ctx,
struct gl_transform_feedback_object
*obj)
{
for (unsigned i = 0; i < ARRAY_SIZE(obj->Buffers); i++) {
_mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
}
free(obj->Label);
FREE(obj);
}
/**
* Fill in the correct Size value for each buffer in \c obj.
*
@ -1005,7 +1012,7 @@ create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
GLsizei i;
for (i = 0; i < n; i++) {
struct gl_transform_feedback_object *obj
= st_new_transform_feedback(ctx, ids[i]);
= new_transform_feedback(ctx, ids[i]);
if (!obj) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;

View File

@ -47,57 +47,6 @@
#include "util/u_inlines.h"
#include "cso_cache/cso_context.h"
struct st_transform_feedback_object {
struct gl_transform_feedback_object base;
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 stream output targets from the last call of
* EndTransformFeedback for each stream. */
struct pipe_stream_output_target *draw_count[MAX_VERTEX_STREAMS];
};
static inline struct st_transform_feedback_object *
st_transform_feedback_object(struct gl_transform_feedback_object *obj)
{
return (struct st_transform_feedback_object *) obj;
}
struct gl_transform_feedback_object *
st_new_transform_feedback(struct gl_context *ctx, GLuint name)
{
struct st_transform_feedback_object *obj;
obj = CALLOC_STRUCT(st_transform_feedback_object);
if (!obj)
return NULL;
_mesa_init_transform_feedback_object(&obj->base, name);
return &obj->base;
}
void
st_delete_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj)
{
struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj);
unsigned i;
for (i = 0; i < ARRAY_SIZE(sobj->draw_count); i++)
pipe_so_target_reference(&sobj->draw_count[i], NULL);
/* Unreference targets. */
for (i = 0; i < sobj->num_targets; i++) {
pipe_so_target_reference(&sobj->targets[i], NULL);
}
_mesa_delete_transform_feedback_object(ctx, obj);
}
/* XXX Do we really need the mode? */
@ -106,48 +55,46 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
struct gl_transform_feedback_object *obj)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj);
struct pipe_context *pipe = ctx->pipe;
unsigned i, max_num_targets;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
max_num_targets = MIN2(ARRAY_SIZE(sobj->base.Buffers),
ARRAY_SIZE(sobj->targets));
max_num_targets = MIN2(ARRAY_SIZE(obj->Buffers),
ARRAY_SIZE(obj->targets));
/* Convert the transform feedback state into the gallium representation. */
for (i = 0; i < max_num_targets; i++) {
struct gl_buffer_object *bo = sobj->base.Buffers[i];
struct gl_buffer_object *bo = obj->Buffers[i];
if (bo && bo->buffer) {
unsigned stream = obj->program->sh.LinkedTransformFeedback->
Buffers[i].Stream;
/* Check whether we need to recreate the target. */
if (!sobj->targets[i] ||
sobj->targets[i] == sobj->draw_count[stream] ||
sobj->targets[i]->buffer != bo->buffer ||
sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
if (!obj->targets[i] ||
obj->targets[i] == obj->draw_count[stream] ||
obj->targets[i]->buffer != bo->buffer ||
obj->targets[i]->buffer_offset != obj->Offset[i] ||
obj->targets[i]->buffer_size != obj->Size[i]) {
/* Create a new target. */
struct pipe_stream_output_target *so_target =
pipe->create_stream_output_target(pipe, bo->buffer,
sobj->base.Offset[i],
sobj->base.Size[i]);
obj->Offset[i],
obj->Size[i]);
pipe_so_target_reference(&sobj->targets[i], NULL);
sobj->targets[i] = so_target;
pipe_so_target_reference(&obj->targets[i], NULL);
obj->targets[i] = so_target;
}
sobj->num_targets = i+1;
obj->num_targets = i+1;
} else {
pipe_so_target_reference(&sobj->targets[i], NULL);
pipe_so_target_reference(&obj->targets[i], NULL);
}
}
/* Start writing at the beginning of each target. */
cso_set_stream_outputs(st->cso_context, sobj->num_targets,
sobj->targets, offsets);
cso_set_stream_outputs(st->cso_context, obj->num_targets,
obj->targets, offsets);
}
@ -165,16 +112,14 @@ st_resume_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);
unsigned offsets[PIPE_MAX_SO_BUFFERS];
unsigned i;
for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++)
offsets[i] = (unsigned)-1;
cso_set_stream_outputs(st->cso_context, sobj->num_targets,
sobj->targets, offsets);
cso_set_stream_outputs(st->cso_context, obj->num_targets,
obj->targets, offsets);
}
void
@ -182,8 +127,6 @@ 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);
unsigned i;
cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
@ -194,18 +137,18 @@ st_end_transform_feedback(struct gl_context *ctx,
*
* NULL means the vertex counter is 0 (initial state).
*/
for (i = 0; i < ARRAY_SIZE(sobj->draw_count); i++)
pipe_so_target_reference(&sobj->draw_count[i], NULL);
for (i = 0; i < ARRAY_SIZE(obj->draw_count); i++)
pipe_so_target_reference(&obj->draw_count[i], NULL);
for (i = 0; i < ARRAY_SIZE(sobj->targets); i++) {
for (i = 0; i < ARRAY_SIZE(obj->targets); i++) {
unsigned stream = obj->program->sh.LinkedTransformFeedback->
Buffers[i].Stream;
/* Is it not bound or already set for this stream? */
if (!sobj->targets[i] || sobj->draw_count[stream])
if (!obj->targets[i] || obj->draw_count[stream])
continue;
pipe_so_target_reference(&sobj->draw_count[stream], sobj->targets[i]);
pipe_so_target_reference(&obj->draw_count[stream], obj->targets[i]);
}
}
@ -215,9 +158,6 @@ st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
unsigned stream,
struct pipe_draw_indirect_info *out)
{
struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj);
out->count_from_stream_output = sobj->draw_count[stream];
out->count_from_stream_output = obj->draw_count[stream];
return out->count_from_stream_output != NULL;
}

View File

@ -32,13 +32,6 @@
struct gl_transform_feedback_object;
struct pipe_draw_indirect_info;
struct gl_transform_feedback_object *
st_new_transform_feedback(struct gl_context *ctx, GLuint name);
void
st_delete_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj);
void
st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
struct gl_transform_feedback_object *obj);