From 7674068673c4e5497674afade51d37b987f3dc7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Tue, 18 Oct 2016 17:35:45 +0200 Subject: [PATCH] st/glsl_to_tgsi: sort input and output decls by TGSI index Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98307 --- 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 b91ebaf..ee17163 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 #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; @@ -6095,20 +6096,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 @@ -6167,20 +6191,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) @@ -6219,20 +6245,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