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

@@ -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