[Mesa-dev] [PATCH] st/glsl_to_tgsi: sort input and output decls by TGSI index

Nicolai Hähnle nhaehnle at gmail.com
Tue Oct 18 16:06:16 UTC 2016


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Fixes a regression introduced by commit 777dcf81b.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98307
--
Using std::sort here is quite a bit C++-ier than most parts of Mesa.
I used it because the standard C library is being its usual lame self.
If people think using qsort_r is fine from a portability point of view
(it's a glibc-ism), I'd be happy to use that instead.
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index f49a873..406f4d5 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -48,20 +48,21 @@
 #include "tgsi/tgsi_ureg.h"
 #include "tgsi/tgsi_info.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "st_program.h"
 #include "st_mesa_to_tgsi.h"
 #include "st_format.h"
 #include "st_glsl_types.h"
 #include "st_nir.h"
 
+#include <algorithm>
 
 #define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) |    \
                            (1 << PROGRAM_CONSTANT) |     \
                            (1 << PROGRAM_UNIFORM))
 
 #define MAX_GLSL_TEXTURE_OFFSET 4
 
 class st_src_reg;
 class st_dst_reg;
 
@@ -6092,20 +6093,43 @@ emit_compute_block_size(const struct gl_program *program,
       (const struct gl_compute_program *)program;
 
    ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH,
                        cp->LocalSize[0]);
    ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT,
                        cp->LocalSize[1]);
    ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH,
                        cp->LocalSize[2]);
 }
 
+struct sort_inout_decls {
+   bool operator()(const struct inout_decl &a, const struct inout_decl &b) const {
+      return mapping[a.mesa_index] < mapping[b.mesa_index];
+   }
+
+   const GLuint *mapping;
+};
+
+/* Sort the given array of decls by the corresponding slot (TGSI file index).
+ *
+ * This is for the benefit of older drivers which are broken when the
+ * declarations aren't sorted in this way.
+ */
+static void
+sort_inout_decls_by_slot(struct inout_decl *decls,
+                         unsigned count,
+                         const GLuint mapping[])
+{
+   sort_inout_decls sorter;
+   sorter.mapping = mapping;
+   std::sort(decls, decls + count, sorter);
+}
+
 /**
  * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format.
  * \param program  the program to translate
  * \param numInputs  number of input registers used
  * \param inputMapping  maps Mesa fragment program inputs to TGSI generic
  *                      input indexes
  * \param inputSemanticName  the TGSI_SEMANTIC flag for each input
  * \param inputSemanticIndex  the semantic index (ex: which texcoord) for
  *                            each input
  * \param interpMode  the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
@@ -6164,20 +6188,22 @@ st_translate_program(
                   calloc(t->num_temp_arrays, sizeof(t->arrays[0]));
 
    /*
     * Declare input attributes.
     */
    switch (procType) {
    case PIPE_SHADER_FRAGMENT:
    case PIPE_SHADER_GEOMETRY:
    case PIPE_SHADER_TESS_EVAL:
    case PIPE_SHADER_TESS_CTRL:
+      sort_inout_decls_by_slot(program->inputs, program->num_inputs, inputMapping);
+
       for (i = 0; i < program->num_inputs; ++i) {
          struct inout_decl *decl = &program->inputs[i];
          unsigned slot = inputMapping[decl->mesa_index];
          struct ureg_src src;
          ubyte tgsi_usage_mask = decl->usage_mask;
 
          if (glsl_base_type_is_64bit(decl->base_type)) {
             if (tgsi_usage_mask == 1)
                tgsi_usage_mask = TGSI_WRITEMASK_XY;
             else if (tgsi_usage_mask == 2)
@@ -6216,20 +6242,22 @@ st_translate_program(
     * Declare output attributes.
     */
    switch (procType) {
    case PIPE_SHADER_FRAGMENT:
    case PIPE_SHADER_COMPUTE:
       break;
    case PIPE_SHADER_GEOMETRY:
    case PIPE_SHADER_TESS_EVAL:
    case PIPE_SHADER_TESS_CTRL:
    case PIPE_SHADER_VERTEX:
+      sort_inout_decls_by_slot(program->outputs, program->num_outputs, outputMapping);
+
       for (i = 0; i < program->num_outputs; ++i) {
          struct inout_decl *decl = &program->outputs[i];
          unsigned slot = outputMapping[decl->mesa_index];
          struct ureg_dst dst;
          ubyte tgsi_usage_mask = decl->usage_mask;
 
          if (glsl_base_type_is_64bit(decl->base_type)) {
             if (tgsi_usage_mask == 1)
                tgsi_usage_mask = TGSI_WRITEMASK_XY;
             else if (tgsi_usage_mask == 2)
-- 
2.7.4



More information about the mesa-dev mailing list