Shader.cpp 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  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 "Shader.h"
  22. #include "Graphics.h"
  23. #include "math/MathModule.h"
  24. // glslang
  25. #include "libraries/glslang/glslang/Public/ShaderLang.h"
  26. // Needed for reflection information.
  27. #include "libraries/glslang/glslang/Include/Types.h"
  28. #include "libraries/glslang/glslang/MachineIndependent/localintermediate.h"
  29. // C++
  30. #include <string>
  31. #include <regex>
  32. #include <sstream>
  33. namespace love
  34. {
  35. namespace graphics
  36. {
  37. namespace glsl
  38. {
  39. static const char global_syntax[] = R"(
  40. #if !defined(GL_ES) && __VERSION__ < 140
  41. #define lowp
  42. #define mediump
  43. #define highp
  44. #endif
  45. #if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
  46. #define LOVE_HIGHP_OR_MEDIUMP highp
  47. #else
  48. #define LOVE_HIGHP_OR_MEDIUMP mediump
  49. #endif
  50. #if __VERSION__ >= 300
  51. #define LOVE_IO_LOCATION(x) layout (location = x)
  52. #else
  53. #define LOVE_IO_LOCATION(x)
  54. #endif
  55. #define number float
  56. #define Image sampler2D
  57. #define ArrayImage sampler2DArray
  58. #define CubeImage samplerCube
  59. #define VolumeImage sampler3D
  60. #if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
  61. #define DepthImage sampler2DShadow
  62. #define DepthArrayImage sampler2DArrayShadow
  63. #define DepthCubeImage samplerCubeShadow
  64. #endif
  65. #define extern uniform
  66. #if defined(GL_EXT_texture_array) && (!defined(GL_ES) || __VERSION__ > 100 || defined(GL_OES_gpu_shader5))
  67. // Only used when !GLSLES1 to work around Ouya driver bug. But we still want it
  68. // enabled for glslang validation when glsl 1-on-3 is used, so also enable it if
  69. // OES_gpu_shader5 exists.
  70. #define LOVE_EXT_TEXTURE_ARRAY_ENABLED
  71. #extension GL_EXT_texture_array : enable
  72. #endif
  73. #ifdef GL_OES_texture_3D
  74. #extension GL_OES_texture_3D : enable
  75. #endif
  76. #ifdef GL_OES_standard_derivatives
  77. #extension GL_OES_standard_derivatives : enable
  78. #endif
  79. #ifdef USE_VULKAN
  80. #define VULKAN_LOCATION(x) layout(location=x)
  81. #define VULKAN_BINDING(x) layout(binding=x)
  82. #else
  83. #define VULKAN_LOCATION(x)
  84. #define VULKAN_BINDING(x)
  85. #endif
  86. )";
  87. static const char render_uniforms[] = R"(
  88. #ifdef USE_VULKAN
  89. VULKAN_BINDING(0) uniform LoveUniformsPerDraw {
  90. vec4 uniformsPerDraw[13];
  91. } udp;
  92. #define love_UniformsPerDraw udp.uniformsPerDraw
  93. #else
  94. // According to the GLSL ES 1.0 spec, uniform precision must match between stages,
  95. // but we can't guarantee that highp is always supported in fragment shaders...
  96. // We *really* don't want to use mediump for these in vertex shaders though.
  97. uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[13];
  98. #endif
  99. // These are initialized in love_initializeBuiltinUniforms below. GLSL ES can't
  100. // do it as an initializer.
  101. LOVE_HIGHP_OR_MEDIUMP mat4 TransformMatrix;
  102. LOVE_HIGHP_OR_MEDIUMP mat4 ProjectionMatrix;
  103. LOVE_HIGHP_OR_MEDIUMP mat3 NormalMatrix;
  104. LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
  105. LOVE_HIGHP_OR_MEDIUMP vec4 ConstantColor;
  106. LOVE_HIGHP_OR_MEDIUMP float CurrentDPIScale;
  107. LOVE_HIGHP_OR_MEDIUMP float ConstantPointSize;
  108. #define TransformProjectionMatrix (ProjectionMatrix * TransformMatrix)
  109. // Alternate names
  110. #define ViewSpaceFromLocal TransformMatrix
  111. #define ClipSpaceFromView ProjectionMatrix
  112. #define ClipSpaceFromLocal TransformProjectionMatrix
  113. #define ViewNormalFromLocal NormalMatrix
  114. void love_initializeBuiltinUniforms() {
  115. TransformMatrix = mat4(
  116. love_UniformsPerDraw[0],
  117. love_UniformsPerDraw[1],
  118. love_UniformsPerDraw[2],
  119. love_UniformsPerDraw[3]
  120. );
  121. ProjectionMatrix = mat4(
  122. love_UniformsPerDraw[4],
  123. love_UniformsPerDraw[5],
  124. love_UniformsPerDraw[6],
  125. love_UniformsPerDraw[7]
  126. );
  127. NormalMatrix = mat3(
  128. love_UniformsPerDraw[8].xyz,
  129. love_UniformsPerDraw[9].xyz,
  130. love_UniformsPerDraw[10].xyz
  131. );
  132. CurrentDPIScale = love_UniformsPerDraw[8].w;
  133. ConstantPointSize = love_UniformsPerDraw[9].w;
  134. love_ScreenSize = love_UniformsPerDraw[11];
  135. ConstantColor = love_UniformsPerDraw[12];
  136. }
  137. )";
  138. static const char global_functions[] = R"(
  139. #ifdef GL_ES
  140. #if __VERSION__ >= 300 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
  141. precision lowp sampler2DArray;
  142. #endif
  143. #if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
  144. precision lowp sampler3D;
  145. #endif
  146. #if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
  147. precision lowp sampler2DShadow;
  148. precision lowp samplerCubeShadow;
  149. precision lowp sampler2DArrayShadow;
  150. #endif
  151. #endif
  152. #if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3)
  153. #define Texel texture
  154. #else
  155. #if __VERSION__ >= 130
  156. #define texture2D Texel
  157. #define texture3D Texel
  158. #define textureCube Texel
  159. #define texture2DArray Texel
  160. #define love_texture2D texture
  161. #define love_texture3D texture
  162. #define love_textureCube texture
  163. #define love_texture2DArray texture
  164. #else
  165. #define love_texture2D texture2D
  166. #define love_texture3D texture3D
  167. #define love_textureCube textureCube
  168. #define love_texture2DArray texture2DArray
  169. #endif
  170. vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); }
  171. vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); }
  172. #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
  173. vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
  174. #endif
  175. #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
  176. vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
  177. #endif
  178. #ifdef PIXEL
  179. vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); }
  180. vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); }
  181. #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
  182. vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
  183. #endif
  184. #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
  185. vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
  186. #endif
  187. #endif
  188. #define texture love_texture
  189. #endif
  190. float gammaToLinearPrecise(float c) {
  191. return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);
  192. }
  193. vec3 gammaToLinearPrecise(vec3 c) {
  194. bvec3 leq = lessThanEqual(c, vec3(0.04045));
  195. c.r = leq.r ? c.r / 12.92 : pow((c.r + 0.055) / 1.055, 2.4);
  196. c.g = leq.g ? c.g / 12.92 : pow((c.g + 0.055) / 1.055, 2.4);
  197. c.b = leq.b ? c.b / 12.92 : pow((c.b + 0.055) / 1.055, 2.4);
  198. return c;
  199. }
  200. vec4 gammaToLinearPrecise(vec4 c) { return vec4(gammaToLinearPrecise(c.rgb), c.a); }
  201. float linearToGammaPrecise(float c) {
  202. return c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;
  203. }
  204. vec3 linearToGammaPrecise(vec3 c) {
  205. bvec3 lt = lessThanEqual(c, vec3(0.0031308));
  206. c.r = lt.r ? c.r * 12.92 : 1.055 * pow(c.r, 1.0 / 2.4) - 0.055;
  207. c.g = lt.g ? c.g * 12.92 : 1.055 * pow(c.g, 1.0 / 2.4) - 0.055;
  208. c.b = lt.b ? c.b * 12.92 : 1.055 * pow(c.b, 1.0 / 2.4) - 0.055;
  209. return c;
  210. }
  211. vec4 linearToGammaPrecise(vec4 c) { return vec4(linearToGammaPrecise(c.rgb), c.a); }
  212. // http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
  213. mediump float gammaToLinearFast(mediump float c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
  214. mediump vec3 gammaToLinearFast(mediump vec3 c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); }
  215. mediump vec4 gammaToLinearFast(mediump vec4 c) { return vec4(gammaToLinearFast(c.rgb), c.a); }
  216. mediump float linearToGammaFast(mediump float c) { return max(1.055 * pow(max(c, 0.0), 0.41666666) - 0.055, 0.0); }
  217. mediump vec3 linearToGammaFast(mediump vec3 c) { return max(1.055 * pow(max(c, vec3(0.0)), vec3(0.41666666)) - 0.055, vec3(0.0)); }
  218. mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c.rgb), c.a); }
  219. #define gammaToLinear gammaToLinearFast
  220. #define linearToGamma linearToGammaFast
  221. #ifdef LOVE_GAMMA_CORRECT
  222. #define gammaCorrectColor gammaToLinear
  223. #define unGammaCorrectColor linearToGamma
  224. #define gammaCorrectColorPrecise gammaToLinearPrecise
  225. #define unGammaCorrectColorPrecise linearToGammaPrecise
  226. #define gammaCorrectColorFast gammaToLinearFast
  227. #define unGammaCorrectColorFast linearToGammaFast
  228. #else
  229. #define gammaCorrectColor
  230. #define unGammaCorrectColor
  231. #define gammaCorrectColorPrecise
  232. #define unGammaCorrectColorPrecise
  233. #define gammaCorrectColorFast
  234. #define unGammaCorrectColorFast
  235. #endif
  236. )";
  237. static const char vertex_header[] = R"(
  238. #define love_Position gl_Position
  239. #define love_PointSize gl_PointSize
  240. #if __VERSION__ >= 130
  241. #define attribute in
  242. #define varying out
  243. #ifndef LOVE_GLSL1_ON_GLSL3
  244. #define love_VertexID gl_VertexID
  245. #define love_InstanceID gl_InstanceID
  246. #endif
  247. #endif
  248. )";
  249. static const char vertex_functions[] = R"()";
  250. static const char vertex_main[] = R"(
  251. VULKAN_LOCATION(0) attribute vec4 VertexPosition;
  252. VULKAN_LOCATION(1) attribute vec4 VertexTexCoord;
  253. VULKAN_LOCATION(2) attribute vec4 VertexColor;
  254. VULKAN_LOCATION(0) varying vec4 VaryingTexCoord;
  255. VULKAN_LOCATION(1) varying vec4 VaryingColor;
  256. vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
  257. void main() {
  258. love_initializeBuiltinUniforms();
  259. VaryingTexCoord = VertexTexCoord;
  260. VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
  261. love_Position = position(ClipSpaceFromLocal, VertexPosition);
  262. }
  263. )";
  264. static const char vertex_main_raw[] = R"(
  265. void vertexmain();
  266. void main() {
  267. love_initializeBuiltinUniforms();
  268. vertexmain();
  269. }
  270. )";
  271. static const char pixel_header[] = R"(
  272. #ifdef GL_ES
  273. precision mediump float;
  274. #endif
  275. #define love_MaxRenderTargets gl_MaxDrawBuffers
  276. #if __VERSION__ >= 130
  277. #define varying in
  278. #endif
  279. // Legacy
  280. #define love_MaxCanvases love_MaxRenderTargets
  281. // See Shader::updateScreenParams in Shader.cpp.
  282. #define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))
  283. )";
  284. static const char pixel_functions[] = R"(
  285. VULKAN_BINDING(1) uniform sampler2D love_VideoYChannel;
  286. VULKAN_BINDING(2) uniform sampler2D love_VideoCbChannel;
  287. VULKAN_BINDING(3) uniform sampler2D love_VideoCrChannel;
  288. vec4 VideoTexel(vec2 texcoords) {
  289. vec3 yuv;
  290. yuv[0] = Texel(love_VideoYChannel, texcoords).r;
  291. yuv[1] = Texel(love_VideoCbChannel, texcoords).r;
  292. yuv[2] = Texel(love_VideoCrChannel, texcoords).r;
  293. yuv += vec3(-0.0627451017, -0.501960814, -0.501960814);
  294. vec4 color;
  295. color.r = dot(yuv, vec3(1.164, 0.000, 1.596));
  296. color.g = dot(yuv, vec3(1.164, -0.391, -0.813));
  297. color.b = dot(yuv, vec3(1.164, 2.018, 0.000));
  298. color.a = 1.0;
  299. return gammaCorrectColor(color);
  300. }
  301. )";
  302. static const char pixel_main[] = R"(
  303. #if __VERSION__ >= 130
  304. LOVE_IO_LOCATION(0) out vec4 love_PixelColor;
  305. #else
  306. #define love_PixelColor gl_FragColor
  307. #endif
  308. VULKAN_BINDING(4) uniform sampler2D MainTex;
  309. VULKAN_LOCATION(0) varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
  310. VULKAN_LOCATION(1) varying mediump vec4 VaryingColor;
  311. vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
  312. void main() {
  313. love_initializeBuiltinUniforms();
  314. love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
  315. }
  316. )";
  317. static const char pixel_main_custom[] = R"(
  318. #if __VERSION__ >= 130
  319. // Some drivers seem to make the pixel shader do more work when multiple
  320. // pixel shader outputs are defined, even when only one is actually used.
  321. // TODO: We should use reflection or something instead of this, to determine
  322. // how many outputs are actually used in the shader code.
  323. #ifdef LOVE_MULTI_RENDER_TARGETS
  324. LOVE_IO_LOCATION(0) out vec4 love_RenderTargets[love_MaxRenderTargets];
  325. #define love_PixelColor love_RenderTargets[0]
  326. #else
  327. LOVE_IO_LOCATION(0) out vec4 love_PixelColor;
  328. #endif
  329. #else
  330. #ifdef LOVE_MULTI_RENDER_TARGETS
  331. #define love_RenderTargets gl_FragData
  332. #endif
  333. #define love_PixelColor gl_FragColor
  334. #endif
  335. // Legacy
  336. #define love_Canvases love_RenderTargets
  337. #ifdef LOVE_MULTI_RENDER_TARGETS
  338. #define LOVE_MULTI_CANVASES 1
  339. #endif
  340. VULKAN_LOCATION(0) varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
  341. VULKAN_LOCATION(1) varying mediump vec4 VaryingColor;
  342. void effect();
  343. void main() {
  344. love_initializeBuiltinUniforms();
  345. effect();
  346. }
  347. )";
  348. static const char pixel_main_raw[] = R"(
  349. void pixelmain();
  350. void main() {
  351. love_initializeBuiltinUniforms();
  352. pixelmain();
  353. }
  354. )";
  355. static const char compute_header[] = R"(
  356. #define love_ThreadGroupCount gl_NumWorkGroups
  357. #define love_ThreadGroupID gl_WorkGroupID
  358. #define love_LocalThreadID gl_LocalInvocationID
  359. #define love_GlobalThreadID gl_GlobalInvocationID
  360. #define love_LocalThreadIndex gl_LocalInvocationIndex
  361. #define love_ThreadGroupSize gl_WorkGroupSize
  362. )";
  363. static const char compute_uniforms[] = R"(
  364. void love_initializeBuiltinUniforms() {}
  365. )";
  366. static const char compute_functions[] = R"()";
  367. static const char compute_main[] = R"(
  368. void computemain();
  369. void main() {
  370. love_initializeBuiltinUniforms();
  371. computemain();
  372. }
  373. )";
  374. static const char vulkan_vert[] = R"(
  375. #version 450
  376. layout(location = 0) in vec2 inPosition;
  377. layout(location = 0) out vec4 fragColor;
  378. layout(binding = 0) uniform LoveUniforms {
  379. float windowWidth;
  380. float windowHeight;
  381. } loveUniforms;
  382. void main() {
  383. gl_Position = vec4(
  384. 2 * inPosition.x / loveUniforms.windowWidth - 1,
  385. 2 * inPosition.y / loveUniforms.windowHeight - 1,
  386. 0.0, 1.0);
  387. fragColor = vec4(1, 1, 1, 1);
  388. }
  389. )";
  390. static const char vulkan_pixel[] = R"(
  391. #version 450
  392. layout(location = 0) in vec4 fragColor;
  393. layout(location = 0) out vec4 outColor;
  394. void main() {
  395. outColor = fragColor;
  396. }
  397. )";
  398. struct StageInfo
  399. {
  400. const char *name;
  401. const char *header;
  402. const char *uniforms;
  403. const char *functions;
  404. const char *main;
  405. const char *main_custom;
  406. const char *main_raw;
  407. };
  408. static const StageInfo stageInfo[] =
  409. {
  410. { "VERTEX", vertex_header, render_uniforms, vertex_functions, vertex_main, vertex_main, vertex_main_raw },
  411. { "PIXEL", pixel_header, render_uniforms, pixel_functions, pixel_main, pixel_main_custom, pixel_main_raw },
  412. { "COMPUTE", compute_header, compute_uniforms, compute_functions, compute_main, compute_main, compute_main },
  413. };
  414. static_assert((sizeof(stageInfo) / sizeof(StageInfo)) == SHADERSTAGE_MAX_ENUM, "Stages array size must match ShaderStage enum.");
  415. struct Version
  416. {
  417. std::string glsl;
  418. std::string glsles;
  419. };
  420. // Indexed by Shader::Version
  421. static const Version versions[] =
  422. {
  423. { "#version 120", "#version 100" },
  424. { "#version 330 core", "#version 300 es" },
  425. { "#version 430 core", "#version 320 es" },
  426. };
  427. static Shader::Language getTargetLanguage(const std::string &src)
  428. {
  429. std::regex r("^\\s*#pragma language (\\w+)");
  430. std::smatch m;
  431. std::string langstr = std::regex_search(src, m, r) && m.size() > 1 ? m[1] : std::string("glsl1");
  432. Shader::Language lang = Shader::LANGUAGE_MAX_ENUM;
  433. Shader::getConstant(langstr.c_str(), lang);
  434. return lang;
  435. }
  436. static Shader::EntryPoint getVertexEntryPoint(const std::string &src)
  437. {
  438. std::smatch m;
  439. if (std::regex_search(src, m, std::regex("void\\s+vertexmain\\s*\\(")))
  440. return Shader::ENTRYPOINT_RAW;
  441. if (std::regex_search(src, m, std::regex("vec4\\s+position\\s*\\(")))
  442. return Shader::ENTRYPOINT_HIGHLEVEL;
  443. return Shader::ENTRYPOINT_NONE;
  444. }
  445. static Shader::EntryPoint getPixelEntryPoint(const std::string &src, bool &mrt)
  446. {
  447. mrt = false;
  448. std::smatch m;
  449. if (std::regex_search(src, m, std::regex("void\\s+pixelmain\\s*\\(")))
  450. return Shader::ENTRYPOINT_RAW;
  451. if (std::regex_search(src, m, std::regex("vec4\\s+effect\\s*\\(")))
  452. return Shader::ENTRYPOINT_HIGHLEVEL;
  453. if (std::regex_search(src, m, std::regex("void\\s+effect\\s*\\(")))
  454. {
  455. if (src.find("love_RenderTargets") != std::string::npos || src.find("love_Canvases") != std::string::npos)
  456. mrt = true;
  457. return Shader::ENTRYPOINT_CUSTOM;
  458. }
  459. return Shader::ENTRYPOINT_NONE;
  460. }
  461. static Shader::EntryPoint getComputeEntryPoint(const std::string &src) {
  462. std::smatch m;
  463. if (std::regex_search(src, m, std::regex("void\\s+computemain\\s*\\(")))
  464. return Shader::ENTRYPOINT_RAW;
  465. return Shader::ENTRYPOINT_NONE;
  466. }
  467. } // glsl
  468. static_assert(sizeof(Shader::BuiltinUniformData) == sizeof(float) * 4 * 13, "Update the array in wrap_GraphicsShader.lua if this changes.");
  469. love::Type Shader::type("Shader", &Object::type);
  470. Shader *Shader::current = nullptr;
  471. Shader *Shader::standardShaders[Shader::STANDARD_MAX_ENUM] = {nullptr};
  472. Shader::SourceInfo Shader::getSourceInfo(const std::string &src)
  473. {
  474. SourceInfo info = {};
  475. info.language = glsl::getTargetLanguage(src);
  476. info.stages[SHADERSTAGE_VERTEX] = glsl::getVertexEntryPoint(src);
  477. info.stages[SHADERSTAGE_PIXEL] = glsl::getPixelEntryPoint(src, info.usesMRT);
  478. info.stages[SHADERSTAGE_COMPUTE] = glsl::getComputeEntryPoint(src);
  479. if (info.stages[SHADERSTAGE_COMPUTE])
  480. info.language = LANGUAGE_GLSL4;
  481. return info;
  482. }
  483. std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage, const std::string &code, const Shader::SourceInfo &info, bool gles, bool checksystemfeatures)
  484. {
  485. if (info.language == Shader::LANGUAGE_MAX_ENUM)
  486. throw love::Exception("Invalid shader language");
  487. if (info.stages[stage] == ENTRYPOINT_NONE)
  488. throw love::Exception("Cannot find entry point for shader stage.");
  489. if (info.stages[stage] == ENTRYPOINT_RAW && info.language == LANGUAGE_GLSL1)
  490. throw love::Exception("Shaders using a raw entry point (vertexmain or pixelmain) must use GLSL 3 or greater.");
  491. if (stage == SHADERSTAGE_COMPUTE && info.language != LANGUAGE_GLSL4)
  492. throw love::Exception("Compute shaders must use GLSL 4.");
  493. bool glsl1on3 = info.language == LANGUAGE_GLSL1;
  494. if (checksystemfeatures)
  495. {
  496. const auto &features = gfx->getCapabilities().features;
  497. if (stage == SHADERSTAGE_COMPUTE && !features[Graphics::FEATURE_GLSL4])
  498. throw love::Exception("Compute shaders require GLSL 4 which is not supported on this system.");
  499. if (info.language == LANGUAGE_GLSL3 && !features[Graphics::FEATURE_GLSL3])
  500. throw love::Exception("GLSL 3 shaders are not supported on this system.");
  501. if (info.language == LANGUAGE_GLSL4 && !features[Graphics::FEATURE_GLSL4])
  502. throw love::Exception("GLSL 4 shaders are not supported on this system.");
  503. glsl1on3 = info.language == LANGUAGE_GLSL1 && features[Graphics::FEATURE_GLSL3];
  504. }
  505. Language lang = info.language;
  506. if (glsl1on3)
  507. lang = LANGUAGE_GLSL3;
  508. if (info.vulkan) {
  509. if (stage == SHADERSTAGE_VERTEX) {
  510. return love::graphics::glsl::vulkan_vert;
  511. }
  512. if (stage == SHADERSTAGE_PIXEL) {
  513. return love::graphics::glsl::vulkan_pixel;
  514. }
  515. }
  516. glsl::StageInfo stageinfo = glsl::stageInfo[stage];
  517. std::stringstream ss;
  518. ss << (gles ? glsl::versions[lang].glsles : glsl::versions[lang].glsl) << "\n";
  519. ss << "#define " << stageinfo.name << " " << stageinfo.name << "\n";
  520. if (glsl1on3)
  521. ss << "#define LOVE_GLSL1_ON_GLSL3 1\n";
  522. if (isGammaCorrect())
  523. ss << "#define LOVE_GAMMA_CORRECT 1\n";
  524. if (info.usesMRT)
  525. ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
  526. if (info.vulkan)
  527. ss << "#define USE_VULKAN\n";
  528. ss << glsl::global_syntax;
  529. ss << stageinfo.header;
  530. ss << stageinfo.uniforms;
  531. ss << glsl::global_functions;
  532. ss << stageinfo.functions;
  533. if (info.stages[stage] == ENTRYPOINT_HIGHLEVEL)
  534. ss << stageinfo.main;
  535. else if (info.stages[stage] == ENTRYPOINT_CUSTOM)
  536. ss << stageinfo.main_custom;
  537. else if (info.stages[stage] == ENTRYPOINT_RAW)
  538. ss << stageinfo.main_raw;
  539. else
  540. throw love::Exception("Unknown shader entry point %d", info.stages[stage]);
  541. ss << ((!gles && (lang == Shader::LANGUAGE_GLSL1 || glsl1on3)) ? "#line 0\n" : "#line 1\n");
  542. ss << code;
  543. return ss.str();
  544. }
  545. Shader::Shader(StrongRef<ShaderStage> _stages[])
  546. : stages()
  547. {
  548. std::string err;
  549. if (!validateInternal(_stages, err, validationReflection))
  550. throw love::Exception("%s", err.c_str());
  551. for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
  552. stages[i] = _stages[i];
  553. }
  554. Shader::~Shader()
  555. {
  556. for (int i = 0; i < STANDARD_MAX_ENUM; i++)
  557. {
  558. if (this == standardShaders[i])
  559. standardShaders[i] = nullptr;
  560. }
  561. if (current == this)
  562. attachDefault(STANDARD_DEFAULT);
  563. }
  564. bool Shader::hasStage(ShaderStageType stage)
  565. {
  566. return stages[stage] != nullptr;
  567. }
  568. void Shader::attachDefault(StandardShader defaultType)
  569. {
  570. Shader *defaultshader = standardShaders[defaultType];
  571. if (defaultshader == nullptr)
  572. {
  573. current = nullptr;
  574. return;
  575. }
  576. if (current != defaultshader)
  577. defaultshader->attach();
  578. }
  579. bool Shader::isDefaultActive()
  580. {
  581. for (int i = 0; i < STANDARD_MAX_ENUM; i++)
  582. {
  583. if (current == standardShaders[i])
  584. return true;
  585. }
  586. return false;
  587. }
  588. const Shader::UniformInfo *Shader::getMainTextureInfo() const
  589. {
  590. return getUniformInfo(BUILTIN_TEXTURE_MAIN);
  591. }
  592. DataBaseType Shader::getDataBaseType(PixelFormat format)
  593. {
  594. switch (getPixelFormatInfo(format).dataType)
  595. {
  596. case PIXELFORMATTYPE_UNORM:
  597. return DATA_BASETYPE_UNORM;
  598. case PIXELFORMATTYPE_SNORM:
  599. return DATA_BASETYPE_SNORM;
  600. case PIXELFORMATTYPE_UFLOAT:
  601. case PIXELFORMATTYPE_SFLOAT:
  602. return DATA_BASETYPE_FLOAT;
  603. case PIXELFORMATTYPE_SINT:
  604. return DATA_BASETYPE_INT;
  605. case PIXELFORMATTYPE_UINT:
  606. return DATA_BASETYPE_UINT;
  607. default:
  608. return DATA_BASETYPE_FLOAT;
  609. }
  610. }
  611. bool Shader::isResourceBaseTypeCompatible(DataBaseType a, DataBaseType b)
  612. {
  613. if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
  614. return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
  615. if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
  616. return true;
  617. if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
  618. return true;
  619. return false;
  620. }
  621. void Shader::validateDrawState(PrimitiveType primtype, Texture *maintex) const
  622. {
  623. if ((primtype == PRIMITIVE_POINTS) != validationReflection.usesPointSize)
  624. {
  625. if (validationReflection.usesPointSize)
  626. throw love::Exception("The active shader can only be used to draw points.");
  627. else
  628. throw love::Exception("The gl_PointSize variable must be set in a vertex shader when drawing points.");
  629. }
  630. if (maintex == nullptr)
  631. return;
  632. const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
  633. if (info == nullptr)
  634. return;
  635. if (!maintex->isReadable())
  636. throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
  637. auto textype = maintex->getTextureType();
  638. if (info->textureType != TEXTURE_MAX_ENUM && info->textureType != textype)
  639. {
  640. const char *textypestr = "unknown";
  641. const char *shadertextypestr = "unknown";
  642. Texture::getConstant(textype, textypestr);
  643. Texture::getConstant(info->textureType, shadertextypestr);
  644. throw love::Exception("Texture's type (%s) must match the type of the shader's main texture type (%s).", textypestr, shadertextypestr);
  645. }
  646. if (!isResourceBaseTypeCompatible(info->dataBaseType, getDataBaseType(maintex->getPixelFormat())))
  647. throw love::Exception("Texture's data format base type must match the uniform variable declared in the shader (float, int, or uint).");
  648. if (info->isDepthSampler != maintex->getSamplerState().depthSampleMode.hasValue)
  649. {
  650. if (info->isDepthSampler)
  651. throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
  652. else
  653. throw love::Exception("Depth textures which have depth comparison set can only be used with depth/shadow samplers in shaders.");
  654. }
  655. }
  656. void Shader::getLocalThreadgroupSize(int *x, int *y, int *z)
  657. {
  658. *x = validationReflection.localThreadgroupSize[0];
  659. *y = validationReflection.localThreadgroupSize[1];
  660. *z = validationReflection.localThreadgroupSize[2];
  661. }
  662. bool Shader::validate(StrongRef<ShaderStage> stages[], std::string& err)
  663. {
  664. ValidationReflection reflection;
  665. return validateInternal(stages, err, reflection);
  666. }
  667. static PixelFormat getPixelFormat(glslang::TLayoutFormat format)
  668. {
  669. using namespace glslang;
  670. switch (format)
  671. {
  672. case ElfNone: return PIXELFORMAT_UNKNOWN;
  673. case ElfRgba32f: return PIXELFORMAT_RGBA32_FLOAT;
  674. case ElfRgba16f: return PIXELFORMAT_RGBA16_FLOAT;
  675. case ElfR32f: return PIXELFORMAT_R32_FLOAT;
  676. case ElfRgba8: return PIXELFORMAT_RGBA8_UNORM;
  677. case ElfRgba8Snorm: return PIXELFORMAT_UNKNOWN; // no snorm yet
  678. case ElfRg32f: return PIXELFORMAT_RG32_FLOAT;
  679. case ElfRg16f: return PIXELFORMAT_RG16_FLOAT;
  680. case ElfR11fG11fB10f: return PIXELFORMAT_RG11B10_FLOAT;
  681. case ElfR16f: return PIXELFORMAT_R16_FLOAT;
  682. case ElfRgba16: return PIXELFORMAT_RGBA16_UNORM;
  683. case ElfRgb10A2: return PIXELFORMAT_RGB10A2_UNORM;
  684. case ElfRg16: return PIXELFORMAT_RG16_UNORM;
  685. case ElfRg8: return PIXELFORMAT_RG8_UNORM;
  686. case ElfR8: return PIXELFORMAT_R8_UNORM;
  687. case ElfRgba16Snorm: return PIXELFORMAT_UNKNOWN;
  688. case ElfRg16Snorm: return PIXELFORMAT_UNKNOWN;
  689. case ElfRg8Snorm: return PIXELFORMAT_UNKNOWN;
  690. case ElfR16Snorm: return PIXELFORMAT_UNKNOWN;
  691. case ElfR8Snorm: return PIXELFORMAT_UNKNOWN;
  692. case ElfRgba32i: return PIXELFORMAT_RGBA32_INT;
  693. case ElfRgba16i: return PIXELFORMAT_RGBA16_INT;
  694. case ElfRgba8i: return PIXELFORMAT_RGBA8_INT;
  695. case ElfR32i: return PIXELFORMAT_R32_INT;
  696. case ElfRg32i: return PIXELFORMAT_RG32_INT;
  697. case ElfRg16i: return PIXELFORMAT_RG16_INT;
  698. case ElfRg8i: return PIXELFORMAT_RG8_INT;
  699. case ElfR16i: return PIXELFORMAT_R16_INT;
  700. case ElfR8i: return PIXELFORMAT_R8_INT;
  701. case ElfRgba32ui: return PIXELFORMAT_RGBA32_UINT;
  702. case ElfRgba16ui: return PIXELFORMAT_RGBA16_UINT;
  703. case ElfRgba8ui: return PIXELFORMAT_RGBA8_UINT;
  704. case ElfR32ui: return PIXELFORMAT_R32_UINT;
  705. case ElfRg32ui: return PIXELFORMAT_RG32_UINT;
  706. case ElfRg16ui: return PIXELFORMAT_RG16_UINT;
  707. case ElfRgb10a2ui: return PIXELFORMAT_UNKNOWN;
  708. case ElfRg8ui: return PIXELFORMAT_RG8_UINT;
  709. case ElfR16ui: return PIXELFORMAT_R16_UINT;
  710. case ElfR8ui: return PIXELFORMAT_R8_UINT;
  711. default: return PIXELFORMAT_UNKNOWN;
  712. }
  713. }
  714. template <typename T>
  715. static T convertData(const glslang::TConstUnion &data)
  716. {
  717. switch (data.getType())
  718. {
  719. case glslang::EbtInt: return (T) data.getIConst();
  720. case glslang::EbtUint: return (T) data.getUConst();
  721. case glslang::EbtDouble: return (T) data.getDConst();
  722. case glslang::EbtInt8: return (T) data.getI8Const();
  723. case glslang::EbtInt16: return (T) data.getI16Const();
  724. case glslang::EbtInt64: return (T) data.getI64Const();
  725. case glslang::EbtUint8: return (T) data.getU8Const();
  726. case glslang::EbtUint16: return (T) data.getU16Const();
  727. case glslang::EbtUint64: return (T) data.getU64Const();
  728. default: return 0;
  729. }
  730. }
  731. bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err, ValidationReflection &reflection)
  732. {
  733. glslang::TProgram program;
  734. for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
  735. {
  736. if (stages[i] != nullptr)
  737. program.addShader(stages[i]->getGLSLangValidationShader());
  738. }
  739. if (!program.link(EShMsgDefault))
  740. {
  741. err = "Cannot compile shader:\n\n" + std::string(program.getInfoLog()) + "\n" + std::string(program.getInfoDebugLog());
  742. return false;
  743. }
  744. if (!program.buildReflection(EShReflectionSeparateBuffers))
  745. {
  746. err = "Cannot get reflection information for shader.";
  747. return false;
  748. }
  749. const auto *vertintermediate = program.getIntermediate(EShLangVertex);
  750. if (vertintermediate != nullptr)
  751. {
  752. // NOTE: this doesn't check whether the use affects final output...
  753. reflection.usesPointSize = vertintermediate->inIoAccessed("gl_PointSize");
  754. }
  755. if (stages[SHADERSTAGE_COMPUTE] != nullptr)
  756. {
  757. for (int i = 0; i < 3; i++)
  758. {
  759. reflection.localThreadgroupSize[i] = program.getLocalSize(i);
  760. if (reflection.localThreadgroupSize[i] <= 0)
  761. {
  762. err = "Shader validation error:\nNegative local threadgroup size.";
  763. return false;
  764. }
  765. }
  766. }
  767. for (int i = 0; i < program.getNumUniformVariables(); i++)
  768. {
  769. const glslang::TObjectReflection &info = program.getUniform(i);
  770. const glslang::TType *type = info.getType();
  771. if (type == nullptr)
  772. continue;
  773. const glslang::TQualifier &qualifiers = type->getQualifier();
  774. if (type->isImage())
  775. {
  776. if ((info.stages & EShLangComputeMask) == 0)
  777. {
  778. err = "Shader validation error:\nStorage Texture uniform variables (image2D, etc) are only allowed in compute shaders.";
  779. return false;
  780. }
  781. if (!qualifiers.hasFormat())
  782. {
  783. err = "Shader validation error:\nStorage Texture '" + info.name + "' must have an explicit format set in its layout declaration.";
  784. return false;
  785. }
  786. StorageTextureReflection texreflection = {};
  787. texreflection.format = getPixelFormat(qualifiers.getFormat());
  788. if (qualifiers.isReadOnly())
  789. texreflection.access = ACCESS_READ;
  790. else if (qualifiers.isWriteOnly())
  791. texreflection.access = ACCESS_WRITE;
  792. else
  793. texreflection.access = (Access)(ACCESS_READ | ACCESS_WRITE);
  794. reflection.storageTextures[info.name] = texreflection;
  795. }
  796. else if (!type->isOpaque())
  797. {
  798. LocalUniform u = {};
  799. auto &values = u.initializerValues;
  800. // const glslang::TConstUnionArray *constarray = info.getConstArray(); was this function deprecated in a later version?
  801. const glslang::TConstUnionArray* constarray = nullptr;
  802. // Store initializer values for local uniforms. Some love graphics
  803. // backends strip these out of the shader so we need to be able to
  804. // access them (to re-send them) by getting them here.
  805. switch (type->getBasicType())
  806. {
  807. case glslang::EbtFloat:
  808. u.dataType = DATA_BASETYPE_FLOAT;
  809. if (constarray != nullptr)
  810. {
  811. values.resize(constarray->size());
  812. for (int i = 0; i < constarray->size(); i++)
  813. values[i].f = convertData<float>((*constarray)[i]);
  814. }
  815. break;
  816. case glslang::EbtUint:
  817. u.dataType = DATA_BASETYPE_UINT;
  818. if (constarray != nullptr)
  819. {
  820. values.resize(constarray->size());
  821. for (int i = 0; i < constarray->size(); i++)
  822. values[i].u = convertData<uint32>((*constarray)[i]);
  823. }
  824. break;
  825. case glslang::EbtInt:
  826. case glslang::EbtBool:
  827. default:
  828. u.dataType = DATA_BASETYPE_INT;
  829. if (constarray != nullptr)
  830. {
  831. values.resize(constarray->size());
  832. for (int i = 0; i < constarray->size(); i++)
  833. values[i].i = convertData<int32>((*constarray)[i]);
  834. }
  835. break;
  836. }
  837. reflection.localUniforms[info.name] = u;
  838. }
  839. }
  840. for (int i = 0; i < program.getNumBufferBlocks(); i++)
  841. {
  842. const glslang::TObjectReflection &info = program.getBufferBlock(i);
  843. const glslang::TType *type = info.getType();
  844. if (type != nullptr)
  845. {
  846. const glslang::TQualifier &qualifiers = type->getQualifier();
  847. if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && (info.stages & EShLangComputeMask) == 0)
  848. {
  849. err = "Shader validation error:\nStorage Buffer block '" + info.name + "' must be marked as readonly in vertex and pixel shaders.";
  850. return false;
  851. }
  852. if (qualifiers.layoutPacking != glslang::ElpStd430)
  853. {
  854. err = "Shader validation error:\nStorage Buffer block '" + info.name + "' must use the std430 packing layout.";
  855. return false;
  856. }
  857. const glslang::TTypeList *structure = type->getStruct();
  858. if (structure == nullptr || structure->size() != 1)
  859. {
  860. err = "Shader validation error:\nStorage Buffer block '" + info.name + "' must contain a single unsized array of base types or structs.";
  861. return false;
  862. }
  863. const glslang::TType* elementtype = (*structure)[0].type;
  864. if (elementtype == nullptr || !elementtype->isUnsizedArray())
  865. {
  866. err = "Shader validation error:\nStorage Buffer block '" + info.name + "' must contain a single unsized array of base types or structs.";
  867. return false;
  868. }
  869. BufferReflection bufferReflection = {};
  870. bufferReflection.stride = (size_t) info.size;
  871. bufferReflection.memberCount = (size_t) info.numMembers;
  872. if (qualifiers.isReadOnly())
  873. bufferReflection.access = ACCESS_READ;
  874. else if (qualifiers.isWriteOnly())
  875. bufferReflection.access = ACCESS_WRITE;
  876. else
  877. bufferReflection.access = (Access)(ACCESS_READ | ACCESS_WRITE);
  878. reflection.storageBuffers[info.name] = bufferReflection;
  879. }
  880. else
  881. {
  882. err = "Shader validation error:\nCannot retrieve type information for Storage Buffer Block '" + info.name + "'.";
  883. return false;
  884. }
  885. }
  886. return true;
  887. }
  888. bool Shader::validateTexture(const UniformInfo *info, Texture *tex, bool internalUpdate)
  889. {
  890. const SamplerState &sampler = tex->getSamplerState();
  891. bool isstoragetex = info->baseType == UNIFORM_STORAGETEXTURE;
  892. if (!tex->isReadable())
  893. {
  894. if (internalUpdate)
  895. return false;
  896. else
  897. throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
  898. }
  899. else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
  900. {
  901. if (internalUpdate)
  902. return false;
  903. else if (info->isDepthSampler)
  904. throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
  905. else
  906. throw love::Exception("Depth textures which have depth comparison set can only be used with depth/shadow samplers in shaders.");
  907. }
  908. else if (tex->getTextureType() != info->textureType)
  909. {
  910. if (internalUpdate)
  911. return false;
  912. else
  913. {
  914. const char *textypestr = "unknown";
  915. const char *shadertextypestr = "unknown";
  916. Texture::getConstant(tex->getTextureType(), textypestr);
  917. Texture::getConstant(info->textureType, shadertextypestr);
  918. throw love::Exception("Texture's type (%s) must match the type of %s (%s).", textypestr, info->name.c_str(), shadertextypestr);
  919. }
  920. }
  921. else if (!isResourceBaseTypeCompatible(info->dataBaseType, getDataBaseType(tex->getPixelFormat())))
  922. {
  923. if (internalUpdate)
  924. return false;
  925. else
  926. throw love::Exception("Texture's data format base type must match the uniform variable declared in the shader (float, int, or uint).");
  927. }
  928. else if (isstoragetex && !tex->isComputeWritable())
  929. {
  930. if (internalUpdate)
  931. return false;
  932. else
  933. 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.");
  934. }
  935. else if (isstoragetex && info->storageTextureFormat != getLinearPixelFormat(tex->getPixelFormat()))
  936. {
  937. if (internalUpdate)
  938. return false;
  939. else
  940. {
  941. const char *texpfstr = "unknown";
  942. const char *shaderpfstr = "unknown";
  943. love::getConstant(getLinearPixelFormat(tex->getPixelFormat()), texpfstr);
  944. love::getConstant(info->storageTextureFormat, shaderpfstr);
  945. 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);
  946. }
  947. }
  948. return true;
  949. }
  950. bool Shader::validateBuffer(const UniformInfo *info, Buffer *buffer, bool internalUpdate)
  951. {
  952. uint32 requiredtypeflags = 0;
  953. bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
  954. bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
  955. if (texelbinding)
  956. requiredtypeflags = BUFFERUSAGEFLAG_TEXEL;
  957. else if (storagebinding)
  958. requiredtypeflags = BUFFERUSAGEFLAG_SHADER_STORAGE;
  959. if ((buffer->getUsageFlags() & requiredtypeflags) == 0)
  960. {
  961. if (internalUpdate)
  962. return false;
  963. else if (texelbinding)
  964. 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());
  965. else if (storagebinding)
  966. 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());
  967. else
  968. throw love::Exception("Shader uniform '%s' does not match the types supported by the given Buffer.", info->name.c_str());
  969. }
  970. if (texelbinding)
  971. {
  972. DataBaseType basetype = buffer->getDataMember(0).info.baseType;
  973. if (!isResourceBaseTypeCompatible(basetype, info->dataBaseType))
  974. {
  975. if (internalUpdate)
  976. return false;
  977. else
  978. throw love::Exception("Texel buffer's data format base type must match the variable declared in the shader.");
  979. }
  980. }
  981. else if (storagebinding)
  982. {
  983. if (info->bufferStride != buffer->getArrayStride())
  984. {
  985. if (internalUpdate)
  986. return false;
  987. else
  988. 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.",
  989. info->name.c_str(), info->bufferStride, buffer->getArrayStride());
  990. }
  991. else if (info->bufferMemberCount != buffer->getDataMembers().size())
  992. {
  993. if (internalUpdate)
  994. return false;
  995. else
  996. throw love::Exception("Shader storage block '%s' has a struct with %d fields, but the given Buffer has a format with %d members.",
  997. info->name.c_str(), info->bufferMemberCount, buffer->getDataMembers().size());
  998. }
  999. }
  1000. return true;
  1001. }
  1002. bool Shader::initialize()
  1003. {
  1004. return glslang::InitializeProcess();
  1005. }
  1006. void Shader::deinitialize()
  1007. {
  1008. glslang::FinalizeProcess();
  1009. }
  1010. static const std::string defaultVertex = R"(
  1011. vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition)
  1012. {
  1013. return clipSpaceFromLocal * localPosition;
  1014. }
  1015. )";
  1016. static const std::string defaultPointsVertex = R"(
  1017. vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition)
  1018. {
  1019. love_PointSize = ConstantPointSize * CurrentDPIScale;
  1020. return clipSpaceFromLocal * localPosition;
  1021. }
  1022. )";
  1023. static const std::string defaultStandardPixel = R"(
  1024. vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord)
  1025. {
  1026. return Texel(tex, texcoord) * vcolor;
  1027. }
  1028. )";
  1029. static const std::string defaultVideoPixel = R"(
  1030. void effect()
  1031. {
  1032. love_PixelColor = VideoTexel(VaryingTexCoord.xy) * VaryingColor;
  1033. }
  1034. )";
  1035. static const std::string defaultArrayPixel = R"(
  1036. uniform ArrayImage MainTex;
  1037. void effect()
  1038. {
  1039. love_PixelColor = Texel(MainTex, VaryingTexCoord.xyz) * VaryingColor;
  1040. }
  1041. )";
  1042. const std::string &Shader::getDefaultCode(StandardShader shader, ShaderStageType stage)
  1043. {
  1044. if (stage == SHADERSTAGE_VERTEX)
  1045. {
  1046. if (shader == STANDARD_POINTS)
  1047. return defaultPointsVertex;
  1048. else
  1049. return defaultVertex;
  1050. }
  1051. static std::string nocode = "";
  1052. switch (shader)
  1053. {
  1054. case STANDARD_DEFAULT: return defaultStandardPixel;
  1055. case STANDARD_VIDEO: return defaultVideoPixel;
  1056. case STANDARD_ARRAY: return defaultArrayPixel;
  1057. case STANDARD_POINTS: return defaultStandardPixel;
  1058. case STANDARD_MAX_ENUM: return nocode;
  1059. }
  1060. return nocode;
  1061. }
  1062. static StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM>::Entry languageEntries[] =
  1063. {
  1064. { "glsl1", Shader::LANGUAGE_GLSL1 },
  1065. { "glsl3", Shader::LANGUAGE_GLSL3 },
  1066. { "glsl4", Shader::LANGUAGE_GLSL4 },
  1067. };
  1068. static StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM> languages(languageEntries, sizeof(languageEntries));
  1069. static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry builtinNameEntries[] =
  1070. {
  1071. { "MainTex", Shader::BUILTIN_TEXTURE_MAIN },
  1072. { "love_VideoYChannel", Shader::BUILTIN_TEXTURE_VIDEO_Y },
  1073. { "love_VideoCbChannel", Shader::BUILTIN_TEXTURE_VIDEO_CB },
  1074. { "love_VideoCrChannel", Shader::BUILTIN_TEXTURE_VIDEO_CR },
  1075. { "love_UniformsPerDraw", Shader::BUILTIN_UNIFORMS_PER_DRAW },
  1076. };
  1077. static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> builtinNames(builtinNameEntries, sizeof(builtinNameEntries));
  1078. bool Shader::getConstant(const char *in, Language &out)
  1079. {
  1080. return languages.find(in, out);
  1081. }
  1082. bool Shader::getConstant(Language in, const char *&out)
  1083. {
  1084. return languages.find(in, out);
  1085. }
  1086. bool Shader::getConstant(const char *in, BuiltinUniform &out)
  1087. {
  1088. return builtinNames.find(in, out);
  1089. }
  1090. bool Shader::getConstant(BuiltinUniform in, const char *&out)
  1091. {
  1092. return builtinNames.find(in, out);
  1093. }
  1094. } // graphics
  1095. } // love