mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
chore: generalize material constant zone state
This commit is contained in:
parent
88499b6428
commit
3b59dad109
@ -21,6 +21,11 @@ namespace T6
|
||||
return hash;
|
||||
}
|
||||
|
||||
static constexpr uint32_t R_HashString(const char* string)
|
||||
{
|
||||
return R_HashString(string, 0u);
|
||||
}
|
||||
|
||||
static constexpr uint32_t SND_HashName(const char* str)
|
||||
{
|
||||
if (!str || !*str)
|
||||
|
@ -61,12 +61,12 @@ namespace d3d9
|
||||
uint32_t TypeInfo;
|
||||
};
|
||||
|
||||
bool PopulateVersionInfo(ShaderInfo& shaderInfo, const uint32_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
bool PopulateVersionInfo(ShaderInfo& shaderInfo, const void* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
if (shaderByteCodeSize < sizeof(uint32_t))
|
||||
return false;
|
||||
|
||||
const auto version = *shaderByteCode;
|
||||
const auto version = *static_cast<const uint32_t*>(shaderByteCode);
|
||||
shaderInfo.m_version_minor = version & 0xFF;
|
||||
shaderInfo.m_version_major = (version & 0xFF00) >> 8;
|
||||
|
||||
@ -91,10 +91,10 @@ namespace d3d9
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FindComment(const uint32_t* shaderByteCode, const size_t shaderByteCodeSize, const uint32_t magic, const char*& commentStart, size_t& commentSize)
|
||||
bool FindComment(const uint8_t* shaderByteCode, const size_t shaderByteCodeSize, const uint32_t magic, const char*& commentStart, size_t& commentSize)
|
||||
{
|
||||
const uint32_t* currentPos = shaderByteCode + 1;
|
||||
size_t currentOffset = sizeof(uint32_t);
|
||||
const auto* currentPos = reinterpret_cast<const uint32_t*>(shaderByteCode + sizeof(uint32_t));
|
||||
auto currentOffset = sizeof(uint32_t);
|
||||
while (*currentPos != OPCODE_END && (currentOffset + sizeof(uint32_t) - 1) < shaderByteCodeSize)
|
||||
{
|
||||
const auto currentValue = *currentPos;
|
||||
@ -215,7 +215,7 @@ namespace d3d9
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateShaderInfoFromShaderByteCode(ShaderInfo& shaderInfo, const uint32_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
bool PopulateShaderInfoFromShaderByteCode(ShaderInfo& shaderInfo, const uint8_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
if (!PopulateVersionInfo(shaderInfo, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
@ -236,14 +236,14 @@ namespace d3d9
|
||||
}
|
||||
} // namespace d3d9
|
||||
|
||||
std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const uint32_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const void* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
if (shaderByteCode == nullptr || shaderByteCodeSize == 0)
|
||||
return nullptr;
|
||||
|
||||
auto shaderInfo = std::make_unique<ShaderInfo>();
|
||||
|
||||
if (!PopulateShaderInfoFromShaderByteCode(*shaderInfo, shaderByteCode, shaderByteCodeSize))
|
||||
if (!PopulateShaderInfoFromShaderByteCode(*shaderInfo, static_cast<const uint8_t*>(shaderByteCode), shaderByteCodeSize))
|
||||
return nullptr;
|
||||
|
||||
return shaderInfo;
|
||||
|
@ -95,6 +95,6 @@ namespace d3d9
|
||||
class ShaderAnalyser
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<ShaderInfo> GetShaderInfo(const uint32_t* shaderByteCode, size_t shaderByteCodeSize);
|
||||
static std::unique_ptr<ShaderInfo> GetShaderInfo(const void* shaderByteCode, size_t shaderByteCodeSize);
|
||||
};
|
||||
} // namespace d3d9
|
||||
|
@ -4,16 +4,9 @@
|
||||
#include "Game/T6/GameAssetPoolT6.h"
|
||||
#include "Game/T6/GameT6.h"
|
||||
#include "ObjWriting.h"
|
||||
#include "Shader/D3D11ShaderAnalyser.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace T6
|
||||
{
|
||||
static constexpr const char* SAMPLER_STR = "Sampler";
|
||||
static constexpr const char* GLOBALS_CBUFFER_NAME = "$Globals";
|
||||
static constexpr const char* PER_OBJECT_CONSTS_CBUFFER_NAME = "PerObjectConsts";
|
||||
|
||||
const char* KNOWN_CONSTANT_NAMES[]{
|
||||
"AngularVelocityScale",
|
||||
"AnimSpeed",
|
||||
@ -478,15 +471,8 @@ namespace T6
|
||||
"ui3dSampler",
|
||||
};
|
||||
|
||||
void MaterialConstantZoneState::ExtractNamesFromZone()
|
||||
void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
|
||||
{
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
std::cout << "Building material constant name lookup...\n";
|
||||
|
||||
const auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
AddStaticKnownNames();
|
||||
|
||||
for (const auto* zone : g_GameT6.GetZones())
|
||||
{
|
||||
const auto* t6AssetPools = dynamic_cast<const GameAssetPoolT6*>(zone->m_pools.get());
|
||||
@ -504,49 +490,18 @@ namespace T6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
{
|
||||
const auto durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
|
||||
std::cout << "Built material constant name lookup in " << durationInMs.count() << "ms: " << m_constant_names_from_shaders.size()
|
||||
<< " constant names; " << m_texture_def_names_from_shaders.size() << " texture def names\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialConstantZoneState::GetConstantName(const unsigned hash, std::string& constantName) const
|
||||
unsigned MaterialConstantZoneState::HashString(const std::string& str)
|
||||
{
|
||||
const auto existingConstantName = m_constant_names_from_shaders.find(hash);
|
||||
if (existingConstantName != m_constant_names_from_shaders.end())
|
||||
{
|
||||
constantName = existingConstantName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MaterialConstantZoneState::GetTextureDefName(const unsigned hash, std::string& textureDefName) const
|
||||
{
|
||||
const auto existingTextureDefName = m_texture_def_names_from_shaders.find(hash);
|
||||
if (existingTextureDefName != m_texture_def_names_from_shaders.end())
|
||||
{
|
||||
textureDefName = existingTextureDefName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return Common::R_HashString(str.c_str());
|
||||
}
|
||||
|
||||
void MaterialConstantZoneState::ExtractNamesFromTechnique(const MaterialTechnique* technique)
|
||||
{
|
||||
const auto existingTechnique = m_dumped_techniques.find(technique);
|
||||
if (existingTechnique != m_dumped_techniques.end())
|
||||
if (!ShouldDumpFromStruct(technique))
|
||||
return;
|
||||
|
||||
m_dumped_techniques.emplace(technique);
|
||||
|
||||
for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++)
|
||||
{
|
||||
const auto& pass = technique->passArray[passIndex];
|
||||
@ -559,54 +514,6 @@ namespace T6
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialConstantZoneState::ExtractNamesFromShader(const char* shader, const size_t shaderSize)
|
||||
{
|
||||
const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(reinterpret_cast<const uint8_t*>(shader), shaderSize);
|
||||
if (!shaderInfo)
|
||||
return;
|
||||
|
||||
const auto globalsConstantBuffer = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == GLOBALS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
const auto perObjectConsts = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == PER_OBJECT_CONSTS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
if (globalsConstantBuffer != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : globalsConstantBuffer->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
if (perObjectConsts != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : perObjectConsts->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
for (const auto& boundResource : shaderInfo->m_bound_resources)
|
||||
{
|
||||
if (boundResource.m_type == d3d11::BoundResourceType::SAMPLER || boundResource.m_type == d3d11::BoundResourceType::TEXTURE)
|
||||
{
|
||||
if (AddTextureDefName(boundResource.m_name))
|
||||
{
|
||||
const auto samplerPos = boundResource.m_name.rfind(SAMPLER_STR);
|
||||
if (samplerPos != std::string::npos)
|
||||
{
|
||||
auto nameWithoutSamplerStr = boundResource.m_name;
|
||||
nameWithoutSamplerStr.erase(samplerPos, std::char_traits<char>::length(SAMPLER_STR));
|
||||
AddTextureDefName(std::move(nameWithoutSamplerStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialConstantZoneState::AddStaticKnownNames()
|
||||
{
|
||||
for (const auto* knownConstantName : KNOWN_CONSTANT_NAMES)
|
||||
@ -614,23 +521,4 @@ namespace T6
|
||||
for (const auto* knownTextureDefName : KNOWN_TEXTURE_DEF_NAMES)
|
||||
AddTextureDefName(knownTextureDefName);
|
||||
}
|
||||
|
||||
void MaterialConstantZoneState::AddConstantName(std::string constantName)
|
||||
{
|
||||
const auto hash = Common::R_HashString(constantName.c_str(), 0);
|
||||
if (m_constant_names_from_shaders.contains(hash))
|
||||
return;
|
||||
|
||||
m_constant_names_from_shaders.emplace(hash, std::move(constantName));
|
||||
}
|
||||
|
||||
bool MaterialConstantZoneState::AddTextureDefName(std::string textureDefName)
|
||||
{
|
||||
const auto hash = Common::R_HashString(textureDefName.c_str(), 0);
|
||||
if (m_texture_def_names_from_shaders.contains(hash))
|
||||
return false;
|
||||
|
||||
m_texture_def_names_from_shaders.emplace(hash, std::move(textureDefName));
|
||||
return true;
|
||||
}
|
||||
} // namespace T6
|
||||
|
@ -1,30 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/IZoneAssetDumperState.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Material/AbstractMaterialConstantZoneState.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class MaterialConstantZoneState final : public IZoneAssetDumperState
|
||||
class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx11
|
||||
{
|
||||
public:
|
||||
void ExtractNamesFromZone();
|
||||
bool GetConstantName(unsigned hash, std::string& constantName) const;
|
||||
bool GetTextureDefName(unsigned hash, std::string& textureDefName) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void ExtractNamesFromZoneInternal() override;
|
||||
void ExtractNamesFromTechnique(const MaterialTechnique* technique);
|
||||
void ExtractNamesFromShader(const char* shader, size_t shaderSize);
|
||||
void AddStaticKnownNames();
|
||||
void AddConstantName(std::string constantName);
|
||||
bool AddTextureDefName(std::string textureDefName);
|
||||
|
||||
std::unordered_set<const MaterialTechnique*> m_dumped_techniques;
|
||||
std::unordered_map<unsigned, std::string> m_constant_names_from_shaders;
|
||||
std::unordered_map<unsigned, std::string> m_texture_def_names_from_shaders;
|
||||
void AddStaticKnownNames() override;
|
||||
unsigned HashString(const std::string& str) override;
|
||||
};
|
||||
} // namespace T6
|
||||
|
164
src/ObjWriting/Material/AbstractMaterialConstantZoneState.cpp
Normal file
164
src/ObjWriting/Material/AbstractMaterialConstantZoneState.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include "AbstractMaterialConstantZoneState.h"
|
||||
|
||||
#include "ObjWriting.h"
|
||||
#include "Shader/D3D11ShaderAnalyser.h"
|
||||
#include "Shader/D3D9ShaderAnalyser.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char* SAMPLER_STR = "Sampler";
|
||||
constexpr const char* GLOBALS_CBUFFER_NAME = "$Globals";
|
||||
constexpr const char* PER_OBJECT_CONSTS_CBUFFER_NAME = "PerObjectConsts";
|
||||
} // namespace
|
||||
|
||||
void AbstractMaterialConstantZoneState::ExtractNamesFromZone()
|
||||
{
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
std::cout << "Building material constant name lookup...\n";
|
||||
|
||||
const auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
AddStaticKnownNames();
|
||||
|
||||
ExtractNamesFromZoneInternal();
|
||||
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
{
|
||||
const auto durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
|
||||
std::cout << std::format("Built material constant name lookup in {}ms: {} constant names; {} texture def names\n",
|
||||
durationInMs.count(),
|
||||
m_constant_names_from_shaders.size(),
|
||||
m_texture_def_names_from_shaders.size());
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractMaterialConstantZoneState::GetConstantName(const unsigned hash, std::string& constantName) const
|
||||
{
|
||||
const auto existingConstantName = m_constant_names_from_shaders.find(hash);
|
||||
if (existingConstantName != m_constant_names_from_shaders.end())
|
||||
{
|
||||
constantName = existingConstantName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractMaterialConstantZoneState::GetTextureDefName(const unsigned hash, std::string& textureDefName) const
|
||||
{
|
||||
const auto existingTextureDefName = m_texture_def_names_from_shaders.find(hash);
|
||||
if (existingTextureDefName != m_texture_def_names_from_shaders.end())
|
||||
{
|
||||
textureDefName = existingTextureDefName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractMaterialConstantZoneState::ShouldDumpFromStruct(const void* pStruct)
|
||||
{
|
||||
const auto existingTextureDefName = m_dumped_structs.find(pStruct);
|
||||
if (existingTextureDefName != m_dumped_structs.end())
|
||||
return false;
|
||||
|
||||
m_dumped_structs.emplace(pStruct);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AbstractMaterialConstantZoneState::AddConstantName(const std::string& constantName)
|
||||
{
|
||||
const auto hash = HashString(constantName);
|
||||
if (m_constant_names_from_shaders.contains(hash))
|
||||
return;
|
||||
|
||||
m_constant_names_from_shaders.emplace(hash, constantName);
|
||||
}
|
||||
|
||||
bool AbstractMaterialConstantZoneState::AddTextureDefName(const std::string& textureDefName)
|
||||
{
|
||||
const auto hash = HashString(textureDefName);
|
||||
if (m_texture_def_names_from_shaders.contains(hash))
|
||||
return false;
|
||||
|
||||
m_texture_def_names_from_shaders.emplace(hash, textureDefName);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AbstractMaterialConstantZoneStateDx9::ExtractNamesFromShader(const void* shader, const size_t shaderSize)
|
||||
{
|
||||
const auto shaderInfo = d3d9::ShaderAnalyser::GetShaderInfo(shader, shaderSize);
|
||||
if (!shaderInfo)
|
||||
return;
|
||||
|
||||
for (const auto& constant : shaderInfo->m_constants)
|
||||
{
|
||||
if (constant.m_register_set == d3d9::RegisterSet::SAMPLER)
|
||||
{
|
||||
if (AddTextureDefName(constant.m_name))
|
||||
{
|
||||
const auto samplerPos = constant.m_name.rfind(SAMPLER_STR);
|
||||
if (samplerPos != std::string::npos)
|
||||
{
|
||||
auto nameWithoutSamplerStr = constant.m_name;
|
||||
nameWithoutSamplerStr.erase(samplerPos, std::char_traits<char>::length(SAMPLER_STR));
|
||||
AddTextureDefName(nameWithoutSamplerStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
AddConstantName(constant.m_name);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractMaterialConstantZoneStateDx11::ExtractNamesFromShader(const void* shader, const size_t shaderSize)
|
||||
{
|
||||
const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(static_cast<const uint8_t*>(shader), shaderSize);
|
||||
if (!shaderInfo)
|
||||
return;
|
||||
|
||||
const auto globalsConstantBuffer = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == GLOBALS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
const auto perObjectConsts = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == PER_OBJECT_CONSTS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
if (globalsConstantBuffer != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : globalsConstantBuffer->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
if (perObjectConsts != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : perObjectConsts->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
for (const auto& boundResource : shaderInfo->m_bound_resources)
|
||||
{
|
||||
if (boundResource.m_type == d3d11::BoundResourceType::SAMPLER || boundResource.m_type == d3d11::BoundResourceType::TEXTURE)
|
||||
{
|
||||
if (AddTextureDefName(boundResource.m_name))
|
||||
{
|
||||
const auto samplerPos = boundResource.m_name.rfind(SAMPLER_STR);
|
||||
if (samplerPos != std::string::npos)
|
||||
{
|
||||
auto nameWithoutSamplerStr = boundResource.m_name;
|
||||
nameWithoutSamplerStr.erase(samplerPos, std::char_traits<char>::length(SAMPLER_STR));
|
||||
AddTextureDefName(nameWithoutSamplerStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
src/ObjWriting/Material/AbstractMaterialConstantZoneState.h
Normal file
41
src/ObjWriting/Material/AbstractMaterialConstantZoneState.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/IZoneAssetDumperState.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
class AbstractMaterialConstantZoneState : public IZoneAssetDumperState
|
||||
{
|
||||
public:
|
||||
void ExtractNamesFromZone();
|
||||
bool GetConstantName(unsigned hash, std::string& constantName) const;
|
||||
bool GetTextureDefName(unsigned hash, std::string& textureDefName) const;
|
||||
|
||||
protected:
|
||||
virtual void ExtractNamesFromShader(const void* shader, size_t shaderSize) = 0;
|
||||
virtual void ExtractNamesFromZoneInternal() = 0;
|
||||
virtual void AddStaticKnownNames() = 0;
|
||||
virtual unsigned HashString(const std::string& str) = 0;
|
||||
|
||||
bool ShouldDumpFromStruct(const void* pStruct);
|
||||
void AddConstantName(const std::string& constantName);
|
||||
bool AddTextureDefName(const std::string& textureDefName);
|
||||
|
||||
std::unordered_set<const void*> m_dumped_structs;
|
||||
std::unordered_map<unsigned, std::string> m_constant_names_from_shaders;
|
||||
std::unordered_map<unsigned, std::string> m_texture_def_names_from_shaders;
|
||||
};
|
||||
|
||||
class AbstractMaterialConstantZoneStateDx9 : public AbstractMaterialConstantZoneState
|
||||
{
|
||||
protected:
|
||||
void ExtractNamesFromShader(const void* shader, size_t shaderSize) override;
|
||||
};
|
||||
|
||||
class AbstractMaterialConstantZoneStateDx11 : public AbstractMaterialConstantZoneState
|
||||
{
|
||||
protected:
|
||||
void ExtractNamesFromShader(const void* shader, size_t shaderSize) override;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user