2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-03-16 01:43:04 +00:00

fix: warn but accept invalid argument types in shaders

cheers to T5 mc_sw4_3d_char_skin_gas that uses a sampler in the vertex shader
This commit is contained in:
Jan Laupetin
2026-03-15 12:56:13 +01:00
parent e8b9ece6bd
commit f4ed3e6c93

View File

@@ -12,6 +12,35 @@
namespace namespace
{ {
const char* ShaderTypeName(const techset::CommonTechniqueShaderType shaderType)
{
switch (shaderType)
{
case techset::CommonTechniqueShaderType::VERTEX:
return "vertex";
case techset::CommonTechniqueShaderType::PIXEL:
return "pixel";
}
return "<unknown>";
}
const char* ArgTypeName(const techset::CommonShaderValueType valueType)
{
switch (valueType)
{
case techset::CommonShaderValueType::CODE_CONST:
case techset::CommonShaderValueType::LITERAL_CONST:
case techset::CommonShaderValueType::MATERIAL_CONST:
return "constant";
case techset::CommonShaderValueType::CODE_SAMPLER:
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
return "sampler";
}
return "<unknown>";
}
class BaseCommonShaderArgCreator : public techset::CommonShaderArgCreator class BaseCommonShaderArgCreator : public techset::CommonShaderArgCreator
{ {
public: public:
@@ -28,6 +57,7 @@ namespace
result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override
{ {
m_shader_type = shaderType; m_shader_type = shaderType;
m_shader_name = name;
std::optional<techset::CommonTechniqueShaderBin> maybeShader; std::optional<techset::CommonTechniqueShaderBin> maybeShader;
if (shaderType == techset::CommonTechniqueShaderType::VERTEX) if (shaderType == techset::CommonTechniqueShaderType::VERTEX)
@@ -109,6 +139,9 @@ namespace
.m_value_type = techset::CommonShaderValueType::LITERAL_CONST, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST,
}; };
if (!IsArgumentTypeSupported(argumentType))
return result::Unexpected(std::format("{} constants are unsupported", ShaderTypeName(argumentType.m_shader_type)));
techset::CommonShaderArgValue value{.literal_value = literalValue}; techset::CommonShaderArgValue value{.literal_value = literalValue};
m_args.emplace_back(argumentType, commonDestination, value); m_args.emplace_back(argumentType, commonDestination, value);
@@ -143,6 +176,12 @@ namespace
} }
} }
if (!IsArgumentTypeSupported(argumentType))
{
return result::Unexpected(
std::format("{} {} are unsupported", ShaderTypeName(argumentType.m_shader_type), ArgTypeName(argumentType.m_value_type)));
}
techset::CommonShaderArgValue value{.name_hash = nameHash}; techset::CommonShaderArgValue value{.name_hash = nameHash};
m_args.emplace_back(argumentType, commonDestination, value); m_args.emplace_back(argumentType, commonDestination, value);
@@ -205,6 +244,9 @@ namespace
.m_value_type = techset::CommonShaderValueType::CODE_CONST, .m_value_type = techset::CommonShaderValueType::CODE_CONST,
}; };
if (!IsArgumentTypeSupported(argumentType))
return result::Unexpected(std::format("{} constants are unsupported", ShaderTypeName(argumentType.m_shader_type)));
const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeConstSource(codeConstSource); const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeConstSource(codeConstSource);
if (!maybeInfo) if (!maybeInfo)
return result::Unexpected<std::string>("Could not find info for code constant"); return result::Unexpected<std::string>("Could not find info for code constant");
@@ -249,6 +291,9 @@ namespace
.m_value_type = techset::CommonShaderValueType::CODE_SAMPLER, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER,
}; };
if (!IsArgumentTypeSupported(argumentType))
return result::Unexpected(std::format("{} samplers are unsupported", ShaderTypeName(argumentType.m_shader_type)));
const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeSamplerSource(codeSamplerSource); const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeSamplerSource(codeSamplerSource);
if (!maybeInfo) if (!maybeInfo)
return result::Unexpected<std::string>("Could not find info for code sampler"); return result::Unexpected<std::string>("Could not find info for code sampler");
@@ -262,6 +307,24 @@ namespace
return NoResult{}; return NoResult{};
} }
static bool IsArgumentTypeSupported(const techset::CommonShaderArgumentType& argumentType)
{
if (argumentType.m_shader_type == techset::CommonTechniqueShaderType::PIXEL)
return true;
switch (argumentType.m_value_type)
{
case techset::CommonShaderValueType::LITERAL_CONST:
case techset::CommonShaderValueType::MATERIAL_CONST:
case techset::CommonShaderValueType::CODE_CONST:
return true;
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
case techset::CommonShaderValueType::CODE_SAMPLER:
default:
return false;
}
}
[[nodiscard]] virtual size_t CompareArgumentDestinations(const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) const = 0; [[nodiscard]] virtual size_t CompareArgumentDestinations(const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) const = 0;
[[nodiscard]] virtual bool FindDestinationForConstant(techset::CommonShaderArgDestination& commonDestination, [[nodiscard]] virtual bool FindDestinationForConstant(techset::CommonShaderArgDestination& commonDestination,
@@ -279,6 +342,7 @@ namespace
techset::CommonCodeSourceInfos& m_common_code_source_infos; techset::CommonCodeSourceInfos& m_common_code_source_infos;
techset::CommonTechniqueShaderType m_shader_type; techset::CommonTechniqueShaderType m_shader_type;
std::string m_shader_name;
techset::CommonTechniqueShaderBin m_bin; techset::CommonTechniqueShaderBin m_bin;
std::vector<techset::CommonShaderArg> m_args; std::vector<techset::CommonShaderArg> m_args;
@@ -341,8 +405,6 @@ namespace
if (foundConstant == m_shader_info->m_constants.end()) if (foundConstant == m_shader_info->m_constants.end())
return false; return false;
const auto variableElementCount = std::max<unsigned>(foundConstant->m_register_count, 1);
commonDestination.dx9.m_destination_register = foundConstant->m_register_index; commonDestination.dx9.m_destination_register = foundConstant->m_register_index;
isTransposed = foundConstant->m_class == d3d9::ParameterClass::MATRIX_COLUMNS; isTransposed = foundConstant->m_class == d3d9::ParameterClass::MATRIX_COLUMNS;
rowCount = foundConstant->m_register_count; rowCount = foundConstant->m_register_count;
@@ -409,6 +471,15 @@ namespace
private: private:
result::Expected<NoResult, std::string> AutoCreateConstantArg(const d3d9::ShaderConstant& shaderArg) result::Expected<NoResult, std::string> AutoCreateConstantArg(const d3d9::ShaderConstant& shaderArg)
{ {
if (!IsArgumentTypeSupported(
techset::CommonShaderArgumentType{.m_shader_type = m_shader_type, .m_value_type = techset::CommonShaderValueType::CODE_CONST}))
{
con::warn("Shader {} uses unsupported argument type \"{} constant\". This may cause unstable behaviour.",
m_shader_name,
ShaderTypeName(m_shader_type));
return NoResult{};
}
const auto maybeCodeConst = m_common_code_source_infos.GetCodeConstSourceForAccessor(shaderArg.m_name); const auto maybeCodeConst = m_common_code_source_infos.GetCodeConstSourceForAccessor(shaderArg.m_name);
if (!maybeCodeConst) if (!maybeCodeConst)
{ {
@@ -464,6 +535,15 @@ namespace
result::Expected<NoResult, std::string> AutoCreateSamplerArg(const d3d9::ShaderConstant& shaderArg) result::Expected<NoResult, std::string> AutoCreateSamplerArg(const d3d9::ShaderConstant& shaderArg)
{ {
if (!IsArgumentTypeSupported(
techset::CommonShaderArgumentType{.m_shader_type = m_shader_type, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER}))
{
con::warn("Shader {} uses unsupported argument type \"{} sampler\". This may cause unstable behaviour.",
m_shader_name,
ShaderTypeName(m_shader_type));
return NoResult{};
}
const auto maybeCodeSampler = m_common_code_source_infos.GetCodeSamplerSourceForAccessor(shaderArg.m_name); const auto maybeCodeSampler = m_common_code_source_infos.GetCodeSamplerSourceForAccessor(shaderArg.m_name);
if (!maybeCodeSampler) if (!maybeCodeSampler)
return result::Unexpected(std::format("Missing assignment to shader texture {}", shaderArg.m_name)); return result::Unexpected(std::format("Missing assignment to shader texture {}", shaderArg.m_name));