mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-01-24 08:53:04 +00:00
wip
This commit is contained in:
@@ -1 +1,42 @@
|
||||
#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,
|
||||
ISearchPath& searchPath)
|
||||
{
|
||||
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);
|
||||
|
||||
const auto success = parser->Parse();
|
||||
if (success)
|
||||
return parser->GetParsingResult();
|
||||
|
||||
con::error("Parsing technique file \"{}\" failed!", fileName);
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace techset
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
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,
|
||||
ISearchPath& searchPath);
|
||||
} // namespace techset
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,20 +26,17 @@ 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_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 +44,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 +53,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,11 +64,10 @@ 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_VERSION = 2;
|
||||
static constexpr auto CAPTURE_VERSION_MAJOR = 3;
|
||||
static constexpr auto CAPTURE_VERSION_MINOR = 4;
|
||||
static constexpr auto CAPTURE_SHADER_NAME = 5;
|
||||
static constexpr auto CAPTURE_VERSION = 1;
|
||||
static constexpr auto CAPTURE_VERSION_MAJOR = 2;
|
||||
static constexpr auto CAPTURE_VERSION_MINOR = 3;
|
||||
static constexpr auto CAPTURE_SHADER_NAME = 4;
|
||||
|
||||
public:
|
||||
SequenceShader()
|
||||
@@ -83,12 +75,10 @@ namespace techset
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create
|
||||
.Or({
|
||||
create.Keyword("vertexShader").Tag(TAG_VERTEX_SHADER),
|
||||
create.Keyword("pixelShader").Tag(TAG_PIXEL_SHADER),
|
||||
})
|
||||
.Capture(CAPTURE_START),
|
||||
create.Or({
|
||||
create.Keyword("vertexShader").Tag(TAG_VERTEX_SHADER),
|
||||
create.Keyword("pixelShader").Tag(TAG_PIXEL_SHADER),
|
||||
}),
|
||||
create.Or({
|
||||
create.And({
|
||||
create.Integer().Capture(CAPTURE_VERSION_MAJOR),
|
||||
@@ -106,31 +96,18 @@ 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);
|
||||
|
||||
state->m_current_shader = CommonTechniqueShader(shaderNameToken.StringValue());
|
||||
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 = TechniqueParserShaderType::VERTEX;
|
||||
else
|
||||
{
|
||||
acceptorResult = state->m_acceptor->AcceptPixelShader(shaderNameToken.StringValue(), errorMessage);
|
||||
state->m_current_shader = ShaderSelector::PIXEL_SHADER;
|
||||
}
|
||||
|
||||
state->m_in_shader = true;
|
||||
|
||||
if (!acceptorResult)
|
||||
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
|
||||
state->m_current_shader_type = TechniqueParserShaderType::PIXEL;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -191,13 +168,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
|
||||
|
||||
@@ -23,8 +23,15 @@ namespace techset
|
||||
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 == TechniqueParserShaderType::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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -203,7 +210,7 @@ namespace techset
|
||||
protected:
|
||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_in_shader == true);
|
||||
assert(state->m_current_shader);
|
||||
|
||||
const auto& shaderArgumentNameToken = result.NextCapture(CAPTURE_SHADER_ARGUMENT);
|
||||
|
||||
|
||||
@@ -4,20 +4,29 @@
|
||||
#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)
|
||||
: AbstractParser(&lexer, std::make_unique<TechniqueParserState>(std::move(techniqueName), codeSourceInfos, routingInfos))
|
||||
{
|
||||
}
|
||||
|
||||
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_in_shader)
|
||||
return TechniqueShaderScopeSequences::GetSequences();
|
||||
|
||||
return TechniqueNoScopeSequences::GetSequences();
|
||||
}
|
||||
if (m_state->m_in_pass)
|
||||
return TechniquePassScopeSequences::GetSequences();
|
||||
|
||||
return TechniqueNoScopeSequences::GetSequences();
|
||||
}
|
||||
} // namespace techset
|
||||
|
||||
@@ -4,15 +4,20 @@
|
||||
#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);
|
||||
[[nodiscard]] std::unique_ptr<CommonTechnique> GetParsingResult() const;
|
||||
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor);
|
||||
};
|
||||
} // namespace techset
|
||||
|
||||
@@ -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)
|
||||
: m_technique(std::make_unique<CommonTechnique>(std::move(techniqueName))),
|
||||
m_code_source_infos(codeSourceInfos),
|
||||
m_routing_infos(routingInfos),
|
||||
m_in_pass(false),
|
||||
m_in_shader(false),
|
||||
m_current_shader(ShaderSelector::VERTEX_SHADER)
|
||||
{
|
||||
}
|
||||
} // namespace techset
|
||||
|
||||
@@ -1,18 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "Techset/TechniqueDefinitionAcceptor.h"
|
||||
#include "Techset/CommonTechnique.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace techset
|
||||
{
|
||||
enum class TechniqueParserShaderType : std::uint8_t
|
||||
{
|
||||
VERTEX,
|
||||
PIXEL
|
||||
};
|
||||
|
||||
class TechniqueParserState
|
||||
{
|
||||
public:
|
||||
explicit TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor);
|
||||
TechniqueParserState(std::string techniqueName, const CommonCodeSourceInfos& codeSourceInfos, const CommonStreamRoutingInfos& routingInfos);
|
||||
|
||||
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;
|
||||
|
||||
std::optional<CommonPass> m_current_pass;
|
||||
std::optional<CommonTechniqueShader> m_current_shader;
|
||||
TechniqueParserShaderType m_current_shader_type;
|
||||
};
|
||||
} // namespace techset
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "StateMapExpressionMatchers.h"
|
||||
|
||||
#include "Parsing/Simple/Expression/SimpleExpressionScopeValue.h"
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
static constexpr int CAPTURE_VALUE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION_EXT + 1;
|
||||
|
||||
StateMapExpressionMatchers::StateMapExpressionMatchers()
|
||||
: StateMapExpressionMatchers(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StateMapExpressionMatchers::StateMapExpressionMatchers(StateMapParserState* state)
|
||||
: SimpleExpressionMatchers(false, false, false, false, true),
|
||||
m_state(state)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<SimpleExpressionMatchers::matcher_t> StateMapExpressionMatchers::ParseOperandExtension(const supplier_t* labelSupplier) const
|
||||
{
|
||||
const SimpleMatcherFactory create(labelSupplier);
|
||||
|
||||
return create.Or({
|
||||
create.Identifier().Capture(CAPTURE_VALUE),
|
||||
create.Integer().Capture(CAPTURE_VALUE),
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<ISimpleExpression> StateMapExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
|
||||
{
|
||||
assert(m_state);
|
||||
|
||||
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
|
||||
auto value = valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
|
||||
|
||||
if (value.rfind("mtl", 0) == 0)
|
||||
{
|
||||
if (m_state->m_valid_vars.find(value) == m_state->m_valid_vars.end())
|
||||
throw ParsingException(valueToken.GetPos(), "Unknown variable");
|
||||
|
||||
return std::make_unique<SimpleExpressionScopeValue>(value);
|
||||
}
|
||||
|
||||
if (m_state->m_valid_values.find(value) == m_state->m_valid_values.end())
|
||||
throw ParsingException(valueToken.GetPos(), "Unknown value");
|
||||
|
||||
return std::make_unique<SimpleExpressionValue>(value);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
||||
#include "Techset/StateMap/Parsing/StateMapParserState.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapExpressionMatchers final : public SimpleExpressionMatchers
|
||||
{
|
||||
public:
|
||||
StateMapExpressionMatchers();
|
||||
explicit StateMapExpressionMatchers(StateMapParserState* state);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
|
||||
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
|
||||
|
||||
private:
|
||||
StateMapParserState* m_state;
|
||||
};
|
||||
} // namespace state_map
|
||||
251
src/ObjCompiling/Techset/StateMap/Parsing/StateMapParser.cpp
Normal file
251
src/ObjCompiling/Techset/StateMap/Parsing/StateMapParser.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
#include "StateMapParser.h"
|
||||
|
||||
#include "Matcher/StateMapExpressionMatchers.h"
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class SequenceStateMapEntry final : public StateMapParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_ENTRY_NAME = 1;
|
||||
|
||||
public:
|
||||
SequenceStateMapEntry()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Identifier().Capture(CAPTURE_ENTRY_NAME),
|
||||
create.Char('{'),
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
const auto& entryNameToken = result.NextCapture(CAPTURE_ENTRY_NAME);
|
||||
|
||||
const auto foundEntry = state->m_valid_state_map_entry_names.find(entryNameToken.IdentifierValue());
|
||||
if (foundEntry == state->m_valid_state_map_entry_names.end())
|
||||
throw ParsingException(entryNameToken.GetPos(), "Unknown entry name");
|
||||
|
||||
state->m_in_entry = true;
|
||||
state->m_current_entry_index = foundEntry->second;
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceStateMapEntryClose final : public StateMapParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
||||
|
||||
public:
|
||||
SequenceStateMapEntryClose()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Char('}').Capture(CAPTURE_FIRST_TOKEN),
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
if (!state->m_entry_has_default)
|
||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Entry must have a default case");
|
||||
|
||||
state->m_in_entry = false;
|
||||
state->m_entry_has_default = false;
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceCondition final : public StateMapParser::sequence_t
|
||||
{
|
||||
static constexpr auto TAG_DEFAULT = 1;
|
||||
static constexpr auto TAG_EXPRESSION = 2;
|
||||
|
||||
public:
|
||||
SequenceCondition()
|
||||
{
|
||||
AddLabeledMatchers(StateMapExpressionMatchers().Expression(this), StateMapExpressionMatchers::LABEL_EXPRESSION);
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Or({
|
||||
create.Keyword("default").Tag(TAG_DEFAULT),
|
||||
create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION).Tag(TAG_EXPRESSION),
|
||||
}),
|
||||
create.Char(':'),
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_definition);
|
||||
assert(state->m_in_entry);
|
||||
|
||||
if (!state->m_current_rule)
|
||||
{
|
||||
auto newRule = std::make_unique<StateMapRule>();
|
||||
state->m_current_rule = newRule.get();
|
||||
state->m_definition->m_state_map_entries[state->m_current_entry_index].m_rules.emplace_back(std::move(newRule));
|
||||
}
|
||||
|
||||
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION)
|
||||
{
|
||||
auto expression = StateMapExpressionMatchers(state).ProcessExpression(result);
|
||||
|
||||
state->m_current_rule->m_conditions.emplace_back(std::move(expression));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(result.PeekAndRemoveIfTag(TAG_DEFAULT) == TAG_DEFAULT);
|
||||
auto& entry = state->m_definition->m_state_map_entries[state->m_current_entry_index];
|
||||
state->m_entry_has_default = true;
|
||||
entry.m_default_index = entry.m_rules.size() - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceValue final : public StateMapParser::sequence_t
|
||||
{
|
||||
static constexpr auto TAG_PASSTHROUGH = 1;
|
||||
static constexpr auto TAG_VALUE_LIST = 2;
|
||||
|
||||
static constexpr auto CAPTURE_VALUE = 1;
|
||||
static constexpr auto CAPTURE_VALUE_END = 2;
|
||||
|
||||
static constexpr auto LABEL_VALUE_LIST = 1;
|
||||
static constexpr auto LABEL_VALUE = 2;
|
||||
|
||||
public:
|
||||
SequenceValue()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddLabeledMatchers(create.Or({
|
||||
create.Identifier(),
|
||||
create.Integer(),
|
||||
}),
|
||||
LABEL_VALUE);
|
||||
|
||||
AddLabeledMatchers(
|
||||
{
|
||||
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE),
|
||||
create.OptionalLoop(create.And({
|
||||
create.Char(','),
|
||||
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE),
|
||||
})),
|
||||
},
|
||||
LABEL_VALUE_LIST);
|
||||
|
||||
AddMatchers({
|
||||
create.Or({
|
||||
create.Keyword("passthrough").Tag(TAG_PASSTHROUGH),
|
||||
create.Label(LABEL_VALUE_LIST).Tag(TAG_VALUE_LIST),
|
||||
}),
|
||||
create.Char(';').Capture(CAPTURE_VALUE_END),
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_in_entry);
|
||||
assert(state->m_current_rule);
|
||||
|
||||
const auto& layoutEntry = state->m_layout.m_entry_layout.m_entries[state->m_current_entry_index];
|
||||
|
||||
if (result.PeekAndRemoveIfTag(TAG_VALUE_LIST) == TAG_VALUE_LIST)
|
||||
{
|
||||
auto resultIndex = 0u;
|
||||
|
||||
while (result.HasNextCapture(CAPTURE_VALUE))
|
||||
{
|
||||
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
|
||||
|
||||
if (resultIndex >= layoutEntry.m_result_vars.size())
|
||||
throw ParsingException(valueToken.GetPos(), "Too many results");
|
||||
|
||||
const auto& resultVar = layoutEntry.m_result_vars[resultIndex];
|
||||
const auto varForResult = state->m_valid_vars.find(resultVar);
|
||||
|
||||
if (varForResult != state->m_valid_vars.end())
|
||||
{
|
||||
const auto& var = state->m_layout.m_var_layout.m_vars[varForResult->second];
|
||||
const auto tokenValue =
|
||||
valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
|
||||
|
||||
const auto referencedValue = std::ranges::find_if(var.m_values,
|
||||
[&tokenValue](const StateMapLayoutVarValue& value)
|
||||
{
|
||||
return value.m_name == tokenValue;
|
||||
});
|
||||
|
||||
if (referencedValue == var.m_values.end())
|
||||
throw ParsingException(valueToken.GetPos(), "Not part of the valid values for this var");
|
||||
|
||||
state->m_current_rule->m_value |= referencedValue->m_state_bits_mask;
|
||||
}
|
||||
else
|
||||
throw ParsingException(valueToken.GetPos(), "Unknown var for result?");
|
||||
|
||||
resultIndex++;
|
||||
}
|
||||
|
||||
if (resultIndex < layoutEntry.m_result_vars.size())
|
||||
throw ParsingException(result.NextCapture(CAPTURE_VALUE_END).GetPos(), "Not enough results");
|
||||
}
|
||||
else
|
||||
{
|
||||
// A rule without values is considered passthrough therefore just don't add values
|
||||
assert(result.PeekAndRemoveIfTag(TAG_PASSTHROUGH) == TAG_PASSTHROUGH);
|
||||
state->m_current_rule->m_passthrough = true;
|
||||
}
|
||||
|
||||
state->m_current_rule = nullptr;
|
||||
}
|
||||
};
|
||||
} // namespace state_map
|
||||
|
||||
StateMapParser::StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout)
|
||||
: AbstractParser(lexer, std::make_unique<StateMapParserState>(std::move(stateMapName), layout))
|
||||
{
|
||||
}
|
||||
|
||||
const std::vector<StateMapParser::sequence_t*>& StateMapParser::GetTestsForState()
|
||||
{
|
||||
static std::vector<sequence_t*> rootSequences({
|
||||
new SequenceStateMapEntry(),
|
||||
});
|
||||
|
||||
static std::vector<sequence_t*> entrySequences({
|
||||
new SequenceStateMapEntryClose(),
|
||||
new SequenceCondition(),
|
||||
});
|
||||
|
||||
static std::vector<sequence_t*> ruleSequences({
|
||||
new SequenceCondition(),
|
||||
new SequenceValue(),
|
||||
});
|
||||
|
||||
if (m_state->m_in_entry)
|
||||
{
|
||||
return m_state->m_current_rule ? ruleSequences : entrySequences;
|
||||
}
|
||||
|
||||
return rootSequences;
|
||||
}
|
||||
|
||||
std::unique_ptr<StateMapDefinition> StateMapParser::GetStateMapDefinition() const
|
||||
{
|
||||
return std::move(m_state->m_definition);
|
||||
}
|
||||
|
||||
StateMapParserState* StateMapParser::GetState() const
|
||||
{
|
||||
return m_state.get();
|
||||
}
|
||||
20
src/ObjCompiling/Techset/StateMap/Parsing/StateMapParser.h
Normal file
20
src/ObjCompiling/Techset/StateMap/Parsing/StateMapParser.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Impl/AbstractParser.h"
|
||||
#include "Parsing/Simple/SimpleLexer.h"
|
||||
#include "Parsing/Simple/SimpleParserValue.h"
|
||||
#include "StateMapParserState.h"
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapParser final : public AbstractParser<SimpleParserValue, StateMapParserState>
|
||||
{
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout);
|
||||
[[nodiscard]] std::unique_ptr<StateMapDefinition> GetStateMapDefinition() const;
|
||||
[[nodiscard]] StateMapParserState* GetState() const;
|
||||
};
|
||||
} // namespace state_map
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "StateMapParserState.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
StateMapParserState::StateMapParserState(std::string stateMapName, const StateMapLayout& layout)
|
||||
: m_layout(layout),
|
||||
m_definition(std::make_unique<StateMapDefinition>(std::move(stateMapName), layout.m_entry_layout.m_entries.size())),
|
||||
m_in_entry(false),
|
||||
m_entry_has_default(false),
|
||||
m_current_entry_index(0u),
|
||||
m_current_rule(nullptr)
|
||||
{
|
||||
for (auto i = 0u; i < m_layout.m_entry_layout.m_entries.size(); i++)
|
||||
m_valid_state_map_entry_names.emplace(m_layout.m_entry_layout.m_entries[i].m_name, i);
|
||||
|
||||
for (auto varIndex = 0u; varIndex < layout.m_var_layout.m_vars.size(); varIndex++)
|
||||
{
|
||||
const auto& var = layout.m_var_layout.m_vars[varIndex];
|
||||
m_valid_vars.emplace(std::make_pair(var.m_name, varIndex));
|
||||
|
||||
for (const auto& value : var.m_values)
|
||||
m_valid_values.emplace(value.m_name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "Techset/StateMap/StateMapDefinition.h"
|
||||
#include "Techset/StateMap/StateMapLayout.h"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapParserState
|
||||
{
|
||||
public:
|
||||
const StateMapLayout& m_layout;
|
||||
std::unordered_map<std::string, size_t> m_valid_state_map_entry_names;
|
||||
std::unordered_map<std::string, size_t> m_valid_vars;
|
||||
std::set<std::string> m_valid_values;
|
||||
std::unique_ptr<StateMapDefinition> m_definition;
|
||||
|
||||
bool m_in_entry;
|
||||
bool m_entry_has_default;
|
||||
size_t m_current_entry_index;
|
||||
StateMapRule* m_current_rule;
|
||||
|
||||
StateMapParserState(std::string stateMapName, const StateMapLayout& layout);
|
||||
};
|
||||
} // namespace state_map
|
||||
20
src/ObjCompiling/Techset/StateMap/StateMapDefinition.cpp
Normal file
20
src/ObjCompiling/Techset/StateMap/StateMapDefinition.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "StateMapDefinition.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
StateMapRule::StateMapRule()
|
||||
: m_value(0u),
|
||||
m_passthrough(false)
|
||||
{
|
||||
}
|
||||
|
||||
StateMapEntry::StateMapEntry()
|
||||
: m_default_index(0u)
|
||||
{
|
||||
}
|
||||
|
||||
StateMapDefinition::StateMapDefinition(std::string name, const size_t entryCount)
|
||||
: m_name(std::move(name)),
|
||||
m_state_map_entries(entryCount)
|
||||
{
|
||||
}
|
||||
38
src/ObjCompiling/Techset/StateMap/StateMapDefinition.h
Normal file
38
src/ObjCompiling/Techset/StateMap/StateMapDefinition.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapRule
|
||||
{
|
||||
public:
|
||||
std::vector<std::unique_ptr<ISimpleExpression>> m_conditions;
|
||||
size_t m_value;
|
||||
bool m_passthrough;
|
||||
|
||||
StateMapRule();
|
||||
};
|
||||
|
||||
class StateMapEntry
|
||||
{
|
||||
public:
|
||||
size_t m_default_index;
|
||||
std::vector<std::unique_ptr<StateMapRule>> m_rules;
|
||||
|
||||
StateMapEntry();
|
||||
};
|
||||
|
||||
class StateMapDefinition
|
||||
{
|
||||
public:
|
||||
StateMapDefinition(std::string name, size_t entryCount);
|
||||
|
||||
std::string m_name;
|
||||
std::vector<StateMapEntry> m_state_map_entries;
|
||||
};
|
||||
} // namespace state_map
|
||||
@@ -0,0 +1,68 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#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
|
||||
94
src/ObjCompiling/Techset/StateMap/StateMapHandler.cpp
Normal file
94
src/ObjCompiling/Techset/StateMap/StateMapHandler.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "StateMapHandler.h"
|
||||
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
void StateMapVars::AddValue(std::string key, std::string value)
|
||||
{
|
||||
m_vars.emplace(std::make_pair(std::move(key), std::move(value)));
|
||||
}
|
||||
|
||||
SimpleExpressionValue StateMapVars::ValueByName(const std::string& name) const
|
||||
{
|
||||
const auto foundValue = m_vars.find(name);
|
||||
|
||||
if (foundValue != m_vars.end())
|
||||
return SimpleExpressionValue(foundValue->second);
|
||||
|
||||
return SimpleExpressionValue(0);
|
||||
}
|
||||
|
||||
StateMapHandler::StateMapHandler(const StateMapLayout& stateMapLayout, const StateMapDefinition& stateMap)
|
||||
: m_state_map_layout(stateMapLayout),
|
||||
m_state_map(stateMap)
|
||||
{
|
||||
}
|
||||
|
||||
void StateMapHandler::ApplyStateMap(const uint32_t* baseStateBits, uint32_t* outStateBits) const
|
||||
{
|
||||
assert(baseStateBits != nullptr);
|
||||
assert(outStateBits != nullptr);
|
||||
|
||||
const auto vars = BuildVars(baseStateBits);
|
||||
|
||||
for (auto i = 0u; i < m_state_map_layout.m_state_bits_count; i++)
|
||||
outStateBits[i] = baseStateBits[i];
|
||||
|
||||
for (auto entryIndex = 0u; entryIndex < m_state_map.m_state_map_entries.size(); entryIndex++)
|
||||
{
|
||||
const auto& entry = m_state_map.m_state_map_entries[entryIndex];
|
||||
const auto matchingRule = std::ranges::find_if(entry.m_rules,
|
||||
[&vars](const std::unique_ptr<StateMapRule>& rule)
|
||||
{
|
||||
const auto matchingCondition =
|
||||
std::ranges::find_if(rule->m_conditions,
|
||||
[&vars](std::unique_ptr<ISimpleExpression>& condition)
|
||||
{
|
||||
return condition->EvaluateNonStatic(&vars).IsTruthy();
|
||||
});
|
||||
|
||||
return matchingCondition != rule->m_conditions.end();
|
||||
});
|
||||
|
||||
if (matchingRule != entry.m_rules.end())
|
||||
ApplyRule(m_state_map_layout.m_entry_layout.m_entries[entryIndex], **matchingRule, outStateBits);
|
||||
else
|
||||
ApplyRule(m_state_map_layout.m_entry_layout.m_entries[entryIndex], *entry.m_rules[entry.m_default_index], outStateBits);
|
||||
}
|
||||
}
|
||||
|
||||
StateMapVars StateMapHandler::BuildVars(const uint32_t* baseStateBits) const
|
||||
{
|
||||
StateMapVars result;
|
||||
|
||||
for (const auto& var : m_state_map_layout.m_var_layout.m_vars)
|
||||
{
|
||||
const auto baseStateBitField = baseStateBits[var.m_state_bits_index];
|
||||
const auto matchingValue = std::ranges::find_if(var.m_values,
|
||||
[&baseStateBitField](const StateMapLayoutVarValue& value)
|
||||
{
|
||||
return (baseStateBitField & value.m_state_bits_mask) == value.m_state_bits_mask;
|
||||
});
|
||||
|
||||
if (matchingValue != var.m_values.end())
|
||||
result.AddValue(var.m_name, matchingValue->m_name);
|
||||
else
|
||||
con::error("Could not find base value for state map var \"{}\"", var.m_name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void StateMapHandler::ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits)
|
||||
{
|
||||
if (rule.m_passthrough)
|
||||
return;
|
||||
|
||||
outStateBits[entry.m_state_bits_index] &= ~entry.m_state_bits_mask;
|
||||
outStateBits[entry.m_state_bits_index] |= rule.m_value;
|
||||
}
|
||||
35
src/ObjCompiling/Techset/StateMap/StateMapHandler.h
Normal file
35
src/ObjCompiling/Techset/StateMap/StateMapHandler.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "Techset/StateMap/StateMapDefinition.h"
|
||||
#include "Techset/StateMap/StateMapLayout.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapVars final : public ISimpleExpressionScopeValues
|
||||
{
|
||||
public:
|
||||
void AddValue(std::string key, std::string value);
|
||||
[[nodiscard]] SimpleExpressionValue ValueByName(const std::string& name) const override;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::string> m_vars;
|
||||
};
|
||||
|
||||
class StateMapHandler
|
||||
{
|
||||
public:
|
||||
StateMapHandler(const StateMapLayout& stateMapLayout, const StateMapDefinition& stateMap);
|
||||
|
||||
void ApplyStateMap(const uint32_t* baseStateBits, uint32_t* outStateBits) const;
|
||||
|
||||
private:
|
||||
StateMapVars BuildVars(const uint32_t* baseStateBits) const;
|
||||
static void ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits);
|
||||
|
||||
const StateMapLayout& m_state_map_layout;
|
||||
const StateMapDefinition& m_state_map;
|
||||
};
|
||||
} // namespace state_map
|
||||
72
src/ObjCompiling/Techset/StateMap/StateMapReader.cpp
Normal file
72
src/ObjCompiling/Techset/StateMap/StateMapReader.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "StateMapReader.h"
|
||||
|
||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||
#include "Parsing/Matcher/StateMapExpressionMatchers.h"
|
||||
#include "Parsing/StateMapParser.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
StateMapReader::StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout)
|
||||
: m_state_map_name(std::move(stateMapName)),
|
||||
m_file_name(std::move(fileName)),
|
||||
m_state_map_layout(layout)
|
||||
{
|
||||
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
|
||||
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
|
||||
}
|
||||
|
||||
bool StateMapReader::IsValidEndState(const StateMapParserState* state) const
|
||||
{
|
||||
if (state->m_current_rule)
|
||||
{
|
||||
con::error("In \"{}\": Unclosed rule at end of file!", m_file_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state->m_in_entry)
|
||||
{
|
||||
con::error("In \"{}\": Unclosed entry at end of file!", m_file_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < state->m_layout.m_entry_layout.m_entries.size(); i++)
|
||||
{
|
||||
if (state->m_definition->m_state_map_entries[i].m_rules.empty())
|
||||
{
|
||||
con::error("In \"{}\": State map must define a rule for \"{}\"!", m_file_name, state->m_layout.m_entry_layout.m_entries[i].m_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<StateMapDefinition> StateMapReader::ReadStateMapDefinition() const
|
||||
{
|
||||
SimpleLexer::Config lexerConfig;
|
||||
lexerConfig.m_emit_new_line_tokens = false;
|
||||
lexerConfig.m_read_strings = false;
|
||||
lexerConfig.m_read_integer_numbers = true;
|
||||
lexerConfig.m_read_floating_point_numbers = false;
|
||||
StateMapExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
|
||||
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
|
||||
|
||||
const auto parser = std::make_unique<StateMapParser>(lexer.get(), m_state_map_name, m_state_map_layout);
|
||||
|
||||
const auto success = parser->Parse();
|
||||
if (!success)
|
||||
{
|
||||
con::error("Parsing state map file \"{}\" failed!", m_file_name);
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto* parserEndState = parser->GetState();
|
||||
if (!IsValidEndState(parserEndState))
|
||||
return nullptr;
|
||||
|
||||
return parser->GetStateMapDefinition();
|
||||
}
|
||||
27
src/ObjCompiling/Techset/StateMap/StateMapReader.h
Normal file
27
src/ObjCompiling/Techset/StateMap/StateMapReader.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
#include "Parsing/StateMapParserState.h"
|
||||
#include "StateMapDefinition.h"
|
||||
#include "Techset/StateMap/StateMapLayout.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapReader
|
||||
{
|
||||
std::string m_state_map_name;
|
||||
std::string m_file_name;
|
||||
const StateMapLayout& m_state_map_layout;
|
||||
std::unique_ptr<IParserLineStream> m_base_stream;
|
||||
std::unique_ptr<IParserLineStream> m_comment_proxy;
|
||||
|
||||
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;
|
||||
};
|
||||
} // namespace state_map
|
||||
33
src/ObjCompiling/Techset/StateMap/TechniqueStateMapCache.cpp
Normal file
33
src/ObjCompiling/Techset/StateMap/TechniqueStateMapCache.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "TechniqueStateMapCache.h"
|
||||
|
||||
using namespace techset;
|
||||
|
||||
const state_map::StateMapDefinition* TechniqueStateMapCache::GetCachedStateMap(const std::string& name) const
|
||||
{
|
||||
const auto foundStateMap = m_state_map_cache.find(name);
|
||||
|
||||
if (foundStateMap != m_state_map_cache.end())
|
||||
return foundStateMap->second.get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TechniqueStateMapCache::AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap)
|
||||
{
|
||||
m_state_map_cache.emplace(std::make_pair(stateMap->m_name, std::move(stateMap)));
|
||||
}
|
||||
|
||||
const state_map::StateMapDefinition* TechniqueStateMapCache::GetStateMapForTechnique(const std::string& techniqueName) const
|
||||
{
|
||||
const auto foundTechnique = m_state_map_per_technique.find(techniqueName);
|
||||
|
||||
if (foundTechnique != m_state_map_per_technique.end())
|
||||
return foundTechnique->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TechniqueStateMapCache::SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap)
|
||||
{
|
||||
m_state_map_per_technique.emplace(std::make_pair(std::move(techniqueName), stateMap));
|
||||
}
|
||||
25
src/ObjCompiling/Techset/StateMap/TechniqueStateMapCache.h
Normal file
25
src/ObjCompiling/Techset/StateMap/TechniqueStateMapCache.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IZoneAssetCreationState.h"
|
||||
#include "Techset/StateMap/StateMapDefinition.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace techset
|
||||
{
|
||||
class TechniqueStateMapCache final : public IZoneAssetCreationState
|
||||
{
|
||||
public:
|
||||
[[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;
|
||||
void SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, const state_map::StateMapDefinition*> m_state_map_per_technique;
|
||||
std::unordered_map<std::string, std::unique_ptr<state_map::StateMapDefinition>> m_state_map_cache;
|
||||
};
|
||||
} // namespace techset
|
||||
116
src/ObjCompiling/Techset/TechniqueDefinitionAcceptor.cpp
Normal file
116
src/ObjCompiling/Techset/TechniqueDefinitionAcceptor.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#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))
|
||||
{
|
||||
}
|
||||
100
src/ObjCompiling/Techset/TechniqueDefinitionAcceptor.h
Normal file
100
src/ObjCompiling/Techset/TechniqueDefinitionAcceptor.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user