Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Modified merge of pull request #16 from mawww-master:

* yyerror takes a const char* instead of a char*
* binary not is ~, not -
* enable some bitwise operations as supported features
* add missing outES test files
* fix empty body if handling
* fix cast on function call
* add struct initialisation by scalar support
* fix global-init test
* add (shotgun style) coverage mask support
* Fix inverted left and right shift operators
* fix EOpRightShiftAssign output, >>=, not ??=
* promote constant union to right type, plus fixes
* Add support for more semantics
* Add tests for tokenpasting and global initialization
* add execute permission to bison and flex
* various swizzle and arrays fixes.
* Fix bad order in HLSL matrix rows/columns, add definitions for mul(float.*, float.*)
* update tests results matrix non square
* fix in type construction for swizzle
* Add overloading tests
* handle upward vector promotion in TSymbolTableLevel::findCompatible…
* Add test for non-square matrix and vector promotion
* Fix vector upward promotion for single argument functions
* Add support for non square matrices
* remove unistd.h
* fix CMakeList
* hlsl2glsltest: add glut fallback version
  • Loading branch information...
commit 09889ded0404bd394bcfd81f499a8aa74fcb7f63 2 parents 892b6ba + 7d14add
Aras Pranckevičius authored
Showing with 2,220 additions and 1,031 deletions.
  1. +9 −5 CMakeLists.txt
  2. +2 −0  hlslang.xcodeproj/project.pbxproj
  3. +37 −7 hlslang/GLSLCodeGen/glslCommon.cpp
  4. +6 −0 hlslang/GLSLCodeGen/glslCommon.h
  5. +59 −42 hlslang/GLSLCodeGen/glslOutput.cpp
  6. +121 −4 hlslang/GLSLCodeGen/hlslLinker.cpp
  7. +14 −13 hlslang/GLSLCodeGen/hlslSupportLib.cpp
  8. +84 −27 hlslang/Include/Types.h
  9. +39 −10 hlslang/Include/intermediate.h
  10. +1 −1  hlslang/MachineIndependent/HLSL2GLSL.cpp
  11. +43 −9 hlslang/MachineIndependent/Initialize.cpp
  12. +282 −193 hlslang/MachineIndependent/Intermediate.cpp
  13. +167 −91 hlslang/MachineIndependent/ParseHelper.cpp
  14. +3 −2 hlslang/MachineIndependent/ParseHelper.h
  15. +32 −21 hlslang/MachineIndependent/SymbolTable.cpp
  16. +44 −15 hlslang/MachineIndependent/hlslang.l
  17. +339 −259 hlslang/MachineIndependent/hlslang.y
  18. +15 −8 hlslang/MachineIndependent/intermOut.cpp
  19. +12 −8 hlslang/MachineIndependent/localintermediate.h
  20. +0 −2  hlslang/MachineIndependent/preprocessor/scanner.h
  21. +0 −1  hlslang/MachineIndependent/unistd.h
  22. +30 −1 include/hlsl2glsl.h
  23. +2 −2 tests/combined/index-matrix-assignment-fragment-out.txt
  24. +4 −4 tests/combined/index-matrix-assignment-vertex-out.txt
  25. +28 −0 tests/fragment-120/matrix-in.txt
  26. +44 −0 tests/fragment-120/matrix-out.txt
  27. +44 −0 tests/fragment-120/matrix-out120arr.txt
  28. +29 −0 tests/fragment-failures/matrix-in.txt
  29. +5 −0 tests/fragment-failures/matrix-out.txt
  30. +8 −2 tests/fragment-failures/matrixnonsquare-out.txt
  31. +6 −0 tests/fragment/arrays-in.txt
  32. +17 −0 tests/fragment/arrays-out.txt
  33. +17 −0 tests/fragment/arrays-outES.txt
  34. +1 −1  tests/fragment/const-matrix-init-out.txt
  35. +1 −1  tests/fragment/const-matrix-init-outES.txt
  36. +10 −0 tests/fragment/overloading-in.txt
  37. +21 −0 tests/fragment/overloading-out.txt
  38. +21 −0 tests/fragment/overloading-outES.txt
  39. +1 −1  tests/fragment/pp-complex1-out.txt
  40. +1 −1  tests/fragment/pp-complex1-outES.txt
  41. +2 −2 tests/fragment/pp-complex2-out.txt
  42. +2 −2 tests/fragment/pp-complex2-outES.txt
  43. +1 −1  tests/fragment/pp-linenumbers1-out.txt
  44. +1 −1  tests/fragment/pp-linenumbers1-outES.txt
  45. +4 −4 tests/fragment/pp-linenumbers2-out.txt
  46. +4 −4 tests/fragment/pp-linenumbers2-outES.txt
  47. +1 −1  tests/fragment/sampler2dshadow-out.txt
  48. +1 −1  tests/fragment/sampler2dshadow-outES.txt
  49. +1 −1  tests/fragment/samplerstate-out.txt
  50. +1 −1  tests/fragment/samplerstate-outES.txt
  51. +1 −1  tests/fragment/tex2dlod-out.txt
  52. +1 −1  tests/fragment/tex2dlod-outES.txt
  53. +6 −6 tests/fragment/texture-samplers-out.txt
  54. +6 −6 tests/fragment/texture-samplers-outES.txt
  55. +5 −5 tests/fragment/z-MotionBlur-out.txt
  56. +5 −5 tests/fragment/z-MotionBlur-outES.txt
  57. +1 −1  tests/fragment/z-MotionBlurNeighborMax-out.txt
  58. +1 −1  tests/fragment/z-MotionBlurNeighborMax-outES.txt
  59. +5 −5 tests/fragment/z-WaterDisplRefr-out.txt
  60. +5 −5 tests/fragment/z-WaterDisplRefr-outES.txt
  61. +6 −6 tests/fragment/z-collectshadows-out.txt
  62. +6 −6 tests/fragment/z-collectshadows-outES.txt
  63. +1 −1  tests/fragment/z-flare-out.txt
  64. +1 −1  tests/fragment/z-flare-outES.txt
  65. +1 −1  tests/fragment/z-fxaa-preset1-out.txt
  66. +1 −1  tests/fragment/z-fxaa-preset1-outES.txt
  67. +1 −1  tests/fragment/z-fxaa-preset3-out.txt
  68. +1 −1  tests/fragment/z-fxaa-preset3-outES.txt
  69. +1 −1  tests/fragment/z-fxaa3-11-consolepc-out.txt
  70. +1 −1  tests/fragment/z-fxaa3-11-consolepc-outES.txt
  71. +1 −1  tests/fragment/z-fxaa3-11-pc39-out.txt
  72. +1 −1  tests/fragment/z-fxaa3-11-pc39-outES.txt
  73. +14 −14 tests/fragment/z-mia-lightmap-out.txt
  74. +14 −14 tests/fragment/z-mia-lightmap-outES.txt
  75. +12 −12 tests/fragment/z-mia-rt-out.txt
  76. +12 −12 tests/fragment/z-mia-rt-outES.txt
  77. +1 −1  tests/fragment/z-ogre-grass1-out.txt
  78. +1 −1  tests/fragment/z-ogre-grass1-outES.txt
  79. +2 −2 tests/fragment/z-ogre-grass2-out.txt
  80. +2 −2 tests/fragment/z-ogre-grass2-outES.txt
  81. +6 −6 tests/fragment/z-ogre-pssm-out.txt
  82. +6 −6 tests/fragment/z-ogre-pssm-outES.txt
  83. +1 −1  tests/fragment/z-ogre-radialblur-out.txt
  84. +1 −1  tests/fragment/z-ogre-radialblur-outES.txt
  85. +1 −1  tests/fragment/z-particle-out.txt
  86. +1 −1  tests/fragment/z-particle-outES.txt
  87. +7 −7 tests/fragment/z-prepasslight-out.txt
  88. +7 −7 tests/fragment/z-prepasslight-outES.txt
  89. +2 −2 tests/fragment/z-skin-out.txt
  90. +2 −2 tests/fragment/z-skin-outES.txt
  91. +4 −4 tests/fragment/z-treeleaf-out.txt
  92. +4 −4 tests/fragment/z-treeleaf-outES.txt
  93. +3 −3 tests/fragment/z-treeleafloop-out.txt
  94. +3 −3 tests/fragment/z-treeleafloop-outES.txt
  95. +20 −4 tests/hlsl2glsltest/hlsl2glsltest.cpp
  96. +2 −0  tests/hlsl2glsltest/hlsl2glsltest.xcodeproj/project.pbxproj
  97. +16 −0 tests/vertex-120/global-init-in.txt
  98. +29 −0 tests/vertex-120/global-init-out.txt
  99. +29 −0 tests/vertex-120/global-init-out120arr.txt
  100. +28 −0 tests/vertex-120/global-init-outES.txt
  101. +2 −2 tests/vertex/MF-GodRays-out.txt
  102. +2 −2 tests/vertex/MF-GodRays-outES.txt
  103. +1 −1  tests/vertex/basic-mul-out.txt
  104. +1 −1  tests/vertex/basic-mul-outES.txt
  105. +1 −1  tests/vertex/funccalls-out.txt
  106. +1 −1  tests/vertex/funccalls-outES.txt
  107. +1 −1  tests/vertex/funccalls2-out.txt
  108. +1 −1  tests/vertex/funccalls2-outES.txt
  109. +1 −1  tests/vertex/funccalls3-out.txt
  110. +1 −1  tests/vertex/funccalls3-outES.txt
  111. +16 −0 tests/vertex/global-init-in.txt
  112. +28 −0 tests/vertex/global-init-out.txt
  113. +28 −0 tests/vertex/global-init-outES.txt
  114. +8 −0 tests/vertex/if-in.txt
  115. +14 −0 tests/vertex/if-out.txt
  116. +14 −0 tests/vertex/if-outES.txt
  117. +1 −1  tests/vertex/in-struct-ret-struct-out.txt
  118. +1 −1  tests/vertex/in-struct-ret-struct-outES.txt
  119. +1 −1  tests/vertex/in-struct-ret-vals-out.txt
  120. +1 −1  tests/vertex/in-struct-ret-vals-outES.txt
  121. +1 −1  tests/vertex/in-vals-ret-struct-out.txt
  122. +1 −1  tests/vertex/in-vals-ret-struct-outES.txt
  123. +1 −1  tests/vertex/in-vals-ret-vals-out.txt
  124. +1 −1  tests/vertex/in-vals-ret-vals-outES.txt
  125. +3 −3 tests/vertex/loops-for-out.txt
  126. +3 −3 tests/vertex/loops-for-outES.txt
  127. +1 −1  tests/vertex/loops-formultiple-out.txt
  128. +1 −1  tests/vertex/loops-formultiple-outES.txt
  129. +1 −1  tests/vertex/loops-forvarious-out.txt
  130. +1 −1  tests/vertex/loops-forvarious-outES.txt
  131. +1 −1  tests/vertex/nestedscope-out.txt
  132. +1 −1  tests/vertex/nestedscope-outES.txt
  133. +7 −1 tests/vertex/struct-in.txt
  134. +9 −2 tests/vertex/struct-out.txt
  135. +9 −2 tests/vertex/struct-outES.txt
  136. +7 −0 tests/vertex/swizzle-in.txt
  137. +14 −0 tests/vertex/swizzle-out.txt
  138. +14 −0 tests/vertex/swizzle-outES.txt
  139. +1 −1  tests/vertex/tex2dlod-out.txt
  140. +1 −1  tests/vertex/tex2dlod-outES.txt
  141. +8 −0 tests/vertex/token-pasting-in.txt
  142. +15 −0 tests/vertex/token-pasting-out.txt
  143. +15 −0 tests/vertex/token-pasting-outES.txt
  144. +5 −5 tests/vertex/types-out.txt
  145. +5 −5 tests/vertex/types-outES.txt
  146. +2 −2 tests/vertex/z-WaterDisplRefr-out.txt
  147. +2 −2 tests/vertex/z-WaterDisplRefr-outES.txt
  148. +1 −1  tests/vertex/z-collectshadows-out.txt
  149. +1 −1  tests/vertex/z-collectshadows-outES.txt
  150. +1 −1  tests/vertex/z-flare-out.txt
  151. +1 −1  tests/vertex/z-flare-outES.txt
  152. +5 −5 tests/vertex/z-mia-lightmap-out.txt
  153. +5 −5 tests/vertex/z-mia-lightmap-outES.txt
  154. +5 −5 tests/vertex/z-mia-rt-out.txt
  155. +5 −5 tests/vertex/z-mia-rt-outES.txt
  156. +1 −1  tests/vertex/z-ogre-grass1-out.txt
  157. +1 −1  tests/vertex/z-ogre-grass1-outES.txt
  158. +3 −3 tests/vertex/z-ogre-grass2-out.txt
  159. +3 −3 tests/vertex/z-ogre-grass2-outES.txt
  160. +4 −4 tests/vertex/z-ogre-pssm-out.txt
  161. +4 −4 tests/vertex/z-ogre-pssm-outES.txt
  162. +1 −1  tests/vertex/z-particle-out.txt
  163. +1 −1  tests/vertex/z-particle-outES.txt
  164. +2 −2 tests/vertex/z-prepasslight-out.txt
  165. +2 −2 tests/vertex/z-prepasslight-outES.txt
  166. +7 −7 tests/vertex/z-treeleaf-out.txt
  167. +7 −7 tests/vertex/z-treeleaf-outES.txt
  168. 0  tools/bison.exe
  169. +1 −1  tools/bison.simple
  170. 0  tools/flex.exe
14 CMakeLists.txt
View
@@ -7,7 +7,7 @@ set(CMAKE_SUPPRESS_REGENERATION TRUE)
set(HEADER_FILES
hlslang/Include/BaseTypes.h
hlslang/Include/Common.h
- hlslang/Include/ConstantUnion.h
+ #hlslang/Include/ConstantUnion.h
hlslang/Include/InfoSink.h
hlslang/Include/InitializeGlobals.h
hlslang/Include/InitializeParseContext.h
@@ -15,7 +15,7 @@ set(HEADER_FILES
hlslang/Include/PoolAlloc.h
hlslang/Include/Types.h
hlslang/MachineIndependent/SymbolTable.h
- hlslang/MachineIndependent/unistd.h
+ #hlslang/MachineIndependent/unistd.h
OGLCompilersDLL/InitializeDll.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -63,7 +63,7 @@ set(MACHINE_INDEPENDENT_FILES
hlslang/MachineIndependent/intermOut.cpp
hlslang/MachineIndependent/IntermTraverse.cpp
hlslang/MachineIndependent/localintermediate.h
- hlslang/MachineIndependent/parseConst.cpp
+ #hlslang/MachineIndependent/parseConst.cpp
hlslang/MachineIndependent/ParseHelper.cpp
hlslang/MachineIndependent/ParseHelper.h
hlslang/MachineIndependent/PoolAlloc.cpp
@@ -71,7 +71,8 @@ set(MACHINE_INDEPENDENT_FILES
hlslang/MachineIndependent/RemoveTree.h
hlslang/MachineIndependent/SymbolTable.cpp
hlslang/MachineIndependent/SymbolTable.h
- hlslang/MachineIndependent/unistd.h
+ #hlslang/MachineIndependent/unistd.h
+ hlslang/MachineIndependent/ConstantFolding.cpp
)
source_group("Machine Independent" FILES ${MACHINE_INDEPENDENT_FILES})
@@ -146,6 +147,7 @@ if (WIN32)
)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D\"_HAS_ITERATOR_DEBUGGING=0\" /D\"_SECURE_SCL=0\" /D\"_CRT_SECURE_NO_WARNINGS\"")
+ SET(TEST_LIBS opengl32.lib)
elseif (APPLE)
set(OSDEPENDENT_FILES
hlslang/OSDependent/Mac/osinclude.h
@@ -195,6 +197,8 @@ elseif (UNIX)
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/hlslang/MachineIndependent
COMMENT "Executing flex on hlslang.l"
)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
+ SET(TEST_LIBS GL glut GLEW pthread)
endif ()
@@ -220,4 +224,4 @@ include_directories(
)
add_executable(hlsl2glsltest tests/hlsl2glsltest/hlsl2glsltest.cpp)
-target_link_libraries(hlsl2glsltest hlsl2glsl opengl32.lib)
+target_link_libraries(hlsl2glsltest hlsl2glsl ${TEST_LIBS})
2  hlslang.xcodeproj/project.pbxproj
View
@@ -466,6 +466,7 @@
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_MODEL_TUNING = G5;
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
INSTALL_PATH = /usr/local/lib;
PREBINDING = NO;
PRODUCT_NAME = hlsl2glsl;
@@ -478,6 +479,7 @@
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
GCC_MODEL_TUNING = G5;
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
INSTALL_PATH = /usr/local/lib;
PREBINDING = NO;
PRODUCT_NAME = hlsl2glsl;
44 hlslang/GLSLCodeGen/glslCommon.cpp
View
@@ -22,7 +22,13 @@ const char typeString[EgstTypeCount][32] =
"vec3",
"vec4",
"mat2",
+ "mat2x3",
+ "mat2x4",
+ "mat3x2",
"mat3",
+ "mat3x4",
+ "mat4x2",
+ "mat4x3",
"mat4",
"sampler",
"sampler1D",
@@ -75,7 +81,13 @@ void writeType (std::stringstream &out, EGlslSymbolType type, GlslStruct *s, TPr
case EgstFloat3:
case EgstFloat4:
case EgstFloat2x2:
+ case EgstFloat2x3:
+ case EgstFloat2x4:
+ case EgstFloat3x2:
case EgstFloat3x3:
+ case EgstFloat3x4:
+ case EgstFloat4x2:
+ case EgstFloat4x3:
case EgstFloat4x4:
case EgstSamplerGeneric:
case EgstSampler1D:
@@ -109,11 +121,29 @@ EGlslSymbolType translateType( const TType *type )
{
if ( type->isMatrix() )
{
- switch (type->getNominalSize())
+ switch (type->getColsCount())
{
- case 2: return EgstFloat2x2;
- case 3: return EgstFloat3x3;
- case 4: return EgstFloat4x4;
+ case 2:
+ switch (type->getRowsCount())
+ {
+ case 2: return EgstFloat2x2;
+ case 3: return EgstFloat2x3;
+ case 4: return EgstFloat2x4;
+ } break;
+ case 3:
+ switch (type->getRowsCount())
+ {
+ case 2: return EgstFloat3x2;
+ case 3: return EgstFloat3x3;
+ case 4: return EgstFloat3x4;
+ } break;
+ case 4:
+ switch (type->getRowsCount())
+ {
+ case 2: return EgstFloat4x2;
+ case 3: return EgstFloat4x3;
+ case 4: return EgstFloat4x4;
+ } break;
}
}
else
@@ -123,11 +153,11 @@ EGlslSymbolType translateType( const TType *type )
case EbtVoid:
return EgstVoid;
case EbtBool:
- return EGlslSymbolType(EgstBool + (type->getNominalSize() - 1));
+ return EGlslSymbolType(EgstBool + (type->getRowsCount() - 1));
case EbtInt:
- return EGlslSymbolType(EgstInt + (type->getNominalSize() - 1));
+ return EGlslSymbolType(EgstInt + (type->getRowsCount() - 1));
case EbtFloat:
- return EGlslSymbolType(EgstFloat + (type->getNominalSize() - 1));
+ return EGlslSymbolType(EgstFloat + (type->getRowsCount() - 1));
case EbtSamplerGeneric:
return EgstSamplerGeneric;
case EbtSampler1D:
6 hlslang/GLSLCodeGen/glslCommon.h
View
@@ -27,7 +27,13 @@ enum EGlslSymbolType
EgstFloat3,
EgstFloat4,
EgstFloat2x2,
+ EgstFloat2x3,
+ EgstFloat2x4,
+ EgstFloat3x2,
EgstFloat3x3,
+ EgstFloat3x4,
+ EgstFloat4x2,
+ EgstFloat4x3,
EgstFloat4x4,
EgstSamplerGeneric,
EgstSampler1D,
101 hlslang/GLSLCodeGen/glslOutput.cpp
View
@@ -87,8 +87,20 @@ int getElements( EGlslSymbolType t )
case EgstFloat4:
case EgstFloat2x2:
return 4;
+ case EgstFloat2x3:
+ return 6;
+ case EgstFloat2x4:
+ return 8;
+ case EgstFloat3x2:
+ return 6;
case EgstFloat3x3:
return 9;
+ case EgstFloat3x4:
+ return 12;
+ case EgstFloat4x2:
+ return 8;
+ case EgstFloat4x3:
+ return 12;
case EgstFloat4x4:
return 16;
}
@@ -131,8 +143,10 @@ void writeConstantConstructor( std::stringstream& out, EGlslSymbolType t, TPreci
unsigned v = Min(i, n_constants - 1);
if (construct && i > 0)
out << ", ";
-
- switch (c->getBasicType()) {
+ TBasicType basicType = c->getBasicType();
+ if (basicType == EbtStruct)
+ basicType = c->getValue(v).type;
+ switch (basicType) {
case EbtBool:
out << (c->toBool(v) ? "true" : "false");
break;
@@ -160,8 +174,8 @@ void writeComparison( const TString &compareOp, const TString &compareCall, TInt
bool bUseCompareCall = false;
// Determine whether we need the vector or scalar comparison function
- if ( ( node->getLeft() && node->getLeft()->getNominalSize() > 1 ) ||
- ( node->getRight() && node->getRight()->getNominalSize() > 1 ) )
+ if ( ( node->getLeft() && !node->getLeft()->isScalar()) ||
+ ( node->getRight() && !node->getRight()->isScalar()) )
{
bUseCompareCall = true;
}
@@ -176,9 +190,9 @@ void writeComparison( const TString &compareOp, const TString &compareCall, TInt
if (node->getLeft())
{
// If it is a float, need to smear to the size of the right hand side
- if ( node->getLeft()->getNominalSize() == 1 )
+ if (node->getLeft()->isScalar())
{
- out << "vec" << node->getRight()->getNominalSize() << "( ";
+ out << "vec" << node->getRight()->getRowsCount() << "( ";
node->getLeft()->traverse(goit);
@@ -194,9 +208,9 @@ void writeComparison( const TString &compareOp, const TString &compareCall, TInt
if (node->getRight())
{
// If it is a float, need to smear to the size of the left hand side
- if ( node->getRight()->getNominalSize() == 1 )
+ if (node->getRight()->isScalar())
{
- out << "vec" << node->getLeft()->getNominalSize() << "( ";
+ out << "vec" << node->getLeft()->getRowsCount() << "( ";
node->getRight()->traverse(goit);
@@ -701,7 +715,7 @@ bool TGlslOutputTraverser::traverseBinary( bool preVisit, TIntermBinary *node, T
case EOpInclusiveOrAssign: op = "|="; infix = true; needsParens = false; break;
case EOpExclusiveOrAssign: op = "^="; infix = true; needsParens = false; break;
case EOpLeftShiftAssign: op = "<<="; infix = true; needsParens = false; break;
- case EOpRightShiftAssign: op = "??="; infix = true; needsParens = false; break;
+ case EOpRightShiftAssign: op = ">>="; infix = true; needsParens = false; break;
case EOpIndexDirect:
{
@@ -934,8 +948,8 @@ bool TGlslOutputTraverser::traverseBinary( bool preVisit, TIntermBinary *node, T
case EOpMul: op = "*"; infix = true; break;
case EOpDiv: op = "/"; infix = true; break;
case EOpMod: op = "mod"; infix = false; break;
- case EOpRightShift: op = "<<"; infix = true; break;
- case EOpLeftShift: op = ">>"; infix = true; break;
+ case EOpRightShift: op = ">>"; infix = true; break;
+ case EOpLeftShift: op = "<<"; infix = true; break;
case EOpAnd: op = "&"; infix = true; break;
case EOpInclusiveOr: op = "|"; infix = true; break;
case EOpExclusiveOr: op = "^"; infix = true; break;
@@ -1098,7 +1112,7 @@ bool TGlslOutputTraverser::traverseUnary( bool preVisit, TIntermUnary *node, TIn
case EOpNegative: op = "-"; funcStyle = false; prefix = true; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: op = "!"; funcStyle = false; prefix = true; break;
- case EOpBitwiseNot: op = "-"; funcStyle = false; prefix = true; break;
+ case EOpBitwiseNot: op = "~"; funcStyle = false; prefix = true; break;
case EOpPostIncrement: op = "++"; funcStyle = false; prefix = false; break;
case EOpPostDecrement: op = "--"; funcStyle = false; prefix = false; break;
@@ -1108,9 +1122,9 @@ bool TGlslOutputTraverser::traverseUnary( bool preVisit, TIntermUnary *node, TIn
case EOpConvIntToBool:
case EOpConvFloatToBool:
op = "bool";
- if ( node->getTypePointer()->getNominalSize() > 1)
+ if (node->getTypePointer()->isVector())
{
- zero[0] += node->getTypePointer()->getNominalSize();
+ zero[0] += node->getTypePointer()->getRowsCount();
op = TString("bvec") + zero;
}
funcStyle = true;
@@ -1120,9 +1134,9 @@ bool TGlslOutputTraverser::traverseUnary( bool preVisit, TIntermUnary *node, TIn
case EOpConvBoolToFloat:
case EOpConvIntToFloat:
op = "float";
- if ( node->getTypePointer()->getNominalSize() > 1)
+ if (node->getTypePointer()->isVector())
{
- zero[0] += node->getTypePointer()->getNominalSize();
+ zero[0] += node->getTypePointer()->getRowsCount();
op = TString("vec") + zero;
}
funcStyle = true;
@@ -1132,9 +1146,9 @@ bool TGlslOutputTraverser::traverseUnary( bool preVisit, TIntermUnary *node, TIn
case EOpConvFloatToInt:
case EOpConvBoolToInt:
op = "int";
- if ( node->getTypePointer()->getNominalSize() > 1)
+ if (node->getTypePointer()->isVector())
{
- zero[0] += node->getTypePointer()->getNominalSize();
+ zero[0] += node->getTypePointer()->getRowsCount();
op = TString("ivec") + zero;
}
funcStyle = true;
@@ -1281,7 +1295,8 @@ bool TGlslOutputTraverser::traverseSelection( bool preVisit, TIntermSelection *n
node->getCondition()->traverse(goit);
out << ')';
current->beginBlock();
- node->getTrueBlock()->traverse(goit);
+ if (node->getTrueBlock())
+ node->getTrueBlock()->traverse(goit);
current->endBlock();
if (node->getFalseBlock())
{
@@ -1300,14 +1315,11 @@ bool TGlslOutputTraverser::traverseSelection( bool preVisit, TIntermSelection *n
out << "xll_vecTSel (";
node->getCondition()->traverse(goit);
out << ", ";
+ assert(node->getTrueBlock());
node->getTrueBlock()->traverse(goit);
out << ", ";
- if (node->getFalseBlock())
- {
- node->getFalseBlock()->traverse(goit);
- }
- else
- assert(0);
+ assert(node->getFalseBlock());
+ node->getFalseBlock()->traverse(goit);
out << ")";
}
else
@@ -1316,14 +1328,11 @@ bool TGlslOutputTraverser::traverseSelection( bool preVisit, TIntermSelection *n
out << "(( ";
node->getCondition()->traverse(goit);
out << " ) ? ( ";
+ assert(node->getTrueBlock());
node->getTrueBlock()->traverse(goit);
out << " ) : ( ";
- if (node->getFalseBlock())
- {
- node->getFalseBlock()->traverse(goit);
- }
- else
- assert(0);
+ assert(node->getFalseBlock());
+ node->getFalseBlock()->traverse(goit);
out << " ))";
}
@@ -1420,21 +1429,29 @@ bool TGlslOutputTraverser::traverseAggregate( bool preVisit, TIntermAggregate *n
case EOpConstructIVec2: writeFuncCall( "ivec2", node, goit); return false;
case EOpConstructIVec3: writeFuncCall( "ivec3", node, goit); return false;
case EOpConstructIVec4: writeFuncCall( "ivec4", node, goit); return false;
-
- case EOpConstructMat2: writeFuncCall( "mat2", node, goit); return false;
- case EOpConstructMat3: writeFuncCall( "mat3", node, goit); return false;
- case EOpConstructMat4: writeFuncCall( "mat4", node, goit); return false;
-
- case EOpConstructMat2FromMat:
- current->addLibFunction(EOpConstructMat2FromMat);
+
+ case EOpConstructMat2x2: writeFuncCall( "mat2", node, goit); return false;
+ case EOpConstructMat2x3: writeFuncCall( "mat2x3", node, goit); return false;
+ case EOpConstructMat2x4: writeFuncCall( "mat2x4", node, goit); return false;
+
+ case EOpConstructMat3x2: writeFuncCall( "mat3x2", node, goit); return false;
+ case EOpConstructMat3x3: writeFuncCall( "mat3", node, goit); return false;
+ case EOpConstructMat3x4: writeFuncCall( "mat3x4", node, goit); return false;
+
+ case EOpConstructMat4x2: writeFuncCall( "mat4x2", node, goit); return false;
+ case EOpConstructMat4x3: writeFuncCall( "mat4x3", node, goit); return false;
+ case EOpConstructMat4x4: writeFuncCall( "mat4", node, goit); return false;
+
+
+ case EOpConstructMat2x2FromMat:
+ current->addLibFunction(EOpConstructMat2x2FromMat);
writeFuncCall( "xll_constructMat2", node, goit);
return false;
-
- case EOpConstructMat3FromMat:
- current->addLibFunction(EOpConstructMat3FromMat);
+ case EOpConstructMat3x3FromMat:
+ current->addLibFunction(EOpConstructMat3x3FromMat);
writeFuncCall( "xll_constructMat3", node, goit);
return false;
-
+
case EOpConstructStruct: writeFuncCall( node->getTypePointer()->getTypeName(), node, goit); return false;
case EOpConstructArray: writeFuncCall( buildArrayConstructorString(*node->getTypePointer()), node, goit); return false;
125 hlslang/GLSLCodeGen/hlslLinker.cpp 100644 → 100755
View
@@ -27,7 +27,13 @@ static const char* attribString[EAttrSemCount] = {
"gl_Vertex",
"",
"",
+ "",
+ "",
+ "",
"gl_Normal",
+ "",
+ "",
+ "",
"gl_Color",
"gl_SecondaryColor",
"",
@@ -43,13 +49,30 @@ static const char* attribString[EAttrSemCount] = {
"",
"",
"xlat_attrib_tangent",
+ "",
+ "",
+ "",
"xlat_attrib_binorm",
+ "",
+ "",
+ "",
"xlat_attrib_blendweights",
+ "",
+ "",
+ "",
"xlat_attrib_blendindices",
"",
"",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
"gl_VertexID",
"gl_InstanceIDARB",
+ "",
""
};
@@ -60,6 +83,12 @@ static const char* varOutString[EAttrSemCount] = {
"",
"",
"",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
"gl_FrontColor",
"gl_FrontSecondaryColor",
"",
@@ -82,7 +111,24 @@ static const char* varOutString[EAttrSemCount] = {
"",
"",
"",
- ""
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "gl_PointSize",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
};
@@ -90,9 +136,15 @@ static const char* varOutString[EAttrSemCount] = {
static const char* varInString[EAttrSemCount] = {
"",
"",
+ "",
+ "",
+ "",
"gl_FragCoord",
"gl_FrontFacing",
"",
+ "",
+ "",
+ "",
"gl_Color",
"gl_SecondaryColor",
"",
@@ -115,7 +167,24 @@ static const char* varInString[EAttrSemCount] = {
"",
"",
"",
- "gl_PrimitiveID"
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "gl_PrimitiveID",
+ "",
};
// String table that maps attribute semantics to built-in GLSL fragment shader outputs
@@ -125,6 +194,12 @@ static const char* resultString[EAttrSemCount] = {
"",
"",
"",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
"gl_FragData[0]",
"gl_FragData[1]",
"gl_FragData[2]",
@@ -143,14 +218,30 @@ static const char* resultString[EAttrSemCount] = {
"",
"",
"",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
"gl_FragDepth",
"",
"",
"",
"",
+ "gl_SampleMask[0]",
};
-
static const char* kUserVaryingPrefix = "xlv_";
static inline void AddToVaryings (std::stringstream& s, TPrecision prec, const std::string& type, const std::string& name)
@@ -318,6 +409,8 @@ bool HlslLinker::getArgumentData2( const std::string &name, const std::string &s
}
ctor = "float";
}
+ else if (sem == EAttrSemCoverage)
+ ctor = "int";
else
{
pad = 4 - size;
@@ -400,18 +493,41 @@ struct AttrSemanticMapping {
static AttrSemanticMapping kAttributeSemantic[] = {
{ "position", EAttrSemPosition },
{ "position0", EAttrSemPosition },
+ { "position1", EAttrSemPosition1 },
+ { "position2", EAttrSemPosition2 },
+ { "position3", EAttrSemPosition3 },
{ "vpos", EAttrSemVPos },
{ "vface", EAttrSemVFace },
{ "normal", EAttrSemNormal },
{ "normal0", EAttrSemNormal },
+ { "normal1", EAttrSemNormal1 },
+ { "normal2", EAttrSemNormal2 },
+ { "normal3", EAttrSemNormal3 },
{ "tangent", EAttrSemTangent },
{ "tangent0", EAttrSemTangent },
+ { "tangent1", EAttrSemTangent1 },
+ { "tangent2", EAttrSemTangent2 },
+ { "tangent3", EAttrSemTangent3 },
{ "binormal", EAttrSemBinormal },
{ "binormal0", EAttrSemBinormal },
+ { "binormal1", EAttrSemBinormal1 },
+ { "binormal2", EAttrSemBinormal2 },
+ { "binormal3", EAttrSemBinormal3 },
{ "blendweight", EAttrSemBlendWeight },
{ "blendweight0", EAttrSemBlendWeight },
+ { "blendweight1", EAttrSemBlendWeight1 },
+ { "blendweight2", EAttrSemBlendWeight2 },
+ { "blendweight3", EAttrSemBlendWeight3 },
{ "blendindices", EAttrSemBlendIndices },
{ "blendindices0", EAttrSemBlendIndices },
+ { "blendindices1", EAttrSemBlendIndices1 },
+ { "blendindices2", EAttrSemBlendIndices2 },
+ { "blendindices3", EAttrSemBlendIndices3 },
+ { "psize", EAttrSemPSize },
+ { "psize0", EAttrSemPSize },
+ { "psize1", EAttrSemPSize1 },
+ { "psize2", EAttrSemPSize2 },
+ { "psize3", EAttrSemPSize3 },
{ "color", EAttrSemColor0 },
{ "color0", EAttrSemColor0 },
{ "color1", EAttrSemColor1 },
@@ -431,7 +547,8 @@ static AttrSemanticMapping kAttributeSemantic[] = {
{ "depth", EAttrSemDepth },
{ "sv_vertexid", EAttrSemVertexID },
{ "sv_primitiveid", EAttrSemPrimitiveID },
- { "sv_instanceid", EAttrSemInstanceID }
+ { "sv_instanceid", EAttrSemInstanceID },
+ { "sv_coverage", EAttrSemCoverage }
};
// Determine the GLSL attribute semantic for a given HLSL semantic
27 hlslang/GLSLCodeGen/hlslSupportLib.cpp
View
@@ -441,20 +441,21 @@ void initializeHLSLSupportLibrary()
"#endif\n")
);
- hlslSupportLib->insert( CodeMap::value_type( EOpConstructMat2FromMat,
- "mat2 xll_constructMat2( mat3 m) {\n"
- " return mat2( vec2( m[0]), vec2( m[1]));\n"
- "}\n\n"
- "mat2 xll_constructMat2( mat4 m) {\n"
- " return mat2( vec2( m[0]), vec2( m[1]));\n"
- "}\n")
- );
- hlslSupportLib->insert( CodeMap::value_type( EOpConstructMat3FromMat,
- "mat3 xll_constructMat3( mat4 m) {\n"
- " return mat3( vec3( m[0]), vec3( m[1]), vec3( m[2]));\n"
- "}\n")
- );
+ // Used in pre-GLSL 1.20
+ hlslSupportLib->insert( CodeMap::value_type( EOpConstructMat2x2FromMat,
+ "mat2 xll_constructMat2( mat3 m) {\n"
+ " return mat2( vec2( m[0]), vec2( m[1]));\n"
+ "}\n\n"
+ "mat2 xll_constructMat2( mat4 m) {\n"
+ " return mat2( vec2( m[0]), vec2( m[1]));\n"
+ "}\n")
+ );
+ hlslSupportLib->insert( CodeMap::value_type( EOpConstructMat3x3FromMat,
+ "mat3 xll_constructMat3( mat4 m) {\n"
+ " return mat3( vec3( m[0]), vec3( m[1]), vec3( m[2]));\n"
+ "}\n")
+ );
hlslSupportLib->insert( CodeMap::value_type( EOpDeterminant,
"float xll_determinant( mat2 m) {\n"
111 hlslang/Include/Types.h
View
@@ -41,7 +41,8 @@ class TPublicType
TBasicType type;
TQualifier qualifier;
TPrecision precision;
- int size; // size of vector or matrix, not size of array
+ int matcols;
+ int matrows;
bool matrix;
bool array;
int arraySize;
@@ -53,7 +54,8 @@ class TPublicType
type = bt;
qualifier = q;
precision = EbpUndefined;
- size = 1;
+ matcols = 1;
+ matrows = 1;
matrix = false;
array = false;
arraySize = 0;
@@ -61,10 +63,18 @@ class TPublicType
line = ln;
}
- void setAggregate(int s, bool m = false)
+ void setVector(int s)
{
- size = s;
- matrix = m;
+ matcols = 1;
+ matrows = s;
+ matrix = false;
+ }
+
+ void setMatrix(int columns, int rows)
+ {
+ matcols = columns;
+ matrows = rows;
+ matrix = true;
}
void setArray(bool a, int s = 0)
@@ -96,16 +106,17 @@ class TType
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
explicit TType() { }
- explicit TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
- type(t), precision(p), qualifier(q), size(s), line(gNullSourceLoc), matrix(m), array(a), arraySize(0),
+ explicit TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int cols = 1, int rows = 1, bool m = false, bool a = false) :
+ type(t), precision(p), qualifier(q), matcols(cols), matrows(rows), line(gNullSourceLoc), matrix(m), array(a), arraySize(0),
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0),
semantic(0)
{
+ checkInvariants();
}
explicit TType(const TPublicType &p) :
- type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), line(p.line), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0),
- semantic(0)
+ type(p.type), precision(p.precision), qualifier(p.qualifier), matrows(p.matrows), matcols(p.matcols), line(p.line), matrix(p.matrix),
+ array(p.array), arraySize(p.arraySize), structure(0), structureSize(0), maxArraySize(0),
+ arrayInformationType(0), fieldName(0), mangled(0), typeName(0), semantic(0)
{
if (p.userDef)
{
@@ -113,22 +124,25 @@ class TType
line = p.userDef->line;
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
+ checkInvariants();
}
explicit TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined, const TSourceLoc& l = gNullSourceLoc) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), line(l), matrix(false), array(false), arraySize(0),
+ type(EbtStruct), precision(p), qualifier(EvqTemporary), matrows(1), matcols(1), line(l), matrix(false), array(false), arraySize(0),
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), semantic(0)
{
typeName = NewPoolTString(n.c_str());
+ checkInvariants();
}
- TType(const TType& type) { *this = type; }
+ TType(const TType& type) { *this = type; checkInvariants(); }
void copyType(const TType& copyOf, TStructureMap& remapper)
{
type = copyOf.type;
precision = copyOf.precision;
qualifier = copyOf.qualifier;
- size = copyOf.size;
+ matrows = copyOf.matrows;
+ matcols = copyOf.matcols;
matrix = copyOf.matrix;
array = copyOf.array;
arraySize = copyOf.arraySize;
@@ -175,6 +189,8 @@ class TType
maxArraySize = copyOf.maxArraySize;
assert(copyOf.arrayInformationType == 0);
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
+
+ checkInvariants();
}
TType* clone(TStructureMap& remapper)
@@ -185,6 +201,20 @@ class TType
return newType;
}
+ void setType(TBasicType t, int cols, int rows, bool m, bool a, int aS = 0)
+ {
+ type = t; matcols = cols; matrows = rows; matrix = m; array = a; arraySize = aS;
+ }
+ void setType(TBasicType t, int cols, int rows, bool m, TType* userDef = 0)
+ {
+ type = t;
+ matcols = cols;
+ matrows = rows;
+ matrix = m;
+ if (userDef)
+ structure = userDef->getStruct();
+ // leave array information intact.
+ }
void setTypeName(const TString& n)
{
typeName = NewPoolTString(n.c_str());
@@ -214,17 +244,27 @@ class TType
void setPrecision(TPrecision p) { precision = p; }
void changeQualifier(TQualifier q) { qualifier = q; }
- // One-dimensional size of single instance type
- int getNominalSize() const { return size; }
- void setNominalSize(int s) { size = s; }
+ int getColsCount() const { return matcols; }
+ void setColsCount(int count) { matcols = count; }
+
+ int getRowsCount() const { return matrows; }
+ void setRowsCount(int count) { matrows = count; }
// Full-dimensional size of single instance of type
- int getInstanceSize() const
+ int getInstanceSize() const
{
if (matrix)
- return size * size;
+ return matrows * matcols;
else
- return size;
+ {
+ assert(matcols == 1);
+ return matrows;
+ }
+ }
+
+ bool isScalar() const
+ {
+ return !isMatrix() && !isArray() && !isVector();
}
bool isMatrix() const { return matrix ? true : false; }
@@ -238,7 +278,7 @@ class TType
void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
void setArrayInformationType(TType* t) { arrayInformationType = t; }
TType* getArrayInformationType() { return arrayInformationType; }
- bool isVector() const { return size > 1 && !matrix; }
+ bool isVector() const { return matrows > 1 && !matrix; }
static const char* getBasicString(TBasicType t)
{
switch (t)
@@ -269,9 +309,9 @@ class TType
if (getBasicType() == EbtStruct)
totalSize = getStructSize();
else if (matrix)
- totalSize = size * size;
+ totalSize = matrows * matcols;
else
- totalSize = size;
+ totalSize = matrows;
if (isArray())
totalSize *= Max(getArraySize(), getMaxArraySize());
@@ -292,15 +332,17 @@ class TType
}
bool sameElementType(const TType& right) const
{
- return type == right.type &&
- size == right.size &&
+ return type == right.type &&
+ matrows == right.matrows &&
+ matcols == right.matcols &&
matrix == right.matrix &&
structure == right.structure;
}
bool operator==(const TType& right) const
{
return type == right.type &&
- size == right.size &&
+ matrows == right.matrows &&
+ matcols == right.matcols &&
matrix == right.matrix &&
array == right.array && (!array || arraySize == right.arraySize) &&
structure == right.structure;
@@ -318,7 +360,21 @@ class TType
void setSemantic( const TString &s) { semantic = NewPoolTString(s.c_str()); }
bool hasSemantic() const { return semantic != 0; }
- void buildMangledName(TString& res) const;
+ void checkInvariants() const
+ {
+ if (matrix)
+ {
+ assert(matcols >= 2 && matcols <= 4);
+ assert(matrows >= 2 && matrows <= 4);
+ }
+ else
+ {
+ assert(matcols == 1);
+ assert(matrows >= 1 && matrows <= 4);
+ }
+ }
+
+ void buildMangledName(TString&) const;
// Determine the parameter compatibility between this type and the parameter type
ECompatibility determineCompatibility ( const TType *pType ) const;
@@ -329,7 +385,8 @@ class TType
TPrecision precision;
TBasicType type : 6;
TQualifier qualifier : 7;
- int size : 8; // size of vector or matrix, not size of array
+ int matrows : 8;
+ int matcols : 8;
unsigned int matrix : 1;
unsigned int array : 1;
int arraySize;
49 hlslang/Include/intermediate.h
View
@@ -15,6 +15,9 @@
#include "../Include/Common.h"
#include "../Include/Types.h"
+#include "../../include/hlsl2glsl.h"
+
+struct TParseContext;
//
// Operators used by the high-level (parse tree) representation.
@@ -197,15 +200,21 @@ enum TOperator
EOpConstructIVec2,
EOpConstructIVec3,
EOpConstructIVec4,
- EOpConstructMat2,
- EOpConstructMat3,
- EOpConstructMat4,
+ EOpConstructMat2x2,
+ EOpConstructMat2x3,
+ EOpConstructMat2x4,
+ EOpConstructMat3x2,
+ EOpConstructMat3x3,
+ EOpConstructMat3x4,
+ EOpConstructMat4x2,
+ EOpConstructMat4x3,
+ EOpConstructMat4x4,
EOpConstructStruct,
EOpConstructArray,
- // HLSL matrix/matrix constructors
- EOpConstructMat2FromMat,
- EOpConstructMat3FromMat,
+ // pre-GLSL1.20 matrix downcasts
+ EOpConstructMat2x2FromMat,
+ EOpConstructMat3x3FromMat,
EOpMatrixIndex,
EOpMatrixIndexDynamic,
@@ -308,11 +317,13 @@ class TIntermTyped : public TIntermNode
TBasicType getBasicType() const { return type.getBasicType(); }
TQualifier getQualifier() const { return type.getQualifier(); }
TPrecision getPrecision() const { return type.getPrecision(); }
- int getNominalSize() const { return type.getNominalSize(); }
+ int getColsCount() const { return type.getColsCount(); }
+ int getRowsCount() const { return type.getRowsCount(); }
int getSize() const { return type.getInstanceSize(); }
bool isMatrix() const { return type.isMatrix(); }
bool isArray() const { return type.isArray(); }
bool isVector() const { return type.isVector(); }
+ bool isScalar() const { return type.isScalar(); }
const char* getBasicString() const { return type.getBasicString(); }
const char* getQualifierString() const { return type.getQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); }
@@ -425,6 +436,24 @@ class TIntermDeclaration : public TIntermTyped {
bool hasInitialization() const { return _declaration->getAsBinaryNode() != NULL; }
TIntermTyped*& getDeclaration() { return _declaration; }
+ /* @TODO
+ TPublicType getPublicType() {
+ TType& t = *getTypePointer();
+ TPublicType p = {
+ t.getBasicType(),
+ t.getQualifier(),
+ t.getPrecision(),
+ t.getColsCount(),
+ t.getRowsCount(),
+ t.isMatrix(),
+ t.isArray(),
+ t.getArraySize(),
+ t.getBasicType() == EbtStruct ? &t : NULL,
+ t.getLine()
+ };
+ return p;
+ }
+ */
bool containsArrayInitialization() const { return isArray() && hasInitialization(); }
private:
@@ -497,7 +526,7 @@ class TIntermOperator : public TIntermTyped
TOperator getOp() const { return op; }
bool modifiesState() const;
bool isConstructor() const;
- virtual bool promote(TInfoSink&)
+ virtual bool promote(TParseContext& ctx)
{
return true;
}
@@ -532,7 +561,7 @@ class TIntermBinary : public TIntermOperator
{
return this;
}
- virtual bool promote(TInfoSink&);
+ virtual bool promote(TParseContext& ctx);
protected:
TIntermTyped* left;
@@ -556,7 +585,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped* o) { operand = o; }
TIntermTyped* getOperand() { return operand; }
- virtual bool promote(TInfoSink&);
+ virtual bool promote(TParseContext& ctx);
private:
TIntermTyped* operand;
2  hlslang/MachineIndependent/HLSL2GLSL.cpp
View
@@ -51,7 +51,7 @@ static bool InitializeSymbolTable( TBuiltInStrings* BuiltInStrings, EShLanguage
//@TODO: for now, we use same global symbol table for all target language versions.
// This is wrong and will have to be changed at some point.
- TParseContext parseContext(*symbolTable, language, ETargetGLSL_ES_100, 0, infoSink);
+ TParseContext parseContext(*symbolTable, language, ETargetVersionCount, 0, infoSink);
GlobalParseContext = &parseContext;
52 hlslang/MachineIndependent/Initialize.cpp
View
@@ -13,6 +13,18 @@
#include "Initialize.h"
#include "SymbolTable.h"
+#include <sstream>
+
+static void appendMatrixType(std::stringstream& ss, unsigned rows, unsigned cols)
+{
+ ss << "float";
+ if (rows > 1 && cols > 1)
+ ss << rows << "x" << cols;
+ else if (cols > 1)
+ ss << cols;
+ else if (rows > 1)
+ ss << rows;
+}
void TBuiltIns::initialize()
{
@@ -376,21 +388,43 @@ void TBuiltIns::initialize()
//
// HLSL Matrix Functions.
//
- s.append(TString("float2x2 mul(float2x2 x, float2x2 y);"));
- s.append(TString("float3x3 mul(float3x3 x, float3x3 y);"));
- s.append(TString("float4x4 mul(float4x4 x, float4x4 y);"));
- s.append(TString("float2 mul(float2 x, float2x2 y);"));
- s.append(TString("float3 mul(float3 x, float3x3 y);"));
- s.append(TString("float4 mul(float4 x, float4x4 y);"));
- s.append(TString("float2 mul(float2x2 x, float2 y);"));
- s.append(TString("float3 mul(float3x3 x, float3 y);"));
- s.append(TString("float4 mul(float4x4 x, float4 y);"));
+
+ for (unsigned cols = 2; cols <= 4; ++cols)
+ {
+ for (unsigned rows = 1; rows <= 4; ++rows)
+ {
+ std::stringstream ss;
+ appendMatrixType(ss, rows, cols);
+ ss << " mul(float x, ";
+ appendMatrixType(ss, rows, cols);
+ ss << " y);";
+
+ appendMatrixType(ss, rows, cols);
+ ss << " mul(";
+ appendMatrixType(ss, rows, cols);
+ ss << " x, float y);";
+ for (unsigned othercols = 1; othercols <= 4; ++othercols)
+ {
+ // matrix<rows, othercols> mul(matrix<rows, cols>, matrix<cols, othercols>)
+
+ appendMatrixType(ss, rows, othercols);
+ ss << " mul(";
+ appendMatrixType(ss, rows, cols);
+ ss << " x, ";
+ appendMatrixType(ss, cols, othercols);
+ ss << " y);";
+ }
+ s.append(TString(ss.str().c_str()));
+ }
+ }
+
s.append(TString("float2x2 transpose(float2x2 m);"));
s.append(TString("float3x3 transpose(float3x3 m);"));
s.append(TString("float4x4 transpose(float4x4 m);"));
s.append(TString("float determinant(float2x2 m);"));
s.append(TString("float determinant(float3x3 m);"));
s.append(TString("float determinant(float4x4 m);"));
+ s.append(TString("float2x2 mul(float2x2 x, float2x2 y);"));
//
// Vector relational functions.
475 hlslang/MachineIndependent/Intermediate.cpp
View
@@ -9,6 +9,7 @@
#include "localintermediate.h"
#include "RemoveTree.h"
+#include "ParseHelper.h"
#include <float.h>
#include <limits.h>
@@ -39,7 +40,7 @@ TIntermSymbol* ir_add_symbol_internal(int id, const TString& name, const TTypeIn
// Connect two nodes with a new parent that does a binary operation on the nodes.
-TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TInfoSink& infoSink)
+TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TParseContext& ctx)
{
if (!left || !right)
return 0;
@@ -71,8 +72,8 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
// does
left = ir_add_conversion(EOpConstructBool,
TType ( EbtBool, left->getPrecision(), left->getQualifier(),
- left->getNominalSize(), left->isMatrix(), left->isArray()),
- left, infoSink);
+ left->getColsCount(), left->getRowsCount(), left->isMatrix(), left->isArray()),
+ left, ctx.infoSink);
if ( left == 0 )
return 0;
@@ -93,8 +94,8 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
// does
right = ir_add_conversion(EOpConstructBool,
TType ( EbtBool, right->getPrecision(), right->getQualifier(),
- right->getNominalSize(), right->isMatrix(), right->isArray()),
- right, infoSink);
+ right->getColsCount(), right->getRowsCount(), right->isMatrix(), right->isArray()),
+ right, ctx.infoSink);
if ( right == 0 )
return 0;
@@ -125,13 +126,13 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
if (leftToFloat)
{
- left = ir_add_conversion (EOpConstructFloat, TType (EbtFloat, left->getPrecision(), left->getQualifier(), left->getNominalSize(), left->isMatrix(), left->isArray()), left, infoSink);
+ left = ir_add_conversion (EOpConstructFloat, TType (EbtFloat, left->getPrecision(), left->getQualifier(), left->getColsCount(), left->getRowsCount(), left->isMatrix(), left->isArray()), left, ctx.infoSink);
if (left == 0)
return 0;
}
if (rightToFloat)
{
- right = ir_add_conversion (EOpConstructFloat, TType (EbtFloat, right->getPrecision(), right->getQualifier(), right->getNominalSize(), right->isMatrix(), right->isArray()), right, infoSink);
+ right = ir_add_conversion (EOpConstructFloat, TType (EbtFloat, right->getPrecision(), right->getQualifier(), right->getColsCount(), right->getRowsCount(), right->isMatrix(), right->isArray()), right, ctx.infoSink);
if (right == 0)
return 0;
}
@@ -169,12 +170,12 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
if (useLeft)
{
- child = ir_add_conversion(op, left->getType(), right, infoSink);
+ child = ir_add_conversion(op, left->getType(), right, ctx.infoSink);
if (child)
right = child;
else
{
- child = ir_add_conversion(op, right->getType(), left, infoSink);
+ child = ir_add_conversion(op, right->getType(), left, ctx.infoSink);
if (child)
left = child;
else
@@ -183,12 +184,12 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
}
else
{
- child = ir_add_conversion(op, right->getType(), left, infoSink);
+ child = ir_add_conversion(op, right->getType(), left, ctx.infoSink);
if (child)
left = child;
else
{
- child = ir_add_conversion(op, left->getType(), right, infoSink);
+ child = ir_add_conversion(op, left->getType(), right, ctx.infoSink);
if (child)
right = child;
else
@@ -215,7 +216,7 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
node->setLeft(left);
node->setRight(right);
- if (! node->promote(infoSink))
+ if (! node->promote(ctx))
return 0;
//
@@ -237,7 +238,7 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
// Connect two nodes through an assignment.
-TIntermTyped* ir_add_assign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TInfoSink& infoSink)
+TIntermTyped* ir_add_assign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TParseContext& ctx)
{
//
// Like adding binary math, except the conversion can only go
@@ -248,13 +249,13 @@ TIntermTyped* ir_add_assign(TOperator op, TIntermTyped* left, TIntermTyped* righ
line = left->getLine();
node->setLine(line);
- TIntermTyped* child = ir_add_conversion(op, left->getType(), right, infoSink);
+ TIntermTyped* child = ir_add_conversion(op, left->getType(), right, ctx.infoSink);
if (child == 0)
return 0;
node->setLeft(left);
node->setRight(child);
- if (! node->promote(infoSink))
+ if (! node->promote(ctx))
return 0;
return node;
@@ -281,24 +282,22 @@ TIntermTyped* ir_add_index(TOperator op, TIntermTyped* base, TIntermTyped* index
// Add one node as the parent of another that it operates on.
-TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc line, TInfoSink& infoSink)
+TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc line, TParseContext& ctx)
{
TIntermUnary* node;
TIntermTyped* child = childNode->getAsTyped();
if (child == 0)
{
- infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+ ctx.infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
return 0;
}
switch (op)
{
case EOpLogicalNot:
- if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector())
- {
+ if (!child->isScalar())
return 0;
- }
break;
case EOpPostIncrement:
@@ -322,15 +321,16 @@ TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc
case EOpConstructInt: newType = EbtInt; break;
case EOpConstructBool: newType = EbtBool; break;
case EOpConstructFloat: newType = EbtFloat; break;
+ case EOpLogicalNot: newType = EbtBool; break;
default: break;
}
if (newType != EbtVoid)
{
- child = ir_add_conversion(op, TType(newType, child->getPrecision(), EvqTemporary, child->getNominalSize(),
+ child = ir_add_conversion(op, TType(newType, child->getPrecision(), EvqTemporary, child->getColsCount(), child->getRowsCount(),
child->isMatrix(),
child->isArray()),
- child, infoSink);
+ child, ctx.infoSink);
if (child == 0)
return 0;
}
@@ -358,7 +358,7 @@ TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc
node->setLine(line);
node->setOperand(child);
- if (! node->promote(infoSink))
+ if (! node->promote(ctx))
return 0;
@@ -427,8 +427,8 @@ TIntermAggregate* ir_set_aggregate_op(TIntermNode* node, TOperator op, TSourceLo
// node passed in if no conversion was needed. Returns NULL if conversion can't be done.
TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* node, TInfoSink& infoSink)
{
- if (!node)
- return 0;
+ if (!node)
+ return 0;
//
// Does the base type allow operation?
@@ -514,7 +514,7 @@ TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* n
{
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
- default:
+ default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
@@ -524,7 +524,7 @@ TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* n
{
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
- default:
+ default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
@@ -534,17 +534,17 @@ TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* n
{
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
- default:
+ default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
break;
- default:
+ default:
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
return 0;
}
- TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
+ TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getColsCount(), node->getRowsCount(), node->isMatrix(), node->isArray());
newNode = new TIntermUnary(newOp, type);
newNode->setLine(node->getLine());
newNode->setOperand(node);
@@ -553,7 +553,7 @@ TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* n
}
}
-TIntermDeclaration* ir_add_declaration(TIntermSymbol* symbol, TIntermTyped* initializer, TSourceLoc line, TInfoSink& infoSink)
+TIntermDeclaration* ir_add_declaration(TIntermSymbol* symbol, TIntermTyped* initializer, TSourceLoc line, TParseContext& ctx)
{
TIntermDeclaration* decl = new TIntermDeclaration(symbol->getType());
decl->setLine(line);
@@ -561,31 +561,38 @@ TIntermDeclaration* ir_add_declaration(TIntermSymbol* symbol, TIntermTyped* init
if (!initializer)
decl->getDeclaration() = symbol;
else
- decl->getDeclaration() = ir_add_assign(EOpAssign, symbol, initializer, line, infoSink);
+ {
+ TIntermTyped* t = ir_add_assign(EOpAssign, symbol, initializer, line, ctx);
+ if (!t) {
+ delete decl;
+ return NULL;
+ }
+ decl->getDeclaration() = t;
+ }
return decl;
}
-TIntermDeclaration* ir_add_declaration(TSymbol* symbol, TIntermTyped* initializer, TSourceLoc line, TInfoSink& infoSink)
+TIntermDeclaration* ir_add_declaration(TSymbol* symbol, TIntermTyped* initializer, TSourceLoc line, TParseContext& ctx)
{
TVariable* var = static_cast<TVariable*>(symbol);
TIntermSymbol* sym = ir_add_symbol(var, line);
- return ir_add_declaration(sym, initializer, line, infoSink);
+ return ir_add_declaration(sym, initializer, line, ctx);
}
-TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TSymbol* symbol, TIntermTyped* initializer, TInfoSink& infoSink)
+TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TSymbol* symbol, TIntermTyped* initializer, TParseContext& ctx)
{
TVariable* var = static_cast<TVariable*>(symbol);
TIntermSymbol* sym = ir_add_symbol(var, var->getType().getLine());
- return ir_grow_declaration(declaration, sym, initializer, infoSink);
+ return ir_grow_declaration(declaration, sym, initializer, ctx);
}
-TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TIntermSymbol *symbol, TIntermTyped *initializer, TInfoSink& infoSink)
+TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TIntermSymbol *symbol, TIntermTyped *initializer, TParseContext& ctx)
{
- TIntermTyped* added_decl = ir_add_declaration (symbol, initializer, symbol->getLine(), infoSink);
+ TIntermTyped* added_decl = ir_add_declaration (symbol, initializer, symbol->getLine(), ctx);
if (declaration->getAsDeclaration()) {
TIntermAggregate* aggregate = ir_make_aggregate(declaration, declaration->getLine());
@@ -604,7 +611,7 @@ TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TIntermSymbol *
// Safe way to combine two nodes into an aggregate. Works with null pointers,
// a node that's not a aggregate yet, etc.
//
-// Returns the resulting aggregate, unless 0 was passed in for
+// Returns the resulting aggregate, unless 0 was passed in for
// both existing nodes.
TIntermAggregate* ir_grow_aggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line, TOperator expectedOp)
{
@@ -658,17 +665,11 @@ TIntermAggregate* ir_make_aggregate(TIntermNode* node, TSourceLoc line)
TIntermNode* ir_add_selection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line, TInfoSink& infoSink)
{
// Convert float/int to bool
- switch ( cond->getBasicType() )
+ if ( cond->getBasicType() != EbtBool)
{
- case EbtFloat:
- case EbtInt:
- cond = ir_add_conversion (EOpConstructBool,
- TType (EbtBool, cond->getPrecision(), cond->getQualifier(), cond->getNominalSize(), cond->isMatrix(), cond->isArray()),
+ cond = ir_add_conversion (EOpConstructBool,
+ TType (EbtBool, cond->getPrecision(), cond->getQualifier(), cond->getColsCount(), cond->getRowsCount(), cond->isMatrix(), cond->isArray()),
cond, infoSink);
- break;
- default:
- // Do nothing
- break;
}
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
@@ -704,7 +705,7 @@ TIntermTyped* ir_add_selection(TIntermTyped* cond, TIntermTyped* trueBlock, TInt
if (cond->getBasicType() != EbtBool)
{
cond = ir_add_conversion (EOpConstructBool,
- TType (EbtBool, cond->getPrecision(), cond->getQualifier(), cond->getNominalSize(), cond->isMatrix(), cond->isArray()),
+ TType (EbtBool, cond->getPrecision(), cond->getQualifier(), cond->getColsCount(), cond->getRowsCount(), cond->isMatrix(), cond->isArray()),
cond, infoSink);
}
@@ -766,10 +767,10 @@ TIntermTyped* ir_add_selection(TIntermTyped* cond, TIntermTyped* trueBlock, TInt
//
TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
node->setLine(line);
-
- if (!node->promoteTernary(infoSink))
- return 0;
-
+
+ if (!node->promoteTernary(infoSink))
+ return 0;
+
return node;
}
@@ -849,7 +850,7 @@ TIntermTyped* ir_add_vector_swizzle(TVectorFields& fields, TIntermTyped* arg, TS
{
TIntermTyped* index = ir_add_swizzle(fields, lineIndex);
res = ir_add_index(EOpVectorSwizzle, arg, index, lineDot);
- res->setType(TType(arg->getBasicType(), arg->getPrecision(), EvqTemporary, fields.num));
+ res->setType(TType(arg->getBasicType(), arg->getPrecision(), EvqTemporary, 1, fields.num));
}
return res;
}
@@ -893,25 +894,25 @@ bool TIntermOperator::modifiesState() const
{
switch (op)
{
- case EOpPostIncrement:
- case EOpPostDecrement:
- case EOpPreIncrement:
- case EOpPreDecrement:
- case EOpAssign:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpMulAssign:
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ case EOpAssign:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpMulAssign:
case EOpVectorTimesMatrixAssign:
case EOpVectorTimesScalarAssign:
case EOpMatrixTimesScalarAssign:
case EOpMatrixTimesMatrixAssign:
- case EOpDivAssign:
- case EOpModAssign:
- case EOpAndAssign:
- case EOpInclusiveOrAssign:
- case EOpExclusiveOrAssign:
- case EOpLeftShiftAssign:
- case EOpRightShiftAssign:
+ case EOpDivAssign:
+ case EOpModAssign:
+ case EOpAndAssign:
+ case EOpInclusiveOrAssign:
+ case EOpExclusiveOrAssign:
+ case EOpLeftShiftAssign:
+ case EOpRightShiftAssign:
return true;
default:
return false;
@@ -928,9 +929,15 @@ bool TIntermOperator::isConstructor() const
case EOpConstructVec2:
case EOpConstructVec3:
case EOpConstructVec4:
- case EOpConstructMat2:
- case EOpConstructMat3:
- case EOpConstructMat4:
+ case EOpConstructMat2x2:
+ case EOpConstructMat2x3:
+ case EOpConstructMat2x4:
+ case EOpConstructMat3x2:
+ case EOpConstructMat3x3:
+ case EOpConstructMat3x4:
+ case EOpConstructMat4x2:
+ case EOpConstructMat4x3:
+ case EOpConstructMat4x4:
case EOpConstructFloat:
case EOpConstructIVec2:
case EOpConstructIVec3:
@@ -947,12 +954,12 @@ bool TIntermOperator::isConstructor() const
}
}
//
-// Make sure the type of a unary operator is appropriate for its
+// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
// Returns false in nothing makes sense.
//
-bool TIntermUnary::promote(TInfoSink&)
+bool TIntermUnary::promote(TParseContext& ctx)
{
switch (op)
{
@@ -989,25 +996,96 @@ bool TIntermUnary::promote(TInfoSink&)
return true;
}
+
+TOperator ir_get_constructor_op_float(const TPublicType& t, TParseContext& ctx)
+{
+ TOperator op = EOpNull;
+ if (t.matrix) {
+ const bool hasNonSquare = (ctx.targetVersion >= ETargetGLSL_120);
+ switch(t.matcols) {
+ case 2: switch(t.matrows) {
+ case 2: op = EOpConstructMat2x2; break;
+ case 3: if (hasNonSquare) op = EOpConstructMat2x3; break;
+ case 4: if (hasNonSquare) op = EOpConstructMat2x4; break;
+ } break;
+ case 3: switch(t.matrows) {
+ case 2: if (hasNonSquare) op = EOpConstructMat3x2; break;
+ case 3: op = EOpConstructMat3x3; break;
+ case 4: if (hasNonSquare) op = EOpConstructMat3x4; break;
+ } break;
+ case 4: switch(t.matrows) {
+ case 2: if (hasNonSquare) op = EOpConstructMat4x2; break;
+ case 3: if (hasNonSquare) op = EOpConstructMat4x3; break;
+ case 4: op = EOpConstructMat4x4; break;
+ } break;
+ }
+ } else {
+ switch(t.matrows) {
+ case 1: op = EOpConstructFloat; break;
+ case 2: op = EOpConstructVec2; break;
+ case 3: op = EOpConstructVec3; break;
+ case 4: op = EOpConstructVec4; break;
+ }
+ }
+ return op;
+}
+
+
+static TOperator getMatrixConstructOp(const TIntermTyped& intermediate, TParseContext& ctx)
+{
+ // before GLSL 1.20, only square matrices
+ if (ctx.targetVersion < ETargetGLSL_120)
+ {
+ const int c = intermediate.getColsCount();
+ const int r = intermediate.getRowsCount();
+ if (c == 2 && r == 2)
+ return EOpConstructMat2x2FromMat;
+ if (c == 3 && r == 3)
+ return EOpConstructMat3x3FromMat;
+ if (c == 4 && r == 4)
+ return EOpConstructMat4x4;
+ ctx.error(intermediate.getLine(), " non-square matrices not supported", "", "(%ix%i)", r, c);
+ return EOpNull;
+ }
+
+ switch (intermediate.getColsCount())
+ {
+ case 2:
+ switch (intermediate.getRowsCount())
+ {
+ case 2: return EOpConstructMat2x2;
+ case 3: return EOpConstructMat2x3;
+ case 4: return EOpConstructMat2x4;
+ } break;
+ case 3:
+ switch (intermediate.getRowsCount())
+ {
+ case 2: return EOpConstructMat3x2;
+ case 3: return EOpConstructMat3x3;
+ case 4: return EOpConstructMat3x4;
+ } break;
+ case 4:
+ switch (intermediate.getRowsCount())
+ {
+ case 2: return EOpConstructMat4x2;
+ case 3: return EOpConstructMat4x3;
+ case 4: return EOpConstructMat4x4;
+ } break;
+ }
+ assert(false);
+ return EOpNull;
+}
+
+
+
//
// Establishes the type of the resultant operation, as well as
// makes the operator the correct one for the operands.
//
// Returns false if operator can't work on operands.
//
-bool TIntermBinary::promote(TInfoSink& infoSink)
+bool TIntermBinary::promote(TParseContext& ctx)
{
- int size = left->getNominalSize();
- if (right->getNominalSize() < size)
- size = right->getNominalSize();
-
- if (size == 1)
- {
- size = left->getNominalSize();
- if (right->getNominalSize() > size)
- size = right->getNominalSize();
- }
-
TBasicType type = left->getBasicType();
//
@@ -1020,7 +1098,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// Base assumption: just make the type the same as the left
// operand. Then only deviations from this need be coded.
//
- setType(TType(type, left->getPrecision(), EvqTemporary, left->getNominalSize(), left->isMatrix()));
+ setType(TType(type, left->getPrecision(), EvqTemporary, left->getColsCount(), left->getRowsCount(), left->isMatrix()));
// The result gets promoted to the highest precision.
TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
@@ -1062,7 +1140,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
//
// All scalars. Code after this test assumes this case is removed!
//
- if (size == 1)
+ if (left->isScalar() && right->isScalar())
{
switch (op)
@@ -1123,87 +1201,99 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
return true;
}
+ // this is not an allowed promotion : float3x4 * float4x3
+ if (left->getRowsCount() != right->getRowsCount() && left->getColsCount() != right->getColsCount() &&
+ (left->getRowsCount() > right->getRowsCount()) != (left->getColsCount() > right->getColsCount()))
+ return false;
+
//determine if this is an assignment
bool assignment = ( op >= EOpAssign && op <= EOpRightShiftAssign) ? true : false;
+ // find size of the resulting value
+ int cols = 0;
+ int rows = 0;
+
+ if (!left->isScalar() && !right->isScalar()) // no scalars, so downcast of the larger type
+ {
+ cols = std::min(left->getColsCount(), right->getColsCount());
+ rows = std::min(left->getRowsCount(), right->getRowsCount());
+ }
+ else
+ {
+ cols = std::max(left->getColsCount(), right->getColsCount());
+ rows = std::max(left->getRowsCount(), right->getRowsCount());
+ }
+ assert(cols > 0);
+ assert(rows > 0);
+
//
- // Are the sizes compatible?
+ // Downcast needed ?
//
- if ( (left->getNominalSize() != size && left->getNominalSize() != 1) ||
- (right->getNominalSize() != size && right->getNominalSize() != 1))
+ if ( left->getColsCount() > cols || left->getRowsCount() > rows)
{
- //Insert a constructor on the larger type to make the sizes match
-
- if ( left->getNominalSize() > right->getNominalSize() )
- {
-
- if (assignment)
- return false; //can't promote the destination
-
- //down convert left to match right
- TOperator convert = EOpNull;
- if (left->getTypePointer()->isMatrix())
- {
- switch (right->getNominalSize())
- {
- case 2: convert = EOpConstructMat2FromMat; break;
- case 3: convert = EOpConstructMat3FromMat; break;
- case 4: convert = EOpConstructMat4; break; //should never need to down convert to mat4
- }
- }
- else if (left->getTypePointer()->isVector())
- {
- switch (left->getTypePointer()->getBasicType())
- {
- case EbtBool: convert = TOperator( EOpConstructBVec2 + right->getNominalSize() - 2); break;
- case EbtInt: convert = TOperator( EOpConstructIVec2 + right->getNominalSize() - 2); break;
- case EbtFloat: convert = TOperator( EOpConstructVec2 + right->getNominalSize() - 2); break;
- }
- }
- else
- {
- assert(0); //size 1 case should have been handled
- }
- TIntermAggregate *node = new TIntermAggregate(convert);
- node->setLine(left->getLine());
- node->setType(TType(left->getBasicType(), left->getPrecision(), EvqTemporary, right->getNominalSize(), left->isMatrix()));
- node->getNodes().push_back(left);
- left = node;
- //now reset this node's type
- setType(TType(left->getBasicType(), left->getPrecision(), EvqTemporary, right->getNominalSize(), left->isMatrix()));
- }
- else
- {
- //down convert right to match left
- TOperator convert = EOpNull;
- if (right->getTypePointer()->isMatrix())
- {
- switch (left->getNominalSize())
- {
- case 2: convert = EOpConstructMat2FromMat; break;
- case 3: convert = EOpConstructMat3FromMat; break;
- case 4: convert = EOpConstructMat4; break; //should never need to down convert to mat4
- }
- }
- else if (right->getTypePointer()->isVector())
- {
- switch (right->getTypePointer()->getBasicType())
- {
- case EbtBool: convert = TOperator( EOpConstructBVec2 + left->getNominalSize() - 2); break;
- case EbtInt: convert = TOperator( EOpConstructIVec2 + left->getNominalSize() - 2); break;
- case EbtFloat: convert = TOperator( EOpConstructVec2 + left->getNominalSize() - 2); break;
- }
- }
- else
- {
- assert(0); //size 1 case should have been handled
- }
- TIntermAggregate *node = new TIntermAggregate(convert);
- node->setLine(right->getLine());
- node->setType(TType(right->getBasicType(), right->getPrecision(), EvqTemporary, left->getNominalSize(), right->isMatrix()));
- node->getNodes().push_back(right);
- right = node;
- }
+ if (assignment)
+ return false; //can't promote the destination
+
+ //down convert left to match right
+ TOperator convert = EOpNull;
+ if (left->getTypePointer()->isMatrix())
+ {
+ convert = getMatrixConstructOp(*right, ctx);
+ if (convert == EOpNull)
+ return false;
+ }
+ else if (left->getTypePointer()->isVector())
+ {
+ switch (right->getTypePointer()->getBasicType())
+ {
+ case EbtBool: convert = TOperator( EOpConstructBVec2 + rows - 2); break;
+ case EbtInt: convert = TOperator( EOpConstructIVec2 + rows - 2); break;
+ case EbtFloat: convert = TOperator( EOpConstructVec2 + rows - 2); break;
+ }
+ }
+ else
+ {
+ assert(0); //size 1 case should have been handled
+ }
+ TIntermAggregate *node = new TIntermAggregate(convert);
+ node->setLine(left->getLine());
+ node->setType(TType(left->getBasicType(), left->getPrecision(), EvqTemporary,
+ right->getColsCount(), right->getRowsCount(), left->isMatrix()));
+ node->getNodes().push_back(left);
+ left = node;
+ //now reset this node's type
+ setType(TType(left->getBasicType(), left->getPrecision(), EvqTemporary,
+ right->getColsCount(), right->getRowsCount(), left->isMatrix()));
+ }
+ else if ( right->getColsCount() > cols || right->getRowsCount() > rows)
+ {
+ //down convert right to match left
+ TOperator convert = EOpNull;
+ if (right->getTypePointer()->isMatrix())
+ {
+ convert = getMatrixConstructOp(*left, ctx);
+ if (convert == EOpNull)
+ return false;
+ }
+ else if (right->getTypePointer()->isVector())
+ {
+ switch (left->getTypePointer()->getBasicType())
+ {
+ case EbtBool: convert = TOperator( EOpConstructBVec2 + rows - 2); break;
+ case EbtInt: convert = TOperator( EOpConstructIVec2 + rows - 2); break;
+ case EbtFloat: convert = TOperator( EOpConstructVec2 + rows - 2); break;
+ }
+ }
+ else
+ {
+ assert(0); //size 1 case should have been handled
+ }
+ TIntermAggregate *node = new TIntermAggregate(convert);
+ node->setLine(right->getLine());
+ node->setType(TType(right->getBasicType(), right->getPrecision(), EvqTemporary,
+ left->getColsCount(), left->getRowsCount(), right->isMatrix()));
+ node->getNodes().push_back(right);
+ right = node;
}
//
@@ -1219,7 +1309,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
else
{
op = EOpMatrixTimesScalar;
- setType(TType(type, higherPrecision, EvqTemporary, size, true));
+ setType(TType(type, higherPrecision, EvqTemporary, cols, rows, true));
}
}
else if (left->isMatrix() && !right->isMatrix())
@@ -1227,7 +1317,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (right->isVector())
{
op = EOpMatrixTimesVector;
- setType(TType(type, higherPrecision, EvqTemporary, size, false));
+ setType(TType(type, higherPrecision, EvqTemporary, cols, rows, false));
}
else
{
@@ -1247,12 +1337,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
else if (left->isVector() || right->isVector())
{
op = EOpVectorTimesScalar;
- setType(TType(type, higherPrecision, EvqTemporary, size, false));
+ setType(TType(type, higherPrecision, EvqTemporary, cols, rows, false));
}
}
else
{
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+ ctx.infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
return false;
}
break;
@@ -1292,43 +1382,40 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (! left->isVector())
return false;
op = EOpVectorTimesScalarAssign;
- setType(TType(type, higherPrecision, EvqTemporary, size, false));
+ setType(TType(type, higherPrecision, EvqTemporary, cols, rows, false));
}
}
else
{
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+ ctx.infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
return false;
}
break;
case EOpAssign:
- if (left->getNominalSize() != right->getNominalSize())
+ if ( left->getColsCount() != right->getColsCount() ||
+ left->getRowsCount() != right->getRowsCount())
{
//right needs to be forced to match left
TOperator convert = EOpNull;
if (left->isMatrix() )
{
- //TODO: These might need to be changed to smears
- switch (left->getNominalSize())
- {
- case 2: convert = EOpConstructMat2; break;
- case 3: convert = EOpConstructMat3; break;
- case 4: convert = EOpConstructMat4; break;
- }
+ convert = getMatrixConstructOp(*left, ctx);
+ if (convert == EOpNull)
+ return false;
}
else if (left->isVector() )
{
- switch (right->getTypePointer()->getBasicType())
+ switch (left->getTypePointer()->getBasicType())
{
- case EbtBool: convert = TOperator( EOpConstructBVec2 + left->getNominalSize() - 2); break;
- case EbtInt: convert = TOperator( EOpConstructIVec2 + left->getNominalSize() - 2); break;
- case EbtFloat: convert = TOperator( EOpConstructVec2 + left->getNominalSize() - 2); break;
+ case EbtBool: convert = TOperator( EOpConstructBVec2 + left->getRowsCount() - 2); break;
+ case EbtInt: convert = TOperator( EOpConstructIVec2 + left->getRowsCount() - 2); break;
+ case EbtFloat: convert = TOperator( EOpConstructVec2 + left->getRowsCount() - 2); break;
}
}
else
{
- switch (right->getTypePointer()->getBasicType())
+ switch (left->getTypePointer()->getBasicType())
{
case EbtBool: convert = EOpConstructBool; break;
case EbtInt: convert = EOpConstructInt; break;
@@ -1339,10 +1426,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
assert( convert != EOpNull);
TIntermAggregate *node = new TIntermAggregate(convert);
node->setLine(right->getLine());
- node->setType(TType(left->getBasicType(), left->getPrecision(), right->getQualifier() == EvqConst ? EvqConst : EvqTemporary, left->getNominalSize(), left->isMatrix()));
+ node->setType(TType(left->getBasicType(), left->getPrecision(), right->getQualifier() == EvqConst ? EvqConst : EvqTemporary,
+ left->getColsCount(), left->getRowsCount(), left->isMatrix()));
node->getNodes().push_back(right);
right = node;
- size = right->getNominalSize();
+ cols = right->getColsCount();
+ rows = right->getRowsCount();
}
// fall through
case EOpMod:
@@ -1359,7 +1448,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
left->isVector() && right->isMatrix() ||
left->getBasicType() != right->getBasicType())
return false;
- setType(TType(type, left->getPrecision(), EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+ setType(TType(type, left->getPrecision(), EvqTemporary, cols, rows, left->isMatrix() || right->isMatrix()));
break;
case EOpEqual:
@@ -1372,7 +1461,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
left->isVector() && right->isMatrix() ||
left->getBasicType() != right->getBasicType())
return false;
- setType(TType(EbtBool, higherPrecision, EvqTemporary, size, false));
+ setType(TType(EbtBool, higherPrecision, EvqTemporary, cols, rows, false));
break;
default:
@@ -1398,7 +1487,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (getType() != left->getType())
return false;
break;
- default:
+ default:
break;
}
@@ -1411,25 +1500,25 @@ bool TIntermSelection::promoteTernary(TInfoSink& infoSink)
if (!condition->isVector())
return true;