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:
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user