Skip to content

Commit

Permalink
old behaviour is back!
Browse files Browse the repository at this point in the history
  • Loading branch information
devshgraphicsprogramming committed Nov 28, 2023
1 parent edaed60 commit cc37325
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 76 deletions.
90 changes: 48 additions & 42 deletions include/nbl/asset/utils/IShaderCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,75 +26,81 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted

class NBL_API2 IIncludeLoader : public core::IReferenceCounted
{
public:
virtual std::optional<std::string> getInclude(const system::path& searchPath, const std::string& includeName) const = 0;
public:
struct found_t
{
system::path absolutePath = {};
std::string contents = {};

explicit inline operator bool() const {return !absolutePath.empty();}
};
virtual found_t getInclude(const system::path& searchPath, const std::string& includeName) const = 0;
};

class NBL_API2 IIncludeGenerator : public core::IReferenceCounted
{
public:
// ! if includeName doesn't begin with prefix from `getPrefix` this function will return an empty string
virtual std::optional<std::string> getInclude(const std::string& includeName) const;
public:
// ! if includeName doesn't begin with prefix from `getPrefix` this function will return an empty string
virtual IIncludeLoader::found_t getInclude(const std::string& includeName) const;

virtual std::string_view getPrefix() const = 0;
virtual std::string_view getPrefix() const = 0;

protected:
protected:

using HandleFunc_t = std::function<std::string(const std::string&)>;
virtual core::vector<std::pair<std::regex, HandleFunc_t>> getBuiltinNamesToFunctionMapping() const = 0;
using HandleFunc_t = std::function<std::string(const std::string&)>;
virtual core::vector<std::pair<std::regex,HandleFunc_t>> getBuiltinNamesToFunctionMapping() const = 0;

// ! Parses arguments from include path
// ! template is path/to/shader.hlsl/arg0/arg1/...
static core::vector<std::string> parseArgumentsFromPath(const std::string& _path);
// ! Parses arguments from include path
// ! template is path/to/shader.hlsl/arg0/arg1/...
static core::vector<std::string> parseArgumentsFromPath(const std::string& _path);
};

class NBL_API2 CFileSystemIncludeLoader : public IIncludeLoader
{
public:
CFileSystemIncludeLoader(core::smart_refctd_ptr<system::ISystem>&& system);
public:
CFileSystemIncludeLoader(core::smart_refctd_ptr<system::ISystem>&& system);

std::optional<std::string> getInclude(const system::path& searchPath, const std::string& includeName) const override;
IIncludeLoader::found_t getInclude(const system::path& searchPath, const std::string& includeName) const override;

protected:
core::smart_refctd_ptr<system::ISystem> m_system;
protected:
core::smart_refctd_ptr<system::ISystem> m_system;
};

class NBL_API2 CIncludeFinder : public core::IReferenceCounted
{
public:
CIncludeFinder(core::smart_refctd_ptr<system::ISystem>&& system);

// ! includes within <>
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within <> of the include preprocessing directive
std::optional<std::string> getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName) const;
public:
CIncludeFinder(core::smart_refctd_ptr<system::ISystem>&& system);

// ! includes within ""
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within "" of the include preprocessing directive
std::optional<std::string> getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName) const;
// ! includes within <>
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within <> of the include preprocessing directive
IIncludeLoader::found_t getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName) const;

inline core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader() const { return m_defaultFileSystemLoader; }
// ! includes within ""
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within "" of the include preprocessing directive
IIncludeLoader::found_t getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName) const;

void addSearchPath(const std::string& searchPath, const core::smart_refctd_ptr<IIncludeLoader>& loader);
inline core::smart_refctd_ptr<CFileSystemIncludeLoader> getDefaultFileSystemLoader() const { return m_defaultFileSystemLoader; }

void addGenerator(const core::smart_refctd_ptr<IIncludeGenerator>& generator);
void addSearchPath(const std::string& searchPath, const core::smart_refctd_ptr<IIncludeLoader>& loader);

protected:
void addGenerator(const core::smart_refctd_ptr<IIncludeGenerator>& generator);

std::optional<std::string> trySearchPaths(const std::string& includeName) const;
protected:
IIncludeLoader::found_t trySearchPaths(const std::string& includeName) const;

std::optional<std::string> tryIncludeGenerators(const std::string& includeName) const;
IIncludeLoader::found_t tryIncludeGenerators(const std::string& includeName) const;

struct LoaderSearchPath
{
core::smart_refctd_ptr<IIncludeLoader> loader = nullptr;
std::string searchPath = {};
};
struct LoaderSearchPath
{
core::smart_refctd_ptr<IIncludeLoader> loader = nullptr;
std::string searchPath = {};
};

std::vector<LoaderSearchPath> m_loaders;
std::vector<core::smart_refctd_ptr<IIncludeGenerator>> m_generators;
core::smart_refctd_ptr<CFileSystemIncludeLoader> m_defaultFileSystemLoader;
std::vector<LoaderSearchPath> m_loaders;
std::vector<core::smart_refctd_ptr<IIncludeGenerator>> m_generators;
core::smart_refctd_ptr<CFileSystemIncludeLoader> m_defaultFileSystemLoader;
};

enum class E_SPIRV_VERSION : uint32_t
Expand Down
10 changes: 6 additions & 4 deletions src/nbl/asset/utils/CGLSLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace nbl::asset::impl
if (std::filesystem::exists(name) && !reqBuiltin)
name = std::filesystem::absolute(name);

std::optional<std::string> result;
IShaderCompiler::IIncludeLoader::found_t result;
if (_type == shaderc_include_type_relative)
{
result = m_defaultIncludeFinder->getIncludeRelative(relDir, _requested_source);
Expand All @@ -87,16 +87,18 @@ namespace nbl::asset::impl
result = m_defaultIncludeFinder->getIncludeStandard(relDir, _requested_source);
}

if (!result) {
if (!result)
{
const char* error_str = "Could not open file";
res->content_length = strlen(error_str);
res->content = new char[res->content_length + 1u];
strcpy(const_cast<char*>(res->content), error_str);
res->source_name_length = 0u;
res->source_name = "";
}
else {
auto& res_str = *result;
else
{
auto res_str = std::move(result.contents);
//employ encloseWithinExtraInclGuards() in order to prevent infinite loop of (not necesarilly direct) self-inclusions while other # directives (incl guards among them) are disabled
IShaderCompiler::disableAllDirectivesExceptIncludes(res_str);
disableGlDirectives(res_str);
Expand Down
44 changes: 22 additions & 22 deletions src/nbl/asset/utils/IShaderCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,22 @@ std::string IShaderCompiler::preprocessShader(
return preprocessShader(std::move(code), stage, preprocessOptions);
}

std::optional<std::string> IShaderCompiler::IIncludeGenerator::getInclude(const std::string& includeName) const
auto IShaderCompiler::IIncludeGenerator::getInclude(const std::string& includeName) const -> IIncludeLoader::found_t
{
core::vector<std::pair<std::regex, HandleFunc_t>> builtinNames = getBuiltinNamesToFunctionMapping();

for (const auto& pattern : builtinNames)
if (std::regex_match(includeName, pattern.first))
if (std::regex_match(includeName,pattern.first))
{
if (auto contents=pattern.second(includeName); !contents.empty())
{
if(auto contents = pattern.second(includeName); !contents.empty())
return contents;
// Welcome, you've came to a very disused piece of code, please check the first parameter (path) makes sense!
_NBL_DEBUG_BREAK_IF(true);
return {includeName,contents};
}
}

return std::nullopt;
return {};
}

core::vector<std::string> IShaderCompiler::IIncludeGenerator::parseArgumentsFromPath(const std::string& _path)
Expand All @@ -148,7 +152,7 @@ core::vector<std::string> IShaderCompiler::IIncludeGenerator::parseArgumentsFrom
IShaderCompiler::CFileSystemIncludeLoader::CFileSystemIncludeLoader(core::smart_refctd_ptr<system::ISystem>&& system) : m_system(std::move(system))
{}

std::optional<std::string> IShaderCompiler::CFileSystemIncludeLoader::getInclude(const system::path& searchPath, const std::string& includeName) const
auto IShaderCompiler::CFileSystemIncludeLoader::getInclude(const system::path& searchPath, const std::string& includeName) const -> found_t
{
system::path path = searchPath / includeName;
if (std::filesystem::exists(path))
Expand All @@ -163,7 +167,7 @@ std::optional<std::string> IShaderCompiler::CFileSystemIncludeLoader::getInclude
future.acquire().move_into(f);
}
if (!f)
return std::nullopt;
return {};
const size_t size = f->getSize();

std::string contents(size, '\0');
Expand All @@ -172,7 +176,7 @@ std::optional<std::string> IShaderCompiler::CFileSystemIncludeLoader::getInclude
const bool success = bool(succ);
assert(success);

return contents;
return {f->getFileName(),std::move(contents)};
}

IShaderCompiler::CIncludeFinder::CIncludeFinder(core::smart_refctd_ptr<system::ISystem>&& system)
Expand All @@ -184,21 +188,21 @@ IShaderCompiler::CIncludeFinder::CIncludeFinder(core::smart_refctd_ptr<system::I
// ! includes within <>
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within <> of the include preprocessing directive
std::optional<std::string> IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName) const
auto IShaderCompiler::CIncludeFinder::getIncludeStandard(const system::path& requestingSourceDir, const std::string& includeName) const -> IIncludeLoader::found_t
{
if (auto contents = tryIncludeGenerators(includeName))
return contents;
if (auto contents = trySearchPaths(includeName))
return contents;
return m_defaultFileSystemLoader->getInclude(requestingSourceDir.string(), includeName);
return m_defaultFileSystemLoader->getInclude(requestingSourceDir.string(),includeName);
}

// ! includes within ""
// @param requestingSourceDir: the directory where the incude was requested
// @param includeName: the string within "" of the include preprocessing directive
std::optional<std::string> IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName) const
auto IShaderCompiler::CIncludeFinder::getIncludeRelative(const system::path& requestingSourceDir, const std::string& includeName) const -> IIncludeLoader::found_t
{
if (auto contents = m_defaultFileSystemLoader->getInclude(requestingSourceDir.string(), includeName))
if (auto contents = m_defaultFileSystemLoader->getInclude(requestingSourceDir.string(),includeName))
return contents;
return trySearchPaths(includeName);
}
Expand Down Expand Up @@ -226,19 +230,15 @@ void IShaderCompiler::CIncludeFinder::addGenerator(const core::smart_refctd_ptr<
m_generators.insert(found, generatorToAdd);
}

std::optional<std::string> IShaderCompiler::CIncludeFinder::trySearchPaths(const std::string& includeName) const
auto IShaderCompiler::CIncludeFinder::trySearchPaths(const std::string& includeName) const -> IIncludeLoader::found_t
{
for (const auto& itr : m_loaders)
{
if (auto contents = itr.loader->getInclude(itr.searchPath, includeName))
{
return contents;
}
}
return std::nullopt;
if (auto contents = itr.loader->getInclude(itr.searchPath,includeName))
return contents;
return {};
}

std::optional<std::string> IShaderCompiler::CIncludeFinder::tryIncludeGenerators(const std::string& includeName) const
auto IShaderCompiler::CIncludeFinder::tryIncludeGenerators(const std::string& includeName) const -> IIncludeLoader::found_t
{
// Need custom function because std::filesystem doesn't consider the parameters we use after the extension like CustomShader.hlsl/512/64
auto removeExtension = [](const std::string& str)
Expand Down Expand Up @@ -287,5 +287,5 @@ std::optional<std::string> IShaderCompiler::CIncludeFinder::tryIncludeGenerators
path = path.parent_path();
}

return std::nullopt;
return {};
}
14 changes: 6 additions & 8 deletions src/nbl/asset/utils/waveContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,11 @@ template<> inline bool boost::wave::impl::pp_iterator_functor<nbl::wave::context
std::string file_path(s);

// call the 'found_include_directive' hook function
if (ctx.get_hooks().found_include_directive(ctx.derived(),f,include_next))
if (ctx.get_hooks().found_include_directive(ctx.derived(),f,false))
return true; // client returned false: skip file to include
file_path = util::impl::unescape_lit(file_path);

std::optional<std::string> result;
IShaderCompiler::IIncludeLoader::found_t result;
auto* includeFinder = ctx.get_hooks().m_includeFinder;
if (includeFinder)
{
Expand All @@ -462,22 +462,20 @@ template<> inline bool boost::wave::impl::pp_iterator_functor<nbl::wave::context
return false;
}

ctx.located_include_content = std::move(*result);
ctx.located_include_content = std::move(result.contents);
// the new include file determines the actual current directory
// TODO: the found file can be in a completely different place
nbl::system::path abs_path = ctx.get_current_directory()/file_path;
ctx.set_current_directory(abs_path);
ctx.set_current_directory(result.absolutePath);

{
// preprocess the opened file
boost::shared_ptr<base_iteration_context_type> new_iter_ctx(
new iteration_context_type(ctx,abs_path.string().c_str(),act_pos,
new iteration_context_type(ctx,result.absolutePath.string().c_str(),act_pos,
boost::wave::enable_prefer_pp_numbers(ctx.get_language()),
is_system ? base_iteration_context_type::system_header :
base_iteration_context_type::user_header));

// call the include policy trace function
ctx.get_hooks().opened_include_file(ctx.derived(), file_path, abs_path.string(), is_system);
ctx.get_hooks().opened_include_file(ctx.derived(),file_path,result.absolutePath.string(),is_system);

// store current file position
iter_ctx->real_relative_filename = ctx.get_current_relative_filename().c_str();
Expand Down

0 comments on commit cc37325

Please sign in to comment.