2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-03-05 12:33:02 +00:00

fix: errors with common techset dumping

* not respecting transposing matrices
* not respecting arrays
This commit is contained in:
Jan Laupetin
2026-02-27 23:04:42 +01:00
parent 86ae57578b
commit 38abe459e1
6 changed files with 470 additions and 367 deletions

View File

@@ -208,6 +208,48 @@ namespace techset
return std::nullopt; return std::nullopt;
} }
CommonShaderArg::CommonShaderArg(const CommonShaderArgumentType type, const CommonShaderArgDestination& destination, const CommonShaderArgValue& value)
: m_type(type),
m_destination(destination),
m_value(value)
{
}
CommonCodeSourceUpdateFrequency CommonShaderArg::GetFrequency(const CommonCodeSourceInfos& infos) const
{
switch (m_type.m_value_type)
{
case CommonShaderValueType::CODE_CONST:
{
const auto info = infos.GetInfoForCodeConstSource(m_value.code_const_source.m_index);
assert(info);
return info->updateFrequency;
}
case CommonShaderValueType::CODE_SAMPLER:
{
const auto info = infos.GetInfoForCodeSamplerSource(m_value.code_sampler_source);
assert(info);
return info->updateFrequency;
}
case CommonShaderValueType::MATERIAL_CONST:
case CommonShaderValueType::LITERAL_CONST:
case CommonShaderValueType::MATERIAL_SAMPLER:
return CommonCodeSourceUpdateFrequency::RARELY;
default:
assert(false);
return CommonCodeSourceUpdateFrequency::RARELY;
}
}
CommonStreamRouting::CommonStreamRouting(const CommonStreamSource source, const CommonStreamDestination destination)
: m_source(source),
m_destination(destination)
{
}
CommonVertexDeclaration::CommonVertexDeclaration(std::vector<CommonStreamRouting> routing) CommonVertexDeclaration::CommonVertexDeclaration(std::vector<CommonStreamRouting> routing)
: m_routing(std::move(routing)) : m_routing(std::move(routing))
{ {
@@ -221,4 +263,52 @@ namespace techset
return r1.m_source < r2.m_source; return r1.m_source < r2.m_source;
}); });
} }
CommonTechniqueShader::CommonTechniqueShader()
: m_type(CommonTechniqueShaderType::VERTEX)
{
}
CommonTechniqueShader::CommonTechniqueShader(const CommonTechniqueShaderType type, std::string name)
: m_type(type),
m_name(std::move(name))
{
}
CommonPass::CommonPass(const uint32_t samplerFlags,
std::string stateMap,
CommonTechniqueShader vertexShader,
CommonTechniqueShader pixelShader,
CommonVertexDeclaration vertexDeclaration)
: m_sampler_flags(samplerFlags),
m_state_map(std::move(stateMap)),
m_vertex_shader(std::move(vertexShader)),
m_pixel_shader(std::move(pixelShader)),
m_vertex_declaration(std::move(vertexDeclaration))
{
}
CommonPass::FrequencyCounts_t CommonPass::GetFrequencyCounts(const CommonCodeSourceInfos& infos) const
{
FrequencyCounts_t result;
for (auto& count : result)
count = 0;
for (auto& arg : m_args)
result[std::to_underlying(arg.GetFrequency(infos))]++;
return result;
}
CommonTechnique::CommonTechnique(std::string name)
: m_name(std::move(name)),
m_flags(0)
{
}
CommonTechnique::CommonTechnique(std::string name, const uint64_t flags)
: m_name(std::move(name)),
m_flags(flags)
{
}
} // namespace techset } // namespace techset

View File

@@ -172,10 +172,17 @@ namespace techset
std::unordered_map<std::string, CommonStreamDestination> m_destination_abbreviation_lookup; std::unordered_map<std::string, CommonStreamDestination> m_destination_abbreviation_lookup;
}; };
struct CommonShaderArgCodeConstValue
{
CommonCodeConstSource m_index;
unsigned m_first_row;
unsigned m_row_count;
};
union CommonShaderArgValue union CommonShaderArgValue
{ {
std::array<float, 4> literal_value; std::array<float, 4> literal_value;
CommonCodeConstSource code_const_source; CommonShaderArgCodeConstValue code_const_source;
CommonCodeSamplerSource code_sampler_source; CommonCodeSamplerSource code_sampler_source;
unsigned name_hash; unsigned name_hash;
}; };
@@ -186,12 +193,23 @@ namespace techset
unsigned m_destination_register; unsigned m_destination_register;
}; };
// In case of a constant: Offset in constant buffer
// In case of a sampler: Index of sampler + index of texture
union CommonShaderArgLocationDx11
{
unsigned constant_buffer_offset;
struct
{
unsigned texture_index;
unsigned sampler_index;
};
};
class CommonShaderArgDestinationDx11 class CommonShaderArgDestinationDx11
{ {
public: public:
// In case of a constant: Offset in constant buffer CommonShaderArgLocationDx11 m_location;
// In case of a sampler: Index of sampler
unsigned m_location;
unsigned m_size; unsigned m_size;
unsigned m_buffer; unsigned m_buffer;
}; };
@@ -202,31 +220,26 @@ namespace techset
CommonShaderArgDestinationDx11 dx11; 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 class CommonShaderArg
{ {
public: public:
CommonShaderArgType m_type; CommonShaderArg() = default;
CommonShaderArg(CommonShaderArgumentType type, const CommonShaderArgDestination& destination, const CommonShaderArgValue& value);
[[nodiscard]] CommonCodeSourceUpdateFrequency GetFrequency(const CommonCodeSourceInfos& infos) const;
CommonShaderArgumentType m_type;
CommonShaderArgDestination m_destination; CommonShaderArgDestination m_destination;
CommonShaderArgValue m_value; CommonShaderArgValue m_value;
std::optional<CommonCodeSourceUpdateFrequency> m_bin;
}; };
class CommonStreamRouting class CommonStreamRouting
{ {
public: public:
CommonStreamRouting() = default;
CommonStreamRouting(CommonStreamSource source, CommonStreamDestination destination);
CommonStreamSource m_source; CommonStreamSource m_source;
CommonStreamDestination m_destination; CommonStreamDestination m_destination;
}; };
@@ -242,36 +255,61 @@ namespace techset
std::vector<CommonStreamRouting> m_routing; std::vector<CommonStreamRouting> m_routing;
}; };
class CommonTechniqueShaderBin
{
public:
const void* m_shader_bin;
size_t m_shader_bin_size;
};
class CommonTechniqueShader class CommonTechniqueShader
{ {
public: public:
CommonTechniqueShader();
CommonTechniqueShader(CommonTechniqueShaderType type, std::string name);
CommonTechniqueShaderType m_type;
std::string m_name; std::string m_name;
const void* m_shader_bin; std::optional<CommonTechniqueShaderBin> m_bin;
size_t m_shader_bin_size; };
class CommonPass
{
public:
using FrequencyCounts_t = std::array<size_t, std::to_underlying(CommonCodeSourceUpdateFrequency::COUNT)>;
CommonPass() = default;
CommonPass(uint32_t samplerFlags,
std::string stateMap,
CommonTechniqueShader vertexShader,
CommonTechniqueShader pixelShader,
CommonVertexDeclaration vertexDeclaration);
[[nodiscard]] FrequencyCounts_t GetFrequencyCounts(const CommonCodeSourceInfos& infos) const;
uint32_t m_sampler_flags;
std::string m_state_map;
CommonTechniqueShader m_vertex_shader;
CommonTechniqueShader m_pixel_shader;
CommonVertexDeclaration m_vertex_declaration;
std::vector<CommonShaderArg> m_args; std::vector<CommonShaderArg> m_args;
}; };
class CommonTechnique
{
public:
CommonTechnique() = default;
explicit CommonTechnique(std::string name);
CommonTechnique(std::string name, uint64_t flags);
std::string m_name;
uint64_t m_flags;
std::vector<CommonPass> m_passes;
};
enum class DxVersion : std::uint8_t enum class DxVersion : std::uint8_t
{ {
DX9, DX9,
DX11 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 } // namespace techset

View File

@@ -9,7 +9,6 @@
#include "Techset/TechniqueDumpingZoneState.h" #include "Techset/TechniqueDumpingZoneState.h"
#include <cstdint> #include <cstdint>
#include <unordered_set>
using namespace T5; using namespace T5;
@@ -67,10 +66,8 @@ namespace
for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++) for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++)
{ {
const auto& routing = vertexDecl->routing.data[streamIndex]; const auto& routing = vertexDecl->routing.data[streamIndex];
commonRouting.emplace_back(techset::CommonStreamRouting{ commonRouting.emplace_back(static_cast<techset::CommonStreamSource>(routing.source),
.m_source = static_cast<techset::CommonStreamSource>(routing.source), static_cast<techset::CommonStreamDestination>(routing.dest));
.m_destination = static_cast<techset::CommonStreamDestination>(routing.dest),
});
} }
} }
@@ -79,92 +76,72 @@ namespace
techset::CommonShaderArg ConvertToCommonArg(const MaterialShaderArgument& arg) techset::CommonShaderArg ConvertToCommonArg(const MaterialShaderArgument& arg)
{ {
const techset::CommonShaderArgDestination destination{.dx9 = {.m_destination_register = arg.dest}};
switch (arg.type) switch (arg.type)
{ {
case MTL_ARG_CODE_VERTEX_CONST: case MTL_ARG_CODE_VERTEX_CONST:
case MTL_ARG_CODE_PIXEL_CONST: case MTL_ARG_CODE_PIXEL_CONST:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::CODE_CONST, const techset::CommonShaderArgCodeConstValue codeConstValue{
.m_destination = {.dx9 = .m_index = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
{ .m_first_row = arg.u.codeConst.firstRow,
.m_destination_register = arg.dest, .m_row_count = arg.u.codeConst.rowCount,
}},
.m_value = {
.code_const_source = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
}
}; };
const techset::CommonShaderArgValue value{.code_const_source = codeConstValue};
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_MATERIAL_VERTEX_CONST: case MTL_ARG_MATERIAL_VERTEX_CONST:
case MTL_ARG_MATERIAL_PIXEL_CONST: case MTL_ARG_MATERIAL_PIXEL_CONST:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::MATERIAL_CONST, const techset::CommonShaderArgValue value{
.m_destination = {.dx9 = .name_hash = arg.u.nameHash,
{
.m_destination_register = arg.dest,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
}; };
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_CODE_PIXEL_SAMPLER: case MTL_ARG_CODE_PIXEL_SAMPLER:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::CODE_SAMPLER, const techset::CommonShaderArgValue value{
.m_destination = {.dx9 = .code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler),
{
.m_destination_register = arg.dest,
}},
.m_value = {
.code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler),
}
}; };
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_MATERIAL_PIXEL_SAMPLER: case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::MATERIAL_SAMPLER, const techset::CommonShaderArgValue value{
.m_destination = {.dx9 = .name_hash = arg.u.nameHash,
{
.m_destination_register = arg.dest,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
}; };
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
default: default:
case MTL_ARG_LITERAL_VERTEX_CONST: case MTL_ARG_LITERAL_VERTEX_CONST:
case MTL_ARG_LITERAL_PIXEL_CONST: case MTL_ARG_LITERAL_PIXEL_CONST:
{
techset::CommonShaderArgValue value{};
if (arg.u.literalConst) if (arg.u.literalConst)
{ {
return techset::CommonShaderArg{ value.literal_value = {
.m_type = techset::CommonShaderArgType::LITERAL_CONST, (*arg.u.literalConst)[0],
.m_destination = {.dx9 = (*arg.u.literalConst)[1],
{ (*arg.u.literalConst)[2],
.m_destination_register = arg.dest, (*arg.u.literalConst)[3],
}},
.m_value = {
.literal_value =
{
(*arg.u.literalConst)[0],
(*arg.u.literalConst)[1],
(*arg.u.literalConst)[2],
(*arg.u.literalConst)[3],
}, }
}; };
} }
return techset::CommonShaderArg{ return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
.m_type = techset::CommonShaderArgType::LITERAL_CONST, }
.m_destination = {.dx9 =
{
.m_destination_register = arg.dest,
}},
.m_value = {},
};
} }
} }
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialVertexShader* vertexShader) techset::CommonTechniqueShader ConvertToCommonShader(const MaterialVertexShader* vertexShader)
{ {
techset::CommonTechniqueShader result{}; techset::CommonTechniqueShader result{};
if (!vertexShader) if (!vertexShader)
@@ -175,34 +152,16 @@ namespace
if (vertexShader->prog.loadDef.program) if (vertexShader->prog.loadDef.program)
{ {
result.m_shader_bin = vertexShader->prog.loadDef.program; result.m_bin = techset::CommonTechniqueShaderBin{
result.m_shader_bin_size = vertexShader->prog.loadDef.programSize * sizeof(uint32_t); .m_shader_bin = vertexShader->prog.loadDef.program,
} .m_shader_bin_size = vertexShader->prog.loadDef.programSize * sizeof(uint32_t),
};
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; return result;
} }
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialPixelShader* pixelShader) techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPixelShader* pixelShader)
{ {
techset::CommonTechniqueShader result{}; techset::CommonTechniqueShader result{};
if (!pixelShader) if (!pixelShader)
@@ -213,30 +172,10 @@ namespace
if (pixelShader->prog.loadDef.program) if (pixelShader->prog.loadDef.program)
{ {
result.m_shader_bin = pixelShader->prog.loadDef.program; result.m_bin = techset::CommonTechniqueShaderBin{
result.m_shader_bin_size = pixelShader->prog.loadDef.programSize * sizeof(uint32_t); .m_shader_bin = pixelShader->prog.loadDef.program,
} .m_shader_bin_size = pixelShader->prog.loadDef.programSize * sizeof(uint32_t),
};
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; return result;
@@ -244,26 +183,30 @@ namespace
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique) techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
{ {
std::vector<techset::CommonPass> passes; techset::CommonTechnique commonTechnique(technique.name ? technique.name : std::string(), technique.flags);
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++) for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
{ {
const auto& pass = technique.passArray[passIndex]; const auto& pass = technique.passArray[passIndex];
techset::CommonPass commonPass(pass.customSamplerFlags,
// No clue what the actual state map was
"passthrough",
ConvertToCommonShader(pass.vertexShader),
ConvertToCommonShader(pass.pixelShader),
ConvertToCommonVertexDeclaration(pass.vertexDecl));
passes.emplace_back(techset::CommonPass{ if (pass.args)
.m_sampler_flags = pass.customSamplerFlags, {
.m_dx_version = techset::DxVersion::DX9, const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
.m_vertex_shader = ConvertToCommonShader(pass, pass.vertexShader), commonPass.m_args.reserve(totalArgCount);
.m_pixel_shader = ConvertToCommonShader(pass, pass.pixelShader), for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
.m_vertex_declaration = ConvertToCommonVertexDeclaration(pass.vertexDecl), commonPass.m_args.emplace_back(ConvertToCommonArg(pass.args[argIndex]));
}); }
commonTechnique.m_passes.emplace_back(std::move(commonPass));
} }
return techset::CommonTechnique{ return 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) void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
@@ -276,7 +219,8 @@ namespace
{ {
const auto commonTechnique = ConvertToCommonTechnique(*technique); const auto commonTechnique = ConvertToCommonTechnique(*technique);
techset::DumpCommonTechnique(context, commonTechnique, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState); techset::DumpCommonTechnique(
context, commonTechnique, techset::DxVersion::DX9, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState);
} }
} }
} }

View File

@@ -8,7 +8,7 @@
#include "Techset/ShaderDumpingZoneState.h" #include "Techset/ShaderDumpingZoneState.h"
#include "Techset/TechniqueDumpingZoneState.h" #include "Techset/TechniqueDumpingZoneState.h"
#include <unordered_set> #include <cassert>
using namespace T6; using namespace T6;
@@ -66,10 +66,8 @@ namespace
for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++) for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++)
{ {
const auto& routing = vertexDecl->routing.data[streamIndex]; const auto& routing = vertexDecl->routing.data[streamIndex];
commonRouting.emplace_back(techset::CommonStreamRouting{ commonRouting.emplace_back(static_cast<techset::CommonStreamSource>(routing.source),
.m_source = static_cast<techset::CommonStreamSource>(routing.source), static_cast<techset::CommonStreamDestination>(routing.dest));
.m_destination = static_cast<techset::CommonStreamDestination>(routing.dest),
});
} }
} }
@@ -82,100 +80,119 @@ namespace
{ {
case MTL_ARG_CODE_VERTEX_CONST: case MTL_ARG_CODE_VERTEX_CONST:
case MTL_ARG_CODE_PIXEL_CONST: case MTL_ARG_CODE_PIXEL_CONST:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::CODE_CONST, const techset::CommonShaderArgCodeConstValue codeConstValue{
.m_destination = {.dx11 = .m_index = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
{ .m_first_row = arg.u.codeConst.firstRow,
.m_location = arg.location.offset, .m_row_count = arg.u.codeConst.rowCount,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.code_const_source = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
}
}; };
const techset::CommonShaderArgValue value{.code_const_source = codeConstValue};
const techset::CommonShaderArgLocationDx11 location{
.constant_buffer_offset = arg.location.offset,
};
const techset::CommonShaderArgDestination destination = {
.dx11 = {
.m_location = location,
.m_size = arg.size,
.m_buffer = arg.buffer,
}
};
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_MATERIAL_VERTEX_CONST: case MTL_ARG_MATERIAL_VERTEX_CONST:
case MTL_ARG_MATERIAL_PIXEL_CONST: case MTL_ARG_MATERIAL_PIXEL_CONST:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::MATERIAL_CONST, const techset::CommonShaderArgValue value{
.m_destination = {.dx11 = .name_hash = arg.u.nameHash,
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
}; };
const techset::CommonShaderArgLocationDx11 location{
.constant_buffer_offset = arg.location.offset,
};
const techset::CommonShaderArgDestination destination{
.dx11 = {
.m_location = location,
.m_size = arg.size,
.m_buffer = arg.buffer,
}
};
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_CODE_PIXEL_SAMPLER: case MTL_ARG_CODE_PIXEL_SAMPLER:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::CODE_SAMPLER, const techset::CommonShaderArgValue value{
.m_destination = {.dx11 = .code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler),
{ };
.m_location = arg.location.samplerIndex, const techset::CommonShaderArgLocationDx11 location{
.m_size = arg.size, .texture_index = arg.location.textureIndex,
.m_buffer = arg.buffer, .sampler_index = arg.location.samplerIndex,
}}, };
.m_value = { const techset::CommonShaderArgDestination destination = {
.code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler), .dx11 = {
} .m_location = location,
.m_size = arg.size,
.m_buffer = arg.buffer,
}
}; };
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
case MTL_ARG_MATERIAL_PIXEL_SAMPLER: case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
return techset::CommonShaderArg{ {
.m_type = techset::CommonShaderArgType::MATERIAL_SAMPLER, const techset::CommonShaderArgValue value{
.m_destination = {.dx11 = .name_hash = arg.u.nameHash,
{
.m_location = arg.location.samplerIndex,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {
.name_hash = arg.u.nameHash,
}
}; };
const techset::CommonShaderArgLocationDx11 location{
.texture_index = arg.location.textureIndex,
.sampler_index = arg.location.samplerIndex,
};
const techset::CommonShaderArgDestination destination = {
.dx11 = {
.m_location = location,
.m_size = arg.size,
.m_buffer = arg.buffer,
}
};
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
default: default:
case MTL_ARG_LITERAL_VERTEX_CONST: case MTL_ARG_LITERAL_VERTEX_CONST:
case MTL_ARG_LITERAL_PIXEL_CONST: case MTL_ARG_LITERAL_PIXEL_CONST:
{
techset::CommonShaderArgValue value{};
if (arg.u.literalConst) if (arg.u.literalConst)
{ {
return techset::CommonShaderArg{ value.literal_value = {
.m_type = techset::CommonShaderArgType::LITERAL_CONST, (*arg.u.literalConst)[0],
.m_destination = {.dx11 = (*arg.u.literalConst)[1],
{ (*arg.u.literalConst)[2],
.m_location = arg.location.offset, (*arg.u.literalConst)[3],
.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{ const techset::CommonShaderArgLocationDx11 location{
.m_type = techset::CommonShaderArgType::LITERAL_CONST, .constant_buffer_offset = arg.location.offset,
.m_destination = {.dx11 =
{
.m_location = arg.location.offset,
.m_size = arg.size,
.m_buffer = arg.buffer,
}},
.m_value = {},
}; };
const techset::CommonShaderArgDestination destination = {
.dx11 = {
.m_location = location,
.m_size = arg.size,
.m_buffer = arg.buffer,
}
};
return techset::CommonShaderArg(commonArgumentTypes[arg.type], destination, value);
}
} }
} }
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialVertexShader* vertexShader) techset::CommonTechniqueShader ConvertToCommonShader(const MaterialVertexShader* vertexShader)
{ {
techset::CommonTechniqueShader result{}; techset::CommonTechniqueShader result{};
if (!vertexShader) if (!vertexShader)
@@ -186,34 +203,16 @@ namespace
if (vertexShader->prog.loadDef.program) if (vertexShader->prog.loadDef.program)
{ {
result.m_shader_bin = vertexShader->prog.loadDef.program; result.m_bin = techset::CommonTechniqueShaderBin{
result.m_shader_bin_size = vertexShader->prog.loadDef.programSize; .m_shader_bin = vertexShader->prog.loadDef.program,
} .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; return result;
} }
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialPixelShader* pixelShader) techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPixelShader* pixelShader)
{ {
techset::CommonTechniqueShader result{}; techset::CommonTechniqueShader result{};
if (!pixelShader) if (!pixelShader)
@@ -224,30 +223,10 @@ namespace
if (pixelShader->prog.loadDef.program) if (pixelShader->prog.loadDef.program)
{ {
result.m_shader_bin = pixelShader->prog.loadDef.program; result.m_bin = techset::CommonTechniqueShaderBin{
result.m_shader_bin_size = pixelShader->prog.loadDef.programSize; .m_shader_bin = pixelShader->prog.loadDef.program,
} .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; return result;
@@ -255,26 +234,30 @@ namespace
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique) techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
{ {
std::vector<techset::CommonPass> passes; techset::CommonTechnique commonTechnique(technique.name ? technique.name : std::string(), technique.flags);
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++) for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
{ {
const auto& pass = technique.passArray[passIndex]; const auto& pass = technique.passArray[passIndex];
techset::CommonPass commonPass(pass.customSamplerFlags,
// No clue what the actual state map was
"passthrough",
ConvertToCommonShader(pass.vertexShader),
ConvertToCommonShader(pass.pixelShader),
ConvertToCommonVertexDeclaration(pass.vertexDecl));
passes.emplace_back(techset::CommonPass{ if (pass.args)
.m_sampler_flags = pass.customSamplerFlags, {
.m_dx_version = techset::DxVersion::DX11, const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
.m_vertex_shader = ConvertToCommonShader(pass, pass.vertexShader), commonPass.m_args.reserve(totalArgCount);
.m_pixel_shader = ConvertToCommonShader(pass, pass.pixelShader), for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
.m_vertex_declaration = ConvertToCommonVertexDeclaration(pass.vertexDecl), commonPass.m_args.emplace_back(ConvertToCommonArg(pass.args[argIndex]));
}); }
commonTechnique.m_passes.emplace_back(std::move(commonPass));
} }
return techset::CommonTechnique{ return 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) void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
@@ -287,7 +270,8 @@ namespace
{ {
const auto commonTechnique = ConvertToCommonTechnique(*technique); const auto commonTechnique = ConvertToCommonTechnique(*technique);
techset::DumpCommonTechnique(context, commonTechnique, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState); techset::DumpCommonTechnique(
context, commonTechnique, techset::DxVersion::DX11, commonCodeSourceInfos, commonRoutingInfos, *materialConstantState);
} }
} }
} }

View File

@@ -13,20 +13,16 @@ using namespace techset;
namespace namespace
{ {
enum class TechniqueShaderType : std::uint8_t
{
VERTEX_SHADER,
PIXEL_SHADER
};
class TechniqueFileWriter : public AbstractTextDumper class TechniqueFileWriter : public AbstractTextDumper
{ {
public: public:
TechniqueFileWriter(std::ostream& stream, TechniqueFileWriter(std::ostream& stream,
const DxVersion dxVersion,
const CommonCodeSourceInfos& codeSourceInfos, const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos, const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState) const AbstractMaterialConstantZoneState& constantZoneState)
: AbstractTextDumper(stream), : AbstractTextDumper(stream),
m_dx_version(dxVersion),
m_code_source_infos(codeSourceInfos), m_code_source_infos(codeSourceInfos),
m_routing_infos(routingInfos), m_routing_infos(routingInfos),
m_constant_zone_state(constantZoneState) m_constant_zone_state(constantZoneState)
@@ -73,8 +69,8 @@ namespace
#endif #endif
DumpStateMap(); DumpStateMap();
DumpShader(technique, pass.m_vertex_shader, TechniqueShaderType::VERTEX_SHADER, pass.m_dx_version); DumpShader(technique, pass, pass.m_vertex_shader, CommonTechniqueShaderType::VERTEX, m_dx_version);
DumpShader(technique, pass.m_pixel_shader, TechniqueShaderType::PIXEL_SHADER, pass.m_dx_version); DumpShader(technique, pass, pass.m_pixel_shader, CommonTechniqueShaderType::PIXEL, m_dx_version);
DumpVertexDecl(pass.m_vertex_declaration); DumpVertexDecl(pass.m_vertex_declaration);
DecIndent(); DecIndent();
@@ -89,9 +85,13 @@ namespace
m_stream << "stateMap \"passthrough\"; // TODO\n"; m_stream << "stateMap \"passthrough\"; // TODO\n";
} }
void DumpShader(const CommonTechnique& technique, const CommonTechniqueShader& shader, const TechniqueShaderType shaderType, const DxVersion dxVersion) void DumpShader(const CommonTechnique& technique,
const CommonPass& pass,
const CommonTechniqueShader& shader,
const CommonTechniqueShaderType shaderType,
const DxVersion dxVersion)
{ {
if (!shader.m_shader_bin) if (!shader.m_bin || !shader.m_bin->m_shader_bin)
{ {
if (!shader.m_name.empty()) if (!shader.m_name.empty())
{ {
@@ -105,7 +105,7 @@ namespace
unsigned versionMajor, versionMinor; unsigned versionMajor, versionMinor;
if (dxVersion == DxVersion::DX9) if (dxVersion == DxVersion::DX9)
{ {
const auto shaderInfo = d3d9::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size); const auto shaderInfo = d3d9::ShaderAnalyser::GetShaderInfo(shader.m_bin->m_shader_bin, shader.m_bin->m_shader_bin_size);
assert(shaderInfo); assert(shaderInfo);
if (!shaderInfo) if (!shaderInfo)
return; return;
@@ -115,13 +115,16 @@ namespace
DumpShaderHeader(shader, shaderType, versionMajor, versionMinor); DumpShaderHeader(shader, shaderType, versionMajor, versionMinor);
for (const auto& arg : shader.m_args) for (const auto& arg : pass.m_args)
DumpShaderArgDx9(technique, arg, *shaderInfo); {
if (arg.m_type.m_shader_type == shaderType)
DumpShaderArgDx9(technique, arg, *shaderInfo);
}
} }
else else
{ {
assert(dxVersion == DxVersion::DX11); assert(dxVersion == DxVersion::DX11);
const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size); const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(shader.m_bin->m_shader_bin, shader.m_bin->m_shader_bin_size);
assert(shaderInfo); assert(shaderInfo);
if (!shaderInfo) if (!shaderInfo)
return; return;
@@ -131,8 +134,11 @@ namespace
DumpShaderHeader(shader, shaderType, versionMajor, versionMinor); DumpShaderHeader(shader, shaderType, versionMajor, versionMinor);
for (const auto& arg : shader.m_args) for (const auto& arg : pass.m_args)
DumpShaderArgDx11(technique, arg, *shaderInfo); {
if (arg.m_type.m_shader_type == shaderType)
DumpShaderArgDx11(technique, arg, *shaderInfo);
}
} }
DecIndent(); DecIndent();
@@ -140,9 +146,9 @@ namespace
m_stream << "}\n"; m_stream << "}\n";
} }
void DumpShaderHeader(const CommonTechniqueShader& shader, const TechniqueShaderType shaderType, unsigned versionMajor, unsigned versionMinor) void DumpShaderHeader(const CommonTechniqueShader& shader, const CommonTechniqueShaderType shaderType, unsigned versionMajor, unsigned versionMinor)
{ {
const auto shaderTypeName = shaderType == TechniqueShaderType::VERTEX_SHADER ? "vertexShader" : "pixelShader"; const auto shaderTypeName = shaderType == CommonTechniqueShaderType::VERTEX ? "vertexShader" : "pixelShader";
m_stream << "\n"; m_stream << "\n";
Indent(); Indent();
@@ -154,9 +160,10 @@ namespace
void DumpShaderArgDx9(const CommonTechnique& technique, const CommonShaderArg& arg, const d3d9::ShaderInfo& shaderInfo) const 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 const auto expectedRegisterSet =
? d3d9::RegisterSet::SAMPLER arg.m_type.m_value_type == CommonShaderValueType::CODE_SAMPLER || arg.m_type.m_value_type == CommonShaderValueType::MATERIAL_SAMPLER
: d3d9::RegisterSet::FLOAT_4; ? d3d9::RegisterSet::SAMPLER
: d3d9::RegisterSet::FLOAT_4;
const auto destinationRegister = arg.m_destination.dx9.m_destination_register; const auto destinationRegister = arg.m_destination.dx9.m_destination_register;
const auto targetShaderArg = std::ranges::find_if(shaderInfo.m_constants, const auto targetShaderArg = std::ranges::find_if(shaderInfo.m_constants,
[destinationRegister, expectedRegisterSet](const d3d9::ShaderConstant& constant) [destinationRegister, expectedRegisterSet](const d3d9::ShaderConstant& constant)
@@ -170,11 +177,11 @@ namespace
if (targetShaderArg == shaderInfo.m_constants.end()) if (targetShaderArg == shaderInfo.m_constants.end())
{ {
Indent(); Indent();
m_stream << std::format("// Unrecognized arg dest: {} type: {}\n", destinationRegister, static_cast<unsigned>(arg.m_type)); m_stream << std::format("// Unrecognized arg dest: {} type: {}\n", destinationRegister, static_cast<unsigned>(arg.m_type.m_value_type));
con::error("Technique {}: Could not find arg (type: {}; dest: {}) in shader", con::error("Technique {}: Could not find arg (type: {}; dest: {}) in shader",
technique.m_name, technique.m_name,
destinationRegister, destinationRegister,
static_cast<unsigned>(arg.m_type)); static_cast<unsigned>(arg.m_type.m_value_type));
return; return;
} }
@@ -186,14 +193,14 @@ namespace
else else
codeDestAccessor = targetShaderArg->m_name; codeDestAccessor = targetShaderArg->m_name;
DumpShaderArg(technique, arg, codeDestAccessor); const auto isTransposed = targetShaderArg->m_class == d3d9::ParameterClass::MATRIX_COLUMNS;
DumpShaderArg(technique, arg, codeDestAccessor, isTransposed);
} }
void DumpShaderArgDx11(const CommonTechnique& technique, const CommonShaderArg& arg, const d3d11::ShaderInfo& shaderInfo) const void DumpShaderArgDx11(const CommonTechnique& technique, const CommonShaderArg& arg, const d3d11::ShaderInfo& shaderInfo) const
{ {
const auto& destination = arg.m_destination.dx11; const auto& destination = arg.m_destination.dx11;
if (arg.m_type == CommonShaderArgType::CODE_CONST || arg.m_type == CommonShaderArgType::MATERIAL_CONST if (IsConstValueType(arg.m_type.m_value_type))
|| arg.m_type == CommonShaderArgType::LITERAL_CONST)
{ {
const auto boundResource = std::ranges::find_if(shaderInfo.m_bound_resources, const auto boundResource = std::ranges::find_if(shaderInfo.m_bound_resources,
[destination](const d3d11::BoundResource& resource) [destination](const d3d11::BoundResource& resource)
@@ -207,13 +214,13 @@ namespace
Indent(); Indent();
m_stream << std::format("// Could not find bound resource for arg buffer: {} offset: {} type: {}\n", m_stream << std::format("// Could not find bound resource for arg buffer: {} offset: {} type: {}\n",
destination.m_buffer, destination.m_buffer,
destination.m_location, destination.m_location.constant_buffer_offset,
static_cast<unsigned>(arg.m_type)); static_cast<unsigned>(arg.m_type.m_value_type));
con::error("Technique {}: Could not find bound resource for arg (buffer: {} offset: {} type: {}) in shader", con::error("Technique {}: Could not find bound resource for arg (buffer: {} offset: {} type: {}) in shader",
technique.m_name, technique.m_name,
destination.m_buffer, destination.m_buffer,
destination.m_location, destination.m_location.constant_buffer_offset,
static_cast<unsigned>(arg.m_type)); static_cast<unsigned>(arg.m_type.m_value_type));
return; return;
} }
const auto buffer = std::ranges::find_if(shaderInfo.m_constant_buffers, const auto buffer = std::ranges::find_if(shaderInfo.m_constant_buffers,
@@ -229,75 +236,112 @@ namespace
return; return;
} }
const auto variable = std::ranges::find_if(buffer->m_variables, const auto variable =
[destination](const d3d11::ConstantBufferVariable& var) 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; return var.m_offset <= destination.m_location.constant_buffer_offset
}); && var.m_offset + var.m_size >= destination.m_location.constant_buffer_offset + destination.m_size;
});
if (variable == buffer->m_variables.end()) if (variable == buffer->m_variables.end())
{ {
Indent(); Indent();
m_stream << std::format("// Could not find variable in buffer: {} offset: {} type: {}\n", m_stream << std::format("// Could not find variable in buffer: {} offset: {} type: {}\n",
buffer->m_name, buffer->m_name,
destination.m_location, destination.m_location.constant_buffer_offset,
static_cast<unsigned>(arg.m_type)); static_cast<unsigned>(arg.m_type.m_value_type));
con::error("Technique {}: Could not find variable in buffer for arg (buffer: {} offset: {} type: {}) in shader", con::error("Technique {}: Could not find variable in buffer for arg (buffer: {} offset: {} type: {}) in shader",
technique.m_name, technique.m_name,
buffer->m_name, buffer->m_name,
destination.m_location, destination.m_location.constant_buffer_offset,
static_cast<unsigned>(arg.m_type)); static_cast<unsigned>(arg.m_type.m_value_type));
return; return;
} }
DumpShaderArg(technique, arg, variable->m_name); std::string codeDestAccessor;
if (variable->m_element_count <= 1)
{
codeDestAccessor = variable->m_name;
}
else
{
const auto elementSize = variable->m_size / variable->m_element_count;
// Assert destination is aligned with element size
assert((destination.m_location.constant_buffer_offset - variable->m_offset) % elementSize == 0);
const auto destinationIndex = (destination.m_location.constant_buffer_offset - variable->m_offset) / elementSize;
codeDestAccessor = std::format("{}[{}]", variable->m_name, destinationIndex);
}
const auto isTransposed = variable->m_variable_class == d3d11::VariableClass::MATRIX_COLUMNS;
DumpShaderArg(technique, arg, codeDestAccessor, isTransposed);
} }
else else
{ {
assert(arg.m_type == CommonShaderArgType::CODE_SAMPLER || arg.m_type == CommonShaderArgType::MATERIAL_SAMPLER); assert(IsSamplerValueType(arg.m_type.m_value_type));
const auto boundResource = std::ranges::find_if(shaderInfo.m_bound_resources, // The game seems to guarantee the texture name to be the accurate one
[destination](const d3d11::BoundResource& resource) const auto boundTextureResource = 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) if (resource.m_type == d3d11::BoundResourceType::TEXTURE)
&& resource.m_bind_point == destination.m_location; return resource.m_bind_point == destination.m_location.texture_index;
});
if (boundResource == shaderInfo.m_bound_resources.end()) return false;
});
if (boundTextureResource == shaderInfo.m_bound_resources.end())
{ {
Indent(); Indent();
m_stream << std::format("// Could not find buffer for arg buffer: {} offset: {} type: {}\n", m_stream << std::format("// Could not find buffer for arg buffer: {} sampler: {} texture: {} type: {}\n",
destination.m_buffer, destination.m_buffer,
destination.m_location, destination.m_location.sampler_index,
static_cast<unsigned>(arg.m_type)); destination.m_location.texture_index,
con::error("Technique {}: Could not find buffer for arg (buffer: {} offset: {} type: {}) in shader", static_cast<unsigned>(arg.m_type.m_value_type));
con::error("Technique {}: Could not find buffer for arg (buffer: {} sampler: {} texture: {} type: {}) in shader",
technique.m_name, technique.m_name,
destination.m_buffer, destination.m_buffer,
destination.m_location, destination.m_location.sampler_index,
static_cast<unsigned>(arg.m_type)); destination.m_location.texture_index,
static_cast<unsigned>(arg.m_type.m_value_type));
return; return;
} }
DumpShaderArg(technique, arg, boundResource->m_name); DumpShaderArg(technique, arg, boundTextureResource->m_name, false);
} }
} }
void DumpShaderArg(const CommonTechnique& technique, const CommonShaderArg& arg, std::string codeDestAccessor) const void DumpShaderArg(const CommonTechnique& technique, const CommonShaderArg& arg, std::string codeDestAccessor, const bool isTransposed) const
{ {
if (arg.m_type == CommonShaderArgType::CODE_CONST) if (arg.m_type.m_value_type == CommonShaderValueType::CODE_CONST)
{ {
const auto constSourceInfo = m_code_source_infos.GetInfoForCodeConstSource(arg.m_value.code_const_source); auto constSourceInfo = m_code_source_infos.GetInfoForCodeConstSource(arg.m_value.code_const_source.m_index);
if (isTransposed)
{
assert(constSourceInfo);
if (constSourceInfo && constSourceInfo->transposedMatrix)
constSourceInfo = m_code_source_infos.GetInfoForCodeConstSource(*constSourceInfo->transposedMatrix);
}
if (constSourceInfo) if (constSourceInfo)
{ {
if (codeDestAccessor != constSourceInfo->accessor) std::string codeAccessor;
if (constSourceInfo->arrayCount <= 1)
codeAccessor = constSourceInfo->accessor;
else
codeAccessor = std::format("{}[{}]", constSourceInfo->accessor, arg.m_value.code_const_source.m_index - constSourceInfo->value);
if (codeDestAccessor != codeAccessor)
{ {
Indent(); Indent();
m_stream << std::format("{} = constant.{};\n", codeDestAccessor, constSourceInfo->accessor); m_stream << std::format("{} = constant.{};\n", codeDestAccessor, codeAccessor);
} }
else else
{ {
#ifdef TECHSET_DEBUG #ifdef TECHSET_DEBUG
Indent(); Indent();
m_stream << std::format("// Omitted due to matching accessors: {} = constant.{};\n", codeDestAccessor, constSourceInfo->accessor); m_stream << std::format("// Omitted due to matching accessors: {} = constant.{};\n", codeDestAccessor, codeAccessor);
#endif #endif
} }
} }
@@ -309,7 +353,7 @@ namespace
con::error("Technique {}: Could not find code source info for const {}", technique.m_name, codeDestAccessor); con::error("Technique {}: Could not find code source info for const {}", technique.m_name, codeDestAccessor);
} }
} }
else if (arg.m_type == CommonShaderArgType::CODE_SAMPLER) else if (arg.m_type.m_value_type == CommonShaderValueType::CODE_SAMPLER)
{ {
const auto samplerSourceInfo = m_code_source_infos.GetInfoForCodeSamplerSource(arg.m_value.code_sampler_source); const auto samplerSourceInfo = m_code_source_infos.GetInfoForCodeSamplerSource(arg.m_value.code_sampler_source);
if (samplerSourceInfo) if (samplerSourceInfo)
@@ -335,7 +379,7 @@ namespace
con::error("Technique {}: Could not find code source info for sampler {}", technique.m_name, codeDestAccessor); con::error("Technique {}: Could not find code source info for sampler {}", technique.m_name, codeDestAccessor);
} }
} }
else if (arg.m_type == CommonShaderArgType::LITERAL_CONST) else if (arg.m_type.m_value_type == CommonShaderValueType::LITERAL_CONST)
{ {
Indent(); Indent();
m_stream << std::format("{} = float4({}, {}, {}, {});\n", m_stream << std::format("{} = float4({}, {}, {}, {});\n",
@@ -345,7 +389,7 @@ namespace
arg.m_value.literal_value[2], arg.m_value.literal_value[2],
arg.m_value.literal_value[3]); arg.m_value.literal_value[3]);
} }
else if (arg.m_type == CommonShaderArgType::MATERIAL_CONST || arg.m_type == CommonShaderArgType::MATERIAL_SAMPLER) else if (arg.m_type.m_value_type == CommonShaderValueType::MATERIAL_CONST || arg.m_type.m_value_type == CommonShaderValueType::MATERIAL_SAMPLER)
{ {
Indent(); Indent();
@@ -385,6 +429,7 @@ namespace
} }
} }
DxVersion m_dx_version;
const CommonCodeSourceInfos& m_code_source_infos; const CommonCodeSourceInfos& m_code_source_infos;
const CommonStreamRoutingInfos& m_routing_infos; const CommonStreamRoutingInfos& m_routing_infos;
const AbstractMaterialConstantZoneState& m_constant_zone_state; const AbstractMaterialConstantZoneState& m_constant_zone_state;
@@ -395,6 +440,7 @@ namespace techset
{ {
void DumpCommonTechnique(const AssetDumpingContext& context, void DumpCommonTechnique(const AssetDumpingContext& context,
const CommonTechnique& technique, const CommonTechnique& technique,
const DxVersion dxVersion,
const CommonCodeSourceInfos& codeSourceInfos, const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos, const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState) const AbstractMaterialConstantZoneState& constantZoneState)
@@ -402,7 +448,7 @@ namespace techset
const auto techniqueFile = context.OpenAssetFile(GetFileNameForTechniqueName(technique.m_name)); const auto techniqueFile = context.OpenAssetFile(GetFileNameForTechniqueName(technique.m_name));
if (techniqueFile) if (techniqueFile)
{ {
TechniqueFileWriter writer(*techniqueFile, codeSourceInfos, routingInfos, constantZoneState); TechniqueFileWriter writer(*techniqueFile, dxVersion, codeSourceInfos, routingInfos, constantZoneState);
writer.DumpTechnique(technique); writer.DumpTechnique(technique);
} }
} }

View File

@@ -8,6 +8,7 @@ namespace techset
{ {
void DumpCommonTechnique(const AssetDumpingContext& context, void DumpCommonTechnique(const AssetDumpingContext& context,
const CommonTechnique& technique, const CommonTechnique& technique,
DxVersion dxVersion,
const CommonCodeSourceInfos& codeSourceInfos, const CommonCodeSourceInfos& codeSourceInfos,
const CommonStreamRoutingInfos& routingInfos, const CommonStreamRoutingInfos& routingInfos,
const AbstractMaterialConstantZoneState& constantZoneState); const AbstractMaterialConstantZoneState& constantZoneState);