Shader.cpp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. /**
  2. * Copyright (c) 2006-2020 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "common/config.h"
  22. #include "Shader.h"
  23. #include "ShaderStage.h"
  24. #include "Graphics.h"
  25. #include "graphics/vertex.h"
  26. // C++
  27. #include <algorithm>
  28. #include <limits>
  29. #include <sstream>
  30. namespace love
  31. {
  32. namespace graphics
  33. {
  34. namespace opengl
  35. {
  36. Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
  37. : love::graphics::Shader(vertex, pixel)
  38. , program(0)
  39. , builtinUniforms()
  40. , builtinUniformInfo()
  41. , lastPointSize(0.0f)
  42. {
  43. // load shader source and create program object
  44. loadVolatile();
  45. }
  46. Shader::~Shader()
  47. {
  48. unloadVolatile();
  49. for (const auto &p : uniforms)
  50. {
  51. // Allocated with malloc().
  52. if (p.second.data != nullptr)
  53. free(p.second.data);
  54. if (p.second.baseType == UNIFORM_SAMPLER)
  55. {
  56. for (int i = 0; i < p.second.count; i++)
  57. {
  58. if (p.second.textures[i] != nullptr)
  59. p.second.textures[i]->release();
  60. }
  61. delete[] p.second.textures;
  62. }
  63. else if (p.second.baseType == UNIFORM_TEXELBUFFER)
  64. {
  65. for (int i = 0; i < p.second.count; i++)
  66. {
  67. if (p.second.buffers[i] != nullptr)
  68. p.second.buffers[i]->release();
  69. }
  70. delete[] p.second.buffers;
  71. }
  72. }
  73. }
  74. void Shader::mapActiveUniforms()
  75. {
  76. // Built-in uniform locations default to -1 (nonexistent.)
  77. for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
  78. {
  79. builtinUniforms[i] = -1;
  80. builtinUniformInfo[i] = nullptr;
  81. }
  82. GLint activeprogram = 0;
  83. glGetIntegerv(GL_CURRENT_PROGRAM, &activeprogram);
  84. gl.useProgram(program);
  85. GLint numuniforms;
  86. glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numuniforms);
  87. GLchar cname[256];
  88. const GLint bufsize = (GLint) (sizeof(cname) / sizeof(GLchar));
  89. std::map<std::string, UniformInfo> olduniforms = uniforms;
  90. uniforms.clear();
  91. for (int uindex = 0; uindex < numuniforms; uindex++)
  92. {
  93. GLsizei namelen = 0;
  94. GLenum gltype = 0;
  95. UniformInfo u = {};
  96. glGetActiveUniform(program, (GLuint) uindex, bufsize, &namelen, &u.count, &gltype, cname);
  97. u.name = std::string(cname, (size_t) namelen);
  98. u.location = glGetUniformLocation(program, u.name.c_str());
  99. u.baseType = getUniformBaseType(gltype);
  100. u.textureType = getUniformTextureType(gltype);
  101. u.texelBufferType = getUniformTexelBufferType(gltype);
  102. u.isDepthSampler = isDepthTextureType(gltype);
  103. if (u.baseType == UNIFORM_MATRIX)
  104. u.matrix = getMatrixSize(gltype);
  105. else
  106. u.components = getUniformTypeComponents(gltype);
  107. // glGetActiveUniform appends "[0]" to the end of array uniform names...
  108. if (u.name.length() > 3)
  109. {
  110. size_t findpos = u.name.find("[0]");
  111. if (findpos != std::string::npos && findpos == u.name.length() - 3)
  112. u.name.erase(u.name.length() - 3);
  113. }
  114. // If this is a built-in (LOVE-created) uniform, store the location.
  115. BuiltinUniform builtin = BUILTIN_MAX_ENUM;
  116. if (getConstant(u.name.c_str(), builtin))
  117. builtinUniforms[int(builtin)] = u.location;
  118. if (u.location == -1)
  119. continue;
  120. if ((u.baseType == UNIFORM_SAMPLER && builtin != BUILTIN_TEXTURE_MAIN) || u.baseType == UNIFORM_TEXELBUFFER)
  121. {
  122. TextureUnit unit;
  123. unit.type = u.textureType;
  124. unit.active = true;
  125. if (u.baseType == UNIFORM_TEXELBUFFER)
  126. {
  127. unit.isTexelBuffer = true;
  128. unit.texture = gl.getDefaultTexelBuffer();
  129. }
  130. else
  131. {
  132. unit.isTexelBuffer = false;
  133. unit.texture = gl.getDefaultTexture(u.textureType);
  134. }
  135. for (int i = 0; i < u.count; i++)
  136. textureUnits.push_back(unit);
  137. }
  138. // Make sure previously set uniform data is preserved, and shader-
  139. // initialized values are retrieved.
  140. auto oldu = olduniforms.find(u.name);
  141. if (oldu != olduniforms.end())
  142. {
  143. u.data = oldu->second.data;
  144. u.dataSize = oldu->second.dataSize;
  145. u.textures = oldu->second.textures;
  146. updateUniform(&u, u.count, true);
  147. }
  148. else
  149. {
  150. u.dataSize = 0;
  151. switch (u.baseType)
  152. {
  153. case UNIFORM_FLOAT:
  154. u.dataSize = sizeof(float) * u.components * u.count;
  155. u.data = malloc(u.dataSize);
  156. break;
  157. case UNIFORM_INT:
  158. case UNIFORM_BOOL:
  159. case UNIFORM_SAMPLER:
  160. case UNIFORM_TEXELBUFFER:
  161. u.dataSize = sizeof(int) * u.components * u.count;
  162. u.data = malloc(u.dataSize);
  163. break;
  164. case UNIFORM_UINT:
  165. u.dataSize = sizeof(unsigned int) * u.components * u.count;
  166. u.data = malloc(u.dataSize);
  167. break;
  168. case UNIFORM_MATRIX:
  169. u.dataSize = sizeof(float) * (u.matrix.rows * u.matrix.columns) * u.count;
  170. u.data = malloc(u.dataSize);
  171. break;
  172. default:
  173. break;
  174. }
  175. if (u.dataSize > 0)
  176. {
  177. memset(u.data, 0, u.dataSize);
  178. if (u.baseType == UNIFORM_SAMPLER || u.baseType == UNIFORM_TEXELBUFFER)
  179. {
  180. int startunit = (int) textureUnits.size() - u.count;
  181. if (builtin == BUILTIN_TEXTURE_MAIN)
  182. startunit = 0;
  183. for (int i = 0; i < u.count; i++)
  184. u.ints[i] = startunit + i;
  185. glUniform1iv(u.location, u.count, u.ints);
  186. if (u.baseType == UNIFORM_TEXELBUFFER)
  187. {
  188. u.buffers = new love::graphics::Buffer*[u.count];
  189. memset(u.buffers, 0, sizeof(Buffer *) * u.count);
  190. }
  191. else
  192. {
  193. u.textures = new love::graphics::Texture*[u.count];
  194. memset(u.textures, 0, sizeof(Texture *) * u.count);
  195. }
  196. }
  197. }
  198. size_t offset = 0;
  199. // Store any shader-initialized values in our own memory.
  200. for (int i = 0; i < u.count; i++)
  201. {
  202. GLint location = u.location;
  203. if (u.count > 1)
  204. {
  205. std::ostringstream ss;
  206. ss << i;
  207. std::string indexname = u.name + "[" + ss.str() + "]";
  208. location = glGetUniformLocation(program, indexname.c_str());
  209. }
  210. if (location == -1)
  211. continue;
  212. switch (u.baseType)
  213. {
  214. case UNIFORM_FLOAT:
  215. glGetUniformfv(program, location, &u.floats[offset]);
  216. offset += u.components;
  217. break;
  218. case UNIFORM_INT:
  219. case UNIFORM_BOOL:
  220. glGetUniformiv(program, location, &u.ints[offset]);
  221. offset += u.components;
  222. break;
  223. case UNIFORM_UINT:
  224. glGetUniformuiv(program, location, &u.uints[offset]);
  225. offset += u.components;
  226. break;
  227. case UNIFORM_MATRIX:
  228. glGetUniformfv(program, location, &u.floats[offset]);
  229. offset += u.matrix.rows * u.matrix.columns;
  230. break;
  231. default:
  232. break;
  233. }
  234. }
  235. }
  236. uniforms[u.name] = u;
  237. if (builtin != BUILTIN_MAX_ENUM)
  238. builtinUniformInfo[(int)builtin] = &uniforms[u.name];
  239. if (u.baseType == UNIFORM_SAMPLER)
  240. {
  241. // Make sure all stored textures have their Volatiles loaded before
  242. // the sendTextures call, since it calls getHandle().
  243. for (int i = 0; i < u.count; i++)
  244. {
  245. if (u.textures[i] == nullptr)
  246. continue;
  247. Volatile *v = dynamic_cast<Volatile *>(u.textures[i]);
  248. if (v != nullptr)
  249. v->loadVolatile();
  250. }
  251. sendTextures(&u, u.textures, u.count, true);
  252. }
  253. else if (u.baseType == UNIFORM_TEXELBUFFER)
  254. {
  255. for (int i = 0; i < u.count; i++)
  256. {
  257. if (u.buffers[i] == nullptr)
  258. continue;
  259. Volatile *v = dynamic_cast<Volatile *>(u.buffers[i]);
  260. if (v != nullptr)
  261. v->loadVolatile();
  262. }
  263. sendBuffers(&u, u.buffers, u.count, true);
  264. }
  265. }
  266. // Make sure uniforms that existed before but don't exist anymore are
  267. // cleaned up. This theoretically shouldn't happen, but...
  268. for (const auto &p : olduniforms)
  269. {
  270. if (uniforms.find(p.first) == uniforms.end())
  271. {
  272. free(p.second.data);
  273. if (p.second.baseType == UNIFORM_SAMPLER)
  274. {
  275. for (int i = 0; i < p.second.count; i++)
  276. {
  277. if (p.second.textures[i] != nullptr)
  278. p.second.textures[i]->release();
  279. }
  280. delete[] p.second.textures;
  281. }
  282. else if (p.second.baseType == UNIFORM_TEXELBUFFER)
  283. {
  284. for (int i = 0; i < p.second.count; i++)
  285. {
  286. if (p.second.buffers[i] != nullptr)
  287. p.second.buffers[i]->release();
  288. }
  289. delete[] p.second.buffers;
  290. }
  291. }
  292. }
  293. gl.useProgram(activeprogram);
  294. }
  295. bool Shader::loadVolatile()
  296. {
  297. OpenGL::TempDebugGroup debuggroup("Shader load");
  298. lastPointSize = -1.0f;
  299. // zero out active texture list
  300. textureUnits.clear();
  301. textureUnits.push_back(TextureUnit());
  302. for (const auto &stage : stages)
  303. {
  304. if (stage.get() != nullptr)
  305. ((ShaderStage*)stage.get())->loadVolatile();
  306. }
  307. program = glCreateProgram();
  308. if (program == 0)
  309. throw love::Exception("Cannot create shader program object.");
  310. for (const auto &stage : stages)
  311. {
  312. if (stage.get() != nullptr)
  313. glAttachShader(program, (GLuint) stage->getHandle());
  314. }
  315. // Bind generic vertex attribute indices to names in the shader.
  316. for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
  317. {
  318. const char *name = nullptr;
  319. if (graphics::getConstant((BuiltinVertexAttribute) i, name))
  320. glBindAttribLocation(program, i, (const GLchar *) name);
  321. }
  322. glLinkProgram(program);
  323. GLint status;
  324. glGetProgramiv(program, GL_LINK_STATUS, &status);
  325. if (status == GL_FALSE)
  326. {
  327. std::string warnings = getProgramWarnings();
  328. glDeleteProgram(program);
  329. program = 0;
  330. throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
  331. }
  332. // Get all active uniform variables in this shader from OpenGL.
  333. mapActiveUniforms();
  334. if (current == this)
  335. {
  336. // make sure glUseProgram gets called.
  337. current = nullptr;
  338. attach();
  339. }
  340. return true;
  341. }
  342. void Shader::unloadVolatile()
  343. {
  344. if (program != 0)
  345. {
  346. if (current == this)
  347. gl.useProgram(0);
  348. glDeleteProgram(program);
  349. program = 0;
  350. }
  351. // active texture list is probably invalid, clear it
  352. textureUnits.clear();
  353. textureUnits.push_back(TextureUnit());
  354. attributes.clear();
  355. // And the locations of any built-in uniform variables.
  356. for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
  357. builtinUniforms[i] = -1;
  358. }
  359. std::string Shader::getProgramWarnings() const
  360. {
  361. GLint strsize, nullpos;
  362. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strsize);
  363. if (strsize == 0)
  364. return "";
  365. char *tempstr = new char[strsize];
  366. // be extra sure that the error string will be 0-terminated
  367. memset(tempstr, '\0', strsize);
  368. glGetProgramInfoLog(program, strsize, &nullpos, tempstr);
  369. tempstr[nullpos] = '\0';
  370. std::string warnings(tempstr);
  371. delete[] tempstr;
  372. return warnings;
  373. }
  374. std::string Shader::getWarnings() const
  375. {
  376. std::string warnings;
  377. const char *stagestr;
  378. for (const auto &stage : stages)
  379. {
  380. if (stage.get() == nullptr)
  381. continue;
  382. const std::string &stagewarnings = stage->getWarnings();
  383. if (ShaderStage::getConstant(stage->getStageType(), stagestr))
  384. warnings += std::string(stagestr) + std::string(" shader:\n") + stagewarnings;
  385. }
  386. warnings += getProgramWarnings();
  387. return warnings;
  388. }
  389. void Shader::attach()
  390. {
  391. if (current != this)
  392. {
  393. Graphics::flushBatchedDrawsGlobal();
  394. gl.useProgram(program);
  395. current = this;
  396. // retain/release happens in Graphics::setShader.
  397. // Make sure all textures are bound to their respective texture units.
  398. for (int i = 0; i < (int) textureUnits.size(); ++i)
  399. {
  400. const TextureUnit &unit = textureUnits[i];
  401. if (unit.active)
  402. {
  403. if (unit.isTexelBuffer)
  404. gl.bindBufferTextureToUnit(unit.texture, i, false, false);
  405. else
  406. gl.bindTextureToUnit(unit.type, unit.texture, i, false, false);
  407. }
  408. }
  409. // send any pending uniforms to the shader program.
  410. for (const auto &p : pendingUniformUpdates)
  411. updateUniform(p.first, p.second, true);
  412. pendingUniformUpdates.clear();
  413. }
  414. }
  415. const Shader::UniformInfo *Shader::getUniformInfo(const std::string &name) const
  416. {
  417. const auto it = uniforms.find(name);
  418. if (it == uniforms.end())
  419. return nullptr;
  420. return &(it->second);
  421. }
  422. const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
  423. {
  424. return builtinUniformInfo[(int)builtin];
  425. }
  426. void Shader::updateUniform(const UniformInfo *info, int count)
  427. {
  428. updateUniform(info, count, false);
  429. }
  430. void Shader::updateUniform(const UniformInfo *info, int count, bool internalupdate)
  431. {
  432. if (current != this && !internalupdate)
  433. {
  434. pendingUniformUpdates.push_back(std::make_pair(info, count));
  435. return;
  436. }
  437. if (!internalupdate)
  438. flushBatchedDraws();
  439. int location = info->location;
  440. UniformType type = info->baseType;
  441. if (type == UNIFORM_FLOAT)
  442. {
  443. switch (info->components)
  444. {
  445. case 1:
  446. glUniform1fv(location, count, info->floats);
  447. break;
  448. case 2:
  449. glUniform2fv(location, count, info->floats);
  450. break;
  451. case 3:
  452. glUniform3fv(location, count, info->floats);
  453. break;
  454. case 4:
  455. glUniform4fv(location, count, info->floats);
  456. break;
  457. }
  458. }
  459. else if (type == UNIFORM_INT || type == UNIFORM_BOOL || type == UNIFORM_SAMPLER || type == UNIFORM_TEXELBUFFER)
  460. {
  461. switch (info->components)
  462. {
  463. case 1:
  464. glUniform1iv(location, count, info->ints);
  465. break;
  466. case 2:
  467. glUniform2iv(location, count, info->ints);
  468. break;
  469. case 3:
  470. glUniform3iv(location, count, info->ints);
  471. break;
  472. case 4:
  473. glUniform4iv(location, count, info->ints);
  474. break;
  475. }
  476. }
  477. else if (type == UNIFORM_UINT)
  478. {
  479. switch (info->components)
  480. {
  481. case 1:
  482. glUniform1uiv(location, count, info->uints);
  483. break;
  484. case 2:
  485. glUniform2uiv(location, count, info->uints);
  486. break;
  487. case 3:
  488. glUniform3uiv(location, count, info->uints);
  489. break;
  490. case 4:
  491. glUniform4uiv(location, count, info->uints);
  492. break;
  493. }
  494. }
  495. else if (type == UNIFORM_MATRIX)
  496. {
  497. int columns = info->matrix.columns;
  498. int rows = info->matrix.rows;
  499. if (columns == 2 && rows == 2)
  500. glUniformMatrix2fv(location, count, GL_FALSE, info->floats);
  501. else if (columns == 3 && rows == 3)
  502. glUniformMatrix3fv(location, count, GL_FALSE, info->floats);
  503. else if (columns == 4 && rows == 4)
  504. glUniformMatrix4fv(location, count, GL_FALSE, info->floats);
  505. else if (columns == 2 && rows == 3)
  506. glUniformMatrix2x3fv(location, count, GL_FALSE, info->floats);
  507. else if (columns == 2 && rows == 4)
  508. glUniformMatrix2x4fv(location, count, GL_FALSE, info->floats);
  509. else if (columns == 3 && rows == 2)
  510. glUniformMatrix3x2fv(location, count, GL_FALSE, info->floats);
  511. else if (columns == 3 && rows == 4)
  512. glUniformMatrix3x4fv(location, count, GL_FALSE, info->floats);
  513. else if (columns == 4 && rows == 2)
  514. glUniformMatrix4x2fv(location, count, GL_FALSE, info->floats);
  515. else if (columns == 4 && rows == 3)
  516. glUniformMatrix4x3fv(location, count, GL_FALSE, info->floats);
  517. }
  518. }
  519. void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
  520. {
  521. Shader::sendTextures(info, textures, count, false);
  522. }
  523. void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count, bool internalUpdate)
  524. {
  525. if (info->baseType != UNIFORM_SAMPLER)
  526. return;
  527. bool shaderactive = current == this;
  528. if (!internalUpdate && shaderactive)
  529. flushBatchedDraws();
  530. count = std::min(count, info->count);
  531. // Bind the textures to the texture units.
  532. for (int i = 0; i < count; i++)
  533. {
  534. love::graphics::Texture *tex = textures[i];
  535. if (tex != nullptr)
  536. {
  537. const SamplerState &sampler = tex->getSamplerState();
  538. if (!tex->isReadable())
  539. {
  540. if (internalUpdate)
  541. continue;
  542. else
  543. throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
  544. }
  545. else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
  546. {
  547. if (internalUpdate)
  548. continue;
  549. else if (info->isDepthSampler)
  550. throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
  551. else
  552. throw love::Exception("Depth textures which have depth comparison set can only be used with depth/shadow samplers in shaders.");
  553. }
  554. else if (tex->getTextureType() != info->textureType)
  555. {
  556. if (internalUpdate)
  557. continue;
  558. else
  559. {
  560. const char *textypestr = "unknown";
  561. const char *shadertextypestr = "unknown";
  562. Texture::getConstant(tex->getTextureType(), textypestr);
  563. Texture::getConstant(info->textureType, shadertextypestr);
  564. throw love::Exception("Texture's type (%s) must match the type of %s (%s).", textypestr, info->name.c_str(), shadertextypestr);
  565. }
  566. }
  567. tex->retain();
  568. }
  569. if (info->textures[i] != nullptr)
  570. info->textures[i]->release();
  571. info->textures[i] = tex;
  572. GLuint gltex = 0;
  573. if (textures[i] != nullptr)
  574. gltex = (GLuint) tex->getHandle();
  575. else
  576. gltex = gl.getDefaultTexture(info->textureType);
  577. int texunit = info->ints[i];
  578. if (shaderactive)
  579. gl.bindTextureToUnit(info->textureType, gltex, texunit, false, false);
  580. // Store texture id so it can be re-bound to the texture unit later.
  581. textureUnits[texunit].texture = gltex;
  582. }
  583. }
  584. void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
  585. {
  586. Shader::sendBuffers(info, buffers, count, false);
  587. }
  588. static bool isTexelBufferTypeCompatible(DataBaseType a, DataBaseType b)
  589. {
  590. if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
  591. return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
  592. if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
  593. return true;
  594. if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
  595. return true;
  596. return false;
  597. }
  598. void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
  599. {
  600. if (info->baseType != UNIFORM_TEXELBUFFER)
  601. return;
  602. uint32 requiredtypeflags = Buffer::TYPEFLAG_TEXEL;
  603. bool shaderactive = current == this;
  604. if (!internalUpdate && shaderactive)
  605. flushBatchedDraws();
  606. count = std::min(count, info->count);
  607. // Bind the textures to the texture units.
  608. for (int i = 0; i < count; i++)
  609. {
  610. love::graphics::Buffer *buffer = buffers[i];
  611. if (buffer != nullptr)
  612. {
  613. if ((buffer->getTypeFlags() & requiredtypeflags) == 0)
  614. {
  615. if (internalUpdate)
  616. continue;
  617. else
  618. throw love::Exception("Shader uniform '%s' is a texel buffer, but the given Buffer was not created with texel buffer capabilities.", info->name.c_str());
  619. }
  620. DataBaseType basetype = buffer->getDataMember(0).info.baseType;
  621. if (!isTexelBufferTypeCompatible(basetype, info->texelBufferType))
  622. {
  623. if (internalUpdate)
  624. continue;
  625. else
  626. throw love::Exception("Texel buffer's data format base type must match the variable declared in the shader.");
  627. }
  628. buffer->retain();
  629. }
  630. bool addbuffertoarray = true;
  631. if (info->buffers[i] != nullptr)
  632. {
  633. Buffer *oldbuffer = info->buffers[i];
  634. auto it = std::find(buffersToUnmap.begin(), buffersToUnmap.end(), oldbuffer);
  635. if (it != buffersToUnmap.end())
  636. {
  637. addbuffertoarray = false;
  638. if (buffer != nullptr)
  639. *it = buffer;
  640. else
  641. {
  642. auto last = buffersToUnmap.end() - 1;
  643. *it = *last;
  644. buffersToUnmap.erase(last);
  645. }
  646. }
  647. oldbuffer->release();
  648. }
  649. if (addbuffertoarray && buffer != nullptr)
  650. buffersToUnmap.push_back(buffer);
  651. info->buffers[i] = buffer;
  652. GLuint gltex = 0;
  653. if (buffers[i] != nullptr)
  654. gltex = (GLuint) buffer->getTexelBufferHandle();
  655. else
  656. gltex = gl.getDefaultTexelBuffer();
  657. int texunit = info->ints[i];
  658. if (shaderactive)
  659. gl.bindBufferTextureToUnit(gltex, texunit, false, false);
  660. // Store texture id so it can be re-bound to the texture unit later.
  661. textureUnits[texunit].texture = gltex;
  662. }
  663. }
  664. void Shader::flushBatchedDraws() const
  665. {
  666. if (current == this)
  667. Graphics::flushBatchedDrawsGlobal();
  668. }
  669. bool Shader::hasUniform(const std::string &name) const
  670. {
  671. return uniforms.find(name) != uniforms.end();
  672. }
  673. ptrdiff_t Shader::getHandle() const
  674. {
  675. return program;
  676. }
  677. int Shader::getVertexAttributeIndex(const std::string &name)
  678. {
  679. auto it = attributes.find(name);
  680. if (it != attributes.end())
  681. return it->second;
  682. GLint location = glGetAttribLocation(program, name.c_str());
  683. attributes[name] = location;
  684. return location;
  685. }
  686. void Shader::setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture)
  687. {
  688. const BuiltinUniform builtins[3] = {
  689. BUILTIN_TEXTURE_VIDEO_Y,
  690. BUILTIN_TEXTURE_VIDEO_CB,
  691. BUILTIN_TEXTURE_VIDEO_CR,
  692. };
  693. love::graphics::Texture *textures[3] = {ytexture, cbtexture, crtexture};
  694. for (int i = 0; i < 3; i++)
  695. {
  696. const UniformInfo *info = builtinUniformInfo[builtins[i]];
  697. if (info != nullptr)
  698. sendTextures(info, &textures[i], 1, true);
  699. }
  700. }
  701. void Shader::updatePointSize(float size)
  702. {
  703. if (size == lastPointSize || current != this)
  704. return;
  705. GLint location = builtinUniforms[BUILTIN_POINT_SIZE];
  706. if (location >= 0)
  707. glUniform1f(location, size);
  708. lastPointSize = size;
  709. }
  710. void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW, int viewportH)
  711. {
  712. if (current != this)
  713. return;
  714. if (GLAD_ES_VERSION_2_0)
  715. updatePointSize(gl.getPointSize());
  716. BuiltinUniformData data;
  717. data.transformMatrix = gfx->getTransform();
  718. data.projectionMatrix = gfx->getProjection();
  719. // The normal matrix is the transpose of the inverse of the rotation portion
  720. // (top-left 3x3) of the transform matrix.
  721. {
  722. Matrix3 normalmatrix = Matrix3(data.transformMatrix).transposedInverse();
  723. const float *e = normalmatrix.getElements();
  724. for (int i = 0; i < 3; i++)
  725. {
  726. data.normalMatrix[i].x = e[i * 3 + 0];
  727. data.normalMatrix[i].y = e[i * 3 + 1];
  728. data.normalMatrix[i].z = e[i * 3 + 2];
  729. data.normalMatrix[i].w = 0.0f;
  730. }
  731. }
  732. data.screenSizeParams.x = viewportW;
  733. data.screenSizeParams.y = viewportH;
  734. // The shader does pixcoord.y = gl_FragCoord.y * params.z + params.w.
  735. // This lets us flip pixcoord.y when needed, to be consistent (drawing
  736. // with no RT active makes the pixel coordinates y-flipped.)
  737. if (gfx->isRenderTargetActive())
  738. {
  739. // No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0.
  740. data.screenSizeParams.z = 1.0f;
  741. data.screenSizeParams.w = 0.0f;
  742. }
  743. else
  744. {
  745. // gl_FragCoord.y is flipped when drawing to the screen, so we
  746. // un-flip: pixcoord.y = gl_FragCoord.y * -1.0 + height.
  747. data.screenSizeParams.z = -1.0f;
  748. data.screenSizeParams.w = viewportH;
  749. }
  750. data.constantColor = gfx->getColor();
  751. gammaCorrectColor(data.constantColor);
  752. GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
  753. if (location >= 0)
  754. glUniform4fv(location, 13, (const GLfloat *) &data);
  755. // TODO: Find a better place to put this.
  756. // Buffers used in this shader can be mapped by external code without
  757. // unmapping. We need to make sure the data on the GPU is up to date,
  758. // otherwise the shader can read from old data.
  759. for (Buffer *buffer : buffersToUnmap)
  760. buffer->unmap();
  761. }
  762. int Shader::getUniformTypeComponents(GLenum type) const
  763. {
  764. UniformType basetype = getUniformBaseType(type);
  765. if (basetype == UNIFORM_SAMPLER || basetype == UNIFORM_TEXELBUFFER)
  766. return 1;
  767. switch (type)
  768. {
  769. case GL_INT:
  770. case GL_UNSIGNED_INT:
  771. case GL_FLOAT:
  772. case GL_BOOL:
  773. return 1;
  774. case GL_INT_VEC2:
  775. case GL_UNSIGNED_INT_VEC2:
  776. case GL_FLOAT_VEC2:
  777. case GL_FLOAT_MAT2:
  778. case GL_BOOL_VEC2:
  779. return 2;
  780. case GL_INT_VEC3:
  781. case GL_UNSIGNED_INT_VEC3:
  782. case GL_FLOAT_VEC3:
  783. case GL_FLOAT_MAT3:
  784. case GL_BOOL_VEC3:
  785. return 3;
  786. case GL_INT_VEC4:
  787. case GL_UNSIGNED_INT_VEC4:
  788. case GL_FLOAT_VEC4:
  789. case GL_FLOAT_MAT4:
  790. case GL_BOOL_VEC4:
  791. return 4;
  792. default:
  793. return 1;
  794. }
  795. }
  796. Shader::MatrixSize Shader::getMatrixSize(GLenum type) const
  797. {
  798. MatrixSize m;
  799. switch (type)
  800. {
  801. case GL_FLOAT_MAT2:
  802. m.columns = m.rows = 2;
  803. break;
  804. case GL_FLOAT_MAT3:
  805. m.columns = m.rows = 3;
  806. break;
  807. case GL_FLOAT_MAT4:
  808. m.columns = m.rows = 4;
  809. break;
  810. case GL_FLOAT_MAT2x3:
  811. m.columns = 2;
  812. m.rows = 3;
  813. break;
  814. case GL_FLOAT_MAT2x4:
  815. m.columns = 2;
  816. m.rows = 4;
  817. break;
  818. case GL_FLOAT_MAT3x2:
  819. m.columns = 3;
  820. m.rows = 2;
  821. break;
  822. case GL_FLOAT_MAT3x4:
  823. m.columns = 3;
  824. m.rows = 4;
  825. break;
  826. case GL_FLOAT_MAT4x2:
  827. m.columns = 4;
  828. m.rows = 2;
  829. break;
  830. case GL_FLOAT_MAT4x3:
  831. m.columns = 4;
  832. m.rows = 3;
  833. break;
  834. }
  835. return m;
  836. }
  837. Shader::UniformType Shader::getUniformBaseType(GLenum type) const
  838. {
  839. switch (type)
  840. {
  841. case GL_INT:
  842. case GL_INT_VEC2:
  843. case GL_INT_VEC3:
  844. case GL_INT_VEC4:
  845. return UNIFORM_INT;
  846. case GL_UNSIGNED_INT:
  847. case GL_UNSIGNED_INT_VEC2:
  848. case GL_UNSIGNED_INT_VEC3:
  849. case GL_UNSIGNED_INT_VEC4:
  850. return UNIFORM_UINT;
  851. case GL_FLOAT:
  852. case GL_FLOAT_VEC2:
  853. case GL_FLOAT_VEC3:
  854. case GL_FLOAT_VEC4:
  855. return UNIFORM_FLOAT;
  856. case GL_FLOAT_MAT2:
  857. case GL_FLOAT_MAT3:
  858. case GL_FLOAT_MAT4:
  859. case GL_FLOAT_MAT2x3:
  860. case GL_FLOAT_MAT2x4:
  861. case GL_FLOAT_MAT3x2:
  862. case GL_FLOAT_MAT3x4:
  863. case GL_FLOAT_MAT4x2:
  864. case GL_FLOAT_MAT4x3:
  865. return UNIFORM_MATRIX;
  866. case GL_BOOL:
  867. case GL_BOOL_VEC2:
  868. case GL_BOOL_VEC3:
  869. case GL_BOOL_VEC4:
  870. return UNIFORM_BOOL;
  871. case GL_SAMPLER_1D:
  872. case GL_SAMPLER_1D_SHADOW:
  873. case GL_SAMPLER_1D_ARRAY:
  874. case GL_SAMPLER_1D_ARRAY_SHADOW:
  875. case GL_SAMPLER_2D:
  876. case GL_SAMPLER_2D_MULTISAMPLE:
  877. case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
  878. case GL_SAMPLER_2D_RECT:
  879. case GL_SAMPLER_2D_RECT_SHADOW:
  880. case GL_SAMPLER_2D_SHADOW:
  881. case GL_SAMPLER_2D_ARRAY:
  882. case GL_SAMPLER_2D_ARRAY_SHADOW:
  883. case GL_SAMPLER_3D:
  884. case GL_SAMPLER_CUBE:
  885. case GL_SAMPLER_CUBE_SHADOW:
  886. case GL_SAMPLER_CUBE_MAP_ARRAY:
  887. case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
  888. return UNIFORM_SAMPLER;
  889. case GL_SAMPLER_BUFFER:
  890. case GL_INT_SAMPLER_BUFFER:
  891. case GL_UNSIGNED_INT_SAMPLER_BUFFER:
  892. return UNIFORM_TEXELBUFFER;
  893. default:
  894. return UNIFORM_UNKNOWN;
  895. }
  896. }
  897. TextureType Shader::getUniformTextureType(GLenum type) const
  898. {
  899. switch (type)
  900. {
  901. case GL_SAMPLER_1D:
  902. case GL_SAMPLER_1D_SHADOW:
  903. case GL_SAMPLER_1D_ARRAY:
  904. case GL_SAMPLER_1D_ARRAY_SHADOW:
  905. // 1D-typed textures are not supported.
  906. return TEXTURE_MAX_ENUM;
  907. case GL_SAMPLER_2D:
  908. case GL_SAMPLER_2D_SHADOW:
  909. return TEXTURE_2D;
  910. case GL_SAMPLER_2D_MULTISAMPLE:
  911. case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
  912. // Multisample textures are not supported.
  913. return TEXTURE_MAX_ENUM;
  914. case GL_SAMPLER_2D_RECT:
  915. case GL_SAMPLER_2D_RECT_SHADOW:
  916. // Rectangle textures are not supported.
  917. return TEXTURE_MAX_ENUM;
  918. case GL_SAMPLER_2D_ARRAY:
  919. case GL_SAMPLER_2D_ARRAY_SHADOW:
  920. return TEXTURE_2D_ARRAY;
  921. case GL_SAMPLER_3D:
  922. return TEXTURE_VOLUME;
  923. case GL_SAMPLER_CUBE:
  924. case GL_SAMPLER_CUBE_SHADOW:
  925. return TEXTURE_CUBE;
  926. case GL_SAMPLER_CUBE_MAP_ARRAY:
  927. case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
  928. // Cubemap array textures are not supported.
  929. return TEXTURE_MAX_ENUM;
  930. default:
  931. return TEXTURE_MAX_ENUM;
  932. }
  933. }
  934. DataBaseType Shader::getUniformTexelBufferType(GLenum type) const
  935. {
  936. switch (type)
  937. {
  938. case GL_SAMPLER_BUFFER:
  939. return DATA_BASETYPE_FLOAT;
  940. case GL_INT_SAMPLER_BUFFER:
  941. return DATA_BASETYPE_INT;
  942. case GL_UNSIGNED_INT_SAMPLER_BUFFER:
  943. return DATA_BASETYPE_UINT;
  944. default:
  945. return DATA_BASETYPE_MAX_ENUM;
  946. }
  947. }
  948. bool Shader::isDepthTextureType(GLenum type) const
  949. {
  950. switch (type)
  951. {
  952. case GL_SAMPLER_1D_SHADOW:
  953. case GL_SAMPLER_1D_ARRAY_SHADOW:
  954. case GL_SAMPLER_2D_SHADOW:
  955. case GL_SAMPLER_2D_ARRAY_SHADOW:
  956. case GL_SAMPLER_CUBE_SHADOW:
  957. case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
  958. return true;
  959. default:
  960. return false;
  961. }
  962. }
  963. } // opengl
  964. } // graphics
  965. } // love