+
+/**
+ * Allocate an extra vertex/geometry shader vertex attribute, if it doesn't
+ * exist already.
+ *
+ * This is used by some of the optional draw module stages such
+ * as wide_point which may need to allocate additional generic/texcoord
+ * attributes.
+ */
+int
+draw_alloc_extra_vertex_attrib(struct draw_context *draw,
+ uint semantic_name, uint semantic_index)
+{
+ int slot;
+ uint num_outputs;
+ uint n;
+
+ slot = draw_find_shader_output(draw, semantic_name, semantic_index);
+ if (slot >= 0) {
+ return slot;
+ }
+
+ num_outputs = draw_current_shader_outputs(draw);
+ n = draw->extra_shader_outputs.num;
+
+ assert(n < ARRAY_SIZE(draw->extra_shader_outputs.semantic_name));
+
+ draw->extra_shader_outputs.semantic_name[n] = semantic_name;
+ draw->extra_shader_outputs.semantic_index[n] = semantic_index;
+ draw->extra_shader_outputs.slot[n] = num_outputs + n;
+ draw->extra_shader_outputs.num++;
+
+ return draw->extra_shader_outputs.slot[n];
+}
+
+
+/**
+ * Remove all extra vertex attributes that were allocated with
+ * draw_alloc_extra_vertex_attrib().
+ */
+void
+draw_remove_extra_vertex_attribs(struct draw_context *draw)
+{
+ draw->extra_shader_outputs.num = 0;
+}
+
+
+/**
+ * If a geometry shader is present, return its info, else the vertex shader's
+ * info.
+ */
+struct tgsi_shader_info *
+draw_get_shader_info(const struct draw_context *draw)
+{
+
+ if (draw->gs.geometry_shader) {
+ return &draw->gs.geometry_shader->info;
+ } else {
+ return &draw->vs.vertex_shader->info;
+ }
+}
+
+/**
+ * Prepare outputs slots from the draw module
+ *
+ * Certain parts of the draw module can emit additional
+ * outputs that can be quite useful to the backends, a good
+ * example of it is the process of decomposing primitives
+ * into wireframes (aka. lines) which normally would lose
+ * the face-side information, but using this method we can
+ * inject another shader output which passes the original
+ * face side information to the backend.
+ */
+void
+draw_prepare_shader_outputs(struct draw_context *draw)
+{
+ draw_remove_extra_vertex_attribs(draw);
+ draw_prim_assembler_prepare_outputs(draw->ia);
+ draw_unfilled_prepare_outputs(draw, draw->pipeline.unfilled);
+ if (draw->pipeline.aapoint)
+ draw_aapoint_prepare_outputs(draw, draw->pipeline.aapoint);
+ if (draw->pipeline.aaline)
+ draw_aaline_prepare_outputs(draw, draw->pipeline.aaline);
+}
+