Shader.cpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313
  1. /**
  2. * Copyright (c) 2006-2023 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. static bool isBuffer(Shader::UniformType utype)
  37. {
  38. return utype == Shader::UNIFORM_TEXELBUFFER || utype == Shader::UNIFORM_STORAGEBUFFER;
  39. }
  40. Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
  41. : love::graphics::Shader(stages)
  42. , program(0)
  43. , splitUniformsPerDraw(false)
  44. , builtinUniforms()
  45. , builtinUniformInfo()
  46. {
  47. // load shader source and create program object
  48. loadVolatile();
  49. }
  50. Shader::~Shader()
  51. {
  52. unloadVolatile();
  53. for (const auto &p : uniforms)
  54. {
  55. // Allocated with malloc().
  56. if (p.second.data != nullptr)
  57. free(p.second.data);
  58. if (p.second.baseType == UNIFORM_SAMPLER || p.second.baseType == UNIFORM_STORAGETEXTURE)
  59. {
  60. for (int i = 0; i < p.second.count; i++)
  61. {
  62. if (p.second.textures[i] != nullptr)
  63. p.second.textures[i]->release();
  64. }
  65. delete[] p.second.textures;
  66. }
  67. else if (isBuffer(p.second.baseType))
  68. {
  69. for (int i = 0; i < p.second.count; i++)
  70. {
  71. if (p.second.buffers[i] != nullptr)
  72. p.second.buffers[i]->release();
  73. }
  74. delete[] p.second.buffers;
  75. }
  76. }
  77. }
  78. void Shader::mapActiveUniforms()
  79. {
  80. // Built-in uniform locations default to -1 (nonexistent.)
  81. for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
  82. {
  83. builtinUniforms[i] = -1;
  84. builtinUniformInfo[i] = nullptr;
  85. }
  86. GLint activeprogram = 0;
  87. glGetIntegerv(GL_CURRENT_PROGRAM, &activeprogram);
  88. gl.useProgram(program);
  89. GLint numuniforms;
  90. glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numuniforms);
  91. GLchar cname[256];
  92. const GLint bufsize = (GLint) (sizeof(cname) / sizeof(GLchar));
  93. std::map<std::string, UniformInfo> olduniforms = uniforms;
  94. uniforms.clear();
  95. for (int uindex = 0; uindex < numuniforms; uindex++)
  96. {
  97. GLsizei namelen = 0;
  98. GLenum gltype = 0;
  99. UniformInfo u = {};
  100. glGetActiveUniform(program, (GLuint) uindex, bufsize, &namelen, &u.count, &gltype, cname);
  101. u.name = std::string(cname, (size_t) namelen);
  102. u.location = glGetUniformLocation(program, u.name.c_str());
  103. u.access = ACCESS_READ;
  104. computeUniformTypeInfo(gltype, u);
  105. // glGetActiveUniform appends "[0]" to the end of array uniform names...
  106. if (u.name.length() > 3)
  107. {
  108. size_t findpos = u.name.find("[0]");
  109. if (findpos != std::string::npos && findpos == u.name.length() - 3)
  110. u.name.erase(u.name.length() - 3);
  111. }
  112. // If this is a built-in (LOVE-created) uniform, store the location.
  113. BuiltinUniform builtin = BUILTIN_MAX_ENUM;
  114. if (getConstant(u.name.c_str(), builtin))
  115. builtinUniforms[int(builtin)] = u.location;
  116. if (u.location == -1)
  117. continue;
  118. if (!fillUniformReflectionData(u))
  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, u.dataBaseType);
  134. }
  135. for (int i = 0; i < u.count; i++)
  136. textureUnits.push_back(unit);
  137. }
  138. else if (u.baseType == UNIFORM_STORAGETEXTURE)
  139. {
  140. StorageTextureBinding binding = {};
  141. binding.gltexture = gl.getDefaultTexture(u.textureType, u.dataBaseType);
  142. binding.type = u.textureType;
  143. if ((u.access & (ACCESS_READ | ACCESS_WRITE)) != 0)
  144. binding.access = GL_READ_WRITE;
  145. else if ((u.access & ACCESS_WRITE) != 0)
  146. binding.access = GL_WRITE_ONLY;
  147. else if ((u.access & ACCESS_READ) != 0)
  148. binding.access = GL_READ_ONLY;
  149. auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat, false);
  150. binding.internalFormat = fmt.internalformat;
  151. for (int i = 0; i < u.count; i++)
  152. storageTextureBindings.push_back(binding);
  153. }
  154. // Make sure previously set uniform data is preserved, and shader-
  155. // initialized values are retrieved.
  156. auto oldu = olduniforms.find(u.name);
  157. if (oldu != olduniforms.end())
  158. {
  159. u.data = oldu->second.data;
  160. u.dataSize = oldu->second.dataSize;
  161. u.textures = oldu->second.textures;
  162. updateUniform(&u, u.count, true);
  163. }
  164. else
  165. {
  166. u.dataSize = 0;
  167. switch (u.baseType)
  168. {
  169. case UNIFORM_FLOAT:
  170. u.dataSize = sizeof(float) * u.components * u.count;
  171. u.data = malloc(u.dataSize);
  172. break;
  173. case UNIFORM_INT:
  174. case UNIFORM_BOOL:
  175. case UNIFORM_SAMPLER:
  176. case UNIFORM_STORAGETEXTURE:
  177. case UNIFORM_TEXELBUFFER:
  178. u.dataSize = sizeof(int) * u.components * u.count;
  179. u.data = malloc(u.dataSize);
  180. break;
  181. case UNIFORM_UINT:
  182. u.dataSize = sizeof(unsigned int) * u.components * u.count;
  183. u.data = malloc(u.dataSize);
  184. break;
  185. case UNIFORM_MATRIX:
  186. u.dataSize = sizeof(float) * ((size_t)u.matrix.rows * u.matrix.columns) * u.count;
  187. u.data = malloc(u.dataSize);
  188. break;
  189. default:
  190. break;
  191. }
  192. if (u.dataSize > 0)
  193. {
  194. memset(u.data, 0, u.dataSize);
  195. if (u.baseType == UNIFORM_SAMPLER || u.baseType == UNIFORM_TEXELBUFFER)
  196. {
  197. int startunit = (int) textureUnits.size() - u.count;
  198. if (builtin == BUILTIN_TEXTURE_MAIN)
  199. startunit = 0;
  200. for (int i = 0; i < u.count; i++)
  201. u.ints[i] = startunit + i;
  202. glUniform1iv(u.location, u.count, u.ints);
  203. if (u.baseType == UNIFORM_TEXELBUFFER)
  204. {
  205. u.buffers = new love::graphics::Buffer*[u.count];
  206. memset(u.buffers, 0, sizeof(Buffer *) * u.count);
  207. }
  208. else
  209. {
  210. u.textures = new love::graphics::Texture*[u.count];
  211. memset(u.textures, 0, sizeof(Texture *) * u.count);
  212. }
  213. }
  214. else if (u.baseType == UNIFORM_STORAGETEXTURE)
  215. {
  216. int startbinding = (int) storageTextureBindings.size() - u.count;
  217. for (int i = 0; i < u.count; i++)
  218. u.ints[i] = startbinding + i;
  219. glUniform1iv(u.location, u.count, u.ints);
  220. u.textures = new love::graphics::Texture*[u.count];
  221. memset(u.textures, 0, sizeof(Texture *) * u.count);
  222. }
  223. }
  224. size_t offset = 0;
  225. // Store any shader-initialized values in our own memory.
  226. for (int i = 0; i < u.count; i++)
  227. {
  228. GLint location = u.location;
  229. if (u.count > 1)
  230. {
  231. std::ostringstream ss;
  232. ss << i;
  233. std::string indexname = u.name + "[" + ss.str() + "]";
  234. location = glGetUniformLocation(program, indexname.c_str());
  235. }
  236. if (location == -1)
  237. continue;
  238. switch (u.baseType)
  239. {
  240. case UNIFORM_FLOAT:
  241. glGetUniformfv(program, location, &u.floats[offset]);
  242. offset += u.components;
  243. break;
  244. case UNIFORM_INT:
  245. case UNIFORM_BOOL:
  246. glGetUniformiv(program, location, &u.ints[offset]);
  247. offset += u.components;
  248. break;
  249. case UNIFORM_UINT:
  250. glGetUniformuiv(program, location, &u.uints[offset]);
  251. offset += u.components;
  252. break;
  253. case UNIFORM_MATRIX:
  254. glGetUniformfv(program, location, &u.floats[offset]);
  255. offset += (size_t)u.matrix.rows * u.matrix.columns;
  256. break;
  257. default:
  258. break;
  259. }
  260. }
  261. }
  262. uniforms[u.name] = u;
  263. if (builtin != BUILTIN_MAX_ENUM)
  264. builtinUniformInfo[(int)builtin] = &uniforms[u.name];
  265. if (u.baseType == UNIFORM_SAMPLER || u.baseType == UNIFORM_STORAGETEXTURE)
  266. {
  267. // Make sure all stored textures have their Volatiles loaded before
  268. // the sendTextures call, since it calls getHandle().
  269. for (int i = 0; i < u.count; i++)
  270. {
  271. if (u.textures[i] == nullptr)
  272. continue;
  273. Volatile *v = dynamic_cast<Volatile *>(u.textures[i]);
  274. if (v != nullptr)
  275. v->loadVolatile();
  276. }
  277. sendTextures(&u, u.textures, u.count, true);
  278. }
  279. else if (u.baseType == UNIFORM_TEXELBUFFER)
  280. {
  281. for (int i = 0; i < u.count; i++)
  282. {
  283. if (u.buffers[i] == nullptr)
  284. continue;
  285. Volatile *v = dynamic_cast<Volatile *>(u.buffers[i]);
  286. if (v != nullptr)
  287. v->loadVolatile();
  288. }
  289. sendBuffers(&u, u.buffers, u.count, true);
  290. }
  291. }
  292. if (gl.isBufferUsageSupported(BUFFERUSAGE_SHADER_STORAGE))
  293. {
  294. GLint numstoragebuffers = 0;
  295. glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numstoragebuffers);
  296. char namebuffer[2048] = { '\0' };
  297. int nextstoragebufferbinding = 0;
  298. for (int sindex = 0; sindex < numstoragebuffers; sindex++)
  299. {
  300. UniformInfo u = {};
  301. u.baseType = UNIFORM_STORAGEBUFFER;
  302. u.access = ACCESS_READ;
  303. GLsizei namelength = 0;
  304. glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, sindex, 2048, &namelength, namebuffer);
  305. u.name = std::string(namebuffer, namelength);
  306. u.count = 1;
  307. if (!fillUniformReflectionData(u))
  308. continue;
  309. // Make sure previously set uniform data is preserved, and shader-
  310. // initialized values are retrieved.
  311. auto oldu = olduniforms.find(u.name);
  312. if (oldu != olduniforms.end())
  313. {
  314. u.data = oldu->second.data;
  315. u.dataSize = oldu->second.dataSize;
  316. u.buffers = oldu->second.buffers;
  317. }
  318. else
  319. {
  320. u.dataSize = sizeof(int) * 1;
  321. u.data = malloc(u.dataSize);
  322. u.ints[0] = -1;
  323. u.buffers = new love::graphics::Buffer * [u.count];
  324. memset(u.buffers, 0, sizeof(Buffer*)* u.count);
  325. }
  326. // Unlike local uniforms and attributes, OpenGL doesn't auto-assign storage
  327. // block bindings if they're unspecified in the shader. So we overwrite them
  328. // regardless, here.
  329. u.ints[0] = nextstoragebufferbinding++;
  330. glShaderStorageBlockBinding(program, sindex, u.ints[0]);
  331. BufferBinding binding;
  332. binding.bindingindex = u.ints[0];
  333. binding.buffer = gl.getDefaultStorageBuffer();
  334. if (binding.bindingindex >= 0)
  335. {
  336. int activeindex = (int)activeStorageBufferBindings.size();
  337. activeStorageBufferBindings.push_back(binding);
  338. auto p = std::make_pair(activeindex, -1);
  339. if (u.access & ACCESS_WRITE)
  340. {
  341. p.second = (int)activeWritableStorageBuffers.size();
  342. activeWritableStorageBuffers.push_back(u.buffers[0]);
  343. }
  344. storageBufferBindingIndexToActiveBinding[binding.bindingindex] = p;
  345. }
  346. uniforms[u.name] = u;
  347. for (int i = 0; i < u.count; i++)
  348. {
  349. if (u.buffers[i] == nullptr)
  350. continue;
  351. Volatile* v = dynamic_cast<Volatile*>(u.buffers[i]);
  352. if (v != nullptr)
  353. v->loadVolatile();
  354. }
  355. sendBuffers(&u, u.buffers, u.count, true);
  356. }
  357. }
  358. // Make sure uniforms that existed before but don't exist anymore are
  359. // cleaned up. This theoretically shouldn't happen, but...
  360. for (const auto &p : olduniforms)
  361. {
  362. if (uniforms.find(p.first) == uniforms.end())
  363. {
  364. if (p.second.data != nullptr)
  365. free(p.second.data);
  366. if (p.second.baseType == UNIFORM_SAMPLER || p.second.baseType == UNIFORM_STORAGETEXTURE)
  367. {
  368. for (int i = 0; i < p.second.count; i++)
  369. {
  370. if (p.second.textures[i] != nullptr)
  371. p.second.textures[i]->release();
  372. }
  373. delete[] p.second.textures;
  374. }
  375. else if (isBuffer(p.second.baseType))
  376. {
  377. for (int i = 0; i < p.second.count; i++)
  378. {
  379. if (p.second.buffers[i] != nullptr)
  380. p.second.buffers[i]->release();
  381. }
  382. delete[] p.second.buffers;
  383. }
  384. }
  385. }
  386. gl.useProgram(activeprogram);
  387. }
  388. bool Shader::loadVolatile()
  389. {
  390. OpenGL::TempDebugGroup debuggroup("Shader load");
  391. // love::graphics::Shader sets up the shader code-side of this.
  392. auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
  393. if (gfx != nullptr)
  394. splitUniformsPerDraw = !gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP];
  395. // zero out active texture list
  396. textureUnits.clear();
  397. textureUnits.push_back(TextureUnit());
  398. activeStorageBufferBindings.clear();
  399. storageBufferBindingIndexToActiveBinding.resize(gl.getMaxShaderStorageBufferBindings(), std::make_pair(-1, -1));
  400. activeStorageBufferBindings.clear();
  401. activeWritableStorageBuffers.clear();
  402. for (const auto &stage : stages)
  403. {
  404. if (stage.get() != nullptr)
  405. ((ShaderStage*)stage.get())->loadVolatile();
  406. }
  407. program = glCreateProgram();
  408. if (program == 0)
  409. throw love::Exception("Cannot create shader program object.");
  410. for (const auto &stage : stages)
  411. {
  412. if (stage.get() != nullptr)
  413. glAttachShader(program, (GLuint) stage->getHandle());
  414. }
  415. // Bind generic vertex attribute indices to names in the shader.
  416. for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
  417. {
  418. const char *name = nullptr;
  419. if (graphics::getConstant((BuiltinVertexAttribute) i, name))
  420. glBindAttribLocation(program, i, (const GLchar *) name);
  421. }
  422. glLinkProgram(program);
  423. GLint status;
  424. glGetProgramiv(program, GL_LINK_STATUS, &status);
  425. if (status == GL_FALSE)
  426. {
  427. std::string warnings = getProgramWarnings();
  428. glDeleteProgram(program);
  429. program = 0;
  430. throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
  431. }
  432. // Get all active uniform variables in this shader from OpenGL.
  433. mapActiveUniforms();
  434. if (current == this)
  435. {
  436. // make sure glUseProgram gets called.
  437. current = nullptr;
  438. attach();
  439. }
  440. return true;
  441. }
  442. void Shader::unloadVolatile()
  443. {
  444. if (program != 0)
  445. {
  446. if (current == this)
  447. gl.useProgram(0);
  448. glDeleteProgram(program);
  449. program = 0;
  450. }
  451. // active texture list is probably invalid, clear it
  452. textureUnits.clear();
  453. textureUnits.push_back(TextureUnit());
  454. attributes.clear();
  455. // And the locations of any built-in uniform variables.
  456. for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
  457. builtinUniforms[i] = -1;
  458. }
  459. std::string Shader::getProgramWarnings() const
  460. {
  461. GLint strsize, nullpos;
  462. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strsize);
  463. if (strsize == 0)
  464. return "";
  465. char *tempstr = new char[strsize];
  466. // be extra sure that the error string will be 0-terminated
  467. memset(tempstr, '\0', strsize);
  468. glGetProgramInfoLog(program, strsize, &nullpos, tempstr);
  469. tempstr[nullpos] = '\0';
  470. std::string warnings(tempstr);
  471. delete[] tempstr;
  472. return warnings;
  473. }
  474. std::string Shader::getWarnings() const
  475. {
  476. std::string warnings;
  477. const char *stagestr;
  478. for (const auto &stage : stages)
  479. {
  480. if (stage.get() == nullptr)
  481. continue;
  482. const std::string &stagewarnings = stage->getWarnings();
  483. if (ShaderStage::getConstant(stage->getStageType(), stagestr))
  484. warnings += std::string(stagestr) + std::string(" shader:\n") + stagewarnings;
  485. }
  486. warnings += getProgramWarnings();
  487. return warnings;
  488. }
  489. void Shader::attach()
  490. {
  491. if (current != this)
  492. {
  493. Graphics::flushBatchedDrawsGlobal();
  494. gl.useProgram(program);
  495. current = this;
  496. // retain/release happens in Graphics::setShader.
  497. // Make sure all textures are bound to their respective texture units.
  498. for (int i = 0; i < (int) textureUnits.size(); i++)
  499. {
  500. const TextureUnit &unit = textureUnits[i];
  501. if (unit.active)
  502. {
  503. if (unit.isTexelBuffer)
  504. gl.bindBufferTextureToUnit(unit.texture, i, false, false);
  505. else
  506. gl.bindTextureToUnit(unit.type, unit.texture, i, false, false);
  507. }
  508. }
  509. for (size_t i = 0; i < storageTextureBindings.size(); i++)
  510. {
  511. const auto &binding = storageTextureBindings[i];
  512. glBindImageTexture((GLuint) i, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat);
  513. }
  514. for (auto bufferbinding : activeStorageBufferBindings)
  515. gl.bindIndexedBuffer(bufferbinding.buffer, BUFFERUSAGE_SHADER_STORAGE, bufferbinding.bindingindex);
  516. // send any pending uniforms to the shader program.
  517. for (const auto &p : pendingUniformUpdates)
  518. updateUniform(p.first, p.second, true);
  519. pendingUniformUpdates.clear();
  520. }
  521. }
  522. const Shader::UniformInfo *Shader::getUniformInfo(const std::string &name) const
  523. {
  524. const auto it = uniforms.find(name);
  525. if (it == uniforms.end())
  526. return nullptr;
  527. return &(it->second);
  528. }
  529. const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
  530. {
  531. return builtinUniformInfo[(int)builtin];
  532. }
  533. void Shader::updateUniform(const UniformInfo *info, int count)
  534. {
  535. updateUniform(info, count, false);
  536. }
  537. void Shader::updateUniform(const UniformInfo *info, int count, bool internalupdate)
  538. {
  539. if (current != this && !internalupdate)
  540. {
  541. pendingUniformUpdates.push_back(std::make_pair(info, count));
  542. return;
  543. }
  544. if (!internalupdate)
  545. flushBatchedDraws();
  546. int location = info->location;
  547. UniformType type = info->baseType;
  548. if (type == UNIFORM_FLOAT)
  549. {
  550. switch (info->components)
  551. {
  552. case 1:
  553. glUniform1fv(location, count, info->floats);
  554. break;
  555. case 2:
  556. glUniform2fv(location, count, info->floats);
  557. break;
  558. case 3:
  559. glUniform3fv(location, count, info->floats);
  560. break;
  561. case 4:
  562. glUniform4fv(location, count, info->floats);
  563. break;
  564. }
  565. }
  566. else if (type == UNIFORM_INT || type == UNIFORM_BOOL || type == UNIFORM_SAMPLER || type == UNIFORM_STORAGETEXTURE || type == UNIFORM_TEXELBUFFER)
  567. {
  568. switch (info->components)
  569. {
  570. case 1:
  571. glUniform1iv(location, count, info->ints);
  572. break;
  573. case 2:
  574. glUniform2iv(location, count, info->ints);
  575. break;
  576. case 3:
  577. glUniform3iv(location, count, info->ints);
  578. break;
  579. case 4:
  580. glUniform4iv(location, count, info->ints);
  581. break;
  582. }
  583. }
  584. else if (type == UNIFORM_UINT)
  585. {
  586. switch (info->components)
  587. {
  588. case 1:
  589. glUniform1uiv(location, count, info->uints);
  590. break;
  591. case 2:
  592. glUniform2uiv(location, count, info->uints);
  593. break;
  594. case 3:
  595. glUniform3uiv(location, count, info->uints);
  596. break;
  597. case 4:
  598. glUniform4uiv(location, count, info->uints);
  599. break;
  600. }
  601. }
  602. else if (type == UNIFORM_MATRIX)
  603. {
  604. int columns = info->matrix.columns;
  605. int rows = info->matrix.rows;
  606. if (columns == 2 && rows == 2)
  607. glUniformMatrix2fv(location, count, GL_FALSE, info->floats);
  608. else if (columns == 3 && rows == 3)
  609. glUniformMatrix3fv(location, count, GL_FALSE, info->floats);
  610. else if (columns == 4 && rows == 4)
  611. glUniformMatrix4fv(location, count, GL_FALSE, info->floats);
  612. else if (columns == 2 && rows == 3)
  613. glUniformMatrix2x3fv(location, count, GL_FALSE, info->floats);
  614. else if (columns == 2 && rows == 4)
  615. glUniformMatrix2x4fv(location, count, GL_FALSE, info->floats);
  616. else if (columns == 3 && rows == 2)
  617. glUniformMatrix3x2fv(location, count, GL_FALSE, info->floats);
  618. else if (columns == 3 && rows == 4)
  619. glUniformMatrix3x4fv(location, count, GL_FALSE, info->floats);
  620. else if (columns == 4 && rows == 2)
  621. glUniformMatrix4x2fv(location, count, GL_FALSE, info->floats);
  622. else if (columns == 4 && rows == 3)
  623. glUniformMatrix4x3fv(location, count, GL_FALSE, info->floats);
  624. }
  625. }
  626. void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
  627. {
  628. Shader::sendTextures(info, textures, count, false);
  629. }
  630. void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count, bool internalUpdate)
  631. {
  632. bool issampler = info->baseType == UNIFORM_SAMPLER;
  633. bool isstoragetex = info->baseType == UNIFORM_STORAGETEXTURE;
  634. if (!issampler && !isstoragetex)
  635. return;
  636. bool shaderactive = current == this;
  637. if (!internalUpdate && shaderactive)
  638. flushBatchedDraws();
  639. count = std::min(count, info->count);
  640. // Bind the textures to the texture units.
  641. for (int i = 0; i < count; i++)
  642. {
  643. love::graphics::Texture *tex = textures[i];
  644. if (tex != nullptr)
  645. {
  646. if (!validateTexture(info, tex, internalUpdate))
  647. continue;
  648. tex->retain();
  649. }
  650. if (info->textures[i] != nullptr)
  651. info->textures[i]->release();
  652. info->textures[i] = tex;
  653. if (isstoragetex)
  654. {
  655. GLuint gltex = 0;
  656. if (tex != nullptr)
  657. gltex = (GLuint) tex->getHandle();
  658. else
  659. gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
  660. int bindingindex = info->ints[i];
  661. auto &binding = storageTextureBindings[bindingindex];
  662. binding.texture = tex;
  663. binding.gltexture = gltex;
  664. if (shaderactive)
  665. glBindImageTexture(bindingindex, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat);
  666. }
  667. else
  668. {
  669. GLuint gltex = 0;
  670. if (textures[i] != nullptr)
  671. gltex = (GLuint) tex->getHandle();
  672. else
  673. gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
  674. int texunit = info->ints[i];
  675. if (shaderactive)
  676. gl.bindTextureToUnit(info->textureType, gltex, texunit, false, false);
  677. // Store texture id so it can be re-bound to the texture unit later.
  678. textureUnits[texunit].texture = gltex;
  679. }
  680. }
  681. }
  682. void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
  683. {
  684. Shader::sendBuffers(info, buffers, count, false);
  685. }
  686. void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
  687. {
  688. bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
  689. bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
  690. if (!texelbinding && !storagebinding)
  691. return;
  692. bool shaderactive = current == this;
  693. if (!internalUpdate && shaderactive)
  694. flushBatchedDraws();
  695. count = std::min(count, info->count);
  696. // Bind the textures to the texture units.
  697. for (int i = 0; i < count; i++)
  698. {
  699. love::graphics::Buffer *buffer = buffers[i];
  700. if (buffer != nullptr)
  701. {
  702. if (!validateBuffer(info, buffer, internalUpdate))
  703. continue;
  704. buffer->retain();
  705. }
  706. if (info->buffers[i] != nullptr)
  707. info->buffers[i]->release();
  708. info->buffers[i] = buffer;
  709. if (texelbinding)
  710. {
  711. GLuint gltex = 0;
  712. if (buffer != nullptr)
  713. gltex = (GLuint) buffer->getTexelBufferHandle();
  714. else
  715. gltex = gl.getDefaultTexelBuffer();
  716. int texunit = info->ints[i];
  717. if (shaderactive)
  718. gl.bindBufferTextureToUnit(gltex, texunit, false, false);
  719. // Store texture id so it can be re-bound to the texture unit later.
  720. textureUnits[texunit].texture = gltex;
  721. }
  722. else if (storagebinding)
  723. {
  724. int bindingindex = info->ints[i];
  725. GLuint glbuffer = 0;
  726. if (buffer != nullptr)
  727. glbuffer = (GLuint) buffer->getHandle();
  728. else
  729. glbuffer = gl.getDefaultStorageBuffer();
  730. if (shaderactive)
  731. gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex);
  732. auto activeindex = storageBufferBindingIndexToActiveBinding[bindingindex];
  733. if (activeindex.first >= 0)
  734. activeStorageBufferBindings[activeindex.first].buffer = glbuffer;
  735. if (activeindex.second >= 0)
  736. activeWritableStorageBuffers[activeindex.second] = buffer;
  737. }
  738. }
  739. }
  740. void Shader::flushBatchedDraws() const
  741. {
  742. if (current == this)
  743. Graphics::flushBatchedDrawsGlobal();
  744. }
  745. bool Shader::hasUniform(const std::string &name) const
  746. {
  747. return uniforms.find(name) != uniforms.end();
  748. }
  749. ptrdiff_t Shader::getHandle() const
  750. {
  751. return program;
  752. }
  753. int Shader::getVertexAttributeIndex(const std::string &name)
  754. {
  755. auto it = attributes.find(name);
  756. if (it != attributes.end())
  757. return it->second;
  758. GLint location = glGetAttribLocation(program, name.c_str());
  759. attributes[name] = location;
  760. return location;
  761. }
  762. void Shader::setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture)
  763. {
  764. const BuiltinUniform builtins[3] = {
  765. BUILTIN_TEXTURE_VIDEO_Y,
  766. BUILTIN_TEXTURE_VIDEO_CB,
  767. BUILTIN_TEXTURE_VIDEO_CR,
  768. };
  769. love::graphics::Texture *textures[3] = {ytexture, cbtexture, crtexture};
  770. for (int i = 0; i < 3; i++)
  771. {
  772. const UniformInfo *info = builtinUniformInfo[builtins[i]];
  773. if (info != nullptr)
  774. sendTextures(info, &textures[i], 1, true);
  775. }
  776. }
  777. void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW, int viewportH)
  778. {
  779. if (current != this)
  780. return;
  781. BuiltinUniformData data;
  782. data.transformMatrix = gfx->getTransform();
  783. data.projectionMatrix = gfx->getDeviceProjection();
  784. // The normal matrix is the transpose of the inverse of the rotation portion
  785. // (top-left 3x3) of the transform matrix.
  786. {
  787. Matrix3 normalmatrix = Matrix3(data.transformMatrix).transposedInverse();
  788. const float *e = normalmatrix.getElements();
  789. for (int i = 0; i < 3; i++)
  790. {
  791. data.normalMatrix[i].x = e[i * 3 + 0];
  792. data.normalMatrix[i].y = e[i * 3 + 1];
  793. data.normalMatrix[i].z = e[i * 3 + 2];
  794. data.normalMatrix[i].w = 0.0f;
  795. }
  796. }
  797. // Store DPI scale in an unused component of another vector.
  798. data.normalMatrix[0].w = (float) gfx->getCurrentDPIScale();
  799. // Same with point size.
  800. data.normalMatrix[1].w = gfx->getPointSize();
  801. data.screenSizeParams.x = viewportW;
  802. data.screenSizeParams.y = viewportH;
  803. // The shader does pixcoord.y = gl_FragCoord.y * params.z + params.w.
  804. // This lets us flip pixcoord.y when needed, to be consistent (drawing
  805. // with no RT active makes the pixel coordinates y-flipped.)
  806. if (gfx->isRenderTargetActive())
  807. {
  808. // No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0.
  809. data.screenSizeParams.z = 1.0f;
  810. data.screenSizeParams.w = 0.0f;
  811. }
  812. else
  813. {
  814. // gl_FragCoord.y is flipped when drawing to the screen, so we
  815. // un-flip: pixcoord.y = gl_FragCoord.y * -1.0 + height.
  816. data.screenSizeParams.z = -1.0f;
  817. data.screenSizeParams.w = viewportH;
  818. }
  819. data.constantColor = gfx->getColor();
  820. gammaCorrectColor(data.constantColor);
  821. // This branch is to avoid always declaring the whole array as highp in the
  822. // vertex shader and mediump in the pixel shader for love's default shaders,
  823. // on systems that don't support highp in pixel shaders. The default shaders
  824. // use the transform matrices in vertex shaders and screen size params in
  825. // pixel shaders. If there's a single array containing both and each shader
  826. // stage declares a different precision, that's a compile error.
  827. if (splitUniformsPerDraw)
  828. {
  829. GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
  830. if (location >= 0)
  831. glUniform4fv(location, 12, (const GLfloat *) &data);
  832. GLint location2 = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW_2];
  833. if (location2 >= 0)
  834. glUniform4fv(location2, 1, (const GLfloat *) &data.screenSizeParams);
  835. }
  836. else
  837. {
  838. GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
  839. if (location >= 0)
  840. glUniform4fv(location, 13, (const GLfloat *) &data);
  841. }
  842. }
  843. int Shader::getUniformTypeComponents(GLenum type) const
  844. {
  845. switch (type)
  846. {
  847. case GL_INT:
  848. case GL_UNSIGNED_INT:
  849. case GL_FLOAT:
  850. case GL_BOOL:
  851. return 1;
  852. case GL_INT_VEC2:
  853. case GL_UNSIGNED_INT_VEC2:
  854. case GL_FLOAT_VEC2:
  855. case GL_FLOAT_MAT2:
  856. case GL_BOOL_VEC2:
  857. return 2;
  858. case GL_INT_VEC3:
  859. case GL_UNSIGNED_INT_VEC3:
  860. case GL_FLOAT_VEC3:
  861. case GL_FLOAT_MAT3:
  862. case GL_BOOL_VEC3:
  863. return 3;
  864. case GL_INT_VEC4:
  865. case GL_UNSIGNED_INT_VEC4:
  866. case GL_FLOAT_VEC4:
  867. case GL_FLOAT_MAT4:
  868. case GL_BOOL_VEC4:
  869. return 4;
  870. default:
  871. return 1;
  872. }
  873. }
  874. Shader::MatrixSize Shader::getMatrixSize(GLenum type) const
  875. {
  876. MatrixSize m;
  877. switch (type)
  878. {
  879. case GL_FLOAT_MAT2:
  880. m.columns = m.rows = 2;
  881. break;
  882. case GL_FLOAT_MAT3:
  883. m.columns = m.rows = 3;
  884. break;
  885. case GL_FLOAT_MAT4:
  886. m.columns = m.rows = 4;
  887. break;
  888. case GL_FLOAT_MAT2x3:
  889. m.columns = 2;
  890. m.rows = 3;
  891. break;
  892. case GL_FLOAT_MAT2x4:
  893. m.columns = 2;
  894. m.rows = 4;
  895. break;
  896. case GL_FLOAT_MAT3x2:
  897. m.columns = 3;
  898. m.rows = 2;
  899. break;
  900. case GL_FLOAT_MAT3x4:
  901. m.columns = 3;
  902. m.rows = 4;
  903. break;
  904. case GL_FLOAT_MAT4x2:
  905. m.columns = 4;
  906. m.rows = 2;
  907. break;
  908. case GL_FLOAT_MAT4x3:
  909. m.columns = 4;
  910. m.rows = 3;
  911. break;
  912. default:
  913. m.columns = m.rows = 0;
  914. break;
  915. }
  916. return m;
  917. }
  918. void Shader::computeUniformTypeInfo(GLenum type, UniformInfo &u)
  919. {
  920. u.isDepthSampler = false;
  921. u.components = getUniformTypeComponents(type);
  922. u.baseType = UNIFORM_UNKNOWN;
  923. switch (type)
  924. {
  925. case GL_INT:
  926. case GL_INT_VEC2:
  927. case GL_INT_VEC3:
  928. case GL_INT_VEC4:
  929. u.baseType = UNIFORM_INT;
  930. u.dataBaseType = DATA_BASETYPE_INT;
  931. break;
  932. case GL_UNSIGNED_INT:
  933. case GL_UNSIGNED_INT_VEC2:
  934. case GL_UNSIGNED_INT_VEC3:
  935. case GL_UNSIGNED_INT_VEC4:
  936. u.baseType = UNIFORM_UINT;
  937. u.dataBaseType = DATA_BASETYPE_UINT;
  938. break;
  939. case GL_FLOAT:
  940. case GL_FLOAT_VEC2:
  941. case GL_FLOAT_VEC3:
  942. case GL_FLOAT_VEC4:
  943. u.baseType = UNIFORM_FLOAT;
  944. u.dataBaseType = DATA_BASETYPE_FLOAT;
  945. break;
  946. case GL_FLOAT_MAT2:
  947. case GL_FLOAT_MAT3:
  948. case GL_FLOAT_MAT4:
  949. case GL_FLOAT_MAT2x3:
  950. case GL_FLOAT_MAT2x4:
  951. case GL_FLOAT_MAT3x2:
  952. case GL_FLOAT_MAT3x4:
  953. case GL_FLOAT_MAT4x2:
  954. case GL_FLOAT_MAT4x3:
  955. u.baseType = UNIFORM_MATRIX;
  956. u.dataBaseType = DATA_BASETYPE_FLOAT;
  957. u.matrix = getMatrixSize(type);
  958. break;
  959. case GL_BOOL:
  960. case GL_BOOL_VEC2:
  961. case GL_BOOL_VEC3:
  962. case GL_BOOL_VEC4:
  963. u.baseType = UNIFORM_BOOL;
  964. u.dataBaseType = DATA_BASETYPE_BOOL;
  965. break;
  966. case GL_SAMPLER_2D:
  967. u.baseType = UNIFORM_SAMPLER;
  968. u.dataBaseType = DATA_BASETYPE_FLOAT;
  969. u.textureType = TEXTURE_2D;
  970. break;
  971. case GL_SAMPLER_2D_SHADOW:
  972. u.baseType = UNIFORM_SAMPLER;
  973. u.dataBaseType = DATA_BASETYPE_FLOAT;
  974. u.textureType = TEXTURE_2D;
  975. u.isDepthSampler = true;
  976. break;
  977. case GL_INT_SAMPLER_2D:
  978. u.baseType = UNIFORM_SAMPLER;
  979. u.dataBaseType = DATA_BASETYPE_INT;
  980. u.textureType = TEXTURE_2D;
  981. break;
  982. case GL_UNSIGNED_INT_SAMPLER_2D:
  983. u.baseType = UNIFORM_SAMPLER;
  984. u.dataBaseType = DATA_BASETYPE_UINT;
  985. u.textureType = TEXTURE_2D;
  986. break;
  987. case GL_SAMPLER_2D_ARRAY:
  988. u.baseType = UNIFORM_SAMPLER;
  989. u.dataBaseType = DATA_BASETYPE_FLOAT;
  990. u.textureType = TEXTURE_2D_ARRAY;
  991. break;
  992. case GL_SAMPLER_2D_ARRAY_SHADOW:
  993. u.baseType = UNIFORM_SAMPLER;
  994. u.dataBaseType = DATA_BASETYPE_FLOAT;
  995. u.textureType = TEXTURE_2D_ARRAY;
  996. u.isDepthSampler = true;
  997. break;
  998. case GL_INT_SAMPLER_2D_ARRAY:
  999. u.baseType = UNIFORM_SAMPLER;
  1000. u.dataBaseType = DATA_BASETYPE_INT;
  1001. u.textureType = TEXTURE_2D_ARRAY;
  1002. break;
  1003. case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
  1004. u.baseType = UNIFORM_SAMPLER;
  1005. u.dataBaseType = DATA_BASETYPE_UINT;
  1006. u.textureType = TEXTURE_2D_ARRAY;
  1007. break;
  1008. case GL_SAMPLER_3D:
  1009. u.baseType = UNIFORM_SAMPLER;
  1010. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1011. u.textureType = TEXTURE_VOLUME;
  1012. break;
  1013. case GL_INT_SAMPLER_3D:
  1014. u.baseType = UNIFORM_SAMPLER;
  1015. u.dataBaseType = DATA_BASETYPE_INT;
  1016. u.textureType = TEXTURE_VOLUME;
  1017. break;
  1018. case GL_UNSIGNED_INT_SAMPLER_3D:
  1019. u.baseType = UNIFORM_SAMPLER;
  1020. u.dataBaseType = DATA_BASETYPE_UINT;
  1021. u.textureType = TEXTURE_VOLUME;
  1022. break;
  1023. case GL_SAMPLER_CUBE:
  1024. u.baseType = UNIFORM_SAMPLER;
  1025. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1026. u.textureType = TEXTURE_CUBE;
  1027. break;
  1028. case GL_SAMPLER_CUBE_SHADOW:
  1029. u.baseType = UNIFORM_SAMPLER;
  1030. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1031. u.textureType = TEXTURE_CUBE;
  1032. u.isDepthSampler = true;
  1033. break;
  1034. case GL_INT_SAMPLER_CUBE:
  1035. u.baseType = UNIFORM_SAMPLER;
  1036. u.dataBaseType = DATA_BASETYPE_INT;
  1037. u.textureType = TEXTURE_CUBE;
  1038. break;
  1039. case GL_UNSIGNED_INT_SAMPLER_CUBE:
  1040. u.baseType = UNIFORM_SAMPLER;
  1041. u.dataBaseType = DATA_BASETYPE_UINT;
  1042. u.textureType = TEXTURE_CUBE;
  1043. break;
  1044. case GL_SAMPLER_BUFFER:
  1045. u.baseType = UNIFORM_TEXELBUFFER;
  1046. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1047. break;
  1048. case GL_INT_SAMPLER_BUFFER:
  1049. u.baseType = UNIFORM_TEXELBUFFER;
  1050. u.dataBaseType = DATA_BASETYPE_INT;
  1051. break;
  1052. case GL_UNSIGNED_INT_SAMPLER_BUFFER:
  1053. u.baseType = UNIFORM_TEXELBUFFER;
  1054. u.dataBaseType = DATA_BASETYPE_UINT;
  1055. break;
  1056. case GL_IMAGE_2D:
  1057. u.baseType = UNIFORM_STORAGETEXTURE;
  1058. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1059. u.textureType = TEXTURE_2D;
  1060. break;
  1061. case GL_INT_IMAGE_2D:
  1062. u.baseType = UNIFORM_STORAGETEXTURE;
  1063. u.dataBaseType = DATA_BASETYPE_INT;
  1064. u.textureType = TEXTURE_2D;
  1065. break;
  1066. case GL_UNSIGNED_INT_IMAGE_2D:
  1067. u.baseType = UNIFORM_STORAGETEXTURE;
  1068. u.dataBaseType = DATA_BASETYPE_UINT;
  1069. u.textureType = TEXTURE_2D;
  1070. break;
  1071. case GL_IMAGE_2D_ARRAY:
  1072. u.baseType = UNIFORM_STORAGETEXTURE;
  1073. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1074. u.textureType = TEXTURE_2D_ARRAY;
  1075. break;
  1076. case GL_INT_IMAGE_2D_ARRAY:
  1077. u.baseType = UNIFORM_STORAGETEXTURE;
  1078. u.dataBaseType = DATA_BASETYPE_INT;
  1079. u.textureType = TEXTURE_2D_ARRAY;
  1080. break;
  1081. case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
  1082. u.baseType = UNIFORM_STORAGETEXTURE;
  1083. u.dataBaseType = DATA_BASETYPE_UINT;
  1084. u.textureType = TEXTURE_2D_ARRAY;
  1085. break;
  1086. case GL_IMAGE_3D:
  1087. u.baseType = UNIFORM_STORAGETEXTURE;
  1088. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1089. u.textureType = TEXTURE_VOLUME;
  1090. break;
  1091. case GL_INT_IMAGE_3D:
  1092. u.baseType = UNIFORM_STORAGETEXTURE;
  1093. u.dataBaseType = DATA_BASETYPE_INT;
  1094. u.textureType = TEXTURE_VOLUME;
  1095. break;
  1096. case GL_UNSIGNED_INT_IMAGE_3D:
  1097. u.baseType = UNIFORM_STORAGETEXTURE;
  1098. u.dataBaseType = DATA_BASETYPE_UINT;
  1099. u.textureType = TEXTURE_VOLUME;
  1100. break;
  1101. case GL_IMAGE_CUBE:
  1102. u.baseType = UNIFORM_STORAGETEXTURE;
  1103. u.dataBaseType = DATA_BASETYPE_FLOAT;
  1104. u.textureType = TEXTURE_CUBE;
  1105. break;
  1106. case GL_INT_IMAGE_CUBE:
  1107. u.baseType = UNIFORM_STORAGETEXTURE;
  1108. u.dataBaseType = DATA_BASETYPE_INT;
  1109. u.textureType = TEXTURE_CUBE;
  1110. break;
  1111. case GL_UNSIGNED_INT_IMAGE_CUBE:
  1112. u.baseType = UNIFORM_STORAGETEXTURE;
  1113. u.dataBaseType = DATA_BASETYPE_UINT;
  1114. u.textureType = TEXTURE_CUBE;
  1115. break;
  1116. default:
  1117. break;
  1118. }
  1119. }
  1120. } // opengl
  1121. } // graphics
  1122. } // love