mesa/program_interface_query: fix transform feedback varyings.

The spec says gl_NextBuffer and gl_SkipComponents need to be
returned to userspace in the program interface queries.

We currently throw those away, this requires a complete piglit
run to make sure no drivers fallover due to the extra varyings.

This fixes:
GL45-CTS.program_interface_query.transform-feedback-built-in

Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie
2016-05-24 07:58:32 +10:00
parent 6effdce92e
commit e2791b38b4
2 changed files with 48 additions and 35 deletions

View File

@@ -812,15 +812,20 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
const unsigned max_outputs, bool *explicit_stride, const unsigned max_outputs, bool *explicit_stride,
bool has_xfb_qualifiers) const bool has_xfb_qualifiers) const
{ {
assert(!this->next_buffer_separator); unsigned xfb_offset = 0;
unsigned size = this->size;
/* Handle gl_SkipComponents. */ /* Handle gl_SkipComponents. */
if (this->skip_components) { if (this->skip_components) {
info->Buffers[buffer].Stride += this->skip_components; info->Buffers[buffer].Stride += this->skip_components;
return true; size = this->skip_components;
goto store_varying;
}
if (this->next_buffer_separator) {
size = 0;
goto store_varying;
} }
unsigned xfb_offset = 0;
if (has_xfb_qualifiers) { if (has_xfb_qualifiers) {
xfb_offset = this->offset / 4; xfb_offset = this->offset / 4;
} else { } else {
@@ -828,37 +833,39 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
} }
info->Varyings[info->NumVarying].Offset = xfb_offset * 4; info->Varyings[info->NumVarying].Offset = xfb_offset * 4;
unsigned location = this->location; {
unsigned location_frac = this->location_frac; unsigned location = this->location;
unsigned num_components = this->num_components(); unsigned location_frac = this->location_frac;
while (num_components > 0) { unsigned num_components = this->num_components();
unsigned output_size = MIN2(num_components, 4 - location_frac); while (num_components > 0) {
assert((info->NumOutputs == 0 && max_outputs == 0) || unsigned output_size = MIN2(num_components, 4 - location_frac);
info->NumOutputs < max_outputs); assert((info->NumOutputs == 0 && max_outputs == 0) ||
info->NumOutputs < max_outputs);
/* From the ARB_enhanced_layouts spec: /* From the ARB_enhanced_layouts spec:
* *
* "If such a block member or variable is not written during a shader * "If such a block member or variable is not written during a shader
* invocation, the buffer contents at the assigned offset will be * invocation, the buffer contents at the assigned offset will be
* undefined. Even if there are no static writes to a variable or * undefined. Even if there are no static writes to a variable or
* member that is assigned a transform feedback offset, the space is * member that is assigned a transform feedback offset, the space is
* still allocated in the buffer and still affects the stride." * still allocated in the buffer and still affects the stride."
*/ */
if (this->is_varying_written()) { if (this->is_varying_written()) {
info->Outputs[info->NumOutputs].ComponentOffset = location_frac; info->Outputs[info->NumOutputs].ComponentOffset = location_frac;
info->Outputs[info->NumOutputs].OutputRegister = location; info->Outputs[info->NumOutputs].OutputRegister = location;
info->Outputs[info->NumOutputs].NumComponents = output_size; info->Outputs[info->NumOutputs].NumComponents = output_size;
info->Outputs[info->NumOutputs].StreamId = stream_id; info->Outputs[info->NumOutputs].StreamId = stream_id;
info->Outputs[info->NumOutputs].OutputBuffer = buffer; info->Outputs[info->NumOutputs].OutputBuffer = buffer;
info->Outputs[info->NumOutputs].DstOffset = xfb_offset; info->Outputs[info->NumOutputs].DstOffset = xfb_offset;
++info->NumOutputs; ++info->NumOutputs;
}
info->Buffers[buffer].Stream = this->stream_id;
xfb_offset += output_size;
num_components -= output_size;
location++;
location_frac = 0;
} }
info->Buffers[buffer].Stream = this->stream_id;
xfb_offset += output_size;
num_components -= output_size;
location++;
location_frac = 0;
} }
if (explicit_stride && explicit_stride[buffer]) { if (explicit_stride && explicit_stride[buffer]) {
@@ -903,10 +910,11 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
return false; return false;
} }
store_varying:
info->Varyings[info->NumVarying].Name = ralloc_strdup(prog, info->Varyings[info->NumVarying].Name = ralloc_strdup(prog,
this->orig_name); this->orig_name);
info->Varyings[info->NumVarying].Type = this->type; info->Varyings[info->NumVarying].Type = this->type;
info->Varyings[info->NumVarying].Size = this->size; info->Varyings[info->NumVarying].Size = size;
info->Varyings[info->NumVarying].BufferIndex = buffer_index; info->Varyings[info->NumVarying].BufferIndex = buffer_index;
info->NumVarying++; info->NumVarying++;
info->Buffers[buffer].NumVaryings++; info->Buffers[buffer].NumVaryings++;
@@ -1101,6 +1109,11 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
} }
if (tfeedback_decls[i].is_next_buffer_separator()) { if (tfeedback_decls[i].is_next_buffer_separator()) {
if (!tfeedback_decls[i].store(ctx, prog,
&prog->LinkedTransformFeedback,
buffer, num_buffers, num_outputs,
explicit_stride, has_xfb_qualifiers))
return false;
num_buffers++; num_buffers++;
buffer_stream_id = -1; buffer_stream_id = -1;
continue; continue;

View File

@@ -1143,7 +1143,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
*val = MAX2(_mesa_program_resource_array_size(res), 1); *val = MAX2(_mesa_program_resource_array_size(res), 1);
return 1; return 1;
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
*val = MAX2(RESOURCE_XFV(res)->Size, 1); *val = RESOURCE_XFV(res)->Size;
return 1; return 1;
default: default:
goto invalid_operation; goto invalid_operation;