2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-02-14 19:33:02 +00:00
This commit is contained in:
Jan Laupetin
2026-01-23 21:55:27 +00:00
parent 9c728e2dd5
commit bda33e7851
57 changed files with 1564 additions and 947 deletions

View File

@@ -9,11 +9,8 @@
#include "Gdt/AbstractGdtEntryReader.h"
#include "Gdt/IGdtQueryable.h"
#include "Pool/GlobalAssetPool.h"
#include "Techset/CommonTechsetCache.h"
#include "Techset/StateMap/StateMapFromTechniqueExtractor.h"
#include "Techset/StateMap/StateMapHandler.h"
#include "Techset/TechniqueFileReader.h"
#include "Techset/TechniqueStateMapCache.h"
#include "Techset/StateMap/TechniqueStateMapCache.h"
#include "Techset/TechsetCommon.h"
#include "Utils/Logging/Log.h"
@@ -28,6 +25,7 @@ using namespace IW4;
namespace
{
/*
class SkipMaterialException final : public std::exception
{
};
@@ -1328,6 +1326,7 @@ namespace
std::unique_ptr<techset::ICreatorIW4> m_techset_creator;
};
*/
class MaterialLoader final : public AssetCreator<AssetMaterial>
{
@@ -1341,6 +1340,8 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
return AssetCreationResult::NoAction();
/*
const auto* entry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
if (!entry)
return AssetCreationResult::NoAction();
@@ -1367,6 +1368,7 @@ namespace
}
return AssetCreationResult::Failure();
*/
}
private:

View File

@@ -6,11 +6,9 @@
#include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Shader/D3D9ShaderAnalyser.h"
#include "Shader/ShaderCommon.h"
#include "Techset/CommonTechsetCache.h"
#include "Techset/CommonTechsetLoader.h"
#include "Techset/StateMap/StateMapReader.h"
#include "Techset/TechniqueFileReader.h"
#include "Techset/TechniqueStateMapCache.h"
#include "Techset/StateMap/TechniqueStateMapCache.h"
#include "Techset/TechsetCommon.h"
#include "Utils/Alignment.h"
#include "Utils/Logging/Log.h"
@@ -32,6 +30,7 @@ using namespace std::string_literals;
namespace
{
/*
class LoadedTechnique
{
public:
@@ -407,7 +406,7 @@ namespace
if (arg1.m_arg.type == MTL_ARG_MATERIAL_VERTEX_CONST || arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_CONST
|| arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_SAMPLER)
return arg1.m_arg.u.codeSampler < arg2.m_arg.u.codeSampler;
return arg1.m_arg.u.nameHash < arg2.m_arg.u.nameHash;
return arg1.m_arg.dest < arg2.m_arg.dest;
});
@@ -1263,7 +1262,7 @@ namespace
TechniqueZoneLoadingState& m_zone_state;
techset::ICreatorIW4* m_techset_creator;
};
*/
class TechsetLoader final : public techset::ICreatorIW4
{
public:
@@ -1275,15 +1274,18 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
return AssetCreationResult::NoAction();
/*
bool failure = false;
const auto* techsetDefinition = LoadTechsetDefinition(assetName, context, failure);
if (!techsetDefinition)
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
return CreateTechsetFromDefinition(assetName, *techsetDefinition, context);
*/
}
private:
/*
AssetCreationResult CreateTechsetFromDefinition(const std::string& assetName, const CommonTechset& definition, AssetCreationContext& context)
{
auto* techset = m_memory.Alloc<MaterialTechniqueSet>();
@@ -1311,9 +1313,11 @@ namespace
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
*/
CommonTechset* LoadTechsetDefinition(const std::string& assetName, AssetCreationContext& context, bool& failure) override
{
/*
failure = false;
auto& definitionCache = context.GetZoneAssetCreationState<CommonTechsetCache>();
auto* cachedTechsetDefinition = definitionCache.GetCachedTechsetDefinition(assetName);
@@ -1334,10 +1338,13 @@ namespace
definitionCache.AddCommonTechsetToCache(assetName, std::move(techsetDefinition));
return techsetDefinitionPtr;
*/
return nullptr;
}
const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, AssetCreationContext& context) override
{
/*
auto& stateMapCache = context.GetZoneAssetCreationState<TechniqueStateMapCache>();
auto* cachedStateMap = stateMapCache.GetCachedStateMap(stateMapName);
if (cachedStateMap)
@@ -1358,6 +1365,8 @@ namespace
stateMapCache.AddStateMapToCache(std::move(stateMapDefinition));
return stateMapDefinitionPtr;
*/
return nullptr;
}
private:

View File

@@ -4,7 +4,9 @@
#include "Image/ImageIPakPostProcessor.h"
#include "Image/ImageIwdPostProcessor.h"
#include "KeyValuePairs/KeyValuePairsCompilerT6.h"
#include "Techset/TechniqueCompilerT6.h"
#include "Techset/TechsetCompilerT6.h"
#include "Techset/VertexDeclCompilerT6.h"
#include <memory>
@@ -22,6 +24,9 @@ namespace
collection.AddAssetCreator(key_value_pairs::CreateCompilerT6(memory, zone, zoneDefinition.m_zone_definition, zoneStates));
collection.AddAssetCreator(techset::CreateCompilerT6(memory, searchPath));
collection.AddSubAssetCreator(techset::CreateTechniqueCompilerT6(memory, searchPath));
collection.AddSubAssetCreator(techset::CreateVertexDeclCompilerT6(memory));
}
void ConfigurePostProcessors(AssetCreatorCollection& collection,

View File

@@ -0,0 +1,223 @@
#include "TechniqueCompilerT6.h"
#include "Game/T6/T6.h"
#include "Game/T6/Techset/TechsetConstantsT6.h"
#include "Techset/CommonShaderArgCreator.h"
#include "Techset/CommonTechniqueLoader.h"
#include "Utils/StringUtils.h"
#include <cassert>
#include <sstream>
using namespace T6;
namespace
{
void UpdateTechniqueFlags(MaterialTechnique& technique, const techset::CommonTechnique& commonTechnique)
{
std::string lowerTechniqueName(commonTechnique.m_name);
utils::MakeStringLowerCase(lowerTechniqueName);
// Not a particularly cool way to do this but...
// the game actually does this :shrug:
if (lowerTechniqueName == "zprepass" || lowerTechniqueName.starts_with("pimp_technique_zprepass_")
|| lowerTechniqueName.starts_with("pimp_technique_layer_zprepass_") || lowerTechniqueName.starts_with("pimp_technique_buildshadowmap_"))
{
technique.flags |= TECHNIQUE_FLAG_4;
}
}
void ConvertMaterialArgs(MaterialPass& pass, const techset::CommonPass& commonPass, MemoryManager& memory)
{
pass.args = memory.Alloc<MaterialShaderArgument>(commonPass.m_args.size());
size_t perObjArgCount = 0u;
size_t perPrimArgCount = 0u;
size_t stableArgCount = 0u;
size_t argIndex = 0u;
const auto frequencyCount = commonPass.GetFrequencyCounts(commonCodeSourceInfos);
for (const auto& arg : commonPass.m_args)
{
UpdateTechniqueFlagsForArgument(technique.flags, arg);
switch (arg.m_update_frequency)
{
case MTL_UPDATE_PER_PRIM:
perPrimArgCount++;
break;
case MTL_UPDATE_PER_OBJECT:
perObjArgCount++;
break;
case MTL_UPDATE_RARELY:
stableArgCount++;
break;
case MTL_UPDATE_CUSTOM:
{
assert(arg.m_arg.type == MTL_ARG_CODE_PIXEL_SAMPLER);
if (arg.m_arg.type == MTL_ARG_CODE_PIXEL_SAMPLER)
{
const auto customSampler = std::ranges::find(g_customSamplerSrc, arg.m_arg.u.codeSampler);
assert(customSampler != std::end(g_customSamplerSrc));
if (customSampler != std::end(g_customSamplerSrc))
{
const auto customSamplerIndex = customSampler - std::begin(g_customSamplerSrc);
out.customSamplerFlags |= 1 << customSamplerIndex;
}
}
}
continue;
default:
assert(false);
continue;
}
out.args[argIndex++] = arg.m_arg;
}
pass.perObjArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::PER_OBJECT)]);
pass.perPrimArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::PER_PRIM)]);
pass.stableArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::RARELY)]);
}
void ConvertVertexDecl(MaterialPass& pass, const techset::CommonVertexDeclaration& commonDecl, AssetCreationContext& context)
{
std::ostringstream nameStream;
for (const auto& entry : commonDecl.m_routing)
{
nameStream << commonRoutingInfos.GetSourceAbbreviation(entry.m_source);
nameStream << commonRoutingInfos.GetDestinationAbbreviation(entry.m_destination);
}
const std::string declName(nameStream.str());
auto* vertexDeclAsset = context.LoadSubAsset<SubAssetVertexDecl>(declName);
assert(vertexDeclAsset);
pass.vertexDecl = vertexDeclAsset ? vertexDeclAsset->Asset() : nullptr;
}
void ConvertMaterialPass(MaterialPass& pass, const techset::CommonPass& commonPass, AssetCreationContext& context, MemoryManager& memory)
{
ConvertVertexDecl(pass, commonPass.m_vertex_declaration, context);
if (!commonPass.m_vertex_shader.m_name.empty())
{
auto* vertexShaderAsset = context.LoadSubAsset<SubAssetVertexShader>(commonPass.m_vertex_shader.m_name);
assert(vertexShaderAsset);
pass.vertexShader = vertexShaderAsset ? vertexShaderAsset->Asset() : nullptr;
}
if (!commonPass.m_pixel_shader.m_name.empty())
{
auto* pixelShaderAsset = context.LoadSubAsset<SubAssetPixelShader>(commonPass.m_pixel_shader.m_name);
assert(pixelShaderAsset);
pass.pixelShader = pixelShaderAsset ? pixelShaderAsset->Asset() : nullptr;
}
}
MaterialTechnique* ConvertTechnique(const techset::CommonTechnique& commonTechnique, AssetCreationContext& context, MemoryManager& memory)
{
const auto additionalPassCount = std::max(commonTechnique.m_passes.size(), 1u) - 1u;
auto* technique = static_cast<MaterialTechnique*>(memory.AllocRaw(sizeof(MaterialTechnique) + additionalPassCount * sizeof(MaterialPass)));
const auto passCount = static_cast<decltype(MaterialTechnique::passCount)>(commonTechnique.m_passes.size());
technique->name = memory.Dup(commonTechnique.m_name.c_str());
// Take common flags and apply further logic
technique->flags = static_cast<decltype(MaterialTechnique::flags)>(commonTechnique.m_flags);
UpdateTechniqueFlags(*technique, commonTechnique);
technique->passCount = passCount;
for (auto passIndex = 0u; passIndex < passCount; passIndex++)
ConvertMaterialPass(technique->passArray[passIndex], commonTechnique.m_passes[passIndex], context, memory);
return technique;
}
class TechniqueShaderLoaderT6 final : public techset::ITechniqueShaderLoader
{
public:
explicit TechniqueShaderLoaderT6(AssetCreationContext& context)
: m_context(context)
{
}
std::optional<techset::CommonTechniqueShaderBin> LoadVertexShader(const std::string& name) override
{
auto* shaderAsset = m_context.LoadSubAsset<SubAssetVertexShader>(name);
if (!shaderAsset)
return std::nullopt;
const auto* shader = shaderAsset->Asset();
assert(shader->prog.loadDef.program && shader->prog.loadDef.programSize > 0);
if (!shader->prog.loadDef.program || shader->prog.loadDef.programSize == 0)
return std::nullopt;
return techset::CommonTechniqueShaderBin{
.m_shader_bin = shader->prog.loadDef.program,
.m_shader_bin_size = shader->prog.loadDef.programSize,
};
}
std::optional<techset::CommonTechniqueShaderBin> LoadPixelShader(const std::string& name) override
{
auto* shaderAsset = m_context.LoadSubAsset<SubAssetPixelShader>(name);
if (!shaderAsset)
return std::nullopt;
const auto* shader = shaderAsset->Asset();
assert(shader->prog.loadDef.program && shader->prog.loadDef.programSize > 0);
if (!shader->prog.loadDef.program || shader->prog.loadDef.programSize == 0)
return std::nullopt;
return techset::CommonTechniqueShaderBin{
.m_shader_bin = shader->prog.loadDef.program,
.m_shader_bin_size = shader->prog.loadDef.programSize,
};
}
private:
AssetCreationContext& m_context;
};
class TechniqueCompilerT6 final : public SubAssetCreator<SubAssetTechnique>
{
public:
TechniqueCompilerT6(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateSubAsset(const std::string& subAssetName, AssetCreationContext& context) override
{
bool failure = false;
TechniqueShaderLoaderT6 shaderLoader(context);
const auto commonShaderArgCreator = techset::CommonShaderArgCreator::CreateDx11(shaderLoader, context);
const auto commonTechnique =
techset::LoadCommonTechnique(subAssetName, commonCodeSourceInfos, commonRoutingInfos, *commonShaderArgCreator, m_search_path, failure);
if (!commonTechnique)
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
auto* convertedTechnique = ConvertTechnique(*commonTechnique, context, m_memory);
assert(convertedTechnique);
return AssetCreationResult::Success(context.AddSubAsset(AssetRegistration<SubAssetTechnique>(subAssetName, convertedTechnique)));
}
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace techset
{
std::unique_ptr<ISubAssetCreator> CreateTechniqueCompilerT6(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<TechniqueCompilerT6>(memory, searchPath);
}
} // namespace techset

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace techset
{
std::unique_ptr<ISubAssetCreator> CreateTechniqueCompilerT6(MemoryManager& memory, ISearchPath& searchPath);
}

View File

@@ -70,6 +70,19 @@ namespace
auto* techset = ConvertTechniqueSet(*commonTechset, m_memory);
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(MaterialTechniqueSet::techniques)>; techniqueIndex++)
{
const auto& techniqueName = commonTechset->m_technique_names[techniqueIndex];
if (techniqueName.empty())
continue;
auto* technique = context.LoadSubAsset<SubAssetTechnique>(techniqueName);
if (!technique)
return AssetCreationResult::Failure();
techset->techniques[techniqueIndex] = technique->Asset();
}
return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetTechniqueSet>(assetName, techset)));
}

View File

@@ -0,0 +1,57 @@
#include "VertexDeclCompilerT6.h"
#include "Game/T6/T6.h"
#include "Game/T6/Techset/TechsetConstantsT6.h"
#include "Techset/CommonVertexDeclCreator.h"
#include "Utils/Logging/Log.h"
using namespace T6;
namespace
{
class VertexDeclCompilerT6 final : public SubAssetCreator<SubAssetVertexDecl>
{
public:
explicit VertexDeclCompilerT6(MemoryManager& memory)
: m_memory(memory)
{
}
AssetCreationResult CreateSubAsset(const std::string& subAssetName, AssetCreationContext& context) override
{
const auto commonVertexDecl = techset::CreateVertexDeclFromName(subAssetName, commonRoutingInfos);
if (!commonVertexDecl)
return AssetCreationResult::Failure();
if (commonVertexDecl->m_routing.size() > std::extent_v<decltype(MaterialVertexStreamRouting::data)>)
{
con::error("Vertex declaration can only have up to {} routing entries", std::extent_v<decltype(MaterialVertexStreamRouting::data)>);
return AssetCreationResult::Failure();
}
auto* vertexDecl = m_memory.Alloc<MaterialVertexDeclaration>();
for (const auto& commonRoutingEntry : commonVertexDecl->m_routing)
{
vertexDecl->routing.data[vertexDecl->streamCount].source = commonRoutingEntry.m_source;
vertexDecl->routing.data[vertexDecl->streamCount].dest = commonRoutingEntry.m_destination;
vertexDecl->hasOptionalSource = vertexDecl->hasOptionalSource || commonRoutingEntry.m_source >= STREAM_SRC_OPTIONAL_BEGIN;
vertexDecl->streamCount++;
}
return AssetCreationResult::Success(context.AddSubAsset(AssetRegistration<SubAssetVertexDecl>(subAssetName, vertexDecl)));
}
private:
MemoryManager& m_memory;
};
} // namespace
namespace techset
{
std::unique_ptr<ISubAssetCreator> CreateVertexDeclCompilerT6(MemoryManager& memory)
{
return std::make_unique<VertexDeclCompilerT6>(memory);
}
} // namespace techset

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace techset
{
std::unique_ptr<ISubAssetCreator> CreateVertexDeclCompilerT6(MemoryManager& memory);
}

View File

@@ -0,0 +1,164 @@
#include "CommonShaderArgCreator.h"
#include <algorithm>
#include <cassert>
namespace
{
class BaseCommonShaderArgCreator : public techset::CommonShaderArgCreator
{
public:
explicit BaseCommonShaderArgCreator(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos)
: m_shader_loader(shaderLoader),
m_common_code_source_infos(commonCodeSourceInfos),
m_shader_type(techset::CommonTechniqueShaderType::VERTEX),
m_bin{}
{
}
result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override
{
m_shader_type = shaderType;
std::optional<techset::CommonTechniqueShaderBin> maybeShader;
if (shaderType == techset::CommonTechniqueShaderType::VERTEX)
{
maybeShader = m_shader_loader.LoadVertexShader(name);
}
else if (shaderType == techset::CommonTechniqueShaderType::PIXEL)
{
maybeShader = m_shader_loader.LoadPixelShader(name);
}
if (!maybeShader)
return result::Unexpected<std::string>("Failed to load shader");
m_bin = *maybeShader;
return NoResult{};
}
void LeaveShader() override
{
m_bin = {};
}
result::Expected<NoResult, std::string> AcceptShaderConstantArgument(const techset::CommonShaderArgCreatorDestination& destination,
techset::CommonCodeConstSource codeConstSource) override
{
return result::Unexpected<std::string>("Not implemented");
}
result::Expected<NoResult, std::string> AcceptShaderSamplerArgument(const techset::CommonShaderArgCreatorDestination& destination,
techset::CommonCodeSamplerSource codeSamplerSource) override
{
return result::Unexpected<std::string>("Not implemented");
}
result::Expected<NoResult, std::string> AcceptShaderLiteralArgument(const techset::CommonShaderArgCreatorDestination& destination,
const std::array<float, 4>& literalValue) override
{
return result::Unexpected<std::string>("Not implemented");
}
result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const techset::CommonShaderArgCreatorDestination& destination,
unsigned nameHash) override
{
return result::Unexpected<std::string>("Not implemented");
}
result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const techset::CommonShaderArgCreatorDestination& destination,
const std::string& nameValue) override
{
return result::Unexpected<std::string>("Not implemented");
}
result::Expected<std::vector<techset::CommonShaderArg>, std::string> FinalizeArgs() override
{
// TODO: Auto create remaining args
std::ranges::sort(m_args,
[this](const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) -> bool
{
const auto updateFreq0 = arg0.GetFrequency(m_common_code_source_infos);
const auto updateFreq1 = arg1.GetFrequency(m_common_code_source_infos);
if (updateFreq0 != updateFreq1)
return updateFreq0 < updateFreq1;
const auto typeNumeric0 = m_common_code_source_infos.GetArgumentTypeNumericValue(arg0.m_type);
const auto typeNumeric1 = m_common_code_source_infos.GetArgumentTypeNumericValue(arg1.m_type);
assert(typeNumeric0);
assert(typeNumeric1);
if (*typeNumeric0 != *typeNumeric1)
return *typeNumeric0 < *typeNumeric1;
if (arg0.m_type.m_value_type == techset::CommonShaderValueType::MATERIAL_CONST
|| arg0.m_type.m_value_type == techset::CommonShaderValueType::MATERIAL_SAMPLER)
{
return arg0.m_value.name_hash < arg1.m_value.name_hash;
}
return CompareArgumentDestinations(arg0.m_destination, arg1.m_destination);
});
return m_args;
}
protected:
[[nodiscard]] virtual size_t CompareArgumentDestinations(const techset::CommonShaderArgDestination& dest0,
const techset::CommonShaderArgDestination& dest1) const = 0;
techset::ITechniqueShaderLoader& m_shader_loader;
techset::CommonCodeSourceInfos& m_common_code_source_infos;
techset::CommonTechniqueShaderType m_shader_type;
techset::CommonTechniqueShaderBin m_bin;
std::vector<techset::CommonShaderArg> m_args;
};
class CommonShaderArgCreatorDx11 final : public BaseCommonShaderArgCreator
{
public:
explicit CommonShaderArgCreatorDx11(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos)
: BaseCommonShaderArgCreator(shaderLoader, commonCodeSourceInfos)
{
}
protected:
[[nodiscard]] size_t CompareArgumentDestinations(const techset::CommonShaderArgDestination& dest0,
const techset::CommonShaderArgDestination& dest1) const override
{
if (dest0.dx11.m_buffer != dest1.dx11.m_buffer)
return dest0.dx11.m_buffer < dest1.dx11.m_buffer;
return dest0.dx11.m_location < dest1.dx11.m_location;
}
};
} // namespace
namespace techset
{
CommonShaderArgCreatorDestination::CommonShaderArgCreatorDestination(std::string argumentName)
: m_argument_name(std::move(argumentName))
{
}
CommonShaderArgCreatorDestination::CommonShaderArgCreatorDestination(std::string argumentName, const unsigned argumentIndex)
: m_argument_name(std::move(argumentName)),
m_argument_index(argumentIndex)
{
}
std::unique_ptr<CommonShaderArgCreator> CommonShaderArgCreator::CreateDx9(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context)
{
// TODO
return nullptr;
}
std::unique_ptr<CommonShaderArgCreator>
CommonShaderArgCreator::CreateDx11(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos)
{
return std::make_unique<CommonShaderArgCreatorDx11>(shaderLoader, commonCodeSourceInfos);
}
} // namespace techset

View File

@@ -0,0 +1,61 @@
#pragma once
#include "Asset/AssetCreationContext.h"
#include "Techset/CommonTechnique.h"
#include "Utils/Result.h"
#include <array>
#include <memory>
#include <optional>
#include <string>
namespace techset
{
class ITechniqueShaderLoader
{
public:
ITechniqueShaderLoader() = default;
virtual ~ITechniqueShaderLoader() = default;
virtual std::optional<CommonTechniqueShaderBin> LoadVertexShader(const std::string& name) = 0;
virtual std::optional<CommonTechniqueShaderBin> LoadPixelShader(const std::string& name) = 0;
};
class CommonShaderArgCreatorDestination
{
public:
std::string m_argument_name;
std::optional<unsigned> m_argument_index;
CommonShaderArgCreatorDestination() = default;
explicit CommonShaderArgCreatorDestination(std::string argumentName);
CommonShaderArgCreatorDestination(std::string argumentName, unsigned argumentIndex);
};
class CommonShaderArgCreator
{
public:
CommonShaderArgCreator() = default;
virtual ~CommonShaderArgCreator() = default;
virtual result::Expected<NoResult, std::string> EnterShader(CommonTechniqueShaderType shaderType, const std::string& name) = 0;
virtual void LeaveShader() = 0;
virtual result::Expected<NoResult, std::string> AcceptShaderConstantArgument(const CommonShaderArgCreatorDestination& destination,
CommonCodeConstSource codeConstSource) = 0;
virtual result::Expected<NoResult, std::string> AcceptShaderSamplerArgument(const CommonShaderArgCreatorDestination& destination,
CommonCodeSamplerSource codeSamplerSource) = 0;
virtual result::Expected<NoResult, std::string> AcceptShaderLiteralArgument(const CommonShaderArgCreatorDestination& destination,
const std::array<float, 4>& literalValue) = 0;
virtual result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const CommonShaderArgCreatorDestination& destination,
unsigned nameHash) = 0;
virtual result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const CommonShaderArgCreatorDestination& destination,
const std::string& nameValue) = 0;
virtual result::Expected<std::vector<CommonShaderArg>, std::string> FinalizeArgs() = 0;
static std::unique_ptr<CommonShaderArgCreator> CreateDx9(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context);
static std::unique_ptr<CommonShaderArgCreator>
CreateDx11(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos);
};
} // namespace techset

View File

@@ -1 +1,47 @@
#include "CommonTechniqueLoader.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/ParserSingleInputStream.h"
#include "Parsing/Simple/SimpleLexer.h"
#include "Parsing/TechniqueFileParser.h"
#include "Techset/TechsetCommon.h"
#include "Utils/Logging/Log.h"
namespace techset
{
std::unique_ptr<CommonTechnique> LoadCommonTechnique(const std::string& techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& commonShaderArgCreator,
ISearchPath& searchPath,
bool& failure)
{
failure = false;
const auto fileName = GetFileNameForTechniqueName(techniqueName);
const auto techniqueFile = searchPath.Open(fileName);
if (!techniqueFile.IsOpen())
return nullptr;
SimpleLexer::Config lexerConfig;
lexerConfig.m_emit_new_line_tokens = false;
lexerConfig.m_read_strings = true;
lexerConfig.m_string_escape_sequences = false;
lexerConfig.m_read_integer_numbers = true;
lexerConfig.m_read_floating_point_numbers = true;
const auto baseStream = std::make_unique<ParserSingleInputStream>(*techniqueFile.m_stream, fileName);
const auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(baseStream.get());
const auto lexer = std::make_unique<SimpleLexer>(commentProxy.get(), std::move(lexerConfig));
const auto parser = std::make_unique<TechniqueParser>(*lexer, techniqueName, codeSourceInfos, routingInfos, commonShaderArgCreator);
const auto success = parser->Parse();
if (success)
return parser->GetParsingResult();
failure = true;
con::error("Parsing technique file \"{}\" failed!", fileName);
return nullptr;
}
} // namespace techset

View File

@@ -1,12 +1,18 @@
#pragma once
#include "Asset/AssetCreationContext.h"
#include "CommonShaderArgCreator.h"
#include "Techset/CommonTechnique.h"
#include <memory>
#include <string>
namespace techset
{
std::unique_ptr<CommonTechnique>
LoadCommonTechnique(const AssetCreationContext& context, const CommonCodeSourceInfos& codeSourceInfos, const CommonStreamRoutingInfos& routingInfos);
std::unique_ptr<CommonTechnique> LoadCommonTechnique(const std::string& techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& commonShaderArgCreator,
ISearchPath& searchPath,
bool& failure);
} // namespace techset

View File

@@ -1,18 +0,0 @@
#include "CommonTechsetCache.h"
using namespace techset;
CommonTechset* CommonTechsetCache::GetCachedTechsetDefinition(const std::string& techsetName) const
{
const auto foundTechset = m_cache.find(techsetName);
if (foundTechset != m_cache.end())
return foundTechset->second.get();
return nullptr;
}
void CommonTechsetCache::AddCommonTechsetToCache(std::string name, std::unique_ptr<CommonTechset> definition)
{
m_cache.emplace(std::make_pair(std::move(name), std::move(definition)));
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include "Asset/IZoneAssetCreationState.h"
#include "Techset/CommonTechset.h"
#include <memory>
#include <string>
#include <unordered_map>
namespace techset
{
class CommonTechsetCache final : public IZoneAssetCreationState
{
public:
[[nodiscard]] CommonTechset* GetCachedTechsetDefinition(const std::string& techsetName) const;
void AddCommonTechsetToCache(std::string name, std::unique_ptr<CommonTechset> definition);
private:
std::unordered_map<std::string, std::unique_ptr<CommonTechset>> m_cache;
};
} // namespace techset

View File

@@ -9,7 +9,6 @@
#include "Utils/Logging/Log.h"
#include <format>
#include <iostream>
#include <memory>
#include <string>

View File

@@ -23,10 +23,8 @@ namespace techset
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_in_pass == false);
state->m_in_pass = true;
state->m_acceptor->AcceptNextPass();
assert(!state->m_current_pass);
state->m_current_pass = CommonPass();
}
};
} // namespace techset

View File

@@ -26,20 +26,18 @@ namespace techset
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_in_pass == true);
assert(state->m_current_pass);
assert(state->m_technique);
std::string errorMessage;
if (!state->m_acceptor->AcceptEndPass(errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), errorMessage);
state->m_in_pass = false;
state->m_current_pass->m_vertex_declaration.SortRoutingEntries();
state->m_technique->m_passes.emplace_back(std::move(*state->m_current_pass));
state->m_current_pass = std::nullopt;
}
};
class SequenceStateMap final : public TechniqueParser::sequence_t
{
static constexpr auto CAPTURE_START = 1;
static constexpr auto CAPTURE_STATE_MAP_NAME = 2;
static constexpr auto CAPTURE_STATE_MAP_NAME = 1;
public:
SequenceStateMap()
@@ -47,7 +45,7 @@ namespace techset
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("stateMap").Capture(CAPTURE_START),
create.Keyword("stateMap"),
create.String().Capture(CAPTURE_STATE_MAP_NAME),
create.Char(';'),
});
@@ -56,13 +54,9 @@ namespace techset
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
const auto& firstToken = result.NextCapture(CAPTURE_START);
assert(state->m_current_pass);
std::string errorMessage;
const auto acceptorResult = state->m_acceptor->AcceptStateMap(result.NextCapture(CAPTURE_STATE_MAP_NAME).StringValue(), errorMessage);
if (!acceptorResult)
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
state->m_current_pass->m_state_map = result.NextCapture(CAPTURE_STATE_MAP_NAME).StringValue();
}
};
@@ -71,7 +65,7 @@ namespace techset
static constexpr auto TAG_VERTEX_SHADER = 1;
static constexpr auto TAG_PIXEL_SHADER = 2;
static constexpr auto CAPTURE_START = 1;
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
static constexpr auto CAPTURE_VERSION = 2;
static constexpr auto CAPTURE_VERSION_MAJOR = 3;
static constexpr auto CAPTURE_VERSION_MINOR = 4;
@@ -88,7 +82,7 @@ namespace techset
create.Keyword("vertexShader").Tag(TAG_VERTEX_SHADER),
create.Keyword("pixelShader").Tag(TAG_PIXEL_SHADER),
})
.Capture(CAPTURE_START),
.Capture(CAPTURE_FIRST_TOKEN),
create.Or({
create.And({
create.Integer().Capture(CAPTURE_VERSION_MAJOR),
@@ -106,31 +100,23 @@ namespace techset
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
const auto& firstToken = result.NextCapture(CAPTURE_START);
// Don't care about shader version since it's stated in the shader bin anyway
const auto& shaderNameToken = result.NextCapture(CAPTURE_SHADER_NAME);
bool acceptorResult;
std::string errorMessage;
const auto shaderTag = result.NextTag();
assert(shaderTag == TAG_VERTEX_SHADER || shaderTag == TAG_PIXEL_SHADER);
if (shaderTag == TAG_VERTEX_SHADER)
{
acceptorResult = state->m_acceptor->AcceptVertexShader(shaderNameToken.StringValue(), errorMessage);
state->m_current_shader = ShaderSelector::VERTEX_SHADER;
}
state->m_current_shader_type = CommonTechniqueShaderType::VERTEX;
else
{
acceptorResult = state->m_acceptor->AcceptPixelShader(shaderNameToken.StringValue(), errorMessage);
state->m_current_shader = ShaderSelector::PIXEL_SHADER;
}
state->m_current_shader_type = CommonTechniqueShaderType::PIXEL;
state->m_in_shader = true;
state->m_current_shader = CommonTechniqueShader(state->m_current_shader_type, shaderNameToken.StringValue());
if (!acceptorResult)
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
auto enterResult = state->m_shader_arg_creator.EnterShader(state->m_current_shader->m_type, state->m_current_shader->m_name);
if (!enterResult.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), enterResult.error());
}
};
@@ -191,13 +177,23 @@ namespace techset
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
const auto& firstToken = result.NextCapture(CAPTURE_FIRST_TOKEN);
const std::string destinationString = CreateRoutingString(result, CAPTURE_STREAM_DESTINATION_NAME, CAPTURE_STREAM_DESTINATION_INDEX);
const std::string sourceString = CreateRoutingString(result, CAPTURE_STREAM_SOURCE_NAME, CAPTURE_STREAM_SOURCE_INDEX);
assert(state->m_current_pass);
std::string errorMessage;
if (!state->m_acceptor->AcceptVertexStreamRouting(destinationString, sourceString, errorMessage))
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
const auto& firstToken = result.NextCapture(CAPTURE_FIRST_TOKEN);
const std::string destinationString = CreateRoutingString(result, CAPTURE_STREAM_DESTINATION_NAME, CAPTURE_STREAM_DESTINATION_INDEX);
const auto maybeDestination = state->m_routing_infos.GetDestinationByName(destinationString);
if (!maybeDestination.has_value())
throw ParsingException(firstToken.GetPos(), "Unknown routing destination");
const std::string sourceString = CreateRoutingString(result, CAPTURE_STREAM_SOURCE_NAME, CAPTURE_STREAM_SOURCE_INDEX);
const auto maybeSource = state->m_routing_infos.GetSourceByName(sourceString);
if (!maybeSource.has_value())
throw ParsingException(firstToken.GetPos(), "Unknown routing source");
state->m_current_pass->m_vertex_declaration.m_routing.emplace_back(*maybeSource, *maybeDestination);
}
};
} // namespace techset

View File

@@ -1,6 +1,7 @@
#include "TechniqueShaderScopeSequences.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
#include "Techset/CommonShaderArgCreator.h"
#include <cassert>
@@ -10,21 +11,35 @@ namespace techset
{
class SequenceEndShader final : public TechniqueParser::sequence_t
{
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
public:
SequenceEndShader()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Char('}'),
create.Char('}').Capture(CAPTURE_FIRST_TOKEN),
});
}
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_in_shader == true);
state->m_in_shader = false;
assert(state->m_current_pass);
assert(state->m_current_shader);
if (state->m_current_shader_type == CommonTechniqueShaderType::VERTEX)
state->m_current_pass->m_vertex_shader = std::move(*state->m_current_shader);
else
state->m_current_pass->m_pixel_shader = std::move(*state->m_current_shader);
state->m_current_shader = std::nullopt;
auto finalizationResult = state->m_shader_arg_creator.FinalizeArgs();
if (!finalizationResult.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), finalizationResult.error());
state->m_shader_arg_creator.LeaveShader();
}
};
@@ -134,40 +149,120 @@ namespace techset
});
}
static void ProcessCodeArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg, const bool isSampler)
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
std::vector<std::string> accessors;
while (result.HasNextCapture(CAPTURE_CODE_ACCESSOR))
accessors.emplace_back(result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue());
assert(state->m_current_shader);
ShaderArgumentCodeSource source;
if (result.HasNextCapture(CAPTURE_CODE_INDEX))
const auto& shaderArgumentNameToken = result.NextCapture(CAPTURE_SHADER_ARGUMENT);
CommonShaderArgCreatorDestination destination;
if (result.HasNextCapture(CAPTURE_SHADER_INDEX))
{
const auto& codeIndexToken = result.NextCapture(CAPTURE_CODE_INDEX);
if (codeIndexToken.IntegerValue() < 0)
throw ParsingException(codeIndexToken.GetPos(), "Index cannot be negative");
source = ShaderArgumentCodeSource(std::move(accessors), static_cast<size_t>(codeIndexToken.IntegerValue()));
const auto& shaderArgumentIndexToken = result.NextCapture(CAPTURE_SHADER_INDEX);
if (shaderArgumentIndexToken.IntegerValue() < 0)
throw ParsingException(shaderArgumentIndexToken.GetPos(), "Index cannot be negative");
const auto index = static_cast<unsigned>(shaderArgumentIndexToken.IntegerValue());
destination = CommonShaderArgCreatorDestination(shaderArgumentNameToken.IdentifierValue(), index);
}
else
source = ShaderArgumentCodeSource(std::move(accessors));
destination = CommonShaderArgCreatorDestination(shaderArgumentNameToken.IdentifierValue());
std::string errorMessage;
if (!isSampler)
const auto typeTag = result.NextTag();
assert(typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER || typeTag == TAG_LITERAL || typeTag == TAG_MATERIAL);
if (typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER)
{
if (!state->m_acceptor->AcceptShaderConstantArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
ProcessCodeArgument(state, result, destination, typeTag == TAG_SAMPLER);
}
else if (typeTag == TAG_LITERAL)
{
ProcessLiteralArgument(state, result, destination);
}
else
{
if (!state->m_acceptor->AcceptShaderSamplerArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
ProcessMaterialArgument(state, result, destination);
}
}
static void ProcessLiteralArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg)
private:
static void ProcessCodeArgument(const TechniqueParserState* state,
SequenceResult<SimpleParserValue>& result,
const CommonShaderArgCreatorDestination& destination,
const bool isSampler)
{
float value[4];
for (float& i : value)
const auto accessor = GetAccessorValue(result);
CommonShaderArgValue argValue;
if (isSampler)
{
const auto maybeSamplerSource = state->m_code_source_infos.GetCodeSamplerSourceForAccessor(accessor);
if (!maybeSamplerSource.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Unknown code sampler");
argValue.code_const_source = *maybeSamplerSource;
}
else
{
const auto maybeConstSource = state->m_code_source_infos.GetCodeSamplerSourceForAccessor(accessor);
if (!maybeConstSource.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Unknown code constant");
argValue.code_const_source = *maybeConstSource;
}
if (result.HasNextCapture(CAPTURE_CODE_INDEX))
{
if (isSampler)
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Code sampler is not an array");
const auto& codeIndexToken = result.NextCapture(CAPTURE_CODE_INDEX);
const auto indexIntValue = codeIndexToken.IntegerValue();
if (indexIntValue < 0)
throw ParsingException(codeIndexToken.GetPos(), "Index cannot be negative");
const auto indexValue = static_cast<size_t>(indexIntValue);
size_t codeArraySize = state->m_code_source_infos.GetInfoForCodeConstSource(argValue.code_const_source)->arrayCount;
if (codeArraySize == 0)
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Code constant is not an array");
if (codeArraySize <= indexValue)
{
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(),
std::format("Array overflow: Code array has size {}", codeArraySize));
}
argValue.code_const_source += static_cast<CommonCodeConstSource>(indexValue);
}
result::Expected<NoResult, std::string> shaderCreatorResult(NoResult{});
if (isSampler)
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderSamplerArgument(destination, argValue.code_sampler_source);
else
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderConstantArgument(destination, argValue.code_const_source);
if (!shaderCreatorResult.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
}
static std::string GetAccessorValue(SequenceResult<SimpleParserValue>& result)
{
std::ostringstream accessorStream;
accessorStream << result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue();
while (result.HasNextCapture(CAPTURE_CODE_ACCESSOR))
accessorStream << '.' << result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue();
return accessorStream.str();
}
static void ProcessLiteralArgument(const TechniqueParserState* state,
SequenceResult<SimpleParserValue>& result,
const CommonShaderArgCreatorDestination& destination)
{
std::array<float, 4> argValue;
for (float& i : argValue)
{
const auto& literalValueToken = result.NextCapture(CAPTURE_LITERAL_VALUE);
@@ -177,56 +272,30 @@ namespace techset
i = static_cast<float>(literalValueToken.IntegerValue());
}
const ShaderArgumentLiteralSource source(value);
std::string errorMessage;
if (!state->m_acceptor->AcceptShaderLiteralArgument(state->m_current_shader, std::move(arg), source, errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
auto shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderLiteralArgument(destination, argValue);
if (!shaderCreatorResult.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
}
static void ProcessMaterialArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg)
static void ProcessMaterialArgument(const TechniqueParserState* state,
SequenceResult<SimpleParserValue>& result,
const CommonShaderArgCreatorDestination& destination)
{
std::string errorMessage;
result::Expected<NoResult, std::string> shaderCreatorResult(NoResult{});
if (result.HasNextCapture(CAPTURE_MATERIAL_HASH))
{
ShaderArgumentMaterialSource source(static_cast<size_t>(result.NextCapture(CAPTURE_MATERIAL_HASH).IntegerValue()));
if (!state->m_acceptor->AcceptShaderMaterialArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderMaterialArgument(
destination, static_cast<unsigned>(result.NextCapture(CAPTURE_MATERIAL_HASH).IntegerValue()));
}
else
{
ShaderArgumentMaterialSource source(result.NextCapture(CAPTURE_MATERIAL_NAME).IdentifierValue());
if (!state->m_acceptor->AcceptShaderMaterialArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
const auto stringValue = result.NextCapture(CAPTURE_MATERIAL_NAME).IdentifierValue();
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderMaterialArgument(destination, stringValue);
}
}
protected:
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_in_shader == true);
const auto& shaderArgumentNameToken = result.NextCapture(CAPTURE_SHADER_ARGUMENT);
ShaderArgument arg;
if (result.HasNextCapture(CAPTURE_SHADER_INDEX))
{
const auto& shaderArgumentIndexToken = result.NextCapture(CAPTURE_SHADER_INDEX);
if (shaderArgumentIndexToken.IntegerValue() < 0)
throw ParsingException(shaderArgumentIndexToken.GetPos(), "Index cannot be negative");
const auto index = static_cast<unsigned>(shaderArgumentIndexToken.IntegerValue());
arg = ShaderArgument(shaderArgumentNameToken.IdentifierValue(), index);
}
else
arg = ShaderArgument(shaderArgumentNameToken.IdentifierValue());
const auto typeTag = result.NextTag();
assert(typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER || typeTag == TAG_LITERAL || typeTag == TAG_MATERIAL);
if (typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER)
ProcessCodeArgument(state, result, std::move(arg), typeTag == TAG_SAMPLER);
else if (typeTag == TAG_LITERAL)
ProcessLiteralArgument(state, result, std::move(arg));
else
ProcessMaterialArgument(state, result, std::move(arg));
if (!shaderCreatorResult.has_value())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
}
};
} // namespace techset

View File

@@ -4,20 +4,30 @@
#include "Sequence/TechniquePassScopeSequences.h"
#include "Sequence/TechniqueShaderScopeSequences.h"
using namespace techset;
TechniqueParser::TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor)
: AbstractParser(lexer, std::make_unique<TechniqueParserState>(acceptor))
namespace techset
{
}
TechniqueParser::TechniqueParser(SimpleLexer& lexer,
std::string techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& shaderArgCreator)
: AbstractParser(&lexer, std::make_unique<TechniqueParserState>(std::move(techniqueName), codeSourceInfos, routingInfos, shaderArgCreator))
{
}
const std::vector<TechniqueParser::sequence_t*>& TechniqueParser::GetTestsForState()
{
if (m_state->m_in_shader)
return TechniqueShaderScopeSequences::GetSequences();
std::unique_ptr<CommonTechnique> TechniqueParser::GetParsingResult() const
{
return std::move(m_state->m_technique);
}
if (m_state->m_in_pass)
return TechniquePassScopeSequences::GetSequences();
const std::vector<TechniqueParser::sequence_t*>& TechniqueParser::GetTestsForState()
{
if (m_state->m_current_shader.has_value())
return TechniqueShaderScopeSequences::GetSequences();
return TechniqueNoScopeSequences::GetSequences();
}
if (m_state->m_current_pass.has_value())
return TechniquePassScopeSequences::GetSequences();
return TechniqueNoScopeSequences::GetSequences();
}
} // namespace techset

View File

@@ -4,15 +4,21 @@
#include "Parsing/Simple/SimpleLexer.h"
#include "Parsing/Simple/SimpleParserValue.h"
#include "TechniqueFileParserState.h"
#include "Techset/CommonTechnique.h"
namespace techset
{
class TechniqueParser final : public AbstractParser<SimpleParserValue, TechniqueParserState>
{
public:
TechniqueParser(SimpleLexer& lexer,
std::string techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& shaderArgCreator);
[[nodiscard]] std::unique_ptr<CommonTechnique> GetParsingResult() const;
protected:
const std::vector<sequence_t*>& GetTestsForState() override;
public:
TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor);
};
} // namespace techset

View File

@@ -1,14 +1,16 @@
#include "TechniqueFileParserState.h"
#include <cassert>
using namespace techset;
TechniqueParserState::TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor)
: m_acceptor(acceptor),
m_in_pass(false),
m_in_shader(false),
m_current_shader(ShaderSelector::VERTEX_SHADER)
namespace techset
{
assert(acceptor);
}
TechniqueParserState::TechniqueParserState(std::string techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& shaderArgCreator)
: m_technique(std::make_unique<CommonTechnique>(std::move(techniqueName))),
m_code_source_infos(codeSourceInfos),
m_routing_infos(routingInfos),
m_shader_arg_creator(shaderArgCreator),
m_current_shader_type(CommonTechniqueShaderType::VERTEX)
{
}
} // namespace techset

View File

@@ -1,18 +1,28 @@
#pragma once
#include "Techset/TechniqueDefinitionAcceptor.h"
#include "Techset/CommonShaderArgCreator.h"
#include "Techset/CommonTechnique.h"
#include <memory>
namespace techset
{
class TechniqueParserState
{
public:
explicit TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor);
TechniqueParserState(std::string techniqueName,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
CommonShaderArgCreator& shaderArgCreator);
ITechniqueDefinitionAcceptor* const m_acceptor;
std::unique_ptr<CommonTechnique> m_technique;
bool m_in_pass;
bool m_in_shader;
ShaderSelector m_current_shader;
const CommonCodeSourceInfos& m_code_source_infos;
const CommonStreamRoutingInfos& m_routing_infos;
CommonShaderArgCreator& m_shader_arg_creator;
std::optional<CommonPass> m_current_pass;
std::optional<CommonTechniqueShader> m_current_shader;
CommonTechniqueShaderType m_current_shader_type;
};
} // namespace techset

View File

@@ -1,68 +0,0 @@
#include "StateMapFromTechniqueExtractor.h"
using namespace state_map;
std::string StateMapFromTechniqueExtractor::RetrieveStateMap()
{
return std::move(m_state_map);
}
void StateMapFromTechniqueExtractor::AcceptNextPass() {}
bool StateMapFromTechniqueExtractor::AcceptEndPass(std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptStateMap(const std::string& stateMapName, std::string& errorMessage)
{
m_state_map = stateMapName;
return true;
}
bool StateMapFromTechniqueExtractor::AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderConstantArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderSamplerArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderLiteralArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentLiteralSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderMaterialArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentMaterialSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage)
{
return true;
}

View File

@@ -1,40 +0,0 @@
#pragma once
#include "Techset/TechniqueDefinitionAcceptor.h"
#include <string>
namespace state_map
{
class StateMapFromTechniqueExtractor final : public techset::ITechniqueDefinitionAcceptor
{
public:
std::string RetrieveStateMap();
void AcceptNextPass() override;
bool AcceptEndPass(std::string& errorMessage) override;
bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) override;
bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) override;
bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) override;
bool AcceptShaderConstantArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage) override;
bool AcceptShaderSamplerArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage) override;
bool AcceptShaderLiteralArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentLiteralSource source,
std::string& errorMessage) override;
bool AcceptShaderMaterialArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentMaterialSource source,
std::string& errorMessage) override;
bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) override;
private:
std::string m_state_map;
};
} // namespace state_map

View File

@@ -4,7 +4,6 @@
#include "Parsing/StateMapParserState.h"
#include "StateMapDefinition.h"
#include "Techset/StateMap/StateMapLayout.h"
#include "Utils/ClassUtils.h"
#include <memory>
#include <string>
@@ -22,7 +21,7 @@ namespace state_map
public:
StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout);
_NODISCARD bool IsValidEndState(const StateMapParserState* state) const;
_NODISCARD std::unique_ptr<StateMapDefinition> ReadStateMapDefinition() const;
[[nodiscard]] bool IsValidEndState(const StateMapParserState* state) const;
[[nodiscard]] std::unique_ptr<StateMapDefinition> ReadStateMapDefinition() const;
};
} // namespace state_map

View File

@@ -1,8 +1,7 @@
#pragma once
#include "Asset/IZoneAssetCreationState.h"
#include "StateMap/StateMapDefinition.h"
#include "Utils/ClassUtils.h"
#include "Techset/StateMap/StateMapDefinition.h"
#include <memory>
#include <string>
@@ -13,10 +12,10 @@ namespace techset
class TechniqueStateMapCache final : public IZoneAssetCreationState
{
public:
_NODISCARD const state_map::StateMapDefinition* GetCachedStateMap(const std::string& name) const;
[[nodiscard]] const state_map::StateMapDefinition* GetCachedStateMap(const std::string& name) const;
void AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap);
_NODISCARD const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const;
[[nodiscard]] const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const;
void SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap);
private:

View File

@@ -1,116 +0,0 @@
#include "TechniqueDefinitionAcceptor.h"
using namespace techset;
ShaderArgument::ShaderArgument()
: m_argument_index_specified(false),
m_argument_index(0u)
{
}
ShaderArgument::ShaderArgument(std::string argumentName)
: m_argument_name(std::move(argumentName)),
m_argument_index_specified(false),
m_argument_index(0u)
{
}
ShaderArgument::ShaderArgument(std::string argumentName, const unsigned argumentIndex)
: m_argument_name(std::move(argumentName)),
m_argument_index_specified(true),
m_argument_index(argumentIndex)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource()
: m_index_accessor_specified(false),
m_index_accessor(0u)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors)
: m_accessors(std::move(accessors)),
m_index_accessor_specified(false),
m_index_accessor(0u)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors, const unsigned indexAccessor)
: m_accessors(std::move(accessors)),
m_index_accessor_specified(true),
m_index_accessor(indexAccessor)
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource()
: m_value{}
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(const float v0, const float v1, const float v2, const float v3)
: m_value{v0, v1, v2, v3}
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(float value[4])
: m_value{value[0], value[1], value[2], value[3]}
{
}
namespace techset
{
bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
if (lhs.m_value[0] < rhs.m_value[0])
return true;
if (lhs.m_value[0] > rhs.m_value[0])
return false;
if (lhs.m_value[1] < rhs.m_value[1])
return true;
if (lhs.m_value[1] > rhs.m_value[1])
return false;
if (lhs.m_value[2] < rhs.m_value[2])
return true;
if (lhs.m_value[2] > rhs.m_value[2])
return false;
if (lhs.m_value[3] < rhs.m_value[3])
return true;
if (lhs.m_value[3] > rhs.m_value[3])
return false;
return false;
}
bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return !(rhs < lhs);
}
bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return rhs < lhs;
}
bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return !(lhs < rhs);
}
} // namespace techset
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource()
: m_is_hash(false),
m_hash(0u)
{
}
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(const unsigned hash)
: m_is_hash(true),
m_hash(hash)
{
}
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(std::string name)
: m_is_hash(false),
m_hash(0u),
m_name(std::move(name))
{
}

View File

@@ -1,100 +0,0 @@
#pragma once
#include <string>
#include <vector>
namespace techset
{
enum class ShaderSelector
{
VERTEX_SHADER,
PIXEL_SHADER
};
class ShaderArgument
{
public:
std::string m_argument_name;
bool m_argument_index_specified;
unsigned m_argument_index;
ShaderArgument();
explicit ShaderArgument(std::string argumentName);
ShaderArgument(std::string argumentName, unsigned argumentIndex);
};
class ShaderArgumentCodeSource
{
public:
std::vector<std::string> m_accessors;
bool m_index_accessor_specified;
unsigned m_index_accessor;
ShaderArgumentCodeSource();
explicit ShaderArgumentCodeSource(std::vector<std::string> accessors);
ShaderArgumentCodeSource(std::vector<std::string> accessors, unsigned indexAccessor);
};
class ShaderArgumentLiteralSource
{
public:
float m_value[4];
ShaderArgumentLiteralSource();
ShaderArgumentLiteralSource(float v0, float v1, float v2, float v3);
explicit ShaderArgumentLiteralSource(float value[4]);
friend bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
};
class ShaderArgumentMaterialSource
{
public:
ShaderArgumentMaterialSource();
explicit ShaderArgumentMaterialSource(unsigned hash);
explicit ShaderArgumentMaterialSource(std::string name);
bool m_is_hash;
unsigned m_hash;
std::string m_name;
};
class ITechniqueDefinitionAcceptor
{
protected:
ITechniqueDefinitionAcceptor() = default;
public:
virtual ~ITechniqueDefinitionAcceptor() = default;
ITechniqueDefinitionAcceptor(const ITechniqueDefinitionAcceptor& other) = default;
ITechniqueDefinitionAcceptor(ITechniqueDefinitionAcceptor&& other) noexcept = default;
ITechniqueDefinitionAcceptor& operator=(const ITechniqueDefinitionAcceptor& other) = default;
ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default;
virtual void AcceptNextPass() = 0;
virtual bool AcceptEndPass(std::string& errorMessage) = 0;
virtual bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) = 0;
virtual bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) = 0;
virtual bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) = 0;
virtual bool
AcceptShaderConstantArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
virtual bool
AcceptShaderSamplerArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
virtual bool AcceptShaderLiteralArgument(ShaderSelector shader,
ShaderArgument shaderArgument,
ShaderArgumentLiteralSource source,
std::string& errorMessage) = 0;
virtual bool AcceptShaderMaterialArgument(ShaderSelector shader,
ShaderArgument shaderArgument,
ShaderArgumentMaterialSource source,
std::string& errorMessage) = 0;
virtual bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) = 0;
};
} // namespace techset

View File

@@ -1,39 +0,0 @@
#include "TechniqueFileReader.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/ParserSingleInputStream.h"
#include "Parsing/Simple/SimpleLexer.h"
#include "Techset/Parsing/TechniqueFileParser.h"
#include "Utils/Logging/Log.h"
#include <iostream>
using namespace techset;
TechniqueFileReader::TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor)
: m_file_name(std::move(fileName)),
m_acceptor(acceptor)
{
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
}
bool TechniqueFileReader::ReadTechniqueDefinition() const
{
SimpleLexer::Config lexerConfig;
lexerConfig.m_emit_new_line_tokens = false;
lexerConfig.m_read_strings = true;
lexerConfig.m_string_escape_sequences = false;
lexerConfig.m_read_integer_numbers = true;
lexerConfig.m_read_floating_point_numbers = true;
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
const auto parser = std::make_unique<TechniqueParser>(lexer.get(), m_acceptor);
const auto success = parser->Parse();
if (success)
return true;
con::error("Parsing technique file \"{}\" failed!", m_file_name);
return false;
}

View File

@@ -1,24 +0,0 @@
#pragma once
#include "Parsing/IParserLineStream.h"
#include "TechniqueDefinitionAcceptor.h"
#include <memory>
#include <string>
namespace techset
{
class TechniqueFileReader
{
public:
TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor);
[[nodiscard]] bool ReadTechniqueDefinition() const;
private:
std::string m_file_name;
ITechniqueDefinitionAcceptor* m_acceptor;
std::unique_ptr<IParserLineStream> m_base_stream;
std::unique_ptr<IParserLineStream> m_comment_proxy;
};
} // namespace techset