From ad5abde066737b1df155d4d7e2c2955bfae54e7921d524a0a360b78bde2132f6 Mon Sep 17 00:00:00 2001
From: Jan Engelhardt <jengelh@inai.de>
Date: Thu, 9 Dec 2021 19:32:50 +0000
Subject: [PATCH] Accepting request 938263 from
 home:cgiboudeaux:branches:X11:Wayland

OBS-URL: https://build.opensuse.org/request/show/938263
OBS-URL: https://build.opensuse.org/package/show/X11:Wayland/glslang?expand=0&rev=84
---
 glslang-big-endian_1.patch | 189 +++++++++++++++++++++++++++++++++++++
 glslang-big-endian_2.patch | 173 +++++++++++++++++++++++++++++++++
 glslang-big-endian_3.patch |  29 ++++++
 glslang.changes            |   9 ++
 glslang.spec               |   5 +-
 5 files changed, 404 insertions(+), 1 deletion(-)
 create mode 100644 glslang-big-endian_1.patch
 create mode 100644 glslang-big-endian_2.patch
 create mode 100644 glslang-big-endian_3.patch

diff --git a/glslang-big-endian_1.patch b/glslang-big-endian_1.patch
new file mode 100644
index 0000000..8c90ab8
--- /dev/null
+++ b/glslang-big-endian_1.patch
@@ -0,0 +1,189 @@
+From 78ce7e567fce86d611353c5a9194833a54a6fbe0 Mon Sep 17 00:00:00 2001
+From: Marius Hillenbrand <mhillen@linux.ibm.com>
+Date: Tue, 19 Oct 2021 18:09:52 +0200
+Subject: [PATCH] Fix encoding/decoding of string literals for big-endian
+ systems
+
+Per SPIR-V spec, a string literal's UTF-8 octets are encoded packed into
+words with little-endian convention. Explicitly perform that encoding
+instead of assuming that the host system is little-endian.
+
+Note that this change requires corresponding fixes in SPIRV-Tools.
+
+Fixes #202
+---
+ SPIRV/SPVRemapper.cpp | 18 +++++++++++------
+ SPIRV/disassemble.cpp | 47 ++++++++++++++++++++++++++++---------------
+ SPIRV/spvIR.h         | 22 +++++++++-----------
+ 3 files changed, 52 insertions(+), 35 deletions(-)
+
+diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp
+index 56d6d5d4a5..fdfbeb90cd 100644
+--- a/SPIRV/SPVRemapper.cpp
++++ b/SPIRV/SPVRemapper.cpp
+@@ -297,15 +297,21 @@ namespace spv {
+     std::string spirvbin_t::literalString(unsigned word) const
+     {
+         std::string literal;
++        const spirword_t * pos = spv.data() + word;
+ 
+         literal.reserve(16);
+ 
+-        const char* bytes = reinterpret_cast<const char*>(spv.data() + word);
+-
+-        while (bytes && *bytes)
+-            literal += *bytes++;
+-
+-        return literal;
++        do {
++            spirword_t word = *pos;
++            for (int i = 0; i < 4; i++) {
++                char c = word & 0xff;
++                if (c == '\0')
++                    return literal;
++                literal += c;
++                word >>= 8;
++            }
++            pos++;
++        } while (true);
+     }
+ 
+     void spirvbin_t::applyMap()
+diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
+index 73c988c5b3..74dd605409 100644
+--- a/SPIRV/disassemble.cpp
++++ b/SPIRV/disassemble.cpp
+@@ -43,6 +43,7 @@
+ #include <stack>
+ #include <sstream>
+ #include <cstring>
++#include <utility>
+ 
+ #include "disassemble.h"
+ #include "doc.h"
+@@ -100,6 +101,7 @@ class SpirvStream {
+     void outputMask(OperandClass operandClass, unsigned mask);
+     void disassembleImmediates(int numOperands);
+     void disassembleIds(int numOperands);
++    std::pair<int, std::string> decodeString();
+     int disassembleString();
+     void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
+ 
+@@ -290,31 +292,44 @@ void SpirvStream::disassembleIds(int numOperands)
+     }
+ }
+ 
+-// return the number of operands consumed by the string
+-int SpirvStream::disassembleString()
++// decode string from words at current position (non-consuming)
++std::pair<int, std::string> SpirvStream::decodeString()
+ {
+-    int startWord = word;
+-
+-    out << " \"";
+-
+-    const char* wordString;
++    std::string res;
++    int wordPos = word;
++    char c;
+     bool done = false;
++
+     do {
+-        unsigned int content = stream[word];
+-        wordString = (const char*)&content;
++        unsigned int content = stream[wordPos];
+         for (int charCount = 0; charCount < 4; ++charCount) {
+-            if (*wordString == 0) {
++            c = content & 0xff;
++            content >>= 8;
++            if (c == '\0') {
+                 done = true;
+                 break;
+             }
+-            out << *(wordString++);
++            res += c;
+         }
+-        ++word;
+-    } while (! done);
++        ++wordPos;
++    } while(! done);
++
++    return std::make_pair(wordPos - word, res);
++}
++
++// return the number of operands consumed by the string
++int SpirvStream::disassembleString()
++{
++    out << " \"";
+ 
++    std::pair<int, std::string> decoderes = decodeString();
++
++    out << decoderes.second;
+     out << "\"";
+ 
+-    return word - startWord;
++    word += decoderes.first;
++
++    return decoderes.first;
+ }
+ 
+ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
+@@ -331,7 +346,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
+             nextNestedControl = 0;
+         }
+     } else if (opCode == OpExtInstImport) {
+-        idDescriptor[resultId] = (const char*)(&stream[word]);
++        idDescriptor[resultId] = decodeString().second;
+     }
+     else {
+         if (resultId != 0 && idDescriptor[resultId].size() == 0) {
+@@ -428,7 +443,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
+             --numOperands;
+             // Get names for printing "(XXX)" for readability, *after* this id
+             if (opCode == OpName)
+-                idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
++                idDescriptor[stream[word - 1]] = decodeString().second;
+             break;
+         case OperandVariableIds:
+             disassembleIds(numOperands);
+diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
+index 486e80d000..5249a5ba73 100644
+--- a/SPIRV/spvIR.h
++++ b/SPIRV/spvIR.h
+@@ -111,27 +111,23 @@ class Instruction {
+ 
+     void addStringOperand(const char* str)
+     {
+-        unsigned int word;
+-        char* wordString = (char*)&word;
+-        char* wordPtr = wordString;
+-        int charCount = 0;
++        unsigned int word = 0;
++        unsigned int shiftAmount = 0;
+         char c;
++
+         do {
+             c = *(str++);
+-            *(wordPtr++) = c;
+-            ++charCount;
+-            if (charCount == 4) {
++            word |= ((unsigned int)c) << shiftAmount;
++            shiftAmount += 8;
++            if (shiftAmount == 32) {
+                 addImmediateOperand(word);
+-                wordPtr = wordString;
+-                charCount = 0;
++                word = 0;
++                shiftAmount = 0;
+             }
+         } while (c != 0);
+ 
+         // deal with partial last word
+-        if (charCount > 0) {
+-            // pad with 0s
+-            for (; charCount < 4; ++charCount)
+-                *(wordPtr++) = 0;
++        if (shiftAmount > 0) {
+             addImmediateOperand(word);
+         }
+     }
diff --git a/glslang-big-endian_2.patch b/glslang-big-endian_2.patch
new file mode 100644
index 0000000..218fbe4
--- /dev/null
+++ b/glslang-big-endian_2.patch
@@ -0,0 +1,173 @@
+From 0eda343970e04e7c9447d264271b1c4cfdc923f4 Mon Sep 17 00:00:00 2001
+From: Marius Hillenbrand <mhillen@linux.ibm.com>
+Date: Tue, 9 Nov 2021 16:31:22 +0100
+Subject: [PATCH] Use intermOut.cpp's IsNan and IsInfinity for parse-time
+ constant folding (updated)
+
+There were two implementations of isInf() and isNan(), in Constant.cpp
+and in intermOut.cpp. The former only works on little-endian systems,
+the latter is a wrapper for library functions and works regardless of
+endianness. Move the second version into Common.h and adopt it in both
+places. Thereby avoid the duplication and fix for big-endian systems.
+
+A previous commit with the same intent and purpose had missed a required
+header for builds on Windows.
+
+On s390x, this fixes the test case
+Glsl/CompileToAstTest.FromFile/constFold_frag.
+
+Fixes #2802
+---
+ glslang/Include/Common.h                 | 33 ++++++++++++++++++++++++
+ glslang/MachineIndependent/Constant.cpp  | 33 ++----------------------
+ glslang/MachineIndependent/intermOut.cpp | 31 ----------------------
+ 3 files changed, 35 insertions(+), 62 deletions(-)
+
+diff --git a/glslang/Include/Common.h b/glslang/Include/Common.h
+index e7b5e072b..9042a1aa2 100644
+--- a/glslang/Include/Common.h
++++ b/glslang/Include/Common.h
+@@ -39,6 +39,11 @@
+ 
+ #include <algorithm>
+ #include <cassert>
++#ifdef _MSC_VER
++#include <cfloat>
++#else
++#include <cmath>
++#endif
+ #include <cstdio>
+ #include <cstdlib>
+ #include <list>
+@@ -302,6 +307,34 @@ template <class T> int IntLog2(T n)
+     return result;
+ }
+ 
++inline bool IsInfinity(double x) {
++#ifdef _MSC_VER
++    switch (_fpclass(x)) {
++    case _FPCLASS_NINF:
++    case _FPCLASS_PINF:
++        return true;
++    default:
++        return false;
++    }
++#else
++    return std::isinf(x);
++#endif
++}
++
++inline bool IsNan(double x) {
++#ifdef _MSC_VER
++    switch (_fpclass(x)) {
++    case _FPCLASS_SNAN:
++    case _FPCLASS_QNAN:
++        return true;
++    default:
++        return false;
++    }
++#else
++  return std::isnan(x);
++#endif
++}
++
+ } // end namespace glslang
+ 
+ #endif // _COMMON_INCLUDED_
+diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
+index 7f5d4c4f2..5fc61dbb7 100644
+--- a/glslang/MachineIndependent/Constant.cpp
++++ b/glslang/MachineIndependent/Constant.cpp
+@@ -46,35 +46,6 @@ namespace {
+ 
+ using namespace glslang;
+ 
+-typedef union {
+-    double d;
+-    int i[2];
+-} DoubleIntUnion;
+-
+-// Some helper functions
+-
+-bool isNan(double x)
+-{
+-    DoubleIntUnion u;
+-    // tough to find a platform independent library function, do it directly
+-    u.d = x;
+-    int bitPatternL = u.i[0];
+-    int bitPatternH = u.i[1];
+-    return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
+-           ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
+-}
+-
+-bool isInf(double x)
+-{
+-    DoubleIntUnion u;
+-    // tough to find a platform independent library function, do it directly
+-    u.d = x;
+-    int bitPatternL = u.i[0];
+-    int bitPatternH = u.i[1];
+-    return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
+-           (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
+-}
+-
+ const double pi = 3.1415926535897932384626433832795;
+ 
+ } // end anonymous namespace
+@@ -663,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
+ 
+         case EOpIsNan:
+         {
+-            newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
++            newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
+             break;
+         }
+         case EOpIsInf:
+         {
+-            newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
++            newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
+             break;
+         }
+ 
+diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
+index a0fade16c..d8a3aab5d 100644
+--- a/glslang/MachineIndependent/intermOut.cpp
++++ b/glslang/MachineIndependent/intermOut.cpp
+@@ -48,37 +48,6 @@
+ #endif
+ #include <cstdint>
+ 
+-namespace {
+-
+-bool IsInfinity(double x) {
+-#ifdef _MSC_VER
+-    switch (_fpclass(x)) {
+-    case _FPCLASS_NINF:
+-    case _FPCLASS_PINF:
+-        return true;
+-    default:
+-        return false;
+-    }
+-#else
+-    return std::isinf(x);
+-#endif
+-}
+-
+-bool IsNan(double x) {
+-#ifdef _MSC_VER
+-    switch (_fpclass(x)) {
+-    case _FPCLASS_SNAN:
+-    case _FPCLASS_QNAN:
+-        return true;
+-    default:
+-        return false;
+-    }
+-#else
+-  return std::isnan(x);
+-#endif
+-}
+-
+-}
+ 
+ namespace glslang {
+ 
diff --git a/glslang-big-endian_3.patch b/glslang-big-endian_3.patch
new file mode 100644
index 0000000..8d165e3
--- /dev/null
+++ b/glslang-big-endian_3.patch
@@ -0,0 +1,29 @@
+From f1fa8afa25c99a550b3d80c516b7cfa3ac725de5 Mon Sep 17 00:00:00 2001
+From: Marius Hillenbrand <mhillen@linux.ibm.com>
+Date: Wed, 10 Nov 2021 18:10:58 +0100
+Subject: [PATCH] TIntermediate::promoteConstantUnion(): fix conversion to int8
+
+The signedness of type char is implementation-defined in C++. The
+conversion to (signed) int8 currently uses a cast to char, which is
+undefined for negative values when the type char is implemented as
+unsigned. Thus, fix to cast to "signed char", which has the intended
+semantic on all implementations.
+
+Fixes #2807
+---
+ glslang/MachineIndependent/Intermediate.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
+index 1283f4493..6aea5b3d7 100644
+--- a/glslang/MachineIndependent/Intermediate.cpp
++++ b/glslang/MachineIndependent/Intermediate.cpp
+@@ -3902,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
+         case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
+         case EbtFloat: PROMOTE(setDConst, double, Get); break; \
+         case EbtDouble: PROMOTE(setDConst, double, Get); break; \
+-        case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
++        case EbtInt8: PROMOTE(setI8Const, signed char, Get); break; \
+         case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
+         case EbtInt: PROMOTE(setIConst, int, Get); break; \
+         case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
diff --git a/glslang.changes b/glslang.changes
index 8acba3d..db6ba67 100644
--- a/glslang.changes
+++ b/glslang.changes
@@ -1,3 +1,12 @@
+-------------------------------------------------------------------
+Thu Dec  9 19:18:39 UTC 2021 - Christophe Giboudeaux <christophe@krop.fr>
+
+- Add patches to fix issues on big endian platforms
+  (Needed to fix https://bugreports.qt.io/browse/QTBUG-93101)
+  * glslang-big-endian_1.patch
+  * glslang-big-endian_2.patch
+  * glslang-big-endian_3.patch
+
 -------------------------------------------------------------------
 Sat Nov 27 14:11:19 UTC 2021 - Jan Engelhardt <jengelh@inai.de>
 
diff --git a/glslang.spec b/glslang.spec
index 715ebd3..ade32d2 100644
--- a/glslang.spec
+++ b/glslang.spec
@@ -28,7 +28,10 @@ URL:            https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
 #Git-URL:	https://github.com/KhronosGroup/glslang
 
 Source:         https://github.com/KhronosGroup/glslang/archive/%version.tar.gz
-Patch1:         0001-build-set-SOVERSION-on-all-libraries.patch
+Patch0:         0001-build-set-SOVERSION-on-all-libraries.patch
+Patch1:         glslang-big-endian_1.patch
+Patch2:         glslang-big-endian_2.patch
+Patch3:         glslang-big-endian_3.patch
 BuildRequires:  bison
 BuildRequires:  cmake >= 2.8
 BuildRequires:  fdupes