Commit f61de7d5 authored by Johannes Braun's avatar Johannes Braun
Browse files

Using custom C preprocessor for GLSL. Huge compiling performance boost.

parent 6cb47e4d
......@@ -34,6 +34,7 @@ include(${EXTENSION_PATH}/setup/macros.cmake)
if(SYS_WINDOWS)
add_definitions("-DLOG_PLATFORM_WINDOWS")
endif()
add_definitions(-DMCPP_LIB=1)
collect_subdirectories(PROJECT_EXECUTABLES ${CMAKE_SOURCE_DIR}/src/executables)
collect_subdirectories(PROJECT_LIBRARIES ${CMAKE_SOURCE_DIR}/src/libraries)
......
#pragma once
void muuuh()
{
int kuh = 10;
}
\ No newline at end of file
......@@ -86,7 +86,6 @@ LightData sampleLight(const in Light light, const in Vertex vertex, const in vec
result.sample_succeeded = sampleLightRoutines[i](light, vertex.position.xyz, result.point_on_light, result.light_color, random_sample);
}
}
kleklekle;
vec3 non_normal_direction = result.point_on_light - vertex.position.xyz;
result.testing_distance = length(non_normal_direction);
result.shadow_test.direction = normalize(non_normal_direction);
......
#version 430
#line 3 "center_texture.frag"
#extension GL_ARB_bindless_texture : require
//in vec2 out_texcoord;
......
......@@ -63,32 +63,42 @@ struct Material
////
////////////////////////////////////////////////////////////////////
#define parameter3f(parameter, texcoord) (parameter.texture_available ? texture(parameter.texture, texcoord).rgb : parameter.value)
#define parameter1f(parameter, texcoord) (parameter.texture_available ? compMax(texture(parameter.texture, texcoord).rgb) : parameter.value)
vec3 parameter3f(const in ParameterColor parameter, const in vec2 texcoord)
{
return parameter.texture_available ? texture(parameter.texture, texcoord).rgb : parameter.value;
}
float parameter1f(const in ParameterFloat parameter, const in vec2 texcoord)
{
return parameter.texture_available ? compMax(texture(parameter.texture, texcoord).rgb) : parameter.value;
}
//#define parameter3f(parameter, texcoord) (parameter.texture_available ? texture(parameter.texture, texcoord).rgb : parameter.value)
//#define parameter1f(parameter, texcoord) (parameter.texture_available ? compMax(texture(parameter.texture, texcoord).rgb) : parameter.value)
vec3 getBase(const in Material material, const in vec2 texcoord)
{
return material.base.parameter3f(texcoord);
return parameter3f(material.base, texcoord);
}
float getEmission(const in Material material, const in vec2 texcoord)
{
return material.emission.parameter1f(texcoord);
return parameter1f(material.emission, texcoord);
}
float getRoughness(const in Material material, const in vec2 texcoord)
{
return material.roughness.parameter1f(texcoord);
return parameter1f(material.roughness, texcoord);
}
float getMetallic(const in Material material, const in vec2 texcoord)
{
return material.metallic.parameter1f(texcoord);
return parameter1f(material.metallic, texcoord);
}
float getTransmission(const in Material material, const in vec2 texcoord)
{
return material.transmission.parameter1f(texcoord);
return parameter1f(material.transmission, texcoord);
}
#endif //!INCLUDE_UTIL_MATERIAL_GLSL
#pragma once
#include "some_other_local.glsl"
void bleghud()
{
int oauilfdzsi = 0;
}
\ No newline at end of file
#ifndef INCLUDE_OTHER_LOCAL_GLSL
#define INCLUDE_OTHER_LOCAL_GLSL
#include "some_local.glsl"
#include <bla.glsl>
void blub()
{
int a = 0;
}
#endif //!INCLUDE_OTHER_LOCAL_GLSL
void thisisatest()
{
int baldbs = 234;
}
\ No newline at end of file
#version 450
struct meh{int blauyg;};
void bluh(int a, int b);
void blamm(int c){float m = 2;}
void blegh()
{
int alka = 20;
}
void main()
{
}
\ No newline at end of file
......@@ -7,5 +7,4 @@ set(ROOT_PATH ${CMAKE_SOURCE_DIR})
#Assets
#add_definitions(-DASSETS_PATH="${ROOT_PATH}/assets/")
#file(MAKE_DIRECTORY "${ROOT_PATH}/assets")
message("Set necessary path definitions.")
\ No newline at end of file
......@@ -16,8 +16,10 @@ MACRO(make_executable result directory)
ENDMACRO()
MACRO(make_library result directory list_to_append_to)
file(GLOB_RECURSE SOURCE ${directory}/*.cpp)
file(GLOB_RECURSE SOURCEcpp ${directory}/*.cpp)
file(GLOB_RECURSE SOURCEc ${directory}/*.c)
file(GLOB_RECURSE SOURCEdef ${directory}/*.def)
file(GLOB_RECURSE HEADERS ${directory}/*.h)
add_library(${result} ${SOURCE} ${HEADERS})
add_library(${result} ${SOURCEcpp} ${SOURCEc} ${SOURCEdef} ${HEADERS})
list(APPEND ${list_to_append_to} ${result})
ENDMACRO()
\ No newline at end of file
#include "glsl.h"
#include <util/log.h>
#include "core/state.h"
#include "util/files.h"
#include <string>
#include "core/base/glsl.h"
#include <mcpp_glsl/mcpp_glsl.h>
#include <core/state.h>
std::string preprocessGlsl(const fs::path& shader, const std::vector<std::string>& include_paths)
{
mcpp::mcpp_use_mem_buffers(1);
std::vector<const char*> args;
args.push_back("mcpp");
auto path = shader.string();
args.push_back(path.c_str());
for (const auto& inc : include_paths)
{
args.push_back("-I");
args.push_back(inc.c_str());
}
mcpp::mcpp_lib_main(static_cast<int>(args.size()), const_cast<char**>(args.data()));
char* result = mcpp::mcpp_get_mem_buffer(mcpp::OUT);
// Now we just have to revert the order of #version and the first #line
std::string line;
bool ln_name = false;
while (*(++result) != '\n')
{
if (*result == '"')
ln_name = true;
if (ln_name)
line += *result;
}
std::string src(result + 1);
auto it = src.begin();
for (; *it != '\n'; ++it)
{
}
line = "\n#line 2 " + line;
src.insert(it, line.begin(), line.end());
glare::core::GLSLParser::format(src);
return src;
}
int main(int argc, char* argv[])
{
glare::core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
glare::core::GLSLParser parser(files::asset("shaders/pathtracer/pathtracer.comp"));
std::string src = parser.get();
auto src = preprocessGlsl(files::asset("shaders/pathtracer/pathtracer.comp"), std::vector<std::string>{ files::asset("shaders").string() });
auto shader = std::make_shared<glare::core::Shader>(gl::ShaderType::eCompute, parser.get(), "pathtracer");
glare::core::Program program(shader);
auto sh = std::make_shared<glare::core::Shader>(gl::ShaderType::eCompute, src, "aosidjsdi");
glare::core::Program program(sh);
return 0;
}
#include "glsl.h"
#include <mcpp_glsl/mcpp_glsl.h>
#include <core/state.h>
namespace glare::core
{
std::string GLSLParser::preprocess(const fs::path& shader, const std::vector<std::string>& include_paths)
{
mcpp::mcpp_use_mem_buffers(1);
std::vector<const char*> args;
args.push_back("mcpp");
auto path = shader.string();
args.push_back(path.c_str());
for (const auto& inc : include_paths)
{
args.push_back("-I");
args.push_back(inc.c_str());
}
mcpp::mcpp_lib_main(static_cast<int>(args.size()), const_cast<char**>(args.data()));
char* result = mcpp::mcpp_get_mem_buffer(mcpp::OUT);
char* version = "#version";
std::string line;
if (strncmp(result, version, strlen(version)) != 0)
{
// Now we just have to revert the order of #version and the first #line
bool ln_name = false;
while (*(++result) != '\n')
{
if (*result == '"')
ln_name = true;
if (ln_name)
line += *result;
}
while (*(result) != '#') ++result;
}
else
{
line = "\"" + path + "\"";
}
std::string src(result);
if (src[0] == '\n')
Log_Info << "di";
auto it = src.begin();
for (; *it != '\n'; ++it)
{
}
line = "\n#line 2 " + line;
src.insert(it, line.begin(), line.end());
format(src);
return src;
}
void GLSLParser::format(std::string &source)
{
const auto endOfCall = [](char c, bool backtrace)
{
return (c == ';' || c == '=' || c == '?' || c == '!' || c == ' ' || c == '\n' || c == ':' || c == ',' || c == '<' || c == '>' || (backtrace && (c == '(')) || (!backtrace && (c == '[' || c == ']')) || c == ')' || c == '%' || c == '/' || c == '+' || c == '-' || c == '*');
};
std::string &content = source;
enum class state_t
{
eIdle = 0,
eExpression = 1
};
state_t state = state_t::eIdle;
std::string expression_name = "";
for (unsigned pos = 0; pos < content.length(); ++pos)
{
const char c = content[pos];
if (c == '.') {
state = state_t::eExpression;
expression_name.clear();
continue;
}
if (state == state_t::eExpression) {
if (endOfCall(c, false)) {
state = state_t::eIdle;
}
else if (c == '(' && expression_name != "length")
{
const bool empty_call = content[pos + 1] == ')';
const size_t exp_length = expression_name.length();
unsigned temp_pos = pos - 2 - static_cast<unsigned>(exp_length);
char last = content[temp_pos];
std::string object;
while (!endOfCall(last, true)) {
object = last + object;
last = content[--temp_pos];
}
content = content.erase(temp_pos + 1, object.length() + 1);
content = content.insert(temp_pos + 2 + exp_length, object + (empty_call ? "" : ","));
pos = temp_pos;
state = state_t::eIdle;
}
else
{
expression_name += c;
}
continue;
}
}
}
}
#ifndef INCLUDE_GLSL_H
#define INCLUDE_GLSL_H
#include <util/files.h>
#include <string>
#include <map>
#include <vector>
namespace glare::core
{
class GLSLParser
{
public:
static std::string preprocess(const fs::path& shader, const std::vector<std::string>& include_paths);
private:
static void format(std::string& src);
};
}
#endif //!INCLUDE_GLSL_H
\ No newline at end of file
......@@ -14,7 +14,7 @@ namespace glare::core
{}
Shader::Shader(gl::ShaderType shader_type, const fs::path& path)
: Shader(shader_type, GLSLParser(path).get(), path.string())
: Shader(shader_type, GLSLParser::preprocess(path, std::vector<std::string>{ files::asset("shaders").string() }), path.string())
{}
Shader::Shader(gl::ShaderType shader_type, const std::string &source, const std::string& identifier)
......
/*
* cc1.c: dummy cc1 and cc1plus to be invoked by MinGW's GCC
* MinGW's GCC does not invoke shell-script named cc1.
*/
#include "stdio.h"
#include "string.h"
#include "process.h"
#define ARG_LIM 64
int exec_program( int argc, char ** argv);
int main( int argc, char ** argv) {
int status;
if (argc - 1 >= ARG_LIM) {
fprintf( stderr, "Too many arguments.\n");
return 1;
}
status = exec_program( argc, argv);
/* MinGW does not have fork() nor wait(). */
return status;
}
int exec_program( int argc, char ** argv) {
char * buf[ ARG_LIM];
char temp[ FILENAME_MAX];
char * tp;
int plus = 0;
int n = 1;
int i;
int status;
size_t len;
if (strstr( argv[ 0], "cc1plus"))
plus = 1; /* C++ */
tp = strstr( argv[ 0], "cc1");
len = tp - argv[ 0];
memcpy( temp, argv[ 0], len);
temp[ len] = '\0';
tp = temp + len;
for (i = 1; i < argc; i++)
if ((strcmp( argv[ i], "-fpreprocessed") == 0)
|| (strncmp( argv[ i], "-traditional", 12) == 0))
break; /* Invoke cc1 or cc1plus */
if (i < argc) {
strcpy( tp, plus ? "cc1plus_gnuc.exe" : "cc1_gnuc.exe");
} else { /* Invoke mcpp */
strcpy( tp, "mcpp.exe");
if (plus)
buf[ n++] = "-+"; /* Insert the option */
}
buf[ 0] = temp;
for (i = 1; i < argc; i++, n++)
buf[ n] = argv[ i];
buf[ n] = NULL;
status = spawnv( _P_WAIT, buf[ 0], buf);
return status;
}
/*
* configed.H
* Configurations for MCPP using config.h genarated by configure script.
*
* WARNING: These settings assume HOST == TARGET. In case of HOST
* differs from TARGET, you must edit this file here and there.
*/
#define TRUE 1
#define FALSE 0
#define DATE "2008/11" /* Date of mcpp */
/*
* 'Target' means the O.S. and the compiler to which cpp is implemented.
* 'Host' means the O.S. and the compiler with which cpp is compiled.
*/
#include "config.h"
#ifndef COMPILER /* No target compiler specified */
#define COMPILER COMPILER_UNKNOWN
#endif
#ifndef HOST_COMPILER /* No host compiler specified */
#define HOST_COMPILER COMPILER
#endif
/*
* P A R T 1 Configurations for target-operating-system
* and target-compiler.
*/
/*
* Names of the SYSTEM (i.e. target operating system). This is needed so that
* cpp can use appropriate filename conventions.
*/
#define SYS_UNKNOWN 0
#define SYS_UNIX 0x1000
#define SYS_LINUX 0x1800 /* (SYS_LINUX & 0xF000) == SYS_UNIX */
#define SYS_FREEBSD 0x1A00 /* (SYS_FREEBSD & 0xF000) == SYS_UNIX */
#define SYS_CYGWIN 0x1C00 /* (SYS_CYGWIN & 0xF000) == SYS_UNIX */
#define SYS_MAC 0x1E00 /* (SYS_MAC & 0xF000) == SYS_UNIX */
#define SYS_WIN 0x7000
#define SYS_WIN32 0x7400 /* (SYS_WIN32 & 0xF000) == SYS_WIN */
#define SYS_MINGW 0x7C00 /* (SYS_MINGW & 0xF000) == SYS_WIN */
/* COMPILER */
#define COMPILER_UNKNOWN 0
#define MSC 0x7400 /* Microsoft C, Visual C++ */
#define BORLANDC 0x7440 /* Borland C */
#define WIN_SYMANTECC 0x7470 /* Symantec for Windows */
#define LCC 0x74C0 /* LCC-Win32 */
#define GNUC 0x00E0 /* GNU C (GCC) */
#define INDEPENDENT 0xFFFF /* No target, compiler-independent-build*/
#define SYS_FAMILY (SYSTEM & 0xF000)
#define COMPILER_FAMILY (COMPILER & 0xF0)
#define HOST_SYS_FAMILY (HOST_SYSTEM & 0xF000)
/* Default MBCHAR (multi-byte character) encoding. */
#define EUC_JP 0x10 /* Extended UNIX code of JIS X 0208 */
#define GB2312 0x20 /* EUC-like encoding of Chinese GB 2312-80 */
#define KSC5601 0x30 /* EUC-like encoding of Korean KS C 5601 */
#define SJIS 0x80 /* Shift-JIS encoding of JIS X 0208 */
#define BIGFIVE 0x90 /* Encoding of Taiwanese Big Five */
#define ISO2022_JP 0x100 /* ISO-2022-JP (ISO-2022-JP1) encoding */
#define UTF8 0x1000 /* UTF-8 encoding */
/*
* MBCHAR means multi-byte character encoding.
* MBCHAR means the default encoding, and you can change the encoding by
* #pragma MCPP setlocale, -e <encoding> option or environment variable
* LC_ALL, LC_CTYPE, LANG.
* MBCHAR == 0 means not to recognize any multi-byte character encoding.
*/
/*
* In order to predefine target-dependent macros,
* several macros are defined here:
* *_OLD define the macro beginning with an alphabetic letter,
* *_STD, *_STD?, *_EXT, *_EXT2 define the macro beginning with an '_'.
* *_STD1 define the macro beginning with '__' and ending with an alpha-
* numeric letter.
* *_STD2 define the macro beginning with '__' and ending with '__'.
* These may not be defined, if they are not needed.
* They should not be #defined to no token or to "".
*
* SYSTEM_OLD, SYSTEM_STD1, SYSTEM_STD2, SYSTEM_EXT, SYSTEM_EXT2
* define the target operating system (by name).
* SYSTEM_SP_OLD, SYSTEM_SP_STD define the target-OS specific macro name
* COMPILER_OLD, COMPILER_STD1, COMPILER_STD2, COMPILER_EXT, COMPILER_EXT2
* , COMPILER_SP_OLD, COMPILER_SP_STD
* define the target compiler (by name).
* COMPILER_CPLUS defines the target C++ compiler.
* COMPILER_SP1, COMPILER_SP2, COMPILER_SP3
* define the compiler-specific macros.
*
* <macro>_VAL specify the value of the <macro>.
* If not specified, these values default to "1".
* To define the value of no-token, specify as "" rather than no-token.
* SYSTEM_OLD, SYSTEM_STD?, COMPILER_OLD have the value of "1".
*/
/*
* target-compiler-dependent definitions:
*
* LINE_PREFIX defines the output line prefix, if not "#line 123".
* This should be defined as "# " to represent "# 123" format
* ("#line " represents "#line 123" format).
*
* ENV_C_INCLUDE_DIR may be defined to the name of environment-variable for
* C include directory.
* ENV_CPLUS_INCLUDE_DIR is name of environment-variable for C++ include
* directory which exists other than ENV_C_INCLUDE_DIR.
* ENV_SEP is the separator (other than space) of include-paths in an
* environment-variable. e.g. the ':' in
* "/usr/abc/include:/usr/xyz/include"
*
* EMFILE should be defined to the macro to represent errno of 'too many
* open files' if the macro is different from EMFILE.
*
* ONE_PASS should be set TRUE, if COMPILER is "one pass compiler".
*
* FNAME_FOLD means that target-system folds upper and lower cases of
* directory and file-name.
*
* SEARCH_INIT specifies the default value of 'search_rule' (in system.c).
* 'search_rule' holds searching rule of #include "header.h" to
* search first before searching user specified or system-
* specific include directories.
* CURRENT means to search the directory relative to "current
* directory" which is current at cpp invocation.
* SOURCE means to search the directory relative to that of the
* source file (i.e. "includer").
* (CURRENT & SOURCE) means to search current directory first
* source directory next.
* 'search_rule' is initialized to SEARCH_INIT.
*/
#define CURRENT 1
#define SOURCE 2
#if SYS_FAMILY == SYS_UNIX
#define SYSTEM_OLD "unix"
#define SYSTEM_STD1 "__unix"
#define SYSTEM_STD2 "__unix__"
#endif
#if SYSTEM == SYS_FREEBSD
#define SYSTEM_EXT "__FreeBSD__"
#endif
#if SYSTEM == SYS_LINUX
#define SYSTEM_EXT "__linux__"
#endif
#if SYSTEM == SYS_MAC
#define SYSTEM_EXT "__APPLE__"
#endif
#if SYSTEM == SYS_CYGWIN
#define SYSTEM_EXT "__CYGWIN__"
#if defined (__CYGWIN64__)
#define SYSTEM_EXT2 "__CYGWIN64__"
#else
#define SYSTEM_EXT2 "__CYGWIN32__"
#endif
#ifndef MBCHAR
#define MBCHAR SJIS
#endif
#endif
#if SYSTEM == SYS_MINGW
#define SYSTEM_EXT "__MINGW__"
#if defined (__MINGW64__)
#define SYSTEM_EXT2 "__MINGW64__"
#else
#define SYSTEM_EXT2 "__MINGW32__"
#endif
#ifndef MBCHAR
#define MBCHAR SJIS
#endif