shader_gles3.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /*************************************************************************/
  2. /* shader_gles3.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "shader_gles3.h"
  31. #ifdef GLES3_ENABLED
  32. #include "core/io/compression.h"
  33. #include "core/io/dir_access.h"
  34. #include "core/io/file_access.h"
  35. void ShaderGLES3::_add_stage(const char *p_code, StageType p_stage_type) {
  36. Vector<String> lines = String(p_code).split("\n");
  37. String text;
  38. for (int i = 0; i < lines.size(); i++) {
  39. String l = lines[i];
  40. bool push_chunk = false;
  41. StageTemplate::Chunk chunk;
  42. if (l.begins_with("#GLOBALS")) {
  43. switch (p_stage_type) {
  44. case STAGE_TYPE_VERTEX:
  45. chunk.type = StageTemplate::Chunk::TYPE_VERTEX_GLOBALS;
  46. break;
  47. case STAGE_TYPE_FRAGMENT:
  48. chunk.type = StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS;
  49. break;
  50. default: {
  51. }
  52. }
  53. push_chunk = true;
  54. } else if (l.begins_with("#MATERIAL_UNIFORMS")) {
  55. chunk.type = StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS;
  56. push_chunk = true;
  57. } else if (l.begins_with("#CODE")) {
  58. chunk.type = StageTemplate::Chunk::TYPE_CODE;
  59. push_chunk = true;
  60. chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper();
  61. } else {
  62. text += l + "\n";
  63. }
  64. if (push_chunk) {
  65. if (text != String()) {
  66. StageTemplate::Chunk text_chunk;
  67. text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
  68. text_chunk.text = text.utf8();
  69. stage_templates[p_stage_type].chunks.push_back(text_chunk);
  70. text = String();
  71. }
  72. stage_templates[p_stage_type].chunks.push_back(chunk);
  73. }
  74. if (text != String()) {
  75. StageTemplate::Chunk text_chunk;
  76. text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
  77. text_chunk.text = text.utf8();
  78. stage_templates[p_stage_type].chunks.push_back(text_chunk);
  79. text = String();
  80. }
  81. }
  82. }
  83. void ShaderGLES3::_setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants) {
  84. name = p_name;
  85. if (p_vertex_code) {
  86. _add_stage(p_vertex_code, STAGE_TYPE_VERTEX);
  87. }
  88. if (p_fragment_code) {
  89. _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT);
  90. }
  91. uniform_names = p_uniform_names;
  92. uniform_count = p_uniform_count;
  93. ubo_pairs = p_ubos;
  94. ubo_count = p_ubo_count;
  95. texunit_pairs = p_tex_units;
  96. texunit_pair_count = p_texture_count;
  97. specializations = p_specializations;
  98. specialization_count = p_specialization_count;
  99. specialization_default_mask = 0;
  100. for (int i = 0; i < specialization_count; i++) {
  101. if (specializations[i].default_value) {
  102. specialization_default_mask |= (uint64_t(1) << uint64_t(i));
  103. }
  104. }
  105. variant_defines = p_variants;
  106. variant_count = p_variant_count;
  107. StringBuilder tohash;
  108. /*
  109. tohash.append("[SpirvCacheKey]");
  110. tohash.append(RenderingDevice::get_singleton()->shader_get_spirv_cache_key());
  111. tohash.append("[BinaryCacheKey]");
  112. tohash.append(RenderingDevice::get_singleton()->shader_get_binary_cache_key());
  113. */
  114. tohash.append("[Vertex]");
  115. tohash.append(p_vertex_code ? p_vertex_code : "");
  116. tohash.append("[Fragment]");
  117. tohash.append(p_fragment_code ? p_fragment_code : "");
  118. base_sha256 = tohash.as_string().sha256_text();
  119. }
  120. RID ShaderGLES3::version_create() {
  121. //initialize() was never called
  122. ERR_FAIL_COND_V(variant_count == 0, RID());
  123. Version version;
  124. return version_owner.make_rid(version);
  125. }
  126. void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization) {
  127. #ifdef GLES_OVER_GL
  128. builder.append("#version 330\n");
  129. builder.append("#define USE_GLES_OVER_GL\n");
  130. #else
  131. builder.append("#version 300 es\n");
  132. #endif
  133. for (int i = 0; i < specialization_count; i++) {
  134. if (p_specialization & (uint64_t(1) << uint64_t(i))) {
  135. builder.append("#define " + String(specializations[i].name) + "\n");
  136. }
  137. }
  138. if (p_version->uniforms.size()) {
  139. builder.append("#define MATERIAL_UNIFORMS_USED\n");
  140. }
  141. for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
  142. builder.append(String("#define ") + String(E.key) + "_CODE_USED\n");
  143. }
  144. builder.append("\n"); //make sure defines begin at newline
  145. builder.append(general_defines.get_data());
  146. builder.append(variant_defines[p_variant]);
  147. for (int j = 0; j < p_version->custom_defines.size(); j++) {
  148. builder.append(p_version->custom_defines[j].get_data());
  149. }
  150. builder.append("\n"); //make sure defines begin at newline
  151. for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
  152. const StageTemplate::Chunk &chunk = p_template.chunks[i];
  153. switch (chunk.type) {
  154. case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: {
  155. builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)
  156. } break;
  157. case StageTemplate::Chunk::TYPE_VERTEX_GLOBALS: {
  158. builder.append(p_version->vertex_globals.get_data()); // vertex globals
  159. } break;
  160. case StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS: {
  161. builder.append(p_version->fragment_globals.get_data()); // fragment globals
  162. } break;
  163. case StageTemplate::Chunk::TYPE_CODE: {
  164. if (p_version->code_sections.has(chunk.code)) {
  165. builder.append(p_version->code_sections[chunk.code].get_data());
  166. }
  167. } break;
  168. case StageTemplate::Chunk::TYPE_TEXT: {
  169. builder.append(chunk.text.get_data());
  170. } break;
  171. }
  172. }
  173. }
  174. static void _display_error_with_code(const String &p_error, const String &p_code) {
  175. int line = 1;
  176. Vector<String> lines = p_code.split("\n");
  177. for (int j = 0; j < lines.size(); j++) {
  178. print_line(itos(line) + ": " + lines[j]);
  179. line++;
  180. }
  181. ERR_PRINT(p_error);
  182. }
  183. void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization) {
  184. spec.id = glCreateProgram();
  185. spec.ok = false;
  186. GLint status;
  187. //vertex stage
  188. {
  189. StringBuilder builder;
  190. _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX], p_specialization);
  191. spec.vert_id = glCreateShader(GL_VERTEX_SHADER);
  192. String builder_string = builder.as_string();
  193. CharString cs = builder_string.utf8();
  194. const char *cstr = cs.ptr();
  195. glShaderSource(spec.vert_id, 1, &cstr, nullptr);
  196. glCompileShader(spec.vert_id);
  197. glGetShaderiv(spec.vert_id, GL_COMPILE_STATUS, &status);
  198. if (status == GL_FALSE) {
  199. GLsizei iloglen;
  200. glGetShaderiv(spec.vert_id, GL_INFO_LOG_LENGTH, &iloglen);
  201. if (iloglen < 0) {
  202. glDeleteShader(spec.vert_id);
  203. glDeleteProgram(spec.id);
  204. spec.id = 0;
  205. ERR_PRINT("No OpenGL vertex shader compiler log.");
  206. } else {
  207. if (iloglen == 0) {
  208. iloglen = 4096; // buggy driver (Adreno 220+)
  209. }
  210. char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
  211. ilogmem[iloglen] = '\0';
  212. glGetShaderInfoLog(spec.vert_id, iloglen, &iloglen, ilogmem);
  213. String err_string = name + ": Vertex shader compilation failed:\n";
  214. err_string += ilogmem;
  215. _display_error_with_code(err_string, builder_string);
  216. Memory::free_static(ilogmem);
  217. glDeleteShader(spec.vert_id);
  218. glDeleteProgram(spec.id);
  219. spec.id = 0;
  220. }
  221. ERR_FAIL();
  222. }
  223. }
  224. //fragment stage
  225. {
  226. StringBuilder builder;
  227. _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT], p_specialization);
  228. spec.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
  229. String builder_string = builder.as_string();
  230. CharString cs = builder_string.utf8();
  231. const char *cstr = cs.ptr();
  232. glShaderSource(spec.frag_id, 1, &cstr, nullptr);
  233. glCompileShader(spec.frag_id);
  234. glGetShaderiv(spec.frag_id, GL_COMPILE_STATUS, &status);
  235. if (status == GL_FALSE) {
  236. GLsizei iloglen;
  237. glGetShaderiv(spec.frag_id, GL_INFO_LOG_LENGTH, &iloglen);
  238. if (iloglen < 0) {
  239. glDeleteShader(spec.frag_id);
  240. glDeleteProgram(spec.id);
  241. spec.id = 0;
  242. ERR_PRINT("No OpenGL fragment shader compiler log.");
  243. } else {
  244. if (iloglen == 0) {
  245. iloglen = 4096; // buggy driver (Adreno 220+)
  246. }
  247. char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
  248. ilogmem[iloglen] = '\0';
  249. glGetShaderInfoLog(spec.frag_id, iloglen, &iloglen, ilogmem);
  250. String err_string = name + ": Fragment shader compilation failed:\n";
  251. err_string += ilogmem;
  252. _display_error_with_code(err_string, builder_string);
  253. Memory::free_static(ilogmem);
  254. glDeleteShader(spec.frag_id);
  255. glDeleteProgram(spec.id);
  256. spec.id = 0;
  257. }
  258. ERR_FAIL();
  259. }
  260. }
  261. glAttachShader(spec.id, spec.frag_id);
  262. glAttachShader(spec.id, spec.vert_id);
  263. //for (int i = 0; i < attribute_pair_count; i++) {
  264. // glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
  265. //}
  266. glLinkProgram(spec.id);
  267. glGetProgramiv(spec.id, GL_LINK_STATUS, &status);
  268. if (status == GL_FALSE) {
  269. GLsizei iloglen;
  270. glGetProgramiv(spec.id, GL_INFO_LOG_LENGTH, &iloglen);
  271. if (iloglen < 0) {
  272. glDeleteShader(spec.frag_id);
  273. glDeleteShader(spec.vert_id);
  274. glDeleteProgram(spec.id);
  275. spec.id = 0;
  276. ERR_PRINT("No OpenGL program link log. What the frick?");
  277. ERR_FAIL();
  278. }
  279. if (iloglen == 0) {
  280. iloglen = 4096; // buggy driver (Adreno 220+)
  281. }
  282. char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
  283. ilogmem[iloglen] = '\0';
  284. glGetProgramInfoLog(spec.id, iloglen, &iloglen, ilogmem);
  285. String err_string = name + ": Program linking failed:\n";
  286. err_string += ilogmem;
  287. _display_error_with_code(err_string, String());
  288. Memory::free_static(ilogmem);
  289. glDeleteShader(spec.frag_id);
  290. glDeleteShader(spec.vert_id);
  291. glDeleteProgram(spec.id);
  292. spec.id = 0;
  293. ERR_FAIL();
  294. }
  295. // get uniform locations
  296. glUseProgram(spec.id);
  297. spec.uniform_location.resize(uniform_count);
  298. for (int i = 0; i < uniform_count; i++) {
  299. spec.uniform_location[i] = glGetUniformLocation(spec.id, uniform_names[i]);
  300. }
  301. for (int i = 0; i < texunit_pair_count; i++) {
  302. GLint loc = glGetUniformLocation(spec.id, texunit_pairs[i].name);
  303. if (loc >= 0) {
  304. if (texunit_pairs[i].index < 0) {
  305. glUniform1i(loc, max_image_units + texunit_pairs[i].index);
  306. } else {
  307. glUniform1i(loc, texunit_pairs[i].index);
  308. }
  309. }
  310. }
  311. for (int i = 0; i < ubo_count; i++) {
  312. GLint loc = glGetUniformBlockIndex(spec.id, ubo_pairs[i].name);
  313. if (loc >= 0) {
  314. glUniformBlockBinding(spec.id, loc, ubo_pairs[i].index);
  315. }
  316. }
  317. // textures
  318. for (int i = 0; i < p_version->texture_uniforms.size(); i++) {
  319. String native_uniform_name = p_version->texture_uniforms[i];
  320. GLint location = glGetUniformLocation(spec.id, (native_uniform_name).ascii().get_data());
  321. glUniform1i(location, i + base_texture_index);
  322. }
  323. glUseProgram(0);
  324. spec.ok = true;
  325. }
  326. RS::ShaderNativeSourceCode ShaderGLES3::version_get_native_source_code(RID p_version) {
  327. Version *version = version_owner.get_or_null(p_version);
  328. RS::ShaderNativeSourceCode source_code;
  329. ERR_FAIL_COND_V(!version, source_code);
  330. source_code.versions.resize(variant_count);
  331. for (int i = 0; i < source_code.versions.size(); i++) {
  332. //vertex stage
  333. {
  334. StringBuilder builder;
  335. _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_VERTEX], specialization_default_mask);
  336. RS::ShaderNativeSourceCode::Version::Stage stage;
  337. stage.name = "vertex";
  338. stage.code = builder.as_string();
  339. source_code.versions.write[i].stages.push_back(stage);
  340. }
  341. //fragment stage
  342. {
  343. StringBuilder builder;
  344. _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_FRAGMENT], specialization_default_mask);
  345. RS::ShaderNativeSourceCode::Version::Stage stage;
  346. stage.name = "fragment";
  347. stage.code = builder.as_string();
  348. source_code.versions.write[i].stages.push_back(stage);
  349. }
  350. }
  351. return source_code;
  352. }
  353. String ShaderGLES3::_version_get_sha1(Version *p_version) const {
  354. StringBuilder hash_build;
  355. hash_build.append("[uniforms]");
  356. hash_build.append(p_version->uniforms.get_data());
  357. hash_build.append("[vertex_globals]");
  358. hash_build.append(p_version->vertex_globals.get_data());
  359. hash_build.append("[fragment_globals]");
  360. hash_build.append(p_version->fragment_globals.get_data());
  361. Vector<StringName> code_sections;
  362. for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
  363. code_sections.push_back(E.key);
  364. }
  365. code_sections.sort_custom<StringName::AlphCompare>();
  366. for (int i = 0; i < code_sections.size(); i++) {
  367. hash_build.append(String("[code:") + String(code_sections[i]) + "]");
  368. hash_build.append(p_version->code_sections[code_sections[i]].get_data());
  369. }
  370. for (int i = 0; i < p_version->custom_defines.size(); i++) {
  371. hash_build.append("[custom_defines:" + itos(i) + "]");
  372. hash_build.append(p_version->custom_defines[i].get_data());
  373. }
  374. return hash_build.as_string().sha1_text();
  375. }
  376. //static const char *shader_file_header = "GLSC";
  377. //static const uint32_t cache_file_version = 2;
  378. bool ShaderGLES3::_load_from_cache(Version *p_version) {
  379. #if 0
  380. String sha1 = _version_get_sha1(p_version);
  381. String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache";
  382. FileAccessRef f = FileAccess::open(path, FileAccess::READ);
  383. if (!f) {
  384. return false;
  385. }
  386. char header[5] = { 0, 0, 0, 0, 0 };
  387. f->get_buffer((uint8_t *)header, 4);
  388. ERR_FAIL_COND_V(header != String(shader_file_header), false);
  389. uint32_t file_version = f->get_32();
  390. if (file_version != cache_file_version) {
  391. return false; // wrong version
  392. }
  393. uint32_t variant_count = f->get_32();
  394. ERR_FAIL_COND_V(variant_count != (uint32_t)variant_count, false); //should not happen but check
  395. for (uint32_t i = 0; i < variant_count; i++) {
  396. uint32_t variant_size = f->get_32();
  397. ERR_FAIL_COND_V(variant_size == 0 && variants_enabled[i], false);
  398. if (!variants_enabled[i]) {
  399. continue;
  400. }
  401. Vector<uint8_t> variant_bytes;
  402. variant_bytes.resize(variant_size);
  403. uint32_t br = f->get_buffer(variant_bytes.ptrw(), variant_size);
  404. ERR_FAIL_COND_V(br != variant_size, false);
  405. p_version->variant_data[i] = variant_bytes;
  406. }
  407. for (uint32_t i = 0; i < variant_count; i++) {
  408. if (!variants_enabled[i]) {
  409. MutexLock lock(variant_set_mutex);
  410. p_version->variants[i] = RID();
  411. continue;
  412. }
  413. RID shader = GLES3::get_singleton()->shader_create_from_bytecode(p_version->variant_data[i]);
  414. if (shader.is_null()) {
  415. for (uint32_t j = 0; j < i; j++) {
  416. GLES3::get_singleton()->free(p_version->variants[i]);
  417. }
  418. ERR_FAIL_COND_V(shader.is_null(), false);
  419. }
  420. {
  421. MutexLock lock(variant_set_mutex);
  422. p_version->variants[i] = shader;
  423. }
  424. }
  425. memdelete_arr(p_version->variant_data); //clear stages
  426. p_version->variant_data = nullptr;
  427. p_version->valid = true;
  428. return true;
  429. #endif
  430. return false;
  431. }
  432. void ShaderGLES3::_save_to_cache(Version *p_version) {
  433. #if 0
  434. String sha1 = _version_get_sha1(p_version);
  435. String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache";
  436. FileAccessRef f = FileAccess::open(path, FileAccess::WRITE);
  437. ERR_FAIL_COND(!f);
  438. f->store_buffer((const uint8_t *)shader_file_header, 4);
  439. f->store_32(cache_file_version); //file version
  440. uint32_t variant_count = variant_count;
  441. f->store_32(variant_count); //variant count
  442. for (uint32_t i = 0; i < variant_count; i++) {
  443. f->store_32(p_version->variant_data[i].size()); //stage count
  444. f->store_buffer(p_version->variant_data[i].ptr(), p_version->variant_data[i].size());
  445. }
  446. f->close();
  447. #endif
  448. }
  449. void ShaderGLES3::_clear_version(Version *p_version) {
  450. // Variants not compiled yet, just return
  451. if (p_version->variants.size() == 0) {
  452. return;
  453. }
  454. for (int i = 0; i < variant_count; i++) {
  455. for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) {
  456. if (it.valid) {
  457. glDeleteShader(it.value->vert_id);
  458. glDeleteShader(it.value->frag_id);
  459. glDeleteProgram(it.value->id);
  460. }
  461. }
  462. }
  463. p_version->variants.clear();
  464. }
  465. void ShaderGLES3::_initialize_version(Version *p_version) {
  466. ERR_FAIL_COND(p_version->variants.size() > 0);
  467. p_version->variants.reserve(variant_count);
  468. for (int i = 0; i < variant_count; i++) {
  469. OAHashMap<uint64_t, Version::Specialization> variant;
  470. p_version->variants.push_back(variant);
  471. Version::Specialization spec;
  472. _compile_specialization(spec, i, p_version, specialization_default_mask);
  473. p_version->variants[i].insert(specialization_default_mask, spec);
  474. }
  475. }
  476. void ShaderGLES3::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize) {
  477. Version *version = version_owner.get_or_null(p_version);
  478. ERR_FAIL_COND(!version);
  479. _clear_version(version); //clear if existing
  480. version->vertex_globals = p_vertex_globals.utf8();
  481. version->fragment_globals = p_fragment_globals.utf8();
  482. version->uniforms = p_uniforms.utf8();
  483. version->code_sections.clear();
  484. version->texture_uniforms = p_texture_uniforms;
  485. for (const KeyValue<String, String> &E : p_code) {
  486. version->code_sections[StringName(E.key.to_upper())] = E.value.utf8();
  487. }
  488. version->custom_defines.clear();
  489. for (int i = 0; i < p_custom_defines.size(); i++) {
  490. version->custom_defines.push_back(p_custom_defines[i].utf8());
  491. }
  492. if (p_initialize) {
  493. _initialize_version(version);
  494. }
  495. }
  496. bool ShaderGLES3::version_is_valid(RID p_version) {
  497. Version *version = version_owner.get_or_null(p_version);
  498. return version != nullptr;
  499. }
  500. bool ShaderGLES3::version_free(RID p_version) {
  501. if (version_owner.owns(p_version)) {
  502. Version *version = version_owner.get_or_null(p_version);
  503. _clear_version(version);
  504. version_owner.free(p_version);
  505. } else {
  506. return false;
  507. }
  508. return true;
  509. }
  510. bool ShaderGLES3::shader_cache_cleanup_on_start = false;
  511. ShaderGLES3::ShaderGLES3() {
  512. }
  513. void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture_index) {
  514. general_defines = p_general_defines.utf8();
  515. base_texture_index = p_base_texture_index;
  516. _init();
  517. if (shader_cache_dir != String()) {
  518. StringBuilder hash_build;
  519. hash_build.append("[base_hash]");
  520. hash_build.append(base_sha256);
  521. hash_build.append("[general_defines]");
  522. hash_build.append(general_defines.get_data());
  523. for (int i = 0; i < variant_count; i++) {
  524. hash_build.append("[variant_defines:" + itos(i) + "]");
  525. hash_build.append(variant_defines[i]);
  526. }
  527. base_sha256 = hash_build.as_string().sha256_text();
  528. DirAccessRef d = DirAccess::open(shader_cache_dir);
  529. ERR_FAIL_COND(!d);
  530. if (d->change_dir(name) != OK) {
  531. Error err = d->make_dir(name);
  532. ERR_FAIL_COND(err != OK);
  533. d->change_dir(name);
  534. }
  535. //erase other versions?
  536. if (shader_cache_cleanup_on_start) {
  537. }
  538. //
  539. if (d->change_dir(base_sha256) != OK) {
  540. Error err = d->make_dir(base_sha256);
  541. ERR_FAIL_COND(err != OK);
  542. }
  543. shader_cache_dir_valid = true;
  544. print_verbose("Shader '" + name + "' SHA256: " + base_sha256);
  545. }
  546. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units);
  547. }
  548. void ShaderGLES3::set_shader_cache_dir(const String &p_dir) {
  549. shader_cache_dir = p_dir;
  550. }
  551. void ShaderGLES3::set_shader_cache_save_compressed(bool p_enable) {
  552. shader_cache_save_compressed = p_enable;
  553. }
  554. void ShaderGLES3::set_shader_cache_save_compressed_zstd(bool p_enable) {
  555. shader_cache_save_compressed_zstd = p_enable;
  556. }
  557. void ShaderGLES3::set_shader_cache_save_debug(bool p_enable) {
  558. shader_cache_save_debug = p_enable;
  559. }
  560. String ShaderGLES3::shader_cache_dir;
  561. bool ShaderGLES3::shader_cache_save_compressed = true;
  562. bool ShaderGLES3::shader_cache_save_compressed_zstd = true;
  563. bool ShaderGLES3::shader_cache_save_debug = true;
  564. ShaderGLES3::~ShaderGLES3() {
  565. List<RID> remaining;
  566. version_owner.get_owned_list(&remaining);
  567. if (remaining.size()) {
  568. ERR_PRINT(itos(remaining.size()) + " shaders of type " + name + " were never freed");
  569. while (remaining.size()) {
  570. version_free(remaining.front()->get());
  571. remaining.pop_front();
  572. }
  573. }
  574. }
  575. #endif