Set technique flags based on used constants, samplers and technique names

This commit is contained in:
Jan 2022-04-16 22:51:38 +02:00
parent 6e57834dc6
commit 6ff86ae5e7
2 changed files with 88 additions and 9 deletions

View File

@ -1225,7 +1225,7 @@ namespace IW4
TECHNIQUE_FLAG_20 = 0x20, // techniques with _i_ in its name (all use texcoord[1] in decl -> other optional stream sources are not used at all so might be any optional) TECHNIQUE_FLAG_20 = 0x20, // techniques with _i_ in its name (all use texcoord[1] in decl -> other optional stream sources are not used at all so might be any optional)
TECHNIQUE_FLAG_40 = 0x40, // uses code constant light.spotDir or light.spotFactors TECHNIQUE_FLAG_40 = 0x40, // uses code constant light.spotDir or light.spotFactors
TECHNIQUE_FLAG_80 = 0x80, // uses floatZ sampler and does not have 0x100 flag TECHNIQUE_FLAG_80 = 0x80, // uses floatZ sampler and does not have 0x100 flag
TECHNIQUE_FLAG_100 = 0x100, // distortion_scale_zfeather_dtex + distortion_scale_ua_zfeather TECHNIQUE_FLAG_100 = 0x100, // distortion_scale_zfeather_dtex + distortion_scale_ua_zfeather + distortion_scale_zfeather
TECHNIQUE_FLAG_200 = 0x200, // ? TECHNIQUE_FLAG_200 = 0x200, // ?
}; };

View File

@ -388,7 +388,7 @@ namespace IW4
// Sort args by their update frequency // Sort args by their update frequency
std::sort(pass.m_arguments.begin(), pass.m_arguments.end(), [](const PassShaderArgument& arg1, const PassShaderArgument& arg2) std::sort(pass.m_arguments.begin(), pass.m_arguments.end(), [](const PassShaderArgument& arg1, const PassShaderArgument& arg2)
{ {
if(arg1.m_update_frequency != arg2.m_update_frequency) if (arg1.m_update_frequency != arg2.m_update_frequency)
return arg1.m_update_frequency < arg2.m_update_frequency; return arg1.m_update_frequency < arg2.m_update_frequency;
if (arg1.m_arg.type != arg2.m_arg.type) if (arg1.m_arg.type != arg2.m_arg.type)
@ -995,16 +995,77 @@ namespace IW4
static void UpdateTechniqueFlags(MaterialTechnique& technique) static void UpdateTechniqueFlags(MaterialTechnique& technique)
{ {
// This is stupid but that's what the game does // This is stupid but that's what the game does for zprepass for sure
if("zprepass"s == technique.name) // The other ones might be handled by the game in the same fashion because there is not recognizable pattern that connects the shaders with the same flags
technique.flags |= 4u; static std::unordered_map<std::string, size_t> flagsByTechniqueName({
{"zprepass", TECHNIQUE_FLAG_4 | TECHNIQUE_FLAG_200},
{"build_floatz", TECHNIQUE_FLAG_8},
{"build_shadowmap_depth", TECHNIQUE_FLAG_10 | TECHNIQUE_FLAG_200},
{"build_shadowmap_model", TECHNIQUE_FLAG_10 | TECHNIQUE_FLAG_200},
{"distortion_scale_ua_zfeather", TECHNIQUE_FLAG_100},
{"distortion_scale_zfeather", TECHNIQUE_FLAG_100},
{"distortion_scale_zfeather_dtex", TECHNIQUE_FLAG_100},
{"alternate_scene_overlay", TECHNIQUE_FLAG_200},
{"blur_apply", TECHNIQUE_FLAG_200},
{"build_floatz", TECHNIQUE_FLAG_200},
{"build_floatz_clear", TECHNIQUE_FLAG_200},
{"build_floatz_dtex", TECHNIQUE_FLAG_200},
{"build_floatz_ua", TECHNIQUE_FLAG_200},
{"build_floatz_ua_dtex", TECHNIQUE_FLAG_200},
{"build_shadowmap_depth_nc", TECHNIQUE_FLAG_200},
{"build_shadowmap_depth_ua", TECHNIQUE_FLAG_200},
{"build_shadowmap_model_dtex", TECHNIQUE_FLAG_200},
{"build_shadowmap_model_nc_dtex", TECHNIQUE_FLAG_200},
{"build_shadowmap_model_ua", TECHNIQUE_FLAG_200},
{"cinematic", TECHNIQUE_FLAG_200},
{"cinematic_3d", TECHNIQUE_FLAG_200},
{"cinematic_dtex_3d", TECHNIQUE_FLAG_200},
{"dof_near_coc", TECHNIQUE_FLAG_200},
{"floatz", TECHNIQUE_FLAG_200},
{"floatzdisplay", TECHNIQUE_FLAG_200},
{"particle_blend", TECHNIQUE_FLAG_200},
{"particle_zdownsample", TECHNIQUE_FLAG_200},
{"passthru_alpha", TECHNIQUE_FLAG_200},
{"postfx", TECHNIQUE_FLAG_200},
{"postfx_mblur", TECHNIQUE_FLAG_200},
{"processed_floatz", TECHNIQUE_FLAG_200},
{"ps3_aadownsample", TECHNIQUE_FLAG_200},
{"shell_shock", TECHNIQUE_FLAG_200},
{"shell_shock_flashed", TECHNIQUE_FLAG_200},
{"small_blur", TECHNIQUE_FLAG_200},
{"stencildisplay", TECHNIQUE_FLAG_200},
{"stencilshadow", TECHNIQUE_FLAG_200},
{"wireframe_solid", TECHNIQUE_FLAG_200},
{"wireframe_solid_atest_dtex", TECHNIQUE_FLAG_200},
{"wireframe_solid_dtex", TECHNIQUE_FLAG_200},
{"wireframe_solid_nc", TECHNIQUE_FLAG_200},
{"wireframe_solid_nc_dtex", TECHNIQUE_FLAG_200},
{"wireframe_solid_ua", TECHNIQUE_FLAG_200},
{"wireframe_solid_ua_dtex", TECHNIQUE_FLAG_200}
});
const auto flagsForName = flagsByTechniqueName.find(technique.name);
if (flagsForName != flagsByTechniqueName.end())
{
technique.flags |= flagsForName->second;
}
for (auto i = 0u; i < technique.passCount; i++)
{
const auto& pass = technique.passArray[i];
if (pass.vertexDecl && pass.vertexDecl->hasOptionalSource)
{
technique.flags |= TECHNIQUE_FLAG_20;
break;
}
}
} }
static void UpdateTechniqueFlagsForArgument(uint16_t& techniqueFlags, const TechniqueCreator::PassShaderArgument& arg) static void UpdateTechniqueFlagsForArgument(uint16_t& techniqueFlags, const TechniqueCreator::PassShaderArgument& arg)
{ {
if(arg.m_arg.type == MTL_ARG_CODE_PIXEL_SAMPLER) if (arg.m_arg.type == MTL_ARG_CODE_PIXEL_SAMPLER)
{ {
switch(arg.m_arg.u.codeSampler) switch (arg.m_arg.u.codeSampler)
{ {
case TEXTURE_SRC_CODE_RESOLVED_POST_SUN: case TEXTURE_SRC_CODE_RESOLVED_POST_SUN:
techniqueFlags |= TECHNIQUE_FLAG_1; techniqueFlags |= TECHNIQUE_FLAG_1;
@ -1012,6 +1073,24 @@ namespace IW4
case TEXTURE_SRC_CODE_RESOLVED_SCENE: case TEXTURE_SRC_CODE_RESOLVED_SCENE:
techniqueFlags |= TECHNIQUE_FLAG_2; techniqueFlags |= TECHNIQUE_FLAG_2;
break; break;
case TEXTURE_SRC_CODE_FLOATZ:
case TEXTURE_SRC_CODE_PROCESSED_FLOATZ:
case TEXTURE_SRC_CODE_RAW_FLOATZ:
if ((techniqueFlags & TECHNIQUE_FLAG_100) == 0)
techniqueFlags |= TECHNIQUE_FLAG_80;
break;
default:
break;
}
}
else if(arg.m_arg.type == MTL_ARG_CODE_VERTEX_CONST || arg.m_arg.type == MTL_ARG_CODE_PIXEL_CONST)
{
switch(arg.m_arg.u.codeConst.index)
{
case CONST_SRC_CODE_LIGHT_SPOTDIR:
case CONST_SRC_CODE_LIGHT_SPOTFACTORS:
techniqueFlags |= TECHNIQUE_FLAG_40;
break;
default: default:
break; break;
} }
@ -1073,8 +1152,6 @@ namespace IW4
out.perPrimArgCount = static_cast<unsigned char>(perPrimArgCount); out.perPrimArgCount = static_cast<unsigned char>(perPrimArgCount);
out.stableArgCount = static_cast<unsigned char>(stableArgCount); out.stableArgCount = static_cast<unsigned char>(stableArgCount);
UpdateTechniqueFlags(technique);
if (in.m_vertex_shader) if (in.m_vertex_shader)
dependencies.push_back(in.m_vertex_shader); dependencies.push_back(in.m_vertex_shader);
if (in.m_pixel_shader) if (in.m_pixel_shader)
@ -1092,6 +1169,8 @@ namespace IW4
technique->name = m_memory->Dup(techniqueName.c_str()); technique->name = m_memory->Dup(techniqueName.c_str());
technique->passCount = static_cast<uint16_t>(passes.size()); technique->passCount = static_cast<uint16_t>(passes.size());
UpdateTechniqueFlags(*technique);
for (auto i = 0u; i < passes.size(); i++) for (auto i = 0u; i < passes.size(); i++)
ConvertPass(*technique, technique->passArray[i], passes.at(i), dependencies); ConvertPass(*technique, technique->passArray[i], passes.at(i), dependencies);