mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-11-24 13:42:06 +00:00
feat: dump material techniques for T6
This commit is contained in:
@@ -32,14 +32,17 @@ namespace d3d11
|
|||||||
m_flags(0u)
|
m_flags(0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
} // namespace d3d11
|
||||||
|
|
||||||
static constexpr auto TAG_RDEF = FileUtils::MakeMagic32('R', 'D', 'E', 'F');
|
namespace
|
||||||
static constexpr auto TAG_SHDR = FileUtils::MakeMagic32('S', 'H', 'D', 'R');
|
{
|
||||||
|
constexpr auto TAG_RDEF = FileUtils::MakeMagic32('R', 'D', 'E', 'F');
|
||||||
|
constexpr auto TAG_SHDR = FileUtils::MakeMagic32('S', 'H', 'D', 'R');
|
||||||
|
|
||||||
static constexpr auto VERSION_5_0 = 0x500;
|
constexpr auto VERSION_5_0 = 0x500;
|
||||||
static constexpr auto VERSION_5_1 = 0x501;
|
constexpr auto VERSION_5_1 = 0x501;
|
||||||
static constexpr auto TARGET_VERSION_MASK = 0xFFFF;
|
constexpr auto TARGET_VERSION_MASK = 0xFFFF;
|
||||||
static constexpr auto CHUNK_TABLE_OFFSET = 28u;
|
constexpr auto CHUNK_TABLE_OFFSET = 28u;
|
||||||
|
|
||||||
struct FileRdefHeader
|
struct FileRdefHeader
|
||||||
{
|
{
|
||||||
@@ -669,16 +672,16 @@ namespace d3d11
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace d3d11
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const uint8_t* shader, const size_t shaderSize)
|
std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const void* shader, const size_t shaderSize)
|
||||||
{
|
{
|
||||||
if (shader == nullptr || shaderSize == 0)
|
if (shader == nullptr || shaderSize == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto shaderInfo = std::make_unique<ShaderInfo>();
|
auto shaderInfo = std::make_unique<ShaderInfo>();
|
||||||
|
|
||||||
if (!PopulateShaderInfoFromBytes(*shaderInfo, shader, shaderSize))
|
if (!PopulateShaderInfoFromBytes(*shaderInfo, static_cast<const uint8_t*>(shader), shaderSize))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return shaderInfo;
|
return shaderInfo;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace d3d11
|
namespace d3d11
|
||||||
{
|
{
|
||||||
enum class ShaderType
|
enum class ShaderType : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
PIXEL_SHADER,
|
PIXEL_SHADER,
|
||||||
@@ -33,7 +34,7 @@ namespace d3d11
|
|||||||
unsigned m_flags;
|
unsigned m_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ConstantBufferType
|
enum class ConstantBufferType : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
CBUFFER,
|
CBUFFER,
|
||||||
@@ -59,7 +60,7 @@ namespace d3d11
|
|||||||
std::vector<ConstantBufferVariable> m_variables;
|
std::vector<ConstantBufferVariable> m_variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BoundResourceType
|
enum class BoundResourceType : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
CBUFFER,
|
CBUFFER,
|
||||||
@@ -68,7 +69,7 @@ namespace d3d11
|
|||||||
SAMPLER
|
SAMPLER
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BoundResourceReturnType
|
enum class BoundResourceReturnType : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
UNORM,
|
UNORM,
|
||||||
@@ -81,7 +82,7 @@ namespace d3d11
|
|||||||
CONTINUED,
|
CONTINUED,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BoundResourceDimension
|
enum class BoundResourceDimension : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
BUFFER,
|
BUFFER,
|
||||||
@@ -131,6 +132,6 @@ namespace d3d11
|
|||||||
class ShaderAnalyser
|
class ShaderAnalyser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<ShaderInfo> GetShaderInfo(const uint8_t* shader, size_t shaderSize);
|
static std::unique_ptr<ShaderInfo> GetShaderInfo(const void* shader, size_t shaderSize);
|
||||||
};
|
};
|
||||||
} // namespace d3d11
|
} // namespace d3d11
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace d3d9
|
namespace d3d9
|
||||||
{
|
{
|
||||||
enum class ShaderType
|
enum class ShaderType : std::uint8_t
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
PIXEL_SHADER,
|
PIXEL_SHADER,
|
||||||
@@ -14,7 +15,7 @@ namespace d3d9
|
|||||||
};
|
};
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxregister-set
|
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxregister-set
|
||||||
enum class RegisterSet
|
enum class RegisterSet : std::uint8_t
|
||||||
{
|
{
|
||||||
BOOL,
|
BOOL,
|
||||||
INT_4,
|
INT_4,
|
||||||
@@ -26,7 +27,7 @@ namespace d3d9
|
|||||||
};
|
};
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxparameter-class
|
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxparameter-class
|
||||||
enum class ParameterClass
|
enum class ParameterClass : std::uint8_t
|
||||||
{
|
{
|
||||||
SCALAR,
|
SCALAR,
|
||||||
VECTOR,
|
VECTOR,
|
||||||
@@ -40,7 +41,7 @@ namespace d3d9
|
|||||||
};
|
};
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxparameter-type
|
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxparameter-type
|
||||||
enum class ParameterType
|
enum class ParameterType : std::uint8_t
|
||||||
{
|
{
|
||||||
VOID,
|
VOID,
|
||||||
BOOL,
|
BOOL,
|
||||||
|
|||||||
@@ -10,15 +10,21 @@ namespace techset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
uint32_t m_version_major;
|
const void* m_shader_bin;
|
||||||
uint32_t m_version_minor;
|
size_t m_shader_bin_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DxVersion : std::uint8_t
|
||||||
|
{
|
||||||
|
DX9,
|
||||||
|
DX11
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonPass
|
class CommonPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint64_t m_flags;
|
|
||||||
uint32_t m_sampler_flags;
|
uint32_t m_sampler_flags;
|
||||||
|
DxVersion m_dx_version;
|
||||||
CommonTechniqueShader m_vertex_shader;
|
CommonTechniqueShader m_vertex_shader;
|
||||||
CommonTechniqueShader m_pixel_shader;
|
CommonTechniqueShader m_pixel_shader;
|
||||||
};
|
};
|
||||||
@@ -26,6 +32,7 @@ namespace techset
|
|||||||
class CommonTechnique
|
class CommonTechnique
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::string m_name;
|
||||||
uint64_t m_flags;
|
uint64_t m_flags;
|
||||||
std::vector<CommonPass> m_passes;
|
std::vector<CommonPass> m_passes;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "Techset/CommonTechsetDumper.h"
|
#include "Techset/CommonTechsetDumper.h"
|
||||||
#include "Techset/TechniqueDumpingZoneState.h"
|
#include "Techset/TechniqueDumpingZoneState.h"
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
@@ -102,18 +101,51 @@ namespace
|
|||||||
|
|
||||||
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
|
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
|
||||||
{
|
{
|
||||||
std::vector<std::string> techniqueNames(std::extent_v<decltype(techniqueTypeNames)>);
|
std::vector<techset::CommonPass> passes;
|
||||||
|
|
||||||
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(techniqueTypeNames)>; techniqueIndex++)
|
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||||
{
|
{
|
||||||
const auto* technique = techset.techniques[techniqueIndex];
|
const auto& pass = technique.passArray[passIndex];
|
||||||
if (technique && technique->name)
|
|
||||||
techniqueNames[techniqueIndex] = technique->name;
|
techset::CommonTechniqueShader vertexShader{};
|
||||||
|
techset::CommonTechniqueShader pixelShader{};
|
||||||
|
|
||||||
|
if (pass.vertexShader)
|
||||||
|
{
|
||||||
|
if (pass.vertexShader->name)
|
||||||
|
vertexShader.m_name = pass.vertexShader->name;
|
||||||
|
|
||||||
|
if (pass.vertexShader->prog.loadDef.program)
|
||||||
|
{
|
||||||
|
vertexShader.m_shader_bin = pass.vertexShader->prog.loadDef.program;
|
||||||
|
vertexShader.m_shader_bin_size = pass.vertexShader->prog.loadDef.programSize * sizeof(uint32_t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return techset::CommonTechset{
|
if (pass.pixelShader)
|
||||||
.m_name = techset.name,
|
{
|
||||||
.m_technique_names = std::move(techniqueNames),
|
if (pass.pixelShader->name)
|
||||||
|
pixelShader.m_name = pass.pixelShader->name;
|
||||||
|
|
||||||
|
if (pass.pixelShader->prog.loadDef.program)
|
||||||
|
{
|
||||||
|
pixelShader.m_shader_bin = pass.pixelShader->prog.loadDef.program;
|
||||||
|
pixelShader.m_shader_bin_size = pass.pixelShader->prog.loadDef.programSize * sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
passes.emplace_back(techset::CommonPass{
|
||||||
|
.m_sampler_flags = pass.customSamplerFlags,
|
||||||
|
.m_dx_version = techset::DxVersion::DX11,
|
||||||
|
.m_vertex_shader = vertexShader,
|
||||||
|
.m_pixel_shader = pixelShader,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return techset::CommonTechnique{
|
||||||
|
.m_name = technique.name ? technique.name : std::string(),
|
||||||
|
.m_flags = technique.flags,
|
||||||
|
.m_passes = std::move(passes),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
#include "CommonTechniqueDumper.h"
|
||||||
|
|
||||||
|
#include "Dumping/AbstractTextDumper.h"
|
||||||
|
#include "Shader/D3D11ShaderAnalyser.h"
|
||||||
|
#include "Shader/D3D9ShaderAnalyser.h"
|
||||||
|
#include "Techset/TechsetCommon.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
using namespace techset;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum class TechniqueShaderType : std::uint8_t
|
||||||
|
{
|
||||||
|
VERTEX_SHADER,
|
||||||
|
PIXEL_SHADER
|
||||||
|
};
|
||||||
|
|
||||||
|
class TechniqueFileWriter : public AbstractTextDumper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TechniqueFileWriter(std::ostream& stream)
|
||||||
|
: AbstractTextDumper(stream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpTechnique(const CommonTechnique& technique)
|
||||||
|
{
|
||||||
|
#ifdef TECHSET_DEBUG
|
||||||
|
if (technique.m_flags)
|
||||||
|
{
|
||||||
|
for (auto i = 0u; i < sizeof(CommonTechnique::m_flags) * 8u; i++)
|
||||||
|
{
|
||||||
|
const auto mask = 1ui64 << i;
|
||||||
|
if (technique.m_flags & mask)
|
||||||
|
{
|
||||||
|
Indent();
|
||||||
|
m_stream << std::format("// TECHNIQUE FLAGS: 0x{:x}\n", mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (const auto& pass : technique.m_passes)
|
||||||
|
DumpPass(pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DumpPass(const CommonPass& pass)
|
||||||
|
{
|
||||||
|
m_stream << "{\n";
|
||||||
|
IncIndent();
|
||||||
|
|
||||||
|
#ifdef TECHSET_DEBUG
|
||||||
|
for (auto i = 0u; i < sizeof(CommonPass::m_sampler_flags) * 8u; i++)
|
||||||
|
{
|
||||||
|
const auto mask = 1ui64 << i;
|
||||||
|
if (pass.m_sampler_flags & mask)
|
||||||
|
{
|
||||||
|
Indent();
|
||||||
|
m_stream << std::format("// CUSTOM SAMPLER FLAGS: 0x{:x}\n", mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DumpStateMap();
|
||||||
|
DumpShader(pass, pass.m_vertex_shader, TechniqueShaderType::VERTEX_SHADER);
|
||||||
|
DumpShader(pass, pass.m_pixel_shader, TechniqueShaderType::PIXEL_SHADER);
|
||||||
|
// DumpVertexDecl(pass);
|
||||||
|
|
||||||
|
DecIndent();
|
||||||
|
m_stream << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpStateMap() const
|
||||||
|
{
|
||||||
|
Indent();
|
||||||
|
// TODO: Actual statemap: Maybe find all materials using this techset and try to make out rules
|
||||||
|
// for the flags based on the statebitstable
|
||||||
|
m_stream << "stateMap \"passthrough\"; // TODO\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpShader(const CommonPass& pass, const CommonTechniqueShader& shader, const TechniqueShaderType shaderType) const
|
||||||
|
{
|
||||||
|
if (!shader.m_shader_bin)
|
||||||
|
{
|
||||||
|
if (!shader.m_name.empty())
|
||||||
|
m_stream << std::format("// Cannot dump shader {} as its data is not loaded\n", shader.m_name);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned versionMajor, versionMinor;
|
||||||
|
if (pass.m_dx_version == DxVersion::DX9)
|
||||||
|
{
|
||||||
|
const auto shaderInfo = d3d9::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size);
|
||||||
|
assert(shaderInfo);
|
||||||
|
if (!shaderInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
versionMajor = shaderInfo->m_version_major;
|
||||||
|
versionMinor = shaderInfo->m_version_minor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(pass.m_dx_version == DxVersion::DX11);
|
||||||
|
const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size);
|
||||||
|
assert(shaderInfo);
|
||||||
|
if (!shaderInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
versionMajor = shaderInfo->m_version_major;
|
||||||
|
versionMinor = shaderInfo->m_version_minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto shaderTypeName = shaderType == TechniqueShaderType::VERTEX_SHADER ? "vertexShader" : "pixelShader";
|
||||||
|
|
||||||
|
m_stream << "\n";
|
||||||
|
Indent();
|
||||||
|
m_stream << std::format("{} {}.{} \"{}\"\n", shaderTypeName, versionMajor, versionMinor, shader.m_name);
|
||||||
|
Indent();
|
||||||
|
m_stream << "{\n";
|
||||||
|
|
||||||
|
Indent();
|
||||||
|
m_stream << "}\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechnique& technique)
|
||||||
|
{
|
||||||
|
const auto techniqueFile = context.OpenAssetFile(GetFileNameForTechniqueName(technique.m_name));
|
||||||
|
if (techniqueFile)
|
||||||
|
{
|
||||||
|
TechniqueFileWriter writer(*techniqueFile);
|
||||||
|
writer.DumpTechnique(technique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Dumping/AssetDumpingContext.h"
|
#include "Dumping/AssetDumpingContext.h"
|
||||||
#include "Techset/CommonTechset.h"
|
#include "Techset/CommonTechnique.h"
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
{
|
{
|
||||||
void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechset& techset);
|
void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechnique& technique);
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "CommonTechsetDumper.h"
|
#include "CommonTechsetDumper.h"
|
||||||
|
|
||||||
#include "Dumping/AbstractTextDumper.h"
|
#include "Dumping/AbstractTextDumper.h"
|
||||||
#include "Game/IW3/Material/MaterialConstantZoneStateIW3.h"
|
|
||||||
#include "Techset/TechsetCommon.h"
|
#include "Techset/TechsetCommon.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -36,8 +35,7 @@ namespace
|
|||||||
dumpedTechniques[techniqueIndex] = true;
|
dumpedTechniques[techniqueIndex] = true;
|
||||||
WriteTechniqueType(techniqueIndex);
|
WriteTechniqueType(techniqueIndex);
|
||||||
|
|
||||||
for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < std::extent_v<decltype(IW3::MaterialTechniqueSet::techniques)>;
|
for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < techniqueCount; nextTechniqueIndex++)
|
||||||
nextTechniqueIndex++)
|
|
||||||
{
|
{
|
||||||
if (techset.m_technique_names[nextTechniqueIndex] != technique)
|
if (techset.m_technique_names[nextTechniqueIndex] != technique)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user