mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
shaders: ignore code in comments when parsing entry point functions.
Fixes #1581.
This commit is contained in:
+123
-18
@@ -22,6 +22,7 @@
|
|||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "math/MathModule.h"
|
#include "math/MathModule.h"
|
||||||
|
#include "common/Range.h"
|
||||||
|
|
||||||
// glslang
|
// glslang
|
||||||
#include "libraries/glslang/glslang/Public/ShaderLang.h"
|
#include "libraries/glslang/glslang/Public/ShaderLang.h"
|
||||||
@@ -425,6 +426,111 @@ static const Version versions[] =
|
|||||||
{ "#version 430 core", "#version 320 es" },
|
{ "#version 430 core", "#version 320 es" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CommentType
|
||||||
|
{
|
||||||
|
COMMENT_NONE,
|
||||||
|
COMMENT_LINE,
|
||||||
|
COMMENT_BLOCK,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void parseComments(const std::string &src, std::vector<Range> &comments)
|
||||||
|
{
|
||||||
|
CommentType commenttype = COMMENT_NONE;
|
||||||
|
Range comment;
|
||||||
|
|
||||||
|
const char *srcbytes = src.data();
|
||||||
|
size_t len = src.length();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
char curchar = srcbytes[i];
|
||||||
|
|
||||||
|
if (commenttype == COMMENT_NONE)
|
||||||
|
{
|
||||||
|
if (curchar == '/' && i + 1 < len)
|
||||||
|
{
|
||||||
|
char nextchar = srcbytes[i + 1];
|
||||||
|
if (nextchar == '/')
|
||||||
|
{
|
||||||
|
commenttype = COMMENT_LINE;
|
||||||
|
comment = Range(i, 1);
|
||||||
|
}
|
||||||
|
else if (nextchar == '*')
|
||||||
|
{
|
||||||
|
commenttype = COMMENT_BLOCK;
|
||||||
|
comment = Range(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (commenttype == COMMENT_LINE)
|
||||||
|
{
|
||||||
|
if (curchar == '\n')
|
||||||
|
{
|
||||||
|
commenttype = COMMENT_NONE;
|
||||||
|
comment.last = i;
|
||||||
|
comments.push_back(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (commenttype == COMMENT_BLOCK)
|
||||||
|
{
|
||||||
|
if (curchar == '/' && i > 0 && srcbytes[i - 1] == '*')
|
||||||
|
{
|
||||||
|
commenttype = COMMENT_NONE;
|
||||||
|
comment.last = i;
|
||||||
|
comments.push_back(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commenttype == COMMENT_LINE)
|
||||||
|
{
|
||||||
|
comment.last = len - 1;
|
||||||
|
comments.push_back(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool inComment(size_t i, const std::vector<Range> &comments)
|
||||||
|
{
|
||||||
|
Range r(i, 1);
|
||||||
|
|
||||||
|
for (const Range &comment : comments)
|
||||||
|
{
|
||||||
|
if (comment.contains(r))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool textSearch(const std::string &src, const std::string &str, const std::vector<Range> &comments)
|
||||||
|
{
|
||||||
|
size_t start = 0;
|
||||||
|
size_t found = std::string::npos;
|
||||||
|
|
||||||
|
while ((found = src.find(str, start)) != std::string::npos)
|
||||||
|
{
|
||||||
|
if (!inComment(found, comments))
|
||||||
|
return true;
|
||||||
|
start = found + str.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool regexSearch(const std::string &src, const std::string &rstr, const std::vector<Range> &comments)
|
||||||
|
{
|
||||||
|
std::regex r(rstr);
|
||||||
|
|
||||||
|
for (auto it = std::sregex_iterator(src.begin(), src.end(), r); it != std::sregex_iterator(); it++)
|
||||||
|
{
|
||||||
|
const std::smatch &m = *it;
|
||||||
|
if (!inComment(m.position(), comments))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static Shader::Language getTargetLanguage(const std::string &src)
|
static Shader::Language getTargetLanguage(const std::string &src)
|
||||||
{
|
{
|
||||||
std::regex r("^\\s*#pragma language (\\w+)");
|
std::regex r("^\\s*#pragma language (\\w+)");
|
||||||
@@ -435,33 +541,30 @@ static Shader::Language getTargetLanguage(const std::string &src)
|
|||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Shader::EntryPoint getVertexEntryPoint(const std::string &src)
|
static Shader::EntryPoint getVertexEntryPoint(const std::string &src, const std::vector<Range> &comments)
|
||||||
{
|
{
|
||||||
std::smatch m;
|
if (regexSearch(src, "void\\s+vertexmain\\s*\\(", comments))
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("void\\s+vertexmain\\s*\\(")))
|
|
||||||
return Shader::ENTRYPOINT_RAW;
|
return Shader::ENTRYPOINT_RAW;
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("vec4\\s+position\\s*\\(")))
|
if (regexSearch(src, "vec4\\s+position\\s*\\(", comments))
|
||||||
return Shader::ENTRYPOINT_HIGHLEVEL;
|
return Shader::ENTRYPOINT_HIGHLEVEL;
|
||||||
|
|
||||||
return Shader::ENTRYPOINT_NONE;
|
return Shader::ENTRYPOINT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Shader::EntryPoint getPixelEntryPoint(const std::string &src, bool &mrt)
|
static Shader::EntryPoint getPixelEntryPoint(const std::string &src, const std::vector<Range> &comments, bool &mrt)
|
||||||
{
|
{
|
||||||
mrt = false;
|
mrt = false;
|
||||||
std::smatch m;
|
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("void\\s+pixelmain\\s*\\(")))
|
if (regexSearch(src, "void\\s+pixelmain\\s*\\(", comments))
|
||||||
return Shader::ENTRYPOINT_RAW;
|
return Shader::ENTRYPOINT_RAW;
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("vec4\\s+effect\\s*\\(")))
|
if (regexSearch(src, "vec4\\s+effect\\s*\\(", comments))
|
||||||
return Shader::ENTRYPOINT_HIGHLEVEL;
|
return Shader::ENTRYPOINT_HIGHLEVEL;
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("void\\s+effect\\s*\\(")))
|
if (regexSearch(src, "void\\s+effect\\s*\\(", comments))
|
||||||
{
|
{
|
||||||
if (src.find("love_RenderTargets") != std::string::npos || src.find("love_Canvases") != std::string::npos)
|
if (textSearch(src, "love_RenderTargets", comments) || textSearch(src, "love_Canvases", comments))
|
||||||
mrt = true;
|
mrt = true;
|
||||||
return Shader::ENTRYPOINT_CUSTOM;
|
return Shader::ENTRYPOINT_CUSTOM;
|
||||||
}
|
}
|
||||||
@@ -469,10 +572,9 @@ static Shader::EntryPoint getPixelEntryPoint(const std::string &src, bool &mrt)
|
|||||||
return Shader::ENTRYPOINT_NONE;
|
return Shader::ENTRYPOINT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Shader::EntryPoint getComputeEntryPoint(const std::string &src) {
|
static Shader::EntryPoint getComputeEntryPoint(const std::string &src, const std::vector<Range> &comments)
|
||||||
std::smatch m;
|
{
|
||||||
|
if (regexSearch(src, "void\\s+computemain\\s*\\(", comments))
|
||||||
if (std::regex_search(src, m, std::regex("void\\s+computemain\\s*\\(")))
|
|
||||||
return Shader::ENTRYPOINT_RAW;
|
return Shader::ENTRYPOINT_RAW;
|
||||||
|
|
||||||
return Shader::ENTRYPOINT_NONE;
|
return Shader::ENTRYPOINT_NONE;
|
||||||
@@ -489,11 +591,14 @@ Shader *Shader::standardShaders[Shader::STANDARD_MAX_ENUM] = {nullptr};
|
|||||||
|
|
||||||
Shader::SourceInfo Shader::getSourceInfo(const std::string &src)
|
Shader::SourceInfo Shader::getSourceInfo(const std::string &src)
|
||||||
{
|
{
|
||||||
|
std::vector<Range> comments;
|
||||||
|
glsl::parseComments(src, comments);
|
||||||
|
|
||||||
SourceInfo info = {};
|
SourceInfo info = {};
|
||||||
info.language = glsl::getTargetLanguage(src);
|
info.language = glsl::getTargetLanguage(src);
|
||||||
info.stages[SHADERSTAGE_VERTEX] = glsl::getVertexEntryPoint(src);
|
info.stages[SHADERSTAGE_VERTEX] = glsl::getVertexEntryPoint(src, comments);
|
||||||
info.stages[SHADERSTAGE_PIXEL] = glsl::getPixelEntryPoint(src, info.usesMRT);
|
info.stages[SHADERSTAGE_PIXEL] = glsl::getPixelEntryPoint(src, comments, info.usesMRT);
|
||||||
info.stages[SHADERSTAGE_COMPUTE] = glsl::getComputeEntryPoint(src);
|
info.stages[SHADERSTAGE_COMPUTE] = glsl::getComputeEntryPoint(src, comments);
|
||||||
if (info.stages[SHADERSTAGE_COMPUTE])
|
if (info.stages[SHADERSTAGE_COMPUTE])
|
||||||
info.language = LANGUAGE_GLSL4;
|
info.language = LANGUAGE_GLSL4;
|
||||||
return info;
|
return info;
|
||||||
|
|||||||
Reference in New Issue
Block a user