effects_rd.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*************************************************************************/
  2. /* effects_rd.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 "effects_rd.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/math/math_defs.h"
  33. #include "core/os/os.h"
  34. #include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
  35. #include "thirdparty/misc/cubemap_coeffs.h"
  36. bool EffectsRD::get_prefer_raster_effects() {
  37. return prefer_raster_effects;
  38. }
  39. RID EffectsRD::_get_uniform_set_from_image(RID p_image) {
  40. if (image_to_uniform_set_cache.has(p_image)) {
  41. RID uniform_set = image_to_uniform_set_cache[p_image];
  42. if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
  43. return uniform_set;
  44. }
  45. }
  46. Vector<RD::Uniform> uniforms;
  47. RD::Uniform u;
  48. u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
  49. u.binding = 0;
  50. u.append_id(p_image);
  51. uniforms.push_back(u);
  52. //any thing with the same configuration (one texture in binding 0 for set 0), is good
  53. RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 1);
  54. image_to_uniform_set_cache[p_image] = uniform_set;
  55. return uniform_set;
  56. }
  57. RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
  58. if (texture_to_uniform_set_cache.has(p_texture)) {
  59. RID uniform_set = texture_to_uniform_set_cache[p_texture];
  60. if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
  61. return uniform_set;
  62. }
  63. }
  64. Vector<RD::Uniform> uniforms;
  65. RD::Uniform u;
  66. u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
  67. u.binding = 0;
  68. u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
  69. u.append_id(p_texture);
  70. uniforms.push_back(u);
  71. // anything with the same configuration (one texture in binding 0 for set 0), is good
  72. RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, 0), 0);
  73. texture_to_uniform_set_cache[p_texture] = uniform_set;
  74. return uniform_set;
  75. }
  76. RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
  77. if (texture_to_compute_uniform_set_cache.has(p_texture)) {
  78. RID uniform_set = texture_to_compute_uniform_set_cache[p_texture];
  79. if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
  80. return uniform_set;
  81. }
  82. }
  83. Vector<RD::Uniform> uniforms;
  84. RD::Uniform u;
  85. u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
  86. u.binding = 0;
  87. u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
  88. u.append_id(p_texture);
  89. uniforms.push_back(u);
  90. //any thing with the same configuration (one texture in binding 0 for set 0), is good
  91. RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 0);
  92. texture_to_compute_uniform_set_cache[p_texture] = uniform_set;
  93. return uniform_set;
  94. }
  95. void EffectsRD::fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness) {
  96. memset(&FSR_upscale.push_constant, 0, sizeof(FSRUpscalePushConstant));
  97. int dispatch_x = (p_size.x + 15) / 16;
  98. int dispatch_y = (p_size.y + 15) / 16;
  99. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  100. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, FSR_upscale.pipeline);
  101. FSR_upscale.push_constant.resolution_width = p_internal_size.width;
  102. FSR_upscale.push_constant.resolution_height = p_internal_size.height;
  103. FSR_upscale.push_constant.upscaled_width = p_size.width;
  104. FSR_upscale.push_constant.upscaled_height = p_size.height;
  105. FSR_upscale.push_constant.sharpness = p_fsr_upscale_sharpness;
  106. //FSR Easc
  107. FSR_upscale.push_constant.pass = FSR_UPSCALE_PASS_EASU;
  108. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
  109. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_secondary_texture), 1);
  110. RD::get_singleton()->compute_list_set_push_constant(compute_list, &FSR_upscale.push_constant, sizeof(FSRUpscalePushConstant));
  111. RD::get_singleton()->compute_list_dispatch(compute_list, dispatch_x, dispatch_y, 1);
  112. RD::get_singleton()->compute_list_add_barrier(compute_list);
  113. //FSR Rcas
  114. FSR_upscale.push_constant.pass = FSR_UPSCALE_PASS_RCAS;
  115. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_secondary_texture), 0);
  116. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_destination_texture), 1);
  117. RD::get_singleton()->compute_list_set_push_constant(compute_list, &FSR_upscale.push_constant, sizeof(FSRUpscalePushConstant));
  118. RD::get_singleton()->compute_list_dispatch(compute_list, dispatch_x, dispatch_y, 1);
  119. RD::get_singleton()->compute_list_end(compute_list);
  120. }
  121. void EffectsRD::taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity, RID p_prev_velocity, RID p_history, Size2 p_resolution, float p_z_near, float p_z_far) {
  122. UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
  123. ERR_FAIL_NULL(uniform_set_cache);
  124. RID shader = TAA_resolve.shader.version_get_shader(TAA_resolve.shader_version, 0);
  125. ERR_FAIL_COND(shader.is_null());
  126. memset(&TAA_resolve.push_constant, 0, sizeof(TAAResolvePushConstant));
  127. TAA_resolve.push_constant.resolution_width = p_resolution.width;
  128. TAA_resolve.push_constant.resolution_height = p_resolution.height;
  129. TAA_resolve.push_constant.disocclusion_threshold = 0.025f;
  130. TAA_resolve.push_constant.disocclusion_scale = 10.0f;
  131. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  132. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, TAA_resolve.pipeline);
  133. RD::Uniform u_frame_source(RD::UNIFORM_TYPE_IMAGE, 0, { p_frame });
  134. RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, { default_sampler, p_depth });
  135. RD::Uniform u_velocity(RD::UNIFORM_TYPE_IMAGE, 2, { p_velocity });
  136. RD::Uniform u_prev_velocity(RD::UNIFORM_TYPE_IMAGE, 3, { p_prev_velocity });
  137. RD::Uniform u_history(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 4, { default_sampler, p_history });
  138. RD::Uniform u_frame_dest(RD::UNIFORM_TYPE_IMAGE, 5, { p_temp });
  139. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_frame_source, u_depth, u_velocity, u_prev_velocity, u_history, u_frame_dest), 0);
  140. RD::get_singleton()->compute_list_set_push_constant(compute_list, &TAA_resolve.push_constant, sizeof(TAAResolvePushConstant));
  141. RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_resolution.width, p_resolution.height, 1);
  142. RD::get_singleton()->compute_list_end();
  143. }
  144. void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const Projection &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
  145. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  146. Plane p = p_camera.xform4(Plane(1, 0, -1, 1));
  147. p.normal /= p.d;
  148. float unit_size = p.normal.x;
  149. { //scale color and depth to half
  150. sss.push_constant.camera_z_far = p_camera.get_z_far();
  151. sss.push_constant.camera_z_near = p_camera.get_z_near();
  152. sss.push_constant.orthogonal = p_camera.is_orthogonal();
  153. sss.push_constant.unit_size = unit_size;
  154. sss.push_constant.screen_size[0] = p_screen_size.x;
  155. sss.push_constant.screen_size[1] = p_screen_size.y;
  156. sss.push_constant.vertical = false;
  157. sss.push_constant.scale = p_scale;
  158. sss.push_constant.depth_scale = p_depth_scale;
  159. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sss.pipelines[p_quality - 1]);
  160. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0);
  161. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_diffuse2), 1);
  162. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth), 2);
  163. RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant));
  164. RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
  165. RD::get_singleton()->compute_list_add_barrier(compute_list);
  166. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse2), 0);
  167. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_diffuse), 1);
  168. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth), 2);
  169. sss.push_constant.vertical = true;
  170. RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant));
  171. RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
  172. RD::get_singleton()->compute_list_end();
  173. }
  174. }
  175. void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
  176. ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer.");
  177. luminance_reduce.push_constant.source_size[0] = p_source_size.x;
  178. luminance_reduce.push_constant.source_size[1] = p_source_size.y;
  179. luminance_reduce.push_constant.max_luminance = p_max_luminance;
  180. luminance_reduce.push_constant.min_luminance = p_min_luminance;
  181. luminance_reduce.push_constant.exposure_adjust = p_adjust;
  182. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  183. for (int i = 0; i < p_reduce.size(); i++) {
  184. if (i == 0) {
  185. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]);
  186. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_texture), 0);
  187. } else {
  188. RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done
  189. if (i == p_reduce.size() - 1 && !p_set) {
  190. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_WRITE]);
  191. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_prev_luminance), 2);
  192. } else {
  193. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE]);
  194. }
  195. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_reduce[i - 1]), 0);
  196. }
  197. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_reduce[i]), 1);
  198. RD::get_singleton()->compute_list_set_push_constant(compute_list, &luminance_reduce.push_constant, sizeof(LuminanceReducePushConstant));
  199. RD::get_singleton()->compute_list_dispatch_threads(compute_list, luminance_reduce.push_constant.source_size[0], luminance_reduce.push_constant.source_size[1], 1);
  200. luminance_reduce.push_constant.source_size[0] = MAX(luminance_reduce.push_constant.source_size[0] / 8, 1);
  201. luminance_reduce.push_constant.source_size[1] = MAX(luminance_reduce.push_constant.source_size[1] / 8, 1);
  202. }
  203. RD::get_singleton()->compute_list_end();
  204. }
  205. void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
  206. ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster version of luminance reduction with the clustered renderer.");
  207. ERR_FAIL_COND_MSG(p_reduce.size() != p_fb.size(), "Incorrect frame buffer account for luminance reduction.");
  208. luminance_reduce_raster.push_constant.max_luminance = p_max_luminance;
  209. luminance_reduce_raster.push_constant.min_luminance = p_min_luminance;
  210. luminance_reduce_raster.push_constant.exposure_adjust = p_adjust;
  211. for (int i = 0; i < p_reduce.size(); i++) {
  212. luminance_reduce_raster.push_constant.source_size[0] = i == 0 ? p_source_size.x : luminance_reduce_raster.push_constant.dest_size[0];
  213. luminance_reduce_raster.push_constant.source_size[1] = i == 0 ? p_source_size.y : luminance_reduce_raster.push_constant.dest_size[1];
  214. luminance_reduce_raster.push_constant.dest_size[0] = MAX(luminance_reduce_raster.push_constant.source_size[0] / 8, 1);
  215. luminance_reduce_raster.push_constant.dest_size[1] = MAX(luminance_reduce_raster.push_constant.source_size[1] / 8, 1);
  216. bool final = !p_set && (luminance_reduce_raster.push_constant.dest_size[0] == 1) && (luminance_reduce_raster.push_constant.dest_size[1] == 1);
  217. LuminanceReduceRasterMode mode = final ? LUMINANCE_REDUCE_FRAGMENT_FINAL : (i == 0 ? LUMINANCE_REDUCE_FRAGMENT_FIRST : LUMINANCE_REDUCE_FRAGMENT);
  218. RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
  219. RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, luminance_reduce_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_fb[i])));
  220. RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(i == 0 ? p_source_texture : p_reduce[i - 1]), 0);
  221. if (final) {
  222. RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_prev_luminance), 1);
  223. }
  224. RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
  225. RD::get_singleton()->draw_list_set_push_constant(draw_list, &luminance_reduce_raster.push_constant, sizeof(LuminanceReduceRasterPushConstant));
  226. RD::get_singleton()->draw_list_draw(draw_list, true);
  227. RD::get_singleton()->draw_list_end();
  228. }
  229. }
  230. void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
  231. roughness_limiter.push_constant.screen_size[0] = p_size.x;
  232. roughness_limiter.push_constant.screen_size[1] = p_size.y;
  233. roughness_limiter.push_constant.curve = p_curve;
  234. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  235. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness_limiter.pipeline);
  236. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_normal), 0);
  237. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_roughness), 1);
  238. RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness_limiter.push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway
  239. RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1);
  240. RD::get_singleton()->compute_list_end();
  241. }
  242. void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
  243. Sort::PushConstant push_constant;
  244. push_constant.total_elements = p_size;
  245. bool done = true;
  246. int numThreadGroups = ((p_size - 1) >> 9) + 1;
  247. if (numThreadGroups > 1) {
  248. done = false;
  249. }
  250. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
  251. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_BLOCK]);
  252. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_uniform_set, 1);
  253. RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
  254. RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
  255. int presorted = 512;
  256. while (!done) {
  257. RD::get_singleton()->compute_list_add_barrier(compute_list);
  258. done = true;
  259. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_STEP]);
  260. numThreadGroups = 0;
  261. if (p_size > presorted) {
  262. if (p_size > presorted * 2) {
  263. done = false;
  264. }
  265. int pow2 = presorted;
  266. while (pow2 < p_size) {
  267. pow2 *= 2;
  268. }
  269. numThreadGroups = pow2 >> 9;
  270. }
  271. unsigned int nMergeSize = presorted * 2;
  272. for (unsigned int nMergeSubSize = nMergeSize >> 1; nMergeSubSize > 256; nMergeSubSize = nMergeSubSize >> 1) {
  273. push_constant.job_params[0] = nMergeSubSize;
  274. if (nMergeSubSize == nMergeSize >> 1) {
  275. push_constant.job_params[1] = (2 * nMergeSubSize - 1);
  276. push_constant.job_params[2] = -1;
  277. } else {
  278. push_constant.job_params[1] = nMergeSubSize;
  279. push_constant.job_params[2] = 1;
  280. }
  281. push_constant.job_params[3] = 0;
  282. RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
  283. RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
  284. RD::get_singleton()->compute_list_add_barrier(compute_list);
  285. }
  286. RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_INNER]);
  287. RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
  288. RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
  289. presorted *= 2;
  290. }
  291. RD::get_singleton()->compute_list_end();
  292. }
  293. EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
  294. {
  295. Vector<String> FSR_upscale_modes;
  296. #if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
  297. // MoltenVK does not support some of the operations used by the normal mode of FSR. Fallback works just fine though.
  298. FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_FALLBACK\n");
  299. #else
  300. // Everyone else can use normal mode when available.
  301. if (RD::get_singleton()->has_feature(RD::SUPPORTS_FSR_HALF_FLOAT)) {
  302. FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_NORMAL\n");
  303. } else {
  304. FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_FALLBACK\n");
  305. }
  306. #endif
  307. FSR_upscale.shader.initialize(FSR_upscale_modes);
  308. FSR_upscale.shader_version = FSR_upscale.shader.version_create();
  309. FSR_upscale.pipeline = RD::get_singleton()->compute_pipeline_create(FSR_upscale.shader.version_get_shader(FSR_upscale.shader_version, 0));
  310. }
  311. prefer_raster_effects = p_prefer_raster_effects;
  312. if (prefer_raster_effects) {
  313. Vector<String> luminance_reduce_modes;
  314. luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST
  315. luminance_reduce_modes.push_back("\n"); // LUMINANCE_REDUCE_FRAGMENT
  316. luminance_reduce_modes.push_back("\n#define FINAL_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FINAL
  317. luminance_reduce_raster.shader.initialize(luminance_reduce_modes);
  318. memset(&luminance_reduce_raster.push_constant, 0, sizeof(LuminanceReduceRasterPushConstant));
  319. luminance_reduce_raster.shader_version = luminance_reduce_raster.shader.version_create();
  320. for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
  321. luminance_reduce_raster.pipelines[i].setup(luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
  322. }
  323. } else {
  324. // Initialize luminance_reduce
  325. Vector<String> luminance_reduce_modes;
  326. luminance_reduce_modes.push_back("\n#define READ_TEXTURE\n");
  327. luminance_reduce_modes.push_back("\n");
  328. luminance_reduce_modes.push_back("\n#define WRITE_LUMINANCE\n");
  329. luminance_reduce.shader.initialize(luminance_reduce_modes);
  330. luminance_reduce.shader_version = luminance_reduce.shader.version_create();
  331. for (int i = 0; i < LUMINANCE_REDUCE_MAX; i++) {
  332. luminance_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, i));
  333. }
  334. for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) {
  335. luminance_reduce_raster.pipelines[i].clear();
  336. }
  337. }
  338. if (!prefer_raster_effects) {
  339. // Initialize roughness limiter
  340. Vector<String> shader_modes;
  341. shader_modes.push_back("");
  342. roughness_limiter.shader.initialize(shader_modes);
  343. roughness_limiter.shader_version = roughness_limiter.shader.version_create();
  344. roughness_limiter.pipeline = RD::get_singleton()->compute_pipeline_create(roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0));
  345. }
  346. if (!prefer_raster_effects) {
  347. {
  348. Vector<String> sss_modes;
  349. sss_modes.push_back("\n#define USE_11_SAMPLES\n");
  350. sss_modes.push_back("\n#define USE_17_SAMPLES\n");
  351. sss_modes.push_back("\n#define USE_25_SAMPLES\n");
  352. sss.shader.initialize(sss_modes);
  353. sss.shader_version = sss.shader.version_create();
  354. for (int i = 0; i < sss_modes.size(); i++) {
  355. sss.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sss.shader.version_get_shader(sss.shader_version, i));
  356. }
  357. }
  358. }
  359. {
  360. Vector<String> sort_modes;
  361. sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
  362. sort_modes.push_back("\n#define MODE_SORT_STEP\n");
  363. sort_modes.push_back("\n#define MODE_SORT_INNER\n");
  364. sort.shader.initialize(sort_modes);
  365. sort.shader_version = sort.shader.version_create();
  366. for (int i = 0; i < SORT_MODE_MAX; i++) {
  367. sort.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sort.shader.version_get_shader(sort.shader_version, i));
  368. }
  369. }
  370. {
  371. Vector<String> taa_modes;
  372. taa_modes.push_back("\n#define MODE_TAA_RESOLVE");
  373. TAA_resolve.shader.initialize(taa_modes);
  374. TAA_resolve.shader_version = TAA_resolve.shader.version_create();
  375. TAA_resolve.pipeline = RD::get_singleton()->compute_pipeline_create(TAA_resolve.shader.version_get_shader(TAA_resolve.shader_version, 0));
  376. }
  377. RD::SamplerState sampler;
  378. sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
  379. sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
  380. sampler.max_lod = 0;
  381. default_sampler = RD::get_singleton()->sampler_create(sampler);
  382. RD::get_singleton()->set_resource_name(default_sampler, "Default Linear Sampler");
  383. sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
  384. sampler.mip_filter = RD::SAMPLER_FILTER_LINEAR;
  385. sampler.max_lod = 1e20;
  386. default_mipmap_sampler = RD::get_singleton()->sampler_create(sampler);
  387. RD::get_singleton()->set_resource_name(default_mipmap_sampler, "Default MipMap Sampler");
  388. { //create index array for copy shaders
  389. Vector<uint8_t> pv;
  390. pv.resize(6 * 4);
  391. {
  392. uint8_t *w = pv.ptrw();
  393. int *p32 = (int *)w;
  394. p32[0] = 0;
  395. p32[1] = 1;
  396. p32[2] = 2;
  397. p32[3] = 0;
  398. p32[4] = 2;
  399. p32[5] = 3;
  400. }
  401. index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
  402. index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6);
  403. }
  404. }
  405. EffectsRD::~EffectsRD() {
  406. RD::get_singleton()->free(default_sampler);
  407. RD::get_singleton()->free(default_mipmap_sampler);
  408. RD::get_singleton()->free(index_buffer); //array gets freed as dependency
  409. FSR_upscale.shader.version_free(FSR_upscale.shader_version);
  410. TAA_resolve.shader.version_free(TAA_resolve.shader_version);
  411. if (prefer_raster_effects) {
  412. luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version);
  413. } else {
  414. luminance_reduce.shader.version_free(luminance_reduce.shader_version);
  415. }
  416. if (!prefer_raster_effects) {
  417. roughness_limiter.shader.version_free(roughness_limiter.shader_version);
  418. sss.shader.version_free(sss.shader_version);
  419. }
  420. sort.shader.version_free(sort.shader_version);
  421. }