2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-12-17 16:07:48 +00:00

Merge pull request #612 from Laupetin/feature/t6-techset

feat: dump techsets for t6
This commit is contained in:
Jan
2025-12-16 14:20:23 +01:00
committed by GitHub
39 changed files with 3268 additions and 316 deletions

View File

@@ -3038,17 +3038,45 @@ namespace T6
void /*ID3D11RasterizerState*/* rasterizerState; void /*ID3D11RasterizerState*/* rasterizerState;
}; };
enum VertexShaderPrecompiledIndex : unsigned char
{
VERTEX_SHADER_NONE = 0x0,
VERTEX_SHADER_MODEL_LIT,
VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
VERTEX_SHADER_MODEL_UNLIT,
};
enum MaterialType : unsigned char
{
MTL_TYPE_DEFAULT = 0x0,
MTL_TYPE_MODEL, // m_
MTL_TYPE_MODEL_VERTCOL, // mc_
MTL_TYPE_MODEL_LIGHTMAP_VC, // mlv_
MTL_TYPE_WORLD_VERTCOL, // wc_
MTL_TYPE_PACKED_WORLD_VERTCOL, // wpc_
MTL_TYPE_QUANT_WORLD, // wq_
MTL_TYPE_QUANT_WORLD_VERTCOL, // wqc_
MTL_TYPE_COUNT,
};
struct MaterialTypeInfo
{
const char* materialPrefix;
const char* techniqueSetPrefix;
};
struct MaterialPass struct MaterialPass
{ {
MaterialVertexDeclaration* vertexDecl; MaterialVertexDeclaration* vertexDecl;
MaterialVertexShader* vertexShader; MaterialVertexShader* vertexShader;
MaterialPixelShader* pixelShader; MaterialPixelShader* pixelShader;
char perPrimArgCount; unsigned char perPrimArgCount;
char perObjArgCount; unsigned char perObjArgCount;
char stableArgCount; unsigned char stableArgCount;
char customSamplerFlags; unsigned char customSamplerFlags;
char precompiledIndex; VertexShaderPrecompiledIndex precompiledIndex;
char materialType; MaterialType materialType;
MaterialShaderArgument* args; MaterialShaderArgument* args;
}; };
@@ -5834,31 +5862,11 @@ namespace T6
struct struct
{ {
char textureIndex; uint8_t textureIndex;
char samplerIndex; uint8_t samplerIndex;
}; };
}; };
enum MaterialType
{
MTL_TYPE_DEFAULT = 0x0,
MTL_TYPE_MODEL = 0x1, // m_
MTL_TYPE_MODEL_VERTCOL = 0x2, // mc_
MTL_TYPE_MODEL_LIGHTMAP_VC = 0x3, // ?
MTL_TYPE_WORLD_VERTCOL = 0x4, // wc_
MTL_TYPE_PACKED_WORLD_VERTCOL = 0x5, // ?
MTL_TYPE_QUANT_WORLD = 0x6, // ?
MTL_TYPE_QUANT_WORLD_VERTCOL = 0x7, // ?
MTL_TYPE_COUNT,
};
struct MaterialTypeInfo
{
const char* materialPrefix;
const char* techniqueSetPrefix;
};
enum MaterialConstantSource enum MaterialConstantSource
{ {
CONST_SRC_CODE_MAYBE_DIRTY_PS_BEGIN = 0x0, CONST_SRC_CODE_MAYBE_DIRTY_PS_BEGIN = 0x0,
@@ -5940,7 +5948,6 @@ namespace T6
CONST_SRC_CODE_DEPTH_FROM_CLIP = 0x42, CONST_SRC_CODE_DEPTH_FROM_CLIP = 0x42,
CONST_SRC_CODE_CODE_MESH_ARG_0 = 0x43, CONST_SRC_CODE_CODE_MESH_ARG_0 = 0x43,
CONST_SRC_CODE_CODE_MESH_ARG_1 = 0x44, CONST_SRC_CODE_CODE_MESH_ARG_1 = 0x44,
CONST_SRC_CODE_CODE_MESH_ARG_LAST = 0x44,
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS = 0x45, CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS = 0x45,
CONST_SRC_CODE_GRID_LIGHTING_SH_0 = 0x46, CONST_SRC_CODE_GRID_LIGHTING_SH_0 = 0x46,
CONST_SRC_CODE_GRID_LIGHTING_SH_1 = 0x47, CONST_SRC_CODE_GRID_LIGHTING_SH_1 = 0x47,
@@ -6125,6 +6132,67 @@ namespace T6
CONST_SRC_NONE, CONST_SRC_NONE,
}; };
enum MaterialTextureSource
{
TEXTURE_SRC_CODE_BLACK = 0x0,
TEXTURE_SRC_CODE_WHITE = 0x1,
TEXTURE_SRC_CODE_IDENTITY_NORMAL_MAP = 0x2,
TEXTURE_SRC_CODE_MODEL_LIGHTING = 0x3,
TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY = 0x4,
TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY = 0x5,
TEXTURE_SRC_CODE_SHADOWMAP_SUN = 0x6,
TEXTURE_SRC_CODE_SHADOWMAP_SPOT = 0x7,
TEXTURE_SRC_CODE_FEEDBACK = 0x8,
TEXTURE_SRC_CODE_RESOLVED_POST_SUN = 0x9,
TEXTURE_SRC_CODE_RESOLVED_SCENE = 0xA,
TEXTURE_SRC_CODE_POST_EFFECT_SRC = 0xB,
TEXTURE_SRC_CODE_POST_EFFECT_GODRAYS = 0xC,
TEXTURE_SRC_CODE_POST_EFFECT_0 = 0xD,
TEXTURE_SRC_CODE_POST_EFFECT_1 = 0xE,
TEXTURE_SRC_CODE_LIGHT_ATTENUATION = 0xF,
TEXTURE_SRC_CODE_DLIGHT_ATTENUATION = 0x10,
TEXTURE_SRC_CODE_OUTDOOR = 0x11,
TEXTURE_SRC_CODE_FLOATZ = 0x12,
TEXTURE_SRC_CODE_PROCESSED_FLOATZ = 0x13,
TEXTURE_SRC_CODE_RAW_FLOATZ = 0x14,
TEXTURE_SRC_CODE_STENCIL = 0x15,
TEXTURE_SRC_CODE_CINEMATIC_Y = 0x16,
TEXTURE_SRC_CODE_CINEMATIC_CR = 0x17,
TEXTURE_SRC_CODE_CINEMATIC_CB = 0x18,
TEXTURE_SRC_CODE_CINEMATIC_A = 0x19,
TEXTURE_SRC_CODE_REFLECTION_PROBE = 0x1A,
TEXTURE_SRC_CODE_FEATHER_FLOAT_Z = 0x1B,
TEXTURE_SRC_CODE_TEXTURE_0 = 0x1C,
TEXTURE_SRC_CODE_TEXTURE_1 = 0x1D,
TEXTURE_SRC_CODE_TEXTURE_2 = 0x1E,
TEXTURE_SRC_CODE_TEXTURE_3 = 0x1F,
TEXTURE_SRC_CODE_IMPACT_MASK_DEPRECATED = 0x20,
TEXTURE_SRC_CODE_UI3D = 0x21,
TEXTURE_SRC_CODE_MISSILE_CAM = 0x22,
TEXTURE_SRC_CODE_MISSILE_CAM_0 = 0x23,
TEXTURE_SRC_CODE_MISSILE_CAM_1 = 0x24,
TEXTURE_SRC_CODE_MISSILE_CAM_2 = 0x25,
TEXTURE_SRC_CODE_MISSILE_CAM_3 = 0x26,
TEXTURE_SRC_CODE_COMPOSITE_RESULT = 0x27,
TEXTURE_SRC_CODE_HEATMAP = 0x28,
TEXTURE_SRC_CODE_SONAR_COLOR = 0x29,
TEXTURE_SRC_CODE_SONAR_DEPTH = 0x2A,
TEXTURE_SRC_CODE_QRCODE_0 = 0x2B,
TEXTURE_SRC_CODE_QRCODE_1 = 0x2C,
TEXTURE_SRC_CODE_QRCODE_2 = 0x2D,
TEXTURE_SRC_CODE_QRCODE_3 = 0x2E,
TEXTURE_SRC_CODE_QRCODE_4 = 0x2F,
TEXTURE_SRC_CODE_QRCODE_5 = 0x30,
TEXTURE_SRC_CODE_QRCODE_6 = 0x31,
TEXTURE_SRC_CODE_QRCODE_7 = 0x32,
TEXTURE_SRC_CODE_QRCODE_8 = 0x33,
TEXTURE_SRC_CODE_QRCODE_9 = 0x34,
TEXTURE_SRC_CODE_QRCODE_10 = 0x35,
TEXTURE_SRC_CODE_QRCODE_11 = 0x36,
TEXTURE_SRC_CODE_COUNT
};
struct CodeConstantSource struct CodeConstantSource
{ {
const char* name; const char* name;

File diff suppressed because it is too large Load Diff

View File

@@ -1,101 +0,0 @@
#pragma once
#include "Game/T6/CommonT6.h"
#include "Game/T6/T6.h"
namespace T6
{
inline const char* techniqueTypeNames[]{
"depth prepass",
"build shadowmap depth",
"unlit",
"emissive",
"lit",
"lit sun",
"lit sun shadow",
"lit spot",
"lit spot shadow",
"lit spot square",
"lit spot square shadow",
"lit spot round",
"lit spot round shadow",
"lit omni",
"lit omni shadow",
"lit dlight glight",
"lit sun dlight glight",
"lit sun shadow dlight glight",
"lit spot dlight glight",
"lit spot shadow dlight glight",
"lit spot square dlight glight",
"lit spot square shadow dlight glight",
"lit spot round dlight glight",
"lit spot round shadow dlight glight",
"lit omni dlight glight",
"lit omni shadow dlight glight",
"light spot",
"light omni",
"fakelight normal",
"fakelight view",
"sunlight preview",
"case texture",
"solid wireframe",
"shaded wireframe",
"debug bumpmap",
"debug performance",
};
static_assert(std::extent_v<decltype(techniqueTypeNames)> == TECHNIQUE_COUNT);
static const char* materialStreamDestinationNames[]{
"position", "normal", "color[0]", "color[1]", "depth", "texcoord[0]", "texcoord[1]",
"texcoord[2]", "texcoord[3]", "texcoord[4]", "texcoord[5]", "texcoord[6]", "texcoord[7]", "texcoord[8]",
"texcoord[9]", "texcoord[10]", "texcoord[11]", "texcoord[12]", "texcoord[13]", "blendWeight",
};
static_assert(std::extent_v<decltype(materialStreamDestinationNames)> == STREAM_DST_COUNT);
static const char* materialStreamDestinationAbbreviation[]{
"p", "n", "c0", "c1", "d", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "b",
};
static_assert(std::extent_v<decltype(materialStreamDestinationAbbreviation)> == STREAM_DST_COUNT);
static const char* materialStreamSourceNames[]{
"position",
"color",
"texcoord[0]",
"normal",
"tangent",
"texcoord[1]",
"texcoord[2]",
"texcoord[3]",
"normalTransform[0]",
"normalTransform[1]",
"blendWeight",
};
static_assert(std::extent_v<decltype(materialStreamSourceNames)> == STREAM_SRC_COUNT);
static const char* materialStreamSourceAbbreviation[]{
"p",
"c",
"t0",
"n",
"t",
"t1",
"t2",
"t3",
"n0",
"n1",
"b",
};
static_assert(std::extent_v<decltype(materialStreamSourceAbbreviation)> == STREAM_SRC_COUNT);
inline MaterialTypeInfo g_materialTypeInfo[]{
{"", "" },
{"m/", "m_" },
{"mc/", "mc_"},
{"?", "?" },
{"wc/", "wc_"},
{"?", "?" },
{"?", "?" },
{"?", "?" },
}; // TODO: Fill this
static_assert(std::extent_v<decltype(g_materialTypeInfo)> == MTL_TYPE_COUNT);
} // namespace T6

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -0,0 +1,108 @@
#include "CommonTechnique.h"
#include <algorithm>
namespace techset
{
CommonCodeSourceInfos::CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
const size_t codeConstCount,
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
const size_t codeSamplerCount)
: m_code_const_source_infos(codeConstCount),
m_code_sampler_source_infos(codeSamplerCount)
{
std::copy(codeConstSourceInfos, &codeConstSourceInfos[codeConstCount], m_code_const_source_infos.data());
std::ranges::sort(m_code_const_source_infos,
[](const CommonCodeConstSourceInfo& a, const CommonCodeConstSourceInfo& b) -> bool
{
return a.value < b.value;
});
std::copy(codeSamplerSourceInfos, &codeSamplerSourceInfos[codeSamplerCount], m_code_sampler_source_infos.data());
std::ranges::sort(m_code_sampler_source_infos,
[](const CommonCodeSamplerSourceInfo& a, const CommonCodeSamplerSourceInfo& b) -> bool
{
return a.value < b.value;
});
}
std::optional<CommonCodeConstSourceInfo> CommonCodeSourceInfos::GetInfoForCodeConstSource(const CommonCodeConstSource codeConstSource) const
{
for (const auto& codeConstSourceInfo : m_code_const_source_infos)
{
const auto codeConstSourceInfoEnd = static_cast<unsigned>(codeConstSourceInfo.value) + codeConstSourceInfo.arrayCount;
if (codeConstSourceInfo.value <= codeConstSource && codeConstSourceInfoEnd >= codeConstSource)
return codeConstSourceInfo;
if (codeConstSourceInfoEnd > codeConstSource)
return std::nullopt;
}
return std::nullopt;
}
std::optional<CommonCodeSamplerSourceInfo> CommonCodeSourceInfos::GetInfoForCodeSamplerSource(const CommonCodeSamplerSource codeSamplerSource) const
{
for (const auto& codeSamplerSourceInfo : m_code_sampler_source_infos)
{
if (codeSamplerSourceInfo.value == codeSamplerSource)
return codeSamplerSourceInfo;
if (codeSamplerSourceInfo.value > codeSamplerSource)
return std::nullopt;
}
return std::nullopt;
}
CommonStreamRoutingInfos::CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos,
const size_t sourceCount,
const CommonStreamRoutingDestinationInfo* destinationNames,
const size_t destinationCount)
: m_sources(sourceCount),
m_destinations(destinationCount)
{
std::copy(sourceInfos, &sourceInfos[sourceCount], m_sources.data());
std::copy(destinationNames, &destinationNames[destinationCount], m_destinations.data());
}
const char* CommonStreamRoutingInfos::GetSourceName(const CommonStreamSource source) const
{
if (source >= m_sources.size())
return nullptr;
return m_sources[source].name;
}
const char* CommonStreamRoutingInfos::GetSourceAbbreviation(const CommonStreamSource source) const
{
if (source >= m_sources.size())
return nullptr;
return m_sources[source].abbreviation;
}
bool CommonStreamRoutingInfos::IsSourceOptional(const CommonStreamSource source) const
{
if (source >= m_sources.size())
return false;
return m_sources[source].optional;
}
const char* CommonStreamRoutingInfos::GetDestinationName(const CommonStreamDestination destination) const
{
if (destination >= m_destinations.size())
return nullptr;
return m_destinations[destination].name;
}
const char* CommonStreamRoutingInfos::GetDestinationAbbreviation(const CommonStreamDestination destination) const
{
if (destination >= m_destinations.size())
return nullptr;
return m_destinations[destination].abbreviation;
}
} // namespace techset

View File

@@ -0,0 +1,185 @@
#pragma once
#include <array>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
namespace techset
{
typedef std::uint8_t CommonStreamSource;
typedef std::uint8_t CommonStreamDestination;
typedef std::uint8_t CommonCodeConstSource;
typedef std::uint8_t CommonCodeSamplerSource;
struct CommonStreamRoutingSourceInfo
{
const char* name;
const char* abbreviation;
bool optional;
};
struct CommonStreamRoutingDestinationInfo
{
const char* name;
const char* abbreviation;
};
enum class CommonCodeSourceUpdateFrequency : std::uint8_t
{
PER_PRIM,
PER_OBJECT,
RARELY,
CUSTOM,
};
struct CommonCodeConstSourceInfo
{
CommonCodeConstSource value;
const char* accessor;
std::uint8_t arrayCount;
CommonCodeSourceUpdateFrequency updateFrequency;
};
struct CommonCodeSamplerSourceInfo
{
CommonCodeSamplerSource value;
const char* accessor;
CommonCodeSourceUpdateFrequency updateFrequency;
};
class CommonCodeSourceInfos
{
public:
CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
size_t codeConstCount,
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
size_t codeSamplerCount);
[[nodiscard]] std::optional<CommonCodeConstSourceInfo> GetInfoForCodeConstSource(CommonCodeConstSource codeConstSource) const;
[[nodiscard]] std::optional<CommonCodeSamplerSourceInfo> GetInfoForCodeSamplerSource(CommonCodeSamplerSource codeSamplerSource) const;
private:
std::vector<CommonCodeConstSourceInfo> m_code_const_source_infos;
std::vector<CommonCodeSamplerSourceInfo> m_code_sampler_source_infos;
};
class CommonStreamRoutingInfos
{
public:
CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos,
size_t sourceCount,
const CommonStreamRoutingDestinationInfo* destinationNames,
size_t destinationCount);
[[nodiscard]] const char* GetSourceName(CommonStreamSource source) const;
[[nodiscard]] const char* GetSourceAbbreviation(CommonStreamSource source) const;
[[nodiscard]] bool IsSourceOptional(CommonStreamSource source) const;
[[nodiscard]] const char* GetDestinationName(CommonStreamDestination destination) const;
[[nodiscard]] const char* GetDestinationAbbreviation(CommonStreamDestination destination) const;
private:
std::vector<CommonStreamRoutingSourceInfo> m_sources;
std::vector<CommonStreamRoutingDestinationInfo> m_destinations;
};
union CommonShaderArgValue
{
std::array<float, 4> literal_value;
CommonCodeConstSource code_const_source;
CommonCodeSamplerSource code_sampler_source;
unsigned name_hash;
};
class CommonShaderArgDestinationDx9
{
public:
unsigned m_destination_register;
};
class CommonShaderArgDestinationDx11
{
public:
// In case of a constant: Offset in constant buffer
// In case of a sampler: Index of sampler
unsigned m_location;
unsigned m_size;
unsigned m_buffer;
};
union CommonShaderArgDestination
{
CommonShaderArgDestinationDx9 dx9;
CommonShaderArgDestinationDx11 dx11;
};
enum class CommonShaderArgType : 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
};
class CommonShaderArg
{
public:
CommonShaderArgType m_type;
CommonShaderArgDestination m_destination;
CommonShaderArgValue m_value;
};
class CommonStreamRouting
{
public:
CommonStreamSource m_source;
CommonStreamDestination m_destination;
};
class CommonVertexDeclaration
{
public:
std::vector<CommonStreamRouting> m_routing;
};
class CommonTechniqueShader
{
public:
std::string m_name;
const void* m_shader_bin;
size_t m_shader_bin_size;
std::vector<CommonShaderArg> m_args;
};
enum class DxVersion : std::uint8_t
{
DX9,
DX11
};
class CommonPass
{
public:
uint32_t m_sampler_flags;
DxVersion m_dx_version;
CommonTechniqueShader m_vertex_shader;
CommonTechniqueShader m_pixel_shader;
CommonVertexDeclaration m_vertex_declaration;
};
class CommonTechnique
{
public:
std::string m_name;
uint64_t m_flags;
std::vector<CommonPass> m_passes;
};
} // namespace techset

View File

@@ -0,0 +1,22 @@
#include "CommonTechset.h"
#include <algorithm>
techset::CommonTechniqueTypeNames::CommonTechniqueTypeNames(const char** names, const size_t nameCount)
: m_names(nameCount)
{
std::copy(names, &names[nameCount], m_names.data());
}
const char* techset::CommonTechniqueTypeNames::GetTechniqueTypeName(const size_t techniqueTypeIndex) const
{
if (techniqueTypeIndex >= m_names.size())
return nullptr;
return m_names[techniqueTypeIndex];
}
size_t techset::CommonTechniqueTypeNames::GetTechniqueTypeCount() const
{
return m_names.size();
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace techset
{
class CommonTechniqueTypeNames
{
public:
CommonTechniqueTypeNames(const char** names, size_t nameCount);
[[nodiscard]] const char* GetTechniqueTypeName(size_t techniqueTypeIndex) const;
[[nodiscard]] size_t GetTechniqueTypeCount() const;
private:
std::vector<const char*> m_names;
};
class CommonTechset
{
public:
std::string m_name;
std::vector<std::string> m_technique_names;
};
} // namespace techset

View File

@@ -5,7 +5,7 @@
#include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/MaterialConstantsIW4.h"
#include "Game/IW4/ObjConstantsIW4.h" #include "Game/IW4/ObjConstantsIW4.h"
#include "Game/IW4/Techset/CompilerTechsetIW4.h" #include "Game/IW4/Techset/CompilerTechsetIW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Gdt/AbstractGdtEntryReader.h" #include "Gdt/AbstractGdtEntryReader.h"
#include "Gdt/IGdtQueryable.h" #include "Gdt/IGdtQueryable.h"
#include "ObjLoading.h" #include "ObjLoading.h"

View File

@@ -3,7 +3,7 @@
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Game/IW4/Shader/LoaderPixelShaderIW4.h" #include "Game/IW4/Shader/LoaderPixelShaderIW4.h"
#include "Game/IW4/Shader/LoaderVertexShaderIW4.h" #include "Game/IW4/Shader/LoaderVertexShaderIW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Shader/D3D9ShaderAnalyser.h" #include "Shader/D3D9ShaderAnalyser.h"
#include "Shader/ShaderCommon.h" #include "Shader/ShaderCommon.h"
#include "StateMap/StateMapReader.h" #include "StateMap/StateMapReader.h"

View File

@@ -1,7 +1,7 @@
#include "CompilerVertexDeclIW4.h" #include "CompilerVertexDeclIW4.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
#include <cstring> #include <cstring>

View File

@@ -6,7 +6,7 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Zone/ZoneRegistry.h" #include "Zone/ZoneRegistry.h"
namespace IW3 namespace
{ {
const char* KNOWN_CONSTANT_NAMES[]{ const char* KNOWN_CONSTANT_NAMES[]{
"worldViewProjectionMatrix", "worldViewProjectionMatrix",
@@ -197,7 +197,10 @@ namespace IW3
"worldMap", "worldMap",
"worldMapSampler", "worldMapSampler",
}; };
} // namespace
namespace IW3
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal() void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{ {
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW3)->Zones()) for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW3)->Zones())
@@ -219,7 +222,7 @@ namespace IW3
} }
} }
unsigned MaterialConstantZoneState::HashString(const std::string& str) unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{ {
return Common::R_HashString(str.c_str()); return Common::R_HashString(str.c_str());
} }

View File

@@ -13,6 +13,6 @@ namespace IW3
void ExtractNamesFromZoneInternal() override; void ExtractNamesFromZoneInternal() override;
void ExtractNamesFromTechnique(const MaterialTechnique* technique); void ExtractNamesFromTechnique(const MaterialTechnique* technique);
void AddStaticKnownNames() override; void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override; [[nodiscard]] unsigned HashString(const std::string& str) const override;
}; };
} // namespace IW3 } // namespace IW3

View File

@@ -6,7 +6,7 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Zone/ZoneRegistry.h" #include "Zone/ZoneRegistry.h"
namespace IW4 namespace
{ {
const char* KNOWN_CONSTANT_NAMES[]{ const char* KNOWN_CONSTANT_NAMES[]{
"worldViewProjectionMatrix", "worldViewProjectionMatrix",
@@ -197,7 +197,10 @@ namespace IW4
"worldMap", "worldMap",
"worldMapSampler", "worldMapSampler",
}; };
} // namespace
namespace IW4
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal() void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{ {
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW4)->Zones()) for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW4)->Zones())
@@ -230,7 +233,7 @@ namespace IW4
AddTextureDefName(knownTextureDefName); AddTextureDefName(knownTextureDefName);
} }
unsigned MaterialConstantZoneState::HashString(const std::string& str) unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{ {
return Common::R_HashString(str.c_str()); return Common::R_HashString(str.c_str());
} }

View File

@@ -11,6 +11,6 @@ namespace IW4
protected: protected:
void ExtractNamesFromZoneInternal() override; void ExtractNamesFromZoneInternal() override;
void AddStaticKnownNames() override; void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override; [[nodiscard]] unsigned HashString(const std::string& str) const override;
}; };
} // namespace IW4 } // namespace IW4

View File

@@ -2,8 +2,7 @@
#include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/MaterialConstantsIW4.h"
#include "Game/IW4/ObjConstantsIW4.h" #include "Game/IW4/ObjConstantsIW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Utils/ClassUtils.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
#pragma warning(push, 0) #pragma warning(push, 0)

View File

@@ -1,9 +1,12 @@
#include "TechsetDumperIW4.h" #include "TechsetDumperIW4.h"
#include "Dumping/AbstractTextDumper.h" #include "Dumping/AbstractTextDumper.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Pool/GlobalAssetPool.h" #include "Pool/GlobalAssetPool.h"
#include "Shader/D3D9ShaderAnalyser.h" #include "Shader/D3D9ShaderAnalyser.h"
#include "Techset/CommonTechset.h"
#include "Techset/CommonTechsetDumper.h"
#include "Techset/TechniqueDumpingZoneState.h"
#include "Techset/TechsetCommon.h" #include "Techset/TechsetCommon.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
@@ -16,23 +19,8 @@
using namespace IW4; using namespace IW4;
namespace IW4 namespace
{ {
class TechniqueDumpingZoneState final : public IZoneAssetDumperState
{
std::set<const MaterialTechnique*> m_dumped_techniques;
public:
bool ShouldDumpTechnique(const MaterialTechnique* technique)
{
if (m_dumped_techniques.find(technique) != m_dumped_techniques.end())
return false;
m_dumped_techniques.emplace(technique);
return true;
}
};
class TechniqueFileWriter : public AbstractTextDumper class TechniqueFileWriter : public AbstractTextDumper
{ {
void DumpStateMap() const void DumpStateMap() const
@@ -472,67 +460,31 @@ namespace IW4
} }
}; };
class TechsetFileWriter : public AbstractTextDumper techset::CommonTechset ConvertToCommonTechset(const MaterialTechniqueSet& techset)
{ {
bool m_last_write_was_value; std::vector<std::string> techniqueNames(std::extent_v<decltype(techniqueTypeNames)>);
public: for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(techniqueTypeNames)>; techniqueIndex++)
explicit TechsetFileWriter(std::ostream& stream)
: AbstractTextDumper(stream),
m_last_write_was_value(false)
{ {
const auto* technique = techset.techniques[techniqueIndex];
if (technique && technique->name)
techniqueNames[techniqueIndex] = technique->name;
} }
void WriteTechniqueType(const size_t techniqueIndex) return techset::CommonTechset{
{ .m_name = techset.name,
assert(techniqueIndex < std::extent_v<decltype(techniqueTypeNames)>); .m_technique_names = std::move(techniqueNames),
};
}
if (m_last_write_was_value) void DumpTechset(const AssetDumpingContext& context, const MaterialTechniqueSet& techset)
{ {
m_stream << "\n"; static techset::CommonTechniqueTypeNames commonNames(techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
m_last_write_was_value = false; const auto commonTechset = ConvertToCommonTechset(techset);
}
m_stream << '"' << techniqueTypeNames[techniqueIndex] << "\":\n";
}
void WriteTechniqueValue(const char* value) techset::DumpCommonTechset(commonNames, context, commonTechset);
{ }
m_last_write_was_value = true; } // namespace
IncIndent();
Indent();
m_stream << value << ";\n";
DecIndent();
}
void DumpTechset(const MaterialTechniqueSet* techset)
{
std::vector<bool> dumpedTechniques(std::extent_v<decltype(MaterialTechniqueSet::techniques)>);
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(MaterialTechniqueSet::techniques)>; techniqueIndex++)
{
const auto* technique = techset->techniques[techniqueIndex];
if (technique == nullptr || dumpedTechniques[techniqueIndex])
continue;
dumpedTechniques[techniqueIndex] = true;
WriteTechniqueType(techniqueIndex);
for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < std::extent_v<decltype(MaterialTechniqueSet::techniques)>;
nextTechniqueIndex++)
{
if (techset->techniques[nextTechniqueIndex] != technique)
continue;
dumpedTechniques[nextTechniqueIndex] = true;
WriteTechniqueType(nextTechniqueIndex);
}
WriteTechniqueValue(technique->name);
}
}
};
} // namespace IW4
namespace techset namespace techset
{ {
@@ -543,18 +495,11 @@ namespace techset
void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetTechniqueSet::Type>& asset) void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetTechniqueSet::Type>& asset)
{ {
const auto* techset = asset.Asset(); const auto* techniqueSet = asset.Asset();
DumpTechset(context, *techniqueSet);
const auto techsetFile = context.OpenAssetFile(GetFileNameForTechsetName(techset->name));
if (techsetFile)
{
TechsetFileWriter writer(*techsetFile);
writer.DumpTechset(techset);
}
auto* techniqueState = context.GetZoneAssetDumperState<TechniqueDumpingZoneState>(); auto* techniqueState = context.GetZoneAssetDumperState<TechniqueDumpingZoneState>();
for (const auto* technique : techset->techniques) for (const auto* technique : techniqueSet->techniques)
{ {
if (technique && techniqueState->ShouldDumpTechnique(technique)) if (technique && techniqueState->ShouldDumpTechnique(technique))
{ {

View File

@@ -6,7 +6,7 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Zone/ZoneRegistry.h" #include "Zone/ZoneRegistry.h"
namespace IW5 namespace
{ {
const char* KNOWN_CONSTANT_NAMES[]{ const char* KNOWN_CONSTANT_NAMES[]{
"worldViewProjectionMatrix", "worldViewProjectionMatrix",
@@ -197,7 +197,10 @@ namespace IW5
"worldMap", "worldMap",
"worldMapSampler", "worldMapSampler",
}; };
} // namespace
namespace IW5
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal() void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{ {
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW5)->Zones()) for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::IW5)->Zones())
@@ -230,7 +233,7 @@ namespace IW5
AddTextureDefName(knownTextureDefName); AddTextureDefName(knownTextureDefName);
} }
unsigned MaterialConstantZoneState::HashString(const std::string& str) unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{ {
return Common::R_HashString(str.c_str()); return Common::R_HashString(str.c_str());
} }

View File

@@ -11,6 +11,6 @@ namespace IW5
protected: protected:
void ExtractNamesFromZoneInternal() override; void ExtractNamesFromZoneInternal() override;
void AddStaticKnownNames() override; void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override; [[nodiscard]] unsigned HashString(const std::string& str) const override;
}; };
} // namespace IW5 } // namespace IW5

View File

@@ -6,7 +6,7 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Zone/ZoneRegistry.h" #include "Zone/ZoneRegistry.h"
namespace T5 namespace
{ {
const char* KNOWN_CONSTANT_NAMES[]{ const char* KNOWN_CONSTANT_NAMES[]{
"AngularVelocityScale", "AngularVelocityScale",
@@ -471,7 +471,10 @@ namespace T5
"ui3d", "ui3d",
"ui3dSampler", "ui3dSampler",
}; };
} // namespace
namespace T5
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal() void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{ {
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::T5)->Zones()) for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::T5)->Zones())
@@ -493,7 +496,7 @@ namespace T5
} }
} }
unsigned MaterialConstantZoneState::HashString(const std::string& str) unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{ {
return Common::R_HashString(str.c_str()); return Common::R_HashString(str.c_str());
} }

View File

@@ -7,12 +7,12 @@
namespace T5 namespace T5
{ {
class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx11 class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx9
{ {
protected: protected:
void ExtractNamesFromZoneInternal() override; void ExtractNamesFromZoneInternal() override;
void ExtractNamesFromTechnique(const MaterialTechnique* technique); void ExtractNamesFromTechnique(const MaterialTechnique* technique);
void AddStaticKnownNames() override; void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override; [[nodiscard]] unsigned HashString(const std::string& str) const override;
}; };
} // namespace T5 } // namespace T5

View File

@@ -6,7 +6,7 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Zone/ZoneRegistry.h" #include "Zone/ZoneRegistry.h"
namespace T6 namespace
{ {
const char* KNOWN_CONSTANT_NAMES[]{ const char* KNOWN_CONSTANT_NAMES[]{
"AngularVelocityScale", "AngularVelocityScale",
@@ -471,7 +471,10 @@ namespace T6
"ui3d", "ui3d",
"ui3dSampler", "ui3dSampler",
}; };
} // namespace
namespace T6
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal() void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{ {
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::T6)->Zones()) for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::T6)->Zones())
@@ -493,7 +496,7 @@ namespace T6
} }
} }
unsigned MaterialConstantZoneState::HashString(const std::string& str) unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{ {
return Common::R_HashString(str.c_str()); return Common::R_HashString(str.c_str());
} }

View File

@@ -13,6 +13,6 @@ namespace T6
void ExtractNamesFromZoneInternal() override; void ExtractNamesFromZoneInternal() override;
void ExtractNamesFromTechnique(const MaterialTechnique* technique); void ExtractNamesFromTechnique(const MaterialTechnique* technique);
void AddStaticKnownNames() override; void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override; [[nodiscard]] unsigned HashString(const std::string& str) const override;
}; };
} // namespace T6 } // namespace T6

View File

@@ -1,59 +1,19 @@
#include "TechsetDumperT6.h" #include "TechsetDumperT6.h"
#include "Game/T6/Material/MaterialConstantZoneStateT6.h"
#include "Game/T6/Techset/TechsetConstantsT6.h"
#include "Shader/ShaderCommon.h" #include "Shader/ShaderCommon.h"
#include "Techset/CommonTechniqueDumper.h"
#include "Techset/CommonTechsetDumper.h"
#include "Techset/ShaderDumpingZoneState.h"
#include "Techset/TechniqueDumpingZoneState.h"
#include <sstream>
#include <unordered_set> #include <unordered_set>
using namespace T6; using namespace T6;
namespace namespace
{ {
class ShaderZoneState final : public IZoneAssetDumperState
{
public:
bool ShouldDumpTechnique(const MaterialTechnique* technique)
{
const auto existingTechnique = m_dumped_techniques.find(technique);
if (existingTechnique == m_dumped_techniques.end())
{
m_dumped_techniques.emplace(technique);
return true;
}
return false;
}
bool ShouldDumpPixelShader(const MaterialPixelShader* pixelShader)
{
const auto existingPixelShader = m_dumped_pixel_shaders.find(pixelShader);
if (existingPixelShader == m_dumped_pixel_shaders.end())
{
m_dumped_pixel_shaders.emplace(pixelShader);
return true;
}
return false;
}
bool ShouldDumpVertexShader(const MaterialVertexShader* vertexShader)
{
const auto existingVertexShader = m_dumped_vertex_shaders.find(vertexShader);
if (existingVertexShader == m_dumped_vertex_shaders.end())
{
m_dumped_vertex_shaders.emplace(vertexShader);
return true;
}
return false;
}
private:
std::unordered_set<const MaterialTechnique*> m_dumped_techniques;
std::unordered_set<const MaterialPixelShader*> m_dumped_pixel_shaders;
std::unordered_set<const MaterialVertexShader*> m_dumped_vertex_shaders;
};
void DumpPixelShader(const AssetDumpingContext& context, const MaterialPixelShader& pixelShader) void DumpPixelShader(const AssetDumpingContext& context, const MaterialPixelShader& pixelShader)
{ {
const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForPixelShaderAssetName(pixelShader.name)); const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForPixelShaderAssetName(pixelShader.name));
@@ -73,21 +33,12 @@ namespace
shaderFile->write(vertexShader.prog.loadDef.program, vertexShader.prog.loadDef.programSize); shaderFile->write(vertexShader.prog.loadDef.program, vertexShader.prog.loadDef.programSize);
} }
} // namespace
namespace techset void DumpShaders(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
{
DumperT6::DumperT6(const AssetPool<AssetTechniqueSet::Type>& pool)
: AbstractAssetDumper(pool)
{ {
} auto* shaderState = context.GetZoneAssetDumperState<techset::ShaderDumpingZoneState>();
void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetTechniqueSet::Type>& asset) for (const auto* technique : techset.techniques)
{
const auto* techniqueSet = asset.Asset();
auto* shaderState = context.GetZoneAssetDumperState<ShaderZoneState>();
for (const auto* technique : techniqueSet->techniques)
{ {
if (!technique || !shaderState->ShouldDumpTechnique(technique)) if (!technique || !shaderState->ShouldDumpTechnique(technique))
continue; continue;
@@ -104,4 +55,296 @@ namespace techset
} }
} }
} }
techset::CommonVertexDeclaration ConvertToCommonVertexDeclaration(const MaterialVertexDeclaration* vertexDecl)
{
std::vector<techset::CommonStreamRouting> commonRouting;
if (vertexDecl)
{
const auto streamCount = std::min(static_cast<size_t>(vertexDecl->streamCount), std::extent_v<decltype(MaterialVertexStreamRouting::data)>);
for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++)
{
const auto& routing = vertexDecl->routing.data[streamIndex];
commonRouting.emplace_back(techset::CommonStreamRouting{
.m_source = static_cast<techset::CommonStreamSource>(routing.source),
.m_destination = static_cast<techset::CommonStreamDestination>(routing.dest),
});
}
}
return techset::CommonVertexDeclaration{
.m_routing = std::move(commonRouting),
};
}
techset::CommonShaderArg ConvertToCommonArg(const MaterialShaderArgument& arg)
{
switch (arg.type)
{
case MTL_ARG_CODE_VERTEX_CONST:
case MTL_ARG_CODE_PIXEL_CONST:
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::CODE_CONST,
.m_destination = {.dx11 =
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.code_const_source = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
}
};
case MTL_ARG_MATERIAL_VERTEX_CONST:
case MTL_ARG_MATERIAL_PIXEL_CONST:
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::MATERIAL_CONST,
.m_destination = {.dx11 =
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
};
case MTL_ARG_CODE_PIXEL_SAMPLER:
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::CODE_SAMPLER,
.m_destination = {.dx11 =
{
.m_location = arg.location.samplerIndex,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler),
}
};
case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::MATERIAL_SAMPLER,
.m_destination = {.dx11 =
{
.m_location = arg.location.samplerIndex,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
};
default:
case MTL_ARG_LITERAL_VERTEX_CONST:
case MTL_ARG_LITERAL_PIXEL_CONST:
if (arg.u.literalConst)
{
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::LITERAL_CONST,
.m_destination = {.dx11 =
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.literal_value =
{
(*arg.u.literalConst)[0],
(*arg.u.literalConst)[1],
(*arg.u.literalConst)[2],
(*arg.u.literalConst)[3],
}, }
};
}
return techset::CommonShaderArg{
.m_type = techset::CommonShaderArgType::LITERAL_CONST,
.m_destination = {.dx11 =
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {},
};
}
}
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialVertexShader* vertexShader)
{
techset::CommonTechniqueShader result{};
if (!vertexShader)
return result;
if (vertexShader->name)
result.m_name = vertexShader->name;
if (vertexShader->prog.loadDef.program)
{
result.m_shader_bin = vertexShader->prog.loadDef.program;
result.m_shader_bin_size = vertexShader->prog.loadDef.programSize;
}
if (pass.args)
{
const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
{
const auto& arg = pass.args[argIndex];
switch (arg.type)
{
case MTL_ARG_CODE_VERTEX_CONST:
case MTL_ARG_MATERIAL_VERTEX_CONST:
case MTL_ARG_LITERAL_VERTEX_CONST:
result.m_args.emplace_back(ConvertToCommonArg(arg));
break;
default:
break;
}
}
}
return result;
}
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialPixelShader* pixelShader)
{
techset::CommonTechniqueShader result{};
if (!pixelShader)
return result;
if (pixelShader->name)
result.m_name = pixelShader->name;
if (pixelShader->prog.loadDef.program)
{
result.m_shader_bin = pixelShader->prog.loadDef.program;
result.m_shader_bin_size = pixelShader->prog.loadDef.programSize;
}
if (pass.args)
{
const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
{
const auto& arg = pass.args[argIndex];
switch (arg.type)
{
case MTL_ARG_CODE_PIXEL_CONST:
case MTL_ARG_CODE_PIXEL_SAMPLER:
case MTL_ARG_MATERIAL_PIXEL_CONST:
case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
case MTL_ARG_LITERAL_PIXEL_CONST:
result.m_args.emplace_back(ConvertToCommonArg(arg));
break;
default:
break;
}
}
}
return result;
}
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
{
std::vector<techset::CommonPass> passes;
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
{
const auto& pass = technique.passArray[passIndex];
passes.emplace_back(techset::CommonPass{
.m_sampler_flags = pass.customSamplerFlags,
.m_dx_version = techset::DxVersion::DX11,
.m_vertex_shader = ConvertToCommonShader(pass, pass.vertexShader),
.m_pixel_shader = ConvertToCommonShader(pass, pass.pixelShader),
.m_vertex_declaration = ConvertToCommonVertexDeclaration(pass.vertexDecl),
});
}
return techset::CommonTechnique{
.m_name = technique.name ? technique.name : std::string(),
.m_flags = technique.flags,
.m_passes = std::move(passes),
};
}
void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
{
static techset::CommonCodeSourceInfos codeSourceInfos(commonCodeConstSources,
std::extent_v<decltype(commonCodeConstSources)>,
commonCodeSamplerSources,
std::extent_v<decltype(commonCodeSamplerSources)>);
static techset::CommonStreamRoutingInfos routingInfos(
streamRoutingSources, std::extent_v<decltype(streamRoutingSources)>, streamRoutingDestinations, std::extent_v<decltype(streamRoutingDestinations)>);
auto* techniqueState = context.GetZoneAssetDumperState<techset::TechniqueDumpingZoneState>();
const auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>();
for (const auto* technique : techset.techniques)
{
if (technique && techniqueState->ShouldDumpTechnique(technique))
{
const auto commonTechnique = ConvertToCommonTechnique(*technique);
techset::DumpCommonTechnique(context, commonTechnique, codeSourceInfos, routingInfos, *materialConstantState);
}
}
}
techset::CommonTechset ConvertToCommonTechset(const MaterialTechniqueSet& techset)
{
std::vector<std::string> techniqueNames(std::extent_v<decltype(techniqueTypeNames)>);
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(techniqueTypeNames)>; techniqueIndex++)
{
const auto* technique = techset.techniques[techniqueIndex];
if (technique && technique->name)
techniqueNames[techniqueIndex] = technique->name;
}
return techset::CommonTechset{
.m_name = techset.name,
.m_technique_names = std::move(techniqueNames),
};
}
void DumpTechset(const AssetDumpingContext& context, const MaterialTechniqueSet& techset)
{
static techset::CommonTechniqueTypeNames commonNames(techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
const auto commonTechset = ConvertToCommonTechset(techset);
techset::DumpCommonTechset(commonNames, context, commonTechset);
}
} // namespace
namespace techset
{
DumperT6::DumperT6(const AssetPool<AssetTechniqueSet::Type>& pool)
: AbstractAssetDumper(pool)
{
}
void DumperT6::Dump(AssetDumpingContext& context)
{
context.GetZoneAssetDumperState<MaterialConstantZoneState>()->EnsureInitialized();
AbstractAssetDumper::Dump(context);
}
void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetTechniqueSet::Type>& asset)
{
const auto* techniqueSet = asset.Asset();
DumpTechset(context, *techniqueSet);
DumpTechniques(context, *techniqueSet);
DumpShaders(context, *techniqueSet);
}
} // namespace techset } // namespace techset

View File

@@ -10,6 +10,8 @@ namespace techset
public: public:
explicit DumperT6(const AssetPool<T6::AssetTechniqueSet::Type>& pool); explicit DumperT6(const AssetPool<T6::AssetTechniqueSet::Type>& pool);
void Dump(AssetDumpingContext& context) override;
protected: protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T6::AssetTechniqueSet::Type>& asset) override; void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T6::AssetTechniqueSet::Type>& asset) override;
}; };

View File

@@ -9,13 +9,22 @@
namespace namespace
{ {
constexpr const char* SAMPLER_STR = "Sampler"; constexpr auto SAMPLER_STR = "Sampler";
constexpr const char* GLOBALS_CBUFFER_NAME = "$Globals"; constexpr auto GLOBALS_CBUFFER_NAME = "$Globals";
constexpr const char* PER_OBJECT_CONSTS_CBUFFER_NAME = "PerObjectConsts"; constexpr auto PER_PRIM_CONSTS_CBUFFER_NAME = "PerPrimConsts";
constexpr auto PER_OBJECT_CONSTS_CBUFFER_NAME = "PerObjectConsts";
} // namespace } // namespace
void AbstractMaterialConstantZoneState::ExtractNamesFromZone() AbstractMaterialConstantZoneState::AbstractMaterialConstantZoneState()
: m_initialized(false)
{ {
}
void AbstractMaterialConstantZoneState::EnsureInitialized()
{
if (m_initialized)
return;
con::debug("Building material constant name lookup..."); con::debug("Building material constant name lookup...");
const auto begin = std::chrono::high_resolution_clock::now(); const auto begin = std::chrono::high_resolution_clock::now();
@@ -31,6 +40,8 @@ void AbstractMaterialConstantZoneState::ExtractNamesFromZone()
durationInMs.count(), durationInMs.count(),
m_constant_names_from_shaders.size(), m_constant_names_from_shaders.size(),
m_texture_def_names_from_shaders.size()); m_texture_def_names_from_shaders.size());
m_initialized = true;
} }
bool AbstractMaterialConstantZoneState::GetConstantName(const unsigned hash, std::string& constantName) const bool AbstractMaterialConstantZoneState::GetConstantName(const unsigned hash, std::string& constantName) const
@@ -124,6 +135,12 @@ void AbstractMaterialConstantZoneStateDx11::ExtractNamesFromShader(const void* s
return constantBuffer.m_name == GLOBALS_CBUFFER_NAME; return constantBuffer.m_name == GLOBALS_CBUFFER_NAME;
}); });
const auto perPrimConsts = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
[](const d3d11::ConstantBuffer& constantBuffer)
{
return constantBuffer.m_name == PER_PRIM_CONSTS_CBUFFER_NAME;
});
const auto perObjectConsts = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers), const auto perObjectConsts = std::ranges::find_if(std::as_const(shaderInfo->m_constant_buffers),
[](const d3d11::ConstantBuffer& constantBuffer) [](const d3d11::ConstantBuffer& constantBuffer)
{ {
@@ -136,6 +153,12 @@ void AbstractMaterialConstantZoneStateDx11::ExtractNamesFromShader(const void* s
AddConstantName(variable.m_name); AddConstantName(variable.m_name);
} }
if (perPrimConsts != shaderInfo->m_constant_buffers.end())
{
for (const auto& variable : perPrimConsts->m_variables)
AddConstantName(variable.m_name);
}
if (perObjectConsts != shaderInfo->m_constant_buffers.end()) if (perObjectConsts != shaderInfo->m_constant_buffers.end())
{ {
for (const auto& variable : perObjectConsts->m_variables) for (const auto& variable : perObjectConsts->m_variables)

View File

@@ -9,20 +9,24 @@
class AbstractMaterialConstantZoneState : public IZoneAssetDumperState class AbstractMaterialConstantZoneState : public IZoneAssetDumperState
{ {
public: public:
void ExtractNamesFromZone(); void EnsureInitialized();
bool GetConstantName(unsigned hash, std::string& constantName) const; bool GetConstantName(unsigned hash, std::string& constantName) const;
bool GetTextureDefName(unsigned hash, std::string& textureDefName) const; bool GetTextureDefName(unsigned hash, std::string& textureDefName) const;
[[nodiscard]] virtual unsigned HashString(const std::string& str) const = 0;
protected: protected:
AbstractMaterialConstantZoneState();
virtual void ExtractNamesFromShader(const void* shader, size_t shaderSize) = 0; virtual void ExtractNamesFromShader(const void* shader, size_t shaderSize) = 0;
virtual void ExtractNamesFromZoneInternal() = 0; virtual void ExtractNamesFromZoneInternal() = 0;
virtual void AddStaticKnownNames() = 0; virtual void AddStaticKnownNames() = 0;
virtual unsigned HashString(const std::string& str) = 0;
bool ShouldDumpFromStruct(const void* pStruct); bool ShouldDumpFromStruct(const void* pStruct);
void AddConstantName(const std::string& constantName); void AddConstantName(const std::string& constantName);
bool AddTextureDefName(const std::string& textureDefName); bool AddTextureDefName(const std::string& textureDefName);
bool m_initialized;
std::unordered_set<const void*> m_dumped_structs; 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_constant_names_from_shaders;
std::unordered_map<unsigned, std::string> m_texture_def_names_from_shaders; std::unordered_map<unsigned, std::string> m_texture_def_names_from_shaders;

View File

@@ -369,7 +369,7 @@ namespace material
void CLASS_NAME::Dump(AssetDumpingContext& context) void CLASS_NAME::Dump(AssetDumpingContext& context)
{ {
auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>(); auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>();
materialConstantState->ExtractNamesFromZone(); materialConstantState->EnsureInitialized();
AbstractAssetDumper::Dump(context); AbstractAssetDumper::Dump(context);
} }

View File

@@ -0,0 +1,409 @@
#include "CommonTechniqueDumper.h"
#include "Dumping/AbstractTextDumper.h"
#include "Shader/D3D11ShaderAnalyser.h"
#include "Shader/D3D9ShaderAnalyser.h"
#include "Techset/TechsetCommon.h"
#include "Utils/Logging/Log.h"
#include <cassert>
#include <cstdint>
using namespace techset;
namespace
{
enum class TechniqueShaderType : std::uint8_t
{
VERTEX_SHADER,
PIXEL_SHADER
};
class TechniqueFileWriter : public AbstractTextDumper
{
public:
TechniqueFileWriter(std::ostream& stream,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState)
: AbstractTextDumper(stream),
m_code_source_infos(codeSourceInfos),
m_routing_infos(routingInfos),
m_constant_zone_state(constantZoneState)
{
}
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(technique, pass);
}
private:
void DumpPass(const CommonTechnique& technique, 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(technique, pass.m_vertex_shader, TechniqueShaderType::VERTEX_SHADER, pass.m_dx_version);
DumpShader(technique, pass.m_pixel_shader, TechniqueShaderType::PIXEL_SHADER, pass.m_dx_version);
DumpVertexDecl(pass.m_vertex_declaration);
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 CommonTechnique& technique, const CommonTechniqueShader& shader, const TechniqueShaderType shaderType, const DxVersion dxVersion)
{
if (!shader.m_shader_bin)
{
if (!shader.m_name.empty())
{
m_stream << std::format("// ERROR: Cannot dump shader {} as its data is not loaded\n", shader.m_name);
con::error("Technique {}: Cannot dump shader {} as its data is not loaded\n", technique.m_name, shader.m_name);
}
return;
}
unsigned versionMajor, versionMinor;
if (dxVersion == 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;
DumpShaderHeader(shader, shaderType, versionMajor, versionMinor);
for (const auto& arg : shader.m_args)
DumpShaderArgDx9(technique, arg, *shaderInfo);
}
else
{
assert(dxVersion == 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;
DumpShaderHeader(shader, shaderType, versionMajor, versionMinor);
for (const auto& arg : shader.m_args)
DumpShaderArgDx11(technique, arg, *shaderInfo);
}
DecIndent();
Indent();
m_stream << "}\n";
}
void DumpShaderHeader(const CommonTechniqueShader& shader, const TechniqueShaderType shaderType, unsigned versionMajor, unsigned versionMinor)
{
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";
IncIndent();
}
void DumpShaderArgDx9(const CommonTechnique& technique, const CommonShaderArg& arg, const d3d9::ShaderInfo& shaderInfo) const
{
const auto expectedRegisterSet = arg.m_type == CommonShaderArgType::CODE_SAMPLER || arg.m_type == CommonShaderArgType::MATERIAL_SAMPLER
? d3d9::RegisterSet::SAMPLER
: d3d9::RegisterSet::FLOAT_4;
const auto destinationRegister = arg.m_destination.dx9.m_destination_register;
const auto targetShaderArg = std::ranges::find_if(shaderInfo.m_constants,
[destinationRegister, expectedRegisterSet](const d3d9::ShaderConstant& constant)
{
return constant.m_register_set == expectedRegisterSet
&& constant.m_register_index <= destinationRegister
&& constant.m_register_index + constant.m_register_count > destinationRegister;
});
assert(targetShaderArg != shaderInfo.m_constants.end());
if (targetShaderArg == shaderInfo.m_constants.end())
{
Indent();
m_stream << std::format("// Unrecognized arg dest: {} type: {}\n", destinationRegister, static_cast<unsigned>(arg.m_type));
con::error("Technique {}: Could not find arg (type: {}; dest: {}) in shader",
technique.m_name,
destinationRegister,
static_cast<unsigned>(arg.m_type));
return;
}
std::string codeDestAccessor;
if (targetShaderArg->m_type_elements > 1)
{
codeDestAccessor = std::format("{}[{}]", targetShaderArg->m_name, destinationRegister - targetShaderArg->m_register_index);
}
else
codeDestAccessor = targetShaderArg->m_name;
DumpShaderArg(technique, arg, codeDestAccessor);
}
void DumpShaderArgDx11(const CommonTechnique& technique, const CommonShaderArg& arg, const d3d11::ShaderInfo& shaderInfo) const
{
const auto& destination = arg.m_destination.dx11;
if (arg.m_type == CommonShaderArgType::CODE_CONST || arg.m_type == CommonShaderArgType::MATERIAL_CONST
|| arg.m_type == CommonShaderArgType::LITERAL_CONST)
{
const auto boundResource = std::ranges::find_if(shaderInfo.m_bound_resources,
[destination](const d3d11::BoundResource& resource)
{
return resource.m_type == d3d11::BoundResourceType::CBUFFER
&& resource.m_bind_point >= destination.m_buffer
&& resource.m_bind_point + resource.m_bind_count > destination.m_buffer;
});
if (boundResource == shaderInfo.m_bound_resources.end())
{
Indent();
m_stream << std::format("// Could not find bound resource for arg buffer: {} offset: {} type: {}\n",
destination.m_buffer,
destination.m_location,
static_cast<unsigned>(arg.m_type));
con::error("Technique {}: Could not find bound resource for arg (buffer: {} offset: {} type: {}) in shader",
technique.m_name,
destination.m_buffer,
destination.m_location,
static_cast<unsigned>(arg.m_type));
return;
}
const auto buffer = std::ranges::find_if(shaderInfo.m_constant_buffers,
[&boundResource](const d3d11::ConstantBuffer& constantBuffer)
{
return constantBuffer.m_name == boundResource->m_name;
});
if (buffer == shaderInfo.m_constant_buffers.end())
{
Indent();
m_stream << std::format("// Could not find buffer for bound resource: {}\n", boundResource->m_name);
con::error("Technique {}: Could not find buffer for bound resource: {} in shader", technique.m_name, boundResource->m_name);
return;
}
const auto variable = std::ranges::find_if(buffer->m_variables,
[destination](const d3d11::ConstantBufferVariable& var)
{
return var.m_offset <= destination.m_location
&& var.m_offset + var.m_size >= destination.m_location + destination.m_size;
});
if (variable == buffer->m_variables.end())
{
Indent();
m_stream << std::format("// Could not find variable in buffer: {} offset: {} type: {}\n",
buffer->m_name,
destination.m_location,
static_cast<unsigned>(arg.m_type));
con::error("Technique {}: Could not find variable in buffer for arg (buffer: {} offset: {} type: {}) in shader",
technique.m_name,
buffer->m_name,
destination.m_location,
static_cast<unsigned>(arg.m_type));
return;
}
DumpShaderArg(technique, arg, variable->m_name);
}
else
{
assert(arg.m_type == CommonShaderArgType::CODE_SAMPLER || arg.m_type == CommonShaderArgType::MATERIAL_SAMPLER);
const auto boundResource = std::ranges::find_if(shaderInfo.m_bound_resources,
[destination](const d3d11::BoundResource& resource)
{
return (resource.m_type == d3d11::BoundResourceType::SAMPLER
|| resource.m_type == d3d11::BoundResourceType::TEXTURE)
&& resource.m_bind_point == destination.m_location;
});
if (boundResource == shaderInfo.m_bound_resources.end())
{
Indent();
m_stream << std::format("// Could not find buffer for arg buffer: {} offset: {} type: {}\n",
destination.m_buffer,
destination.m_location,
static_cast<unsigned>(arg.m_type));
con::error("Technique {}: Could not find buffer for arg (buffer: {} offset: {} type: {}) in shader",
technique.m_name,
destination.m_buffer,
destination.m_location,
static_cast<unsigned>(arg.m_type));
return;
}
DumpShaderArg(technique, arg, boundResource->m_name);
}
}
void DumpShaderArg(const CommonTechnique& technique, const CommonShaderArg& arg, std::string codeDestAccessor) const
{
if (arg.m_type == CommonShaderArgType::CODE_CONST)
{
const auto constSourceInfo = m_code_source_infos.GetInfoForCodeConstSource(arg.m_value.code_const_source);
if (constSourceInfo)
{
if (codeDestAccessor != constSourceInfo->accessor)
{
Indent();
m_stream << std::format("{} = constant.{};\n", codeDestAccessor, constSourceInfo->accessor);
}
else
{
#ifdef TECHSET_DEBUG
Indent();
m_stream << std::format("// Omitted due to matching accessors: {} = constant.{};\n", codeDestAccessor, constSourceInfo->accessor);
#endif
}
}
else
{
assert(false);
Indent();
m_stream << std::format("// ERROR: Could not find code source info for const: {}\n", codeDestAccessor);
con::error("Technique {}: Could not find code source info for const {}", technique.m_name, codeDestAccessor);
}
}
else if (arg.m_type == CommonShaderArgType::CODE_SAMPLER)
{
const auto samplerSourceInfo = m_code_source_infos.GetInfoForCodeSamplerSource(arg.m_value.code_sampler_source);
if (samplerSourceInfo)
{
if (codeDestAccessor != samplerSourceInfo->accessor)
{
Indent();
m_stream << std::format("{} = sampler.{};\n", codeDestAccessor, samplerSourceInfo->accessor);
}
else
{
#ifdef TECHSET_DEBUG
Indent();
m_stream << std::format("// Omitted due to matching accessors: {} = sampler.{};\n", codeDestAccessor, samplerSourceInfo->accessor);
#endif
}
}
else
{
assert(false);
Indent();
m_stream << std::format("// ERROR: Could not find code source info for sampler: {}\n", codeDestAccessor);
con::error("Technique {}: Could not find code source info for sampler {}", technique.m_name, codeDestAccessor);
}
}
else if (arg.m_type == CommonShaderArgType::LITERAL_CONST)
{
Indent();
m_stream << std::format("{} = float4({}, {}, {}, {});\n",
codeDestAccessor,
arg.m_value.literal_value[0],
arg.m_value.literal_value[1],
arg.m_value.literal_value[2],
arg.m_value.literal_value[3]);
}
else if (arg.m_type == CommonShaderArgType::MATERIAL_CONST || arg.m_type == CommonShaderArgType::MATERIAL_SAMPLER)
{
Indent();
std::string materialPropertyName;
if (m_constant_zone_state.GetConstantName(arg.m_value.name_hash, materialPropertyName)
|| m_constant_zone_state.GetTextureDefName(arg.m_value.name_hash, materialPropertyName))
{
m_stream << std::format("{} = material.{};\n", codeDestAccessor, materialPropertyName);
}
else if (m_constant_zone_state.HashString(codeDestAccessor) == arg.m_value.name_hash)
{
m_stream << std::format("{} = material.{};\n", codeDestAccessor, codeDestAccessor);
}
else
{
m_stream << std::format("{} = material.#0x{:x};\n", codeDestAccessor, arg.m_value.name_hash);
}
}
else
{
assert(false);
}
}
void DumpVertexDecl(const CommonVertexDeclaration& vertexDeclaration) const
{
if (vertexDeclaration.m_routing.empty())
return;
m_stream << "\n";
for (const auto& routing : vertexDeclaration.m_routing)
{
Indent();
m_stream << std::format(
"vertex.{} = code.{};\n", m_routing_infos.GetDestinationName(routing.m_destination), m_routing_infos.GetSourceName(routing.m_source));
}
}
const CommonCodeSourceInfos& m_code_source_infos;
const CommonStreamRoutingInfos& m_routing_infos;
const AbstractMaterialConstantZoneState& m_constant_zone_state;
};
} // namespace
namespace techset
{
void DumpCommonTechnique(const AssetDumpingContext& context,
const CommonTechnique& technique,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState)
{
const auto techniqueFile = context.OpenAssetFile(GetFileNameForTechniqueName(technique.m_name));
if (techniqueFile)
{
TechniqueFileWriter writer(*techniqueFile, codeSourceInfos, routingInfos, constantZoneState);
writer.DumpTechnique(technique);
}
}
} // namespace techset

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Dumping/AssetDumpingContext.h"
#include "Material/AbstractMaterialConstantZoneState.h"
#include "Techset/CommonTechnique.h"
namespace techset
{
void DumpCommonTechnique(const AssetDumpingContext& context,
const CommonTechnique& technique,
const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState);
} // namespace techset

View File

@@ -0,0 +1,90 @@
#include "CommonTechsetDumper.h"
#include "Dumping/AbstractTextDumper.h"
#include "Techset/TechsetCommon.h"
#include <cassert>
using namespace techset;
namespace
{
class TechsetFileWriter : public AbstractTextDumper
{
public:
TechsetFileWriter(const CommonTechniqueTypeNames& techniqueTypeNames, std::ostream& stream)
: AbstractTextDumper(stream),
m_last_write_was_value(false),
m_technique_type_names(techniqueTypeNames)
{
}
void DumpTechset(const CommonTechset& techset)
{
const auto techniqueCount = m_technique_type_names.GetTechniqueTypeCount();
assert(techset.m_technique_names.size() == techniqueCount);
std::vector<bool> dumpedTechniques(techniqueCount);
for (auto techniqueIndex = 0u; techniqueIndex < techniqueCount; techniqueIndex++)
{
const auto& technique = techset.m_technique_names[techniqueIndex];
if (technique.empty() || dumpedTechniques[techniqueIndex])
continue;
dumpedTechniques[techniqueIndex] = true;
WriteTechniqueType(techniqueIndex);
for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < techniqueCount; nextTechniqueIndex++)
{
if (techset.m_technique_names[nextTechniqueIndex] != technique)
continue;
dumpedTechniques[nextTechniqueIndex] = true;
WriteTechniqueType(nextTechniqueIndex);
}
WriteTechniqueValue(technique);
}
}
private:
void WriteTechniqueType(const size_t techniqueIndex)
{
if (m_last_write_was_value)
{
m_stream << "\n";
m_last_write_was_value = false;
}
m_stream << '"' << m_technique_type_names.GetTechniqueTypeName(techniqueIndex) << "\":\n";
}
void WriteTechniqueValue(const std::string& value)
{
m_last_write_was_value = true;
IncIndent();
Indent();
m_stream << value << ";\n";
DecIndent();
}
bool m_last_write_was_value;
const CommonTechniqueTypeNames& m_technique_type_names;
};
} // namespace
namespace techset
{
void DumpCommonTechset(const CommonTechniqueTypeNames& techniqueTypeNames, const AssetDumpingContext& context, const CommonTechset& techset)
{
const auto techsetFile = context.OpenAssetFile(GetFileNameForTechsetName(techset.m_name));
if (techsetFile)
{
TechsetFileWriter writer(techniqueTypeNames, *techsetFile);
writer.DumpTechset(techset);
}
}
} // namespace techset

View File

@@ -0,0 +1,9 @@
#pragma once
#include "Dumping/AssetDumpingContext.h"
#include "Techset/CommonTechset.h"
namespace techset
{
void DumpCommonTechset(const CommonTechniqueTypeNames& techniqueTypeNames, const AssetDumpingContext& context, const CommonTechset& techset);
} // namespace techset

View File

@@ -0,0 +1,31 @@
#include "ShaderDumpingZoneState.h"
namespace techset
{
bool ShaderDumpingZoneState::ShouldDumpTechnique(const void* technique)
{
if (m_dumped_techniques.contains(technique))
return false;
m_dumped_techniques.emplace(technique);
return true;
}
bool ShaderDumpingZoneState::ShouldDumpVertexShader(const void* vertexShader)
{
if (m_dumped_vertex_shaders.contains(vertexShader))
return false;
m_dumped_vertex_shaders.emplace(vertexShader);
return true;
}
bool ShaderDumpingZoneState::ShouldDumpPixelShader(const void* pixelShader)
{
if (m_dumped_pixel_shaders.contains(pixelShader))
return false;
m_dumped_pixel_shaders.emplace(pixelShader);
return true;
}
} // namespace techset

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Dumping/IZoneAssetDumperState.h"
#include <unordered_set>
namespace techset
{
class ShaderDumpingZoneState final : public IZoneAssetDumperState
{
public:
bool ShouldDumpTechnique(const void* technique);
bool ShouldDumpVertexShader(const void* vertexShader);
bool ShouldDumpPixelShader(const void* pixelShader);
private:
std::unordered_set<const void*> m_dumped_techniques;
std::unordered_set<const void*> m_dumped_vertex_shaders;
std::unordered_set<const void*> m_dumped_pixel_shaders;
};
} // namespace techset

View File

@@ -0,0 +1,13 @@
#include "TechniqueDumpingZoneState.h"
namespace techset
{
bool TechniqueDumpingZoneState::ShouldDumpTechnique(const void* technique)
{
if (m_dumped_techniques.contains(technique))
return false;
m_dumped_techniques.emplace(technique);
return true;
}
} // namespace techset

View File

@@ -0,0 +1,17 @@
#pragma once
#include "Dumping/IZoneAssetDumperState.h"
#include <unordered_set>
namespace techset
{
class TechniqueDumpingZoneState final : public IZoneAssetDumperState
{
public:
bool ShouldDumpTechnique(const void* technique);
private:
std::unordered_set<const void*> m_dumped_techniques;
};
} // namespace techset