|
@@ -28,6 +28,7 @@
|
|
|
|
|
|
// Needed for reflection information.
|
|
// Needed for reflection information.
|
|
#include "libraries/glslang/glslang/Include/Types.h"
|
|
#include "libraries/glslang/glslang/Include/Types.h"
|
|
|
|
+#include "libraries/glslang/glslang/MachineIndependent/localintermediate.h"
|
|
|
|
|
|
// C++
|
|
// C++
|
|
#include <string>
|
|
#include <string>
|
|
@@ -94,6 +95,10 @@ LOVE_HIGHP_OR_MEDIUMP mat3 NormalMatrix;
|
|
LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
|
|
LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
|
|
LOVE_HIGHP_OR_MEDIUMP vec4 ConstantColor;
|
|
LOVE_HIGHP_OR_MEDIUMP vec4 ConstantColor;
|
|
|
|
|
|
|
|
+LOVE_HIGHP_OR_MEDIUMP float CurrentDPIScale;
|
|
|
|
+
|
|
|
|
+LOVE_HIGHP_OR_MEDIUMP float ConstantPointSize;
|
|
|
|
+
|
|
#define TransformProjectionMatrix (ProjectionMatrix * TransformMatrix)
|
|
#define TransformProjectionMatrix (ProjectionMatrix * TransformMatrix)
|
|
|
|
|
|
// Alternate names
|
|
// Alternate names
|
|
@@ -123,6 +128,8 @@ void love_initializeBuiltinUniforms() {
|
|
love_UniformsPerDraw[10].xyz
|
|
love_UniformsPerDraw[10].xyz
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+ CurrentDPIScale = love_UniformsPerDraw[8].w;
|
|
|
|
+ ConstantPointSize = love_UniformsPerDraw[9].w;
|
|
love_ScreenSize = love_UniformsPerDraw[11];
|
|
love_ScreenSize = love_UniformsPerDraw[11];
|
|
ConstantColor = love_UniformsPerDraw[12];
|
|
ConstantColor = love_UniformsPerDraw[12];
|
|
}
|
|
}
|
|
@@ -237,6 +244,7 @@ mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c
|
|
|
|
|
|
static const char vertex_header[] = R"(
|
|
static const char vertex_header[] = R"(
|
|
#define love_Position gl_Position
|
|
#define love_Position gl_Position
|
|
|
|
+#define love_PointSize gl_PointSize
|
|
|
|
|
|
#if __VERSION__ >= 130
|
|
#if __VERSION__ >= 130
|
|
#define attribute in
|
|
#define attribute in
|
|
@@ -246,19 +254,9 @@ static const char vertex_header[] = R"(
|
|
#define love_InstanceID gl_InstanceID
|
|
#define love_InstanceID gl_InstanceID
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
-
|
|
|
|
-#ifdef GL_ES
|
|
|
|
- uniform mediump float love_PointSize;
|
|
|
|
-#endif
|
|
|
|
)";
|
|
)";
|
|
|
|
|
|
-static const char vertex_functions[] = R"(
|
|
|
|
-void setPointSize() {
|
|
|
|
-#ifdef GL_ES
|
|
|
|
- gl_PointSize = love_PointSize;
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
-)";
|
|
|
|
|
|
+static const char vertex_functions[] = R"()";
|
|
|
|
|
|
static const char vertex_main[] = R"(
|
|
static const char vertex_main[] = R"(
|
|
attribute vec4 VertexPosition;
|
|
attribute vec4 VertexPosition;
|
|
@@ -274,7 +272,6 @@ void main() {
|
|
love_initializeBuiltinUniforms();
|
|
love_initializeBuiltinUniforms();
|
|
VaryingTexCoord = VertexTexCoord;
|
|
VaryingTexCoord = VertexTexCoord;
|
|
VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
|
|
VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
|
|
- setPointSize();
|
|
|
|
love_Position = position(ClipSpaceFromLocal, VertexPosition);
|
|
love_Position = position(ClipSpaceFromLocal, VertexPosition);
|
|
}
|
|
}
|
|
)";
|
|
)";
|
|
@@ -284,7 +281,6 @@ void vertexmain();
|
|
|
|
|
|
void main() {
|
|
void main() {
|
|
love_initializeBuiltinUniforms();
|
|
love_initializeBuiltinUniforms();
|
|
- setPointSize();
|
|
|
|
vertexmain();
|
|
vertexmain();
|
|
}
|
|
}
|
|
)";
|
|
)";
|
|
@@ -599,13 +595,29 @@ TextureType Shader::getMainTextureType() const
|
|
return info != nullptr ? info->textureType : TEXTURE_MAX_ENUM;
|
|
return info != nullptr ? info->textureType : TEXTURE_MAX_ENUM;
|
|
}
|
|
}
|
|
|
|
|
|
-void Shader::checkMainTextureType(TextureType textype, bool isDepthSampler) const
|
|
|
|
|
|
+void Shader::validateDrawState(PrimitiveType primtype, Texture *maintex) const
|
|
{
|
|
{
|
|
|
|
+ if ((primtype == PRIMITIVE_POINTS) != validationReflection.usesPointSize)
|
|
|
|
+ {
|
|
|
|
+ if (validationReflection.usesPointSize)
|
|
|
|
+ throw love::Exception("The active shader can only be used to draw points.");
|
|
|
|
+ else
|
|
|
|
+ throw love::Exception("The gl_PointSize variable must be set in a vertex shader when drawing points.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (maintex == nullptr)
|
|
|
|
+ return;
|
|
|
|
+
|
|
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
|
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
|
|
|
|
|
if (info == nullptr)
|
|
if (info == nullptr)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ if (!maintex->isReadable())
|
|
|
|
+ throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
|
|
|
|
+
|
|
|
|
+ auto textype = maintex->getTextureType();
|
|
|
|
+
|
|
if (info->textureType != TEXTURE_MAX_ENUM && info->textureType != textype)
|
|
if (info->textureType != TEXTURE_MAX_ENUM && info->textureType != textype)
|
|
{
|
|
{
|
|
const char *textypestr = "unknown";
|
|
const char *textypestr = "unknown";
|
|
@@ -615,7 +627,7 @@ void Shader::checkMainTextureType(TextureType textype, bool isDepthSampler) cons
|
|
throw love::Exception("Texture's type (%s) must match the type of the shader's main texture type (%s).", textypestr, shadertextypestr);
|
|
throw love::Exception("Texture's type (%s) must match the type of the shader's main texture type (%s).", textypestr, shadertextypestr);
|
|
}
|
|
}
|
|
|
|
|
|
- if (info->isDepthSampler != isDepthSampler)
|
|
|
|
|
|
+ if (info->isDepthSampler != maintex->getSamplerState().depthSampleMode.hasValue)
|
|
{
|
|
{
|
|
if (info->isDepthSampler)
|
|
if (info->isDepthSampler)
|
|
throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
|
|
throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
|
|
@@ -624,14 +636,6 @@ void Shader::checkMainTextureType(TextureType textype, bool isDepthSampler) cons
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void Shader::checkMainTexture(Texture *tex) const
|
|
|
|
-{
|
|
|
|
- if (!tex->isReadable())
|
|
|
|
- throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
|
|
|
|
-
|
|
|
|
- checkMainTextureType(tex->getTextureType(), tex->getSamplerState().depthSampleMode.hasValue);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
bool Shader::validate(ShaderStage* vertex, ShaderStage* pixel, std::string& err)
|
|
bool Shader::validate(ShaderStage* vertex, ShaderStage* pixel, std::string& err)
|
|
{
|
|
{
|
|
ValidationReflection reflection;
|
|
ValidationReflection reflection;
|
|
@@ -660,6 +664,13 @@ bool Shader::validateInternal(ShaderStage *vertex, ShaderStage *pixel, std::stri
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const auto *vertintermediate = program.getIntermediate(EShLangVertex);
|
|
|
|
+ if (vertintermediate != nullptr)
|
|
|
|
+ {
|
|
|
|
+ // NOTE: this doesn't check whether the use affects final output...
|
|
|
|
+ reflection.usesPointSize = vertintermediate->inIoAccessed("gl_PointSize");
|
|
|
|
+ }
|
|
|
|
+
|
|
for (int i = 0; i < program.getNumBufferBlocks(); i++)
|
|
for (int i = 0; i < program.getNumBufferBlocks(); i++)
|
|
{
|
|
{
|
|
const glslang::TObjectReflection &info = program.getBufferBlock(i);
|
|
const glslang::TObjectReflection &info = program.getBufferBlock(i);
|
|
@@ -727,6 +738,14 @@ vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition)
|
|
}
|
|
}
|
|
)";
|
|
)";
|
|
|
|
|
|
|
|
+static const std::string defaultPointsVertex = R"(
|
|
|
|
+vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition)
|
|
|
|
+{
|
|
|
|
+ love_PointSize = ConstantPointSize * CurrentDPIScale;
|
|
|
|
+ return clipSpaceFromLocal * localPosition;
|
|
|
|
+}
|
|
|
|
+)";
|
|
|
|
+
|
|
static const std::string defaultStandardPixel = R"(
|
|
static const std::string defaultStandardPixel = R"(
|
|
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord)
|
|
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord)
|
|
{
|
|
{
|
|
@@ -752,7 +771,12 @@ void effect()
|
|
const std::string &Shader::getDefaultCode(StandardShader shader, ShaderStage::StageType stage)
|
|
const std::string &Shader::getDefaultCode(StandardShader shader, ShaderStage::StageType stage)
|
|
{
|
|
{
|
|
if (stage == ShaderStage::STAGE_VERTEX)
|
|
if (stage == ShaderStage::STAGE_VERTEX)
|
|
- return defaultVertex;
|
|
|
|
|
|
+ {
|
|
|
|
+ if (shader == STANDARD_POINTS)
|
|
|
|
+ return defaultPointsVertex;
|
|
|
|
+ else
|
|
|
|
+ return defaultVertex;
|
|
|
|
+ }
|
|
|
|
|
|
static std::string nocode = "";
|
|
static std::string nocode = "";
|
|
|
|
|
|
@@ -761,6 +785,7 @@ const std::string &Shader::getDefaultCode(StandardShader shader, ShaderStage::St
|
|
case STANDARD_DEFAULT: return defaultStandardPixel;
|
|
case STANDARD_DEFAULT: return defaultStandardPixel;
|
|
case STANDARD_VIDEO: return defaultVideoPixel;
|
|
case STANDARD_VIDEO: return defaultVideoPixel;
|
|
case STANDARD_ARRAY: return defaultArrayPixel;
|
|
case STANDARD_ARRAY: return defaultArrayPixel;
|
|
|
|
+ case STANDARD_POINTS: return defaultStandardPixel;
|
|
case STANDARD_MAX_ENUM: return nocode;
|
|
case STANDARD_MAX_ENUM: return nocode;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -783,7 +808,6 @@ static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry builti
|
|
{ "love_VideoCbChannel", Shader::BUILTIN_TEXTURE_VIDEO_CB },
|
|
{ "love_VideoCbChannel", Shader::BUILTIN_TEXTURE_VIDEO_CB },
|
|
{ "love_VideoCrChannel", Shader::BUILTIN_TEXTURE_VIDEO_CR },
|
|
{ "love_VideoCrChannel", Shader::BUILTIN_TEXTURE_VIDEO_CR },
|
|
{ "love_UniformsPerDraw", Shader::BUILTIN_UNIFORMS_PER_DRAW },
|
|
{ "love_UniformsPerDraw", Shader::BUILTIN_UNIFORMS_PER_DRAW },
|
|
- { "love_PointSize", Shader::BUILTIN_POINT_SIZE },
|
|
|
|
};
|
|
};
|
|
|
|
|
|
static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> builtinNames(builtinNameEntries, sizeof(builtinNameEntries));
|
|
static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> builtinNames(builtinNameEntries, sizeof(builtinNameEntries));
|