mesa/glsl: move LinkedTransformFeedback from gl_shader_program to gl_program
authorTimothy Arceri <timothy.arceri@collabora.com>
Thu, 3 Nov 2016 05:00:37 +0000 (16:00 +1100)
committerTimothy Arceri <timothy.arceri@collabora.com>
Thu, 29 Dec 2016 23:57:16 +0000 (10:57 +1100)
This will help allow us to store gl_program in the CurrentProgram array rather
than gl_shader_program which will allow a bunch of simplifications.

Note that we make LinkedTransformFeedback a pointer so we don't waste
memory creating a struct for each stage. We also store a pointer to
the gl_program that will contain the pointer in gl_shader_program so
we can get easy access to the correct stage.

Reviewed-by: Eric Anholt <eric@anholt.net>
12 files changed:
src/compiler/glsl/link_varyings.cpp
src/compiler/glsl/linker.cpp
src/mesa/drivers/dri/i965/brw_ff_gs.c
src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
src/mesa/drivers/dri/i965/gen6_sol.c
src/mesa/drivers/dri/i965/gen7_sol_state.c
src/mesa/main/mtypes.h
src/mesa/main/shader_query.cpp
src/mesa/main/transformfeedback.c
src/mesa/state_tracker/st_cb_xformfb.c
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_program.c

index 866570c8238ab3de50b4b2ecd536e9313f5dcf08..e1a29b03549ee741b333b2bb1007796dcc2630db 100644 (file)
@@ -1063,7 +1063,8 @@ cmp_xfb_offset(const void * x_generic, const void * y_generic)
 
 /**
  * Store transform feedback location assignments into
- * prog->LinkedTransformFeedback based on the data stored in tfeedback_decls.
+ * prog->sh.LinkedTransformFeedback based on the data stored in
+ * tfeedback_decls.
  *
  * If an error occurs, the error is reported through linker_error() and false
  * is returned.
@@ -1081,11 +1082,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
    bool separate_attribs_mode =
       prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
 
-   ralloc_free(prog->LinkedTransformFeedback.Varyings);
-   ralloc_free(prog->LinkedTransformFeedback.Outputs);
-
-   memset(&prog->LinkedTransformFeedback, 0,
-          sizeof(prog->LinkedTransformFeedback));
+   struct gl_program *xfb_prog = prog->xfb_program;
+   xfb_prog->sh.LinkedTransformFeedback =
+      rzalloc(xfb_prog, struct gl_transform_feedback_info);
 
    /* The xfb_offset qualifier does not have to be used in increasing order
     * however some drivers expect to receive the list of transform feedback
@@ -1095,9 +1094,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
       qsort(tfeedback_decls, num_tfeedback_decls, sizeof(*tfeedback_decls),
             cmp_xfb_offset);
 
-   prog->LinkedTransformFeedback.Varyings =
-      rzalloc_array(prog,
-                    struct gl_transform_feedback_varying_info,
+   xfb_prog->sh.LinkedTransformFeedback->Varyings =
+      rzalloc_array(xfb_prog, struct gl_transform_feedback_varying_info,
                     num_tfeedback_decls);
 
    unsigned num_outputs = 0;
@@ -1106,9 +1104,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
          num_outputs += tfeedback_decls[i].get_num_outputs();
    }
 
-   prog->LinkedTransformFeedback.Outputs =
-      rzalloc_array(prog,
-                    struct gl_transform_feedback_output,
+   xfb_prog->sh.LinkedTransformFeedback->Outputs =
+      rzalloc_array(xfb_prog, struct gl_transform_feedback_output,
                     num_outputs);
 
    unsigned num_buffers = 0;
@@ -1117,7 +1114,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
    if (!has_xfb_qualifiers && separate_attribs_mode) {
       /* GL_SEPARATE_ATTRIBS */
       for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
-         if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
+         if (!tfeedback_decls[i].store(ctx, prog,
+                                       xfb_prog->sh.LinkedTransformFeedback,
                                        num_buffers, num_buffers, num_outputs,
                                        NULL, has_xfb_qualifiers))
             return false;
@@ -1139,7 +1137,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
             if (prog->TransformFeedback.BufferStride[j]) {
                buffers |= 1 << j;
                explicit_stride[j] = true;
-               prog->LinkedTransformFeedback.Buffers[j].Stride =
+               xfb_prog->sh.LinkedTransformFeedback->Buffers[j].Stride =
                   prog->TransformFeedback.BufferStride[j] / 4;
             }
          }
@@ -1155,7 +1153,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
 
          if (tfeedback_decls[i].is_next_buffer_separator()) {
             if (!tfeedback_decls[i].store(ctx, prog,
-                                          &prog->LinkedTransformFeedback,
+                                          xfb_prog->sh.LinkedTransformFeedback,
                                           buffer, num_buffers, num_outputs,
                                           explicit_stride, has_xfb_qualifiers))
                return false;
@@ -1189,16 +1187,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
          buffers |= 1 << buffer;
 
          if (!tfeedback_decls[i].store(ctx, prog,
-                                       &prog->LinkedTransformFeedback,
+                                       xfb_prog->sh.LinkedTransformFeedback,
                                        buffer, num_buffers, num_outputs,
                                        explicit_stride, has_xfb_qualifiers))
             return false;
       }
    }
 
-   assert(prog->LinkedTransformFeedback.NumOutputs == num_outputs);
+   assert(xfb_prog->sh.LinkedTransformFeedback->NumOutputs == num_outputs);
 
-   prog->LinkedTransformFeedback.ActiveBuffers = buffers;
+   xfb_prog->sh.LinkedTransformFeedback->ActiveBuffers = buffers;
    return true;
 }
 
index e5cc6de2d128ce32f50f08bb681619957e68b746..209129c3ea0cdf98d1b6c0bec0a6c8757fbe4e20 100644 (file)
@@ -4242,25 +4242,26 @@ build_program_resource_list(struct gl_context *ctx,
                                 output_stage, GL_PROGRAM_OUTPUT))
       return;
 
+   struct gl_transform_feedback_info *linked_xfb =
+      shProg->xfb_program->sh.LinkedTransformFeedback;
+
    /* Add transform feedback varyings. */
-   if (shProg->LinkedTransformFeedback.NumVarying > 0) {
-      for (int i = 0; i < shProg->LinkedTransformFeedback.NumVarying; i++) {
+   if (linked_xfb->NumVarying > 0) {
+      for (int i = 0; i < linked_xfb->NumVarying; i++) {
          if (!add_program_resource(shProg, resource_set,
                                    GL_TRANSFORM_FEEDBACK_VARYING,
-                                   &shProg->LinkedTransformFeedback.Varyings[i],
-                                   0))
+                                   &linked_xfb->Varyings[i], 0))
          return;
       }
    }
 
    /* Add transform feedback buffers. */
    for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
-      if ((shProg->LinkedTransformFeedback.ActiveBuffers >> i) & 1) {
-         shProg->LinkedTransformFeedback.Buffers[i].Binding = i;
+      if ((linked_xfb->ActiveBuffers >> i) & 1) {
+         linked_xfb->Buffers[i].Binding = i;
          if (!add_program_resource(shProg, resource_set,
                                    GL_TRANSFORM_FEEDBACK_BUFFER,
-                                   &shProg->LinkedTransformFeedback.Buffers[i],
-                                   0))
+                                   &linked_xfb->Buffers[i], 0))
          return;
       }
    }
@@ -4587,6 +4588,18 @@ link_varyings_and_uniforms(unsigned first, unsigned last,
       varying_names = prog->TransformFeedback.VaryingNames;
    }
 
+   /* Find the program used for xfb. Even if we don't use xfb we still want to
+    * set this so we can fill the default values for program interface query.
+    */
+   prog->xfb_program = prog->_LinkedShaders[last]->Program;
+   for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
+      if (prog->_LinkedShaders[i] == NULL)
+         continue;
+
+      prog->xfb_program = prog->_LinkedShaders[i]->Program;
+      break;
+   }
+
    if (num_tfeedback_decls != 0) {
       /* From GL_EXT_transform_feedback:
        *   A program will fail to link if:
index c7129393e5443d055f81801e643726b9110a5576..4934af3fd398a3106d721b9aefaf8da3e74738cf 100644 (file)
@@ -198,7 +198,7 @@ brw_ff_gs_populate_key(struct brw_context *brw,
          const struct gl_shader_program *shaderprog =
             ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
          const struct gl_transform_feedback_info *linked_xfb_info =
-            &shaderprog->LinkedTransformFeedback;
+            shaderprog->xfb_program->sh.LinkedTransformFeedback;
          int i;
 
          /* Make sure that the VUE slots won't overflow the unsigned chars in
index 7254729f41c944a8a177b51be3d343ef2bd04991..4bd37889817a5fc2ccd79a08f4845f3b72961f9e 100644 (file)
@@ -534,7 +534,7 @@ gen6_gs_visitor::xfb_setup()
    };
 
    const struct gl_transform_feedback_info *linked_xfb_info =
-      &this->shader_prog->LinkedTransformFeedback;
+      this->shader_prog->xfb_program->sh.LinkedTransformFeedback;
    int i;
 
    /* Make sure that the VUE slots won't overflow the unsigned chars in
index 6574749079c5991f157d45229f8bdcfe59174a2e..f6a183ad169e12aabf9e609854b73d0e97fe1d64 100644 (file)
@@ -45,7 +45,8 @@ gen6_update_sol_surfaces(struct brw_context *brw)
    if (xfb_active) {
       /* BRW_NEW_TRANSFORM_FEEDBACK */
       xfb_obj = ctx->TransformFeedback.CurrentObject;
-      linked_xfb_info = &xfb_obj->shader_program->LinkedTransformFeedback;
+      linked_xfb_info =
+         xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback;
    }
 
    for (int i = 0; i < BRW_MAX_SOL_BINDINGS; ++i) {
@@ -116,7 +117,7 @@ brw_gs_upload_binding_table(struct brw_context *brw)
       if (shaderprog) {
          /* Skip making a binding table if we don't have anything to put in it */
          const struct gl_transform_feedback_info *linked_xfb_info =
-            &shaderprog->LinkedTransformFeedback;
+            shaderprog->xfb_program->sh.LinkedTransformFeedback;
          need_binding_table = linked_xfb_info->NumOutputs > 0;
       }
       if (!need_binding_table) {
@@ -145,7 +146,7 @@ brw_gs_upload_binding_table(struct brw_context *brw)
          /* Skip making a binding table if we don't have anything to put in it */
          struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data;
          const struct gl_transform_feedback_info *linked_xfb_info =
-            &shaderprog->LinkedTransformFeedback;
+            shaderprog->xfb_program->sh.LinkedTransformFeedback;
          need_binding_table = linked_xfb_info->NumOutputs > 0 ||
                               prog_data->binding_table.size_bytes > 0;
       }
@@ -241,7 +242,7 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
       shaderprog =
          ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
    }
-   linked_xfb_info = &shaderprog->LinkedTransformFeedback;
+   linked_xfb_info = shaderprog->xfb_program->sh.LinkedTransformFeedback;
 
    /* Compute the maximum number of vertices that we can write without
     * overflowing any of the buffers currently being used for feedback.
index 17752742d465eb8499e6797cf61b89ebcab83176..5170f6a16ea25aba63549c0962fe7a780ffe44af 100644 (file)
@@ -43,7 +43,7 @@ upload_3dstate_so_buffers(struct brw_context *brw)
    struct gl_transform_feedback_object *xfb_obj =
       ctx->TransformFeedback.CurrentObject;
    const struct gl_transform_feedback_info *linked_xfb_info =
-      &xfb_obj->shader_program->LinkedTransformFeedback;
+      xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback;
    int i;
 
    /* Set up the up to 4 output buffers.  These are the ranges defined in the
@@ -103,7 +103,7 @@ gen7_upload_3dstate_so_decl_list(struct brw_context *brw,
    struct gl_transform_feedback_object *xfb_obj =
       ctx->TransformFeedback.CurrentObject;
    const struct gl_transform_feedback_info *linked_xfb_info =
-      &xfb_obj->shader_program->LinkedTransformFeedback;
+      xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback;
    uint16_t so_decl[MAX_VERTEX_STREAMS][128];
    int buffer_mask[MAX_VERTEX_STREAMS] = {0, 0, 0, 0};
    int next_offset[MAX_VERTEX_STREAMS] = {0, 0, 0, 0};
@@ -229,7 +229,7 @@ upload_3dstate_streamout(struct brw_context *brw, bool active,
    struct gl_transform_feedback_object *xfb_obj =
       ctx->TransformFeedback.CurrentObject;
    const struct gl_transform_feedback_info *linked_xfb_info =
-      &xfb_obj->shader_program->LinkedTransformFeedback;
+      xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback;
    uint32_t dw1 = 0, dw2 = 0, dw3 = 0, dw4 = 0;
    int i;
 
index 8842791913ea97a7eac7e45ae78db28b2fb8d50a..9b736bb9a3ff2d1105818e9a2cdaa8c2a3884681 100644 (file)
@@ -1950,6 +1950,9 @@ struct gl_program
       struct {
          struct gl_active_atomic_buffer **AtomicBuffers;
 
+         /** Post-link transform feedback info. */
+         struct gl_transform_feedback_info *LinkedTransformFeedback;
+
          /**
           * Number of types for subroutine uniforms.
           */
@@ -2737,8 +2740,7 @@ struct gl_shader_program
       GLchar **VaryingNames;  /**< Array [NumVarying] of char * */
    } TransformFeedback;
 
-   /** Post-link transform feedback info. */
-   struct gl_transform_feedback_info LinkedTransformFeedback;
+   struct gl_program *xfb_program;
 
    /** Post-link gl_FragDepth layout for ARB_conservative_depth. */
    enum gl_frag_depth_layout FragDepthLayout;
index 2f157733a48c7ac5e02bf789fbda40154354e6e6..0f4b2829ce4f094db7f02685ce161bb3179feb67 100644 (file)
@@ -1041,10 +1041,10 @@ get_buffer_property(struct gl_shader_program *shProg,
          *val = RESOURCE_XFB(res)->NumVaryings;
          return 1;
       case GL_ACTIVE_VARIABLES:
-         int i = 0;
-         for ( ; i < shProg->LinkedTransformFeedback.NumVarying; i++) {
-            unsigned index =
-               shProg->LinkedTransformFeedback.Varyings[i].BufferIndex;
+         struct gl_transform_feedback_info *linked_xfb =
+            shProg->xfb_program->sh.LinkedTransformFeedback;
+         for (int i = 0; i < linked_xfb->NumVarying; i++) {
+            unsigned index = linked_xfb->Varyings[i].BufferIndex;
             struct gl_program_resource *buf_res =
                _mesa_program_resource_find_index(shProg,
                                                  GL_TRANSFORM_FEEDBACK_BUFFER,
index 738d63eee37ab894fa64edf08bd2710a824b4005..2088c76e5ea2bf391bf1b11dc74c9d172c0e7b38 100644 (file)
@@ -418,7 +418,7 @@ _mesa_BeginTransformFeedback(GLenum mode)
       return;
    }
 
-   info = &source->LinkedTransformFeedback;
+   info = source->xfb_program->sh.LinkedTransformFeedback;
 
    if (info->NumOutputs == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
index a5cf3dfd5a940d082bfbc277351c4d65d0f412d9..bbc9e03dd0796b6407061ac8adf417b92534e899 100644 (file)
@@ -124,8 +124,8 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
       struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]);
 
       if (bo && bo->buffer) {
-         unsigned stream =
-            obj->shader_program->LinkedTransformFeedback.Buffers[i].Stream;
+         unsigned stream = obj->shader_program->xfb_program->
+            sh.LinkedTransformFeedback->Buffers[i].Stream;
 
          /* Check whether we need to recreate the target. */
          if (!sobj->targets[i] ||
@@ -203,8 +203,8 @@ st_end_transform_feedback(struct gl_context *ctx,
       pipe_so_target_reference(&sobj->draw_count[i], NULL);
 
    for (i = 0; i < ARRAY_SIZE(sobj->targets); i++) {
-      unsigned stream =
-         obj->shader_program->LinkedTransformFeedback.Buffers[i].Stream;
+      unsigned stream = obj->shader_program->xfb_program->
+         sh.LinkedTransformFeedback->Buffers[i].Stream;
 
       /* Is it not bound or already set for this stream? */
       if (!sobj->targets[i] || sobj->draw_count[stream])
index c9ebb5ade8f7ae72cfce8011958ec0eac5e7d922..95992965ed8d20cfc3cdf6252c3feac75712a258 100644 (file)
@@ -6919,7 +6919,7 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi,
                                 struct pipe_stream_output_info *so)
 {
    struct gl_transform_feedback_info *info =
-      &glsl_to_tgsi->shader_program->LinkedTransformFeedback;
+      glsl_to_tgsi->shader_program->xfb_program->sh.LinkedTransformFeedback;
    st_translate_stream_output_info2(info, outputMapping, so);
 }
 
index bf1503197e07db71d55b29d4e8f08b58a5b88ca0..e9dd5846698f688c41cfd9d9d4a6e3e00d97ce6b 100644 (file)
@@ -390,7 +390,7 @@ st_translate_vertex_program(struct st_context *st,
       stvp->tgsi.type = PIPE_SHADER_IR_NIR;
       stvp->tgsi.ir.nir = nir;
 
-      st_translate_stream_output_info2(&stvp->shader_program->LinkedTransformFeedback,
+      st_translate_stream_output_info2(stvp->shader_program->xfb_program->sh.LinkedTransformFeedback,
                                        stvp->result_to_output,
                                        &stvp->tgsi.stream_output);
       return true;