mesa/glsl: move LinkedTransformFeedback from gl_shader_program to gl_program

This will help allow us to store gl_program in the CurrentProgram array rather
than gl_shader_program which will allow a bunch of simplifications.

Note that we make LinkedTransformFeedback a pointer so we don't waste
memory creating a struct for each stage. We also store a pointer to
the gl_program that will contain the pointer in gl_shader_program so
we can get easy access to the correct stage.

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Timothy Arceri
2016-11-03 16:00:37 +11:00
parent 31c04e4e22
commit 700bc94dce
12 changed files with 62 additions and 48 deletions

View File

@@ -1063,7 +1063,8 @@ cmp_xfb_offset(const void * x_generic, const void * y_generic)
/**
* Store transform feedback location assignments into
* prog->LinkedTransformFeedback based on the data stored in tfeedback_decls.
* prog->sh.LinkedTransformFeedback based on the data stored in
* tfeedback_decls.
*
* If an error occurs, the error is reported through linker_error() and false
* is returned.
@@ -1081,11 +1082,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
bool separate_attribs_mode =
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
ralloc_free(prog->LinkedTransformFeedback.Varyings);
ralloc_free(prog->LinkedTransformFeedback.Outputs);
memset(&prog->LinkedTransformFeedback, 0,
sizeof(prog->LinkedTransformFeedback));
struct gl_program *xfb_prog = prog->xfb_program;
xfb_prog->sh.LinkedTransformFeedback =
rzalloc(xfb_prog, struct gl_transform_feedback_info);
/* The xfb_offset qualifier does not have to be used in increasing order
* however some drivers expect to receive the list of transform feedback
@@ -1095,9 +1094,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
qsort(tfeedback_decls, num_tfeedback_decls, sizeof(*tfeedback_decls),
cmp_xfb_offset);
prog->LinkedTransformFeedback.Varyings =
rzalloc_array(prog,
struct gl_transform_feedback_varying_info,
xfb_prog->sh.LinkedTransformFeedback->Varyings =
rzalloc_array(xfb_prog, struct gl_transform_feedback_varying_info,
num_tfeedback_decls);
unsigned num_outputs = 0;
@@ -1106,9 +1104,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
num_outputs += tfeedback_decls[i].get_num_outputs();
}
prog->LinkedTransformFeedback.Outputs =
rzalloc_array(prog,
struct gl_transform_feedback_output,
xfb_prog->sh.LinkedTransformFeedback->Outputs =
rzalloc_array(xfb_prog, struct gl_transform_feedback_output,
num_outputs);
unsigned num_buffers = 0;
@@ -1117,7 +1114,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
if (!has_xfb_qualifiers && separate_attribs_mode) {
/* GL_SEPARATE_ATTRIBS */
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
if (!tfeedback_decls[i].store(ctx, prog,
xfb_prog->sh.LinkedTransformFeedback,
num_buffers, num_buffers, num_outputs,
NULL, has_xfb_qualifiers))
return false;
@@ -1139,7 +1137,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
if (prog->TransformFeedback.BufferStride[j]) {
buffers |= 1 << j;
explicit_stride[j] = true;
prog->LinkedTransformFeedback.Buffers[j].Stride =
xfb_prog->sh.LinkedTransformFeedback->Buffers[j].Stride =
prog->TransformFeedback.BufferStride[j] / 4;
}
}
@@ -1155,7 +1153,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
if (tfeedback_decls[i].is_next_buffer_separator()) {
if (!tfeedback_decls[i].store(ctx, prog,
&prog->LinkedTransformFeedback,
xfb_prog->sh.LinkedTransformFeedback,
buffer, num_buffers, num_outputs,
explicit_stride, has_xfb_qualifiers))
return false;
@@ -1189,16 +1187,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
buffers |= 1 << buffer;
if (!tfeedback_decls[i].store(ctx, prog,
&prog->LinkedTransformFeedback,
xfb_prog->sh.LinkedTransformFeedback,
buffer, num_buffers, num_outputs,
explicit_stride, has_xfb_qualifiers))
return false;
}
}
assert(prog->LinkedTransformFeedback.NumOutputs == num_outputs);
assert(xfb_prog->sh.LinkedTransformFeedback->NumOutputs == num_outputs);
prog->LinkedTransformFeedback.ActiveBuffers = buffers;
xfb_prog->sh.LinkedTransformFeedback->ActiveBuffers = buffers;
return true;
}

View File

@@ -4242,25 +4242,26 @@ build_program_resource_list(struct gl_context *ctx,
output_stage, GL_PROGRAM_OUTPUT))
return;
struct gl_transform_feedback_info *linked_xfb =
shProg->xfb_program->sh.LinkedTransformFeedback;
/* Add transform feedback varyings. */
if (shProg->LinkedTransformFeedback.NumVarying > 0) {
for (int i = 0; i < shProg->LinkedTransformFeedback.NumVarying; i++) {
if (linked_xfb->NumVarying > 0) {
for (int i = 0; i < linked_xfb->NumVarying; i++) {
if (!add_program_resource(shProg, resource_set,
GL_TRANSFORM_FEEDBACK_VARYING,
&shProg->LinkedTransformFeedback.Varyings[i],
0))
&linked_xfb->Varyings[i], 0))
return;
}
}
/* Add transform feedback buffers. */
for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
if ((shProg->LinkedTransformFeedback.ActiveBuffers >> i) & 1) {
shProg->LinkedTransformFeedback.Buffers[i].Binding = i;
if ((linked_xfb->ActiveBuffers >> i) & 1) {
linked_xfb->Buffers[i].Binding = i;
if (!add_program_resource(shProg, resource_set,
GL_TRANSFORM_FEEDBACK_BUFFER,
&shProg->LinkedTransformFeedback.Buffers[i],
0))
&linked_xfb->Buffers[i], 0))
return;
}
}
@@ -4587,6 +4588,18 @@ link_varyings_and_uniforms(unsigned first, unsigned last,
varying_names = prog->TransformFeedback.VaryingNames;
}
/* Find the program used for xfb. Even if we don't use xfb we still want to
* set this so we can fill the default values for program interface query.
*/
prog->xfb_program = prog->_LinkedShaders[last]->Program;
for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
if (prog->_LinkedShaders[i] == NULL)
continue;
prog->xfb_program = prog->_LinkedShaders[i]->Program;
break;
}
if (num_tfeedback_decls != 0) {
/* From GL_EXT_transform_feedback:
* A program will fail to link if: