mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
glsl: implement ARB_transform_feedback3 in the linker
Acked-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
9576d555e0
commit
21cb5ed20d
3 changed files with 106 additions and 15 deletions
|
|
@ -1439,8 +1439,7 @@ public:
|
|||
bool accumulate_num_outputs(struct gl_shader_program *prog, unsigned *count);
|
||||
bool store(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
struct gl_transform_feedback_info *info, unsigned buffer,
|
||||
unsigned varying, const unsigned max_outputs) const;
|
||||
|
||||
const unsigned max_outputs) const;
|
||||
|
||||
/**
|
||||
* True if assign_location() has been called for this object.
|
||||
|
|
@ -1450,6 +1449,16 @@ public:
|
|||
return this->location != -1;
|
||||
}
|
||||
|
||||
bool is_next_buffer_separator() const
|
||||
{
|
||||
return this->next_buffer_separator;
|
||||
}
|
||||
|
||||
bool is_varying() const
|
||||
{
|
||||
return !this->next_buffer_separator && !this->skip_components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this object refers to the variable var.
|
||||
*/
|
||||
|
|
@ -1527,6 +1536,17 @@ private:
|
|||
* glGetTransformFeedbackVarying().
|
||||
*/
|
||||
unsigned size;
|
||||
|
||||
/**
|
||||
* How many components to skip. If non-zero, this is
|
||||
* gl_SkipComponents{1,2,3,4} from ARB_transform_feedback3.
|
||||
*/
|
||||
unsigned skip_components;
|
||||
|
||||
/**
|
||||
* Whether this is gl_NextBuffer from ARB_transform_feedback3.
|
||||
*/
|
||||
bool next_buffer_separator;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1546,7 +1566,31 @@ tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
this->location = -1;
|
||||
this->orig_name = input;
|
||||
this->is_clip_distance_mesa = false;
|
||||
this->skip_components = 0;
|
||||
this->next_buffer_separator = false;
|
||||
|
||||
if (ctx->Extensions.ARB_transform_feedback3) {
|
||||
/* Parse gl_NextBuffer. */
|
||||
if (strcmp(input, "gl_NextBuffer") == 0) {
|
||||
this->next_buffer_separator = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parse gl_SkipComponents. */
|
||||
if (strcmp(input, "gl_SkipComponents1") == 0)
|
||||
this->skip_components = 1;
|
||||
else if (strcmp(input, "gl_SkipComponents2") == 0)
|
||||
this->skip_components = 2;
|
||||
else if (strcmp(input, "gl_SkipComponents3") == 0)
|
||||
this->skip_components = 3;
|
||||
else if (strcmp(input, "gl_SkipComponents4") == 0)
|
||||
this->skip_components = 4;
|
||||
|
||||
if (this->skip_components)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parse a declaration. */
|
||||
const char *bracket = strrchr(input, '[');
|
||||
|
||||
if (bracket) {
|
||||
|
|
@ -1581,6 +1625,8 @@ tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
bool
|
||||
tfeedback_decl::is_same(const tfeedback_decl &x, const tfeedback_decl &y)
|
||||
{
|
||||
assert(x.is_varying() && y.is_varying());
|
||||
|
||||
if (strcmp(x.var_name, y.var_name) != 0)
|
||||
return false;
|
||||
if (x.is_subscripted != y.is_subscripted)
|
||||
|
|
@ -1603,6 +1649,8 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
|
|||
struct gl_shader_program *prog,
|
||||
ir_variable *output_var)
|
||||
{
|
||||
assert(this->is_varying());
|
||||
|
||||
if (output_var->type->is_array()) {
|
||||
/* Array variable */
|
||||
const unsigned matrix_cols =
|
||||
|
|
@ -1677,6 +1725,10 @@ bool
|
|||
tfeedback_decl::accumulate_num_outputs(struct gl_shader_program *prog,
|
||||
unsigned *count)
|
||||
{
|
||||
if (!this->is_varying()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this->is_assigned()) {
|
||||
/* From GL_EXT_transform_feedback:
|
||||
* A program will fail to link if:
|
||||
|
|
@ -1709,9 +1761,16 @@ tfeedback_decl::accumulate_num_outputs(struct gl_shader_program *prog,
|
|||
bool
|
||||
tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
struct gl_transform_feedback_info *info,
|
||||
unsigned buffer,
|
||||
unsigned varying, const unsigned max_outputs) const
|
||||
unsigned buffer, const unsigned max_outputs) const
|
||||
{
|
||||
assert(!this->next_buffer_separator);
|
||||
|
||||
/* Handle gl_SkipComponents. */
|
||||
if (this->skip_components) {
|
||||
info->BufferStride[buffer] += this->skip_components;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* From GL_EXT_transform_feedback:
|
||||
* A program will fail to link if:
|
||||
*
|
||||
|
|
@ -1757,9 +1816,9 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
}
|
||||
assert(components_so_far == this->num_components());
|
||||
|
||||
info->Varyings[varying].Name = ralloc_strdup(prog, this->orig_name);
|
||||
info->Varyings[varying].Type = this->type;
|
||||
info->Varyings[varying].Size = this->size;
|
||||
info->Varyings[info->NumVarying].Name = ralloc_strdup(prog, this->orig_name);
|
||||
info->Varyings[info->NumVarying].Type = this->type;
|
||||
info->Varyings[info->NumVarying].Size = this->size;
|
||||
info->NumVarying++;
|
||||
|
||||
return true;
|
||||
|
|
@ -1781,6 +1840,10 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
for (unsigned i = 0; i < num_names; ++i) {
|
||||
if (!decls[i].init(ctx, prog, mem_ctx, varying_names[i]))
|
||||
return false;
|
||||
|
||||
if (!decls[i].is_varying())
|
||||
continue;
|
||||
|
||||
/* From GL_EXT_transform_feedback:
|
||||
* A program will fail to link if:
|
||||
*
|
||||
|
|
@ -1792,6 +1855,9 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
* feedback of arrays would be useless otherwise.
|
||||
*/
|
||||
for (unsigned j = 0; j < i; ++j) {
|
||||
if (!decls[j].is_varying())
|
||||
continue;
|
||||
|
||||
if (tfeedback_decl::is_same(decls[i], decls[j])) {
|
||||
linker_error(prog, "Transform feedback varying %s specified "
|
||||
"more than once.", varying_names[i]);
|
||||
|
|
@ -1948,6 +2014,9 @@ assign_varying_locations(struct gl_context *ctx,
|
|||
}
|
||||
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
if (!tfeedback_decls[i].is_varying())
|
||||
continue;
|
||||
|
||||
if (!tfeedback_decls[i].is_assigned() &&
|
||||
tfeedback_decls[i].matches_var(output_var)) {
|
||||
if (output_var->location == -1) {
|
||||
|
|
@ -2059,9 +2128,6 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
memset(&prog->LinkedTransformFeedback, 0,
|
||||
sizeof(prog->LinkedTransformFeedback));
|
||||
|
||||
prog->LinkedTransformFeedback.NumBuffers =
|
||||
separate_attribs_mode ? num_tfeedback_decls : 1;
|
||||
|
||||
prog->LinkedTransformFeedback.Varyings =
|
||||
rzalloc_array(prog,
|
||||
struct gl_transform_feedback_varying_info,
|
||||
|
|
@ -2077,14 +2143,37 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
|||
struct gl_transform_feedback_output,
|
||||
num_outputs);
|
||||
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
unsigned buffer = separate_attribs_mode ? i : 0;
|
||||
if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
|
||||
buffer, i, num_outputs))
|
||||
return false;
|
||||
unsigned num_buffers = 0;
|
||||
|
||||
if (separate_attribs_mode) {
|
||||
/* GL_SEPARATE_ATTRIBS */
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
|
||||
num_buffers, num_outputs))
|
||||
return false;
|
||||
|
||||
num_buffers++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* GL_INVERLEAVED_ATTRIBS */
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
if (tfeedback_decls[i].is_next_buffer_separator()) {
|
||||
num_buffers++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tfeedback_decls[i].store(ctx, prog,
|
||||
&prog->LinkedTransformFeedback,
|
||||
num_buffers, num_outputs))
|
||||
return false;
|
||||
}
|
||||
num_buffers++;
|
||||
}
|
||||
|
||||
assert(prog->LinkedTransformFeedback.NumOutputs == num_outputs);
|
||||
|
||||
prog->LinkedTransformFeedback.NumBuffers = num_buffers;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ static const struct extension extension_table[] = {
|
|||
{ "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 },
|
||||
{ "GL_ARB_timer_query", o(ARB_timer_query), GL, 2010 },
|
||||
{ "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 },
|
||||
{ "GL_ARB_transform_feedback3", o(ARB_transform_feedback3), GL, 2010 },
|
||||
{ "GL_ARB_transpose_matrix", o(ARB_transpose_matrix), GL, 1999 },
|
||||
{ "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL, 2009 },
|
||||
{ "GL_ARB_vertex_array_bgra", o(EXT_vertex_array_bgra), GL, 2008 },
|
||||
|
|
|
|||
|
|
@ -2937,6 +2937,7 @@ struct gl_extensions
|
|||
GLboolean ARB_texture_storage;
|
||||
GLboolean ARB_timer_query;
|
||||
GLboolean ARB_transform_feedback2;
|
||||
GLboolean ARB_transform_feedback3;
|
||||
GLboolean ARB_transpose_matrix;
|
||||
GLboolean ARB_uniform_buffer_object;
|
||||
GLboolean ARB_vertex_array_object;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue