mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-03 14:20:21 +01:00
Validate shaders against GLSL 4.60 including compute stage
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
enum class logtype : unsigned int {
|
|
||||||
shader
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void ErrorLog(const std::string &, logtype const)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,2 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
g++ -std=c++17 -O2 -DSHADERVALIDATOR_STANDALONE ../ref/glad/src/glad.c ../gl/glsl_common.cpp ../gl/shader.cpp main.cpp -I../ref/glad/include -I../ref/glm -I. -o validateshaders
|
# Offline GLSL validator for shaders/ (the same preprocessing as gl::shader in the game, then glslangValidator).
|
||||||
|
#
|
||||||
|
# Requirements: g++ with C++20, glslangValidator in PATH (Debian/Ubuntu: apt install glslang-tools),
|
||||||
|
# submodule ref/glm (git submodule update --init ref/glm).
|
||||||
|
# Usage (Linux; build.sh works from any directory, validateshaders reads ../shaders/ so it runs from here):
|
||||||
|
# ci_shadervalidator/build.sh
|
||||||
|
# cd ci_shadervalidator && ./validateshaders
|
||||||
|
# Every .vert/.frag/.geom/.comp under shaders/ is checked twice (features on and off).
|
||||||
|
# Exit code is 0 when all shaders pass, 1 otherwise; failing shaders are listed at the end.
|
||||||
|
#
|
||||||
|
# The validator's own stdafx.h and utilities/{Globals,Logs}.h stand in for the game's headers,
|
||||||
|
# so the repository root must not be on the include path.
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
g++ -std=c++20 -O1 -DSHADERVALIDATOR_STANDALONE ../ref/glad/src/glad.c ../gl/glsl_common.cpp ../gl/shader.cpp main.cpp -I. -I../ref/glad/include -I../ref/glm -o validateshaders
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "../gl/shader.h"
|
#include "../gl/shader.h"
|
||||||
#include "../gl/glsl_common.h"
|
#include "../gl/glsl_common.h"
|
||||||
#include "Globals.h"
|
#include "utilities/Globals.h"
|
||||||
|
#include "utilities/Logs.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
_global Global;
|
_global Global;
|
||||||
|
|
||||||
bool check_shader(std::string filename)
|
bool check_shader(std::string filename)
|
||||||
{
|
{
|
||||||
gl::shader shader_processor;
|
gl::shader shader_processor;
|
||||||
|
shader_processor.name = filename;
|
||||||
|
|
||||||
gl::glsl_common_setup();
|
gl::glsl_common_setup();
|
||||||
std::pair<GLuint, std::string> source = shader_processor.process_source(filename, "../shaders/");
|
std::pair<GLuint, std::string> source = shader_processor.process_source(filename, "../shaders/");
|
||||||
@@ -23,9 +26,17 @@ bool check_shader(std::string filename)
|
|||||||
stage = "frag";
|
stage = "frag";
|
||||||
else if (source.first == GL_GEOMETRY_SHADER)
|
else if (source.first == GL_GEOMETRY_SHADER)
|
||||||
stage = "geom";
|
stage = "geom";
|
||||||
|
else if (source.first == GL_COMPUTE_SHADER)
|
||||||
|
stage = "comp";
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ErrorLogged)
|
||||||
|
{
|
||||||
|
ErrorLogged = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::ofstream file("/tmp/shader");
|
std::ofstream file("/tmp/shader");
|
||||||
file << source.second;
|
file << source.second;
|
||||||
file.close();
|
file.close();
|
||||||
@@ -80,24 +91,38 @@ bool check_shader_confs(std::string filename)
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
if (system("glslangValidator --version > /dev/null 2>&1") != 0)
|
||||||
|
{
|
||||||
|
std::cerr << "glslangValidator not found in PATH" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool suc = true;
|
bool suc = true;
|
||||||
|
std::vector<std::string> failed;
|
||||||
for (auto &f : std::filesystem::recursive_directory_iterator("../shaders/")) {
|
for (auto &f : std::filesystem::recursive_directory_iterator("../shaders/")) {
|
||||||
if (!f.is_regular_file())
|
if (!f.is_regular_file())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string relative = std::filesystem::relative(f.path(), "../shaders/").string();
|
std::string relative = std::filesystem::relative(f.path(), "../shaders/").string();
|
||||||
if (f.path().extension() != ".frag" && f.path().extension() != ".geom" && f.path().extension() != ".vert")
|
auto const ext = f.path().extension();
|
||||||
|
if (ext != ".frag" && ext != ".geom" && ext != ".vert" && ext != ".comp")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::cout << "== validating shader " << relative << ": " << std::flush;
|
std::cout << "== validating shader " << relative << ": " << std::flush;
|
||||||
if (!check_shader_confs(relative))
|
if (!check_shader_confs(relative))
|
||||||
|
{
|
||||||
suc = false;
|
suc = false;
|
||||||
|
failed.push_back(relative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suc)
|
if (suc)
|
||||||
std::cout << "==== all checks ok" << std::endl;
|
std::cout << "==== all checks ok" << std::endl;
|
||||||
else {
|
else {
|
||||||
std::cout << "==== checks failed" << std::endl;
|
std::cout << "==== checks failed:";
|
||||||
|
for (auto const &name : failed)
|
||||||
|
std::cout << " " << name;
|
||||||
|
std::cout << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
ci_shadervalidator/utilities/Logs.h
Normal file
16
ci_shadervalidator/utilities/Logs.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class logtype : unsigned int {
|
||||||
|
shader
|
||||||
|
};
|
||||||
|
|
||||||
|
// gl::shader reports #texture/#param parse errors through ErrorLog; the validator counts them as failures
|
||||||
|
inline bool ErrorLogged = false;
|
||||||
|
|
||||||
|
inline void ErrorLog(const std::string &str, logtype const)
|
||||||
|
{
|
||||||
|
std::cerr << str << std::endl;
|
||||||
|
ErrorLogged = true;
|
||||||
|
}
|
||||||
@@ -86,6 +86,8 @@ std::pair<GLuint, std::string> gl::shader::process_source(const std::string &fil
|
|||||||
type = GL_FRAGMENT_SHADER;
|
type = GL_FRAGMENT_SHADER;
|
||||||
else if (strcend(filename, ".geom"))
|
else if (strcend(filename, ".geom"))
|
||||||
type = GL_GEOMETRY_SHADER;
|
type = GL_GEOMETRY_SHADER;
|
||||||
|
else if (strcend(filename, ".comp"))
|
||||||
|
type = GL_COMPUTE_SHADER;
|
||||||
else
|
else
|
||||||
throw shader_exception("unknown shader " + filename);
|
throw shader_exception("unknown shader " + filename);
|
||||||
|
|
||||||
@@ -96,6 +98,7 @@ std::pair<GLuint, std::string> gl::shader::process_source(const std::string &fil
|
|||||||
if (type == GL_VERTEX_SHADER) str += "#define STAGE_VERTEX 1\n";
|
if (type == GL_VERTEX_SHADER) str += "#define STAGE_VERTEX 1\n";
|
||||||
else if (type == GL_FRAGMENT_SHADER) str += "#define STAGE_FRAGMENT 1\n";
|
else if (type == GL_FRAGMENT_SHADER) str += "#define STAGE_FRAGMENT 1\n";
|
||||||
else if (type == GL_GEOMETRY_SHADER) str += "#define STAGE_GEOMETRY 1\n";
|
else if (type == GL_GEOMETRY_SHADER) str += "#define STAGE_GEOMETRY 1\n";
|
||||||
|
else if (type == GL_COMPUTE_SHADER) str += "#define STAGE_COMPUTE 1\n";
|
||||||
str += "vec4 FBOUT(vec4 x) { return " + (Global.gfx_shadergamma ? std::string("vec4(pow(x.rgb, vec3(1.0 / 2.2)), x.a)") : std::string("x")) + "; }\n";
|
str += "vec4 FBOUT(vec4 x) { return " + (Global.gfx_shadergamma ? std::string("vec4(pow(x.rgb, vec3(1.0 / 2.2)), x.a)") : std::string("x")) + "; }\n";
|
||||||
|
|
||||||
str += read_file(basedir + filename);
|
str += read_file(basedir + filename);
|
||||||
|
|||||||
Reference in New Issue
Block a user