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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user