+
+ unsigned translated_size = this->size;
+ if (this->is_clip_distance_mesa)
+ translated_size = (translated_size + 3) / 4;
+
+ *count += translated_size * this->matrix_columns;
+
+ return true;
+}
+
+
+/**
+ * Update gl_transform_feedback_info to reflect this tfeedback_decl.
+ *
+ * If an error occurs, the error is reported through linker_error() and false
+ * is returned.
+ */
+bool
+tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
+ struct gl_transform_feedback_info *info,
+ 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:
+ *
+ * * the total number of components to capture is greater than
+ * the constant MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT
+ * and the buffer mode is INTERLEAVED_ATTRIBS_EXT.
+ */
+ if (prog->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS &&
+ info->BufferStride[buffer] + this->num_components() >
+ ctx->Const.MaxTransformFeedbackInterleavedComponents) {
+ linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
+ "limit has been exceeded.");
+ return false;
+ }
+
+ unsigned translated_size = this->size;
+ if (this->is_clip_distance_mesa)
+ translated_size = (translated_size + 3) / 4;
+ unsigned components_so_far = 0;
+ for (unsigned index = 0; index < translated_size; ++index) {
+ for (unsigned v = 0; v < this->matrix_columns; ++v) {
+ unsigned num_components = this->vector_elements;
+ assert(info->NumOutputs < max_outputs);
+ info->Outputs[info->NumOutputs].ComponentOffset = 0;
+ if (this->is_clip_distance_mesa) {
+ if (this->is_subscripted) {
+ num_components = 1;
+ info->Outputs[info->NumOutputs].ComponentOffset =
+ this->array_subscript % 4;
+ } else {
+ num_components = MIN2(4, this->size - components_so_far);
+ }
+ }
+ info->Outputs[info->NumOutputs].OutputRegister =
+ this->location + v + index * this->matrix_columns;
+ info->Outputs[info->NumOutputs].NumComponents = num_components;
+ info->Outputs[info->NumOutputs].OutputBuffer = buffer;
+ info->Outputs[info->NumOutputs].DstOffset = info->BufferStride[buffer];
+ ++info->NumOutputs;
+ info->BufferStride[buffer] += num_components;
+ components_so_far += num_components;
+ }