diff --git a/src/ObjCommon/Game/T5/Techset/TechsetConstantsT5.h b/src/ObjCommon/Game/T5/Techset/TechsetConstantsT5.h index ecb0e7ec..8c89b218 100644 --- a/src/ObjCommon/Game/T5/Techset/TechsetConstantsT5.h +++ b/src/ObjCommon/Game/T5/Techset/TechsetConstantsT5.h @@ -277,6 +277,11 @@ namespace T5 }; static_assert(std::extent_v == STREAM_DST_COUNT); + static inline techset::CommonStreamRoutingInfos commonRoutingInfos(streamRoutingSources, + std::extent_v, + streamRoutingDestinations, + std::extent_v); + static techset::CommonCodeConstSourceInfo commonCodeConstSources[]{ { .value = CONST_SRC_CODE_LIGHT_POSITION, @@ -1734,6 +1739,28 @@ namespace T5 }, }; + // See MaterialShaderArgumentType + static inline techset::CommonShaderArgumentType commonArgumentTypes[]{ + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_SAMPLER}, + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::CODE_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST }, + }; + static_assert(std::extent_v == MLT_ARG_COUNT); + + static inline techset::CommonCodeSourceInfos commonCodeSourceInfos(commonCodeConstSources, + std::extent_v, + commonCodeSamplerSources, + std::extent_v, + nullptr, + 0, + commonArgumentTypes, + std::extent_v); + inline MaterialTypeInfo g_materialTypeInfo[]{ {"", "" }, {"m/", "m_" }, diff --git a/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h b/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h index 73569967..acdc4371 100644 --- a/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h +++ b/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h @@ -190,6 +190,11 @@ namespace T6 }; static_assert(std::extent_v == STREAM_DST_COUNT); + static inline techset::CommonStreamRoutingInfos commonRoutingInfos(streamRoutingSources, + std::extent_v, + streamRoutingDestinations, + std::extent_v); + static inline techset::CommonCodeConstSourceInfo commonCodeConstSources[]{ { .value = CONST_SRC_CODE_LIGHT_POSITION, @@ -214,6 +219,7 @@ namespace T6 .accessor = "lightSpotFactors", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_10, }, { .value = CONST_SRC_CODE_LIGHT_ATTENUATION, @@ -544,6 +550,7 @@ namespace T6 .accessor = "particleCloudVelWorld", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .techFlags = TECHNIQUE_FLAG_100, }, { .value = CONST_SRC_CODE_DEPTH_FROM_CLIP, @@ -1324,192 +1331,224 @@ namespace T6 .accessor = "worldMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_WORLD_MATRIX, .accessor = "inverseWorldMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX, .accessor = "transposeWorldMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_WORLD_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX, .accessor = "inverseTransposeWorldMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_MATRIX, }, { .value = CONST_SRC_CODE_VIEW_MATRIX, .accessor = "viewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_VIEW_MATRIX, .accessor = "inverseViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX, .accessor = "transposeViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX, .accessor = "inverseTransposeViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_INVERSE_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_PROJECTION_MATRIX, .accessor = "projectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX, .accessor = "inverseProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX, .accessor = "transposeProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX, .accessor = "inverseTransposeProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_WORLD_VIEW_MATRIX, .accessor = "worldViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX, .accessor = "inverseWorldViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX, .accessor = "transposeWorldViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_WORLD_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX, .accessor = "inverseTransposeWorldViewMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX, }, { .value = CONST_SRC_CODE_VIEW_PROJECTION_MATRIX, .accessor = "viewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX, .accessor = "inverseViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX, .accessor = "transposeViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX, .accessor = "inverseTransposeViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT, + .transposedMatrix = CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX, .accessor = "worldViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX, .accessor = "inverseWorldViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX, .accessor = "transposeWorldViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX, .accessor = "inverseTransposeWorldViewProjectionMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX, }, { .value = CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX, .accessor = "shadowLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX, .accessor = "inverseShadowLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, .accessor = "transposeShadowLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, .accessor = "inverseTransposeShadowLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .transposedMatrix = CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX, .accessor = "worldOutdoorLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX, .accessor = "inverseWorldOutdoorLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, .accessor = "transposeWorldOutdoorLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX, }, { .value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, .accessor = "inverseTransposeWorldOutdoorLookupMatrix", .arrayCount = 0, .updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM, + .transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX, }, }; @@ -1538,11 +1577,13 @@ namespace T6 .value = TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY, .accessor = "lightmapSamplerPrimary", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM, + .customSamplerIndex = CUSTOM_SAMPLER_LIGHTMAP_PRIMARY, }, { .value = TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY, .accessor = "lightmapSamplerSecondary", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM, + .customSamplerIndex = CUSTOM_SAMPLER_LIGHTMAP_SECONDARY, }, { .value = TEXTURE_SRC_CODE_SHADOWMAP_SUN, @@ -1563,11 +1604,13 @@ namespace T6 .value = TEXTURE_SRC_CODE_RESOLVED_POST_SUN, .accessor = "resolvedPostSun", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_1, }, { .value = TEXTURE_SRC_CODE_RESOLVED_SCENE, .accessor = "resolvedScene", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_2, }, { .value = TEXTURE_SRC_CODE_POST_EFFECT_SRC, @@ -1608,16 +1651,19 @@ namespace T6 .value = TEXTURE_SRC_CODE_FLOATZ, .accessor = "floatZSampler", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_40, }, { .value = TEXTURE_SRC_CODE_PROCESSED_FLOATZ, .accessor = "processedFloatZSampler", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_40, }, { .value = TEXTURE_SRC_CODE_RAW_FLOATZ, .accessor = "rawFloatZSampler", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY, + .techFlags = TECHNIQUE_FLAG_40, }, { .value = TEXTURE_SRC_CODE_STENCIL, @@ -1648,6 +1694,7 @@ namespace T6 .value = TEXTURE_SRC_CODE_REFLECTION_PROBE, .accessor = "reflectionProbeSampler", .updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM, + .customSamplerIndex = CUSTOM_SAMPLER_REFLECTION_PROBE, }, { .value = TEXTURE_SRC_CODE_FEATHER_FLOAT_Z, @@ -1791,6 +1838,33 @@ namespace T6 }, }; + // See MaterialShaderArgumentType + static inline techset::CommonShaderArgumentType commonArgumentTypes[]{ + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_SAMPLER}, + {.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::CODE_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST }, + {.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST }, + }; + static_assert(std::extent_v == MLT_ARG_COUNT); + + static inline const char* commonIgnoredArgAccessors[]{ + "combined_dlight", + "combined_glight", + }; + + static inline techset::CommonCodeSourceInfos commonCodeSourceInfos(commonCodeConstSources, + std::extent_v, + commonCodeSamplerSources, + std::extent_v, + commonIgnoredArgAccessors, + std::extent_v, + commonArgumentTypes, + std::extent_v); + static inline MaterialTypeInfo g_materialTypeInfo[]{ {"", "" }, {"m/", "m_" }, diff --git a/src/ObjCommon/Techset/CommonTechnique.cpp b/src/ObjCommon/Techset/CommonTechnique.cpp index a28b2a9c..f0e9ae1b 100644 --- a/src/ObjCommon/Techset/CommonTechnique.cpp +++ b/src/ObjCommon/Techset/CommonTechnique.cpp @@ -1,15 +1,22 @@ #include "CommonTechnique.h" #include +#include namespace techset { CommonCodeSourceInfos::CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos, const size_t codeConstCount, const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos, - const size_t codeSamplerCount) + const size_t codeSamplerCount, + const char** ignoreArgAccessors, + const size_t ignoredArgAccessorCount, + const CommonShaderArgumentType* argumentTypes, + const size_t argumentTypeCount) : m_code_const_source_infos(codeConstCount), - m_code_sampler_source_infos(codeSamplerCount) + m_code_sampler_source_infos(codeSamplerCount), + m_ignored_arg_accessors(ignoredArgAccessorCount), + m_argument_types(argumentTypeCount) { std::copy(codeConstSourceInfos, &codeConstSourceInfos[codeConstCount], m_code_const_source_infos.data()); std::ranges::sort(m_code_const_source_infos, @@ -24,6 +31,21 @@ namespace techset { return a.value < b.value; }); + + for (size_t i = 0; i < ignoredArgAccessorCount; i++) + m_ignored_arg_accessors.emplace(ignoreArgAccessors[i]); + + std::copy(argumentTypes, &argumentTypes[argumentTypeCount], m_argument_types.data()); + + for (const auto& codeConstInfo : m_code_const_source_infos) + { + m_code_const_lookup.emplace(codeConstInfo.accessor, codeConstInfo.value); + } + + for (const auto& codeSamplerInfo : m_code_sampler_source_infos) + { + m_code_sampler_lookup.emplace(codeSamplerInfo.accessor, codeSamplerInfo.value); + } } std::optional CommonCodeSourceInfos::GetInfoForCodeConstSource(const CommonCodeConstSource codeConstSource) const @@ -55,6 +77,38 @@ namespace techset return std::nullopt; } + bool CommonCodeSourceInfos::IsArgAccessorIgnored(const std::string& accessor) const + { + return m_ignored_arg_accessors.contains(accessor); + } + + std::optional CommonCodeSourceInfos::GetCodeConstSourceForAccessor(const std::string& accessor) const + { + const auto foundEntry = m_code_const_lookup.find(accessor); + if (foundEntry == m_code_const_lookup.end()) + return std::nullopt; + + return foundEntry->second; + } + + std::optional CommonCodeSourceInfos::GetCodeSamplerSourceForAccessor(const std::string& accessor) const + { + const auto foundEntry = m_code_sampler_lookup.find(accessor); + if (foundEntry == m_code_sampler_lookup.end()) + return std::nullopt; + + return foundEntry->second; + } + + std::optional CommonCodeSourceInfos::GetArgumentTypeNumericValue(const CommonShaderArgumentType& argumentType) const + { + const auto foundValue = std::ranges::find(m_argument_types, argumentType); + if (foundValue == m_argument_types.end()) + return std::nullopt; + + return static_cast(foundValue - m_argument_types.begin()); + } + CommonStreamRoutingInfos::CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos, const size_t sourceCount, const CommonStreamRoutingDestinationInfo* destinationNames, @@ -64,6 +118,18 @@ namespace techset { std::copy(sourceInfos, &sourceInfos[sourceCount], m_sources.data()); std::copy(destinationNames, &destinationNames[destinationCount], m_destinations.data()); + + for (size_t i = 0; i < sourceCount; i++) + { + m_source_name_lookup[sourceInfos[i].name] = static_cast(i); + m_source_abbreviation_lookup[sourceInfos[i].abbreviation] = static_cast(i); + } + + for (size_t i = 0; i < destinationCount; i++) + { + m_destination_name_lookup[destinationNames[i].name] = static_cast(i); + m_destination_abbreviation_lookup[destinationNames[i].abbreviation] = static_cast(i); + } } const char* CommonStreamRoutingInfos::GetSourceName(const CommonStreamSource source) const @@ -105,4 +171,40 @@ namespace techset return m_destinations[destination].abbreviation; } + + std::optional CommonStreamRoutingInfos::GetSourceByName(const std::string& name) const + { + const auto foundSource = m_source_name_lookup.find(name); + if (foundSource != m_source_name_lookup.end()) + return foundSource->second; + + return std::nullopt; + } + + std::optional CommonStreamRoutingInfos::GetSourceByAbbreviation(const std::string& abbreviation) const + { + const auto foundSource = m_source_abbreviation_lookup.find(abbreviation); + if (foundSource != m_source_abbreviation_lookup.end()) + return foundSource->second; + + return std::nullopt; + } + + std::optional CommonStreamRoutingInfos::GetDestinationByName(const std::string& name) const + { + const auto foundDestination = m_destination_name_lookup.find(name); + if (foundDestination != m_destination_name_lookup.end()) + return foundDestination->second; + + return std::nullopt; + } + + std::optional CommonStreamRoutingInfos::GetDestinationByAbbreviation(const std::string& abbreviation) const + { + const auto foundDestination = m_destination_abbreviation_lookup.find(abbreviation); + if (foundDestination != m_destination_abbreviation_lookup.end()) + return foundDestination->second; + + return std::nullopt; + } } // namespace techset diff --git a/src/ObjCommon/Techset/CommonTechnique.h b/src/ObjCommon/Techset/CommonTechnique.h index 37dcfe3f..4ae50e10 100644 --- a/src/ObjCommon/Techset/CommonTechnique.h +++ b/src/ObjCommon/Techset/CommonTechnique.h @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include namespace techset @@ -27,12 +30,46 @@ namespace techset const char* abbreviation; }; + enum class CommonTechniqueShaderType : std::uint8_t + { + VERTEX, + PIXEL + }; + + enum class CommonShaderValueType : std::uint8_t + { + // Value is set to a float4 value in the pass + LITERAL_CONST, + // Value is set to a float4 value in the material + MATERIAL_CONST, + // Value is set to a float4 value calculated in code + CODE_CONST, + // Value is set to a sampler from the material + MATERIAL_SAMPLER, + // Value is set to a sampler generated in code + CODE_SAMPLER + }; + + constexpr bool IsConstValueType(const CommonShaderValueType valueType) + { + return valueType == CommonShaderValueType::LITERAL_CONST || valueType == CommonShaderValueType::MATERIAL_CONST + || valueType == CommonShaderValueType::CODE_CONST; + } + + constexpr bool IsSamplerValueType(const CommonShaderValueType valueType) + { + return valueType == CommonShaderValueType::MATERIAL_SAMPLER || valueType == CommonShaderValueType::CODE_SAMPLER; + } + enum class CommonCodeSourceUpdateFrequency : std::uint8_t { PER_PRIM, PER_OBJECT, RARELY, CUSTOM, + IGNORE, + + COUNT }; struct CommonCodeConstSourceInfo @@ -41,6 +78,8 @@ namespace techset const char* accessor; std::uint8_t arrayCount; CommonCodeSourceUpdateFrequency updateFrequency; + std::optional techFlags; + std::optional transposedMatrix; }; struct CommonCodeSamplerSourceInfo @@ -48,6 +87,24 @@ namespace techset CommonCodeSamplerSource value; const char* accessor; CommonCodeSourceUpdateFrequency updateFrequency; + std::optional techFlags; + std::optional customSamplerIndex; + }; + + struct CommonShaderArgumentType + { + friend bool operator==(const CommonShaderArgumentType& lhs, const CommonShaderArgumentType& rhs) + { + return lhs.m_shader_type == rhs.m_shader_type && lhs.m_value_type == rhs.m_value_type; + } + + friend bool operator!=(const CommonShaderArgumentType& lhs, const CommonShaderArgumentType& rhs) + { + return !(lhs == rhs); + } + + CommonTechniqueShaderType m_shader_type; + CommonShaderValueType m_value_type; }; class CommonCodeSourceInfos @@ -56,14 +113,36 @@ namespace techset CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos, size_t codeConstCount, const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos, - size_t codeSamplerCount); + size_t codeSamplerCount, + const char** ignoreArgAccessors, + size_t ignoredArgAccessorCount, + const CommonShaderArgumentType* argumentTypes, + size_t argumentTypeCount); [[nodiscard]] std::optional GetInfoForCodeConstSource(CommonCodeConstSource codeConstSource) const; [[nodiscard]] std::optional GetInfoForCodeSamplerSource(CommonCodeSamplerSource codeSamplerSource) const; + /** + * \brief Some games like T6 do not create args for certain variables. This checks whether an accessor identifies one of these variables. + * \param accessor The accessor of the variable + * \return \c true if the accessor should be ignored + */ + [[nodiscard]] bool IsArgAccessorIgnored(const std::string& accessor) const; + + [[nodiscard]] std::optional GetCodeConstSourceForAccessor(const std::string& accessor) const; + [[nodiscard]] std::optional GetCodeSamplerSourceForAccessor(const std::string& accessor) const; + + [[nodiscard]] std::optional GetArgumentTypeNumericValue(const CommonShaderArgumentType& argumentType) const; + private: std::vector m_code_const_source_infos; std::vector m_code_sampler_source_infos; + std::unordered_set m_ignored_arg_accessors; + + std::unordered_map m_code_const_lookup; + std::unordered_map m_code_sampler_lookup; + + std::vector m_argument_types; }; class CommonStreamRoutingInfos @@ -79,10 +158,18 @@ namespace techset [[nodiscard]] bool IsSourceOptional(CommonStreamSource source) const; [[nodiscard]] const char* GetDestinationName(CommonStreamDestination destination) const; [[nodiscard]] const char* GetDestinationAbbreviation(CommonStreamDestination destination) const; + [[nodiscard]] std::optional GetSourceByName(const std::string& name) const; + [[nodiscard]] std::optional GetSourceByAbbreviation(const std::string& abbreviation) const; + [[nodiscard]] std::optional GetDestinationByName(const std::string& name) const; + [[nodiscard]] std::optional GetDestinationByAbbreviation(const std::string& abbreviation) const; private: std::vector m_sources; std::vector m_destinations; + std::unordered_map m_source_name_lookup; + std::unordered_map m_destination_name_lookup; + std::unordered_map m_source_abbreviation_lookup; + std::unordered_map m_destination_abbreviation_lookup; }; union CommonShaderArgValue diff --git a/src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp b/src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp index a68a8206..22a11b2a 100644 --- a/src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp +++ b/src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp @@ -270,13 +270,6 @@ namespace void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset) { - static techset::CommonCodeSourceInfos codeSourceInfos(commonCodeConstSources, - std::extent_v, - commonCodeSamplerSources, - std::extent_v); - static techset::CommonStreamRoutingInfos routingInfos( - streamRoutingSources, std::extent_v, streamRoutingDestinations, std::extent_v); - auto* techniqueState = context.GetZoneAssetDumperState(); const auto* materialConstantState = context.GetZoneAssetDumperState(); for (const auto* technique : techset.techniques) @@ -285,7 +278,7 @@ namespace { const auto commonTechnique = ConvertToCommonTechnique(*technique); - techset::DumpCommonTechnique(context, commonTechnique, codeSourceInfos, routingInfos, *materialConstantState); + techset::DumpCommonTechnique(context, commonTechnique, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState); } } } diff --git a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp index 699dd34d..68eac6e3 100644 --- a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp @@ -281,13 +281,6 @@ namespace void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset) { - static techset::CommonCodeSourceInfos codeSourceInfos(commonCodeConstSources, - std::extent_v, - commonCodeSamplerSources, - std::extent_v); - static techset::CommonStreamRoutingInfos routingInfos( - streamRoutingSources, std::extent_v, streamRoutingDestinations, std::extent_v); - auto* techniqueState = context.GetZoneAssetDumperState(); const auto* materialConstantState = context.GetZoneAssetDumperState(); for (const auto* technique : techset.techniques) @@ -296,7 +289,7 @@ namespace { const auto commonTechnique = ConvertToCommonTechnique(*technique); - techset::DumpCommonTechnique(context, commonTechnique, codeSourceInfos, routingInfos, *materialConstantState); + techset::DumpCommonTechnique(context, commonTechnique, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState); } } }