shaderCompHLSL.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "shaderGen/HLSL/shaderCompHLSL.h"
  24. #include "shaderGen/shaderComp.h"
  25. #include "shaderGen/langElement.h"
  26. #include "gfx/gfxDevice.h"
  27. Var * ShaderConnectorHLSL::getElement( RegisterType type,
  28. U32 numElements,
  29. U32 numRegisters )
  30. {
  31. Var *ret = getIndexedElement( mCurTexElem, type, numElements, numRegisters );
  32. // Adjust texture offset if this is a texcoord type
  33. if( type == RT_TEXCOORD )
  34. {
  35. if ( numRegisters != -1 )
  36. mCurTexElem += numRegisters;
  37. else
  38. mCurTexElem += numElements;
  39. }
  40. return ret;
  41. }
  42. Var * ShaderConnectorHLSL::getIndexedElement( U32 index, RegisterType type, U32 numElements /*= 1*/, U32 numRegisters /*= -1 */ )
  43. {
  44. switch( type )
  45. {
  46. case RT_POSITION:
  47. {
  48. Var *newVar = new Var;
  49. mElementList.push_back( newVar );
  50. newVar->setConnectName( "POSITION" );
  51. newVar->rank = 0;
  52. return newVar;
  53. }
  54. case RT_VPOS:
  55. {
  56. Var *newVar = new Var;
  57. mElementList.push_back(newVar);
  58. newVar->setConnectName("VPOS");
  59. newVar->rank = 0;
  60. return newVar;
  61. }
  62. case RT_SVPOSITION:
  63. {
  64. Var *newVar = new Var;
  65. mElementList.push_back(newVar);
  66. newVar->setConnectName("SV_Position");
  67. newVar->rank = 0;
  68. return newVar;
  69. }
  70. case RT_NORMAL:
  71. {
  72. Var *newVar = new Var;
  73. mElementList.push_back( newVar );
  74. newVar->setConnectName( "NORMAL" );
  75. newVar->rank = 1;
  76. return newVar;
  77. }
  78. case RT_BINORMAL:
  79. {
  80. Var *newVar = new Var;
  81. mElementList.push_back( newVar );
  82. newVar->setConnectName( "BINORMAL" );
  83. newVar->rank = 2;
  84. return newVar;
  85. }
  86. case RT_TANGENT:
  87. {
  88. Var *newVar = new Var;
  89. mElementList.push_back( newVar );
  90. newVar->setConnectName( "TANGENT" );
  91. newVar->rank = 3;
  92. return newVar;
  93. }
  94. case RT_COLOR:
  95. {
  96. Var *newVar = new Var;
  97. mElementList.push_back( newVar );
  98. newVar->setConnectName( "COLOR" );
  99. newVar->rank = 4;
  100. return newVar;
  101. }
  102. case RT_TEXCOORD:
  103. {
  104. Var *newVar = new Var;
  105. mElementList.push_back( newVar );
  106. // This was needed for hardware instancing, but
  107. // i don't really remember why right now.
  108. if ( index > mCurTexElem )
  109. mCurTexElem = index + 1;
  110. char out[32];
  111. dSprintf( (char*)out, sizeof(out), "TEXCOORD%d", index );
  112. newVar->setConnectName( out );
  113. newVar->constNum = index;
  114. newVar->arraySize = numElements;
  115. newVar->rank = 5 + index;
  116. return newVar;
  117. }
  118. default:
  119. break;
  120. }
  121. return NULL;
  122. }
  123. S32 QSORT_CALLBACK ShaderConnectorHLSL::_hlsl4VarSort(const void* e1, const void* e2)
  124. {
  125. Var* a = *((Var **)e1);
  126. Var* b = *((Var **)e2);
  127. return a->rank - b->rank;
  128. }
  129. void ShaderConnectorHLSL::sortVars()
  130. {
  131. // If shader model 4+ than we gotta sort the vars to make sure the order is consistent
  132. if (GFX->getPixelShaderVersion() >= 4.f)
  133. {
  134. dQsort((void *)&mElementList[0], mElementList.size(), sizeof(Var *), _hlsl4VarSort);
  135. return;
  136. }
  137. return;
  138. }
  139. void ShaderConnectorHLSL::setName( char *newName )
  140. {
  141. dStrcpy( (char*)mName, newName );
  142. }
  143. void ShaderConnectorHLSL::reset()
  144. {
  145. for( U32 i=0; i<mElementList.size(); i++ )
  146. {
  147. mElementList[i] = NULL;
  148. }
  149. mElementList.setSize( 0 );
  150. mCurTexElem = 0;
  151. }
  152. void ShaderConnectorHLSL::print( Stream &stream, bool isVertexShader )
  153. {
  154. const char * header = "struct ";
  155. const char * header2 = "\r\n{\r\n";
  156. const char * footer = "};\r\n\r\n\r\n";
  157. stream.write( dStrlen(header), header );
  158. stream.write( dStrlen((char*)mName), mName );
  159. stream.write( dStrlen(header2), header2 );
  160. // print out elements
  161. for( U32 i=0; i<mElementList.size(); i++ )
  162. {
  163. U8 output[256];
  164. Var *var = mElementList[i];
  165. if (var->arraySize <= 1)
  166. dSprintf( (char*)output, sizeof(output), " %s %-15s : %s;\r\n", var->type, var->name, var->connectName );
  167. else
  168. dSprintf( (char*)output, sizeof(output), " %s %s[%d] : %s;\r\n", var->type, var->name, var->arraySize, var->connectName );
  169. stream.write( dStrlen((char*)output), output );
  170. }
  171. stream.write( dStrlen(footer), footer );
  172. }
  173. void ParamsDefHLSL::assignConstantNumbers()
  174. {
  175. // Here we assign constant number to uniform vars, sorted
  176. // by their update frequency.
  177. U32 mCurrConst = 0;
  178. for (U32 bin = cspUninit+1; bin < csp_Count; bin++)
  179. {
  180. // Find all the uniform variables that are part of this group and assign constant numbers
  181. for( U32 i=0; i<LangElement::elementList.size(); i++)
  182. {
  183. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  184. if( var )
  185. {
  186. bool shaderConst = var->uniform && !var->sampler && !var->texture;
  187. AssertFatal((!shaderConst) || var->constSortPos != cspUninit, "Const sort position has not been set, variable will not receive a constant number!!");
  188. if( shaderConst && var->constSortPos == bin)
  189. {
  190. var->constNum = mCurrConst;
  191. // Increment our constant number based on the variable type
  192. if (dStrcmp((const char*)var->type, "float4x4") == 0)
  193. {
  194. mCurrConst += (4 * var->arraySize);
  195. } else {
  196. if (dStrcmp((const char*)var->type, "float3x3") == 0)
  197. {
  198. mCurrConst += (3 * var->arraySize);
  199. } else {
  200. mCurrConst += var->arraySize;
  201. }
  202. }
  203. }
  204. }
  205. }
  206. }
  207. }
  208. void VertexParamsDefHLSL::print( Stream &stream, bool isVerterShader )
  209. {
  210. assignConstantNumbers();
  211. const char *opener = "ConnectData main( VertData IN";
  212. stream.write( dStrlen(opener), opener );
  213. // find all the uniform variables and print them out
  214. for( U32 i=0; i<LangElement::elementList.size(); i++)
  215. {
  216. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  217. if( var )
  218. {
  219. if( var->uniform )
  220. {
  221. const char* nextVar = ",\r\n ";
  222. stream.write( dStrlen(nextVar), nextVar );
  223. U8 varNum[64];
  224. dSprintf( (char*)varNum, sizeof(varNum), "register(C%d)", var->constNum );
  225. U8 output[256];
  226. if (var->arraySize <= 1)
  227. dSprintf( (char*)output, sizeof(output), "uniform %-8s %-15s : %s", var->type, var->name, varNum );
  228. else
  229. dSprintf( (char*)output, sizeof(output), "uniform %-8s %s[%d] : %s", var->type, var->name, var->arraySize, varNum );
  230. stream.write( dStrlen((char*)output), output );
  231. }
  232. }
  233. }
  234. const char *closer = "\r\n)\r\n{\r\n ConnectData OUT;\r\n\r\n";
  235. stream.write( dStrlen(closer), closer );
  236. }
  237. void PixelParamsDefHLSL::print( Stream &stream, bool isVerterShader )
  238. {
  239. assignConstantNumbers();
  240. const char * opener = "Fragout main( ConnectData IN";
  241. stream.write( dStrlen(opener), opener );
  242. // find all the sampler & uniform variables and print them out
  243. for( U32 i=0; i<LangElement::elementList.size(); i++)
  244. {
  245. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  246. if( var )
  247. {
  248. if( var->uniform )
  249. {
  250. WRITESTR( ",\r\n " );
  251. U8 varNum[32];
  252. if( var->sampler )
  253. {
  254. dSprintf( (char*)varNum, sizeof(varNum), ": register(S%d)", var->constNum );
  255. }
  256. else if (var->texture)
  257. {
  258. dSprintf((char*)varNum, sizeof(varNum), ": register(T%d)", var->constNum);
  259. }
  260. else
  261. {
  262. dSprintf( (char*)varNum, sizeof(varNum), ": register(C%d)", var->constNum );
  263. }
  264. U8 output[256];
  265. if (var->arraySize <= 1)
  266. dSprintf( (char*)output, sizeof(output), "uniform %-9s %-15s %s", var->type, var->name, varNum );
  267. else
  268. dSprintf( (char*)output, sizeof(output), "uniform %-9s %s[%d] %s", var->type, var->name, var->arraySize, varNum );
  269. WRITESTR( (char*) output );
  270. }
  271. }
  272. }
  273. const char *closer = "\r\n)\r\n{\r\n Fragout OUT;\r\n\r\n";
  274. stream.write( dStrlen(closer), closer );
  275. }