mesa/glsl: move TransformFeedbackBufferStride to gl_shader

Here we remove the single use of this field in gl_linked_shader
which allows us to move the field out of gl_shader_info

While we are at it we rewrite link_xfb_stride_layout_qualifiers()
to be more clear.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
Timothy Arceri 2016-11-22 20:24:33 +11:00
parent e603cf1841
commit 4d65f68a9b
4 changed files with 41 additions and 45 deletions

View File

@ -1704,7 +1704,7 @@ set_shader_inout_layout(struct gl_shader *shader,
if (state->out_qualifier->out_xfb_stride[i]->
process_qualifier_constant(state, "xfb_stride", &xfb_stride,
true)) {
shader->info.TransformFeedback.BufferStride[i] = xfb_stride;
shader->TransformFeedbackBufferStride[i] = xfb_stride;
}
}
}

View File

@ -108,6 +108,7 @@ create_xfb_varying_names(void *mem_ctx, const glsl_type *t, char **name,
static bool
process_xfb_layout_qualifiers(void *mem_ctx, const gl_linked_shader *sh,
struct gl_shader_program *prog,
unsigned *num_tfeedback_decls,
char ***varying_names)
{
@ -118,7 +119,7 @@ process_xfb_layout_qualifiers(void *mem_ctx, const gl_linked_shader *sh,
* xfb_stride to interface block members so this will catch that case also.
*/
for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
if (sh->info.TransformFeedback.BufferStride[j]) {
if (prog->TransformFeedback.BufferStride[j]) {
has_xfb_qualifiers = true;
break;
}
@ -2397,7 +2398,7 @@ link_varyings(struct gl_shader_program *prog, unsigned first, unsigned last,
if (prog->_LinkedShaders[i]) {
has_xfb_qualifiers =
process_xfb_layout_qualifiers(mem_ctx, prog->_LinkedShaders[i],
&num_tfeedback_decls,
prog, &num_tfeedback_decls,
&varying_names);
break;
}

View File

@ -1587,6 +1587,29 @@ private:
hash_table *unnamed_interfaces;
};
static bool
validate_xfb_buffer_stride(struct gl_context *ctx, unsigned idx,
struct gl_shader_program *prog)
{
/* We will validate doubles at a later stage */
if (prog->TransformFeedback.BufferStride[idx] % 4) {
linker_error(prog, "invalid qualifier xfb_stride=%d must be a "
"multiple of 4 or if its applied to a type that is "
"or contains a double a multiple of 8.",
prog->TransformFeedback.BufferStride[idx]);
return false;
}
if (prog->TransformFeedback.BufferStride[idx] / 4 >
ctx->Const.MaxTransformFeedbackInterleavedComponents) {
linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
"limit has been exceeded.");
return false;
}
return true;
}
/**
* Check for conflicting xfb_stride default qualifiers and store buffer stride
* for later use.
@ -1599,54 +1622,28 @@ link_xfb_stride_layout_qualifiers(struct gl_context *ctx,
unsigned num_shaders)
{
for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
linked_shader->info.TransformFeedback.BufferStride[i] = 0;
prog->TransformFeedback.BufferStride[i] = 0;
}
for (unsigned i = 0; i < num_shaders; i++) {
struct gl_shader *shader = shader_list[i];
for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
if (shader->info.TransformFeedback.BufferStride[j]) {
if (linked_shader->info.TransformFeedback.BufferStride[j] != 0 &&
shader->info.TransformFeedback.BufferStride[j] != 0 &&
linked_shader->info.TransformFeedback.BufferStride[j] !=
shader->info.TransformFeedback.BufferStride[j]) {
if (shader->TransformFeedbackBufferStride[j]) {
if (prog->TransformFeedback.BufferStride[j] == 0) {
prog->TransformFeedback.BufferStride[j] =
shader->TransformFeedbackBufferStride[j];
if (!validate_xfb_buffer_stride(ctx, j, prog))
return;
} else if (prog->TransformFeedback.BufferStride[j] !=
shader->TransformFeedbackBufferStride[j]){
linker_error(prog,
"intrastage shaders defined with conflicting "
"xfb_stride for buffer %d (%d and %d)\n", j,
linked_shader->
info.TransformFeedback.BufferStride[j],
shader->info.TransformFeedback.BufferStride[j]);
prog->TransformFeedback.BufferStride[j],
shader->TransformFeedbackBufferStride[j]);
return;
}
if (shader->info.TransformFeedback.BufferStride[j])
linked_shader->info.TransformFeedback.BufferStride[j] =
shader->info.TransformFeedback.BufferStride[j];
}
}
}
for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
if (linked_shader->info.TransformFeedback.BufferStride[j]) {
prog->TransformFeedback.BufferStride[j] =
linked_shader->info.TransformFeedback.BufferStride[j];
/* We will validate doubles at a later stage */
if (prog->TransformFeedback.BufferStride[j] % 4) {
linker_error(prog, "invalid qualifier xfb_stride=%d must be a "
"multiple of 4 or if its applied to a type that is "
"or contains a double a multiple of 8.",
prog->TransformFeedback.BufferStride[j]);
return;
}
if (prog->TransformFeedback.BufferStride[j] / 4 >
ctx->Const.MaxTransformFeedbackInterleavedComponents) {
linker_error(prog,
"The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
"limit has been exceeded.");
return;
}
}
}

View File

@ -2242,11 +2242,6 @@ struct gl_subroutine_function
*/
struct gl_shader_info
{
struct {
/** Global xfb_stride out qualifier if any */
GLuint BufferStride[MAX_FEEDBACK_BUFFERS];
} TransformFeedback;
/**
* Tessellation Control shader state from layout qualifiers.
*/
@ -2436,6 +2431,9 @@ struct gl_shader
bool origin_upper_left;
bool pixel_center_integer;
/** Global xfb_stride out qualifier if any */
GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS];
struct gl_shader_info info;
};