diff --git a/src/ObjCommon/Techset/CommonTechnique.h b/src/ObjCommon/Techset/CommonTechnique.h index 3f2153a5..e0a8ac66 100644 --- a/src/ObjCommon/Techset/CommonTechnique.h +++ b/src/ObjCommon/Techset/CommonTechnique.h @@ -33,7 +33,9 @@ namespace techset enum class CommonTechniqueShaderType : std::uint8_t { VERTEX, - PIXEL + PIXEL, + + COUNT }; enum class CommonShaderValueType : std::uint8_t @@ -47,7 +49,9 @@ namespace techset // Value is set to a sampler from the material MATERIAL_SAMPLER, // Value is set to a sampler generated in code - CODE_SAMPLER + CODE_SAMPLER, + + COUNT }; constexpr bool IsConstValueType(const CommonShaderValueType valueType) diff --git a/src/ObjCompiling/Techset/CommonShaderArgCreator.cpp b/src/ObjCompiling/Techset/CommonShaderArgCreator.cpp index 87ae4f3e..e277b578 100644 --- a/src/ObjCompiling/Techset/CommonShaderArgCreator.cpp +++ b/src/ObjCompiling/Techset/CommonShaderArgCreator.cpp @@ -12,6 +12,16 @@ namespace { + enum class ArgumentType : std::uint8_t + { + VERTEX_CONSTANT, + VERTEX_SAMPLER, + PIXEL_CONSTANT, + PIXEL_SAMPLER, + + COUNT + }; + const char* ShaderTypeName(const techset::CommonTechniqueShaderType shaderType) { switch (shaderType) @@ -20,6 +30,9 @@ namespace return "vertex"; case techset::CommonTechniqueShaderType::PIXEL: return "pixel"; + case techset::CommonTechniqueShaderType::COUNT: + assert(false); + break; } return ""; @@ -36,6 +49,9 @@ namespace case techset::CommonShaderValueType::CODE_SAMPLER: case techset::CommonShaderValueType::MATERIAL_SAMPLER: return "sampler"; + case techset::CommonShaderValueType::COUNT: + assert(false); + break; } return ""; @@ -47,11 +63,13 @@ namespace explicit BaseCommonShaderArgCreator(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos) : m_shader_loader(shaderLoader), m_common_code_source_infos(commonCodeSourceInfos), + m_supported_argument_types(0), m_shader_type(techset::CommonTechniqueShaderType::VERTEX), m_bin{}, m_tech_flags(0), m_sampler_flags(0) { + DetermineSupportedArgumentTypes(); } result::Expected EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override @@ -307,21 +325,36 @@ namespace return NoResult{}; } - static bool IsArgumentTypeSupported(const techset::CommonShaderArgumentType& argumentType) + [[nodiscard]] bool IsArgumentTypeSupported(const techset::CommonShaderArgumentType& argumentType) const { - if (argumentType.m_shader_type == techset::CommonTechniqueShaderType::PIXEL) - return true; + const auto mask = 1 << (std::to_underlying(argumentType.m_shader_type) * std::to_underlying(techset::CommonShaderValueType::COUNT) + + std::to_underlying(argumentType.m_value_type)); - switch (argumentType.m_value_type) + return m_supported_argument_types & mask; + } + + void DetermineSupportedArgumentTypes() + { + // Ensure we have enough bits for the flags + static_assert(std::to_underlying(techset::CommonTechniqueShaderType::COUNT) * std::to_underlying(techset::CommonShaderValueType::COUNT) + <= sizeof(m_supported_argument_types) * 8); + + m_supported_argument_types = 0; + for (auto shaderType = 0u; shaderType < std::to_underlying(techset::CommonTechniqueShaderType::COUNT); shaderType++) { - 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; + for (auto valueType = 0u; valueType < std::to_underlying(techset::CommonShaderValueType::COUNT); valueType++) + { + techset::CommonShaderArgumentType argumentType{ + .m_shader_type = static_cast(shaderType), + .m_value_type = static_cast(valueType), + }; + + if (m_common_code_source_infos.GetArgumentTypeNumericValue(argumentType).has_value()) + { + const auto flag = 1 << (shaderType * std::to_underlying(techset::CommonShaderValueType::COUNT) + valueType); + m_supported_argument_types |= flag; + } + } } } @@ -340,6 +373,7 @@ namespace techset::ITechniqueShaderLoader& m_shader_loader; techset::CommonCodeSourceInfos& m_common_code_source_infos; + std::uint16_t m_supported_argument_types; techset::CommonTechniqueShaderType m_shader_type; std::string m_shader_name; diff --git a/src/ObjCompiling/Techset/TechniqueCompiler.cpp.template b/src/ObjCompiling/Techset/TechniqueCompiler.cpp.template index 4d460024..ef5a954e 100644 --- a/src/ObjCompiling/Techset/TechniqueCompiler.cpp.template +++ b/src/ObjCompiling/Techset/TechniqueCompiler.cpp.template @@ -70,6 +70,9 @@ namespace case techset::CommonShaderValueType::CODE_CONST: return MTL_ARG_CODE_VERTEX_CONST; case techset::CommonShaderValueType::MATERIAL_SAMPLER: +#if defined(FEATURE_IW5) + return MTL_ARG_MATERIAL_VERTEX_SAMPLER; +#endif case techset::CommonShaderValueType::CODE_SAMPLER: default: assert(false); @@ -119,6 +122,9 @@ namespace case techset::CommonShaderValueType::MATERIAL_SAMPLER: argValue.nameHash = static_cast(commonArg.m_value.name_hash); break; + case techset::CommonShaderValueType::COUNT: + assert(false); + break; } }