Shader.cpp 37 KB

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