mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Merge pull request #126 from Laupetin/feature/dx11-shader-parsing
feat: use parameter names from dx11 shaders to resolve material hashes
This commit is contained in:
commit
99632f5d98
685
src/ObjCommon/Shader/D3D11ShaderAnalyser.cpp
Normal file
685
src/ObjCommon/Shader/D3D11ShaderAnalyser.cpp
Normal file
@ -0,0 +1,685 @@
|
||||
#include "D3D11ShaderAnalyser.h"
|
||||
|
||||
#include "Utils/FileUtils.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace d3d11;
|
||||
|
||||
namespace d3d11
|
||||
{
|
||||
BoundResource::BoundResource()
|
||||
: m_type(BoundResourceType::UNKNOWN),
|
||||
m_return_type(BoundResourceReturnType::UNKNOWN),
|
||||
m_dimension(BoundResourceDimension::UNKNOWN),
|
||||
m_num_samples(0u),
|
||||
m_bind_point(0u),
|
||||
m_bind_count(0u),
|
||||
m_flags(0u)
|
||||
{
|
||||
}
|
||||
|
||||
ConstantBuffer::ConstantBuffer()
|
||||
: m_size(0u),
|
||||
m_flags(0u),
|
||||
m_type(ConstantBufferType::UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
ConstantBufferVariable::ConstantBufferVariable()
|
||||
: m_offset(0u),
|
||||
m_size(0u),
|
||||
m_flags(0u)
|
||||
{
|
||||
}
|
||||
|
||||
static constexpr auto TAG_RDEF = FileUtils::MakeMagic32('R', 'D', 'E', 'F');
|
||||
static constexpr auto TAG_SHDR = FileUtils::MakeMagic32('S', 'H', 'D', 'R');
|
||||
|
||||
static constexpr auto VERSION_5_0 = 0x500;
|
||||
static constexpr auto VERSION_5_1 = 0x501;
|
||||
static constexpr auto TARGET_VERSION_MASK = 0xFFFF;
|
||||
static constexpr auto CHUNK_TABLE_OFFSET = 28u;
|
||||
|
||||
struct FileRdefHeader
|
||||
{
|
||||
uint32_t constantBufferCount;
|
||||
uint32_t constantBufferOffset;
|
||||
uint32_t boundResourceCount;
|
||||
uint32_t boundResourceOffset;
|
||||
uint32_t target;
|
||||
uint32_t flags;
|
||||
uint32_t creatorOffset;
|
||||
};
|
||||
|
||||
struct FileRdefExtraHeader_5_0
|
||||
{
|
||||
// Wine project does not seem to know what this is
|
||||
uint32_t unknown[8];
|
||||
};
|
||||
|
||||
static_assert(sizeof(FileRdefHeader) == 28);
|
||||
static_assert(sizeof(FileRdefExtraHeader_5_0) == 32);
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_shader_input_type
|
||||
enum D3D_SHADER_INPUT_TYPE : uint32_t
|
||||
{
|
||||
D3D_SIT_CBUFFER = 0,
|
||||
D3D_SIT_TBUFFER,
|
||||
D3D_SIT_TEXTURE,
|
||||
D3D_SIT_SAMPLER,
|
||||
D3D_SIT_UAV_RWTYPED,
|
||||
D3D_SIT_STRUCTURED,
|
||||
D3D_SIT_UAV_RWSTRUCTURED,
|
||||
D3D_SIT_BYTEADDRESS,
|
||||
D3D_SIT_UAV_RWBYTEADDRESS,
|
||||
D3D_SIT_UAV_APPEND_STRUCTURED,
|
||||
D3D_SIT_UAV_CONSUME_STRUCTURED,
|
||||
D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER,
|
||||
D3D_SIT_RTACCELERATIONSTRUCTURE,
|
||||
D3D_SIT_UAV_FEEDBACKTEXTURE,
|
||||
D3D10_SIT_CBUFFER,
|
||||
D3D10_SIT_TBUFFER,
|
||||
D3D10_SIT_TEXTURE,
|
||||
D3D10_SIT_SAMPLER,
|
||||
D3D11_SIT_UAV_RWTYPED,
|
||||
D3D11_SIT_STRUCTURED,
|
||||
D3D11_SIT_UAV_RWSTRUCTURED,
|
||||
D3D11_SIT_BYTEADDRESS,
|
||||
D3D11_SIT_UAV_RWBYTEADDRESS,
|
||||
D3D11_SIT_UAV_APPEND_STRUCTURED,
|
||||
D3D11_SIT_UAV_CONSUME_STRUCTURED,
|
||||
D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_resource_return_type
|
||||
enum D3D_RESOURCE_RETURN_TYPE : uint32_t
|
||||
{
|
||||
D3D_RETURN_TYPE_UNORM = 1,
|
||||
D3D_RETURN_TYPE_SNORM = 2,
|
||||
D3D_RETURN_TYPE_SINT = 3,
|
||||
D3D_RETURN_TYPE_UINT = 4,
|
||||
D3D_RETURN_TYPE_FLOAT = 5,
|
||||
D3D_RETURN_TYPE_MIXED = 6,
|
||||
D3D_RETURN_TYPE_DOUBLE = 7,
|
||||
D3D_RETURN_TYPE_CONTINUED = 8,
|
||||
D3D10_RETURN_TYPE_UNORM,
|
||||
D3D10_RETURN_TYPE_SNORM,
|
||||
D3D10_RETURN_TYPE_SINT,
|
||||
D3D10_RETURN_TYPE_UINT,
|
||||
D3D10_RETURN_TYPE_FLOAT,
|
||||
D3D10_RETURN_TYPE_MIXED,
|
||||
D3D11_RETURN_TYPE_UNORM,
|
||||
D3D11_RETURN_TYPE_SNORM,
|
||||
D3D11_RETURN_TYPE_SINT,
|
||||
D3D11_RETURN_TYPE_UINT,
|
||||
D3D11_RETURN_TYPE_FLOAT,
|
||||
D3D11_RETURN_TYPE_MIXED,
|
||||
D3D11_RETURN_TYPE_DOUBLE,
|
||||
D3D11_RETURN_TYPE_CONTINUED
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_srv_dimension
|
||||
enum D3D_SRV_DIMENSION : uint32_t
|
||||
{
|
||||
D3D_SRV_DIMENSION_UNKNOWN = 0,
|
||||
D3D_SRV_DIMENSION_BUFFER = 1,
|
||||
D3D_SRV_DIMENSION_TEXTURE1D = 2,
|
||||
D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3,
|
||||
D3D_SRV_DIMENSION_TEXTURE2D = 4,
|
||||
D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5,
|
||||
D3D_SRV_DIMENSION_TEXTURE2DMS = 6,
|
||||
D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7,
|
||||
D3D_SRV_DIMENSION_TEXTURE3D = 8,
|
||||
D3D_SRV_DIMENSION_TEXTURECUBE = 9,
|
||||
D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10,
|
||||
D3D_SRV_DIMENSION_BUFFEREX = 11,
|
||||
D3D10_SRV_DIMENSION_UNKNOWN,
|
||||
D3D10_SRV_DIMENSION_BUFFER,
|
||||
D3D10_SRV_DIMENSION_TEXTURE1D,
|
||||
D3D10_SRV_DIMENSION_TEXTURE1DARRAY,
|
||||
D3D10_SRV_DIMENSION_TEXTURE2D,
|
||||
D3D10_SRV_DIMENSION_TEXTURE2DARRAY,
|
||||
D3D10_SRV_DIMENSION_TEXTURE2DMS,
|
||||
D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY,
|
||||
D3D10_SRV_DIMENSION_TEXTURE3D,
|
||||
D3D10_SRV_DIMENSION_TEXTURECUBE,
|
||||
D3D10_1_SRV_DIMENSION_UNKNOWN,
|
||||
D3D10_1_SRV_DIMENSION_BUFFER,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE1D,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE2D,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE2DMS,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURE3D,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURECUBE,
|
||||
D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY,
|
||||
D3D11_SRV_DIMENSION_UNKNOWN,
|
||||
D3D11_SRV_DIMENSION_BUFFER,
|
||||
D3D11_SRV_DIMENSION_TEXTURE1D,
|
||||
D3D11_SRV_DIMENSION_TEXTURE1DARRAY,
|
||||
D3D11_SRV_DIMENSION_TEXTURE2D,
|
||||
D3D11_SRV_DIMENSION_TEXTURE2DARRAY,
|
||||
D3D11_SRV_DIMENSION_TEXTURE2DMS,
|
||||
D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY,
|
||||
D3D11_SRV_DIMENSION_TEXTURE3D,
|
||||
D3D11_SRV_DIMENSION_TEXTURECUBE,
|
||||
D3D11_SRV_DIMENSION_TEXTURECUBEARRAY,
|
||||
D3D11_SRV_DIMENSION_BUFFEREX
|
||||
};
|
||||
|
||||
struct FileBoundResource
|
||||
{
|
||||
uint32_t nameOffset;
|
||||
D3D_SHADER_INPUT_TYPE type;
|
||||
D3D_RESOURCE_RETURN_TYPE returnType;
|
||||
D3D_SRV_DIMENSION dimension;
|
||||
uint32_t numSamples;
|
||||
uint32_t bindPoint;
|
||||
uint32_t bindCount;
|
||||
uint32_t uFlags;
|
||||
};
|
||||
|
||||
struct FileBoundResource_5_1 : FileBoundResource
|
||||
{
|
||||
uint32_t space;
|
||||
uint32_t uID;
|
||||
};
|
||||
|
||||
static_assert(sizeof(FileBoundResource) == 32);
|
||||
static_assert(sizeof(FileBoundResource_5_1) == 40);
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_cbuffer_type
|
||||
enum D3D_CBUFFER_TYPE : uint32_t
|
||||
{
|
||||
D3D_CT_CBUFFER = 0,
|
||||
D3D_CT_TBUFFER,
|
||||
D3D_CT_INTERFACE_POINTERS,
|
||||
D3D_CT_RESOURCE_BIND_INFO,
|
||||
D3D10_CT_CBUFFER,
|
||||
D3D10_CT_TBUFFER,
|
||||
D3D11_CT_CBUFFER,
|
||||
D3D11_CT_TBUFFER,
|
||||
D3D11_CT_INTERFACE_POINTERS,
|
||||
D3D11_CT_RESOURCE_BIND_INFO
|
||||
};
|
||||
|
||||
struct FileConstantBuffer
|
||||
{
|
||||
uint32_t nameOffset;
|
||||
uint32_t variableCount;
|
||||
uint32_t variableOffset;
|
||||
uint32_t size;
|
||||
uint32_t flags;
|
||||
D3D_CBUFFER_TYPE type;
|
||||
};
|
||||
|
||||
struct FileConstantBufferVariable
|
||||
{
|
||||
uint32_t nameOffset;
|
||||
uint32_t startOffset;
|
||||
uint32_t size;
|
||||
uint32_t flags;
|
||||
uint32_t typeOffset;
|
||||
uint32_t defaultValueOffset;
|
||||
};
|
||||
|
||||
struct FileConstantBufferVariable_5_0 : FileConstantBufferVariable
|
||||
{
|
||||
// Wine project does not seem to know what this is
|
||||
uint32_t unknown[4];
|
||||
};
|
||||
|
||||
static_assert(sizeof(FileConstantBufferVariable) == 24);
|
||||
static_assert(sizeof(FileConstantBufferVariable_5_0) == 40);
|
||||
|
||||
enum FileProgramType : uint32_t
|
||||
{
|
||||
D3D10_SB_PIXEL_SHADER = 0,
|
||||
D3D10_SB_VERTEX_SHADER = 1,
|
||||
D3D10_SB_GEOMETRY_SHADER = 2,
|
||||
|
||||
// D3D11 Shaders
|
||||
D3D11_SB_HULL_SHADER = 3,
|
||||
D3D11_SB_DOMAIN_SHADER = 4,
|
||||
D3D11_SB_COMPUTE_SHADER = 5,
|
||||
|
||||
D3D11_SB_RESERVED0 = 0xFFF0
|
||||
};
|
||||
|
||||
struct FileShaderHeader
|
||||
{
|
||||
uint32_t versionMinor : 4;
|
||||
uint32_t versionMajor : 4;
|
||||
uint32_t unused : 8;
|
||||
FileProgramType programType : 16;
|
||||
};
|
||||
|
||||
static_assert(sizeof(FileShaderHeader) == 4);
|
||||
|
||||
uint32_t ReadU32(const uint8_t*& ptr)
|
||||
{
|
||||
const auto result = *reinterpret_cast<const uint32_t*>(ptr);
|
||||
ptr += sizeof(uint32_t);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FindChunk(const uint32_t magic, const uint8_t* byteCode, const size_t byteCodeSize, size_t& chunkOffset, size_t& chunkSize)
|
||||
{
|
||||
if (byteCodeSize < CHUNK_TABLE_OFFSET + sizeof(uint32_t))
|
||||
return false;
|
||||
|
||||
const auto* ptr = byteCode + CHUNK_TABLE_OFFSET;
|
||||
const auto chunkCount = ReadU32(ptr);
|
||||
if (byteCodeSize < (ptr - byteCode) + chunkCount * sizeof(uint32_t))
|
||||
return false;
|
||||
|
||||
for (auto chunkIndex = 0u; chunkIndex < chunkCount; chunkIndex++)
|
||||
{
|
||||
const auto currentChunkOffset = ReadU32(ptr);
|
||||
if (byteCodeSize < currentChunkOffset + sizeof(uint32_t) * 2)
|
||||
return false;
|
||||
|
||||
const auto currentChunkTag = *reinterpret_cast<const uint32_t*>(byteCode + currentChunkOffset + 0);
|
||||
const auto currentChunkSize = *reinterpret_cast<const uint32_t*>(byteCode + currentChunkOffset + 4);
|
||||
|
||||
if (byteCodeSize < currentChunkOffset + sizeof(uint32_t) * 2 + currentChunkSize)
|
||||
return false;
|
||||
|
||||
if (currentChunkTag == magic)
|
||||
{
|
||||
chunkOffset = currentChunkOffset + 8;
|
||||
chunkSize = currentChunkSize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StringFitsInChunk(const char* str, const uint8_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
const auto strLen = strnlen(str, shaderByteCodeSize - (reinterpret_cast<const uint8_t*>(str) - shaderByteCode));
|
||||
return str[strLen] == '\0';
|
||||
}
|
||||
|
||||
BoundResourceType GetType(const D3D_SHADER_INPUT_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case D3D_SIT_CBUFFER:
|
||||
case D3D10_SIT_CBUFFER:
|
||||
return BoundResourceType::CBUFFER;
|
||||
case D3D_SIT_TBUFFER:
|
||||
case D3D10_SIT_TBUFFER:
|
||||
return BoundResourceType::TBUFFER;
|
||||
case D3D_SIT_TEXTURE:
|
||||
case D3D10_SIT_TEXTURE:
|
||||
return BoundResourceType::TEXTURE;
|
||||
case D3D_SIT_SAMPLER:
|
||||
case D3D10_SIT_SAMPLER:
|
||||
return BoundResourceType::SAMPLER;
|
||||
default:
|
||||
return BoundResourceType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
BoundResourceReturnType GetReturnType(const D3D_RESOURCE_RETURN_TYPE returnType)
|
||||
{
|
||||
switch (returnType)
|
||||
{
|
||||
case D3D_RETURN_TYPE_UNORM:
|
||||
case D3D10_RETURN_TYPE_UNORM:
|
||||
case D3D11_RETURN_TYPE_UNORM:
|
||||
return BoundResourceReturnType::UNORM;
|
||||
case D3D_RETURN_TYPE_SNORM:
|
||||
case D3D10_RETURN_TYPE_SNORM:
|
||||
case D3D11_RETURN_TYPE_SNORM:
|
||||
return BoundResourceReturnType::SNORM;
|
||||
case D3D_RETURN_TYPE_SINT:
|
||||
case D3D10_RETURN_TYPE_SINT:
|
||||
case D3D11_RETURN_TYPE_SINT:
|
||||
return BoundResourceReturnType::SINT;
|
||||
case D3D_RETURN_TYPE_UINT:
|
||||
case D3D10_RETURN_TYPE_UINT:
|
||||
case D3D11_RETURN_TYPE_UINT:
|
||||
return BoundResourceReturnType::UINT;
|
||||
case D3D_RETURN_TYPE_FLOAT:
|
||||
case D3D10_RETURN_TYPE_FLOAT:
|
||||
case D3D11_RETURN_TYPE_FLOAT:
|
||||
return BoundResourceReturnType::FLOAT;
|
||||
case D3D_RETURN_TYPE_MIXED:
|
||||
case D3D10_RETURN_TYPE_MIXED:
|
||||
case D3D11_RETURN_TYPE_MIXED:
|
||||
return BoundResourceReturnType::MIXED;
|
||||
case D3D_RETURN_TYPE_DOUBLE:
|
||||
case D3D11_RETURN_TYPE_DOUBLE:
|
||||
return BoundResourceReturnType::DOUBLE;
|
||||
case D3D_RETURN_TYPE_CONTINUED:
|
||||
case D3D11_RETURN_TYPE_CONTINUED:
|
||||
return BoundResourceReturnType::CONTINUED;
|
||||
default:
|
||||
return BoundResourceReturnType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
BoundResourceDimension GetDimension(const D3D_SRV_DIMENSION dimension)
|
||||
{
|
||||
switch (dimension)
|
||||
{
|
||||
case D3D_SRV_DIMENSION_BUFFER:
|
||||
case D3D10_SRV_DIMENSION_BUFFER:
|
||||
case D3D10_1_SRV_DIMENSION_BUFFER:
|
||||
case D3D11_SRV_DIMENSION_BUFFER:
|
||||
return BoundResourceDimension::BUFFER;
|
||||
case D3D_SRV_DIMENSION_TEXTURE1D:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE1D:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE1D:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE1D:
|
||||
return BoundResourceDimension::TEXTURE_1D;
|
||||
case D3D_SRV_DIMENSION_TEXTURE1DARRAY:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE1DARRAY:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
|
||||
return BoundResourceDimension::TEXTURE_1D_ARRAY;
|
||||
case D3D_SRV_DIMENSION_TEXTURE2D:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE2D:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE2D:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2D:
|
||||
return BoundResourceDimension::TEXTURE_2D;
|
||||
case D3D_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
return BoundResourceDimension::TEXTURE_2D_ARRAY;
|
||||
case D3D_SRV_DIMENSION_TEXTURE2DMS:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE2DMS:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE2DMS:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DMS:
|
||||
return BoundResourceDimension::TEXTURE_2D_MS;
|
||||
case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
return BoundResourceDimension::TEXTURE_2D_MS_ARRAY;
|
||||
case D3D_SRV_DIMENSION_TEXTURE3D:
|
||||
case D3D10_SRV_DIMENSION_TEXTURE3D:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURE3D:
|
||||
case D3D11_SRV_DIMENSION_TEXTURE3D:
|
||||
return BoundResourceDimension::TEXTURE_3D;
|
||||
case D3D_SRV_DIMENSION_TEXTURECUBE:
|
||||
case D3D10_SRV_DIMENSION_TEXTURECUBE:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURECUBE:
|
||||
case D3D11_SRV_DIMENSION_TEXTURECUBE:
|
||||
return BoundResourceDimension::TEXTURE_CUBE;
|
||||
case D3D_SRV_DIMENSION_TEXTURECUBEARRAY:
|
||||
case D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY:
|
||||
case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
|
||||
return BoundResourceDimension::TEXTURE_CUBE_ARRAY;
|
||||
case D3D_SRV_DIMENSION_BUFFEREX:
|
||||
case D3D11_SRV_DIMENSION_BUFFEREX:
|
||||
return BoundResourceDimension::BUFFER_EX;
|
||||
default:
|
||||
return BoundResourceDimension::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool PopulateBoundResource(BoundResource& boundResource,
|
||||
const FileBoundResource& fileBoundResource,
|
||||
const uint8_t* shaderByteCode,
|
||||
const size_t shaderByteCodeSize,
|
||||
const size_t chunkOffset)
|
||||
{
|
||||
const auto nameString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + fileBoundResource.nameOffset);
|
||||
|
||||
if (!StringFitsInChunk(nameString, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
boundResource.m_name = std::string(nameString);
|
||||
boundResource.m_type = GetType(fileBoundResource.type);
|
||||
boundResource.m_return_type = GetReturnType(fileBoundResource.returnType);
|
||||
boundResource.m_dimension = GetDimension(fileBoundResource.dimension);
|
||||
boundResource.m_num_samples = fileBoundResource.numSamples;
|
||||
boundResource.m_bind_point = fileBoundResource.bindPoint;
|
||||
boundResource.m_bind_count = fileBoundResource.bindCount;
|
||||
boundResource.m_flags = fileBoundResource.uFlags;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateConstantBufferVariable(ConstantBufferVariable& constantBufferVariable,
|
||||
const FileConstantBufferVariable& fileConstantBufferVariable,
|
||||
const uint8_t* shaderByteCode,
|
||||
const size_t shaderByteCodeSize,
|
||||
const size_t chunkOffset,
|
||||
const size_t chunkSize)
|
||||
{
|
||||
const auto nameString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + fileConstantBufferVariable.nameOffset);
|
||||
|
||||
if (!StringFitsInChunk(nameString, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
constantBufferVariable.m_name = std::string(nameString);
|
||||
constantBufferVariable.m_offset = fileConstantBufferVariable.startOffset;
|
||||
constantBufferVariable.m_size = fileConstantBufferVariable.size;
|
||||
constantBufferVariable.m_flags = fileConstantBufferVariable.flags;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ConstantBufferType GetType(const D3D_CBUFFER_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case D3D_CT_CBUFFER:
|
||||
case D3D10_CT_CBUFFER:
|
||||
case D3D11_CT_CBUFFER:
|
||||
return ConstantBufferType::CBUFFER;
|
||||
case D3D_CT_TBUFFER:
|
||||
case D3D10_CT_TBUFFER:
|
||||
case D3D11_CT_TBUFFER:
|
||||
return ConstantBufferType::TBUFFER;
|
||||
case D3D_CT_INTERFACE_POINTERS:
|
||||
case D3D11_CT_INTERFACE_POINTERS:
|
||||
return ConstantBufferType::INTERFACE_POINTERS;
|
||||
case D3D_CT_RESOURCE_BIND_INFO:
|
||||
case D3D11_CT_RESOURCE_BIND_INFO:
|
||||
return ConstantBufferType::RESOURCE_BIND_INFO;
|
||||
default:
|
||||
return ConstantBufferType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool PopulateConstantBuffer(ConstantBuffer& constantBuffer,
|
||||
const FileConstantBuffer& fileConstantBuffer,
|
||||
const uint8_t* shaderByteCode,
|
||||
const size_t shaderByteCodeSize,
|
||||
const size_t chunkOffset,
|
||||
const size_t chunkSize,
|
||||
const unsigned targetVersion)
|
||||
{
|
||||
const auto nameString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + fileConstantBuffer.nameOffset);
|
||||
|
||||
if (!StringFitsInChunk(nameString, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
constantBuffer.m_name = std::string(nameString);
|
||||
|
||||
constantBuffer.m_size = fileConstantBuffer.size;
|
||||
constantBuffer.m_flags = fileConstantBuffer.flags;
|
||||
constantBuffer.m_type = GetType(fileConstantBuffer.type);
|
||||
|
||||
if (targetVersion < VERSION_5_0)
|
||||
{
|
||||
const auto* variables = reinterpret_cast<const FileConstantBufferVariable*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
||||
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable) * fileConstantBuffer.variableCount > chunkSize)
|
||||
return false;
|
||||
|
||||
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
||||
{
|
||||
const auto& fileVariable = variables[variableIndex];
|
||||
ConstantBufferVariable variable;
|
||||
|
||||
if (!PopulateConstantBufferVariable(variable, fileVariable, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize))
|
||||
return false;
|
||||
|
||||
constantBuffer.m_variables.emplace_back(std::move(variable));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto* variables = reinterpret_cast<const FileConstantBufferVariable_5_0*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
||||
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable_5_0) * fileConstantBuffer.variableCount > chunkSize)
|
||||
return false;
|
||||
|
||||
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
||||
{
|
||||
const auto& fileVariable = variables[variableIndex];
|
||||
ConstantBufferVariable variable;
|
||||
|
||||
if (!PopulateConstantBufferVariable(variable, fileVariable, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize))
|
||||
return false;
|
||||
|
||||
constantBuffer.m_variables.emplace_back(std::move(variable));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateShaderInfoFromRdef(ShaderInfo& shaderInfo, const uint8_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
size_t chunkOffset, chunkSize;
|
||||
if (!FindChunk(TAG_RDEF, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize))
|
||||
return false;
|
||||
|
||||
if (sizeof(FileRdefHeader) > chunkSize)
|
||||
return false;
|
||||
|
||||
const auto* header = reinterpret_cast<const FileRdefHeader*>(shaderByteCode + chunkOffset);
|
||||
|
||||
const auto targetVersion = header->target & TARGET_VERSION_MASK;
|
||||
const auto creatorString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + header->creatorOffset);
|
||||
|
||||
if (!StringFitsInChunk(creatorString, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
shaderInfo.m_creator = std::string(creatorString);
|
||||
|
||||
if (targetVersion < VERSION_5_1)
|
||||
{
|
||||
const auto* boundResources = reinterpret_cast<const FileBoundResource*>(shaderByteCode + chunkOffset + header->boundResourceOffset);
|
||||
if (header->boundResourceOffset + sizeof(FileBoundResource) * header->boundResourceCount > chunkSize)
|
||||
return false;
|
||||
|
||||
for (auto boundResourceIndex = 0u; boundResourceIndex < header->boundResourceCount; boundResourceIndex++)
|
||||
{
|
||||
const auto& fileBoundResource = boundResources[boundResourceIndex];
|
||||
BoundResource boundResource;
|
||||
|
||||
PopulateBoundResource(boundResource, fileBoundResource, shaderByteCode, shaderByteCodeSize, chunkOffset);
|
||||
|
||||
shaderInfo.m_bound_resources.emplace_back(std::move(boundResource));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto* boundResources = reinterpret_cast<const FileBoundResource_5_1*>(shaderByteCode + chunkOffset + header->boundResourceOffset);
|
||||
if (header->boundResourceOffset + sizeof(FileBoundResource_5_1) * header->boundResourceCount > chunkSize)
|
||||
return false;
|
||||
|
||||
for (auto boundResourceIndex = 0u; boundResourceIndex < header->boundResourceCount; boundResourceIndex++)
|
||||
{
|
||||
const auto& fileBoundResource = boundResources[boundResourceIndex];
|
||||
BoundResource boundResource;
|
||||
|
||||
if (!PopulateBoundResource(boundResource, fileBoundResource, shaderByteCode, shaderByteCodeSize, chunkOffset))
|
||||
return false;
|
||||
|
||||
shaderInfo.m_bound_resources.emplace_back(std::move(boundResource));
|
||||
}
|
||||
}
|
||||
|
||||
const auto* constantBuffers = reinterpret_cast<const FileConstantBuffer*>(shaderByteCode + chunkOffset + header->constantBufferOffset);
|
||||
if (header->constantBufferOffset + sizeof(FileConstantBuffer) * header->constantBufferCount > chunkSize)
|
||||
return false;
|
||||
|
||||
for (auto constantBufferIndex = 0u; constantBufferIndex < header->constantBufferCount; constantBufferIndex++)
|
||||
{
|
||||
const auto& fileConstantBuffer = constantBuffers[constantBufferIndex];
|
||||
ConstantBuffer constantBuffer;
|
||||
|
||||
if (!PopulateConstantBuffer(constantBuffer, fileConstantBuffer, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize, targetVersion))
|
||||
return false;
|
||||
|
||||
shaderInfo.m_constant_buffers.emplace_back(std::move(constantBuffer));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ShaderType GetShaderType(const FileProgramType programType)
|
||||
{
|
||||
switch (programType)
|
||||
{
|
||||
case D3D10_SB_PIXEL_SHADER:
|
||||
return ShaderType::PIXEL_SHADER;
|
||||
case D3D10_SB_VERTEX_SHADER:
|
||||
return ShaderType::VERTEX_SHADER;
|
||||
case D3D10_SB_GEOMETRY_SHADER:
|
||||
return ShaderType::GEOMETRY_SHADER;
|
||||
case D3D11_SB_HULL_SHADER:
|
||||
return ShaderType::HULL_SHADER;
|
||||
case D3D11_SB_DOMAIN_SHADER:
|
||||
return ShaderType::DOMAIN_SHADER;
|
||||
case D3D11_SB_COMPUTE_SHADER:
|
||||
return ShaderType::COMPUTE_SHADER;
|
||||
default:
|
||||
return ShaderType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool PopulateShaderInfoFromShdr(ShaderInfo& shaderInfo, const uint8_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
size_t chunkOffset, chunkSize;
|
||||
if (!FindChunk(TAG_SHDR, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize))
|
||||
return false;
|
||||
|
||||
if (sizeof(FileShaderHeader) > chunkSize)
|
||||
return false;
|
||||
|
||||
const auto* header = reinterpret_cast<const FileShaderHeader*>(shaderByteCode + chunkOffset);
|
||||
|
||||
shaderInfo.m_version_major = header->versionMajor;
|
||||
shaderInfo.m_version_minor = header->versionMinor;
|
||||
|
||||
shaderInfo.m_type = GetShaderType(header->programType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateShaderInfoFromBytes(ShaderInfo& shaderInfo, const uint8_t* shaderByteCode, const size_t shaderByteCodeSize)
|
||||
{
|
||||
if (!PopulateShaderInfoFromRdef(shaderInfo, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
if (!PopulateShaderInfoFromShdr(shaderInfo, shaderByteCode, shaderByteCodeSize))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace d3d11
|
||||
|
||||
std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const uint8_t* shader, const size_t shaderSize)
|
||||
{
|
||||
if (shader == nullptr || shaderSize == 0)
|
||||
return nullptr;
|
||||
|
||||
auto shaderInfo = std::make_unique<ShaderInfo>();
|
||||
|
||||
if (!PopulateShaderInfoFromBytes(*shaderInfo, shader, shaderSize))
|
||||
return nullptr;
|
||||
|
||||
return shaderInfo;
|
||||
}
|
136
src/ObjCommon/Shader/D3D11ShaderAnalyser.h
Normal file
136
src/ObjCommon/Shader/D3D11ShaderAnalyser.h
Normal file
@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace d3d11
|
||||
{
|
||||
enum class ShaderType
|
||||
{
|
||||
UNKNOWN,
|
||||
PIXEL_SHADER,
|
||||
VERTEX_SHADER,
|
||||
GEOMETRY_SHADER,
|
||||
HULL_SHADER,
|
||||
DOMAIN_SHADER,
|
||||
COMPUTE_SHADER
|
||||
};
|
||||
|
||||
class ConstantBufferVariable
|
||||
{
|
||||
public:
|
||||
ConstantBufferVariable();
|
||||
~ConstantBufferVariable() = default;
|
||||
ConstantBufferVariable(const ConstantBufferVariable& other) = default;
|
||||
ConstantBufferVariable(ConstantBufferVariable&& other) noexcept = default;
|
||||
ConstantBufferVariable& operator=(const ConstantBufferVariable& other) = default;
|
||||
ConstantBufferVariable& operator=(ConstantBufferVariable&& other) noexcept = default;
|
||||
|
||||
std::string m_name;
|
||||
unsigned m_offset;
|
||||
unsigned m_size;
|
||||
unsigned m_flags;
|
||||
};
|
||||
|
||||
enum class ConstantBufferType
|
||||
{
|
||||
UNKNOWN,
|
||||
CBUFFER,
|
||||
TBUFFER,
|
||||
INTERFACE_POINTERS,
|
||||
RESOURCE_BIND_INFO,
|
||||
};
|
||||
|
||||
class ConstantBuffer
|
||||
{
|
||||
public:
|
||||
ConstantBuffer();
|
||||
~ConstantBuffer() = default;
|
||||
ConstantBuffer(const ConstantBuffer& other) = default;
|
||||
ConstantBuffer(ConstantBuffer&& other) noexcept = default;
|
||||
ConstantBuffer& operator=(const ConstantBuffer& other) = default;
|
||||
ConstantBuffer& operator=(ConstantBuffer&& other) noexcept = default;
|
||||
|
||||
std::string m_name;
|
||||
unsigned m_size;
|
||||
unsigned m_flags;
|
||||
ConstantBufferType m_type;
|
||||
std::vector<ConstantBufferVariable> m_variables;
|
||||
};
|
||||
|
||||
enum class BoundResourceType
|
||||
{
|
||||
UNKNOWN,
|
||||
CBUFFER,
|
||||
TBUFFER,
|
||||
TEXTURE,
|
||||
SAMPLER
|
||||
};
|
||||
|
||||
enum class BoundResourceReturnType
|
||||
{
|
||||
UNKNOWN,
|
||||
UNORM,
|
||||
SNORM,
|
||||
SINT,
|
||||
UINT,
|
||||
FLOAT,
|
||||
MIXED,
|
||||
DOUBLE,
|
||||
CONTINUED,
|
||||
};
|
||||
|
||||
enum class BoundResourceDimension
|
||||
{
|
||||
UNKNOWN,
|
||||
BUFFER,
|
||||
TEXTURE_1D,
|
||||
TEXTURE_1D_ARRAY,
|
||||
TEXTURE_2D,
|
||||
TEXTURE_2D_ARRAY,
|
||||
TEXTURE_2D_MS,
|
||||
TEXTURE_2D_MS_ARRAY,
|
||||
TEXTURE_3D,
|
||||
TEXTURE_CUBE,
|
||||
TEXTURE_CUBE_ARRAY,
|
||||
BUFFER_EX,
|
||||
};
|
||||
|
||||
class BoundResource
|
||||
{
|
||||
public:
|
||||
BoundResource();
|
||||
~BoundResource() = default;
|
||||
BoundResource(const BoundResource& other) = default;
|
||||
BoundResource(BoundResource&& other) noexcept = default;
|
||||
BoundResource& operator=(const BoundResource& other) = default;
|
||||
BoundResource& operator=(BoundResource&& other) noexcept = default;
|
||||
|
||||
std::string m_name;
|
||||
BoundResourceType m_type;
|
||||
BoundResourceReturnType m_return_type;
|
||||
BoundResourceDimension m_dimension;
|
||||
unsigned m_num_samples;
|
||||
unsigned m_bind_point;
|
||||
unsigned m_bind_count;
|
||||
unsigned m_flags;
|
||||
};
|
||||
|
||||
class ShaderInfo
|
||||
{
|
||||
public:
|
||||
ShaderType m_type = ShaderType::UNKNOWN;
|
||||
unsigned m_version_major = 0;
|
||||
unsigned m_version_minor = 0;
|
||||
std::string m_creator;
|
||||
std::vector<ConstantBuffer> m_constant_buffers;
|
||||
std::vector<BoundResource> m_bound_resources;
|
||||
};
|
||||
|
||||
class ShaderAnalyser
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<ShaderInfo> GetShaderInfo(const uint8_t* shader, size_t shaderSize);
|
||||
};
|
||||
} // namespace d3d11
|
@ -1,12 +1,17 @@
|
||||
#include "AssetDumperMaterial.h"
|
||||
|
||||
#include "Game/T6/CommonT6.h"
|
||||
#include "Game/T6/GameAssetPoolT6.h"
|
||||
#include "Game/T6/GameT6.h"
|
||||
#include "Game/T6/MaterialConstantsT6.h"
|
||||
#include "Game/T6/TechsetConstantsT6.h"
|
||||
#include "ObjWriting.h"
|
||||
#include "Shader/D3D11ShaderAnalyser.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace T6;
|
||||
using namespace nlohmann;
|
||||
@ -18,17 +23,647 @@ namespace T6::material
|
||||
Common::R_HashString(strValue, 0), strValue \
|
||||
}
|
||||
|
||||
std::unordered_map<unsigned, std::string> knownHashes{
|
||||
KNOWN_HASH("colorMap"),
|
||||
KNOWN_HASH("normalMap"),
|
||||
KNOWN_HASH("specularMap"),
|
||||
static constexpr const char* SAMPLER_STR = "Sampler";
|
||||
static constexpr const char* GLOBALS_CBUFFER_NAME = "$Globals";
|
||||
static constexpr const char* PER_OBJECT_CONSTS_CBUFFER_NAME = "PerObjectConsts";
|
||||
|
||||
const char* KNOWN_CONSTANT_NAMES[]{
|
||||
"AngularVelocityScale",
|
||||
"AnimSpeed",
|
||||
"Background",
|
||||
"BackgroundColor",
|
||||
"BackgroundNoise",
|
||||
"BakedLightingIntensity",
|
||||
"BloodBrightness",
|
||||
"BloodIntensity",
|
||||
"BlurAmount",
|
||||
"CapWidth",
|
||||
"Char_Size",
|
||||
"Char_Width",
|
||||
"Coarseness",
|
||||
"Color",
|
||||
"ColorAmount",
|
||||
"ColorBias",
|
||||
"Color_Map_Noise",
|
||||
"Color_Map_Scale",
|
||||
"Color_Map_Size_Scale",
|
||||
"DDXScale",
|
||||
"DDYScale",
|
||||
"DarkenAmount",
|
||||
"DarkenPower",
|
||||
"Detail_Amount",
|
||||
"Detail_Normal_Tile",
|
||||
"Diffuse_Normal_Height_Facing",
|
||||
"Dimensions",
|
||||
"DispersionAmount",
|
||||
"Dolly",
|
||||
"EdgeColor",
|
||||
"EdgeHarshness",
|
||||
"EdgeIntensity",
|
||||
"EdgeMaxDist",
|
||||
"EdgeMinDist",
|
||||
"EdgeSize",
|
||||
"Edge_Color_Multiplier",
|
||||
"Emissive_Amount",
|
||||
"EnemiesColor",
|
||||
"Exposure",
|
||||
"FPS",
|
||||
"Fade_Distance",
|
||||
"Fill_Direction",
|
||||
"Fill_Direction2",
|
||||
"FirstFrame",
|
||||
"FlareIntensity",
|
||||
"FlareScale",
|
||||
"FlattenEdges",
|
||||
"Flicker_Max",
|
||||
"Flicker_Min",
|
||||
"Flicker_Seed",
|
||||
"Flicker_Speed",
|
||||
"Font_Color",
|
||||
"Gamma",
|
||||
"GlossAmount",
|
||||
"Gloss_Amount",
|
||||
"Glow_Alt_Color",
|
||||
"Glow_Color",
|
||||
"Glow_Falloff",
|
||||
"GradientColor",
|
||||
"GradientMax",
|
||||
"GradientMin",
|
||||
"Grain_Amount",
|
||||
"Grain_Color",
|
||||
"Grid",
|
||||
"Hardness",
|
||||
"Heart_Rate_Offset",
|
||||
"Heart_Rate_Scale",
|
||||
"Highlight_1_Brightness",
|
||||
"Highlight_1_Sharpness",
|
||||
"Highlight_2_Brightness",
|
||||
"Highlight_2_Sharpness",
|
||||
"Highlight_2_Size",
|
||||
"Hightlight_1_Size",
|
||||
"Holo_Scale",
|
||||
"LastFrame",
|
||||
"Layer1Alpha",
|
||||
"Layer1Depth",
|
||||
"Layer1Offset",
|
||||
"Layer1OffsetBobbleDelay",
|
||||
"Layer1OffsetBobbleSpeedAndSize",
|
||||
"Layer1Origin",
|
||||
"Layer1Rotation",
|
||||
"Layer1Scale",
|
||||
"Layer1ScaleBobbleDelay",
|
||||
"Layer1ScaleBobbleSpeedAndSize",
|
||||
"Layer1Scroll",
|
||||
"Layer2Alpha",
|
||||
"Layer2Depth",
|
||||
"Layer2Offset",
|
||||
"Layer2OffsetBobbleDelay",
|
||||
"Layer2OffsetBobbleSpeedAndSize",
|
||||
"Layer2Origin",
|
||||
"Layer2Rotation",
|
||||
"Layer2Scale",
|
||||
"Layer2ScaleBobbleDelay",
|
||||
"Layer2ScaleBobbleSpeedAndSize",
|
||||
"Layer2Scroll",
|
||||
"Layer3Alpha",
|
||||
"Layer3Depth",
|
||||
"Layer3Offset",
|
||||
"Layer3Origin",
|
||||
"Layer3Rotation",
|
||||
"Layer3Scale",
|
||||
"Layer3Scroll",
|
||||
"Layer4Alpha",
|
||||
"Layer4Depth",
|
||||
"Layer4Offset",
|
||||
"Layer4Origin",
|
||||
"Layer4Rotation",
|
||||
"Layer4Scale",
|
||||
"Layer4Scroll",
|
||||
"LineColor",
|
||||
"LineNoise",
|
||||
"LineWidth",
|
||||
"MaxDepth",
|
||||
"MaxFlickerColor",
|
||||
"MaxPulseDepth",
|
||||
"MaxResolution",
|
||||
"Max_Color",
|
||||
"Maximum_Distance",
|
||||
"Midlayer_Depth",
|
||||
"MinDepth",
|
||||
"MinFlickerColor",
|
||||
"MinResolution",
|
||||
"MinStatic",
|
||||
"MinVelocityFraction",
|
||||
"Min_Color",
|
||||
"Min_Player_Intensity",
|
||||
"MomentumColor",
|
||||
"NegativeColor",
|
||||
"NoisePower",
|
||||
"Noise_Scale",
|
||||
"NormalHeightMultiplier",
|
||||
"Normal_Detail_Height",
|
||||
"Normal_Detail_Scale",
|
||||
"Normal_Map_Size_Scale",
|
||||
"Normal_Variance_Scale",
|
||||
"NumFrames",
|
||||
"Outline_Lookup_Scale",
|
||||
"OverallAmount",
|
||||
"OverallBrightness",
|
||||
"Overlay_Color",
|
||||
"P1",
|
||||
"P2",
|
||||
"Padding",
|
||||
"Player_Color_Multiplier",
|
||||
"Player_Lookup_Scale",
|
||||
"PositiveColor",
|
||||
"Power",
|
||||
"PulseColor",
|
||||
"PulseInterval",
|
||||
"PulseTime",
|
||||
"Pulse_Color_Multiplier",
|
||||
"Pulse_Lookup_Scale",
|
||||
"Radius",
|
||||
"ReflectionAmount",
|
||||
"Reflection_Amount",
|
||||
"Reflection_Blur",
|
||||
"Reticle_Alt_Color",
|
||||
"Reticle_Color",
|
||||
"Row_Chars_",
|
||||
"Scale",
|
||||
"ScanlineColor",
|
||||
"ScanlineIntensity",
|
||||
"ScanlineOffset",
|
||||
"ScanlinePower",
|
||||
"ScanlineSpeed",
|
||||
"ScatterAmount",
|
||||
"ScatterSize",
|
||||
"SceneNoise",
|
||||
"SparkleBrightness",
|
||||
"SparkleDensity",
|
||||
"SparklePower",
|
||||
"SparkleProbeAmount",
|
||||
"SparkleScale",
|
||||
"SparkleSpecAmount",
|
||||
"SparkleWash",
|
||||
"SpecGloss_Map_Size_Scale",
|
||||
"SpecularAmount",
|
||||
"SpecularColor",
|
||||
"Specular_Amount",
|
||||
"Specular_Decay_Threshold",
|
||||
"Speed",
|
||||
"StaticAmount",
|
||||
"StaticLookupSpeed",
|
||||
"StaticLookupX",
|
||||
"StaticScale",
|
||||
"Static_Size",
|
||||
"Static_amount",
|
||||
"TearLookupMaxX",
|
||||
"TearLookupMinX",
|
||||
"TearLookupSpeed",
|
||||
"TearMultiplier",
|
||||
"TearPower",
|
||||
"Thickness",
|
||||
"TickMarkColorAndHarshness",
|
||||
"Tint",
|
||||
"VelocityScale",
|
||||
"VignetteMultiplier",
|
||||
"VignettePower",
|
||||
"WarpAmount",
|
||||
"WarpHeight",
|
||||
"WarpScale",
|
||||
"WarpSpeed",
|
||||
"WashOut",
|
||||
"WashoutMultiply",
|
||||
"WaterDirection",
|
||||
"WaterHeight",
|
||||
"WaterRefraction",
|
||||
"WaterScale1",
|
||||
"WaterScale2",
|
||||
"WaterSpeed1",
|
||||
"WaterSpeed2",
|
||||
"Zoom",
|
||||
"alphaDissolveParms",
|
||||
"alphaRevealParms",
|
||||
"alphaRevealParms1",
|
||||
"alphaRevealParms2",
|
||||
"alphaRevealParms3",
|
||||
"alphaRevealParms4",
|
||||
"clipSpaceLookupOffset",
|
||||
"clipSpaceLookupScale",
|
||||
"cloudsFeather",
|
||||
"cloudsHeights",
|
||||
"cloudsUVMad1",
|
||||
"cloudsUVMad2",
|
||||
"cloudsUVMul1",
|
||||
"cloudsUVMul2",
|
||||
"codeMeshArg",
|
||||
"colorDetailScale",
|
||||
"colorObjMax",
|
||||
"colorObjMaxBaseBlend",
|
||||
"colorObjMin",
|
||||
"colorObjMinBaseBlend",
|
||||
"colorTint",
|
||||
"debugBumpmap",
|
||||
"debugPerformance",
|
||||
"detailScale",
|
||||
"detailScale1",
|
||||
"detailScale2",
|
||||
"detailScale3",
|
||||
"detailScale4",
|
||||
"distortionScale",
|
||||
"dofEquationScene",
|
||||
"dofEquationViewModelAndFarBlur",
|
||||
"dofLerpBias",
|
||||
"dofLerpDownBias",
|
||||
"dofLerpDownScale",
|
||||
"dofLerpScale",
|
||||
"dofLerpUpBias",
|
||||
"dofLerpUpScale",
|
||||
"dofRowDelta",
|
||||
"eyeOffsetParms",
|
||||
"falloffBeginColor",
|
||||
"falloffEndColor",
|
||||
"falloffParms",
|
||||
"featherParms",
|
||||
"flagParams",
|
||||
"framebufferRead",
|
||||
"gameTime",
|
||||
"hdrAmount",
|
||||
"inverseTransposeWorldMatrix",
|
||||
"inverseTransposeWorldViewMatrix",
|
||||
"inverseWorldMatrix",
|
||||
"inverseWorldViewMatrix",
|
||||
"motionblurDirectionAndMagnitude",
|
||||
"occlusionAmount",
|
||||
"occlusionAmount1",
|
||||
"occlusionAmount2",
|
||||
"occlusionAmount3",
|
||||
"occlusionAmount4",
|
||||
"particleCloudColor",
|
||||
"particleCloudMatrix",
|
||||
"particleCloudVelWorld",
|
||||
"resizeParams1",
|
||||
"resizeParams2",
|
||||
"scaleRGB",
|
||||
"scriptVector0",
|
||||
"scriptVector1",
|
||||
"scriptVector2",
|
||||
"scriptVector3",
|
||||
"scriptVector4",
|
||||
"scriptVector5",
|
||||
"scriptVector6",
|
||||
"scriptVector7",
|
||||
"skyBoxCloudWeights",
|
||||
"skyBoxRotationSize",
|
||||
"skyColorParms",
|
||||
"spotLightWeight",
|
||||
"treeCanopyLightingParms",
|
||||
"treeCanopyScatterColor",
|
||||
"treeCanopySwayParms",
|
||||
"ui3dUVSetup0",
|
||||
"ui3dUVSetup1",
|
||||
"ui3dUVSetup2",
|
||||
"ui3dUVSetup3",
|
||||
"ui3dUVSetup4",
|
||||
"ui3dUVSetup5",
|
||||
"uvAnimParms",
|
||||
"uvScroll",
|
||||
"viewMatrix",
|
||||
"weaponParam0",
|
||||
"weaponParam1",
|
||||
"weaponParam2",
|
||||
"weaponParam3",
|
||||
"weaponParam4",
|
||||
"weaponParam5",
|
||||
"weaponParam6",
|
||||
"weaponParam7",
|
||||
"weaponParam8",
|
||||
"weaponParam9",
|
||||
"worldViewMatrix",
|
||||
"worldViewProjectionMatrix",
|
||||
};
|
||||
|
||||
const char* KNOWN_TEXTURE_DEF_NAMES[]{
|
||||
"AddMap",
|
||||
"Blip_Mask",
|
||||
"BlockNoise",
|
||||
"CS_Z_buffer",
|
||||
"Camo_Detail_Map",
|
||||
"Color_Map",
|
||||
"CompassMap",
|
||||
"Detail_Map",
|
||||
"Diffuse",
|
||||
"Diffuse_Map",
|
||||
"DpadTexture",
|
||||
"FontTextutre",
|
||||
"Grain_Map",
|
||||
"GridTexture",
|
||||
"GrimeMap",
|
||||
"Heart_Rate_Image",
|
||||
"Hologram_Diffuse",
|
||||
"Image",
|
||||
"Layer1Map",
|
||||
"Layer2Map",
|
||||
"Layer3Map",
|
||||
"Layer4Map",
|
||||
"Lookup",
|
||||
"Lookup2",
|
||||
"LookupMap",
|
||||
"Mask",
|
||||
"Noise",
|
||||
"Noise_Texture",
|
||||
"NormalDetailMap",
|
||||
"Normal_Detail_Map",
|
||||
"Normal_Map",
|
||||
"Overlay_Map",
|
||||
"Reflection_Mask",
|
||||
"Reveal_Map",
|
||||
"Rim_Color_Mask",
|
||||
"Rim_Specular_Mask",
|
||||
"Rim_Occlusion_Mask",
|
||||
"Scanline",
|
||||
"SparkleMap",
|
||||
"SpecularAndGloss",
|
||||
"SpecularAndGloss2",
|
||||
"Specular_Color_Map",
|
||||
"Specular_Gloss_Map",
|
||||
"Specular_Map",
|
||||
"SpotShadowSamplerState",
|
||||
"SpotShadowState",
|
||||
"SpriteMap",
|
||||
"Static",
|
||||
"StaticMap",
|
||||
"Static_Noise_Map",
|
||||
"SunShadowSamplerState",
|
||||
"SunShadowState",
|
||||
"Surface_Normal_Map",
|
||||
"ThermalMapMask",
|
||||
"Thermal_Gradient",
|
||||
"Thermal_Map",
|
||||
"TickMarkMaterial",
|
||||
"Tile",
|
||||
"WarpMap",
|
||||
"WaterNormalMap",
|
||||
"Weapon_Normal_Map",
|
||||
"Weapon_Specular_Map",
|
||||
"Wireframe",
|
||||
"ZBuffer_Map",
|
||||
"attenuation",
|
||||
"attenuationSampler",
|
||||
"baseLut2D",
|
||||
"baseLut2DSampler",
|
||||
"cinematicA",
|
||||
"cinematicASampler",
|
||||
"cinematicCb",
|
||||
"cinematicCbSampler",
|
||||
"cinematicCr",
|
||||
"cinematicCrSampler",
|
||||
"cinematicY",
|
||||
"cinematicYSampler",
|
||||
"codeTexture0",
|
||||
"codeTexture1",
|
||||
"codeTexture2",
|
||||
"color",
|
||||
"colorDetailMap",
|
||||
"colorDetailMapSampler",
|
||||
"colorMap",
|
||||
"colorMap1",
|
||||
"colorMap2",
|
||||
"colorMap2D",
|
||||
"colorMapPostSun",
|
||||
"colorMapPostSunSampler",
|
||||
"colorMapSampler",
|
||||
"colorMapSampler1",
|
||||
"colorMapSampler2",
|
||||
"colorSampler",
|
||||
"detailMap",
|
||||
"detailMapSampler",
|
||||
"dlightAttenuation",
|
||||
"dlightAttenuationSampler",
|
||||
"floatZ",
|
||||
"floatZSampler",
|
||||
"imageSampler",
|
||||
"lightmapSamplerSecondary",
|
||||
"lightmapSecondary",
|
||||
"lut2D",
|
||||
"lut2DSampler",
|
||||
"lut3D",
|
||||
"lut3DSampler",
|
||||
"missileCam",
|
||||
"missileCamSampler",
|
||||
"modelLighting",
|
||||
"modelLightingSampler",
|
||||
"normalMap",
|
||||
"normalMap1",
|
||||
"normalMap2",
|
||||
"normalMapSampler",
|
||||
"normalMapSampler1",
|
||||
"normalMapSampler2",
|
||||
"occlusionMap",
|
||||
"occlusionMapSampler",
|
||||
"occMap",
|
||||
"occMapSampler",
|
||||
"outdoorMap",
|
||||
"outdoorMapSampler",
|
||||
"radiantDiffuseMap",
|
||||
"rawFloatZ",
|
||||
"rawFloatZSampler",
|
||||
"reflectionProbe",
|
||||
"reflectionProbeSampler",
|
||||
"shadowmapSamplerSpot",
|
||||
"shadowmapSamplerSun",
|
||||
"shadowmapSpot",
|
||||
"shadowmapSun",
|
||||
"sonarColor",
|
||||
"sonarColorSampler",
|
||||
"sonarDepth",
|
||||
"sonarDepthSampler",
|
||||
"source",
|
||||
"specularMap",
|
||||
"specularMap1",
|
||||
"specularMap2",
|
||||
"specularMapSampler",
|
||||
"specularMapSampler1",
|
||||
"specularMapSampler2",
|
||||
"stencil",
|
||||
"stencilSampler",
|
||||
"ui3d",
|
||||
"ui3dSampler",
|
||||
};
|
||||
|
||||
class MaterialConstantZoneState final : public IZoneAssetDumperState
|
||||
{
|
||||
public:
|
||||
void ExtractNamesFromZone()
|
||||
{
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
std::cout << "Building material constant name lookup...\n";
|
||||
|
||||
const auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
AddStaticKnownNames();
|
||||
|
||||
for (const auto* zone : g_GameT6.GetZones())
|
||||
{
|
||||
const auto* t6AssetPools = dynamic_cast<const GameAssetPoolT6*>(zone->m_pools.get());
|
||||
if (!t6AssetPools)
|
||||
return;
|
||||
|
||||
for (const auto* techniqueSetInfo : *t6AssetPools->m_technique_set)
|
||||
{
|
||||
const auto* techniqueSet = techniqueSetInfo->Asset();
|
||||
|
||||
for (const auto* technique : techniqueSet->techniques)
|
||||
{
|
||||
if (technique)
|
||||
ExtractNamesFromTechnique(technique);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (ObjWriting::Configuration.Verbose)
|
||||
{
|
||||
const auto durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
|
||||
std::cout << "Built material constant name lookup in " << durationInMs.count() << "ms: " << m_constant_names_from_shaders.size()
|
||||
<< " constant names; " << m_texture_def_names_from_shaders.size() << " texture def names\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool GetConstantName(const unsigned hash, std::string& constantName) const
|
||||
{
|
||||
const auto existingConstantName = m_constant_names_from_shaders.find(hash);
|
||||
if (existingConstantName != m_constant_names_from_shaders.end())
|
||||
{
|
||||
constantName = existingConstantName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetTextureDefName(const unsigned hash, std::string& textureDefName) const
|
||||
{
|
||||
const auto existingTextureDefName = m_texture_def_names_from_shaders.find(hash);
|
||||
if (existingTextureDefName != m_texture_def_names_from_shaders.end())
|
||||
{
|
||||
textureDefName = existingTextureDefName->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void ExtractNamesFromTechnique(const MaterialTechnique* technique)
|
||||
{
|
||||
const auto existingTechnique = m_dumped_techniques.find(technique);
|
||||
if (existingTechnique != m_dumped_techniques.end())
|
||||
return;
|
||||
|
||||
m_dumped_techniques.emplace(technique);
|
||||
|
||||
for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++)
|
||||
{
|
||||
const auto& pass = technique->passArray[passIndex];
|
||||
|
||||
if (pass.vertexShader && pass.vertexShader->prog.loadDef.program)
|
||||
ExtractNamesFromShader(pass.vertexShader->prog.loadDef.program, pass.vertexShader->prog.loadDef.programSize);
|
||||
|
||||
if (pass.pixelShader && pass.pixelShader->prog.loadDef.program)
|
||||
ExtractNamesFromShader(pass.pixelShader->prog.loadDef.program, pass.pixelShader->prog.loadDef.programSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ExtractNamesFromShader(const char* shader, const size_t shaderSize)
|
||||
{
|
||||
const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(reinterpret_cast<const uint8_t*>(shader), shaderSize);
|
||||
if (!shaderInfo)
|
||||
return;
|
||||
|
||||
const auto globalsConstantBuffer = std::find_if(shaderInfo->m_constant_buffers.cbegin(),
|
||||
shaderInfo->m_constant_buffers.cend(),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == GLOBALS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
const auto perObjectConsts = std::find_if(shaderInfo->m_constant_buffers.cbegin(),
|
||||
shaderInfo->m_constant_buffers.cend(),
|
||||
[](const d3d11::ConstantBuffer& constantBuffer)
|
||||
{
|
||||
return constantBuffer.m_name == PER_OBJECT_CONSTS_CBUFFER_NAME;
|
||||
});
|
||||
|
||||
if (globalsConstantBuffer != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : globalsConstantBuffer->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
if (perObjectConsts != shaderInfo->m_constant_buffers.end())
|
||||
{
|
||||
for (const auto& variable : perObjectConsts->m_variables)
|
||||
AddConstantName(variable.m_name);
|
||||
}
|
||||
|
||||
for (const auto& boundResource : shaderInfo->m_bound_resources)
|
||||
{
|
||||
if (boundResource.m_type == d3d11::BoundResourceType::SAMPLER || boundResource.m_type == d3d11::BoundResourceType::TEXTURE)
|
||||
{
|
||||
if (AddTextureDefName(boundResource.m_name))
|
||||
{
|
||||
const auto samplerPos = boundResource.m_name.rfind(SAMPLER_STR);
|
||||
if (samplerPos != std::string::npos)
|
||||
{
|
||||
auto nameWithoutSamplerStr = boundResource.m_name;
|
||||
nameWithoutSamplerStr.erase(samplerPos, std::char_traits<char>::length(SAMPLER_STR));
|
||||
AddTextureDefName(std::move(nameWithoutSamplerStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddStaticKnownNames()
|
||||
{
|
||||
for (const auto* knownConstantName : KNOWN_CONSTANT_NAMES)
|
||||
AddConstantName(knownConstantName);
|
||||
for (const auto* knownTextureDefName : KNOWN_TEXTURE_DEF_NAMES)
|
||||
AddTextureDefName(knownTextureDefName);
|
||||
}
|
||||
|
||||
void AddConstantName(std::string constantName)
|
||||
{
|
||||
const auto hash = Common::R_HashString(constantName.c_str(), 0);
|
||||
if (m_constant_names_from_shaders.find(hash) != m_constant_names_from_shaders.end())
|
||||
return;
|
||||
|
||||
m_constant_names_from_shaders.emplace(hash, std::move(constantName));
|
||||
}
|
||||
|
||||
bool AddTextureDefName(std::string textureDefName)
|
||||
{
|
||||
const auto hash = Common::R_HashString(textureDefName.c_str(), 0);
|
||||
if (m_texture_def_names_from_shaders.find(hash) != m_texture_def_names_from_shaders.end())
|
||||
return false;
|
||||
|
||||
m_texture_def_names_from_shaders.emplace(hash, std::move(textureDefName));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unordered_set<const MaterialTechnique*> m_dumped_techniques;
|
||||
std::unordered_map<unsigned, std::string> m_constant_names_from_shaders;
|
||||
std::unordered_map<unsigned, std::string> m_texture_def_names_from_shaders;
|
||||
};
|
||||
|
||||
class JsonDumper
|
||||
{
|
||||
public:
|
||||
explicit JsonDumper(std::ostream& stream)
|
||||
: m_stream(stream)
|
||||
explicit JsonDumper(AssetDumpingContext& context, std::ostream& stream)
|
||||
: m_stream(stream),
|
||||
m_material_constants(*context.GetZoneAssetDumperState<MaterialConstantZoneState>())
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,8 +696,9 @@ namespace T6::material
|
||||
j[key] = nullptr;
|
||||
}
|
||||
|
||||
static void MaterialToJson(json& jRoot, const Material* material)
|
||||
void MaterialToJson(json& jRoot, const Material* material) const
|
||||
{
|
||||
|
||||
MaterialInfoToJson(jRoot, material);
|
||||
StateBitsEntryToJson(jRoot, material);
|
||||
jRoot["stateFlags"] = material->stateFlags;
|
||||
@ -128,7 +764,7 @@ namespace T6::material
|
||||
jRoot["techniqueSet"] = nullptr;
|
||||
}
|
||||
|
||||
static void TextureTableToJson(json& jRoot, const Material* material)
|
||||
void TextureTableToJson(json& jRoot, const Material* material) const
|
||||
{
|
||||
json jTextures = json::array();
|
||||
if (material->textureTable)
|
||||
@ -143,19 +779,19 @@ namespace T6::material
|
||||
jRoot["textures"] = std::move(jTextures);
|
||||
}
|
||||
|
||||
static void TextureDefToJson(json& jTexture, const MaterialTextureDef* textureDef)
|
||||
void TextureDefToJson(json& jTexture, const MaterialTextureDef* textureDef) const
|
||||
{
|
||||
const auto knownHash = knownHashes.find(textureDef->nameHash);
|
||||
if (knownHash == knownHashes.end())
|
||||
std::string textureDefName;
|
||||
if (m_material_constants.GetTextureDefName(textureDef->nameHash, textureDefName))
|
||||
{
|
||||
jTexture["name"] = textureDefName;
|
||||
}
|
||||
else
|
||||
{
|
||||
jTexture["nameHash"] = textureDef->nameHash;
|
||||
jTexture["nameStart"] = std::string(1u, textureDef->nameStart);
|
||||
jTexture["nameEnd"] = std::string(1u, textureDef->nameEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
jTexture["name"] = knownHash->second;
|
||||
}
|
||||
|
||||
JsonEnumEntry(jTexture, "semantic", textureDef->semantic, textureSemanticNames);
|
||||
jTexture["isMatureContent"] = textureDef->isMatureContent;
|
||||
@ -179,7 +815,7 @@ namespace T6::material
|
||||
jSamplerState["clampW"] = samplerState.clampW ? true : false;
|
||||
}
|
||||
|
||||
static void ConstantTableToJson(json& jRoot, const Material* material)
|
||||
void ConstantTableToJson(json& jRoot, const Material* material) const
|
||||
{
|
||||
json jConstants = json::array();
|
||||
if (material->constantTable)
|
||||
@ -194,26 +830,31 @@ namespace T6::material
|
||||
jRoot["constants"] = std::move(jConstants);
|
||||
}
|
||||
|
||||
static void ConstantDefToJson(json& jConstant, const MaterialConstantDef* textureDef)
|
||||
void ConstantDefToJson(json& jConstant, const MaterialConstantDef* constantDef) const
|
||||
{
|
||||
const auto fragmentLength = strnlen(textureDef->name, std::extent_v<decltype(MaterialConstantDef::name)>);
|
||||
const std::string nameFragment(textureDef->name, fragmentLength);
|
||||
const auto fragmentLength = strnlen(constantDef->name, std::extent_v<decltype(MaterialConstantDef::name)>);
|
||||
const std::string nameFragment(constantDef->name, fragmentLength);
|
||||
std::string knownConstantName;
|
||||
|
||||
if (fragmentLength < std::extent_v<decltype(MaterialConstantDef::name)> || Common::R_HashString(nameFragment.c_str(), 0) == textureDef->nameHash)
|
||||
if (fragmentLength < std::extent_v<decltype(MaterialConstantDef::name)> || Common::R_HashString(nameFragment.c_str(), 0) == constantDef->nameHash)
|
||||
{
|
||||
jConstant["name"] = nameFragment;
|
||||
}
|
||||
else if (m_material_constants.GetConstantName(constantDef->nameHash, knownConstantName))
|
||||
{
|
||||
jConstant["name"] = knownConstantName;
|
||||
}
|
||||
else
|
||||
{
|
||||
jConstant["nameHash"] = textureDef->nameHash;
|
||||
jConstant["nameHash"] = constantDef->nameHash;
|
||||
jConstant["nameFragment"] = nameFragment;
|
||||
}
|
||||
|
||||
json jLiteral;
|
||||
jLiteral.push_back(textureDef->literal.v[0]);
|
||||
jLiteral.push_back(textureDef->literal.v[1]);
|
||||
jLiteral.push_back(textureDef->literal.v[2]);
|
||||
jLiteral.push_back(textureDef->literal.v[3]);
|
||||
jLiteral.push_back(constantDef->literal.v[0]);
|
||||
jLiteral.push_back(constantDef->literal.v[1]);
|
||||
jLiteral.push_back(constantDef->literal.v[2]);
|
||||
jLiteral.push_back(constantDef->literal.v[3]);
|
||||
jConstant["literal"] = std::move(jLiteral);
|
||||
}
|
||||
|
||||
@ -324,6 +965,7 @@ namespace T6::material
|
||||
}
|
||||
|
||||
std::ostream& m_stream;
|
||||
const MaterialConstantZoneState& m_material_constants;
|
||||
};
|
||||
} // namespace T6::material
|
||||
|
||||
@ -357,6 +999,14 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
|
||||
if (!assetFile)
|
||||
return;
|
||||
|
||||
const material::JsonDumper dumper(*assetFile);
|
||||
const material::JsonDumper dumper(context, *assetFile);
|
||||
dumper.Dump(asset->Asset());
|
||||
}
|
||||
|
||||
void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool)
|
||||
{
|
||||
auto* materialConstantState = context.GetZoneAssetDumperState<material::MaterialConstantZoneState>();
|
||||
materialConstantState->ExtractNamesFromZone();
|
||||
|
||||
AbstractAssetDumper<Material>::DumpPool(context, pool);
|
||||
}
|
||||
|
@ -14,5 +14,8 @@ namespace T6
|
||||
protected:
|
||||
bool ShouldDump(XAssetInfo<Material>* asset) override;
|
||||
void DumpAsset(AssetDumpingContext& context, XAssetInfo<Material>* asset) override;
|
||||
|
||||
public:
|
||||
void DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool) override;
|
||||
};
|
||||
} // namespace T6
|
||||
|
Loading…
x
Reference in New Issue
Block a user