PageRenderTime 524ms CodeModel.GetById 20ms RepoModel.GetById 2ms app.codeStats 1ms

/GT-I5700/gles20/src/glShader.cpp

https://github.com/DE-NISkA/cm_android_vendor_spica
C++ | 2326 lines | 1597 code | 493 blank | 236 comment | 390 complexity | 1c5e78ae2ccd87e28b134978e5d4f5d4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. *******************************************************************************
  3. *
  4. * SAMSUNG INDIA SOFTWARE OPERATIONS
  5. * Copyright(C) 2006
  6. * ALL RIGHTS RESERVED
  7. *
  8. * This program is proprietary to Samsung India Software Operations Pvt. Ltd.,
  9. * and is protected under International Copyright Act as an unpublished work.Its
  10. * use and disclosure is limited by the terms and conditions of a license agree-
  11. * -ment. It may not be copied or otherwise reproduced or disclosed to persons
  12. * outside the licensee's organization except in accordance with the terms and
  13. * conditions of such an agreement. All copies and reproductions shall be the
  14. * property of Samsung India Software Operations Pvt. Ltd. and must bear this
  15. * notice in its entirety.
  16. *
  17. *******************************************************************************
  18. */
  19. /*
  20. ***************************************************************************//*!
  21. *
  22. * \file glShader.cpp
  23. * \author Sandeep Kakarlapudi (s.kakarla@samsung.com)
  24. * \brief Implementation of all shader and program related functionality
  25. *
  26. *//*---------------------------------------------------------------------------
  27. * NOTES:
  28. *
  29. *//*---------------------------------------------------------------------------
  30. * HISTORY:
  31. *
  32. * 07.08.2006 Sandeep Kakarlapudi Initial version from ogl2_fimg.c
  33. *
  34. *******************************************************************************
  35. */
  36. #include "glState.h"
  37. #include "platform.h"
  38. #include "ustl.h"
  39. using namespace ustl;
  40. static const char VSMagicNum[] = {'V', 'S', ' ', ' '};
  41. static const char FSMagicNum[] = {'P', 'S', ' ', ' '};
  42. int InitShaderState(OGLState* ctx)
  43. {
  44. //GET_GL_STATE(ctx);
  45. ctx->current_program = 0;
  46. ctx->current_program_ptr = NULL;
  47. ctx->cur_exe_own_memory = GL_FALSE;
  48. ctx->current_executable = NULL;
  49. // ctx->current_executable.clear();
  50. // ctx->shaderProgNames.cleanup();
  51. return 0;
  52. }
  53. int DeInitShaderState(OGLState* ctx)
  54. {
  55. ctx->current_program = 0;
  56. ctx->current_program_ptr = NULL;
  57. if(ctx->cur_exe_own_memory == GL_TRUE){
  58. ctx->current_executable->clear();
  59. delete ctx->current_executable;
  60. //Plat::safe_free(ctx->current_executable);
  61. ctx->cur_exe_own_memory = GL_FALSE;
  62. }
  63. ctx->current_executable = NULL; // whether true or false for both cases
  64. ctx->shaderProgNames.cleanup();
  65. return 0;
  66. }
  67. GLenum translateDclType(DclDataType dclType)
  68. {
  69. const int NUM_TYPES = 19;
  70. static const GLenum glTypes[NUM_TYPES] =
  71. {
  72. GL_FLOAT, //DCL_TYPE_FLOAT,
  73. GL_INT, //DCL_TYPE_INT,
  74. GL_BOOL, //DCL_TYPE_BOOL,
  75. GL_FLOAT_VEC2, //DCL_TYPE_VEC2_FLOAT,
  76. GL_INT_VEC2, //DCL_TYPE_VEC2_INT,
  77. GL_BOOL_VEC2, //DCL_TYPE_VEC2_BOOL,
  78. GL_FLOAT_VEC3, //DCL_TYPE_VEC3_FLOAT,
  79. GL_INT_VEC3, //DCL_TYPE_VEC3_INT,
  80. GL_BOOL_VEC3, //DCL_TYPE_VEC3_BOOL,
  81. GL_FLOAT_VEC4, //DCL_TYPE_VEC4_FLOAT,
  82. GL_INT_VEC4, //DCL_TYPE_VEC4_INT,
  83. GL_BOOL_VEC4, //DCL_TYPE_VEC4_BOOL,
  84. GL_FLOAT_MAT2, //DCL_TYPE_MAT2_FLOAT,
  85. GL_FLOAT_MAT3, //DCL_TYPE_MAT3_FLOAT,
  86. GL_FLOAT_MAT4, //DCL_TYPE_MAT4_FLOAT,
  87. GL_SAMPLER_2D, //DCL_TYPE_SAMPLER_2D,
  88. GL_SAMPLER_3D, //DCL_TYPE_SAMPLER_3D,
  89. GL_SAMPLER_CUBE, //DCL_TYPE_SAMPLER_CUBE,
  90. GL_INVALID_ENUM, //DCL_TYPE_NONE
  91. };
  92. if(int(dclType) < NUM_TYPES)
  93. {
  94. return glTypes[dclType];
  95. }
  96. return GL_INVALID_ENUM;
  97. }
  98. const char* getGLTypeString(GLenum type)
  99. {
  100. switch(type)
  101. {
  102. case GL_FLOAT: return "GL_FLOAT";
  103. case GL_INT: return "GL_INT";
  104. case GL_BOOL: return "GL_BOOL";
  105. case GL_FLOAT_VEC2: return "GL_FLOAT_VEC2";
  106. case GL_INT_VEC2: return "GL_INT_VEC2";
  107. case GL_BOOL_VEC2: return "GL_BOOL_VEC2";
  108. case GL_FLOAT_VEC3: return "GL_FLOAT_VEC3";
  109. case GL_INT_VEC3: return "GL_INT_VEC3";
  110. case GL_BOOL_VEC3: return "GL_BOOL_VEC3";
  111. case GL_FLOAT_VEC4: return "GL_FLOAT_VEC4";
  112. case GL_INT_VEC4: return "GL_INT_VEC4";
  113. case GL_BOOL_VEC4: return "GL_BOOL_VEC4";
  114. case GL_FLOAT_MAT2: return "GL_FLOAT_MAT2";
  115. case GL_FLOAT_MAT3: return "GL_FLOAT_MAT3";
  116. case GL_FLOAT_MAT4: return "GL_FLOAT_MAT4";
  117. case GL_SAMPLER_2D: return "GL_SAMPLER_2D";
  118. case GL_SAMPLER_3D: return "GL_SAMPLER_3D";
  119. case GL_SAMPLER_CUBE: return "GL_SAMPLER_CUBE";
  120. default: return "";
  121. }
  122. }
  123. int getNumComponents(GLenum type)
  124. {
  125. switch(type)
  126. {
  127. case GL_FLOAT:
  128. case GL_INT:
  129. case GL_BOOL:
  130. return 1;
  131. break;
  132. case GL_FLOAT_VEC2:
  133. case GL_INT_VEC2:
  134. case GL_BOOL_VEC2:
  135. return 2;
  136. break;
  137. case GL_FLOAT_VEC3:
  138. case GL_INT_VEC3:
  139. case GL_BOOL_VEC3:
  140. return 3;
  141. break;
  142. case GL_FLOAT_VEC4:
  143. case GL_INT_VEC4:
  144. case GL_BOOL_VEC4:
  145. return 4;
  146. case GL_FLOAT_MAT2:
  147. return 4;
  148. case GL_FLOAT_MAT3:
  149. return 9;
  150. case GL_FLOAT_MAT4:
  151. return 16;
  152. break;
  153. default:
  154. return 0;
  155. }
  156. }
  157. unsigned int getNumSlots(GLenum type)
  158. {
  159. switch(type)
  160. {
  161. case GL_FLOAT:
  162. case GL_INT:
  163. case GL_BOOL:
  164. return 1;
  165. break;
  166. case GL_FLOAT_VEC2:
  167. case GL_INT_VEC2:
  168. case GL_BOOL_VEC2:
  169. return 1;
  170. break;
  171. case GL_FLOAT_VEC3:
  172. case GL_INT_VEC3:
  173. case GL_BOOL_VEC3:
  174. return 1;
  175. break;
  176. case GL_FLOAT_VEC4:
  177. case GL_INT_VEC4:
  178. case GL_BOOL_VEC4:
  179. return 1;
  180. case GL_FLOAT_MAT2:
  181. return 1;
  182. case GL_FLOAT_MAT3:
  183. return 3;
  184. case GL_FLOAT_MAT4:
  185. return 4;
  186. break;
  187. default:
  188. return 0;
  189. }
  190. }
  191. bool isVector(GLenum type)
  192. {
  193. return (type == GL_FLOAT) || (type == GL_FLOAT_VEC2) || (type == GL_FLOAT_VEC3) || (type == GL_FLOAT_VEC4)
  194. || (type == GL_INT) || (type == GL_INT_VEC2) || (type == GL_INT_VEC3) || (type == GL_INT_VEC4)
  195. || (type == GL_BOOL) || (type == GL_BOOL_VEC2) || (type == GL_BOOL_VEC3) || (type == GL_BOOL_VEC4);
  196. }
  197. bool isMatrix(GLenum type)
  198. {
  199. return (type == GL_FLOAT_MAT2) || (type == GL_FLOAT_MAT3) || (type == GL_FLOAT_MAT4);
  200. }
  201. bool isSampler(GLenum type)
  202. {
  203. return (type == GL_SAMPLER_2D) || (type == GL_SAMPLER_3D) || (type == GL_SAMPLER_CUBE);
  204. }
  205. GLenum getBaseType(GLenum type)
  206. {
  207. switch(type)
  208. {
  209. case GL_FLOAT:
  210. case GL_FLOAT_VEC2:
  211. case GL_FLOAT_VEC3:
  212. case GL_FLOAT_VEC4:
  213. case GL_FLOAT_MAT2:
  214. case GL_FLOAT_MAT3:
  215. case GL_FLOAT_MAT4:
  216. return GL_FLOAT;
  217. case GL_INT:
  218. case GL_INT_VEC2:
  219. case GL_INT_VEC3:
  220. case GL_INT_VEC4:
  221. return GL_INT;
  222. case GL_BOOL:
  223. case GL_BOOL_VEC2:
  224. case GL_BOOL_VEC3:
  225. case GL_BOOL_VEC4:
  226. return GL_BOOL;
  227. default:
  228. return GL_INVALID_ENUM; //TODO: (ab)using GL_INVALID_ENUM!
  229. }
  230. }
  231. ShaderType shaderHeaderType(const void* bin)
  232. {
  233. if(Plat::memcmp(bin, VSMagicNum, 4)==0)
  234. {
  235. return VERTEX_SHADER;
  236. }
  237. else if(Plat::memcmp(bin, FSMagicNum, 4)==0)
  238. {
  239. return FRAGMENT_SHADER;
  240. }
  241. return INVALID_SHADER;
  242. }
  243. //--------------- UniformVar ---------------
  244. UniformVar::UniformVar()
  245. {
  246. setDefaults();
  247. }
  248. void UniformVar::setDefaults()
  249. {
  250. name.clear();
  251. size = 0;
  252. type = (GLenum)0;
  253. vsLocation = -1;
  254. fsLocation = -1;
  255. vsRegSet = DCL_REGSET_CONST_FLOAT;
  256. fsRegSet = DCL_REGSET_CONST_FLOAT;
  257. nextElement = 0;
  258. isArray = false;
  259. isInitialized = false;
  260. }
  261. //--------------- UniformTable ---------------
  262. //If name is of the form <name[123]> baseName is <name> else its just name
  263. //If the name is invalid in anyway, then it returns name itself.
  264. static const char* extractBaseNameAndOffset(char* baseName, int maxSize, int* offset, int* isArrayType, const char* name)
  265. {
  266. *offset = 0;
  267. *isArrayType = 0;
  268. int length = strlen(name);
  269. if( length > (maxSize-1))
  270. {
  271. //do nothing, just return the original name
  272. return name;
  273. }
  274. int i=0;
  275. if( name[length-1] != ']' )
  276. {
  277. //no ']' at the end, so return the source string
  278. return name;
  279. }
  280. int endPos = length-2; //endPos is one position before ]
  281. for( i=endPos; i>=0; i--)
  282. {
  283. if( name[i] == '[')
  284. break;
  285. }
  286. if( (i == -1) || (i == (endPos))) // '[' doesnt exist in string or if we
  287. // have '[]' return name
  288. {
  289. return name;
  290. }
  291. int startPos = i+1;
  292. int lengthToCopy = i;
  293. strncpy(baseName, name, lengthToCopy);
  294. baseName[lengthToCopy] = '\0';
  295. int val =0;
  296. for(i= startPos; i<=endPos; i++)
  297. {
  298. char c = name[i];
  299. if( (c >= '0')&&(c <= '9') ) //digit
  300. {
  301. val = c - '0' + 10*val;
  302. }
  303. else
  304. {
  305. //not a number
  306. return name;
  307. }
  308. }
  309. *offset = val;
  310. *isArrayType = 1;
  311. return baseName;
  312. }
  313. UniformTable::UniformTable()
  314. :uniformNameMap()
  315. {
  316. //Empty
  317. }
  318. void UniformTable::clear()
  319. {
  320. uniformNameMap.clear();
  321. uniforms.clear();
  322. }
  323. int UniformTable::getLocation(const char* uniformName)
  324. {
  325. GET_GL_STATE(ctx);
  326. //static char buff[MAX_UNIFORM_NAME_LENGTH];
  327. char* buff = ctx->tempStrBuff;
  328. int offset = 0;
  329. int isArrayType = 0;
  330. if(!uniformName)
  331. return -1;
  332. const char* baseName = extractBaseNameAndOffset(buff, GLF_TEMP_STRING_BUFFER_LENGTH, &offset, &isArrayType, uniformName);
  333. NameMap::const_iterator it = uniformNameMap.find(NameString(baseName));
  334. if(it == uniformNameMap.end())
  335. {
  336. return -1;
  337. }
  338. //Need to check if this is really an array type, should not allow <nonArrayName>[123]!
  339. if(isArrayType)
  340. {
  341. if(!uniforms[it->second.index].isArray)
  342. {
  343. //Using array operator on non array uniform
  344. return -1;
  345. }
  346. if(uniforms[it->second.index].name != NameString(baseName))
  347. {
  348. return -1;
  349. }
  350. if( offset >= it->second.size) //out of range
  351. {
  352. return -1;
  353. }
  354. /*
  355. int i=0;
  356. for(i=0; i<=offset; i++)
  357. {
  358. if( uniforms[it->second.index+i].name != NameString(baseName))
  359. return -1;
  360. if( uniforms[it->second.index+i].nextElement == 0)
  361. break;
  362. }
  363. if(i<offset)
  364. {
  365. //out of range! i.e. actual array length is L and requested is element r where r>=L
  366. return -1;
  367. }
  368. */
  369. }
  370. // Note that array types' first element location can also be got from just arrayName
  371. return it->second.index + offset;
  372. }
  373. //TODO: This function assumes that the vertex shader's uniforms are inserted first.
  374. bool UniformTable::insertOrUpdateBaseEntry(const DclBaseType* bt, ShaderType sType, const char* name, ustl::string& errString , const uint32 constFloatSize)
  375. {
  376. GLenum varType = translateDclType(DclDataType(bt->type));
  377. if(GL_INVALID_ENUM == varType)
  378. {
  379. errString.append("INTERNAL ERROR: unknown variable type!");
  380. return false;
  381. }
  382. static const char * regClassStr[]=
  383. {
  384. "INPUT", "OUTPUT", "UNIFORM", "SAMPLER"
  385. };
  386. gAssert( (bt->regclass == DCL_REGSET_CONST_FLOAT) || (bt->regclass == DCL_REGSET_CONST_INT) || (bt->regclass == DCL_REGSET_CONST_BOOL));
  387. int startRidx = bt->start_reg_index;
  388. unsigned int val3 = startRidx>>2;
  389. int val4 = startRidx&0x3;
  390. //TODO: mask out and extract the constregset index
  391. int offset = startRidx;
  392. if(isSampler(varType))
  393. {
  394. //Sampler registers are virtual registers used to identify the texture unit
  395. // so the components are unused.
  396. offset >>=2;
  397. }
  398. //LOGMSG("Var: %s, regClass: %s, regIndex: %d, comp: %d,Type: %s\n",name, regClassStr[bt->regclass], val3, val4, getGLTypeString(varType));
  399. //to check that the const_float_size present in the shader is correct.Sampler are not part of constant float register.
  400. if(isSampler(varType) == false){
  401. if(constFloatSize < val3 + getNumSlots(varType)){
  402. //LOGMSG("\n const float size = %u, location =%d", constFloatSize , val3 + getNumSlots(varType) );
  403. errString.append("LINK FAILED: Internal Error. The register value is greater than the size of const float register ");
  404. return false;
  405. }
  406. }
  407. ustl::string nameStr(name);
  408. NameMap::iterator it = this->uniformNameMap.find(nameStr);
  409. int index = -1;
  410. if( it != uniformNameMap.end())//Entry Already exits
  411. {
  412. if(sType == VERTEX_SHADER)
  413. {
  414. gAssert(false && "Duplicate var name!");
  415. errString.append("LINK FAILED: Duplicate uniform name in VS");
  416. return false;
  417. }
  418. index = it->second.index;
  419. if(it->second.size != 1)
  420. {
  421. errString.append("LINK FAILED: Uniform name for base entry exists but its size != 1");
  422. return false;
  423. }
  424. }
  425. else
  426. {
  427. index = uniforms.size();
  428. uniformNameMap[nameStr] = NameInfo(index,1);
  429. uniforms.push_back(UniformVar());
  430. }
  431. if(!(uniforms[index].isInitialized))
  432. {
  433. uniforms[index].name = nameStr;
  434. uniforms[index].size = 1;
  435. uniforms[index].type = varType;
  436. if(sType == VERTEX_SHADER)
  437. {
  438. uniforms[index].vsLocation = offset;
  439. uniforms[index].vsRegSet = (unsigned char)(bt->regset);
  440. }
  441. else
  442. {
  443. uniforms[index].fsLocation = offset;
  444. uniforms[index].fsRegSet = (unsigned char)(bt->regset);
  445. }
  446. uniforms[index].isArray = false;
  447. uniforms[index].isInitialized = true;
  448. uniforms[index].nextElement = 0;
  449. }
  450. else
  451. {
  452. //Check if the data matches
  453. if(uniforms[index].name != nameStr)
  454. {
  455. gAssert(false && "Internal error: var string not as expected!");
  456. return false;
  457. }
  458. if( (uniforms[index].size != 1) || (uniforms[index].type != varType)
  459. || (uniforms[index].isArray != false))
  460. {
  461. errString.append("LINK FAILED: Mismatched uniform data");
  462. return false;
  463. }
  464. //It matches, so update the vs location or fs location
  465. if(sType == VERTEX_SHADER)
  466. {
  467. uniforms[index].vsLocation = offset;
  468. uniforms[index].vsRegSet = (unsigned char)(bt->regset);
  469. }
  470. else
  471. {
  472. uniforms[index].fsLocation = offset;
  473. uniforms[index].fsRegSet = (unsigned char)(bt->regset);
  474. }
  475. }
  476. return true;
  477. }
  478. bool UniformTable::insertOrUpdateArrayEntry(const DclArrayType* at, ShaderType sType, const char* name, ustl::string& errString, const uint32 constFloatSize)
  479. {
  480. GLenum varType = translateDclType(DclDataType(at->type));
  481. if(GL_INVALID_ENUM == varType)
  482. {
  483. errString.append("INTERNAL ERROR: unknown variable type!");
  484. return false;
  485. }
  486. static const char * regClassStr[]=
  487. {
  488. "INPUT", "OUTPUT", "UNIFORM", "SAMPLER"
  489. };
  490. gAssert( (at->regclass == DCL_REGSET_CONST_FLOAT) || (at->regclass == DCL_REGSET_CONST_INT) || (at->regclass == DCL_REGSET_CONST_BOOL));
  491. int startRidx = at->start_reg_index;
  492. int val3 = startRidx>>2;
  493. int val4 = startRidx&0x3;
  494. //TODO: mask out and extract the constregset index
  495. int offset = startRidx;
  496. int stride = at->stride;
  497. if(isSampler(varType))
  498. {
  499. //Sampler registers are virtual registers used to identify the texture unit
  500. // so the components are unused.
  501. offset >>=2;
  502. gAssert( ((stride & 0x3)==0) && "Sampler var has non multiple of 4 stride!");
  503. stride >>=2;
  504. }
  505. //LOGMSG("ArrayVar: %s[%d], regClass: %s, regIndex: %d, comp: %d, Type: %s\n",name,at->num_elements, regClassStr[at->regclass], val3, val4, getGLTypeString(varType));
  506. //to check that the const_float_size present in the shader is correct.Sampler are not part of constant float register.
  507. if(isSampler(varType) == false){
  508. if(constFloatSize < val3 + (at->num_elements - 1) * (stride/4) + getNumSlots(varType)){
  509. //LOGMSG("\n const float size 1 = %u, location 1=%d", constFloatSize ,val3 + (at->num_elements - 1) * stride + getNumSlots(varType) );
  510. errString.append("LINK FAILED: Internal Error. The register value is greater than the size of const float register ");
  511. return false;
  512. }
  513. }
  514. ustl::string nameStr(name);
  515. NameMap::iterator it = this->uniformNameMap.find(nameStr);
  516. int index = -1;
  517. if( it != uniformNameMap.end()) //Entry exists
  518. {
  519. if(sType == VERTEX_SHADER)
  520. {
  521. gAssert(false && "Duplicate var name!");
  522. errString.append("LINK FAILED: Duplicate uniform name in VS");
  523. return false;
  524. }
  525. index = it->second.index;
  526. gAssert(it->second.size >= 0);
  527. if(static_cast<unsigned int>(it->second.size) != at->num_elements)
  528. {
  529. errString.append("LINK FAILED: Uniform name for array entry exists but its size != array size");
  530. return false;
  531. }
  532. }
  533. else
  534. {
  535. //Create entry
  536. index = uniforms.size();
  537. uniformNameMap[nameStr] = NameInfo(index,at->num_elements);
  538. for(unsigned int i=0; i< at->num_elements; i++)
  539. {
  540. uniforms.push_back(UniformVar());
  541. }
  542. }
  543. for(unsigned int i=0; i<at->num_elements; i++)
  544. {
  545. if(!(uniforms[index+i].isInitialized))
  546. {
  547. uniforms[index+i].name = nameStr;
  548. uniforms[index+i].size = 1;
  549. uniforms[index+i].type = varType;
  550. if(sType == VERTEX_SHADER)
  551. {
  552. uniforms[index+i].vsLocation = offset+i*stride;
  553. uniforms[index+i].vsRegSet = (unsigned char)(at->regset);
  554. }
  555. else
  556. {
  557. uniforms[index+i].fsLocation = offset+i*stride;
  558. uniforms[index+i].fsRegSet = (unsigned char)(at->regset);
  559. }
  560. uniforms[index+i].isArray = true;
  561. uniforms[index+i].isInitialized = true;
  562. uniforms[index+i].nextElement = 0;
  563. }
  564. else
  565. {
  566. //Check if the data matches
  567. if(uniforms[index+i].name != nameStr)
  568. {
  569. gAssert(false && "Internal error: var string not as expected!");
  570. return false;
  571. }
  572. if( (uniforms[index+i].size != 1) || (uniforms[index+i].type != varType)
  573. || (uniforms[index+i].isArray != true))
  574. {
  575. errString.append("LINK FAILED: Mismatched uniform data");
  576. return false;
  577. }
  578. //It matches, so update the vs location or fs location
  579. if(sType == VERTEX_SHADER)
  580. {
  581. uniforms[index+i].vsLocation = offset+i*stride;
  582. uniforms[index+i].vsRegSet = (unsigned char)(at->regset);
  583. }
  584. else
  585. {
  586. uniforms[index+i].fsLocation = offset+i*stride;
  587. uniforms[index+i].fsRegSet = (unsigned char)(at->regset);
  588. }
  589. }
  590. }
  591. if(uniforms[index].nextElement == 0)
  592. {
  593. //The pointers to the next element in the array is not initialized
  594. for(unsigned int i=0; i<at->num_elements; i++)
  595. {
  596. if(i==(at->num_elements-1))//last element of array
  597. {
  598. uniforms[index+i].nextElement=0;
  599. }
  600. else
  601. {
  602. uniforms[index+i].nextElement = &(uniforms[index+i+1]);
  603. }
  604. }
  605. }
  606. return true;
  607. }
  608. //--------------- VaryingVar ---------------
  609. VaryingVar::VaryingVar()
  610. {
  611. setDefaults();
  612. }
  613. void VaryingVar::setDefaults()
  614. {
  615. name.clear();
  616. type = (GLenum)0;
  617. vsRegIndex = -1;
  618. fsRegIndex = -1;
  619. }
  620. //--------------- Sampler map Entry ---------------
  621. SamplerMapEntry::SamplerMapEntry()
  622. {
  623. setDefaults();
  624. }
  625. void SamplerMapEntry::setDefaults()
  626. {
  627. name.clear();
  628. type = (GLenum)(0);
  629. glTexUnit = 0; // glTexUnit initialized to 0 (since all uniforms are
  630. //!< initialized to 0
  631. isUsed = false;
  632. }
  633. //--------------- AttributeVar ---------------
  634. AttributeVar::AttributeVar()
  635. {
  636. setDefaults();
  637. }
  638. void AttributeVar::setDefaults()
  639. {
  640. name.clear();
  641. type = (GLenum)(0);
  642. vsRegIndex = -1;
  643. attributeIndex = -1;
  644. }
  645. //--------------- ProgramVars ---------------
  646. ProgramVars::ProgramVars()
  647. {
  648. //TODO: not really required here now since ProgramVars does
  649. // own the mem blocks
  650. vsFloatMemBlock = 0;
  651. fsFloatMemBlock = 0;
  652. vsIntMemBlock = 0;
  653. fsIntMemBlock = 0;
  654. vsBoolMemBlock = 0;
  655. fsBoolMemBlock = 0;
  656. clear();
  657. }
  658. void ProgramVars::clear()
  659. {
  660. uniformTbl.clear();
  661. //TODO: Clearing of the these arrays can be removed in final code
  662. for(int i=0; i<MAX_VARYING_VARS; i++)
  663. {
  664. varyingArray[i].setDefaults();
  665. }
  666. numVaryingVars = 0;
  667. for(int i=0; i<MAX_VERTEX_ATTRIB_VARS; i++)
  668. {
  669. attributeArray[i].setDefaults();
  670. }
  671. numAttributeVars = 0;
  672. vsFloatMemBlock = 0;
  673. fsFloatMemBlock = 0;
  674. vsIntMemBlock = 0;
  675. fsIntMemBlock = 0;
  676. vsBoolMemBlock = 0;
  677. fsBoolMemBlock = 0;
  678. }
  679. bool ProgramVars::insertVars(Executable& exe, const unsigned char* bin, int size, ShaderType sType, ustl::string& errString)
  680. {
  681. GET_GL_STATE(ctx);
  682. char* tmpNameBuff = ctx->tempStrBuff;
  683. const char* texDimVarPrefix = "TexDim";
  684. //const char* pointCoordStr = "gl_PointCoord";
  685. const ShaderHeader* sh = (ShaderHeader*)(bin);
  686. gAssert( bin && "Bin shaderPtr is 0!");
  687. gAssert( (sType == shaderHeaderType(bin)) && "shader type and shader binary type are differing!");
  688. //TODO: check version number (though it will already be checked while loading the binary)
  689. //WORKAROUND: binary shader offsets info, size in types units rather than bytes.
  690. int curOffset = sh->header_sz + (sh->instruction_sz)*16 + (sh->const_float_sz)*16 + sh->const_int_sz*4 + (sh->const_bool_sz ? 4 : 0);
  691. int offsetsBaseTypes[NR_DCL_REG_CLASSES];
  692. for(int i=0; i<NR_DCL_REG_CLASSES; i++)
  693. {
  694. offsetsBaseTypes[i] = curOffset;
  695. curOffset += (sh->dcl_base_type_dcls_table_sz[i])*sizeof(DclBaseType);
  696. }
  697. int offsetsArrayTypes[NR_DCL_REG_CLASSES];
  698. for(int i=0; i<NR_DCL_REG_CLASSES; i++)
  699. {
  700. offsetsArrayTypes[i] = curOffset;
  701. curOffset += (sh->dcl_array_type_dcls_table_sz[i])*sizeof(DclArrayType);
  702. }
  703. int offsetStringTable = curOffset;
  704. ShaderExecutable* se = 0;
  705. if(sType == VERTEX_SHADER)
  706. {
  707. se = &(exe.vs);
  708. }
  709. else if(sType == FRAGMENT_SHADER)
  710. {
  711. se = &(exe.fs);
  712. }
  713. else
  714. {
  715. gAssert(false && "unexpected sType");
  716. }
  717. //TODO: Following clear is Not really required
  718. se->clear();
  719. se->fmbSize = sh->const_float_sz * 4*4;
  720. se->imbSize = sh->const_int_sz * 4*1;
  721. se->bmbSize = sh->const_bool_sz ? 4 : 0; //Max of 32 bools, the full storage is used
  722. // even if a single bool is used.
  723. se->constFloatMemBlock = (float*) Plat::malloc(se->fmbSize);
  724. se->constIntMemBlock = (char*) Plat::malloc(se->imbSize);
  725. se->constBoolMemBlock = (char*) Plat::malloc(se->bmbSize);
  726. //Not required
  727. Plat::memset(se->constFloatMemBlock, 0, se->fmbSize);
  728. Plat::memset(se->constIntMemBlock, 0, se->imbSize);
  729. Plat::memset(se->constBoolMemBlock,0, se->bmbSize);
  730. const int constFloatOffset = sh->header_sz + (sh->instruction_sz)*16;
  731. const int constIntOffset = constFloatOffset + se->fmbSize;
  732. const int constBoolOffset = constIntOffset + se->imbSize;
  733. Plat::memcpy(se->constFloatMemBlock, bin + constFloatOffset,se->fmbSize);
  734. Plat::memcpy(se->constIntMemBlock, bin + constIntOffset, se->imbSize);
  735. Plat::memcpy(se->constBoolMemBlock, bin+ constBoolOffset, se->bmbSize);
  736. if(sType == VERTEX_SHADER)
  737. {
  738. this->vsFloatMemBlock = se->constFloatMemBlock;
  739. this->vsIntMemBlock = se->constIntMemBlock;
  740. this->vsBoolMemBlock = se->constBoolMemBlock;
  741. }
  742. else if(sType == FRAGMENT_SHADER)
  743. {
  744. this->fsFloatMemBlock = se->constFloatMemBlock;
  745. this->fsIntMemBlock = se->constIntMemBlock;
  746. this->fsBoolMemBlock = se->constBoolMemBlock;
  747. }
  748. /*
  749. //Verify our offsets by printing the string table!
  750. //LOGMSG("String table: ######\n");
  751. for(int i=0; i < sh->dcl_string_table_sz; )
  752. {
  753. int len = strlen((const char*)bin + offsetStringTable + i);
  754. //LOGMSG("%s\n",bin + offsetStringTable + i);
  755. i += len+1;
  756. }
  757. //LOGMSG(" ###### \n");
  758. */
  759. ////LOGMSG(" sizeof DclBaseType = %d \n",sizeof(DclBaseType));
  760. const DclBaseType* bt = (const DclBaseType*)(bin+offsetsBaseTypes[DCL_REGCLASS_UNIFORM]);
  761. //Insert base type uniforms
  762. for(unsigned int j=0; j< sh->dcl_base_type_dcls_table_sz[DCL_REGCLASS_UNIFORM]; j++,bt++)
  763. {
  764. //check if this is a special compiler generated variable.
  765. int len = strlen(texDimVarPrefix);
  766. const char* name = (const char*)(bin+offsetStringTable+bt->name_offset);
  767. if(strncmp(name,texDimVarPrefix,len)==0)
  768. {
  769. if(sType == VERTEX_SHADER)
  770. {
  771. errString.append("INTERNAL ERROR: TexDim var generated for vertex shader");
  772. return false;
  773. }
  774. int texIndex = name[len]-'0';
  775. gAssert( MAX_TEXTURE_UNITS < 10 ); //Else the above code name[len]-'' breaks;
  776. if(texIndex >= MAX_TEXTURE_UNITS)
  777. {
  778. errString.append("INTERNAL WARNING: TexDim used for a tex unit > MAX_TEXTURE_UNIT");
  779. }
  780. else // add it
  781. {
  782. exe.dimensions.tex[texIndex] = bt->start_reg_index;
  783. }
  784. }
  785. else if(len >3 && name[0] == 'g' && name[1] == 'l' && name[2] == '_') {
  786. // Built-in uniforms
  787. if( strcmp(name,"gl_DepthRange.near") == 0) {
  788. se->builtinUniformIndices.depthRange_near = bt->start_reg_index;
  789. }
  790. else if( strcmp(name,"gl_DepthRange.far") == 0) {
  791. se->builtinUniformIndices.depthRange_far = bt->start_reg_index;
  792. }
  793. else if( strcmp(name,"gl_DepthRange.diff") == 0) {
  794. se->builtinUniformIndices.depthRange_diff = bt->start_reg_index;
  795. }
  796. else {
  797. gAssert("Unrecognized built in uniform\n");
  798. }
  799. }
  800. else if(!this->uniformTbl.insertOrUpdateBaseEntry(bt, sType, name, errString ,sh->const_float_sz))
  801. {
  802. return false;
  803. }
  804. }
  805. //Insert Array type uniforms //TODO: test!!!
  806. const DclArrayType* at = (const DclArrayType*)(bin+offsetsArrayTypes[DCL_REGCLASS_UNIFORM]);
  807. for(unsigned int j=0; j< sh->dcl_array_type_dcls_table_sz[DCL_REGCLASS_UNIFORM]; j++,at++)
  808. {
  809. if(!this->uniformTbl.insertOrUpdateArrayEntry(at, sType, (const char*)(bin+offsetStringTable+at->name_offset), errString, sh->const_float_sz))
  810. {
  811. return false;
  812. }
  813. //at++;
  814. }
  815. const int maxSamplers = ((sType == VERTEX_SHADER) ? MAX_VERTEX_TEXTURE_UNITS : MAX_TEXTURE_UNITS);
  816. const ustl::string errExeceededSamplers = ((sType == VERTEX_SHADER) ? ustl::string("Exceeded VS samplers!\n") : "Exceeded FS samplers!\n");
  817. //Insert base type Sampler vars
  818. bt = (const DclBaseType*)(bin+offsetsBaseTypes[DCL_REGCLASS_SAMPLER]);
  819. for(unsigned int j=0; j< sh->dcl_base_type_dcls_table_sz[DCL_REGCLASS_SAMPLER]; j++,bt++)
  820. {
  821. ustl::string varName((const char*)(bin+offsetStringTable+bt->name_offset));
  822. GLenum varType = translateDclType(DclDataType(bt->type));
  823. if(!isSampler(varType))
  824. {
  825. errString.append("Unsupported sampler type\n");
  826. return false;
  827. }
  828. int sReg = (bt->start_reg_index)>>2;
  829. if(sReg >= maxSamplers)
  830. {
  831. errString.append(errExeceededSamplers);
  832. return false;
  833. }
  834. if(!this->uniformTbl.insertOrUpdateBaseEntry(bt, sType, (const char*)(bin+offsetStringTable+bt->name_offset), errString, sh->const_float_sz))
  835. {
  836. return false;
  837. }
  838. if(sType == VERTEX_SHADER)
  839. {
  840. //ALERT: unlike the rest of the vars the type info is stored in the exe!
  841. exe.vsSamplerMappings[sReg].isUsed = true;
  842. exe.vsSamplerMappings[sReg].type = varType;
  843. exe.vsSamplerMappings[sReg].name = varName;
  844. }
  845. else if(sType == FRAGMENT_SHADER)
  846. {
  847. exe.fsSamplerMappings[sReg].isUsed = true;
  848. exe.fsSamplerMappings[sReg].type = varType;
  849. exe.fsSamplerMappings[sReg].name = varName;
  850. }
  851. //bt++;
  852. }
  853. //Insert array type samplers
  854. at = (const DclArrayType*)(bin+offsetsArrayTypes[DCL_REGCLASS_SAMPLER]);
  855. for(unsigned int j=0; j< sh->dcl_array_type_dcls_table_sz[DCL_REGCLASS_SAMPLER]; j++,at++)
  856. {
  857. ustl::string varName((const char*)(bin+offsetStringTable+at->name_offset));
  858. GLenum varType = translateDclType(DclDataType(at->type));
  859. if(!isSampler(varType))
  860. {
  861. errString.append("Unsupported sampler type\n");
  862. return false;
  863. }
  864. int sReg = (at->start_reg_index)>>2;
  865. int stride = at->stride;
  866. gAssert( ((stride & 0x3)==0) && "Sampler var has non multiple of 4 stride!");
  867. stride >>=2;
  868. int maxSReg = (at->start_reg_index + (at->num_elements)*(at->stride))>>2;
  869. if(maxSReg >= maxSamplers)
  870. {
  871. errString.append(errExeceededSamplers);
  872. return false;
  873. }
  874. if(!this->uniformTbl.insertOrUpdateArrayEntry(at, sType, (const char*)(bin+offsetStringTable+at->name_offset), errString, sh->const_float_sz))
  875. {
  876. return false;
  877. }
  878. for(unsigned int i=0; i<at->num_elements; i++)
  879. {
  880. int reg = (sReg + i*(stride));
  881. if(sType == VERTEX_SHADER)
  882. {
  883. //ALERT: unlike the rest of the vars the type info is stored in the exe!
  884. exe.vsSamplerMappings[reg].isUsed = true;
  885. exe.vsSamplerMappings[reg].type = varType;
  886. exe.vsSamplerMappings[reg].name = varName;
  887. }
  888. else if(sType == FRAGMENT_SHADER)
  889. {
  890. exe.fsSamplerMappings[reg].isUsed = true;
  891. exe.fsSamplerMappings[reg].type = varType;
  892. exe.fsSamplerMappings[reg].name = varName;
  893. }
  894. }
  895. //at++;
  896. }
  897. //Insert attribs
  898. if(sType == VERTEX_SHADER)
  899. {
  900. numAttributeVars = sh->dcl_base_type_dcls_table_sz[DCL_REGCLASS_INPUT];
  901. bt = (const DclBaseType*)(bin+offsetsBaseTypes[DCL_REGCLASS_INPUT]);
  902. for(unsigned int i=0; i< numAttributeVars; i++,bt++)
  903. {
  904. attributeArray[i].name = ustl::string((const char*)(bin+offsetStringTable+bt->name_offset));
  905. attributeArray[i].type = translateDclType((DclDataType)bt->type);
  906. attributeArray[i].vsRegIndex = bt->start_reg_index>>2; //Discard component
  907. //LOGMSG("ATTRIB: %s type: %s\n",attributeArray[i].name.c_str(), getGLTypeString(attributeArray[i].type));
  908. //bt += 1;
  909. }
  910. }
  911. //TODO: test, prove, remove older code
  912. DclRegClass varyingClass;
  913. if(sType == VERTEX_SHADER)
  914. {
  915. varyingClass = DCL_REGCLASS_OUTPUT;
  916. }
  917. else
  918. {
  919. varyingClass = DCL_REGCLASS_INPUT;
  920. }
  921. //Insert base type varying vars
  922. bt = (const DclBaseType*)(bin+offsetsBaseTypes[varyingClass]);
  923. int numBtVaryings = sh->dcl_base_type_dcls_table_sz[varyingClass];
  924. for(int i=0; i< numBtVaryings; i++,bt++)
  925. {
  926. if( (sType == FRAGMENT_SHADER) &&
  927. (strcmp((const char*)(bin+offsetStringTable+bt->name_offset),"gl_FragCoord")==0))
  928. {
  929. continue;
  930. }
  931. #if 1
  932. if( (sType == VERTEX_SHADER) &&
  933. (strcmp((const char*)(bin+offsetStringTable+bt->name_offset),"gl_PointSize")==0))
  934. {
  935. //to add the Reg value
  936. //exe.pointSizeIndex = 9;
  937. exe.pointSizeIndex = bt->start_reg_index>>2;
  938. ////LOGMSG("\n point sizer =%d",exe.pointSizeIndex);
  939. continue;
  940. }
  941. #endif
  942. if(!(insertVaryingVar(sType, ustl::string((const char*)(bin+offsetStringTable+bt->name_offset)),
  943. translateDclType((DclDataType)bt->type), bt->start_reg_index, errString)))
  944. {
  945. return false;
  946. }
  947. //bt+=1;
  948. }
  949. //Insert array type varying vars by essentially cnoverting each array's slements into base types with names <array_name>[<i>]
  950. at = (const DclArrayType*)(bin+offsetsArrayTypes[varyingClass]);
  951. int numAtVaryings = sh->dcl_array_type_dcls_table_sz[varyingClass];
  952. for(int i=0; i < numAtVaryings; i++,at++)
  953. {
  954. for(unsigned int j=0; j< at->num_elements; j++)
  955. {
  956. sprintf(tmpNameBuff,"[%d]",j);
  957. if(!(insertVaryingVar(sType, ustl::string((const char*)(bin+offsetStringTable+at->name_offset))+ustl::string(tmpNameBuff),
  958. translateDclType((DclDataType)at->type), at->start_reg_index+j*(at->stride), errString)))
  959. {
  960. return false;
  961. }
  962. }
  963. //at+=1;
  964. }
  965. return true;
  966. }
  967. bool ProgramVars::insertVaryingVar(ShaderType sType, ustl::string name, GLenum type, int regIndex, ustl::string& errString)
  968. {
  969. if(sType == VERTEX_SHADER)
  970. {
  971. int index = numVaryingVars;
  972. numVaryingVars++;
  973. varyingArray[index].name = name;
  974. varyingArray[index].type = type;
  975. varyingArray[index].vsRegIndex = regIndex;
  976. if(varyingArray[index].type == GL_INVALID_ENUM)
  977. {
  978. errString.append("LINK FAILED: unknown varying type");
  979. return false;
  980. }
  981. }
  982. else
  983. {
  984. if(name == ustl::string("gl_PointCoord"))
  985. {
  986. int index = numVaryingVars;
  987. numVaryingVars++;
  988. varyingArray[index].name = name;
  989. varyingArray[index].type = type;
  990. varyingArray[index].fsRegIndex = regIndex;
  991. }
  992. else
  993. {
  994. int j=0;
  995. for(j=0; j< numVaryingVars; j++)
  996. {
  997. if(varyingArray[j].name == name)
  998. break;
  999. }
  1000. if(j == numVaryingVars)
  1001. {
  1002. errString.append("LINK FAILED: no matching varying declaration found in VS for: ");
  1003. errString.append(name);
  1004. return false;
  1005. }
  1006. if(varyingArray[j].type != type)
  1007. {
  1008. errString.append("LINK FAILED: type mismatch for varying : ");
  1009. errString.append(name + " VStype: "+getGLTypeString(varyingArray[j].type)+ " FStype: "
  1010. +getGLTypeString(type)+"\n");
  1011. return false;
  1012. }
  1013. varyingArray[j].fsRegIndex = regIndex;
  1014. }
  1015. }
  1016. return true;
  1017. }
  1018. bool ProgramVars::updateVaryingMap(Executable& exe, ustl::string& errString)
  1019. {
  1020. for(int i=0; i < MAX_VARYING_MAPPINGS; i++)
  1021. {
  1022. exe.varyingMap[i] = -1;
  1023. }
  1024. #if 1
  1025. //TODO: Handle arrays, implemented needs testing
  1026. for(int i=0; i < numVaryingVars; i++)
  1027. {
  1028. //discard component indices since hw only maps a full vs vec4 to a fs vec4
  1029. const int& vsReg = (varyingArray[i].vsRegIndex)>>2;
  1030. const int& fsReg = (varyingArray[i].fsRegIndex)>>2;
  1031. const int numSlotsUsed = getNumSlots(varyingArray[i].type);
  1032. gAssert( numSlotsUsed!= 0);
  1033. if( varyingArray[i].name != ustl::string("gl_PointCoord"))
  1034. {
  1035. if( (0 > vsReg) || ((vsReg+numSlotsUsed-1) > (MAX_VARYING_MAPPINGS)) )
  1036. {
  1037. errString.append(ustl::string("LINK ERROR: VS varying <")+varyingArray[i].name+ustl::string("> register out of range\n"));
  1038. return false;
  1039. }
  1040. }
  1041. else
  1042. {
  1043. exe.pointCoordIndex = varyingArray[i].fsRegIndex>>2;
  1044. }
  1045. //its okay to have a vs out which is not used by fs in so fsReg = -1 is allowed
  1046. if( /*(0 > fsReg) || */((fsReg+numSlotsUsed-1)>= MAX_VARYING_MAPPINGS) )
  1047. {
  1048. errString.append(ustl::string("LINK ERROR: FS varying <")+varyingArray[i].name+ustl::string("> register out of range\n"));
  1049. return false;
  1050. }
  1051. if( varyingArray[i].name != ustl::string("gl_PointCoord"))
  1052. {
  1053. for(int j = 0; j < numSlotsUsed; j++)
  1054. {
  1055. int actFsReg = (vsReg == 0)? 0 : (fsReg+j+1);
  1056. if(fsReg == -1 && vsReg !=0 )
  1057. {
  1058. actFsReg = -2;//TODO: remove this
  1059. }
  1060. gAssert((vsReg!=-1) &&"vsReg is -1");
  1061. if( exe.varyingMap[vsReg+j] == -1)
  1062. {
  1063. exe.varyingMap[vsReg+j] = actFsReg;
  1064. }
  1065. else if( exe.varyingMap[vsReg+j] != actFsReg )
  1066. {
  1067. //There is a bad mapping in the varyings. A variable in part of vsReg is mapped to exe.varyingMap[vsReg] but another
  1068. // variable needs it to be mapped to fsReg
  1069. errString.append(ustl::string("LINK ERROR: two variables in a VS varying register are to be mapped to different FS varying registers"));
  1070. return false;
  1071. }
  1072. }
  1073. }
  1074. }
  1075. //find the number of used varyings regs (may not be equal to numVaryingVars
  1076. // because of types like mat4 which requires 4 full vec4 registers or
  1077. // the number might be different due to packing.
  1078. int lastActiveMapping = -1;
  1079. int numActiveMappings = 0;
  1080. int lastActiveFSReg = -1;
  1081. for(int i=0; i< MAX_VARYING_MAPPINGS; i++)
  1082. {
  1083. if( exe.varyingMap[i] >=0)
  1084. {
  1085. lastActiveMapping = i;
  1086. numActiveMappings++;
  1087. }
  1088. }
  1089. for(int i=0; i< MAX_VARYING_MAPPINGS; i++)
  1090. {
  1091. if(exe.varyingMap[i]>=lastActiveFSReg)
  1092. {
  1093. lastActiveFSReg = exe.varyingMap[i];
  1094. }
  1095. }
  1096. bool unusedVSVarying = false;
  1097. // set all fsregs with -2 to some unused fs attrib reg. Like lastActiveMapping+1;
  1098. for(int i=0; i<=lastActiveMapping; i++)
  1099. {
  1100. if( exe.varyingMap[i] == -2)
  1101. {
  1102. //exe.varyingMap[i] = lastActiveFSReg+1;
  1103. exe.varyingMap[i] = ++lastActiveFSReg;
  1104. unusedVSVarying = true;
  1105. }
  1106. }
  1107. if(unusedVSVarying)
  1108. {
  1109. lastActiveFSReg++;
  1110. }
  1111. //TODO: since fimg has no problem with "holes" in mapping, we disregard it
  1112. /*
  1113. if( numActiveMappings != (lastActiveMapping+1))
  1114. {
  1115. //Some intermediate regs have no mapping
  1116. errString.append(ustl::string("LINK ERROR\n"));
  1117. gAssert(false && "Some intermediate varying regs have no mapping!");
  1118. return false;
  1119. }
  1120. */
  1121. exe.numVSVarying = lastActiveMapping+1;
  1122. exe.numFSVarying = lastActiveFSReg; //TODO check this
  1123. if(exe.pointCoordIndex!=-1)
  1124. {
  1125. if((exe.pointCoordIndex+1) > lastActiveFSReg)
  1126. {
  1127. exe.numFSVarying = (exe.pointCoordIndex+1);
  1128. }
  1129. #if 0
  1130. else
  1131. {
  1132. }
  1133. #endif
  1134. }
  1135. //LOGMSG("\n\n_____VARYING MAP: [max used VS varyings = %d, FS varyings = %d]_____\ngl_PointCoord : %d\n", exe.numVSVarying, exe.numFSVarying, exe.pointCoordIndex);
  1136. for(int i=0; i< exe.numVSVarying; i++)
  1137. {
  1138. //LOGMSG(" %d => %d\n", i, exe.varyingMap[i]);
  1139. }
  1140. //LOGMSG("\n");
  1141. #endif
  1142. return true;
  1143. }
  1144. bool ProgramVars::updateAttribMap(Executable& exe, ustl::string& errString)
  1145. {
  1146. int numMappings = 0;
  1147. int currentMap = 0;
  1148. for(unsigned int i=0; i < numAttributeVars; i++)
  1149. {
  1150. const int numSlotsUsed = getNumSlots(this->attributeArray[i].type);
  1151. gAssert( numSlotsUsed!= 0);
  1152. //Check here user assigned bindings
  1153. for(int j=0; j<numSlotsUsed; j++)
  1154. {
  1155. exe.attribMap[numMappings++] = currentMap++;
  1156. }
  1157. }
  1158. exe.numAttribs = numMappings;
  1159. //LOGMSG("\n\n_____OLD ATTRIB MAPPING: [max used attribs = %d]_____\n", exe.numAttribs);
  1160. //LOGMSG("VSReg => attrib index\n");
  1161. for(int i=0; i< exe.numAttribs; i++)
  1162. {
  1163. //LOGMSG(" %d => %d\n", i, exe.attribMap[i]);
  1164. }
  1165. //LOGMSG("\n");
  1166. return true;
  1167. }
  1168. void ProgramVars::printVaryings() const
  1169. {
  1170. //LOGMSG("\nVARYINGS (actuals not mapping!):\n");
  1171. // for(int i=0; i<numVaryingVars; i++)
  1172. // {
  1173. //LOGMSG("%s\t vs:%d\t fs:%d\t type:%s\n", varyingArray[i].name.c_str(),
  1174. // varyingArray[i].vsRegIndex, varyingArray[i].fsRegIndex, getGLTypeString(varyingArray[i].type));
  1175. // }
  1176. //LOGMSG("\n");
  1177. }
  1178. ProgramVars::~ProgramVars()
  1179. {
  1180. clear();
  1181. }
  1182. unsigned int ProgramVars::getNumActiveAttributes() const
  1183. {
  1184. return this->numAttributeVars;
  1185. }
  1186. int ProgramVars::getActiveAttributeMaxLength() const
  1187. {
  1188. const int numActiveAttributes = getNumActiveAttributes();
  1189. int maxLength = 0;
  1190. for(int i=0; i< numActiveAttributes; i++)
  1191. {
  1192. int curAttribLen = attributeArray[i].name.length()+1;
  1193. if(maxLength < curAttribLen)
  1194. maxLength = curAttribLen;
  1195. }
  1196. return maxLength;
  1197. }
  1198. unsigned int ProgramVars::getNumActiveUniforms() const
  1199. {
  1200. return uniformTbl.uniformNameMap.size();
  1201. }
  1202. int ProgramVars::getActiveUniformMaxLength() const
  1203. {
  1204. //int numActiveUniforms = getNumActiveUniforms();
  1205. int maxLength = 0;
  1206. NameMap::const_iterator it = uniformTbl.uniformNameMap.begin();
  1207. for(; it !=uniformTbl.uniformNameMap.end() ; ++it)
  1208. {
  1209. int curUniformLength = it->first.length()+1;
  1210. if(maxLength < curUniformLength)
  1211. maxLength = curUniformLength;
  1212. }
  1213. return maxLength;
  1214. }
  1215. //--------------- AttribBindings ---------------
  1216. AttribBindings::AttribBindings()
  1217. {
  1218. }
  1219. AttribBindings::~AttribBindings()
  1220. {
  1221. clear();
  1222. }
  1223. void AttribBindings::clear()
  1224. {
  1225. attribMap.clear();
  1226. }
  1227. // getLocation : returns the location if an entry is made against name
  1228. // else returns -1;
  1229. int AttribBindings::getLocation(const char *name)
  1230. {
  1231. ustl::string s(name);
  1232. ustl::map<ustl::string, int>::const_iterator it = attribMap.find(s);
  1233. if(it == attribMap.end())
  1234. {
  1235. return -1;
  1236. }
  1237. return it->second;
  1238. }
  1239. bool AttribBindings::setBinding(const char *name, int attribLoc)
  1240. {
  1241. ustl::map<ustl::string,int>::iterator it = attribMap.find(ustl::string(name));
  1242. if( it == attribMap.end()) //New entry
  1243. {
  1244. //Limit the maximum number of bindings!
  1245. if(attribMap.size() < MAX_VERTEX_ATTRIB_BINDINGS)
  1246. {
  1247. attribMap[ustl::string(name)] = attribLoc;
  1248. return true;
  1249. }
  1250. return false;
  1251. }
  1252. it->second = attribLoc;
  1253. return true;
  1254. }
  1255. //--------------- ShaderExecutable ---------------
  1256. ShaderExecutable::ShaderExecutable()
  1257. {
  1258. constFloatMemBlock = 0;
  1259. constIntMemBlock = 0;
  1260. constBoolMemBlock = 0;
  1261. binaryCode = 0;
  1262. #ifdef FSO_JITO
  1263. origBinaryCode = 0;
  1264. #endif
  1265. clear();
  1266. }
  1267. void ShaderExecutable::clear()
  1268. {
  1269. Plat::safe_free(constFloatMemBlock);
  1270. Plat::safe_free(constIntMemBlock);
  1271. Plat::safe_free(constBoolMemBlock);
  1272. fmbSize = 0;
  1273. imbSize = 0;
  1274. bmbSize = 0;
  1275. Plat::safe_free(binaryCode);
  1276. binaryCodeSize = 0;
  1277. pcStart = 0;
  1278. builtinUniformIndices.depthRange_near = -1;
  1279. builtinUniformIndices.depthRange_far = -1;
  1280. builtinUniformIndices.depthRange_diff = -1;
  1281. #ifdef FSO_JITO
  1282. Plat::safe_free(origBinaryCode);
  1283. origBinaryCodeSize = 0;
  1284. origPcStart = 0;
  1285. jitoEnabled = false;
  1286. jitoData.clear();
  1287. #endif
  1288. }
  1289. void ShaderExecutable::copyFrom(const ShaderExecutable &se)
  1290. {
  1291. this->clear();
  1292. void* dataPtr = 0;
  1293. dataPtr = Plat::malloc(se.fmbSize);
  1294. Plat::memcpy(dataPtr, se.constFloatMemBlock, se.fmbSize);
  1295. constFloatMemBlock = static_cast<float*>(dataPtr);
  1296. fmbSize = se.fmbSize;
  1297. dataPtr = Plat::malloc(se.imbSize);
  1298. Plat::memcpy(dataPtr, se.constIntMemBlock, se.imbSize);
  1299. constIntMemBlock = static_cast<char*>(dataPtr);
  1300. imbSize = se.imbSize;
  1301. dataPtr = Plat::malloc(se.bmbSize);
  1302. Plat::memcpy(dataPtr, se.constBoolMemBlock, se.bmbSize);
  1303. constBoolMemBlock = static_cast<char*>(dataPtr);
  1304. bmbSize = se.bmbSize;
  1305. dataPtr = Plat::malloc(se.binaryCodeSize);
  1306. Plat::memcpy(dataPtr, se.binaryCode, se.binaryCodeSize);
  1307. binaryCode = static_cast<unsigned char*>(dataPtr);
  1308. binaryCodeSize = se.binaryCodeSize;
  1309. pcStart = se.pcStart;
  1310. builtinUniformIndices = se.builtinUniformIndices;
  1311. #ifdef FSO_JITO
  1312. origBinaryCodeSize = se.origBinaryCodeSize;
  1313. origPcStart = se.origPcStart;
  1314. origBinaryCode = static_cast<unsigned char*>(Plat::malloc(origBinaryCodeSize));
  1315. Plat::memcpy(origBinaryCode, se.origBinaryCode, origBinaryCodeSize);
  1316. jitoEnabled = se.jitoEnabled;
  1317. jitoData = se.jitoData;
  1318. #endif
  1319. }
  1320. //--------------- Executable ---------------
  1321. void Executable::clear()
  1322. {
  1323. vs.clear();
  1324. fs.clear();
  1325. numAttribs = -1;
  1326. numVSVarying = -1;
  1327. numFSVarying = -1;
  1328. pointCoordIndex = -1;
  1329. pointSizeIndex = -1;
  1330. for(int i=0; i< MAX_VERTEX_TEXTURE_UNITS; i++)
  1331. {
  1332. vsSamplerMappings[i].setDefaults();
  1333. }

Large files files are truncated, but you can click here to view the full file