|
@@ -46,40 +46,19 @@ namespace glsl
|
|
|
{
|
|
|
|
|
|
static const char global_syntax[] = R"(
|
|
|
-#if !defined(GL_ES) && __VERSION__ < 140
|
|
|
- #define lowp
|
|
|
- #define mediump
|
|
|
- #define highp
|
|
|
-#endif
|
|
|
#define LOVE_HIGHP_OR_MEDIUMP highp
|
|
|
-#if __VERSION__ >= 300
|
|
|
-#define LOVE_IO_LOCATION(x) layout (location = x)
|
|
|
-#else
|
|
|
-#define LOVE_IO_LOCATION(x)
|
|
|
-#endif
|
|
|
#define number float
|
|
|
#define Image sampler2D
|
|
|
#define ArrayImage sampler2DArray
|
|
|
#define CubeImage samplerCube
|
|
|
#define VolumeImage sampler3D
|
|
|
-#if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
|
|
|
- #define DepthImage sampler2DShadow
|
|
|
- #define DepthArrayImage sampler2DArrayShadow
|
|
|
- #define DepthCubeImage samplerCubeShadow
|
|
|
-#endif
|
|
|
+#define DepthImage sampler2DShadow
|
|
|
+#define DepthArrayImage sampler2DArrayShadow
|
|
|
+#define DepthCubeImage samplerCubeShadow
|
|
|
#define extern uniform
|
|
|
-#if defined(GL_EXT_texture_array) && (!defined(GL_ES) || __VERSION__ > 100 || defined(GL_OES_gpu_shader5))
|
|
|
-// Only used when !GLSLES1 to work around Ouya driver bug. But we still want it
|
|
|
-// enabled for glslang validation when glsl 1-on-3 is used, so also enable it if
|
|
|
-// OES_gpu_shader5 exists.
|
|
|
-#define LOVE_EXT_TEXTURE_ARRAY_ENABLED
|
|
|
-#extension GL_EXT_texture_array : enable
|
|
|
-#endif
|
|
|
-#ifdef GL_OES_texture_3D
|
|
|
-#extension GL_OES_texture_3D : enable
|
|
|
-#endif
|
|
|
-#ifdef GL_OES_standard_derivatives
|
|
|
-#extension GL_OES_standard_derivatives : enable
|
|
|
+
|
|
|
+#if __VERSION__ >= 430 || (defined(GL_ES) && __VERSION__ >= 310)
|
|
|
+ layout (std430) buffer;
|
|
|
#endif
|
|
|
)";
|
|
|
|
|
@@ -106,62 +85,80 @@ uniform highp vec4 love_UniformsPerDraw[12];
|
|
|
static const char global_functions[] = R"(
|
|
|
#ifdef GL_ES
|
|
|
precision mediump sampler2D;
|
|
|
- #if __VERSION__ >= 300 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
|
|
- precision mediump sampler2DArray;
|
|
|
- #endif
|
|
|
- #if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
|
|
|
- precision mediump sampler3D;
|
|
|
- #endif
|
|
|
- #if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3)
|
|
|
- precision mediump sampler2DShadow;
|
|
|
- precision mediump samplerCubeShadow;
|
|
|
- precision mediump sampler2DArrayShadow;
|
|
|
- #endif
|
|
|
+ precision mediump sampler2DArray;
|
|
|
+ precision mediump sampler3D;
|
|
|
+ precision mediump samplerCube;
|
|
|
+ precision mediump sampler2DShadow;
|
|
|
+ precision mediump samplerCubeShadow;
|
|
|
+ precision mediump sampler2DArrayShadow;
|
|
|
+
|
|
|
+ precision highp isampler2D;
|
|
|
+ precision highp isampler2DArray;
|
|
|
+ precision highp isampler3D;
|
|
|
+ precision highp isamplerCube;
|
|
|
+
|
|
|
+ precision highp usampler2D;
|
|
|
+ precision highp usampler2DArray;
|
|
|
+ precision highp usampler3D;
|
|
|
+ precision highp usamplerCube;
|
|
|
#endif
|
|
|
|
|
|
-#if __VERSION__ >= 430 || (defined(GL_ES) && __VERSION__ >= 310)
|
|
|
- layout (std430) buffer;
|
|
|
+// Avoid #define so legacy code that uses 'texture' as a variable can work...
|
|
|
+// Unfortunately it means these can't have variable precision.
|
|
|
+vec4 Texel(sampler2D s, highp vec2 c) { return texture(s, c); }
|
|
|
+ivec4 Texel(isampler2D s, highp vec2 c) { return texture(s, c); }
|
|
|
+uvec4 Texel(usampler2D s, highp vec2 c) { return texture(s, c); }
|
|
|
+
|
|
|
+vec4 Texel(sampler3D s, highp vec3 c) { return texture(s, c); }
|
|
|
+ivec4 Texel(isampler3D s, highp vec3 c) { return texture(s, c); }
|
|
|
+uvec4 Texel(usampler3D s, highp vec3 c) { return texture(s, c); }
|
|
|
+
|
|
|
+vec4 Texel(samplerCube s, highp vec3 c) { return texture(s, c); }
|
|
|
+ivec4 Texel(isamplerCube s, highp vec3 c) { return texture(s, c); }
|
|
|
+uvec4 Texel(usamplerCube s, highp vec3 c) { return texture(s, c); }
|
|
|
+
|
|
|
+vec4 Texel(sampler2DArray s, highp vec3 c) { return texture(s, c); }
|
|
|
+ivec4 Texel(isampler2DArray s, highp vec3 c) { return texture(s, c); }
|
|
|
+uvec4 Texel(usampler2DArray s, highp vec3 c) { return texture(s, c); }
|
|
|
+
|
|
|
+float Texel(sampler2DShadow s, highp vec3 c) { return texture(s, c); }
|
|
|
+float Texel(samplerCubeShadow s, highp vec4 c) { return texture(s, c); }
|
|
|
+float Texel(sampler2DArrayShadow s, highp vec4 c) { return texture(s, c); }
|
|
|
+
|
|
|
+#ifdef PIXEL
|
|
|
+ vec4 Texel(sampler2D s, highp vec2 c, float b) { return texture(s, c, b); }
|
|
|
+ ivec4 Texel(isampler2D s, highp vec2 c, float b) { return texture(s, c, b); }
|
|
|
+ uvec4 Texel(usampler2D s, highp vec2 c, float b) { return texture(s, c, b); }
|
|
|
+
|
|
|
+ vec4 Texel(sampler3D s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ ivec4 Texel(isampler3D s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ uvec4 Texel(usampler3D s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+
|
|
|
+ vec4 Texel(samplerCube s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ ivec4 Texel(isamplerCube s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ uvec4 Texel(usamplerCube s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+
|
|
|
+ vec4 Texel(sampler2DArray s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ ivec4 Texel(isampler2DArray s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ uvec4 Texel(usampler2DArray s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+
|
|
|
+ float Texel(sampler2DShadow s, highp vec3 c, float b) { return texture(s, c, b); }
|
|
|
+ float Texel(samplerCubeShadow s, highp vec4 c, float b) { return texture(s, c, b); }
|
|
|
#endif
|
|
|
|
|
|
-#if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3)
|
|
|
- #define Texel texture
|
|
|
-#else
|
|
|
- #if __VERSION__ >= 130
|
|
|
- #define texture2D Texel
|
|
|
- #define texture3D Texel
|
|
|
- #define textureCube Texel
|
|
|
- #define texture2DArray Texel
|
|
|
- #define love_texture2D texture
|
|
|
- #define love_texture3D texture
|
|
|
- #define love_textureCube texture
|
|
|
- #define love_texture2DArray texture
|
|
|
- #else
|
|
|
- #define love_texture2D texture2D
|
|
|
- #define love_texture3D texture3D
|
|
|
- #define love_textureCube textureCube
|
|
|
- #define love_texture2DArray texture2DArray
|
|
|
- #endif
|
|
|
- vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); }
|
|
|
- vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); }
|
|
|
- #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
|
|
- vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
|
|
|
- #endif
|
|
|
- #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
|
|
- vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
|
|
|
- #endif
|
|
|
- #ifdef PIXEL
|
|
|
- vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); }
|
|
|
- vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); }
|
|
|
- #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
|
|
- vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
|
|
|
- #endif
|
|
|
- #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
|
|
- vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
|
|
|
- #endif
|
|
|
- #endif
|
|
|
- #define texture love_texture
|
|
|
+uniform mediump float deprecatedTextureCall;
|
|
|
+
|
|
|
+vec4 texture2DDeprecated(sampler2D s, vec2 c) { return texture(s, c) + deprecatedTextureCall; }
|
|
|
+vec4 textureCubeDeprecated(samplerCube s, vec3 c) { return texture(s, c) + deprecatedTextureCall; }
|
|
|
+
|
|
|
+#ifdef PIXEL
|
|
|
+vec4 texture2DDeprecated(sampler2D s, vec2 c, float b) { return texture(s, c, b) + deprecatedTextureCall; }
|
|
|
+vec4 textureCubeDeprecated(samplerCube s, vec3 c, float b) { return texture(s, c, b) + deprecatedTextureCall; }
|
|
|
#endif
|
|
|
|
|
|
+#define texture2D texture2DDeprecated
|
|
|
+#define textureCube textureCubeDeprecated
|
|
|
+
|
|
|
float gammaToLinearPrecise(float c) {
|
|
|
return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);
|
|
|
}
|
|
@@ -219,14 +216,10 @@ static const char vertex_header[] = R"(
|
|
|
#define love_Position gl_Position
|
|
|
#define love_PointSize gl_PointSize
|
|
|
|
|
|
-#if __VERSION__ >= 130
|
|
|
- #define attribute in
|
|
|
- #define varying out
|
|
|
- #ifndef LOVE_GLSL1_ON_GLSL3
|
|
|
- #define love_VertexID gl_VertexID
|
|
|
- #define love_InstanceID gl_InstanceID
|
|
|
- #endif
|
|
|
-#endif
|
|
|
+#define attribute in
|
|
|
+#define varying out
|
|
|
+#define love_VertexID gl_VertexID
|
|
|
+#define love_InstanceID gl_InstanceID
|
|
|
)";
|
|
|
|
|
|
static const char vertex_functions[] = R"(
|
|
@@ -238,12 +231,12 @@ vec4 love_clipSpaceTransform(vec4 clipPosition) {
|
|
|
)";
|
|
|
|
|
|
static const char vertex_main[] = R"(
|
|
|
-LOVE_IO_LOCATION(0) attribute vec4 VertexPosition;
|
|
|
-LOVE_IO_LOCATION(1) attribute vec4 VertexTexCoord;
|
|
|
-LOVE_IO_LOCATION(2) attribute vec4 VertexColor;
|
|
|
+layout (location = 0) in vec4 VertexPosition;
|
|
|
+layout (location = 1) in vec4 VertexTexCoord;
|
|
|
+layout (location = 2) in vec4 VertexColor;
|
|
|
|
|
|
-varying vec4 VaryingTexCoord;
|
|
|
-varying vec4 VaryingColor;
|
|
|
+out vec4 VaryingTexCoord;
|
|
|
+out vec4 VaryingColor;
|
|
|
|
|
|
vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
|
|
|
|
|
@@ -271,9 +264,7 @@ static const char pixel_header[] = R"(
|
|
|
|
|
|
#define love_MaxRenderTargets gl_MaxDrawBuffers
|
|
|
|
|
|
-#if __VERSION__ >= 130
|
|
|
- #define varying in
|
|
|
-#endif
|
|
|
+#define varying in
|
|
|
|
|
|
// Legacy
|
|
|
#define love_MaxCanvases love_MaxRenderTargets
|
|
@@ -305,15 +296,11 @@ vec4 VideoTexel(vec2 texcoords) {
|
|
|
)";
|
|
|
|
|
|
static const char pixel_main[] = R"(
|
|
|
-#if __VERSION__ >= 130
|
|
|
- LOVE_IO_LOCATION(0) out vec4 love_PixelColor;
|
|
|
-#else
|
|
|
- #define love_PixelColor gl_FragColor
|
|
|
-#endif
|
|
|
+layout (location = 0) out vec4 love_PixelColor;
|
|
|
|
|
|
uniform sampler2D MainTex;
|
|
|
-varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
|
|
-varying mediump vec4 VaryingColor;
|
|
|
+in highp vec4 VaryingTexCoord;
|
|
|
+in mediump vec4 VaryingColor;
|
|
|
|
|
|
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
|
|
|
|
|
@@ -323,22 +310,15 @@ void main() {
|
|
|
)";
|
|
|
|
|
|
static const char pixel_main_custom[] = R"(
|
|
|
-#if __VERSION__ >= 130
|
|
|
- // Some drivers seem to make the pixel shader do more work when multiple
|
|
|
- // pixel shader outputs are defined, even when only one is actually used.
|
|
|
- // TODO: We should use reflection or something instead of this, to determine
|
|
|
- // how many outputs are actually used in the shader code.
|
|
|
- #ifdef LOVE_MULTI_RENDER_TARGETS
|
|
|
- LOVE_IO_LOCATION(0) out vec4 love_RenderTargets[love_MaxRenderTargets];
|
|
|
- #define love_PixelColor love_RenderTargets[0]
|
|
|
- #else
|
|
|
- LOVE_IO_LOCATION(0) out vec4 love_PixelColor;
|
|
|
- #endif
|
|
|
+// Some drivers seem to make the pixel shader do more work when multiple
|
|
|
+// pixel shader outputs are defined, even when only one is actually used.
|
|
|
+// TODO: We should use reflection or something instead of this, to determine
|
|
|
+// how many outputs are actually used in the shader code.
|
|
|
+#ifdef LOVE_MULTI_RENDER_TARGETS
|
|
|
+ layout (location = 0) out vec4 love_RenderTargets[love_MaxRenderTargets];
|
|
|
+ #define love_PixelColor love_RenderTargets[0]
|
|
|
#else
|
|
|
- #ifdef LOVE_MULTI_RENDER_TARGETS
|
|
|
- #define love_RenderTargets gl_FragData
|
|
|
- #endif
|
|
|
- #define love_PixelColor gl_FragColor
|
|
|
+ layout (location = 0) out vec4 love_PixelColor;
|
|
|
#endif
|
|
|
|
|
|
// Legacy
|
|
@@ -347,8 +327,8 @@ static const char pixel_main_custom[] = R"(
|
|
|
#define LOVE_MULTI_CANVASES 1
|
|
|
#endif
|
|
|
|
|
|
-varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
|
|
-varying mediump vec4 VaryingColor;
|
|
|
+in highp vec4 VaryingTexCoord;
|
|
|
+in mediump vec4 VaryingColor;
|
|
|
|
|
|
void effect();
|
|
|
|
|
@@ -416,7 +396,6 @@ struct Version
|
|
|
// Indexed by Shader::Version
|
|
|
static const Version versions[] =
|
|
|
{
|
|
|
- { "#version 120", "#version 100" },
|
|
|
{ "#version 330 core", "#version 300 es" },
|
|
|
{ "#version 430 core", "#version 320 es" },
|
|
|
};
|
|
@@ -530,7 +509,7 @@ static Shader::Language getTargetLanguage(const std::string &src)
|
|
|
{
|
|
|
std::regex r("^\\s*#pragma language (\\w+)");
|
|
|
std::smatch m;
|
|
|
- std::string langstr = std::regex_search(src, m, r) && m.size() > 1 ? m[1] : std::string("glsl1");
|
|
|
+ std::string langstr = std::regex_search(src, m, r) && m.size() > 1 ? m[1] : std::string("glsl3");
|
|
|
Shader::Language lang = Shader::LANGUAGE_MAX_ENUM;
|
|
|
Shader::getConstant(langstr.c_str(), lang);
|
|
|
return lang;
|
|
@@ -607,14 +586,9 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
|
|
if (info.stages[stage] == ENTRYPOINT_NONE)
|
|
|
throw love::Exception("Cannot find entry point for shader stage.");
|
|
|
|
|
|
- if (info.stages[stage] == ENTRYPOINT_RAW && info.language == LANGUAGE_GLSL1)
|
|
|
- throw love::Exception("Shaders using a raw entry point (vertexmain or pixelmain) must use GLSL 3 or greater.");
|
|
|
-
|
|
|
if (stage == SHADERSTAGE_COMPUTE && info.language != LANGUAGE_GLSL4)
|
|
|
throw love::Exception("Compute shaders must use GLSL 4.");
|
|
|
|
|
|
- bool glsl1on3 = info.language == LANGUAGE_GLSL1;
|
|
|
-
|
|
|
if (checksystemfeatures)
|
|
|
{
|
|
|
const auto &features = gfx->getCapabilities().features;
|
|
@@ -622,26 +596,17 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
|
|
if (stage == SHADERSTAGE_COMPUTE && !features[Graphics::FEATURE_GLSL4])
|
|
|
throw love::Exception("Compute shaders require GLSL 4 which is not supported on this system.");
|
|
|
|
|
|
- if (info.language == LANGUAGE_GLSL3 && !features[Graphics::FEATURE_GLSL3])
|
|
|
- throw love::Exception("GLSL 3 shaders are not supported on this system.");
|
|
|
-
|
|
|
if (info.language == LANGUAGE_GLSL4 && !features[Graphics::FEATURE_GLSL4])
|
|
|
throw love::Exception("GLSL 4 shaders are not supported on this system.");
|
|
|
-
|
|
|
- glsl1on3 = info.language == LANGUAGE_GLSL1 && features[Graphics::FEATURE_GLSL3];
|
|
|
}
|
|
|
|
|
|
Language lang = info.language;
|
|
|
- if (glsl1on3)
|
|
|
- lang = LANGUAGE_GLSL3;
|
|
|
|
|
|
glsl::StageInfo stageinfo = glsl::stageInfo[stage];
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
|
ss << (gles ? glsl::versions[lang].glsles : glsl::versions[lang].glsl) << "\n";
|
|
|
- if (glsl1on3)
|
|
|
- ss << "#define LOVE_GLSL1_ON_GLSL3 1\n";
|
|
|
|
|
|
if (isGammaCorrect())
|
|
|
ss << "#define LOVE_GAMMA_CORRECT 1\n";
|
|
@@ -666,7 +631,7 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
|
|
ss << stageinfo.main_raw;
|
|
|
else
|
|
|
throw love::Exception("Unknown shader entry point %d", info.stages[stage]);
|
|
|
- ss << ((!gles && (lang == Shader::LANGUAGE_GLSL1 || glsl1on3)) ? "#line 0\n" : "#line 1\n");
|
|
|
+ ss << "#line 1\n";
|
|
|
ss << code;
|
|
|
|
|
|
return ss.str();
|
|
@@ -909,6 +874,18 @@ const std::vector<Buffer::DataDeclaration> *Shader::getBufferFormat(const std::s
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
+bool Shader::isUsingDeprecatedTextureFunctions() const
|
|
|
+{
|
|
|
+ auto it = reflection.localUniforms.find("deprecatedTextureCall");
|
|
|
+ return it != reflection.localUniforms.end() && it->second.stageMask != 0;
|
|
|
+}
|
|
|
+
|
|
|
+bool Shader::isUsingDeprecatedTextureUniform() const
|
|
|
+{
|
|
|
+ auto it = reflection.allUniforms.find("texture");
|
|
|
+ return it != reflection.allUniforms.end() && it->second->stageMask != 0;
|
|
|
+}
|
|
|
+
|
|
|
bool Shader::validate(StrongRef<ShaderStage> stages[], std::string& err)
|
|
|
{
|
|
|
Reflection reflection;
|
|
@@ -1693,7 +1670,6 @@ const std::string &Shader::getDefaultCode(StandardShader shader, ShaderStageType
|
|
|
|
|
|
static StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM>::Entry languageEntries[] =
|
|
|
{
|
|
|
- { "glsl1", Shader::LANGUAGE_GLSL1 },
|
|
|
{ "glsl3", Shader::LANGUAGE_GLSL3 },
|
|
|
{ "glsl4", Shader::LANGUAGE_GLSL4 },
|
|
|
};
|