mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-03-05 04:23:02 +00:00
Merge pull request #692 from Laupetin/feature/t6-techset-loading
feat: t6 techset and technique loading
This commit is contained in:
@@ -8,18 +8,21 @@ using namespace IW3;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char* ASSET_TYPE_NAMES[ASSET_TYPE_COUNT]{
|
constexpr const char* ASSET_TYPE_NAMES[]{
|
||||||
"xmodelpieces", "physpreset", "xanim", "xmodel", "material", "techniqueset", "image", "sound", "soundcurve", "loadedsound",
|
"xmodelpieces", "physpreset", "xanim", "xmodel", "material", "techniqueset", "image", "sound", "soundcurve", "loadedsound",
|
||||||
"clipmap_unused", "clipmap", "comworld", "gameworldsp", "gameworldmp", "mapents", "gfxworld", "lightdef", "uimap", "font",
|
"clipmap_unused", "clipmap", "comworld", "gameworldsp", "gameworldmp", "mapents", "gfxworld", "lightdef", "uimap", "font",
|
||||||
"menulist", "menu", "localize", "weapon", "snddriverglobals", "fx", "impactfx", "aitype", "mptype", "character",
|
"menulist", "menu", "localize", "weapon", "snddriverglobals", "fx", "impactfx", "aitype", "mptype", "character",
|
||||||
"xmodelalias", "rawfile", "stringtable",
|
"xmodelalias", "rawfile", "stringtable",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
|
||||||
|
|
||||||
constexpr const char* SUB_ASSET_TYPE_NAMES[SUB_ASSET_TYPE_COUNT]{
|
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
|
||||||
"technique",
|
"technique",
|
||||||
|
"vertexdecl",
|
||||||
"vertexshader",
|
"vertexshader",
|
||||||
"pixelshader",
|
"pixelshader",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace IW3
|
namespace IW3
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ namespace IW3
|
|||||||
enum SubAssetType
|
enum SubAssetType
|
||||||
{
|
{
|
||||||
SUB_ASSET_TYPE_TECHNIQUE,
|
SUB_ASSET_TYPE_TECHNIQUE,
|
||||||
|
SUB_ASSET_TYPE_VERTEX_DECL,
|
||||||
SUB_ASSET_TYPE_VERTEX_SHADER,
|
SUB_ASSET_TYPE_VERTEX_SHADER,
|
||||||
SUB_ASSET_TYPE_PIXEL_SHADER,
|
SUB_ASSET_TYPE_PIXEL_SHADER,
|
||||||
|
|
||||||
|
|||||||
@@ -1425,10 +1425,26 @@ namespace IW3
|
|||||||
TECHNIQUE_NONE = 0x24,
|
TECHNIQUE_NONE = 0x24,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialWorldVertexFormat : unsigned char
|
||||||
|
{
|
||||||
|
MTL_WORLDVERT_TEX_1_NRM_1 = 0x0,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_1 = 0x1,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_2 = 0x2,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_1 = 0x3,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_2 = 0x4,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_3 = 0x5,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_1 = 0x6,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_2 = 0x7,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_3 = 0x8,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_1 = 0x9,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_2 = 0xA,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_3 = 0xB,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechniqueSet
|
struct MaterialTechniqueSet
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
char worldVertFormat;
|
MaterialWorldVertexFormat worldVertFormat;
|
||||||
bool hasBeenUploaded;
|
bool hasBeenUploaded;
|
||||||
char unused[1];
|
char unused[1];
|
||||||
MaterialTechniqueSet* remappedTechniqueSet;
|
MaterialTechniqueSet* remappedTechniqueSet;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using namespace IW4;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char* ASSET_TYPE_NAMES[ASSET_TYPE_COUNT]{
|
constexpr const char* ASSET_TYPE_NAMES[]{
|
||||||
"physpreset", "physcollmap", "xanim", "xmodelsurfs", "xmodel",
|
"physpreset", "physcollmap", "xanim", "xmodelsurfs", "xmodel",
|
||||||
"material", "pixelshader", "vertexshader", "vertexdecl", "techniqueset",
|
"material", "pixelshader", "vertexshader", "vertexdecl", "techniqueset",
|
||||||
"image", "sound", "soundcurve", "loadedsound", "clipmap_unused",
|
"image", "sound", "soundcurve", "loadedsound", "clipmap_unused",
|
||||||
@@ -19,10 +19,12 @@ namespace
|
|||||||
"xmodelalias", "rawfile", "stringtable", "leaderboard", "structureddatadef",
|
"xmodelalias", "rawfile", "stringtable", "leaderboard", "structureddatadef",
|
||||||
"tracer", "vehicle", "addonmapents",
|
"tracer", "vehicle", "addonmapents",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
|
||||||
|
|
||||||
constexpr const char* SUB_ASSET_TYPE_NAMES[SUB_ASSET_TYPE_COUNT]{
|
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
|
||||||
"technique",
|
"technique",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
|
|||||||
@@ -1668,10 +1668,26 @@ namespace IW4
|
|||||||
TECHNIQUE_COUNT
|
TECHNIQUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialWorldVertexFormat : unsigned char
|
||||||
|
{
|
||||||
|
MTL_WORLDVERT_TEX_1_NRM_1 = 0x0,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_1 = 0x1,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_2 = 0x2,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_1 = 0x3,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_2 = 0x4,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_3 = 0x5,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_1 = 0x6,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_2 = 0x7,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_3 = 0x8,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_1 = 0x9,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_2 = 0xA,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_3 = 0xB,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechniqueSet
|
struct MaterialTechniqueSet
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned char worldVertFormat;
|
MaterialWorldVertexFormat worldVertFormat;
|
||||||
bool hasBeenUploaded;
|
bool hasBeenUploaded;
|
||||||
unsigned char unused[1];
|
unsigned char unused[1];
|
||||||
MaterialTechniqueSet* remappedTechniqueSet;
|
MaterialTechniqueSet* remappedTechniqueSet;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using namespace IW5;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char* ASSET_TYPE_NAMES[ASSET_TYPE_COUNT]{
|
constexpr const char* ASSET_TYPE_NAMES[]{
|
||||||
"physpreset",
|
"physpreset",
|
||||||
"physcollmap",
|
"physcollmap",
|
||||||
"xanim",
|
"xanim",
|
||||||
@@ -56,10 +56,12 @@ namespace
|
|||||||
"vehicle",
|
"vehicle",
|
||||||
"addonmapents",
|
"addonmapents",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
|
||||||
|
|
||||||
constexpr const char* SUB_ASSET_TYPE_NAMES[SUB_ASSET_TYPE_COUNT]{
|
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
|
||||||
"technique",
|
"technique",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace IW5
|
namespace IW5
|
||||||
|
|||||||
@@ -1046,10 +1046,26 @@ namespace IW5
|
|||||||
MaterialPass passArray[1];
|
MaterialPass passArray[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialWorldVertexFormat : unsigned char
|
||||||
|
{
|
||||||
|
MTL_WORLDVERT_TEX_1_NRM_1 = 0x0,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_1 = 0x1,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_2 = 0x2,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_1 = 0x3,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_2 = 0x4,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_3 = 0x5,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_1 = 0x6,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_2 = 0x7,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_3 = 0x8,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_1 = 0x9,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_2 = 0xA,
|
||||||
|
MTL_WORLDVERT_TEX_5_NRM_3 = 0xB,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechniqueSet
|
struct MaterialTechniqueSet
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned char worldVertFormat;
|
MaterialWorldVertexFormat worldVertFormat;
|
||||||
unsigned char unused[2];
|
unsigned char unused[2];
|
||||||
MaterialTechniqueSet* remappedTechniqueSet;
|
MaterialTechniqueSet* remappedTechniqueSet;
|
||||||
MaterialTechnique* techniques[54];
|
MaterialTechnique* techniques[54];
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using namespace T5;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char* ASSET_TYPE_NAMES[ASSET_TYPE_COUNT]{
|
constexpr const char* ASSET_TYPE_NAMES[]{
|
||||||
"xmodelpieces", "physpreset", "physconstraints", "destructibledef", "xanim", "xmodel", "material",
|
"xmodelpieces", "physpreset", "physconstraints", "destructibledef", "xanim", "xmodel", "material",
|
||||||
"techniqueset", "image", "soundbank", "soundpatch", "clipmap_unused", "clipmap", "comworld",
|
"techniqueset", "image", "soundbank", "soundpatch", "clipmap_unused", "clipmap", "comworld",
|
||||||
"gameworldsp", "gameworldmp", "mapents", "gfxworld", "gfxlightdef", "uimap", "font",
|
"gameworldsp", "gameworldmp", "mapents", "gfxworld", "gfxlightdef", "uimap", "font",
|
||||||
@@ -17,12 +17,15 @@ namespace
|
|||||||
"xmodelalias", "rawfile", "stringtable", "packindex", "xglobals", "ddl", "glasses",
|
"xmodelalias", "rawfile", "stringtable", "packindex", "xglobals", "ddl", "glasses",
|
||||||
"emblemset",
|
"emblemset",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
|
||||||
|
|
||||||
constexpr const char* SUB_ASSET_TYPE_NAMES[SUB_ASSET_TYPE_COUNT]{
|
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
|
||||||
"technique",
|
"technique",
|
||||||
|
"vertexdecl",
|
||||||
"vertexshader",
|
"vertexshader",
|
||||||
"pixelshader",
|
"pixelshader",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace T5
|
namespace T5
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ namespace T5
|
|||||||
|
|
||||||
enum SubAssetType
|
enum SubAssetType
|
||||||
{
|
{
|
||||||
SUB_ASSET_TYPE_TECHNIQUE = ASSET_TYPE_COUNT,
|
SUB_ASSET_TYPE_TECHNIQUE,
|
||||||
|
SUB_ASSET_TYPE_VERTEX_DECL,
|
||||||
SUB_ASSET_TYPE_VERTEX_SHADER,
|
SUB_ASSET_TYPE_VERTEX_SHADER,
|
||||||
SUB_ASSET_TYPE_PIXEL_SHADER,
|
SUB_ASSET_TYPE_PIXEL_SHADER,
|
||||||
|
|
||||||
|
|||||||
@@ -1448,8 +1448,8 @@ namespace T5
|
|||||||
struct MaterialArgumentCodeConst
|
struct MaterialArgumentCodeConst
|
||||||
{
|
{
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
char firstRow;
|
unsigned char firstRow;
|
||||||
char rowCount;
|
unsigned char rowCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
union MaterialArgumentDef
|
union MaterialArgumentDef
|
||||||
@@ -1465,11 +1465,15 @@ namespace T5
|
|||||||
MTL_ARG_MATERIAL_VERTEX_CONST = 0x0,
|
MTL_ARG_MATERIAL_VERTEX_CONST = 0x0,
|
||||||
MTL_ARG_LITERAL_VERTEX_CONST = 0x1,
|
MTL_ARG_LITERAL_VERTEX_CONST = 0x1,
|
||||||
MTL_ARG_MATERIAL_PIXEL_SAMPLER = 0x2,
|
MTL_ARG_MATERIAL_PIXEL_SAMPLER = 0x2,
|
||||||
|
|
||||||
MTL_ARG_CODE_PRIM_BEGIN = 0x3,
|
MTL_ARG_CODE_PRIM_BEGIN = 0x3,
|
||||||
|
|
||||||
MTL_ARG_CODE_VERTEX_CONST = 0x3,
|
MTL_ARG_CODE_VERTEX_CONST = 0x3,
|
||||||
MTL_ARG_CODE_PIXEL_SAMPLER = 0x4,
|
MTL_ARG_CODE_PIXEL_SAMPLER = 0x4,
|
||||||
MTL_ARG_CODE_PIXEL_CONST = 0x5,
|
MTL_ARG_CODE_PIXEL_CONST = 0x5,
|
||||||
|
|
||||||
MTL_ARG_CODE_PRIM_END = 0x6,
|
MTL_ARG_CODE_PRIM_END = 0x6,
|
||||||
|
|
||||||
MTL_ARG_MATERIAL_PIXEL_CONST = 0x6,
|
MTL_ARG_MATERIAL_PIXEL_CONST = 0x6,
|
||||||
MTL_ARG_LITERAL_PIXEL_CONST = 0x7,
|
MTL_ARG_LITERAL_PIXEL_CONST = 0x7,
|
||||||
|
|
||||||
@@ -1500,6 +1504,29 @@ namespace T5
|
|||||||
const char* techniqueSetPrefix;
|
const char* techniqueSetPrefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TechniqueFlags
|
||||||
|
{
|
||||||
|
TECHNIQUE_FLAG_1 = 0x1,
|
||||||
|
TECHNIQUE_FLAG_2 = 0x2,
|
||||||
|
TECHNIQUE_FLAG_4 = 0x4,
|
||||||
|
|
||||||
|
// Vertex decl has optional source
|
||||||
|
TECHNIQUE_FLAG_8 = 0x8,
|
||||||
|
|
||||||
|
TECHNIQUE_FLAG_10 = 0x10,
|
||||||
|
TECHNIQUE_FLAG_20 = 0x20,
|
||||||
|
TECHNIQUE_FLAG_40 = 0x40,
|
||||||
|
|
||||||
|
// Any material that has statebits according to any of the following sets this:
|
||||||
|
// - GFXS1_DEPTHWRITE set
|
||||||
|
// - Any depth test (No GFXS1_DEPTHTEST_DISABLE set)
|
||||||
|
// - Any polygon offset that is not GFXS1_POLYGON_OFFSET_0
|
||||||
|
TECHNIQUE_FLAG_80 = 0x80,
|
||||||
|
|
||||||
|
TECHNIQUE_FLAG_100 = 0x100,
|
||||||
|
TECHNIQUE_FLAG_200 = 0x200,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialPass
|
struct MaterialPass
|
||||||
{
|
{
|
||||||
MaterialVertexDeclaration* vertexDecl;
|
MaterialVertexDeclaration* vertexDecl;
|
||||||
@@ -1668,10 +1695,23 @@ namespace T5
|
|||||||
TECHNIQUE_COUNT
|
TECHNIQUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialWorldVertexFormat : unsigned char
|
||||||
|
{
|
||||||
|
MTL_WORLDVERT_TEX_1_NRM_1 = 0x0,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_1 = 0x1,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_2 = 0x2,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_1 = 0x3,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_2 = 0x4,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_3 = 0x5,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_1 = 0x6,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_2 = 0x7,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_3 = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechniqueSet
|
struct MaterialTechniqueSet
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
char worldVertFormat;
|
MaterialWorldVertexFormat worldVertFormat;
|
||||||
char unused[1];
|
char unused[1];
|
||||||
uint16_t techsetFlags;
|
uint16_t techsetFlags;
|
||||||
MaterialTechnique* techniques[130];
|
MaterialTechnique* techniques[130];
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using namespace T6;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char* ASSET_TYPE_NAMES[ASSET_TYPE_COUNT]{
|
constexpr const char* ASSET_TYPE_NAMES[]{
|
||||||
"xmodelpieces",
|
"xmodelpieces",
|
||||||
"physpreset",
|
"physpreset",
|
||||||
"physconstraints",
|
"physconstraints",
|
||||||
@@ -70,12 +70,15 @@ namespace
|
|||||||
"footstepfxtable",
|
"footstepfxtable",
|
||||||
"zbarrier",
|
"zbarrier",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
|
||||||
|
|
||||||
constexpr const char* SUB_ASSET_TYPE_NAMES[SUB_ASSET_TYPE_COUNT]{
|
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
|
||||||
"technique",
|
"technique",
|
||||||
|
"vertexdecl",
|
||||||
"vertexshader",
|
"vertexshader",
|
||||||
"pixelshader",
|
"pixelshader",
|
||||||
};
|
};
|
||||||
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ namespace T6
|
|||||||
enum SubAssetType
|
enum SubAssetType
|
||||||
{
|
{
|
||||||
SUB_ASSET_TYPE_TECHNIQUE,
|
SUB_ASSET_TYPE_TECHNIQUE,
|
||||||
|
SUB_ASSET_TYPE_VERTEX_DECL,
|
||||||
SUB_ASSET_TYPE_VERTEX_SHADER,
|
SUB_ASSET_TYPE_VERTEX_SHADER,
|
||||||
SUB_ASSET_TYPE_PIXEL_SHADER,
|
SUB_ASSET_TYPE_PIXEL_SHADER,
|
||||||
|
|
||||||
@@ -288,8 +289,9 @@ namespace T6
|
|||||||
using AssetZBarrier = Asset<ASSET_TYPE_ZBARRIER, ZBarrierDef>;
|
using AssetZBarrier = Asset<ASSET_TYPE_ZBARRIER, ZBarrierDef>;
|
||||||
|
|
||||||
using SubAssetTechnique = SubAsset<SUB_ASSET_TYPE_TECHNIQUE, MaterialTechnique>;
|
using SubAssetTechnique = SubAsset<SUB_ASSET_TYPE_TECHNIQUE, MaterialTechnique>;
|
||||||
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialTechnique>;
|
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
|
||||||
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialTechnique>;
|
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
|
||||||
|
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysPreset, name);
|
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysPreset, name);
|
||||||
|
|||||||
@@ -770,10 +770,23 @@ namespace T6
|
|||||||
TECHNIQUE_COUNT
|
TECHNIQUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialWorldVertexFormat : unsigned char
|
||||||
|
{
|
||||||
|
MTL_WORLDVERT_TEX_1_NRM_1 = 0x0,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_1 = 0x1,
|
||||||
|
MTL_WORLDVERT_TEX_2_NRM_2 = 0x2,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_1 = 0x3,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_2 = 0x4,
|
||||||
|
MTL_WORLDVERT_TEX_3_NRM_3 = 0x5,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_1 = 0x6,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_2 = 0x7,
|
||||||
|
MTL_WORLDVERT_TEX_4_NRM_3 = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechniqueSet
|
struct MaterialTechniqueSet
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
char worldVertFormat;
|
MaterialWorldVertexFormat worldVertFormat;
|
||||||
MaterialTechnique* techniques[36];
|
MaterialTechnique* techniques[36];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2988,6 +3001,14 @@ namespace T6
|
|||||||
VERTEX_SHADER_MODEL_UNLIT,
|
VERTEX_SHADER_MODEL_UNLIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CustomSampler
|
||||||
|
{
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE = 0,
|
||||||
|
CUSTOM_SAMPLER_LIGHTMAP_SECONDARY,
|
||||||
|
|
||||||
|
CUSTOM_SAMPLER_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
enum MaterialType : unsigned char
|
enum MaterialType : unsigned char
|
||||||
{
|
{
|
||||||
MTL_TYPE_DEFAULT = 0x0,
|
MTL_TYPE_DEFAULT = 0x0,
|
||||||
@@ -3022,6 +3043,29 @@ namespace T6
|
|||||||
MaterialShaderArgument* args;
|
MaterialShaderArgument* args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TechniqueFlags
|
||||||
|
{
|
||||||
|
TECHNIQUE_FLAG_1 = 0x1,
|
||||||
|
TECHNIQUE_FLAG_2 = 0x2,
|
||||||
|
TECHNIQUE_FLAG_4 = 0x4,
|
||||||
|
|
||||||
|
// Vertex decl has optional source
|
||||||
|
TECHNIQUE_FLAG_8 = 0x8,
|
||||||
|
|
||||||
|
TECHNIQUE_FLAG_10 = 0x10,
|
||||||
|
TECHNIQUE_FLAG_20 = 0x20,
|
||||||
|
TECHNIQUE_FLAG_40 = 0x40,
|
||||||
|
|
||||||
|
// Any material that has statebits according to any of the following sets this:
|
||||||
|
// - GFXS1_DEPTHWRITE set
|
||||||
|
// - Any depth test (No GFXS1_DEPTHTEST_DISABLE set)
|
||||||
|
// - Any polygon offset that is not GFXS1_POLYGON_OFFSET_0
|
||||||
|
TECHNIQUE_FLAG_80 = 0x80,
|
||||||
|
|
||||||
|
TECHNIQUE_FLAG_100 = 0x100,
|
||||||
|
TECHNIQUE_FLAG_200 = 0x200,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialTechnique
|
struct MaterialTechnique
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@@ -3030,14 +3074,6 @@ namespace T6
|
|||||||
MaterialPass passArray[1];
|
MaterialPass passArray[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct __cppobj ID3D11View : ID3D11DeviceChild
|
|
||||||
{
|
|
||||||
};*/
|
|
||||||
|
|
||||||
/* struct __cppobj ID3D11ShaderResourceView : ID3D11View
|
|
||||||
{
|
|
||||||
};*/
|
|
||||||
|
|
||||||
struct type_align32(4) GfxImageLoadDef
|
struct type_align32(4) GfxImageLoadDef
|
||||||
{
|
{
|
||||||
char levelCount;
|
char levelCount;
|
||||||
@@ -3706,14 +3742,6 @@ namespace T6
|
|||||||
GfxImage* secondary;
|
GfxImage* secondary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct __cppobj ID3D11Resource : ID3D11DeviceChild
|
|
||||||
{
|
|
||||||
};*/
|
|
||||||
|
|
||||||
/* struct __cppobj ID3D11Buffer : ID3D11Resource
|
|
||||||
{
|
|
||||||
};*/
|
|
||||||
|
|
||||||
struct type_align(4) GfxLightGridEntry
|
struct type_align(4) GfxLightGridEntry
|
||||||
{
|
{
|
||||||
uint16_t colorsIndex;
|
uint16_t colorsIndex;
|
||||||
@@ -5740,9 +5768,13 @@ namespace T6
|
|||||||
STREAM_SRC_TEXCOORD_0 = 0x2,
|
STREAM_SRC_TEXCOORD_0 = 0x2,
|
||||||
STREAM_SRC_NORMAL = 0x3,
|
STREAM_SRC_NORMAL = 0x3,
|
||||||
STREAM_SRC_TANGENT = 0x4,
|
STREAM_SRC_TANGENT = 0x4,
|
||||||
STREAM_SRC_TEXCOORD_1 = 0x5,
|
|
||||||
STREAM_SRC_OPTIONAL_BEGIN = 0x6,
|
|
||||||
STREAM_SRC_PRE_OPTIONAL_BEGIN = 0x5,
|
STREAM_SRC_PRE_OPTIONAL_BEGIN = 0x5,
|
||||||
|
|
||||||
|
STREAM_SRC_TEXCOORD_1 = 0x5,
|
||||||
|
|
||||||
|
STREAM_SRC_OPTIONAL_BEGIN = 0x6,
|
||||||
|
|
||||||
STREAM_SRC_TEXCOORD_2 = 0x6,
|
STREAM_SRC_TEXCOORD_2 = 0x6,
|
||||||
STREAM_SRC_TEXCOORD_3 = 0x7,
|
STREAM_SRC_TEXCOORD_3 = 0x7,
|
||||||
STREAM_SRC_NORMAL_TRANSFORM_0 = 0x8,
|
STREAM_SRC_NORMAL_TRANSFORM_0 = 0x8,
|
||||||
@@ -5780,8 +5812,8 @@ namespace T6
|
|||||||
|
|
||||||
struct MaterialStreamRouting
|
struct MaterialStreamRouting
|
||||||
{
|
{
|
||||||
char source;
|
unsigned char source;
|
||||||
char dest;
|
unsigned char dest;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialVertexStreamRouting
|
struct MaterialVertexStreamRouting
|
||||||
@@ -5792,7 +5824,7 @@ namespace T6
|
|||||||
|
|
||||||
struct MaterialVertexDeclaration
|
struct MaterialVertexDeclaration
|
||||||
{
|
{
|
||||||
char streamCount;
|
unsigned char streamCount;
|
||||||
bool hasOptionalSource;
|
bool hasOptionalSource;
|
||||||
bool isLoaded;
|
bool isLoaded;
|
||||||
MaterialVertexStreamRouting routing;
|
MaterialVertexStreamRouting routing;
|
||||||
@@ -6147,8 +6179,8 @@ namespace T6
|
|||||||
struct MaterialArgumentCodeConst
|
struct MaterialArgumentCodeConst
|
||||||
{
|
{
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
char firstRow;
|
unsigned char firstRow;
|
||||||
char rowCount;
|
unsigned char rowCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
union MaterialArgumentDef
|
union MaterialArgumentDef
|
||||||
@@ -6159,24 +6191,29 @@ namespace T6
|
|||||||
unsigned int nameHash;
|
unsigned int nameHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MaterialShaderArgumentType
|
enum MaterialShaderArgumentType : uint16_t
|
||||||
{
|
{
|
||||||
MTL_ARG_MATERIAL_VERTEX_CONST = 0x0,
|
MTL_ARG_MATERIAL_VERTEX_CONST = 0x0,
|
||||||
MTL_ARG_LITERAL_VERTEX_CONST = 0x1,
|
MTL_ARG_LITERAL_VERTEX_CONST = 0x1,
|
||||||
MTL_ARG_MATERIAL_PIXEL_SAMPLER = 0x2,
|
MTL_ARG_MATERIAL_PIXEL_SAMPLER = 0x2,
|
||||||
|
|
||||||
MTL_ARG_CODE_PRIM_BEGIN = 0x3,
|
MTL_ARG_CODE_PRIM_BEGIN = 0x3,
|
||||||
|
|
||||||
MTL_ARG_CODE_VERTEX_CONST = 0x3,
|
MTL_ARG_CODE_VERTEX_CONST = 0x3,
|
||||||
MTL_ARG_CODE_PIXEL_SAMPLER = 0x4,
|
MTL_ARG_CODE_PIXEL_SAMPLER = 0x4,
|
||||||
MTL_ARG_CODE_PIXEL_CONST = 0x5,
|
MTL_ARG_CODE_PIXEL_CONST = 0x5,
|
||||||
|
|
||||||
MTL_ARG_CODE_PRIM_END = 0x6,
|
MTL_ARG_CODE_PRIM_END = 0x6,
|
||||||
|
|
||||||
MTL_ARG_MATERIAL_PIXEL_CONST = 0x6,
|
MTL_ARG_MATERIAL_PIXEL_CONST = 0x6,
|
||||||
MTL_ARG_LITERAL_PIXEL_CONST = 0x7,
|
MTL_ARG_LITERAL_PIXEL_CONST = 0x7,
|
||||||
MLT_ARG_COUNT = 0x8,
|
|
||||||
|
MLT_ARG_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialShaderArgument
|
struct MaterialShaderArgument
|
||||||
{
|
{
|
||||||
uint16_t type;
|
MaterialShaderArgumentType type;
|
||||||
MaterialArgumentLocation location;
|
MaterialArgumentLocation location;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint16_t buffer;
|
uint16_t buffer;
|
||||||
@@ -6882,10 +6919,6 @@ namespace T6
|
|||||||
vec3_t halfLengths;
|
vec3_t halfLengths;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct __cppobj ID3D11InputLayout : ID3D11DeviceChild
|
|
||||||
{
|
|
||||||
};*/
|
|
||||||
|
|
||||||
struct GfxLightRegionAxis
|
struct GfxLightRegionAxis
|
||||||
{
|
{
|
||||||
vec3_t dir;
|
vec3_t dir;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include "Game/IW4/CommonIW4.h"
|
#include "Game/IW4/CommonIW4.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "StateMap/StateMapLayout.h"
|
#include "Techset/CommonTechset.h"
|
||||||
|
#include "Techset/StateMap/StateMapLayout.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
inline const char* techniqueTypeNames[]{
|
static inline const char* techniqueTypeNames[]{
|
||||||
"depth prepass",
|
"depth prepass",
|
||||||
"build floatz",
|
"build floatz",
|
||||||
"build shadowmap depth",
|
"build shadowmap depth",
|
||||||
@@ -60,8 +61,9 @@ namespace IW4
|
|||||||
"debug bumpmap instanced",
|
"debug bumpmap instanced",
|
||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(techniqueTypeNames)> == TECHNIQUE_COUNT);
|
static_assert(std::extent_v<decltype(techniqueTypeNames)> == TECHNIQUE_COUNT);
|
||||||
|
static inline techset::CommonTechniqueTypeNames commonTechniqueTypeNames(techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
|
||||||
|
|
||||||
static const char* materialStreamDestinationNames[]{
|
static inline const char* materialStreamDestinationNames[]{
|
||||||
"position",
|
"position",
|
||||||
"normal",
|
"normal",
|
||||||
"color[0]",
|
"color[0]",
|
||||||
@@ -78,7 +80,7 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(materialStreamDestinationNames)> == STREAM_DST_COUNT);
|
static_assert(std::extent_v<decltype(materialStreamDestinationNames)> == STREAM_DST_COUNT);
|
||||||
|
|
||||||
static const char* materialStreamDestinationAbbreviation[]{
|
static inline const char* materialStreamDestinationAbbreviation[]{
|
||||||
"p",
|
"p",
|
||||||
"n",
|
"n",
|
||||||
"c0",
|
"c0",
|
||||||
@@ -95,7 +97,7 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(materialStreamDestinationAbbreviation)> == STREAM_DST_COUNT);
|
static_assert(std::extent_v<decltype(materialStreamDestinationAbbreviation)> == STREAM_DST_COUNT);
|
||||||
|
|
||||||
static const char* materialStreamSourceNames[]{
|
static inline const char* materialStreamSourceNames[]{
|
||||||
"position",
|
"position",
|
||||||
"color",
|
"color",
|
||||||
"texcoord[0]",
|
"texcoord[0]",
|
||||||
@@ -108,7 +110,7 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(materialStreamSourceNames)> == STREAM_SRC_COUNT);
|
static_assert(std::extent_v<decltype(materialStreamSourceNames)> == STREAM_SRC_COUNT);
|
||||||
|
|
||||||
static const char* materialStreamSourceAbbreviation[]{
|
static inline const char* materialStreamSourceAbbreviation[]{
|
||||||
"p",
|
"p",
|
||||||
"c",
|
"c",
|
||||||
"t0",
|
"t0",
|
||||||
@@ -121,18 +123,18 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(materialStreamSourceAbbreviation)> == STREAM_SRC_COUNT);
|
static_assert(std::extent_v<decltype(materialStreamSourceAbbreviation)> == STREAM_SRC_COUNT);
|
||||||
|
|
||||||
inline CodeSamplerSource s_lightmapSamplers[]{
|
static inline CodeSamplerSource s_lightmapSamplers[]{
|
||||||
{"primary", TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY, nullptr, 0, 0},
|
{"primary", TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY, nullptr, 0, 0},
|
||||||
{"secondary", TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY, nullptr, 0, 0},
|
{"secondary", TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY, nullptr, 0, 0},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeSamplerSource s_lightSamplers[]{
|
static inline CodeSamplerSource s_lightSamplers[]{
|
||||||
{"attenuation", TEXTURE_SRC_CODE_LIGHT_ATTENUATION, nullptr, 0, 0},
|
{"attenuation", TEXTURE_SRC_CODE_LIGHT_ATTENUATION, nullptr, 0, 0},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeSamplerSource s_codeSamplers[]{
|
static inline CodeSamplerSource s_codeSamplers[]{
|
||||||
{"white", TEXTURE_SRC_CODE_WHITE, nullptr, 0, 0},
|
{"white", TEXTURE_SRC_CODE_WHITE, nullptr, 0, 0},
|
||||||
{"black", TEXTURE_SRC_CODE_BLACK, nullptr, 0, 0},
|
{"black", TEXTURE_SRC_CODE_BLACK, nullptr, 0, 0},
|
||||||
{"identityNormalMap", TEXTURE_SRC_CODE_IDENTITY_NORMAL_MAP, nullptr, 0, 0},
|
{"identityNormalMap", TEXTURE_SRC_CODE_IDENTITY_NORMAL_MAP, nullptr, 0, 0},
|
||||||
@@ -155,7 +157,7 @@ namespace IW4
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeSamplerSource s_defaultCodeSamplers[]{
|
static inline CodeSamplerSource s_defaultCodeSamplers[]{
|
||||||
{"shadowmapSamplerSun", TEXTURE_SRC_CODE_SHADOWMAP_SUN, nullptr, 0, 0},
|
{"shadowmapSamplerSun", TEXTURE_SRC_CODE_SHADOWMAP_SUN, nullptr, 0, 0},
|
||||||
{"shadowmapSamplerSpot", TEXTURE_SRC_CODE_SHADOWMAP_SPOT, nullptr, 0, 0},
|
{"shadowmapSamplerSpot", TEXTURE_SRC_CODE_SHADOWMAP_SPOT, nullptr, 0, 0},
|
||||||
{"feedbackSampler", TEXTURE_SRC_CODE_FEEDBACK, nullptr, 0, 0},
|
{"feedbackSampler", TEXTURE_SRC_CODE_FEEDBACK, nullptr, 0, 0},
|
||||||
@@ -177,7 +179,7 @@ namespace IW4
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeConstantSource s_sunConsts[]{
|
static inline CodeConstantSource s_sunConsts[]{
|
||||||
{"position", CONST_SRC_CODE_LIGHT_POSITION, nullptr, 0, 0},
|
{"position", CONST_SRC_CODE_LIGHT_POSITION, nullptr, 0, 0},
|
||||||
{"diffuse", CONST_SRC_CODE_LIGHT_DIFFUSE, nullptr, 0, 0},
|
{"diffuse", CONST_SRC_CODE_LIGHT_DIFFUSE, nullptr, 0, 0},
|
||||||
{"specular", CONST_SRC_CODE_LIGHT_SPECULAR, nullptr, 0, 0},
|
{"specular", CONST_SRC_CODE_LIGHT_SPECULAR, nullptr, 0, 0},
|
||||||
@@ -187,14 +189,14 @@ namespace IW4
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeConstantSource s_nearPlaneConsts[]{
|
static inline CodeConstantSource s_nearPlaneConsts[]{
|
||||||
{"org", CONST_SRC_CODE_NEARPLANE_ORG, nullptr, 0, 0},
|
{"org", CONST_SRC_CODE_NEARPLANE_ORG, nullptr, 0, 0},
|
||||||
{"dx", CONST_SRC_CODE_NEARPLANE_DX, nullptr, 0, 0},
|
{"dx", CONST_SRC_CODE_NEARPLANE_DX, nullptr, 0, 0},
|
||||||
{"dy", CONST_SRC_CODE_NEARPLANE_DY, nullptr, 0, 0},
|
{"dy", CONST_SRC_CODE_NEARPLANE_DY, nullptr, 0, 0},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeConstantSource s_codeConsts[]{
|
static inline CodeConstantSource s_codeConsts[]{
|
||||||
{"nearPlane", CONST_SRC_NONE, s_nearPlaneConsts, 0, 0},
|
{"nearPlane", CONST_SRC_NONE, s_nearPlaneConsts, 0, 0},
|
||||||
{"light", CONST_SRC_NONE, s_sunConsts, 0, 0},
|
{"light", CONST_SRC_NONE, s_sunConsts, 0, 0},
|
||||||
{"baseLightingCoords", CONST_SRC_CODE_BASE_LIGHTING_COORDS, nullptr, 0, 0},
|
{"baseLightingCoords", CONST_SRC_CODE_BASE_LIGHTING_COORDS, nullptr, 0, 0},
|
||||||
@@ -313,7 +315,7 @@ namespace IW4
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeConstantSource s_defaultCodeConsts[]{
|
static inline CodeConstantSource s_defaultCodeConsts[]{
|
||||||
{"nearPlaneOrg", CONST_SRC_CODE_NEARPLANE_ORG, nullptr, 0, 0},
|
{"nearPlaneOrg", CONST_SRC_CODE_NEARPLANE_ORG, nullptr, 0, 0},
|
||||||
{"nearPlaneDx", CONST_SRC_CODE_NEARPLANE_DX, nullptr, 0, 0},
|
{"nearPlaneDx", CONST_SRC_CODE_NEARPLANE_DX, nullptr, 0, 0},
|
||||||
{"nearPlaneDy", CONST_SRC_CODE_NEARPLANE_DY, nullptr, 0, 0},
|
{"nearPlaneDy", CONST_SRC_CODE_NEARPLANE_DY, nullptr, 0, 0},
|
||||||
@@ -328,7 +330,7 @@ namespace IW4
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline MaterialUpdateFrequency s_codeConstUpdateFreq[]{
|
static inline MaterialUpdateFrequency s_codeConstUpdateFreq[]{
|
||||||
MTL_UPDATE_RARELY, // LIGHT_POSITION
|
MTL_UPDATE_RARELY, // LIGHT_POSITION
|
||||||
MTL_UPDATE_RARELY, // LIGHT_DIFFUSE
|
MTL_UPDATE_RARELY, // LIGHT_DIFFUSE
|
||||||
MTL_UPDATE_RARELY, // LIGHT_SPECULAR
|
MTL_UPDATE_RARELY, // LIGHT_SPECULAR
|
||||||
@@ -464,7 +466,7 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(s_codeConstUpdateFreq)> == CONST_SRC_TOTAL_COUNT);
|
static_assert(std::extent_v<decltype(s_codeConstUpdateFreq)> == CONST_SRC_TOTAL_COUNT);
|
||||||
|
|
||||||
inline MaterialUpdateFrequency s_codeSamplerUpdateFreq[]{
|
static inline MaterialUpdateFrequency s_codeSamplerUpdateFreq[]{
|
||||||
MTL_UPDATE_RARELY, // BLACK
|
MTL_UPDATE_RARELY, // BLACK
|
||||||
MTL_UPDATE_RARELY, // WHITE
|
MTL_UPDATE_RARELY, // WHITE
|
||||||
MTL_UPDATE_RARELY, // IDENTITY_NORMAL_MAP
|
MTL_UPDATE_RARELY, // IDENTITY_NORMAL_MAP
|
||||||
@@ -495,14 +497,14 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(s_codeSamplerUpdateFreq)> == TEXTURE_SRC_CODE_COUNT);
|
static_assert(std::extent_v<decltype(s_codeSamplerUpdateFreq)> == TEXTURE_SRC_CODE_COUNT);
|
||||||
|
|
||||||
inline MaterialTextureSource g_customSamplerSrc[]{
|
static inline MaterialTextureSource g_customSamplerSrc[]{
|
||||||
TEXTURE_SRC_CODE_REFLECTION_PROBE, // CUSTOM_SAMPLER_REFLECTION_PROBE
|
TEXTURE_SRC_CODE_REFLECTION_PROBE, // CUSTOM_SAMPLER_REFLECTION_PROBE
|
||||||
TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY, // CUSTOM_SAMPLER_LIGHTMAP_PRIMARY
|
TEXTURE_SRC_CODE_LIGHTMAP_PRIMARY, // CUSTOM_SAMPLER_LIGHTMAP_PRIMARY
|
||||||
TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY, // CUSTOM_SAMPLER_LIGHTMAP_SECONDARY
|
TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY, // CUSTOM_SAMPLER_LIGHTMAP_SECONDARY
|
||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(g_customSamplerSrc)> == CUSTOM_SAMPLER_COUNT);
|
static_assert(std::extent_v<decltype(g_customSamplerSrc)> == CUSTOM_SAMPLER_COUNT);
|
||||||
|
|
||||||
inline MaterialTypeInfo g_materialTypeInfo[]{
|
static inline MaterialTypeInfo g_materialTypeInfo[]{
|
||||||
{"", "" },
|
{"", "" },
|
||||||
{"m/", "m_" },
|
{"m/", "m_" },
|
||||||
{"mc/", "mc_"},
|
{"mc/", "mc_"},
|
||||||
@@ -523,7 +525,7 @@ namespace IW4
|
|||||||
return std::make_pair(Common::R_HashString(name, 0u), KnownMaterialTextureMap{name, additionalPropertySuffix});
|
return std::make_pair(Common::R_HashString(name, 0u), KnownMaterialTextureMap{name, additionalPropertySuffix});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unordered_map knownTextureMaps{
|
static inline std::unordered_map knownTextureMaps{
|
||||||
MakeKnownTextureMap("colorMap", "Color"),
|
MakeKnownTextureMap("colorMap", "Color"),
|
||||||
MakeKnownTextureMap("colorMap0", "Color00"),
|
MakeKnownTextureMap("colorMap0", "Color00"),
|
||||||
MakeKnownTextureMap("colorMap1", "Color01"),
|
MakeKnownTextureMap("colorMap1", "Color01"),
|
||||||
@@ -538,7 +540,7 @@ namespace IW4
|
|||||||
return std::make_pair(Common::R_HashString(name, 0u), name);
|
return std::make_pair(Common::R_HashString(name, 0u), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unordered_map knownConstantNames{
|
static inline std::unordered_map knownConstantNames{
|
||||||
MakeKnownConstantName("distortionScale"),
|
MakeKnownConstantName("distortionScale"),
|
||||||
MakeKnownConstantName("eyeOffsetParms"),
|
MakeKnownConstantName("eyeOffsetParms"),
|
||||||
MakeKnownConstantName("falloffBeginColor"),
|
MakeKnownConstantName("falloffBeginColor"),
|
||||||
@@ -560,7 +562,7 @@ namespace IW4
|
|||||||
WIREFRAME
|
WIREFRAME
|
||||||
};
|
};
|
||||||
|
|
||||||
inline state_map::StateMapLayoutEntries stateMapEntryLayout({
|
static inline state_map::StateMapLayoutEntries stateMapEntryLayout({
|
||||||
{"alphaTest", 0, GFXS0_ATEST_MASK | GFXS0_ATEST_DISABLE, {"mtlAlphaTest"} },
|
{"alphaTest", 0, GFXS0_ATEST_MASK | GFXS0_ATEST_DISABLE, {"mtlAlphaTest"} },
|
||||||
{"blendFunc", 0, GFXS0_BLEND_RGB_MASK, {"mtlBlendOp", "mtlSrcBlend", "mtlDestBlend"} },
|
{"blendFunc", 0, GFXS0_BLEND_RGB_MASK, {"mtlBlendOp", "mtlSrcBlend", "mtlDestBlend"} },
|
||||||
{"separateAlphaBlendFunc", 0, GFXS0_BLEND_ALPHA_MASK, {"mtlBlendOpAlpha", "mtlSrcBlendAlpha", "mtlDestBlendAlpha"}},
|
{"separateAlphaBlendFunc", 0, GFXS0_BLEND_ALPHA_MASK, {"mtlBlendOpAlpha", "mtlSrcBlendAlpha", "mtlDestBlendAlpha"}},
|
||||||
@@ -598,7 +600,7 @@ namespace IW4
|
|||||||
} }
|
} }
|
||||||
});
|
});
|
||||||
|
|
||||||
inline state_map::StateMapLayoutVars stateMapVarLayout({
|
static inline state_map::StateMapLayoutVars stateMapVarLayout({
|
||||||
{"mtlAlphaTest",
|
{"mtlAlphaTest",
|
||||||
0, {
|
0, {
|
||||||
{"Always", GFXS0_ATEST_DISABLE},
|
{"Always", GFXS0_ATEST_DISABLE},
|
||||||
@@ -818,5 +820,5 @@ namespace IW4
|
|||||||
}},
|
}},
|
||||||
});
|
});
|
||||||
|
|
||||||
inline state_map::StateMapLayout stateMapLayout(std::extent_v<decltype(GfxStateBits::loadBits.raw)>, stateMapEntryLayout, stateMapVarLayout);
|
static inline state_map::StateMapLayout stateMapLayout(std::extent_v<decltype(GfxStateBits::loadBits.raw)>, stateMapEntryLayout, stateMapVarLayout);
|
||||||
} // namespace IW4
|
} // namespace IW4
|
||||||
|
|||||||
@@ -277,6 +277,11 @@ namespace T5
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(streamRoutingDestinations)> == STREAM_DST_COUNT);
|
static_assert(std::extent_v<decltype(streamRoutingDestinations)> == STREAM_DST_COUNT);
|
||||||
|
|
||||||
|
static inline techset::CommonStreamRoutingInfos commonRoutingInfos(streamRoutingSources,
|
||||||
|
std::extent_v<decltype(streamRoutingSources)>,
|
||||||
|
streamRoutingDestinations,
|
||||||
|
std::extent_v<decltype(streamRoutingDestinations)>);
|
||||||
|
|
||||||
static techset::CommonCodeConstSourceInfo commonCodeConstSources[]{
|
static techset::CommonCodeConstSourceInfo commonCodeConstSources[]{
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_LIGHT_POSITION,
|
.value = CONST_SRC_CODE_LIGHT_POSITION,
|
||||||
@@ -1734,6 +1739,28 @@ namespace T5
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// See MaterialShaderArgumentType
|
||||||
|
static inline techset::CommonShaderArgumentType commonArgumentTypes[]{
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_SAMPLER},
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::CODE_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST },
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(commonArgumentTypes)> == MLT_ARG_COUNT);
|
||||||
|
|
||||||
|
static inline techset::CommonCodeSourceInfos commonCodeSourceInfos(commonCodeConstSources,
|
||||||
|
std::extent_v<decltype(commonCodeConstSources)>,
|
||||||
|
commonCodeSamplerSources,
|
||||||
|
std::extent_v<decltype(commonCodeSamplerSources)>,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
commonArgumentTypes,
|
||||||
|
std::extent_v<decltype(commonArgumentTypes)>);
|
||||||
|
|
||||||
inline MaterialTypeInfo g_materialTypeInfo[]{
|
inline MaterialTypeInfo g_materialTypeInfo[]{
|
||||||
{"", "" },
|
{"", "" },
|
||||||
{"m/", "m_" },
|
{"m/", "m_" },
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Techset/CommonTechnique.h"
|
#include "Techset/CommonTechnique.h"
|
||||||
|
#include "Techset/CommonTechset.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
inline const char* techniqueTypeNames[]{
|
static inline const char* techniqueTypeNames[]{
|
||||||
"depth prepass",
|
"depth prepass",
|
||||||
"build shadowmap depth",
|
"build shadowmap depth",
|
||||||
"unlit",
|
"unlit",
|
||||||
@@ -44,8 +45,9 @@ namespace T6
|
|||||||
"debug performance",
|
"debug performance",
|
||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(techniqueTypeNames)> == TECHNIQUE_COUNT);
|
static_assert(std::extent_v<decltype(techniqueTypeNames)> == TECHNIQUE_COUNT);
|
||||||
|
static inline techset::CommonTechniqueTypeNames commonTechniqueTypeNames(techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
|
||||||
|
|
||||||
static techset::CommonStreamRoutingSourceInfo streamRoutingSources[]{
|
static inline techset::CommonStreamRoutingSourceInfo streamRoutingSources[]{
|
||||||
{
|
{
|
||||||
.name = "position",
|
.name = "position",
|
||||||
.abbreviation = "p",
|
.abbreviation = "p",
|
||||||
@@ -104,7 +106,7 @@ namespace T6
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(streamRoutingSources)> == STREAM_SRC_COUNT);
|
static_assert(std::extent_v<decltype(streamRoutingSources)> == STREAM_SRC_COUNT);
|
||||||
|
|
||||||
static techset::CommonStreamRoutingDestinationInfo streamRoutingDestinations[]{
|
static inline techset::CommonStreamRoutingDestinationInfo streamRoutingDestinations[]{
|
||||||
{
|
{
|
||||||
.name = "position",
|
.name = "position",
|
||||||
.abbreviation = "p",
|
.abbreviation = "p",
|
||||||
@@ -188,7 +190,12 @@ namespace T6
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(streamRoutingDestinations)> == STREAM_DST_COUNT);
|
static_assert(std::extent_v<decltype(streamRoutingDestinations)> == STREAM_DST_COUNT);
|
||||||
|
|
||||||
static techset::CommonCodeConstSourceInfo commonCodeConstSources[]{
|
static inline techset::CommonStreamRoutingInfos commonRoutingInfos(streamRoutingSources,
|
||||||
|
std::extent_v<decltype(streamRoutingSources)>,
|
||||||
|
streamRoutingDestinations,
|
||||||
|
std::extent_v<decltype(streamRoutingDestinations)>);
|
||||||
|
|
||||||
|
static inline techset::CommonCodeConstSourceInfo commonCodeConstSources[]{
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_LIGHT_POSITION,
|
.value = CONST_SRC_CODE_LIGHT_POSITION,
|
||||||
.accessor = "lightPosition",
|
.accessor = "lightPosition",
|
||||||
@@ -212,6 +219,7 @@ namespace T6
|
|||||||
.accessor = "lightSpotFactors",
|
.accessor = "lightSpotFactors",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_10,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_LIGHT_ATTENUATION,
|
.value = CONST_SRC_CODE_LIGHT_ATTENUATION,
|
||||||
@@ -542,6 +550,7 @@ namespace T6
|
|||||||
.accessor = "particleCloudVelWorld",
|
.accessor = "particleCloudVelWorld",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_DEPTH_FROM_CLIP,
|
.value = CONST_SRC_CODE_DEPTH_FROM_CLIP,
|
||||||
@@ -1322,196 +1331,228 @@ namespace T6
|
|||||||
.accessor = "worldMatrix",
|
.accessor = "worldMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_WORLD_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_WORLD_MATRIX,
|
||||||
.accessor = "inverseWorldMatrix",
|
.accessor = "inverseWorldMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX,
|
||||||
.accessor = "transposeWorldMatrix",
|
.accessor = "transposeWorldMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX,
|
||||||
.accessor = "inverseTransposeWorldMatrix",
|
.accessor = "inverseTransposeWorldMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_VIEW_MATRIX,
|
||||||
.accessor = "viewMatrix",
|
.accessor = "viewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_VIEW_MATRIX,
|
||||||
.accessor = "inverseViewMatrix",
|
.accessor = "inverseViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX,
|
||||||
.accessor = "transposeViewMatrix",
|
.accessor = "transposeViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX,
|
||||||
.accessor = "inverseTransposeViewMatrix",
|
.accessor = "inverseTransposeViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_PROJECTION_MATRIX,
|
||||||
.accessor = "projectionMatrix",
|
.accessor = "projectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseProjectionMatrix",
|
.accessor = "inverseProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX,
|
||||||
.accessor = "transposeProjectionMatrix",
|
.accessor = "transposeProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseTransposeProjectionMatrix",
|
.accessor = "inverseTransposeProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_WORLD_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_WORLD_VIEW_MATRIX,
|
||||||
.accessor = "worldViewMatrix",
|
.accessor = "worldViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX,
|
||||||
.accessor = "inverseWorldViewMatrix",
|
.accessor = "inverseWorldViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
||||||
.accessor = "transposeWorldViewMatrix",
|
.accessor = "transposeWorldViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_WORLD_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX,
|
||||||
.accessor = "inverseTransposeWorldViewMatrix",
|
.accessor = "inverseTransposeWorldViewMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "viewProjectionMatrix",
|
.accessor = "viewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseViewProjectionMatrix",
|
.accessor = "inverseViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "transposeViewProjectionMatrix",
|
.accessor = "transposeViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseTransposeViewProjectionMatrix",
|
.accessor = "inverseTransposeViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_OBJECT,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "worldViewProjectionMatrix",
|
.accessor = "worldViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseWorldViewProjectionMatrix",
|
.accessor = "inverseWorldViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "transposeWorldViewProjectionMatrix",
|
.accessor = "transposeWorldViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
.accessor = "inverseTransposeWorldViewProjectionMatrix",
|
.accessor = "inverseTransposeWorldViewProjectionMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX,
|
||||||
.accessor = "shadowLookupMatrix",
|
.accessor = "shadowLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX,
|
||||||
.accessor = "inverseShadowLookupMatrix",
|
.accessor = "inverseShadowLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
||||||
.accessor = "transposeShadowLookupMatrix",
|
.accessor = "transposeShadowLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX,
|
||||||
.accessor = "inverseTransposeShadowLookupMatrix",
|
.accessor = "inverseTransposeShadowLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
.accessor = "worldOutdoorLookupMatrix",
|
.accessor = "worldOutdoorLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
.accessor = "inverseWorldOutdoorLookupMatrix",
|
.accessor = "inverseWorldOutdoorLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
.accessor = "transposeWorldOutdoorLookupMatrix",
|
.accessor = "transposeWorldOutdoorLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
.value = CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
.accessor = "inverseTransposeWorldOutdoorLookupMatrix",
|
.accessor = "inverseTransposeWorldOutdoorLookupMatrix",
|
||||||
.arrayCount = 0,
|
.arrayCount = 0,
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::PER_PRIM,
|
||||||
|
.transposedMatrix = CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static techset::CommonCodeSamplerSourceInfo commonCodeSamplerSources[]{
|
static inline techset::CommonCodeSamplerSourceInfo commonCodeSamplerSources[]{
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_BLACK,
|
.value = TEXTURE_SRC_CODE_BLACK,
|
||||||
.accessor = "black",
|
.accessor = "black",
|
||||||
@@ -1541,6 +1582,7 @@ namespace T6
|
|||||||
.value = TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY,
|
.value = TEXTURE_SRC_CODE_LIGHTMAP_SECONDARY,
|
||||||
.accessor = "lightmapSamplerSecondary",
|
.accessor = "lightmapSamplerSecondary",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM,
|
||||||
|
.customSamplerIndex = CUSTOM_SAMPLER_LIGHTMAP_SECONDARY,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_SHADOWMAP_SUN,
|
.value = TEXTURE_SRC_CODE_SHADOWMAP_SUN,
|
||||||
@@ -1561,11 +1603,13 @@ namespace T6
|
|||||||
.value = TEXTURE_SRC_CODE_RESOLVED_POST_SUN,
|
.value = TEXTURE_SRC_CODE_RESOLVED_POST_SUN,
|
||||||
.accessor = "resolvedPostSun",
|
.accessor = "resolvedPostSun",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_RESOLVED_SCENE,
|
.value = TEXTURE_SRC_CODE_RESOLVED_SCENE,
|
||||||
.accessor = "resolvedScene",
|
.accessor = "resolvedScene",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_POST_EFFECT_SRC,
|
.value = TEXTURE_SRC_CODE_POST_EFFECT_SRC,
|
||||||
@@ -1606,16 +1650,19 @@ namespace T6
|
|||||||
.value = TEXTURE_SRC_CODE_FLOATZ,
|
.value = TEXTURE_SRC_CODE_FLOATZ,
|
||||||
.accessor = "floatZSampler",
|
.accessor = "floatZSampler",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_40,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_PROCESSED_FLOATZ,
|
.value = TEXTURE_SRC_CODE_PROCESSED_FLOATZ,
|
||||||
.accessor = "processedFloatZSampler",
|
.accessor = "processedFloatZSampler",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_40,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_RAW_FLOATZ,
|
.value = TEXTURE_SRC_CODE_RAW_FLOATZ,
|
||||||
.accessor = "rawFloatZSampler",
|
.accessor = "rawFloatZSampler",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::RARELY,
|
||||||
|
.techFlags = TECHNIQUE_FLAG_40,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_STENCIL,
|
.value = TEXTURE_SRC_CODE_STENCIL,
|
||||||
@@ -1646,6 +1693,7 @@ namespace T6
|
|||||||
.value = TEXTURE_SRC_CODE_REFLECTION_PROBE,
|
.value = TEXTURE_SRC_CODE_REFLECTION_PROBE,
|
||||||
.accessor = "reflectionProbeSampler",
|
.accessor = "reflectionProbeSampler",
|
||||||
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM,
|
.updateFrequency = techset::CommonCodeSourceUpdateFrequency::CUSTOM,
|
||||||
|
.customSamplerIndex = CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.value = TEXTURE_SRC_CODE_FEATHER_FLOAT_Z,
|
.value = TEXTURE_SRC_CODE_FEATHER_FLOAT_Z,
|
||||||
@@ -1789,7 +1837,34 @@ namespace T6
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline MaterialTypeInfo g_materialTypeInfo[]{
|
// See MaterialShaderArgumentType
|
||||||
|
static inline techset::CommonShaderArgumentType commonArgumentTypes[]{
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_SAMPLER},
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::VERTEX, .m_value_type = techset::CommonShaderValueType::CODE_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_SAMPLER },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::CODE_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::MATERIAL_CONST },
|
||||||
|
{.m_shader_type = techset::CommonTechniqueShaderType::PIXEL, .m_value_type = techset::CommonShaderValueType::LITERAL_CONST },
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(commonArgumentTypes)> == MLT_ARG_COUNT);
|
||||||
|
|
||||||
|
static inline const char* commonIgnoredArgAccessors[]{
|
||||||
|
"combined_dlight",
|
||||||
|
"combined_glight",
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline techset::CommonCodeSourceInfos commonCodeSourceInfos(commonCodeConstSources,
|
||||||
|
std::extent_v<decltype(commonCodeConstSources)>,
|
||||||
|
commonCodeSamplerSources,
|
||||||
|
std::extent_v<decltype(commonCodeSamplerSources)>,
|
||||||
|
commonIgnoredArgAccessors,
|
||||||
|
std::extent_v<decltype(commonIgnoredArgAccessors)>,
|
||||||
|
commonArgumentTypes,
|
||||||
|
std::extent_v<decltype(commonArgumentTypes)>);
|
||||||
|
|
||||||
|
static inline MaterialTypeInfo g_materialTypeInfo[]{
|
||||||
{"", "" },
|
{"", "" },
|
||||||
{"m/", "m_" },
|
{"m/", "m_" },
|
||||||
{"mc/", "mc_" },
|
{"mc/", "mc_" },
|
||||||
|
|||||||
@@ -29,7 +29,12 @@ namespace d3d11
|
|||||||
ConstantBufferVariable::ConstantBufferVariable()
|
ConstantBufferVariable::ConstantBufferVariable()
|
||||||
: m_offset(0u),
|
: m_offset(0u),
|
||||||
m_size(0u),
|
m_size(0u),
|
||||||
m_flags(0u)
|
m_flags(0u),
|
||||||
|
m_is_used(false),
|
||||||
|
m_variable_class(VariableClass::UNKNOWN),
|
||||||
|
m_element_count(0),
|
||||||
|
m_row_count(0),
|
||||||
|
m_column_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
} // namespace d3d11
|
} // namespace d3d11
|
||||||
@@ -39,9 +44,6 @@ namespace
|
|||||||
constexpr auto TAG_RDEF = FileUtils::MakeMagic32('R', 'D', 'E', 'F');
|
constexpr auto TAG_RDEF = FileUtils::MakeMagic32('R', 'D', 'E', 'F');
|
||||||
constexpr auto TAG_SHDR = FileUtils::MakeMagic32('S', 'H', 'D', 'R');
|
constexpr auto TAG_SHDR = FileUtils::MakeMagic32('S', 'H', 'D', 'R');
|
||||||
|
|
||||||
constexpr auto VERSION_5_0 = 0x500;
|
|
||||||
constexpr auto VERSION_5_1 = 0x501;
|
|
||||||
constexpr auto TARGET_VERSION_MASK = 0xFFFF;
|
|
||||||
constexpr auto CHUNK_TABLE_OFFSET = 28u;
|
constexpr auto CHUNK_TABLE_OFFSET = 28u;
|
||||||
|
|
||||||
struct FileRdefHeader
|
struct FileRdefHeader
|
||||||
@@ -50,7 +52,9 @@ namespace
|
|||||||
uint32_t constantBufferOffset;
|
uint32_t constantBufferOffset;
|
||||||
uint32_t boundResourceCount;
|
uint32_t boundResourceCount;
|
||||||
uint32_t boundResourceOffset;
|
uint32_t boundResourceOffset;
|
||||||
uint32_t target;
|
uint8_t minorVersion;
|
||||||
|
uint8_t majorVersion;
|
||||||
|
uint16_t type;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t creatorOffset;
|
uint32_t creatorOffset;
|
||||||
};
|
};
|
||||||
@@ -172,6 +176,17 @@ namespace
|
|||||||
D3D11_SRV_DIMENSION_BUFFEREX
|
D3D11_SRV_DIMENSION_BUFFEREX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_shader_input_flags
|
||||||
|
enum D3D_SHADER_INPUT_FLAGS
|
||||||
|
{
|
||||||
|
D3D_SIF_USERPACKED = 0x1,
|
||||||
|
D3D_SIF_COMPARISON_SAMPLER = 0x2,
|
||||||
|
D3D_SIF_TEXTURE_COMPONENT_0 = 0x4,
|
||||||
|
D3D_SIF_TEXTURE_COMPONENT_1 = 0x8,
|
||||||
|
D3D_SIF_TEXTURE_COMPONENTS = 0xc,
|
||||||
|
D3D_SIF_UNUSED = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
struct FileBoundResource
|
struct FileBoundResource
|
||||||
{
|
{
|
||||||
uint32_t nameOffset;
|
uint32_t nameOffset;
|
||||||
@@ -181,7 +196,7 @@ namespace
|
|||||||
uint32_t numSamples;
|
uint32_t numSamples;
|
||||||
uint32_t bindPoint;
|
uint32_t bindPoint;
|
||||||
uint32_t bindCount;
|
uint32_t bindCount;
|
||||||
uint32_t uFlags;
|
uint32_t uFlags; // D3D_SHADER_INPUT_FLAGS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileBoundResource_5_1 : FileBoundResource
|
struct FileBoundResource_5_1 : FileBoundResource
|
||||||
@@ -218,6 +233,15 @@ namespace
|
|||||||
D3D_CBUFFER_TYPE type;
|
D3D_CBUFFER_TYPE type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_shader_variable_flags
|
||||||
|
enum D3D_SHADER_VARIABLE_FLAGS
|
||||||
|
{
|
||||||
|
D3D_SVF_USERPACKED = 1,
|
||||||
|
D3D_SVF_USED = 2,
|
||||||
|
D3D_SVF_INTERFACE_POINTER = 4,
|
||||||
|
D3D_SVF_INTERFACE_PARAMETER = 8,
|
||||||
|
};
|
||||||
|
|
||||||
struct FileConstantBufferVariable
|
struct FileConstantBufferVariable
|
||||||
{
|
{
|
||||||
uint32_t nameOffset;
|
uint32_t nameOffset;
|
||||||
@@ -230,13 +254,46 @@ namespace
|
|||||||
|
|
||||||
struct FileConstantBufferVariable_5_0 : FileConstantBufferVariable
|
struct FileConstantBufferVariable_5_0 : FileConstantBufferVariable
|
||||||
{
|
{
|
||||||
// Wine project does not seem to know what this is
|
uint32_t resourceBinding;
|
||||||
uint32_t unknown[4];
|
uint32_t resourceCount;
|
||||||
|
uint32_t samplerBinding;
|
||||||
|
uint32_t samplerCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(FileConstantBufferVariable) == 24);
|
static_assert(sizeof(FileConstantBufferVariable) == 24);
|
||||||
static_assert(sizeof(FileConstantBufferVariable_5_0) == 40);
|
static_assert(sizeof(FileConstantBufferVariable_5_0) == 40);
|
||||||
|
|
||||||
|
enum D3D_SHADER_VARIABLE_CLASS : uint16_t
|
||||||
|
{
|
||||||
|
D3D_SVC_SCALAR = 0,
|
||||||
|
D3D_SVC_VECTOR,
|
||||||
|
D3D_SVC_MATRIX_ROWS,
|
||||||
|
D3D_SVC_MATRIX_COLUMNS,
|
||||||
|
D3D_SVC_OBJECT,
|
||||||
|
D3D_SVC_STRUCT,
|
||||||
|
D3D_SVC_INTERFACE_CLASS,
|
||||||
|
D3D_SVC_INTERFACE_POINTER,
|
||||||
|
D3D10_SVC_SCALAR,
|
||||||
|
D3D10_SVC_VECTOR,
|
||||||
|
D3D10_SVC_MATRIX_ROWS,
|
||||||
|
D3D10_SVC_MATRIX_COLUMNS,
|
||||||
|
D3D10_SVC_OBJECT,
|
||||||
|
D3D10_SVC_STRUCT,
|
||||||
|
D3D11_SVC_INTERFACE_CLASS,
|
||||||
|
D3D11_SVC_INTERFACE_POINTER
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FileRdefType
|
||||||
|
{
|
||||||
|
D3D_SHADER_VARIABLE_CLASS class_;
|
||||||
|
uint16_t baseType;
|
||||||
|
uint16_t rowCount;
|
||||||
|
uint16_t columnCount;
|
||||||
|
uint16_t elementCount;
|
||||||
|
uint16_t fieldCount;
|
||||||
|
uint32_t fieldsOffset;
|
||||||
|
};
|
||||||
|
|
||||||
enum FileProgramType : uint32_t
|
enum FileProgramType : uint32_t
|
||||||
{
|
{
|
||||||
D3D10_SB_PIXEL_SHADER = 0,
|
D3D10_SB_PIXEL_SHADER = 0,
|
||||||
@@ -261,6 +318,16 @@ namespace
|
|||||||
|
|
||||||
static_assert(sizeof(FileShaderHeader) == 4);
|
static_assert(sizeof(FileShaderHeader) == 4);
|
||||||
|
|
||||||
|
constexpr bool IsAtLeastVersion(const uint8_t expectedMajor, const uint8_t expectedMinor, const uint8_t actualMajor, const uint8_t actualMinor)
|
||||||
|
{
|
||||||
|
if (actualMajor < expectedMajor)
|
||||||
|
return false;
|
||||||
|
if (actualMinor < expectedMinor)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ReadU32(const uint8_t*& ptr)
|
uint32_t ReadU32(const uint8_t*& ptr)
|
||||||
{
|
{
|
||||||
const auto result = *reinterpret_cast<const uint32_t*>(ptr);
|
const auto result = *reinterpret_cast<const uint32_t*>(ptr);
|
||||||
@@ -451,6 +518,39 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariableClass GetVariableClass(const D3D_SHADER_VARIABLE_CLASS variableClass)
|
||||||
|
{
|
||||||
|
switch (variableClass)
|
||||||
|
{
|
||||||
|
case D3D_SVC_SCALAR:
|
||||||
|
case D3D10_SVC_SCALAR:
|
||||||
|
return VariableClass::SCALAR;
|
||||||
|
case D3D_SVC_VECTOR:
|
||||||
|
case D3D10_SVC_VECTOR:
|
||||||
|
return VariableClass::VECTOR;
|
||||||
|
case D3D_SVC_MATRIX_ROWS:
|
||||||
|
case D3D10_SVC_MATRIX_ROWS:
|
||||||
|
return VariableClass::MATRIX_ROWS;
|
||||||
|
case D3D_SVC_MATRIX_COLUMNS:
|
||||||
|
case D3D10_SVC_MATRIX_COLUMNS:
|
||||||
|
return VariableClass::MATRIX_COLUMNS;
|
||||||
|
case D3D_SVC_OBJECT:
|
||||||
|
case D3D10_SVC_OBJECT:
|
||||||
|
return VariableClass::OBJECT;
|
||||||
|
case D3D_SVC_STRUCT:
|
||||||
|
case D3D10_SVC_STRUCT:
|
||||||
|
return VariableClass::STRUCT;
|
||||||
|
case D3D_SVC_INTERFACE_CLASS:
|
||||||
|
case D3D11_SVC_INTERFACE_CLASS:
|
||||||
|
return VariableClass::INTERFACE_CLASS;
|
||||||
|
case D3D_SVC_INTERFACE_POINTER:
|
||||||
|
case D3D11_SVC_INTERFACE_POINTER:
|
||||||
|
return VariableClass::INTERFACE_POINTER;
|
||||||
|
default:
|
||||||
|
return VariableClass::UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PopulateConstantBufferVariable(ConstantBufferVariable& constantBufferVariable,
|
bool PopulateConstantBufferVariable(ConstantBufferVariable& constantBufferVariable,
|
||||||
const FileConstantBufferVariable& fileConstantBufferVariable,
|
const FileConstantBufferVariable& fileConstantBufferVariable,
|
||||||
const uint8_t* shaderByteCode,
|
const uint8_t* shaderByteCode,
|
||||||
@@ -467,6 +567,17 @@ namespace
|
|||||||
constantBufferVariable.m_offset = fileConstantBufferVariable.startOffset;
|
constantBufferVariable.m_offset = fileConstantBufferVariable.startOffset;
|
||||||
constantBufferVariable.m_size = fileConstantBufferVariable.size;
|
constantBufferVariable.m_size = fileConstantBufferVariable.size;
|
||||||
constantBufferVariable.m_flags = fileConstantBufferVariable.flags;
|
constantBufferVariable.m_flags = fileConstantBufferVariable.flags;
|
||||||
|
constantBufferVariable.m_is_used = fileConstantBufferVariable.flags & D3D_SVF_USED;
|
||||||
|
|
||||||
|
if (fileConstantBufferVariable.typeOffset + sizeof(FileRdefType) > chunkSize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto type = reinterpret_cast<const FileRdefType*>(shaderByteCode + chunkOffset + fileConstantBufferVariable.typeOffset);
|
||||||
|
|
||||||
|
constantBufferVariable.m_variable_class = GetVariableClass(type->class_);
|
||||||
|
constantBufferVariable.m_element_count = static_cast<uint16_t>(type->elementCount);
|
||||||
|
constantBufferVariable.m_column_count = static_cast<uint16_t>(type->columnCount);
|
||||||
|
constantBufferVariable.m_row_count = static_cast<uint16_t>(type->rowCount);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -500,7 +611,8 @@ namespace
|
|||||||
const size_t shaderByteCodeSize,
|
const size_t shaderByteCodeSize,
|
||||||
const size_t chunkOffset,
|
const size_t chunkOffset,
|
||||||
const size_t chunkSize,
|
const size_t chunkSize,
|
||||||
const unsigned targetVersion)
|
const uint8_t major,
|
||||||
|
const uint8_t minor)
|
||||||
{
|
{
|
||||||
const auto nameString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + fileConstantBuffer.nameOffset);
|
const auto nameString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + fileConstantBuffer.nameOffset);
|
||||||
|
|
||||||
@@ -513,10 +625,10 @@ namespace
|
|||||||
constantBuffer.m_flags = fileConstantBuffer.flags;
|
constantBuffer.m_flags = fileConstantBuffer.flags;
|
||||||
constantBuffer.m_type = GetType(fileConstantBuffer.type);
|
constantBuffer.m_type = GetType(fileConstantBuffer.type);
|
||||||
|
|
||||||
if (targetVersion < VERSION_5_0)
|
if (IsAtLeastVersion(5, 0, major, minor))
|
||||||
{
|
{
|
||||||
const auto* variables = reinterpret_cast<const FileConstantBufferVariable*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
const auto* variables = reinterpret_cast<const FileConstantBufferVariable_5_0*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
||||||
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable) * fileConstantBuffer.variableCount > chunkSize)
|
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable_5_0) * fileConstantBuffer.variableCount > chunkSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
||||||
@@ -532,8 +644,8 @@ namespace
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto* variables = reinterpret_cast<const FileConstantBufferVariable_5_0*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
const auto* variables = reinterpret_cast<const FileConstantBufferVariable*>(shaderByteCode + chunkOffset + fileConstantBuffer.variableOffset);
|
||||||
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable_5_0) * fileConstantBuffer.variableCount > chunkSize)
|
if (fileConstantBuffer.variableOffset + sizeof(FileConstantBufferVariable) * fileConstantBuffer.variableCount > chunkSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
for (auto variableIndex = 0u; variableIndex < fileConstantBuffer.variableCount; variableIndex++)
|
||||||
@@ -562,7 +674,6 @@ namespace
|
|||||||
|
|
||||||
const auto* header = reinterpret_cast<const FileRdefHeader*>(shaderByteCode + chunkOffset);
|
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);
|
const auto creatorString = reinterpret_cast<const char*>(shaderByteCode + chunkOffset + header->creatorOffset);
|
||||||
|
|
||||||
if (!StringFitsInChunk(creatorString, shaderByteCode, shaderByteCodeSize))
|
if (!StringFitsInChunk(creatorString, shaderByteCode, shaderByteCodeSize))
|
||||||
@@ -570,23 +681,7 @@ namespace
|
|||||||
|
|
||||||
shaderInfo.m_creator = std::string(creatorString);
|
shaderInfo.m_creator = std::string(creatorString);
|
||||||
|
|
||||||
if (targetVersion < VERSION_5_1)
|
if (IsAtLeastVersion(5, 1, header->majorVersion, header->minorVersion))
|
||||||
{
|
|
||||||
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);
|
const auto* boundResources = reinterpret_cast<const FileBoundResource_5_1*>(shaderByteCode + chunkOffset + header->boundResourceOffset);
|
||||||
if (header->boundResourceOffset + sizeof(FileBoundResource_5_1) * header->boundResourceCount > chunkSize)
|
if (header->boundResourceOffset + sizeof(FileBoundResource_5_1) * header->boundResourceCount > chunkSize)
|
||||||
@@ -603,6 +698,22 @@ namespace
|
|||||||
shaderInfo.m_bound_resources.emplace_back(std::move(boundResource));
|
shaderInfo.m_bound_resources.emplace_back(std::move(boundResource));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto* constantBuffers = reinterpret_cast<const FileConstantBuffer*>(shaderByteCode + chunkOffset + header->constantBufferOffset);
|
const auto* constantBuffers = reinterpret_cast<const FileConstantBuffer*>(shaderByteCode + chunkOffset + header->constantBufferOffset);
|
||||||
if (header->constantBufferOffset + sizeof(FileConstantBuffer) * header->constantBufferCount > chunkSize)
|
if (header->constantBufferOffset + sizeof(FileConstantBuffer) * header->constantBufferCount > chunkSize)
|
||||||
@@ -613,7 +724,8 @@ namespace
|
|||||||
const auto& fileConstantBuffer = constantBuffers[constantBufferIndex];
|
const auto& fileConstantBuffer = constantBuffers[constantBufferIndex];
|
||||||
ConstantBuffer constantBuffer;
|
ConstantBuffer constantBuffer;
|
||||||
|
|
||||||
if (!PopulateConstantBuffer(constantBuffer, fileConstantBuffer, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize, targetVersion))
|
if (!PopulateConstantBuffer(
|
||||||
|
constantBuffer, fileConstantBuffer, shaderByteCode, shaderByteCodeSize, chunkOffset, chunkSize, header->majorVersion, header->minorVersion))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
shaderInfo.m_constant_buffers.emplace_back(std::move(constantBuffer));
|
shaderInfo.m_constant_buffers.emplace_back(std::move(constantBuffer));
|
||||||
@@ -684,5 +796,5 @@ std::unique_ptr<ShaderInfo> ShaderAnalyser::GetShaderInfo(const void* shader, co
|
|||||||
if (!PopulateShaderInfoFromBytes(*shaderInfo, static_cast<const uint8_t*>(shader), shaderSize))
|
if (!PopulateShaderInfoFromBytes(*shaderInfo, static_cast<const uint8_t*>(shader), shaderSize))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return shaderInfo;
|
return std::move(shaderInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,19 @@ namespace d3d11
|
|||||||
COMPUTE_SHADER
|
COMPUTE_SHADER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class VariableClass : std::uint8_t
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
SCALAR,
|
||||||
|
VECTOR,
|
||||||
|
MATRIX_ROWS,
|
||||||
|
MATRIX_COLUMNS,
|
||||||
|
OBJECT,
|
||||||
|
STRUCT,
|
||||||
|
INTERFACE_CLASS,
|
||||||
|
INTERFACE_POINTER
|
||||||
|
};
|
||||||
|
|
||||||
class ConstantBufferVariable
|
class ConstantBufferVariable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -32,6 +45,11 @@ namespace d3d11
|
|||||||
unsigned m_offset;
|
unsigned m_offset;
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_flags;
|
unsigned m_flags;
|
||||||
|
bool m_is_used;
|
||||||
|
VariableClass m_variable_class;
|
||||||
|
std::uint16_t m_element_count;
|
||||||
|
std::uint16_t m_row_count;
|
||||||
|
std::uint16_t m_column_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ConstantBufferType : std::uint8_t
|
enum class ConstantBufferType : std::uint8_t
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
#include "CommonTechnique.h"
|
#include "CommonTechnique.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
{
|
{
|
||||||
CommonCodeSourceInfos::CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
|
CommonCodeSourceInfos::CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
|
||||||
const size_t codeConstCount,
|
const size_t codeConstCount,
|
||||||
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
|
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
|
||||||
const size_t codeSamplerCount)
|
const size_t codeSamplerCount,
|
||||||
|
const char** ignoreArgAccessors,
|
||||||
|
const size_t ignoredArgAccessorCount,
|
||||||
|
const CommonShaderArgumentType* argumentTypes,
|
||||||
|
const size_t argumentTypeCount)
|
||||||
: m_code_const_source_infos(codeConstCount),
|
: m_code_const_source_infos(codeConstCount),
|
||||||
m_code_sampler_source_infos(codeSamplerCount)
|
m_code_sampler_source_infos(codeSamplerCount),
|
||||||
|
m_ignored_arg_accessors(ignoredArgAccessorCount),
|
||||||
|
m_argument_types(argumentTypeCount)
|
||||||
{
|
{
|
||||||
std::copy(codeConstSourceInfos, &codeConstSourceInfos[codeConstCount], m_code_const_source_infos.data());
|
std::copy(codeConstSourceInfos, &codeConstSourceInfos[codeConstCount], m_code_const_source_infos.data());
|
||||||
std::ranges::sort(m_code_const_source_infos,
|
std::ranges::sort(m_code_const_source_infos,
|
||||||
@@ -24,14 +31,30 @@ namespace techset
|
|||||||
{
|
{
|
||||||
return a.value < b.value;
|
return a.value < b.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ignoredArgAccessorCount; i++)
|
||||||
|
m_ignored_arg_accessors.emplace(ignoreArgAccessors[i]);
|
||||||
|
|
||||||
|
std::copy(argumentTypes, &argumentTypes[argumentTypeCount], m_argument_types.data());
|
||||||
|
|
||||||
|
for (const auto& codeConstInfo : m_code_const_source_infos)
|
||||||
|
{
|
||||||
|
m_code_const_lookup.emplace(codeConstInfo.accessor, codeConstInfo.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& codeSamplerInfo : m_code_sampler_source_infos)
|
||||||
|
{
|
||||||
|
m_code_sampler_lookup.emplace(codeSamplerInfo.accessor, codeSamplerInfo.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<CommonCodeConstSourceInfo> CommonCodeSourceInfos::GetInfoForCodeConstSource(const CommonCodeConstSource codeConstSource) const
|
std::optional<CommonCodeConstSourceInfo> CommonCodeSourceInfos::GetInfoForCodeConstSource(const CommonCodeConstSource codeConstSource) const
|
||||||
{
|
{
|
||||||
for (const auto& codeConstSourceInfo : m_code_const_source_infos)
|
for (const auto& codeConstSourceInfo : m_code_const_source_infos)
|
||||||
{
|
{
|
||||||
const auto codeConstSourceInfoEnd = static_cast<unsigned>(codeConstSourceInfo.value) + codeConstSourceInfo.arrayCount;
|
const auto arrayCount = std::max<uint8_t>(codeConstSourceInfo.arrayCount, 1);
|
||||||
if (codeConstSourceInfo.value <= codeConstSource && codeConstSourceInfoEnd >= codeConstSource)
|
const auto codeConstSourceInfoEnd = static_cast<unsigned>(codeConstSourceInfo.value) + arrayCount;
|
||||||
|
if (codeConstSourceInfo.value <= codeConstSource && codeConstSourceInfoEnd > codeConstSource)
|
||||||
return codeConstSourceInfo;
|
return codeConstSourceInfo;
|
||||||
|
|
||||||
if (codeConstSourceInfoEnd > codeConstSource)
|
if (codeConstSourceInfoEnd > codeConstSource)
|
||||||
@@ -55,6 +78,38 @@ namespace techset
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CommonCodeSourceInfos::IsArgAccessorIgnored(const std::string& accessor) const
|
||||||
|
{
|
||||||
|
return m_ignored_arg_accessors.contains(accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<CommonCodeConstSource> CommonCodeSourceInfos::GetCodeConstSourceForAccessor(const std::string& accessor) const
|
||||||
|
{
|
||||||
|
const auto foundEntry = m_code_const_lookup.find(accessor);
|
||||||
|
if (foundEntry == m_code_const_lookup.end())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return foundEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<CommonCodeSamplerSource> CommonCodeSourceInfos::GetCodeSamplerSourceForAccessor(const std::string& accessor) const
|
||||||
|
{
|
||||||
|
const auto foundEntry = m_code_sampler_lookup.find(accessor);
|
||||||
|
if (foundEntry == m_code_sampler_lookup.end())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return foundEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<size_t> CommonCodeSourceInfos::GetArgumentTypeNumericValue(const CommonShaderArgumentType& argumentType) const
|
||||||
|
{
|
||||||
|
const auto foundValue = std::ranges::find(m_argument_types, argumentType);
|
||||||
|
if (foundValue == m_argument_types.end())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return static_cast<size_t>(foundValue - m_argument_types.begin());
|
||||||
|
}
|
||||||
|
|
||||||
CommonStreamRoutingInfos::CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos,
|
CommonStreamRoutingInfos::CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos,
|
||||||
const size_t sourceCount,
|
const size_t sourceCount,
|
||||||
const CommonStreamRoutingDestinationInfo* destinationNames,
|
const CommonStreamRoutingDestinationInfo* destinationNames,
|
||||||
@@ -64,6 +119,18 @@ namespace techset
|
|||||||
{
|
{
|
||||||
std::copy(sourceInfos, &sourceInfos[sourceCount], m_sources.data());
|
std::copy(sourceInfos, &sourceInfos[sourceCount], m_sources.data());
|
||||||
std::copy(destinationNames, &destinationNames[destinationCount], m_destinations.data());
|
std::copy(destinationNames, &destinationNames[destinationCount], m_destinations.data());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sourceCount; i++)
|
||||||
|
{
|
||||||
|
m_source_name_lookup[sourceInfos[i].name] = static_cast<CommonStreamSource>(i);
|
||||||
|
m_source_abbreviation_lookup[sourceInfos[i].abbreviation] = static_cast<CommonStreamSource>(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < destinationCount; i++)
|
||||||
|
{
|
||||||
|
m_destination_name_lookup[destinationNames[i].name] = static_cast<CommonStreamDestination>(i);
|
||||||
|
m_destination_abbreviation_lookup[destinationNames[i].abbreviation] = static_cast<CommonStreamDestination>(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CommonStreamRoutingInfos::GetSourceName(const CommonStreamSource source) const
|
const char* CommonStreamRoutingInfos::GetSourceName(const CommonStreamSource source) const
|
||||||
@@ -105,4 +172,146 @@ namespace techset
|
|||||||
|
|
||||||
return m_destinations[destination].abbreviation;
|
return m_destinations[destination].abbreviation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<CommonStreamSource> CommonStreamRoutingInfos::GetSourceByName(const std::string& name) const
|
||||||
|
{
|
||||||
|
const auto foundSource = m_source_name_lookup.find(name);
|
||||||
|
if (foundSource != m_source_name_lookup.end())
|
||||||
|
return foundSource->second;
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<CommonStreamSource> CommonStreamRoutingInfos::GetSourceByAbbreviation(const std::string& abbreviation) const
|
||||||
|
{
|
||||||
|
const auto foundSource = m_source_abbreviation_lookup.find(abbreviation);
|
||||||
|
if (foundSource != m_source_abbreviation_lookup.end())
|
||||||
|
return foundSource->second;
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<CommonStreamDestination> CommonStreamRoutingInfos::GetDestinationByName(const std::string& name) const
|
||||||
|
{
|
||||||
|
const auto foundDestination = m_destination_name_lookup.find(name);
|
||||||
|
if (foundDestination != m_destination_name_lookup.end())
|
||||||
|
return foundDestination->second;
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<CommonStreamDestination> CommonStreamRoutingInfos::GetDestinationByAbbreviation(const std::string& abbreviation) const
|
||||||
|
{
|
||||||
|
const auto foundDestination = m_destination_abbreviation_lookup.find(abbreviation);
|
||||||
|
if (foundDestination != m_destination_abbreviation_lookup.end())
|
||||||
|
return foundDestination->second;
|
||||||
|
|
||||||
|
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)
|
||||||
|
: m_routing(std::move(routing))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonVertexDeclaration::SortRoutingEntries()
|
||||||
|
{
|
||||||
|
std::ranges::sort(m_routing,
|
||||||
|
[](const CommonStreamRouting& r1, const CommonStreamRouting& r2)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
std::string comment)
|
||||||
|
: 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)),
|
||||||
|
m_comment(std::move(comment))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
@@ -27,12 +30,46 @@ namespace techset
|
|||||||
const char* abbreviation;
|
const char* abbreviation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CommonTechniqueShaderType : std::uint8_t
|
||||||
|
{
|
||||||
|
VERTEX,
|
||||||
|
PIXEL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CommonShaderValueType : 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
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool IsConstValueType(const CommonShaderValueType valueType)
|
||||||
|
{
|
||||||
|
return valueType == CommonShaderValueType::LITERAL_CONST || valueType == CommonShaderValueType::MATERIAL_CONST
|
||||||
|
|| valueType == CommonShaderValueType::CODE_CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsSamplerValueType(const CommonShaderValueType valueType)
|
||||||
|
{
|
||||||
|
return valueType == CommonShaderValueType::MATERIAL_SAMPLER || valueType == CommonShaderValueType::CODE_SAMPLER;
|
||||||
|
}
|
||||||
|
|
||||||
enum class CommonCodeSourceUpdateFrequency : std::uint8_t
|
enum class CommonCodeSourceUpdateFrequency : std::uint8_t
|
||||||
{
|
{
|
||||||
PER_PRIM,
|
PER_PRIM,
|
||||||
PER_OBJECT,
|
PER_OBJECT,
|
||||||
RARELY,
|
RARELY,
|
||||||
CUSTOM,
|
CUSTOM,
|
||||||
|
IGNORE,
|
||||||
|
|
||||||
|
COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommonCodeConstSourceInfo
|
struct CommonCodeConstSourceInfo
|
||||||
@@ -41,6 +78,8 @@ namespace techset
|
|||||||
const char* accessor;
|
const char* accessor;
|
||||||
std::uint8_t arrayCount;
|
std::uint8_t arrayCount;
|
||||||
CommonCodeSourceUpdateFrequency updateFrequency;
|
CommonCodeSourceUpdateFrequency updateFrequency;
|
||||||
|
std::optional<unsigned> techFlags;
|
||||||
|
std::optional<CommonCodeConstSource> transposedMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommonCodeSamplerSourceInfo
|
struct CommonCodeSamplerSourceInfo
|
||||||
@@ -48,6 +87,24 @@ namespace techset
|
|||||||
CommonCodeSamplerSource value;
|
CommonCodeSamplerSource value;
|
||||||
const char* accessor;
|
const char* accessor;
|
||||||
CommonCodeSourceUpdateFrequency updateFrequency;
|
CommonCodeSourceUpdateFrequency updateFrequency;
|
||||||
|
std::optional<unsigned> techFlags;
|
||||||
|
std::optional<unsigned> customSamplerIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommonShaderArgumentType
|
||||||
|
{
|
||||||
|
friend bool operator==(const CommonShaderArgumentType& lhs, const CommonShaderArgumentType& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_shader_type == rhs.m_shader_type && lhs.m_value_type == rhs.m_value_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const CommonShaderArgumentType& lhs, const CommonShaderArgumentType& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonTechniqueShaderType m_shader_type;
|
||||||
|
CommonShaderValueType m_value_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonCodeSourceInfos
|
class CommonCodeSourceInfos
|
||||||
@@ -56,14 +113,36 @@ namespace techset
|
|||||||
CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
|
CommonCodeSourceInfos(const CommonCodeConstSourceInfo* codeConstSourceInfos,
|
||||||
size_t codeConstCount,
|
size_t codeConstCount,
|
||||||
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
|
const CommonCodeSamplerSourceInfo* codeSamplerSourceInfos,
|
||||||
size_t codeSamplerCount);
|
size_t codeSamplerCount,
|
||||||
|
const char** ignoreArgAccessors,
|
||||||
|
size_t ignoredArgAccessorCount,
|
||||||
|
const CommonShaderArgumentType* argumentTypes,
|
||||||
|
size_t argumentTypeCount);
|
||||||
|
|
||||||
[[nodiscard]] std::optional<CommonCodeConstSourceInfo> GetInfoForCodeConstSource(CommonCodeConstSource codeConstSource) const;
|
[[nodiscard]] std::optional<CommonCodeConstSourceInfo> GetInfoForCodeConstSource(CommonCodeConstSource codeConstSource) const;
|
||||||
[[nodiscard]] std::optional<CommonCodeSamplerSourceInfo> GetInfoForCodeSamplerSource(CommonCodeSamplerSource codeSamplerSource) const;
|
[[nodiscard]] std::optional<CommonCodeSamplerSourceInfo> GetInfoForCodeSamplerSource(CommonCodeSamplerSource codeSamplerSource) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Some games like T6 do not create args for certain variables. This checks whether an accessor identifies one of these variables.
|
||||||
|
* \param accessor The accessor of the variable
|
||||||
|
* \return \c true if the accessor should be ignored
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool IsArgAccessorIgnored(const std::string& accessor) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<CommonCodeConstSource> GetCodeConstSourceForAccessor(const std::string& accessor) const;
|
||||||
|
[[nodiscard]] std::optional<CommonCodeSamplerSource> GetCodeSamplerSourceForAccessor(const std::string& accessor) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<size_t> GetArgumentTypeNumericValue(const CommonShaderArgumentType& argumentType) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CommonCodeConstSourceInfo> m_code_const_source_infos;
|
std::vector<CommonCodeConstSourceInfo> m_code_const_source_infos;
|
||||||
std::vector<CommonCodeSamplerSourceInfo> m_code_sampler_source_infos;
|
std::vector<CommonCodeSamplerSourceInfo> m_code_sampler_source_infos;
|
||||||
|
std::unordered_set<std::string> m_ignored_arg_accessors;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, CommonCodeConstSource> m_code_const_lookup;
|
||||||
|
std::unordered_map<std::string, CommonCodeSamplerSource> m_code_sampler_lookup;
|
||||||
|
|
||||||
|
std::vector<CommonShaderArgumentType> m_argument_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonStreamRoutingInfos
|
class CommonStreamRoutingInfos
|
||||||
@@ -79,16 +158,31 @@ namespace techset
|
|||||||
[[nodiscard]] bool IsSourceOptional(CommonStreamSource source) const;
|
[[nodiscard]] bool IsSourceOptional(CommonStreamSource source) const;
|
||||||
[[nodiscard]] const char* GetDestinationName(CommonStreamDestination destination) const;
|
[[nodiscard]] const char* GetDestinationName(CommonStreamDestination destination) const;
|
||||||
[[nodiscard]] const char* GetDestinationAbbreviation(CommonStreamDestination destination) const;
|
[[nodiscard]] const char* GetDestinationAbbreviation(CommonStreamDestination destination) const;
|
||||||
|
[[nodiscard]] std::optional<CommonStreamSource> GetSourceByName(const std::string& name) const;
|
||||||
|
[[nodiscard]] std::optional<CommonStreamSource> GetSourceByAbbreviation(const std::string& abbreviation) const;
|
||||||
|
[[nodiscard]] std::optional<CommonStreamDestination> GetDestinationByName(const std::string& name) const;
|
||||||
|
[[nodiscard]] std::optional<CommonStreamDestination> GetDestinationByAbbreviation(const std::string& abbreviation) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CommonStreamRoutingSourceInfo> m_sources;
|
std::vector<CommonStreamRoutingSourceInfo> m_sources;
|
||||||
std::vector<CommonStreamRoutingDestinationInfo> m_destinations;
|
std::vector<CommonStreamRoutingDestinationInfo> m_destinations;
|
||||||
|
std::unordered_map<std::string, CommonStreamSource> m_source_name_lookup;
|
||||||
|
std::unordered_map<std::string, CommonStreamDestination> m_destination_name_lookup;
|
||||||
|
std::unordered_map<std::string, CommonStreamSource> m_source_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;
|
||||||
};
|
};
|
||||||
@@ -99,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;
|
||||||
};
|
};
|
||||||
@@ -115,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;
|
||||||
};
|
};
|
||||||
@@ -147,39 +247,71 @@ namespace techset
|
|||||||
class CommonVertexDeclaration
|
class CommonVertexDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CommonVertexDeclaration() = default;
|
||||||
|
explicit CommonVertexDeclaration(std::vector<CommonStreamRouting> routing);
|
||||||
|
|
||||||
|
void SortRoutingEntries();
|
||||||
|
|
||||||
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,
|
||||||
|
std::string comment);
|
||||||
|
|
||||||
|
[[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::string m_comment;
|
||||||
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
|
||||||
|
|||||||
@@ -2,21 +2,54 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
techset::CommonTechniqueTypeNames::CommonTechniqueTypeNames(const char** names, const size_t nameCount)
|
namespace techset
|
||||||
: m_names(nameCount)
|
|
||||||
{
|
{
|
||||||
std::copy(names, &names[nameCount], m_names.data());
|
CommonTechniqueTypeNames::CommonTechniqueTypeNames(const char** names, const size_t nameCount)
|
||||||
}
|
: m_names(nameCount)
|
||||||
|
{
|
||||||
|
std::copy(names, &names[nameCount], m_names.data());
|
||||||
|
|
||||||
const char* techset::CommonTechniqueTypeNames::GetTechniqueTypeName(const size_t techniqueTypeIndex) const
|
m_technique_type_lookup.reserve(nameCount);
|
||||||
{
|
for (size_t i = 0; i < nameCount; i++)
|
||||||
if (techniqueTypeIndex >= m_names.size())
|
m_technique_type_lookup.emplace(names[i], i);
|
||||||
return nullptr;
|
}
|
||||||
|
|
||||||
return m_names[techniqueTypeIndex];
|
const char* CommonTechniqueTypeNames::GetTechniqueTypeName(const size_t techniqueTypeIndex) const
|
||||||
}
|
{
|
||||||
|
if (techniqueTypeIndex >= m_names.size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
size_t techset::CommonTechniqueTypeNames::GetTechniqueTypeCount() const
|
return m_names[techniqueTypeIndex];
|
||||||
{
|
}
|
||||||
return m_names.size();
|
|
||||||
}
|
[[nodiscard]] std::optional<size_t> CommonTechniqueTypeNames::GetTechniqueTypeByName(const std::string& name) const
|
||||||
|
{
|
||||||
|
const auto foundValue = m_technique_type_lookup.find(name);
|
||||||
|
if (foundValue != m_technique_type_lookup.end())
|
||||||
|
return foundValue->second;
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CommonTechniqueTypeNames::GetTechniqueTypeCount() const
|
||||||
|
{
|
||||||
|
return m_names.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonTechset::CommonTechset(const size_t techniqueTypeCount)
|
||||||
|
: m_technique_names(techniqueTypeCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonTechset::CommonTechset(std::string name, std::vector<std::string> techniqueNames)
|
||||||
|
: m_name(std::move(name)),
|
||||||
|
m_technique_names(std::move(techniqueNames))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonTechset::CommonTechset(std::string name, const size_t techniqueTypeCount)
|
||||||
|
: m_name(std::move(name)),
|
||||||
|
m_technique_names(techniqueTypeCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
@@ -12,15 +14,22 @@ namespace techset
|
|||||||
CommonTechniqueTypeNames(const char** names, size_t nameCount);
|
CommonTechniqueTypeNames(const char** names, size_t nameCount);
|
||||||
|
|
||||||
[[nodiscard]] const char* GetTechniqueTypeName(size_t techniqueTypeIndex) const;
|
[[nodiscard]] const char* GetTechniqueTypeName(size_t techniqueTypeIndex) const;
|
||||||
|
[[nodiscard]] std::optional<size_t> GetTechniqueTypeByName(const std::string& name) const;
|
||||||
[[nodiscard]] size_t GetTechniqueTypeCount() const;
|
[[nodiscard]] size_t GetTechniqueTypeCount() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<const char*> m_names;
|
std::vector<const char*> m_names;
|
||||||
|
std::unordered_map<std::string, size_t> m_technique_type_lookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonTechset
|
class CommonTechset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CommonTechset() = default;
|
||||||
|
explicit CommonTechset(size_t techniqueTypeCount);
|
||||||
|
CommonTechset(std::string name, std::vector<std::string> techniqueNames);
|
||||||
|
CommonTechset(std::string name, size_t techniqueTypeCount);
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::vector<std::string> m_technique_names;
|
std::vector<std::string> m_technique_names;
|
||||||
};
|
};
|
||||||
|
|||||||
63
src/ObjCommon/Techset/CommonVertexDeclCreator.cpp
Normal file
63
src/ObjCommon/Techset/CommonVertexDeclCreator.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include "CommonVertexDeclCreator.h"
|
||||||
|
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool NextAbbreviation(const std::string& assetName, std::string& abbreviation, size_t& offset)
|
||||||
|
{
|
||||||
|
if (offset >= assetName.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto digitCount = 0;
|
||||||
|
while (offset + digitCount + 1 < assetName.size() && isdigit(assetName[offset + digitCount + 1]))
|
||||||
|
digitCount++;
|
||||||
|
|
||||||
|
abbreviation = std::string(assetName, offset, digitCount + 1);
|
||||||
|
offset += digitCount + 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::optional<CommonVertexDeclaration> CreateVertexDeclFromName(const std::string& name, const CommonStreamRoutingInfos& routingInfos)
|
||||||
|
{
|
||||||
|
CommonVertexDeclaration result;
|
||||||
|
size_t currentOffset = 0u;
|
||||||
|
|
||||||
|
std::string sourceAbbreviation;
|
||||||
|
while (NextAbbreviation(name, sourceAbbreviation, currentOffset))
|
||||||
|
{
|
||||||
|
std::string destinationAbbreviation;
|
||||||
|
if (!NextAbbreviation(name, destinationAbbreviation, currentOffset))
|
||||||
|
{
|
||||||
|
con::error("Failed to detect vertex decl destination abbreviation: {}", name);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto maybeSource = routingInfos.GetSourceByAbbreviation(sourceAbbreviation);
|
||||||
|
if (!maybeSource)
|
||||||
|
{
|
||||||
|
con::error("Unknown vertex decl source abbreviation: {}", sourceAbbreviation);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto maybeDestination = routingInfos.GetDestinationByAbbreviation(destinationAbbreviation);
|
||||||
|
if (!maybeDestination)
|
||||||
|
{
|
||||||
|
con::error("Unknown vertex decl destination abbreviation: {}", destinationAbbreviation);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.m_routing.emplace_back(*maybeSource, *maybeDestination);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.SortRoutingEntries();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
11
src/ObjCommon/Techset/CommonVertexDeclCreator.h
Normal file
11
src/ObjCommon/Techset/CommonVertexDeclCreator.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CommonTechnique.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::optional<CommonVertexDeclaration> CreateVertexDeclFromName(const std::string& name, const CommonStreamRoutingInfos& routingInfos);
|
||||||
|
}
|
||||||
@@ -18,4 +18,28 @@ namespace techset
|
|||||||
{
|
{
|
||||||
return std::format("techsets/{}.techset", assetName);
|
return std::format("techsets/{}.techset", assetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CountWorldVertFormatParameters(const std::string& assetName, size_t& texCount, size_t& normalCount)
|
||||||
|
{
|
||||||
|
texCount = 0;
|
||||||
|
normalCount = 0;
|
||||||
|
|
||||||
|
if (assetName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto nameLen = assetName.size();
|
||||||
|
for (auto pos = 1u; pos < nameLen - 1u; pos++)
|
||||||
|
{
|
||||||
|
if (assetName[pos - 1] != '_' && !isdigit(assetName[pos - 1]))
|
||||||
|
continue;
|
||||||
|
if (!isdigit(assetName[pos + 1]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto c = tolower(assetName[pos]);
|
||||||
|
if (c == 'c')
|
||||||
|
texCount++;
|
||||||
|
else if (c == 'n')
|
||||||
|
normalCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ namespace techset
|
|||||||
std::string GetFileNameForStateMapName(const std::string& stateMapName);
|
std::string GetFileNameForStateMapName(const std::string& stateMapName);
|
||||||
std::string GetFileNameForTechniqueName(const std::string& assetName);
|
std::string GetFileNameForTechniqueName(const std::string& assetName);
|
||||||
std::string GetFileNameForTechsetName(const std::string& assetName);
|
std::string GetFileNameForTechsetName(const std::string& assetName);
|
||||||
|
|
||||||
|
void CountWorldVertFormatParameters(const std::string& assetName, size_t& texCount, size_t& normalCount);
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
|
|||||||
@@ -9,12 +9,9 @@
|
|||||||
#include "Gdt/AbstractGdtEntryReader.h"
|
#include "Gdt/AbstractGdtEntryReader.h"
|
||||||
#include "Gdt/IGdtQueryable.h"
|
#include "Gdt/IGdtQueryable.h"
|
||||||
#include "Pool/GlobalAssetPool.h"
|
#include "Pool/GlobalAssetPool.h"
|
||||||
#include "StateMap/StateMapFromTechniqueExtractor.h"
|
#include "Techset/StateMap/StateMapHandler.h"
|
||||||
#include "StateMap/StateMapHandler.h"
|
#include "Techset/StateMap/TechniqueStateMapCache.h"
|
||||||
#include "Techset/TechniqueFileReader.h"
|
|
||||||
#include "Techset/TechniqueStateMapCache.h"
|
|
||||||
#include "Techset/TechsetCommon.h"
|
#include "Techset/TechsetCommon.h"
|
||||||
#include "Techset/TechsetDefinitionCache.h"
|
|
||||||
#include "Utils/Logging/Log.h"
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -28,6 +25,7 @@ using namespace IW4;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
class SkipMaterialException final : public std::exception
|
class SkipMaterialException final : public std::exception
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@@ -795,7 +793,7 @@ namespace
|
|||||||
m_registration.AddDependency(techset);
|
m_registration.AddDependency(techset);
|
||||||
m_material.techniqueSet = techset->Asset();
|
m_material.techniqueSet = techset->Asset();
|
||||||
|
|
||||||
auto& definitionCache = m_context.GetZoneAssetCreationState<::techset::TechsetDefinitionCache>();
|
auto& definitionCache = m_context.GetZoneAssetCreationState<::techset::CommonTechsetCache>();
|
||||||
|
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
const auto* techsetDefinition = m_techset_creator->LoadTechsetDefinition(techsetName, m_context, failure);
|
const auto* techsetDefinition = m_techset_creator->LoadTechsetDefinition(techsetName, m_context, failure);
|
||||||
@@ -808,12 +806,12 @@ namespace
|
|||||||
SetTechniqueSetCameraRegion(techsetDefinition);
|
SetTechniqueSetCameraRegion(techsetDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTechniqueSetStateBits(const ::techset::TechsetDefinition* techsetDefinition)
|
void SetTechniqueSetStateBits(const techset::CommonTechset* commonTechset)
|
||||||
{
|
{
|
||||||
for (auto i = 0; i < TECHNIQUE_COUNT; i++)
|
for (auto i = 0; i < TECHNIQUE_COUNT; i++)
|
||||||
{
|
{
|
||||||
std::string techniqueName;
|
auto techniqueName = commonTechset->m_technique_names[i];
|
||||||
if (techsetDefinition->GetTechniqueByIndex(i, techniqueName))
|
if (!techniqueName.empty())
|
||||||
{
|
{
|
||||||
const auto stateBitsForTechnique = GetStateBitsForTechnique(techniqueName);
|
const auto stateBitsForTechnique = GetStateBitsForTechnique(techniqueName);
|
||||||
const auto foundStateBits = std::ranges::find_if(m_state_bits,
|
const auto foundStateBits = std::ranges::find_if(m_state_bits,
|
||||||
@@ -892,17 +890,17 @@ namespace
|
|||||||
return outBits;
|
return outBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTechniqueSetCameraRegion(const ::techset::TechsetDefinition* techsetDefinition) const
|
void SetTechniqueSetCameraRegion(const techset::CommonTechset* commonTechset) const
|
||||||
{
|
{
|
||||||
std::string tempName;
|
std::string tempName;
|
||||||
if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_LIT, tempName))
|
if (!commonTechset->m_technique_names[TECHNIQUE_LIT].empty())
|
||||||
{
|
{
|
||||||
if (m_material.info.sortKey >= SORTKEY_TRANS_START)
|
if (m_material.info.sortKey >= SORTKEY_TRANS_START)
|
||||||
m_material.cameraRegion = CAMERA_REGION_LIT_TRANS;
|
m_material.cameraRegion = CAMERA_REGION_LIT_TRANS;
|
||||||
else
|
else
|
||||||
m_material.cameraRegion = CAMERA_REGION_LIT_OPAQUE;
|
m_material.cameraRegion = CAMERA_REGION_LIT_OPAQUE;
|
||||||
}
|
}
|
||||||
else if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_EMISSIVE, tempName))
|
else if (!commonTechset->m_technique_names[TECHNIQUE_EMISSIVE].empty())
|
||||||
{
|
{
|
||||||
m_material.cameraRegion = CAMERA_REGION_EMISSIVE;
|
m_material.cameraRegion = CAMERA_REGION_EMISSIVE;
|
||||||
}
|
}
|
||||||
@@ -1328,6 +1326,7 @@ namespace
|
|||||||
|
|
||||||
std::unique_ptr<techset::ICreatorIW4> m_techset_creator;
|
std::unique_ptr<techset::ICreatorIW4> m_techset_creator;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
||||||
{
|
{
|
||||||
@@ -1341,6 +1340,8 @@ namespace
|
|||||||
|
|
||||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
{
|
{
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
/*
|
||||||
const auto* entry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
|
const auto* entry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return AssetCreationResult::NoAction();
|
return AssetCreationResult::NoAction();
|
||||||
@@ -1367,6 +1368,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AssetCreationResult::Failure();
|
return AssetCreationResult::Failure();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -6,12 +6,10 @@
|
|||||||
#include "Game/IW4/Techset/TechsetConstantsIW4.h"
|
#include "Game/IW4/Techset/TechsetConstantsIW4.h"
|
||||||
#include "Shader/D3D9ShaderAnalyser.h"
|
#include "Shader/D3D9ShaderAnalyser.h"
|
||||||
#include "Shader/ShaderCommon.h"
|
#include "Shader/ShaderCommon.h"
|
||||||
#include "StateMap/StateMapReader.h"
|
#include "Techset/CommonTechsetLoader.h"
|
||||||
#include "Techset/TechniqueFileReader.h"
|
#include "Techset/StateMap/StateMapReader.h"
|
||||||
#include "Techset/TechniqueStateMapCache.h"
|
#include "Techset/StateMap/TechniqueStateMapCache.h"
|
||||||
#include "Techset/TechsetCommon.h"
|
#include "Techset/TechsetCommon.h"
|
||||||
#include "Techset/TechsetDefinitionCache.h"
|
|
||||||
#include "Techset/TechsetFileReader.h"
|
|
||||||
#include "Utils/Alignment.h"
|
#include "Utils/Alignment.h"
|
||||||
#include "Utils/Logging/Log.h"
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
@@ -32,6 +30,7 @@ using namespace std::string_literals;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
class LoadedTechnique
|
class LoadedTechnique
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -407,7 +406,7 @@ namespace
|
|||||||
|
|
||||||
if (arg1.m_arg.type == MTL_ARG_MATERIAL_VERTEX_CONST || arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_CONST
|
if (arg1.m_arg.type == MTL_ARG_MATERIAL_VERTEX_CONST || arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_CONST
|
||||||
|| arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_SAMPLER)
|
|| arg1.m_arg.type == MTL_ARG_MATERIAL_PIXEL_SAMPLER)
|
||||||
return arg1.m_arg.u.codeSampler < arg2.m_arg.u.codeSampler;
|
return arg1.m_arg.u.nameHash < arg2.m_arg.u.nameHash;
|
||||||
|
|
||||||
return arg1.m_arg.dest < arg2.m_arg.dest;
|
return arg1.m_arg.dest < arg2.m_arg.dest;
|
||||||
});
|
});
|
||||||
@@ -1263,7 +1262,7 @@ namespace
|
|||||||
TechniqueZoneLoadingState& m_zone_state;
|
TechniqueZoneLoadingState& m_zone_state;
|
||||||
techset::ICreatorIW4* m_techset_creator;
|
techset::ICreatorIW4* m_techset_creator;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
class TechsetLoader final : public techset::ICreatorIW4
|
class TechsetLoader final : public techset::ICreatorIW4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1275,16 +1274,19 @@ namespace
|
|||||||
|
|
||||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
{
|
{
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
/*
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
const auto* techsetDefinition = LoadTechsetDefinition(assetName, context, failure);
|
const auto* techsetDefinition = LoadTechsetDefinition(assetName, context, failure);
|
||||||
if (!techsetDefinition)
|
if (!techsetDefinition)
|
||||||
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
|
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
|
||||||
|
|
||||||
return CreateTechsetFromDefinition(assetName, *techsetDefinition, context);
|
return CreateTechsetFromDefinition(assetName, *techsetDefinition, context);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
/*
|
||||||
AssetCreationResult CreateTechsetFromDefinition(const std::string& assetName, const TechsetDefinition& definition, AssetCreationContext& context)
|
AssetCreationResult CreateTechsetFromDefinition(const std::string& assetName, const CommonTechset& definition, AssetCreationContext& context)
|
||||||
{
|
{
|
||||||
auto* techset = m_memory.Alloc<MaterialTechniqueSet>();
|
auto* techset = m_memory.Alloc<MaterialTechniqueSet>();
|
||||||
techset->name = m_memory.Dup(assetName.c_str());
|
techset->name = m_memory.Dup(assetName.c_str());
|
||||||
@@ -1294,8 +1296,8 @@ namespace
|
|||||||
const TechniqueLoader techniqueLoader(m_search_path, m_memory, context, this);
|
const TechniqueLoader techniqueLoader(m_search_path, m_memory, context, this);
|
||||||
for (auto i = 0u; i < std::extent_v<decltype(MaterialTechniqueSet::techniques)>; i++)
|
for (auto i = 0u; i < std::extent_v<decltype(MaterialTechniqueSet::techniques)>; i++)
|
||||||
{
|
{
|
||||||
std::string techniqueName;
|
const auto& techniqueName = definition.m_technique_names[i];
|
||||||
if (definition.GetTechniqueByIndex(i, techniqueName))
|
if (!techniqueName.empty())
|
||||||
{
|
{
|
||||||
auto* technique = techniqueLoader.LoadMaterialTechnique(techniqueName);
|
auto* technique = techniqueLoader.LoadMaterialTechnique(techniqueName);
|
||||||
|
|
||||||
@@ -1311,11 +1313,13 @@ namespace
|
|||||||
|
|
||||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
TechsetDefinition* LoadTechsetDefinition(const std::string& assetName, AssetCreationContext& context, bool& failure) override
|
CommonTechset* LoadTechsetDefinition(const std::string& assetName, AssetCreationContext& context, bool& failure) override
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
failure = false;
|
failure = false;
|
||||||
auto& definitionCache = context.GetZoneAssetCreationState<TechsetDefinitionCache>();
|
auto& definitionCache = context.GetZoneAssetCreationState<CommonTechsetCache>();
|
||||||
auto* cachedTechsetDefinition = definitionCache.GetCachedTechsetDefinition(assetName);
|
auto* cachedTechsetDefinition = definitionCache.GetCachedTechsetDefinition(assetName);
|
||||||
if (cachedTechsetDefinition)
|
if (cachedTechsetDefinition)
|
||||||
return cachedTechsetDefinition;
|
return cachedTechsetDefinition;
|
||||||
@@ -1325,23 +1329,22 @@ namespace
|
|||||||
if (!file.IsOpen())
|
if (!file.IsOpen())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const TechsetFileReader reader(*file.m_stream, techsetFileName, techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
|
auto techsetDefinition = LoadCommonTechset(assetName, commonTechniqueTypeNames, m_search_path, failure);
|
||||||
auto techsetDefinition = reader.ReadTechsetDefinition();
|
|
||||||
if (!techsetDefinition)
|
if (!techsetDefinition)
|
||||||
{
|
|
||||||
failure = true;
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
auto* techsetDefinitionPtr = techsetDefinition.get();
|
auto* techsetDefinitionPtr = techsetDefinition.get();
|
||||||
|
|
||||||
definitionCache.AddTechsetDefinitionToCache(assetName, std::move(techsetDefinition));
|
definitionCache.AddCommonTechsetToCache(assetName, std::move(techsetDefinition));
|
||||||
|
|
||||||
return techsetDefinitionPtr;
|
return techsetDefinitionPtr;
|
||||||
|
*/
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, AssetCreationContext& context) override
|
const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, AssetCreationContext& context) override
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
auto& stateMapCache = context.GetZoneAssetCreationState<TechniqueStateMapCache>();
|
auto& stateMapCache = context.GetZoneAssetCreationState<TechniqueStateMapCache>();
|
||||||
auto* cachedStateMap = stateMapCache.GetCachedStateMap(stateMapName);
|
auto* cachedStateMap = stateMapCache.GetCachedStateMap(stateMapName);
|
||||||
if (cachedStateMap)
|
if (cachedStateMap)
|
||||||
@@ -1362,6 +1365,8 @@ namespace
|
|||||||
stateMapCache.AddStateMapToCache(std::move(stateMapDefinition));
|
stateMapCache.AddStateMapToCache(std::move(stateMapDefinition));
|
||||||
|
|
||||||
return stateMapDefinitionPtr;
|
return stateMapDefinitionPtr;
|
||||||
|
*/
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#include "Asset/IAssetCreator.h"
|
#include "Asset/IAssetCreator.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "SearchPath/ISearchPath.h"
|
#include "SearchPath/ISearchPath.h"
|
||||||
#include "StateMap/StateMapDefinition.h"
|
#include "Techset/CommonTechset.h"
|
||||||
#include "Techset/TechsetDefinition.h"
|
#include "Techset/StateMap/StateMapDefinition.h"
|
||||||
#include "Utils/MemoryManager.h"
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -18,7 +18,7 @@ namespace techset
|
|||||||
ICreatorIW4() = default;
|
ICreatorIW4() = default;
|
||||||
virtual ~ICreatorIW4() = default;
|
virtual ~ICreatorIW4() = default;
|
||||||
|
|
||||||
virtual TechsetDefinition* LoadTechsetDefinition(const std::string& assetName, AssetCreationContext& context, bool& failure) = 0;
|
virtual CommonTechset* LoadTechsetDefinition(const std::string& assetName, AssetCreationContext& context, bool& failure) = 0;
|
||||||
virtual const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, AssetCreationContext& context) = 0;
|
virtual const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, AssetCreationContext& context) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "Image/ImageIPakPostProcessor.h"
|
#include "Image/ImageIPakPostProcessor.h"
|
||||||
#include "Image/ImageIwdPostProcessor.h"
|
#include "Image/ImageIwdPostProcessor.h"
|
||||||
#include "KeyValuePairs/KeyValuePairsCompilerT6.h"
|
#include "KeyValuePairs/KeyValuePairsCompilerT6.h"
|
||||||
|
#include "Techset/TechniqueCompilerT6.h"
|
||||||
|
#include "Techset/TechsetCompilerT6.h"
|
||||||
|
#include "Techset/VertexDeclCompilerT6.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -20,6 +23,10 @@ namespace
|
|||||||
auto& memory = zone.Memory();
|
auto& memory = zone.Memory();
|
||||||
|
|
||||||
collection.AddAssetCreator(key_value_pairs::CreateCompilerT6(memory, zone, zoneDefinition.m_zone_definition, zoneStates));
|
collection.AddAssetCreator(key_value_pairs::CreateCompilerT6(memory, zone, zoneDefinition.m_zone_definition, zoneStates));
|
||||||
|
collection.AddAssetCreator(techset::CreateCompilerT6(memory, searchPath));
|
||||||
|
|
||||||
|
collection.AddSubAssetCreator(techset::CreateTechniqueCompilerT6(memory, zone, searchPath));
|
||||||
|
collection.AddSubAssetCreator(techset::CreateVertexDeclCompilerT6(memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigurePostProcessors(AssetCreatorCollection& collection,
|
void ConfigurePostProcessors(AssetCreatorCollection& collection,
|
||||||
|
|||||||
256
src/ObjCompiling/Game/T6/Techset/PrecompiledIndexT6.cpp
Normal file
256
src/ObjCompiling/Game/T6/Techset/PrecompiledIndexT6.cpp
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
#include "PrecompiledIndexT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/Techset/TechsetConstantsT6.h"
|
||||||
|
#include "Techset/CommonTechnique.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class PrecompiledIndexMapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VertexShaderPrecompiledIndex m_value;
|
||||||
|
std::optional<MaterialType> m_material_type;
|
||||||
|
std::vector<MaterialConstantSource> m_vertex_const_constraints;
|
||||||
|
std::vector<CustomSampler> m_custom_sampler_constraints;
|
||||||
|
};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
inline PrecompiledIndexMapping precompiledIndexMappings[]{
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_VERTCOL,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_COORDS_AND_VIS,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC,
|
||||||
|
.m_material_type = MTL_TYPE_MODEL_LIGHTMAP_VC,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_0,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_1,
|
||||||
|
CONST_SRC_CODE_GRID_LIGHTING_SH_2,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {
|
||||||
|
CUSTOM_SAMPLER_REFLECTION_PROBE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_value = VERTEX_SHADER_MODEL_UNLIT,
|
||||||
|
.m_material_type = std::nullopt,
|
||||||
|
.m_vertex_const_constraints = {
|
||||||
|
CONST_SRC_CODE_WORLD_MATRIX,
|
||||||
|
},
|
||||||
|
.m_custom_sampler_constraints = {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
[[nodiscard]] bool MappingMatches(const PrecompiledIndexMapping& mapping,
|
||||||
|
const MaterialType materialType,
|
||||||
|
const std::vector<techset::CommonStreamSource>& passCodeConsts,
|
||||||
|
const unsigned samplerFlags)
|
||||||
|
{
|
||||||
|
if (mapping.m_material_type && *mapping.m_material_type != materialType)
|
||||||
|
return false;
|
||||||
|
if (mapping.m_vertex_const_constraints.size() > passCodeConsts.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto passCodeConstIndex = 0u;
|
||||||
|
for (const auto codeConstConstraint : mapping.m_vertex_const_constraints)
|
||||||
|
{
|
||||||
|
if (passCodeConsts[passCodeConstIndex++] != codeConstConstraint)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expectedSamplerFlags = 0u;
|
||||||
|
for (const auto customSampler : mapping.m_custom_sampler_constraints)
|
||||||
|
expectedSamplerFlags |= (1 << customSampler);
|
||||||
|
|
||||||
|
return samplerFlags == expectedSamplerFlags;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
void ApplyPrecompiledIndex(MaterialPass& pass)
|
||||||
|
{
|
||||||
|
if (!pass.args)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<techset::CommonStreamSource> codeConstants;
|
||||||
|
const auto argCount = static_cast<unsigned>(pass.perPrimArgCount);
|
||||||
|
for (auto argIndex = 0u; argIndex < argCount; argIndex++)
|
||||||
|
{
|
||||||
|
const auto& arg = pass.args[argIndex];
|
||||||
|
if (arg.type != MTL_ARG_CODE_VERTEX_CONST)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto codeConst = static_cast<techset::CommonStreamSource>(arg.u.codeConst.index);
|
||||||
|
|
||||||
|
// Make sure we are agnostic of the used transposed versions
|
||||||
|
const auto codeConstInfo = commonCodeSourceInfos.GetInfoForCodeConstSource(codeConst);
|
||||||
|
if (codeConstInfo && codeConstInfo->transposedMatrix)
|
||||||
|
codeConstants.emplace_back(std::min(codeConst, *codeConstInfo->transposedMatrix));
|
||||||
|
else
|
||||||
|
codeConstants.emplace_back(codeConst);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto end = std::end(precompiledIndexMappings);
|
||||||
|
const auto foundMapping = std::find_if(std::begin(precompiledIndexMappings),
|
||||||
|
end,
|
||||||
|
[&codeConstants, pass](const PrecompiledIndexMapping& mapping) -> bool
|
||||||
|
{
|
||||||
|
return MappingMatches(mapping, pass.materialType, codeConstants, pass.customSamplerFlags);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (foundMapping != end)
|
||||||
|
pass.precompiledIndex = foundMapping->m_value;
|
||||||
|
}
|
||||||
|
} // namespace T6
|
||||||
8
src/ObjCompiling/Game/T6/Techset/PrecompiledIndexT6.h
Normal file
8
src/ObjCompiling/Game/T6/Techset/PrecompiledIndexT6.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
void ApplyPrecompiledIndex(MaterialPass& pass);
|
||||||
|
}
|
||||||
345
src/ObjCompiling/Game/T6/Techset/TechniqueCompilerT6.cpp
Normal file
345
src/ObjCompiling/Game/T6/Techset/TechniqueCompilerT6.cpp
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
#include "TechniqueCompilerT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Game/T6/Techset/TechsetConstantsT6.h"
|
||||||
|
#include "PrecompiledIndexT6.h"
|
||||||
|
#include "Techset/CommonShaderArgCreator.h"
|
||||||
|
#include "Techset/CommonTechniqueLoader.h"
|
||||||
|
#include "Techset/LiteralConstsZoneState.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <optional>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
unsigned ConvertArgumentType(const techset::CommonShaderArgumentType& type)
|
||||||
|
{
|
||||||
|
if (type.m_shader_type == techset::CommonTechniqueShaderType::VERTEX)
|
||||||
|
{
|
||||||
|
switch (type.m_value_type)
|
||||||
|
{
|
||||||
|
case techset::CommonShaderValueType::LITERAL_CONST:
|
||||||
|
return MTL_ARG_LITERAL_VERTEX_CONST;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_CONST:
|
||||||
|
return MTL_ARG_MATERIAL_VERTEX_CONST;
|
||||||
|
case techset::CommonShaderValueType::CODE_CONST:
|
||||||
|
return MTL_ARG_CODE_VERTEX_CONST;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
|
||||||
|
case techset::CommonShaderValueType::CODE_SAMPLER:
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(type.m_shader_type == techset::CommonTechniqueShaderType::PIXEL);
|
||||||
|
|
||||||
|
switch (type.m_value_type)
|
||||||
|
{
|
||||||
|
case techset::CommonShaderValueType::LITERAL_CONST:
|
||||||
|
return MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_CONST:
|
||||||
|
return MTL_ARG_MATERIAL_PIXEL_CONST;
|
||||||
|
case techset::CommonShaderValueType::CODE_CONST:
|
||||||
|
return MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
|
||||||
|
return MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
|
case techset::CommonShaderValueType::CODE_SAMPLER:
|
||||||
|
return MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertArgumentValue(MaterialArgumentDef& argValue, const techset::CommonShaderArg& commonArg, MemoryManager& memory, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
switch (commonArg.m_type.m_value_type)
|
||||||
|
{
|
||||||
|
case techset::CommonShaderValueType::LITERAL_CONST:
|
||||||
|
{
|
||||||
|
const techset::LiteralConst literal(commonArg.m_value.literal_value);
|
||||||
|
argValue.literalConst = context.GetZoneAssetCreationState<techset::LiteralConstsZoneState<float>>().GetAllocatedLiteral(literal)->GamePtr();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case techset::CommonShaderValueType::CODE_CONST:
|
||||||
|
argValue.codeConst.index = static_cast<decltype(MaterialArgumentCodeConst::index)>(commonArg.m_value.code_const_source.m_index);
|
||||||
|
argValue.codeConst.firstRow = static_cast<decltype(MaterialArgumentCodeConst::firstRow)>(commonArg.m_value.code_const_source.m_first_row);
|
||||||
|
argValue.codeConst.rowCount = static_cast<decltype(MaterialArgumentCodeConst::rowCount)>(commonArg.m_value.code_const_source.m_row_count);
|
||||||
|
break;
|
||||||
|
case techset::CommonShaderValueType::CODE_SAMPLER:
|
||||||
|
argValue.codeSampler = static_cast<decltype(MaterialArgumentDef::codeSampler)>(commonArg.m_value.code_sampler_source);
|
||||||
|
break;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_CONST:
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
|
||||||
|
argValue.nameHash = static_cast<decltype(MaterialArgumentDef::nameHash)>(commonArg.m_value.name_hash);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertMaterialArgs(MaterialPass& pass, const techset::CommonPass& commonPass, MemoryManager& memory, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
pass.args = memory.Alloc<MaterialShaderArgument>(commonPass.m_args.size());
|
||||||
|
|
||||||
|
const auto frequencyCount = commonPass.GetFrequencyCounts(commonCodeSourceInfos);
|
||||||
|
|
||||||
|
pass.perObjArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::PER_OBJECT)]);
|
||||||
|
pass.perPrimArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::PER_PRIM)]);
|
||||||
|
pass.stableArgCount = static_cast<unsigned char>(frequencyCount[std::to_underlying(techset::CommonCodeSourceUpdateFrequency::RARELY)]);
|
||||||
|
|
||||||
|
const auto commonArgCount = commonPass.m_args.size();
|
||||||
|
for (auto argIndex = 0u; argIndex < commonArgCount; argIndex++)
|
||||||
|
{
|
||||||
|
auto& arg = pass.args[argIndex];
|
||||||
|
const auto& commonArg = commonPass.m_args[argIndex];
|
||||||
|
|
||||||
|
arg.type = static_cast<decltype(MaterialShaderArgument::type)>(ConvertArgumentType(commonArg.m_type));
|
||||||
|
|
||||||
|
arg.size = static_cast<decltype(MaterialShaderArgument::size)>(commonArg.m_destination.dx11.m_size);
|
||||||
|
arg.buffer = static_cast<decltype(MaterialShaderArgument::buffer)>(commonArg.m_destination.dx11.m_buffer);
|
||||||
|
|
||||||
|
if (techset::IsConstValueType(commonArg.m_type.m_value_type))
|
||||||
|
{
|
||||||
|
arg.location.offset = static_cast<decltype(MaterialArgumentLocation::offset)>(commonArg.m_destination.dx11.m_location.constant_buffer_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(techset::IsSamplerValueType(commonArg.m_type.m_value_type));
|
||||||
|
arg.location.textureIndex =
|
||||||
|
static_cast<decltype(MaterialArgumentLocation::textureIndex)>(commonArg.m_destination.dx11.m_location.texture_index);
|
||||||
|
arg.location.samplerIndex =
|
||||||
|
static_cast<decltype(MaterialArgumentLocation::samplerIndex)>(commonArg.m_destination.dx11.m_location.sampler_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertArgumentValue(arg.u, commonArg, memory, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertVertexDecl(MaterialPass& pass, const techset::CommonVertexDeclaration& commonDecl, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
std::ostringstream nameStream;
|
||||||
|
for (const auto& entry : commonDecl.m_routing)
|
||||||
|
{
|
||||||
|
nameStream << commonRoutingInfos.GetSourceAbbreviation(entry.m_source);
|
||||||
|
nameStream << commonRoutingInfos.GetDestinationAbbreviation(entry.m_destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string declName(nameStream.str());
|
||||||
|
auto* vertexDeclAsset = context.LoadSubAsset<SubAssetVertexDecl>(declName);
|
||||||
|
assert(vertexDeclAsset);
|
||||||
|
pass.vertexDecl = vertexDeclAsset ? vertexDeclAsset->Asset() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertMaterialPass(MaterialPass& pass, const techset::CommonPass& commonPass, AssetCreationContext& context, MemoryManager& memory)
|
||||||
|
{
|
||||||
|
ConvertVertexDecl(pass, commonPass.m_vertex_declaration, context);
|
||||||
|
|
||||||
|
if (!commonPass.m_vertex_shader.m_name.empty())
|
||||||
|
{
|
||||||
|
auto* vertexShaderAsset = context.LoadSubAsset<SubAssetVertexShader>(commonPass.m_vertex_shader.m_name);
|
||||||
|
assert(vertexShaderAsset);
|
||||||
|
pass.vertexShader = vertexShaderAsset ? vertexShaderAsset->Asset() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!commonPass.m_pixel_shader.m_name.empty())
|
||||||
|
{
|
||||||
|
auto* pixelShaderAsset = context.LoadSubAsset<SubAssetPixelShader>(commonPass.m_pixel_shader.m_name);
|
||||||
|
assert(pixelShaderAsset);
|
||||||
|
pass.pixelShader = pixelShaderAsset ? pixelShaderAsset->Asset() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertMaterialArgs(pass, commonPass, memory, context);
|
||||||
|
pass.customSamplerFlags = static_cast<decltype(MaterialPass::customSamplerFlags)>(commonPass.m_sampler_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnyDeclHasOptionalSource(const MaterialTechnique& technique)
|
||||||
|
{
|
||||||
|
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||||
|
{
|
||||||
|
const auto& pass = technique.passArray[passIndex];
|
||||||
|
if (!pass.vertexDecl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pass.vertexDecl->hasOptionalSource)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateTechniqueFlags(MaterialTechnique& technique, const techset::CommonTechnique& commonTechnique)
|
||||||
|
{
|
||||||
|
std::string lowerTechniqueName(commonTechnique.m_name);
|
||||||
|
utils::MakeStringLowerCase(lowerTechniqueName);
|
||||||
|
|
||||||
|
// Not a particularly cool way to do this but...
|
||||||
|
// the game actually does this :shrug:
|
||||||
|
if (lowerTechniqueName == "zprepass" || lowerTechniqueName.starts_with("pimp_technique_zprepass_")
|
||||||
|
|| lowerTechniqueName.starts_with("pimp_technique_layer_zprepass_") || lowerTechniqueName.starts_with("pimp_technique_buildshadowmap_"))
|
||||||
|
{
|
||||||
|
technique.flags |= TECHNIQUE_FLAG_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AnyDeclHasOptionalSource(technique))
|
||||||
|
technique.flags |= TECHNIQUE_FLAG_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialTechnique* ConvertTechnique(const techset::CommonTechnique& commonTechnique, AssetCreationContext& context, MemoryManager& memory)
|
||||||
|
{
|
||||||
|
const auto additionalPassCount = std::max(commonTechnique.m_passes.size(), 1uz) - 1uz;
|
||||||
|
auto* technique = static_cast<MaterialTechnique*>(memory.AllocRaw(sizeof(MaterialTechnique) + additionalPassCount * sizeof(MaterialPass)));
|
||||||
|
|
||||||
|
const auto passCount = static_cast<decltype(MaterialTechnique::passCount)>(commonTechnique.m_passes.size());
|
||||||
|
|
||||||
|
technique->name = memory.Dup(commonTechnique.m_name.c_str());
|
||||||
|
|
||||||
|
technique->passCount = passCount;
|
||||||
|
|
||||||
|
for (auto passIndex = 0u; passIndex < passCount; passIndex++)
|
||||||
|
ConvertMaterialPass(technique->passArray[passIndex], commonTechnique.m_passes[passIndex], context, memory);
|
||||||
|
|
||||||
|
// Take common flags and apply further logic
|
||||||
|
technique->flags = static_cast<decltype(MaterialTechnique::flags)>(commonTechnique.m_flags);
|
||||||
|
UpdateTechniqueFlags(*technique, commonTechnique);
|
||||||
|
|
||||||
|
return technique;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyTechFlagsFromMaterial(const Material& material, const Zone& zone)
|
||||||
|
{
|
||||||
|
if (!material.techniqueSet || !material.techniqueSet->name || !material.stateBitsTable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Find the techniqueset asset from our zone since the material may link to a different one
|
||||||
|
const auto techniqueSetAsset = zone.m_pools.GetAsset<AssetTechniqueSet>(material.techniqueSet->name);
|
||||||
|
if (!techniqueSetAsset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto techType = 0u; techType < TECHNIQUE_COUNT; techType++)
|
||||||
|
{
|
||||||
|
auto* technique = techniqueSetAsset->Asset()->techniques[techType];
|
||||||
|
const auto stateBitsEntry = material.stateBitsEntry[techType];
|
||||||
|
|
||||||
|
if (!technique || stateBitsEntry < 0 || static_cast<decltype(Material::stateBitsCount)>(stateBitsEntry) >= material.stateBitsCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto& stateBits = material.stateBitsTable[static_cast<decltype(Material::stateBitsCount)>(stateBitsEntry)].loadBits;
|
||||||
|
const bool shouldSetFlag80 = stateBits.structured.depthTestDisabled == 0 || stateBits.structured.depthWrite > 0
|
||||||
|
|| stateBits.structured.depthTest > 0 || stateBits.structured.polygonOffset > 0;
|
||||||
|
if (shouldSetFlag80)
|
||||||
|
technique->flags |= TECHNIQUE_FLAG_80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TechniqueShaderLoaderT6 final : public techset::ITechniqueShaderLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TechniqueShaderLoaderT6(AssetCreationContext& context)
|
||||||
|
: m_context(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<techset::CommonTechniqueShaderBin> LoadVertexShader(const std::string& name) override
|
||||||
|
{
|
||||||
|
auto* shaderAsset = m_context.LoadSubAsset<SubAssetVertexShader>(name);
|
||||||
|
if (!shaderAsset)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
const auto* shader = shaderAsset->Asset();
|
||||||
|
assert(shader->prog.loadDef.program && shader->prog.loadDef.programSize > 0);
|
||||||
|
if (!shader->prog.loadDef.program || shader->prog.loadDef.programSize == 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return techset::CommonTechniqueShaderBin{
|
||||||
|
.m_shader_bin = shader->prog.loadDef.program,
|
||||||
|
.m_shader_bin_size = shader->prog.loadDef.programSize,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<techset::CommonTechniqueShaderBin> LoadPixelShader(const std::string& name) override
|
||||||
|
{
|
||||||
|
auto* shaderAsset = m_context.LoadSubAsset<SubAssetPixelShader>(name);
|
||||||
|
if (!shaderAsset)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
const auto* shader = shaderAsset->Asset();
|
||||||
|
assert(shader->prog.loadDef.program && shader->prog.loadDef.programSize > 0);
|
||||||
|
if (!shader->prog.loadDef.program || shader->prog.loadDef.programSize == 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return techset::CommonTechniqueShaderBin{
|
||||||
|
.m_shader_bin = shader->prog.loadDef.program,
|
||||||
|
.m_shader_bin_size = shader->prog.loadDef.programSize,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AssetCreationContext& m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TechniqueCompilerT6 final : public SubAssetCreator<SubAssetTechnique>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TechniqueCompilerT6(MemoryManager& memory, Zone& zone, ISearchPath& searchPath)
|
||||||
|
: m_memory(memory),
|
||||||
|
m_zone(zone),
|
||||||
|
m_search_path(searchPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateSubAsset(const std::string& subAssetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
TechniqueShaderLoaderT6 shaderLoader(context);
|
||||||
|
const auto commonShaderArgCreator = techset::CommonShaderArgCreator::CreateDx11(shaderLoader, context, commonCodeSourceInfos);
|
||||||
|
|
||||||
|
const auto commonTechnique =
|
||||||
|
techset::LoadCommonTechnique(subAssetName, commonCodeSourceInfos, commonRoutingInfos, *commonShaderArgCreator, m_search_path, failure);
|
||||||
|
|
||||||
|
if (!commonTechnique)
|
||||||
|
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
auto* convertedTechnique = ConvertTechnique(*commonTechnique, context, m_memory);
|
||||||
|
assert(convertedTechnique);
|
||||||
|
|
||||||
|
return AssetCreationResult::Success(context.AddSubAsset(AssetRegistration<SubAssetTechnique>(subAssetName, convertedTechnique)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinalizeZone(AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto materials = m_zone.m_pools.PoolAssets<AssetMaterial>();
|
||||||
|
for (auto* materialAsset : materials)
|
||||||
|
{
|
||||||
|
ApplyTechFlagsFromMaterial(*materialAsset->Asset(), m_zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto techniques = context.PoolSubAssets<SubAssetTechnique>();
|
||||||
|
for (auto* techniqueSubAsset : techniques)
|
||||||
|
{
|
||||||
|
auto& technique = *techniqueSubAsset->Asset();
|
||||||
|
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||||
|
{
|
||||||
|
ApplyPrecompiledIndex(technique.passArray[passIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
Zone& m_zone;
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateTechniqueCompilerT6(MemoryManager& memory, Zone& zone, ISearchPath& searchPath)
|
||||||
|
{
|
||||||
|
return std::make_unique<TechniqueCompilerT6>(memory, zone, searchPath);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
12
src/ObjCompiling/Game/T6/Techset/TechniqueCompilerT6.h
Normal file
12
src/ObjCompiling/Game/T6/Techset/TechniqueCompilerT6.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateTechniqueCompilerT6(MemoryManager& memory, Zone& zone, ISearchPath& searchPath);
|
||||||
|
}
|
||||||
128
src/ObjCompiling/Game/T6/Techset/TechsetCompilerT6.cpp
Normal file
128
src/ObjCompiling/Game/T6/Techset/TechsetCompilerT6.cpp
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
#include "TechsetCompilerT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Game/T6/Techset/TechsetConstantsT6.h"
|
||||||
|
#include "Techset/CommonTechsetLoader.h"
|
||||||
|
#include "Techset/TechsetCommon.h"
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
MaterialWorldVertexFormat GetWorldVertexFormat(const std::string& name)
|
||||||
|
{
|
||||||
|
if (name.contains("lit_"))
|
||||||
|
{
|
||||||
|
size_t texCount = 0u, normalCount = 0u;
|
||||||
|
techset::CountWorldVertFormatParameters(name, texCount, normalCount);
|
||||||
|
|
||||||
|
// 0 and 1 seem to be treated equally
|
||||||
|
texCount = std::max(texCount, 1uz);
|
||||||
|
normalCount = std::max(normalCount, 1uz);
|
||||||
|
|
||||||
|
if (texCount == 1 && normalCount == 1)
|
||||||
|
return MTL_WORLDVERT_TEX_1_NRM_1;
|
||||||
|
if (texCount == 2 && normalCount == 1)
|
||||||
|
return MTL_WORLDVERT_TEX_2_NRM_1;
|
||||||
|
if (texCount == 2 && normalCount == 2)
|
||||||
|
return MTL_WORLDVERT_TEX_2_NRM_2;
|
||||||
|
if (texCount == 3 && normalCount == 1)
|
||||||
|
return MTL_WORLDVERT_TEX_3_NRM_1;
|
||||||
|
if (texCount == 3 && normalCount == 2)
|
||||||
|
return MTL_WORLDVERT_TEX_3_NRM_2;
|
||||||
|
if (texCount == 3 && normalCount == 3)
|
||||||
|
return MTL_WORLDVERT_TEX_3_NRM_3;
|
||||||
|
if (texCount == 4 && normalCount == 1)
|
||||||
|
return MTL_WORLDVERT_TEX_4_NRM_1;
|
||||||
|
if (texCount == 4 && normalCount == 2)
|
||||||
|
return MTL_WORLDVERT_TEX_4_NRM_2;
|
||||||
|
if (texCount == 4 && normalCount == 3)
|
||||||
|
return MTL_WORLDVERT_TEX_4_NRM_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<MaterialWorldVertexFormat>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialType GetMaterialType(const std::string& name)
|
||||||
|
{
|
||||||
|
for (unsigned materialTypeIndex = MTL_TYPE_MODEL; materialTypeIndex < MTL_TYPE_COUNT; materialTypeIndex++)
|
||||||
|
{
|
||||||
|
if (name.starts_with(g_materialTypeInfo[materialTypeIndex].techniqueSetPrefix))
|
||||||
|
return static_cast<MaterialType>(materialTypeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MTL_TYPE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyMaterialTypeToTechnique(MaterialTechnique& technique, const MaterialType materialType)
|
||||||
|
{
|
||||||
|
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||||
|
{
|
||||||
|
technique.passArray[passIndex].materialType = materialType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialTechniqueSet* ConvertTechniqueSet(const techset::CommonTechset& commonTechset, MemoryManager& memory)
|
||||||
|
{
|
||||||
|
auto* techset = memory.Alloc<MaterialTechniqueSet>();
|
||||||
|
techset->name = memory.Dup(commonTechset.m_name.c_str());
|
||||||
|
techset->worldVertFormat = GetWorldVertexFormat(commonTechset.m_name);
|
||||||
|
|
||||||
|
return techset;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TechsetCompilerT6 final : public AssetCreator<AssetTechniqueSet>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TechsetCompilerT6(ISearchPath& searchPath, MemoryManager& memory)
|
||||||
|
: m_search_path(searchPath),
|
||||||
|
m_memory(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
const auto commonTechset = techset::LoadCommonTechset(assetName, commonTechniqueTypeNames, m_search_path, failure);
|
||||||
|
if (!commonTechset)
|
||||||
|
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
auto* techset = ConvertTechniqueSet(*commonTechset, m_memory);
|
||||||
|
const auto materialType = GetMaterialType(assetName);
|
||||||
|
|
||||||
|
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(MaterialTechniqueSet::techniques)>; techniqueIndex++)
|
||||||
|
{
|
||||||
|
const auto& techniqueName = commonTechset->m_technique_names[techniqueIndex];
|
||||||
|
if (techniqueName.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto* technique = context.LoadSubAsset<SubAssetTechnique>(techniqueName);
|
||||||
|
if (!technique)
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
|
techset->techniques[techniqueIndex] = technique->Asset();
|
||||||
|
|
||||||
|
// Another techset may override this for the technique
|
||||||
|
// but the game determines the material type by techset name.
|
||||||
|
// So this may just be a constraint that cannot be changed.
|
||||||
|
ApplyMaterialTypeToTechnique(*techset->techniques[techniqueIndex], materialType);
|
||||||
|
|
||||||
|
// Precompiled index?
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetTechniqueSet>(assetName, techset)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<IAssetCreator> CreateCompilerT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||||
|
{
|
||||||
|
return std::make_unique<TechsetCompilerT6>(searchPath, memory);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
12
src/ObjCompiling/Game/T6/Techset/TechsetCompilerT6.h
Normal file
12
src/ObjCompiling/Game/T6/Techset/TechsetCompilerT6.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<IAssetCreator> CreateCompilerT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||||
|
} // namespace techset
|
||||||
57
src/ObjCompiling/Game/T6/Techset/VertexDeclCompilerT6.cpp
Normal file
57
src/ObjCompiling/Game/T6/Techset/VertexDeclCompilerT6.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include "VertexDeclCompilerT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Game/T6/Techset/TechsetConstantsT6.h"
|
||||||
|
#include "Techset/CommonVertexDeclCreator.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class VertexDeclCompilerT6 final : public SubAssetCreator<SubAssetVertexDecl>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit VertexDeclCompilerT6(MemoryManager& memory)
|
||||||
|
: m_memory(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateSubAsset(const std::string& subAssetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto commonVertexDecl = techset::CreateVertexDeclFromName(subAssetName, commonRoutingInfos);
|
||||||
|
if (!commonVertexDecl)
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
|
if (commonVertexDecl->m_routing.size() > std::extent_v<decltype(MaterialVertexStreamRouting::data)>)
|
||||||
|
{
|
||||||
|
con::error("Vertex declaration can only have up to {} routing entries", std::extent_v<decltype(MaterialVertexStreamRouting::data)>);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* vertexDecl = m_memory.Alloc<MaterialVertexDeclaration>();
|
||||||
|
|
||||||
|
for (const auto& commonRoutingEntry : commonVertexDecl->m_routing)
|
||||||
|
{
|
||||||
|
vertexDecl->routing.data[vertexDecl->streamCount].source = commonRoutingEntry.m_source;
|
||||||
|
vertexDecl->routing.data[vertexDecl->streamCount].dest = commonRoutingEntry.m_destination;
|
||||||
|
vertexDecl->hasOptionalSource = vertexDecl->hasOptionalSource || commonRoutingEntry.m_source >= STREAM_SRC_OPTIONAL_BEGIN;
|
||||||
|
|
||||||
|
vertexDecl->streamCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetCreationResult::Success(context.AddSubAsset(AssetRegistration<SubAssetVertexDecl>(subAssetName, vertexDecl)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateVertexDeclCompilerT6(MemoryManager& memory)
|
||||||
|
{
|
||||||
|
return std::make_unique<VertexDeclCompilerT6>(memory);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
11
src/ObjCompiling/Game/T6/Techset/VertexDeclCompilerT6.h
Normal file
11
src/ObjCompiling/Game/T6/Techset/VertexDeclCompilerT6.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateVertexDeclCompilerT6(MemoryManager& memory);
|
||||||
|
}
|
||||||
700
src/ObjCompiling/Techset/CommonShaderArgCreator.cpp
Normal file
700
src/ObjCompiling/Techset/CommonShaderArgCreator.cpp
Normal file
@@ -0,0 +1,700 @@
|
|||||||
|
#include "CommonShaderArgCreator.h"
|
||||||
|
|
||||||
|
#include "Shader/D3D11ShaderAnalyser.h"
|
||||||
|
#include "Shader/D3D9ShaderAnalyser.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class BaseCommonShaderArgCreator : public techset::CommonShaderArgCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit BaseCommonShaderArgCreator(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos)
|
||||||
|
: m_shader_loader(shaderLoader),
|
||||||
|
m_common_code_source_infos(commonCodeSourceInfos),
|
||||||
|
m_shader_type(techset::CommonTechniqueShaderType::VERTEX),
|
||||||
|
m_bin{},
|
||||||
|
m_tech_flags(0),
|
||||||
|
m_sampler_flags(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override
|
||||||
|
{
|
||||||
|
m_shader_type = shaderType;
|
||||||
|
|
||||||
|
std::optional<techset::CommonTechniqueShaderBin> maybeShader;
|
||||||
|
if (shaderType == techset::CommonTechniqueShaderType::VERTEX)
|
||||||
|
{
|
||||||
|
maybeShader = m_shader_loader.LoadVertexShader(name);
|
||||||
|
}
|
||||||
|
else if (shaderType == techset::CommonTechniqueShaderType::PIXEL)
|
||||||
|
{
|
||||||
|
maybeShader = m_shader_loader.LoadPixelShader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maybeShader)
|
||||||
|
return result::Unexpected<std::string>("Failed to load shader");
|
||||||
|
|
||||||
|
m_bin = *maybeShader;
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> LeaveShader() override
|
||||||
|
{
|
||||||
|
m_bin = {};
|
||||||
|
|
||||||
|
return AutoCreateMissingArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderConstantArgument(const techset::CommonShaderArgCreatorDestination& destination,
|
||||||
|
const techset::CommonCodeConstSource codeConstSource,
|
||||||
|
const unsigned sourceIndex) override
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgDestination commonDestination{};
|
||||||
|
bool isTransposed;
|
||||||
|
std::string errorMessage;
|
||||||
|
if (!FindDestinationForConstant(commonDestination, isTransposed, errorMessage, destination))
|
||||||
|
{
|
||||||
|
if (!errorMessage.empty())
|
||||||
|
return result::Unexpected(std::move(errorMessage));
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("Could not find constant shader input with name {}", destination.m_argument_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AcceptShaderConstantArgument(commonDestination, isTransposed, codeConstSource, sourceIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderSamplerArgument(const techset::CommonShaderArgCreatorDestination& destination,
|
||||||
|
const techset::CommonCodeSamplerSource codeSamplerSource) override
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgDestination commonDestination{};
|
||||||
|
std::string errorMessage;
|
||||||
|
if (!FindDestinationForSampler(commonDestination, errorMessage, destination))
|
||||||
|
{
|
||||||
|
if (!errorMessage.empty())
|
||||||
|
return result::Unexpected(std::move(errorMessage));
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("Could not find sampler shader input with name {}", destination.m_argument_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AcceptShaderSamplerArgument(commonDestination, codeSamplerSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderLiteralArgument(const techset::CommonShaderArgCreatorDestination& destination,
|
||||||
|
const std::array<float, 4>& literalValue) override
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgDestination commonDestination{};
|
||||||
|
bool isTransposed;
|
||||||
|
std::string errorMessage;
|
||||||
|
if (!FindDestinationForConstant(commonDestination, isTransposed, errorMessage, destination))
|
||||||
|
{
|
||||||
|
if (!errorMessage.empty())
|
||||||
|
return result::Unexpected(std::move(errorMessage));
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("Could not find constant shader input with name {}", destination.m_argument_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
techset::CommonShaderArgumentType argumentType{
|
||||||
|
.m_shader_type = m_shader_type,
|
||||||
|
.m_value_type = techset::CommonShaderValueType::LITERAL_CONST,
|
||||||
|
};
|
||||||
|
|
||||||
|
techset::CommonShaderArgValue value{.literal_value = literalValue};
|
||||||
|
|
||||||
|
m_args.emplace_back(argumentType, commonDestination, value);
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const techset::CommonShaderArgCreatorDestination& destination,
|
||||||
|
const unsigned nameHash) override
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgumentType argumentType{
|
||||||
|
.m_shader_type = m_shader_type,
|
||||||
|
.m_value_type = techset::CommonShaderValueType::MATERIAL_CONST,
|
||||||
|
};
|
||||||
|
|
||||||
|
techset::CommonShaderArgDestination commonDestination{};
|
||||||
|
bool isTransposed;
|
||||||
|
std::string errorMessage;
|
||||||
|
if (!FindDestinationForConstant(commonDestination, isTransposed, errorMessage, destination))
|
||||||
|
{
|
||||||
|
if (!errorMessage.empty())
|
||||||
|
return result::Unexpected(std::move(errorMessage));
|
||||||
|
|
||||||
|
argumentType.m_value_type = techset::CommonShaderValueType::MATERIAL_SAMPLER;
|
||||||
|
|
||||||
|
if (!FindDestinationForSampler(commonDestination, errorMessage, destination))
|
||||||
|
{
|
||||||
|
if (!errorMessage.empty())
|
||||||
|
return result::Unexpected(std::move(errorMessage));
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("Could not find shader input with name {}", destination.m_argument_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
techset::CommonShaderArgValue value{.name_hash = nameHash};
|
||||||
|
|
||||||
|
m_args.emplace_back(argumentType, commonDestination, value);
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const techset::CommonShaderArgCreatorDestination& destination,
|
||||||
|
const std::string& nameValue) override
|
||||||
|
{
|
||||||
|
// All game's call R_HashString here which has the same implementation in all games
|
||||||
|
return AcceptShaderMaterialArgument(destination, djb2_xor_nocase(nameValue.c_str(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> FinalizePass(techset::CommonTechnique& technique, techset::CommonPass& pass) override
|
||||||
|
{
|
||||||
|
std::ranges::sort(m_args,
|
||||||
|
[this](const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) -> bool
|
||||||
|
{
|
||||||
|
const auto updateFreq0 = arg0.GetFrequency(m_common_code_source_infos);
|
||||||
|
const auto updateFreq1 = arg1.GetFrequency(m_common_code_source_infos);
|
||||||
|
if (updateFreq0 != updateFreq1)
|
||||||
|
return updateFreq0 < updateFreq1;
|
||||||
|
|
||||||
|
const auto typeNumeric0 = m_common_code_source_infos.GetArgumentTypeNumericValue(arg0.m_type);
|
||||||
|
const auto typeNumeric1 = m_common_code_source_infos.GetArgumentTypeNumericValue(arg1.m_type);
|
||||||
|
assert(typeNumeric0);
|
||||||
|
assert(typeNumeric1);
|
||||||
|
if (*typeNumeric0 != *typeNumeric1)
|
||||||
|
return *typeNumeric0 < *typeNumeric1;
|
||||||
|
|
||||||
|
if (arg0.m_type.m_value_type == techset::CommonShaderValueType::MATERIAL_CONST
|
||||||
|
|| arg0.m_type.m_value_type == techset::CommonShaderValueType::MATERIAL_SAMPLER)
|
||||||
|
{
|
||||||
|
return arg0.m_value.name_hash < arg1.m_value.name_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompareArgumentDestinations(arg0, arg1);
|
||||||
|
});
|
||||||
|
|
||||||
|
technique.m_flags |= m_tech_flags;
|
||||||
|
pass.m_args = std::move(m_args);
|
||||||
|
pass.m_sampler_flags |= m_sampler_flags;
|
||||||
|
|
||||||
|
m_tech_flags = 0;
|
||||||
|
m_args = std::vector<techset::CommonShaderArg>();
|
||||||
|
m_sampler_flags = 0;
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderConstantArgument(const techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
const bool isTransposed,
|
||||||
|
const techset::CommonCodeConstSource codeConstSource,
|
||||||
|
const unsigned sourceIndex)
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgumentType argumentType{
|
||||||
|
.m_shader_type = m_shader_type,
|
||||||
|
.m_value_type = techset::CommonShaderValueType::CODE_CONST,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeConstSource(codeConstSource);
|
||||||
|
if (!maybeInfo)
|
||||||
|
return result::Unexpected<std::string>("Could not find info for code constant");
|
||||||
|
|
||||||
|
const auto isMatrix = maybeInfo->transposedMatrix.has_value();
|
||||||
|
techset::CommonShaderArgCodeConstValue value{
|
||||||
|
.m_index = 0,
|
||||||
|
.m_first_row = 0,
|
||||||
|
.m_row_count = isMatrix ? 4u : 1u,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isMatrix)
|
||||||
|
{
|
||||||
|
if (sourceIndex >= 4)
|
||||||
|
return result::Unexpected(std::format("Index for matrix code const is out of bounds: {} (must be < 4)", sourceIndex));
|
||||||
|
|
||||||
|
value.m_index = isTransposed ? *maybeInfo->transposedMatrix : codeConstSource;
|
||||||
|
value.m_first_row = sourceIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto arrayCount = std::max<unsigned>(maybeInfo->arrayCount, 1u);
|
||||||
|
if (sourceIndex >= arrayCount)
|
||||||
|
return result::Unexpected(std::format("Index for code const is out of bounds: {} (must be < {})", sourceIndex, arrayCount));
|
||||||
|
|
||||||
|
value.m_index = codeConstSource + static_cast<techset::CommonCodeConstSource>(sourceIndex);
|
||||||
|
value.m_first_row = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_args.emplace_back(argumentType, commonDestination, techset::CommonShaderArgValue{.code_const_source = value});
|
||||||
|
if (maybeInfo->techFlags)
|
||||||
|
m_tech_flags |= *maybeInfo->techFlags;
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AcceptShaderSamplerArgument(const techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
const techset::CommonCodeSamplerSource codeSamplerSource)
|
||||||
|
{
|
||||||
|
techset::CommonShaderArgumentType argumentType{
|
||||||
|
.m_shader_type = m_shader_type,
|
||||||
|
.m_value_type = techset::CommonShaderValueType::CODE_SAMPLER,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto maybeInfo = m_common_code_source_infos.GetInfoForCodeSamplerSource(codeSamplerSource);
|
||||||
|
if (!maybeInfo)
|
||||||
|
return result::Unexpected<std::string>("Could not find info for code sampler");
|
||||||
|
|
||||||
|
m_args.emplace_back(argumentType, commonDestination, techset::CommonShaderArgValue{.code_sampler_source = codeSamplerSource});
|
||||||
|
if (maybeInfo->techFlags)
|
||||||
|
m_tech_flags |= *maybeInfo->techFlags;
|
||||||
|
if (maybeInfo->customSamplerIndex)
|
||||||
|
m_sampler_flags |= (1 << *maybeInfo->customSamplerIndex);
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] virtual size_t CompareArgumentDestinations(const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) const = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual bool FindDestinationForConstant(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
bool& isTransposed,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) = 0;
|
||||||
|
[[nodiscard]] virtual bool FindDestinationForSampler(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) = 0;
|
||||||
|
|
||||||
|
virtual result::Expected<NoResult, std::string> AutoCreateMissingArgs() = 0;
|
||||||
|
|
||||||
|
techset::ITechniqueShaderLoader& m_shader_loader;
|
||||||
|
techset::CommonCodeSourceInfos& m_common_code_source_infos;
|
||||||
|
|
||||||
|
techset::CommonTechniqueShaderType m_shader_type;
|
||||||
|
techset::CommonTechniqueShaderBin m_bin;
|
||||||
|
|
||||||
|
std::vector<techset::CommonShaderArg> m_args;
|
||||||
|
uint64_t m_tech_flags;
|
||||||
|
unsigned m_sampler_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonShaderArgCreatorDx9 final : public BaseCommonShaderArgCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CommonShaderArgCreatorDx9(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos)
|
||||||
|
: BaseCommonShaderArgCreator(shaderLoader, commonCodeSourceInfos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override
|
||||||
|
{
|
||||||
|
auto result = BaseCommonShaderArgCreator::EnterShader(shaderType, name);
|
||||||
|
if (!result)
|
||||||
|
return std::move(result);
|
||||||
|
|
||||||
|
m_shader_info = d3d9::ShaderAnalyser::GetShaderInfo(m_bin.m_shader_bin, m_bin.m_shader_bin_size);
|
||||||
|
if (!m_shader_info)
|
||||||
|
return result::Unexpected(std::format("Failed to analyse dx9 shader {}", name));
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> LeaveShader() override
|
||||||
|
{
|
||||||
|
auto result = BaseCommonShaderArgCreator::LeaveShader();
|
||||||
|
m_shader_info = nullptr;
|
||||||
|
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] size_t CompareArgumentDestinations(const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) const override
|
||||||
|
{
|
||||||
|
return arg0.m_destination.dx9.m_destination_register < arg1.m_destination.dx9.m_destination_register;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool FindDestinationForConstant(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
bool& isTransposed,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) override
|
||||||
|
{
|
||||||
|
assert(m_shader_info);
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool FindDestinationForSampler(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) override
|
||||||
|
{
|
||||||
|
assert(m_shader_info);
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AutoCreateMissingArgs() override
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<d3d9::ShaderInfo> m_shader_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonShaderArgCreatorDx11 final : public BaseCommonShaderArgCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CommonShaderArgCreatorDx11(techset::ITechniqueShaderLoader& shaderLoader, techset::CommonCodeSourceInfos& commonCodeSourceInfos)
|
||||||
|
: BaseCommonShaderArgCreator(shaderLoader, commonCodeSourceInfos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> EnterShader(const techset::CommonTechniqueShaderType shaderType, const std::string& name) override
|
||||||
|
{
|
||||||
|
auto result = BaseCommonShaderArgCreator::EnterShader(shaderType, name);
|
||||||
|
if (!result)
|
||||||
|
return std::move(result);
|
||||||
|
|
||||||
|
m_shader_info = d3d11::ShaderAnalyser::GetShaderInfo(m_bin.m_shader_bin, m_bin.m_shader_bin_size);
|
||||||
|
if (!m_shader_info)
|
||||||
|
return result::Unexpected(std::format("Failed to analyse dx11 shader {}", name));
|
||||||
|
|
||||||
|
CountShaderArgs();
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> LeaveShader() override
|
||||||
|
{
|
||||||
|
auto result = BaseCommonShaderArgCreator::LeaveShader();
|
||||||
|
m_shader_info = nullptr;
|
||||||
|
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] size_t CompareArgumentDestinations(const techset::CommonShaderArg& arg0, const techset::CommonShaderArg& arg1) const override
|
||||||
|
{
|
||||||
|
if (arg0.m_destination.dx11.m_buffer != arg1.m_destination.dx11.m_buffer)
|
||||||
|
return arg0.m_destination.dx11.m_buffer < arg1.m_destination.dx11.m_buffer;
|
||||||
|
|
||||||
|
return LocationComparisonValue(arg0) < LocationComparisonValue(arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static size_t LocationComparisonValue(const techset::CommonShaderArg& arg)
|
||||||
|
{
|
||||||
|
switch (arg.m_type.m_value_type)
|
||||||
|
{
|
||||||
|
case techset::CommonShaderValueType::LITERAL_CONST:
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_CONST:
|
||||||
|
case techset::CommonShaderValueType::CODE_CONST:
|
||||||
|
return arg.m_destination.dx11.m_location.constant_buffer_offset;
|
||||||
|
case techset::CommonShaderValueType::MATERIAL_SAMPLER:
|
||||||
|
case techset::CommonShaderValueType::CODE_SAMPLER:
|
||||||
|
return arg.m_destination.dx11.m_location.sampler_index;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool FindDestinationForConstant(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
bool& isTransposed,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) override
|
||||||
|
{
|
||||||
|
assert(m_shader_info);
|
||||||
|
|
||||||
|
auto usedConstantIndex = 0uz;
|
||||||
|
for (const auto& buffer : m_shader_info->m_constant_buffers)
|
||||||
|
{
|
||||||
|
const auto bufferBinding =
|
||||||
|
std::ranges::find_if(m_shader_info->m_bound_resources,
|
||||||
|
[buffer](const d3d11::BoundResource& boundResource)
|
||||||
|
{
|
||||||
|
return boundResource.m_type == d3d11::BoundResourceType::CBUFFER && boundResource.m_name == buffer.m_name;
|
||||||
|
});
|
||||||
|
if (bufferBinding == m_shader_info->m_bound_resources.end())
|
||||||
|
{
|
||||||
|
errorMessage = std::format("Failed to find binding for constant buffer {}", buffer.m_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto variableIterator = buffer.m_variables.begin();
|
||||||
|
const auto variableEnd = buffer.m_variables.end();
|
||||||
|
for (; variableIterator != variableEnd; ++variableIterator)
|
||||||
|
{
|
||||||
|
if (variableIterator->m_name == input.m_argument_name)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (variableIterator->m_is_used)
|
||||||
|
usedConstantIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variableIterator != variableEnd)
|
||||||
|
{
|
||||||
|
const auto variableElementCount = std::max<unsigned>(variableIterator->m_element_count, 1);
|
||||||
|
const auto inputArgumentIndex = input.m_argument_index.value_or(0);
|
||||||
|
if (inputArgumentIndex >= variableElementCount)
|
||||||
|
{
|
||||||
|
errorMessage = std::format("Shader variable {} only has {} elements", variableIterator->m_name, variableElementCount);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto variableElementSize = variableIterator->m_size / variableElementCount;
|
||||||
|
commonDestination.dx11.m_location.constant_buffer_offset = variableIterator->m_offset + variableElementSize * inputArgumentIndex;
|
||||||
|
commonDestination.dx11.m_size = variableElementSize;
|
||||||
|
commonDestination.dx11.m_buffer = bufferBinding->m_bind_point;
|
||||||
|
isTransposed = variableIterator->m_variable_class == d3d11::VariableClass::MATRIX_COLUMNS;
|
||||||
|
|
||||||
|
m_const_arg_added[usedConstantIndex] = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool FindDestinationForSampler(techset::CommonShaderArgDestination& commonDestination,
|
||||||
|
std::string& errorMessage,
|
||||||
|
const techset::CommonShaderArgCreatorDestination& input) override
|
||||||
|
{
|
||||||
|
assert(m_shader_info);
|
||||||
|
|
||||||
|
// Find texture and its index
|
||||||
|
size_t textureIndex = 0;
|
||||||
|
auto maybeTextureResource = m_shader_info->m_bound_resources.begin();
|
||||||
|
const auto resourceEnd = m_shader_info->m_bound_resources.end();
|
||||||
|
for (; maybeTextureResource != resourceEnd; ++maybeTextureResource)
|
||||||
|
{
|
||||||
|
if (maybeTextureResource->m_type != d3d11::BoundResourceType::TEXTURE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (maybeTextureResource->m_name == input.m_argument_name)
|
||||||
|
break;
|
||||||
|
|
||||||
|
textureIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find sampler
|
||||||
|
const auto maybeSamplerResource =
|
||||||
|
std::ranges::find_if(m_shader_info->m_bound_resources,
|
||||||
|
[input](const d3d11::BoundResource& boundResource)
|
||||||
|
{
|
||||||
|
return boundResource.m_type == d3d11::BoundResourceType::SAMPLER && boundResource.m_name == input.m_argument_name;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto hasTextureResource = maybeTextureResource != resourceEnd;
|
||||||
|
const auto hasSamplerResource = maybeSamplerResource != resourceEnd;
|
||||||
|
|
||||||
|
if (!hasSamplerResource && !hasTextureResource)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (hasSamplerResource && !hasTextureResource)
|
||||||
|
{
|
||||||
|
errorMessage = std::format("Shader binds a sampler for argument {} but not a texture", input.m_argument_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(hasTextureResource);
|
||||||
|
|
||||||
|
commonDestination.dx11.m_location.texture_index = maybeTextureResource->m_bind_point;
|
||||||
|
|
||||||
|
// The game seems to be fine with not being able to find the sampler
|
||||||
|
// and just takes the same index as the texture
|
||||||
|
if (hasSamplerResource)
|
||||||
|
commonDestination.dx11.m_location.sampler_index = maybeSamplerResource->m_bind_point;
|
||||||
|
else
|
||||||
|
commonDestination.dx11.m_location.sampler_index = maybeTextureResource->m_bind_point;
|
||||||
|
|
||||||
|
commonDestination.dx11.m_size = maybeTextureResource->m_bind_count;
|
||||||
|
commonDestination.dx11.m_buffer = 0;
|
||||||
|
|
||||||
|
m_texture_arg_added[textureIndex] = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AutoCreateMissingArgs() override
|
||||||
|
{
|
||||||
|
size_t usedConstantCount = 0;
|
||||||
|
size_t textureCount = 0;
|
||||||
|
|
||||||
|
for (const auto& buffer : m_shader_info->m_constant_buffers)
|
||||||
|
{
|
||||||
|
const auto bufferBinding =
|
||||||
|
std::ranges::find_if(m_shader_info->m_bound_resources,
|
||||||
|
[buffer](const d3d11::BoundResource& boundResource)
|
||||||
|
{
|
||||||
|
return boundResource.m_type == d3d11::BoundResourceType::CBUFFER && boundResource.m_name == buffer.m_name;
|
||||||
|
});
|
||||||
|
if (bufferBinding == m_shader_info->m_bound_resources.end())
|
||||||
|
return result::Unexpected(std::format("Failed to find binding for constant buffer {}", buffer.m_name));
|
||||||
|
|
||||||
|
for (const auto& variable : buffer.m_variables)
|
||||||
|
{
|
||||||
|
if (!variable.m_is_used)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_const_arg_added[usedConstantCount++])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto result = AutoCreateConstantArg(variable, bufferBinding->m_bind_point);
|
||||||
|
if (!result)
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& maybeTextureResource : m_shader_info->m_bound_resources)
|
||||||
|
{
|
||||||
|
if (maybeTextureResource.m_type != d3d11::BoundResourceType::TEXTURE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_texture_arg_added[textureCount++])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto maybeSamplerResource = std::ranges::find_if(m_shader_info->m_bound_resources,
|
||||||
|
[maybeTextureResource](const d3d11::BoundResource& boundResource)
|
||||||
|
{
|
||||||
|
return boundResource.m_type == d3d11::BoundResourceType::SAMPLER
|
||||||
|
&& boundResource.m_name == maybeTextureResource.m_name;
|
||||||
|
});
|
||||||
|
|
||||||
|
auto result = AutoCreateSamplerArg(maybeTextureResource,
|
||||||
|
maybeSamplerResource != m_shader_info->m_bound_resources.end() ? maybeSamplerResource->m_bind_point
|
||||||
|
: maybeTextureResource.m_bind_point);
|
||||||
|
if (!result)
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CountShaderArgs()
|
||||||
|
{
|
||||||
|
size_t usedConstantCount = 0;
|
||||||
|
size_t textureCount = 0;
|
||||||
|
|
||||||
|
for (const auto& buffer : m_shader_info->m_constant_buffers)
|
||||||
|
{
|
||||||
|
for (const auto& variable : buffer.m_variables)
|
||||||
|
{
|
||||||
|
if (variable.m_is_used)
|
||||||
|
usedConstantCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& resource : m_shader_info->m_bound_resources)
|
||||||
|
{
|
||||||
|
if (resource.m_type == d3d11::BoundResourceType::TEXTURE)
|
||||||
|
textureCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_const_arg_added = std::vector(usedConstantCount, false);
|
||||||
|
m_texture_arg_added = std::vector(textureCount, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AutoCreateConstantArg(const d3d11::ConstantBufferVariable& variable, const size_t bufferIndex)
|
||||||
|
{
|
||||||
|
const auto maybeCodeConst = m_common_code_source_infos.GetCodeConstSourceForAccessor(variable.m_name);
|
||||||
|
if (!maybeCodeConst)
|
||||||
|
{
|
||||||
|
// Some variables are simply not added as args for some reason
|
||||||
|
if (m_common_code_source_infos.IsArgAccessorIgnored(variable.m_name))
|
||||||
|
return NoResult{};
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("Missing assignment to shader constant {}", variable.m_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto constInfo = m_common_code_source_infos.GetInfoForCodeConstSource(*maybeCodeConst);
|
||||||
|
if (!constInfo)
|
||||||
|
return result::Unexpected(std::format("Missing info for code const {}", variable.m_name));
|
||||||
|
|
||||||
|
const auto variableElementCount = std::max<unsigned>(variable.m_element_count, 1);
|
||||||
|
const auto variableElementSize = variable.m_size / variableElementCount;
|
||||||
|
const auto infoArrayCount = std::max<unsigned>(constInfo->arrayCount, 1);
|
||||||
|
if (variableElementCount > infoArrayCount)
|
||||||
|
{
|
||||||
|
return result::Unexpected(std::format("Could not auto create argument for constant {} as it has more elements ({}) than the code constant ({})",
|
||||||
|
variable.m_name,
|
||||||
|
variableElementCount,
|
||||||
|
infoArrayCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
techset::CommonShaderArgDestination commonDestination;
|
||||||
|
commonDestination.dx11.m_size = variableElementSize;
|
||||||
|
commonDestination.dx11.m_buffer = static_cast<unsigned>(bufferIndex);
|
||||||
|
const auto isTransposed = variable.m_variable_class == d3d11::VariableClass::MATRIX_COLUMNS;
|
||||||
|
for (auto elementIndex = 0u; elementIndex < variableElementCount; elementIndex++)
|
||||||
|
{
|
||||||
|
commonDestination.dx11.m_location.constant_buffer_offset = variable.m_offset + variableElementSize * elementIndex;
|
||||||
|
auto result = AcceptShaderConstantArgument(commonDestination, isTransposed, *maybeCodeConst, elementIndex);
|
||||||
|
if (!result)
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constInfo->techFlags)
|
||||||
|
m_tech_flags |= *constInfo->techFlags;
|
||||||
|
|
||||||
|
return NoResult{};
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> AutoCreateSamplerArg(const d3d11::BoundResource& textureResource, const unsigned samplerBindPoint)
|
||||||
|
{
|
||||||
|
const auto maybeCodeSampler = m_common_code_source_infos.GetCodeSamplerSourceForAccessor(textureResource.m_name);
|
||||||
|
if (!maybeCodeSampler)
|
||||||
|
return result::Unexpected(std::format("Missing assignment to shader texture {}", textureResource.m_name));
|
||||||
|
|
||||||
|
const auto samplerInfo = m_common_code_source_infos.GetInfoForCodeSamplerSource(*maybeCodeSampler);
|
||||||
|
if (!samplerInfo)
|
||||||
|
return result::Unexpected(std::format("Missing info for code sampler {}", textureResource.m_name));
|
||||||
|
|
||||||
|
techset::CommonShaderArgDestination commonDestination;
|
||||||
|
commonDestination.dx11.m_location.texture_index = textureResource.m_bind_point;
|
||||||
|
commonDestination.dx11.m_location.sampler_index = samplerBindPoint;
|
||||||
|
commonDestination.dx11.m_size = textureResource.m_bind_count;
|
||||||
|
commonDestination.dx11.m_buffer = 0;
|
||||||
|
|
||||||
|
if (samplerInfo->techFlags)
|
||||||
|
m_tech_flags |= *samplerInfo->techFlags;
|
||||||
|
if (samplerInfo->customSamplerIndex)
|
||||||
|
m_sampler_flags |= (1 << *samplerInfo->customSamplerIndex);
|
||||||
|
|
||||||
|
return AcceptShaderSamplerArgument(commonDestination, *maybeCodeSampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<d3d11::ShaderInfo> m_shader_info;
|
||||||
|
std::vector<bool> m_const_arg_added;
|
||||||
|
std::vector<bool> m_texture_arg_added;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
CommonShaderArgCreatorDestination::CommonShaderArgCreatorDestination(std::string argumentName)
|
||||||
|
: m_argument_name(std::move(argumentName))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonShaderArgCreatorDestination::CommonShaderArgCreatorDestination(std::string argumentName, const unsigned argumentIndex)
|
||||||
|
: m_argument_name(std::move(argumentName)),
|
||||||
|
m_argument_index(argumentIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CommonShaderArgCreator>
|
||||||
|
CommonShaderArgCreator::CreateDx9(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos)
|
||||||
|
{
|
||||||
|
return std::make_unique<CommonShaderArgCreatorDx9>(shaderLoader, commonCodeSourceInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CommonShaderArgCreator>
|
||||||
|
CommonShaderArgCreator::CreateDx11(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos)
|
||||||
|
{
|
||||||
|
return std::make_unique<CommonShaderArgCreatorDx11>(shaderLoader, commonCodeSourceInfos);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
62
src/ObjCompiling/Techset/CommonShaderArgCreator.h
Normal file
62
src/ObjCompiling/Techset/CommonShaderArgCreator.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/AssetCreationContext.h"
|
||||||
|
#include "Techset/CommonTechnique.h"
|
||||||
|
#include "Utils/Result.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
class ITechniqueShaderLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ITechniqueShaderLoader() = default;
|
||||||
|
virtual ~ITechniqueShaderLoader() = default;
|
||||||
|
|
||||||
|
virtual std::optional<CommonTechniqueShaderBin> LoadVertexShader(const std::string& name) = 0;
|
||||||
|
virtual std::optional<CommonTechniqueShaderBin> LoadPixelShader(const std::string& name) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonShaderArgCreatorDestination
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string m_argument_name;
|
||||||
|
std::optional<unsigned> m_argument_index;
|
||||||
|
|
||||||
|
CommonShaderArgCreatorDestination() = default;
|
||||||
|
explicit CommonShaderArgCreatorDestination(std::string argumentName);
|
||||||
|
CommonShaderArgCreatorDestination(std::string argumentName, unsigned argumentIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonShaderArgCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommonShaderArgCreator() = default;
|
||||||
|
virtual ~CommonShaderArgCreator() = default;
|
||||||
|
|
||||||
|
virtual result::Expected<NoResult, std::string> EnterShader(CommonTechniqueShaderType shaderType, const std::string& name) = 0;
|
||||||
|
virtual result::Expected<NoResult, std::string> LeaveShader() = 0;
|
||||||
|
|
||||||
|
virtual result::Expected<NoResult, std::string>
|
||||||
|
AcceptShaderConstantArgument(const CommonShaderArgCreatorDestination& destination, CommonCodeConstSource codeConstSource, unsigned sourceIndex) = 0;
|
||||||
|
virtual result::Expected<NoResult, std::string> AcceptShaderSamplerArgument(const CommonShaderArgCreatorDestination& destination,
|
||||||
|
CommonCodeSamplerSource codeSamplerSource) = 0;
|
||||||
|
virtual result::Expected<NoResult, std::string> AcceptShaderLiteralArgument(const CommonShaderArgCreatorDestination& destination,
|
||||||
|
const std::array<float, 4>& literalValue) = 0;
|
||||||
|
virtual result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const CommonShaderArgCreatorDestination& destination,
|
||||||
|
unsigned nameHash) = 0;
|
||||||
|
virtual result::Expected<NoResult, std::string> AcceptShaderMaterialArgument(const CommonShaderArgCreatorDestination& destination,
|
||||||
|
const std::string& nameValue) = 0;
|
||||||
|
|
||||||
|
virtual result::Expected<NoResult, std::string> FinalizePass(techset::CommonTechnique& technique, CommonPass& pass) = 0;
|
||||||
|
|
||||||
|
static std::unique_ptr<CommonShaderArgCreator>
|
||||||
|
CreateDx9(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos);
|
||||||
|
static std::unique_ptr<CommonShaderArgCreator>
|
||||||
|
CreateDx11(ITechniqueShaderLoader& shaderLoader, AssetCreationContext& context, CommonCodeSourceInfos& commonCodeSourceInfos);
|
||||||
|
};
|
||||||
|
} // namespace techset
|
||||||
47
src/ObjCompiling/Techset/CommonTechniqueLoader.cpp
Normal file
47
src/ObjCompiling/Techset/CommonTechniqueLoader.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "CommonTechniqueLoader.h"
|
||||||
|
|
||||||
|
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||||
|
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||||
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
|
#include "Parsing/TechniqueFileParser.h"
|
||||||
|
#include "Techset/TechsetCommon.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<CommonTechnique> LoadCommonTechnique(const std::string& techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& commonShaderArgCreator,
|
||||||
|
ISearchPath& searchPath,
|
||||||
|
bool& failure)
|
||||||
|
{
|
||||||
|
failure = false;
|
||||||
|
|
||||||
|
const auto fileName = GetFileNameForTechniqueName(techniqueName);
|
||||||
|
const auto techniqueFile = searchPath.Open(fileName);
|
||||||
|
if (!techniqueFile.IsOpen())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
SimpleLexer::Config lexerConfig;
|
||||||
|
lexerConfig.m_emit_new_line_tokens = false;
|
||||||
|
lexerConfig.m_read_strings = true;
|
||||||
|
lexerConfig.m_string_escape_sequences = false;
|
||||||
|
lexerConfig.m_read_integer_numbers = true;
|
||||||
|
lexerConfig.m_read_floating_point_numbers = true;
|
||||||
|
|
||||||
|
const auto baseStream = std::make_unique<ParserSingleInputStream>(*techniqueFile.m_stream, fileName);
|
||||||
|
const auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(baseStream.get());
|
||||||
|
const auto lexer = std::make_unique<SimpleLexer>(commentProxy.get(), std::move(lexerConfig));
|
||||||
|
|
||||||
|
const auto parser = std::make_unique<TechniqueParser>(*lexer, techniqueName, codeSourceInfos, routingInfos, commonShaderArgCreator);
|
||||||
|
|
||||||
|
const auto success = parser->Parse();
|
||||||
|
if (success)
|
||||||
|
return parser->GetParsingResult();
|
||||||
|
|
||||||
|
failure = true;
|
||||||
|
con::error("Parsing technique file \"{}\" failed!", fileName);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
18
src/ObjCompiling/Techset/CommonTechniqueLoader.h
Normal file
18
src/ObjCompiling/Techset/CommonTechniqueLoader.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/AssetCreationContext.h"
|
||||||
|
#include "CommonShaderArgCreator.h"
|
||||||
|
#include "Techset/CommonTechnique.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<CommonTechnique> LoadCommonTechnique(const std::string& techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& commonShaderArgCreator,
|
||||||
|
ISearchPath& searchPath,
|
||||||
|
bool& failure);
|
||||||
|
} // namespace techset
|
||||||
48
src/ObjCompiling/Techset/CommonTechsetLoader.cpp
Normal file
48
src/ObjCompiling/Techset/CommonTechsetLoader.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include "CommonTechsetLoader.h"
|
||||||
|
|
||||||
|
#include "Parsing/IParserLineStream.h"
|
||||||
|
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||||
|
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||||
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
|
#include "Techset/Parsing/TechsetFileParser.h"
|
||||||
|
#include "Techset/TechsetCommon.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<CommonTechset>
|
||||||
|
LoadCommonTechset(const std::string& assetName, const CommonTechniqueTypeNames& techniqueTypeNames, ISearchPath& searchPath, bool& failure)
|
||||||
|
{
|
||||||
|
failure = false;
|
||||||
|
|
||||||
|
const auto fileName = GetFileNameForTechsetName(assetName);
|
||||||
|
const auto techniqueFile = searchPath.Open(fileName);
|
||||||
|
if (!techniqueFile.IsOpen())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
SimpleLexer::Config lexerConfig;
|
||||||
|
lexerConfig.m_emit_new_line_tokens = false;
|
||||||
|
lexerConfig.m_read_strings = true;
|
||||||
|
lexerConfig.m_string_escape_sequences = false;
|
||||||
|
lexerConfig.m_read_integer_numbers = false;
|
||||||
|
lexerConfig.m_read_floating_point_numbers = false;
|
||||||
|
|
||||||
|
ParserSingleInputStream baseStream(*techniqueFile.m_stream, fileName);
|
||||||
|
CommentRemovingStreamProxy commentProxy(&baseStream);
|
||||||
|
const auto lexer = std::make_unique<SimpleLexer>(&commentProxy, std::move(lexerConfig));
|
||||||
|
|
||||||
|
const auto parser = std::make_unique<TechsetParser>(*lexer, assetName, techniqueTypeNames);
|
||||||
|
|
||||||
|
const auto success = parser->Parse();
|
||||||
|
if (success)
|
||||||
|
return parser->GetParsingResult();
|
||||||
|
|
||||||
|
con::error("Parsing techset file \"{}\" failed!", fileName);
|
||||||
|
failure = true;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
12
src/ObjCompiling/Techset/CommonTechsetLoader.h
Normal file
12
src/ObjCompiling/Techset/CommonTechsetLoader.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/AssetCreationContext.h"
|
||||||
|
#include "Techset/CommonTechset.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<CommonTechset>
|
||||||
|
LoadCommonTechset(const std::string& assetName, const CommonTechniqueTypeNames& techniqueTypeNames, ISearchPath& searchPath, bool& failure);
|
||||||
|
} // namespace techset
|
||||||
131
src/ObjCompiling/Techset/LiteralConstsZoneState.h
Normal file
131
src/ObjCompiling/Techset/LiteralConstsZoneState.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IZoneAssetCreationState.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <concepts>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
template<std::floating_point T> class LiteralConst
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using game_ptr_t = const T (*)[4];
|
||||||
|
|
||||||
|
LiteralConst() = default;
|
||||||
|
|
||||||
|
LiteralConst(T v0, T v1, T v2, T v3)
|
||||||
|
: m_value({v0, v1, v2, v3})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit LiteralConst(std::array<T, 4> value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
if (lhs.m_value[0] < rhs.m_value[0])
|
||||||
|
return true;
|
||||||
|
if (lhs.m_value[0] > rhs.m_value[0])
|
||||||
|
return false;
|
||||||
|
if (lhs.m_value[1] < rhs.m_value[1])
|
||||||
|
return true;
|
||||||
|
if (lhs.m_value[1] > rhs.m_value[1])
|
||||||
|
return false;
|
||||||
|
if (lhs.m_value[2] < rhs.m_value[2])
|
||||||
|
return true;
|
||||||
|
if (lhs.m_value[2] > rhs.m_value[2])
|
||||||
|
return false;
|
||||||
|
if (lhs.m_value[3] < rhs.m_value[3])
|
||||||
|
return true;
|
||||||
|
if (lhs.m_value[3] > rhs.m_value[3])
|
||||||
|
return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_value == rhs.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<=(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
return !(rhs < lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>=(const LiteralConst& lhs, const LiteralConst& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
game_ptr_t GamePtr() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<game_ptr_t>(m_value.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<T, 4> m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::floating_point T> struct LiteralConstHash
|
||||||
|
{
|
||||||
|
std::size_t operator()(const LiteralConst<T>& v) const noexcept
|
||||||
|
{
|
||||||
|
std::size_t seed = 0x1DDB76B3;
|
||||||
|
seed ^= (seed << 6) + (seed >> 2) + 0x0354144B + std::hash<T>()(v.m_value[0]);
|
||||||
|
seed ^= (seed << 6) + (seed >> 2) + 0x66847B5C + std::hash<T>()(v.m_value[1]);
|
||||||
|
seed ^= (seed << 6) + (seed >> 2) + 0x77399D60 + std::hash<T>()(v.m_value[2]);
|
||||||
|
seed ^= (seed << 6) + (seed >> 2) + 0x477AF9AB + std::hash<T>()(v.m_value[3]);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::floating_point T> class LiteralConstsZoneState : public IZoneAssetCreationState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using literal_t = LiteralConst<T>;
|
||||||
|
|
||||||
|
LiteralConstsZoneState()
|
||||||
|
: m_memory(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inject(ZoneAssetCreationInjection& inject) override
|
||||||
|
{
|
||||||
|
m_memory = &inject.m_zone.Memory();
|
||||||
|
}
|
||||||
|
|
||||||
|
literal_t* GetAllocatedLiteral(const literal_t& literal)
|
||||||
|
{
|
||||||
|
const auto& existingEntry = m_allocated_literals.find(literal);
|
||||||
|
|
||||||
|
if (existingEntry != m_allocated_literals.end())
|
||||||
|
return existingEntry->second;
|
||||||
|
|
||||||
|
auto* newLiteral = m_memory->Alloc<literal_t>();
|
||||||
|
newLiteral->m_value[0] = literal.m_value[0];
|
||||||
|
newLiteral->m_value[1] = literal.m_value[1];
|
||||||
|
newLiteral->m_value[2] = literal.m_value[2];
|
||||||
|
newLiteral->m_value[3] = literal.m_value[3];
|
||||||
|
m_allocated_literals.emplace(literal, newLiteral);
|
||||||
|
|
||||||
|
return newLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<literal_t, literal_t*, LiteralConstHash<T>> m_allocated_literals;
|
||||||
|
MemoryManager* m_memory;
|
||||||
|
};
|
||||||
|
} // namespace techset
|
||||||
@@ -23,10 +23,8 @@ namespace techset
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
assert(state->m_in_pass == false);
|
assert(!state->m_current_pass);
|
||||||
state->m_in_pass = true;
|
state->m_current_pass = CommonPass();
|
||||||
|
|
||||||
state->m_acceptor->AcceptNextPass();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
@@ -26,20 +26,22 @@ namespace techset
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
assert(state->m_in_pass == true);
|
assert(state->m_current_pass);
|
||||||
|
assert(state->m_technique);
|
||||||
|
|
||||||
std::string errorMessage;
|
auto finalizeResult = state->m_shader_arg_creator.FinalizePass(*state->m_technique, *state->m_current_pass);
|
||||||
if (!state->m_acceptor->AcceptEndPass(errorMessage))
|
if (!finalizeResult.has_value())
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), errorMessage);
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), finalizeResult.error());
|
||||||
|
|
||||||
state->m_in_pass = false;
|
state->m_current_pass->m_vertex_declaration.SortRoutingEntries();
|
||||||
|
state->m_technique->m_passes.emplace_back(std::move(*state->m_current_pass));
|
||||||
|
state->m_current_pass = std::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SequenceStateMap final : public TechniqueParser::sequence_t
|
class SequenceStateMap final : public TechniqueParser::sequence_t
|
||||||
{
|
{
|
||||||
static constexpr auto CAPTURE_START = 1;
|
static constexpr auto CAPTURE_STATE_MAP_NAME = 1;
|
||||||
static constexpr auto CAPTURE_STATE_MAP_NAME = 2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceStateMap()
|
SequenceStateMap()
|
||||||
@@ -47,7 +49,7 @@ namespace techset
|
|||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
AddMatchers({
|
AddMatchers({
|
||||||
create.Keyword("stateMap").Capture(CAPTURE_START),
|
create.Keyword("stateMap"),
|
||||||
create.String().Capture(CAPTURE_STATE_MAP_NAME),
|
create.String().Capture(CAPTURE_STATE_MAP_NAME),
|
||||||
create.Char(';'),
|
create.Char(';'),
|
||||||
});
|
});
|
||||||
@@ -56,13 +58,9 @@ namespace techset
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
const auto& firstToken = result.NextCapture(CAPTURE_START);
|
assert(state->m_current_pass);
|
||||||
|
|
||||||
std::string errorMessage;
|
state->m_current_pass->m_state_map = result.NextCapture(CAPTURE_STATE_MAP_NAME).StringValue();
|
||||||
const auto acceptorResult = state->m_acceptor->AcceptStateMap(result.NextCapture(CAPTURE_STATE_MAP_NAME).StringValue(), errorMessage);
|
|
||||||
|
|
||||||
if (!acceptorResult)
|
|
||||||
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ namespace techset
|
|||||||
static constexpr auto TAG_VERTEX_SHADER = 1;
|
static constexpr auto TAG_VERTEX_SHADER = 1;
|
||||||
static constexpr auto TAG_PIXEL_SHADER = 2;
|
static constexpr auto TAG_PIXEL_SHADER = 2;
|
||||||
|
|
||||||
static constexpr auto CAPTURE_START = 1;
|
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
||||||
static constexpr auto CAPTURE_VERSION = 2;
|
static constexpr auto CAPTURE_VERSION = 2;
|
||||||
static constexpr auto CAPTURE_VERSION_MAJOR = 3;
|
static constexpr auto CAPTURE_VERSION_MAJOR = 3;
|
||||||
static constexpr auto CAPTURE_VERSION_MINOR = 4;
|
static constexpr auto CAPTURE_VERSION_MINOR = 4;
|
||||||
@@ -88,7 +86,7 @@ namespace techset
|
|||||||
create.Keyword("vertexShader").Tag(TAG_VERTEX_SHADER),
|
create.Keyword("vertexShader").Tag(TAG_VERTEX_SHADER),
|
||||||
create.Keyword("pixelShader").Tag(TAG_PIXEL_SHADER),
|
create.Keyword("pixelShader").Tag(TAG_PIXEL_SHADER),
|
||||||
})
|
})
|
||||||
.Capture(CAPTURE_START),
|
.Capture(CAPTURE_FIRST_TOKEN),
|
||||||
create.Or({
|
create.Or({
|
||||||
create.And({
|
create.And({
|
||||||
create.Integer().Capture(CAPTURE_VERSION_MAJOR),
|
create.Integer().Capture(CAPTURE_VERSION_MAJOR),
|
||||||
@@ -106,31 +104,23 @@ namespace techset
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
const auto& firstToken = result.NextCapture(CAPTURE_START);
|
|
||||||
|
|
||||||
// Don't care about shader version since it's stated in the shader bin anyway
|
// Don't care about shader version since it's stated in the shader bin anyway
|
||||||
|
|
||||||
const auto& shaderNameToken = result.NextCapture(CAPTURE_SHADER_NAME);
|
const auto& shaderNameToken = result.NextCapture(CAPTURE_SHADER_NAME);
|
||||||
|
|
||||||
bool acceptorResult;
|
|
||||||
std::string errorMessage;
|
|
||||||
const auto shaderTag = result.NextTag();
|
const auto shaderTag = result.NextTag();
|
||||||
assert(shaderTag == TAG_VERTEX_SHADER || shaderTag == TAG_PIXEL_SHADER);
|
assert(shaderTag == TAG_VERTEX_SHADER || shaderTag == TAG_PIXEL_SHADER);
|
||||||
|
|
||||||
if (shaderTag == TAG_VERTEX_SHADER)
|
if (shaderTag == TAG_VERTEX_SHADER)
|
||||||
{
|
state->m_current_shader_type = CommonTechniqueShaderType::VERTEX;
|
||||||
acceptorResult = state->m_acceptor->AcceptVertexShader(shaderNameToken.StringValue(), errorMessage);
|
|
||||||
state->m_current_shader = ShaderSelector::VERTEX_SHADER;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
state->m_current_shader_type = CommonTechniqueShaderType::PIXEL;
|
||||||
acceptorResult = state->m_acceptor->AcceptPixelShader(shaderNameToken.StringValue(), errorMessage);
|
|
||||||
state->m_current_shader = ShaderSelector::PIXEL_SHADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->m_in_shader = true;
|
state->m_current_shader = CommonTechniqueShader(state->m_current_shader_type, shaderNameToken.StringValue());
|
||||||
|
|
||||||
if (!acceptorResult)
|
auto enterResult = state->m_shader_arg_creator.EnterShader(state->m_current_shader->m_type, state->m_current_shader->m_name);
|
||||||
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
|
if (!enterResult.has_value())
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), enterResult.error());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,13 +181,23 @@ namespace techset
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
const auto& firstToken = result.NextCapture(CAPTURE_FIRST_TOKEN);
|
assert(state->m_current_pass);
|
||||||
const std::string destinationString = CreateRoutingString(result, CAPTURE_STREAM_DESTINATION_NAME, CAPTURE_STREAM_DESTINATION_INDEX);
|
|
||||||
const std::string sourceString = CreateRoutingString(result, CAPTURE_STREAM_SOURCE_NAME, CAPTURE_STREAM_SOURCE_INDEX);
|
|
||||||
|
|
||||||
std::string errorMessage;
|
const auto& firstToken = result.NextCapture(CAPTURE_FIRST_TOKEN);
|
||||||
if (!state->m_acceptor->AcceptVertexStreamRouting(destinationString, sourceString, errorMessage))
|
|
||||||
throw ParsingException(firstToken.GetPos(), std::move(errorMessage));
|
const std::string destinationString = CreateRoutingString(result, CAPTURE_STREAM_DESTINATION_NAME, CAPTURE_STREAM_DESTINATION_INDEX);
|
||||||
|
const auto maybeDestination = state->m_routing_infos.GetDestinationByName(destinationString);
|
||||||
|
|
||||||
|
if (!maybeDestination.has_value())
|
||||||
|
throw ParsingException(firstToken.GetPos(), "Unknown routing destination");
|
||||||
|
|
||||||
|
const std::string sourceString = CreateRoutingString(result, CAPTURE_STREAM_SOURCE_NAME, CAPTURE_STREAM_SOURCE_INDEX);
|
||||||
|
const auto maybeSource = state->m_routing_infos.GetSourceByName(sourceString);
|
||||||
|
|
||||||
|
if (!maybeSource.has_value())
|
||||||
|
throw ParsingException(firstToken.GetPos(), "Unknown routing source");
|
||||||
|
|
||||||
|
state->m_current_pass->m_vertex_declaration.m_routing.emplace_back(*maybeSource, *maybeDestination);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "TechniqueShaderScopeSequences.h"
|
#include "TechniqueShaderScopeSequences.h"
|
||||||
|
|
||||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||||
|
#include "Techset/CommonShaderArgCreator.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@@ -10,21 +11,34 @@ namespace techset
|
|||||||
{
|
{
|
||||||
class SequenceEndShader final : public TechniqueParser::sequence_t
|
class SequenceEndShader final : public TechniqueParser::sequence_t
|
||||||
{
|
{
|
||||||
|
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceEndShader()
|
SequenceEndShader()
|
||||||
{
|
{
|
||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
AddMatchers({
|
AddMatchers({
|
||||||
create.Char('}'),
|
create.Char('}').Capture(CAPTURE_FIRST_TOKEN),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
assert(state->m_in_shader == true);
|
assert(state->m_current_pass);
|
||||||
state->m_in_shader = false;
|
assert(state->m_current_shader);
|
||||||
|
|
||||||
|
if (state->m_current_shader_type == CommonTechniqueShaderType::VERTEX)
|
||||||
|
state->m_current_pass->m_vertex_shader = std::move(*state->m_current_shader);
|
||||||
|
else
|
||||||
|
state->m_current_pass->m_pixel_shader = std::move(*state->m_current_shader);
|
||||||
|
|
||||||
|
state->m_current_shader = std::nullopt;
|
||||||
|
|
||||||
|
auto leaveShaderResult = state->m_shader_arg_creator.LeaveShader();
|
||||||
|
if (!leaveShaderResult.has_value())
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), leaveShaderResult.error());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,40 +148,126 @@ namespace techset
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessCodeArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg, const bool isSampler)
|
protected:
|
||||||
|
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
std::vector<std::string> accessors;
|
assert(state->m_current_shader);
|
||||||
while (result.HasNextCapture(CAPTURE_CODE_ACCESSOR))
|
|
||||||
accessors.emplace_back(result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue());
|
|
||||||
|
|
||||||
ShaderArgumentCodeSource source;
|
const auto& shaderArgumentNameToken = result.NextCapture(CAPTURE_SHADER_ARGUMENT);
|
||||||
if (result.HasNextCapture(CAPTURE_CODE_INDEX))
|
|
||||||
|
CommonShaderArgCreatorDestination destination;
|
||||||
|
if (result.HasNextCapture(CAPTURE_SHADER_INDEX))
|
||||||
{
|
{
|
||||||
const auto& codeIndexToken = result.NextCapture(CAPTURE_CODE_INDEX);
|
const auto& shaderArgumentIndexToken = result.NextCapture(CAPTURE_SHADER_INDEX);
|
||||||
if (codeIndexToken.IntegerValue() < 0)
|
if (shaderArgumentIndexToken.IntegerValue() < 0)
|
||||||
throw ParsingException(codeIndexToken.GetPos(), "Index cannot be negative");
|
throw ParsingException(shaderArgumentIndexToken.GetPos(), "Index cannot be negative");
|
||||||
source = ShaderArgumentCodeSource(std::move(accessors), static_cast<size_t>(codeIndexToken.IntegerValue()));
|
const auto index = static_cast<unsigned>(shaderArgumentIndexToken.IntegerValue());
|
||||||
|
destination = CommonShaderArgCreatorDestination(shaderArgumentNameToken.IdentifierValue(), index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
source = ShaderArgumentCodeSource(std::move(accessors));
|
destination = CommonShaderArgCreatorDestination(shaderArgumentNameToken.IdentifierValue());
|
||||||
|
|
||||||
std::string errorMessage;
|
const auto typeTag = result.NextTag();
|
||||||
if (!isSampler)
|
assert(typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER || typeTag == TAG_LITERAL || typeTag == TAG_MATERIAL);
|
||||||
|
|
||||||
|
if (typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER)
|
||||||
{
|
{
|
||||||
if (!state->m_acceptor->AcceptShaderConstantArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
|
ProcessCodeArgument(state, result, destination, typeTag == TAG_SAMPLER);
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
|
}
|
||||||
|
else if (typeTag == TAG_LITERAL)
|
||||||
|
{
|
||||||
|
ProcessLiteralArgument(state, result, destination);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!state->m_acceptor->AcceptShaderSamplerArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
|
ProcessMaterialArgument(state, result, destination);
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessLiteralArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg)
|
private:
|
||||||
|
static void ProcessCodeArgument(const TechniqueParserState* state,
|
||||||
|
SequenceResult<SimpleParserValue>& result,
|
||||||
|
const CommonShaderArgCreatorDestination& destination,
|
||||||
|
const bool isSampler)
|
||||||
{
|
{
|
||||||
float value[4];
|
const auto accessor = GetAccessorValue(result);
|
||||||
for (float& i : value)
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
CommonCodeConstSource constSource;
|
||||||
|
CommonCodeSamplerSource samplerSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned sourceIndex = 0u;
|
||||||
|
|
||||||
|
if (isSampler)
|
||||||
|
{
|
||||||
|
const auto maybeSamplerSource = state->m_code_source_infos.GetCodeSamplerSourceForAccessor(accessor);
|
||||||
|
if (!maybeSamplerSource.has_value())
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Unknown code sampler");
|
||||||
|
|
||||||
|
samplerSource = *maybeSamplerSource;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto maybeConstSource = state->m_code_source_infos.GetCodeConstSourceForAccessor(accessor);
|
||||||
|
if (!maybeConstSource.has_value())
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Unknown code constant");
|
||||||
|
|
||||||
|
constSource = *maybeConstSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.HasNextCapture(CAPTURE_CODE_INDEX))
|
||||||
|
{
|
||||||
|
if (isSampler)
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Code sampler is not an array");
|
||||||
|
|
||||||
|
const auto& codeIndexToken = result.NextCapture(CAPTURE_CODE_INDEX);
|
||||||
|
const auto indexIntValue = codeIndexToken.IntegerValue();
|
||||||
|
if (indexIntValue < 0)
|
||||||
|
throw ParsingException(codeIndexToken.GetPos(), "Index cannot be negative");
|
||||||
|
|
||||||
|
sourceIndex = static_cast<unsigned>(indexIntValue);
|
||||||
|
|
||||||
|
size_t codeArraySize = state->m_code_source_infos.GetInfoForCodeConstSource(constSource)->arrayCount;
|
||||||
|
|
||||||
|
if (codeArraySize == 0)
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Code constant is not an array");
|
||||||
|
|
||||||
|
if (codeArraySize <= sourceIndex)
|
||||||
|
{
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(),
|
||||||
|
std::format("Array overflow: Code array has size {}", codeArraySize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> shaderCreatorResult(NoResult{});
|
||||||
|
if (isSampler)
|
||||||
|
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderSamplerArgument(destination, samplerSource);
|
||||||
|
else
|
||||||
|
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderConstantArgument(destination, constSource, sourceIndex);
|
||||||
|
|
||||||
|
if (!shaderCreatorResult.has_value())
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetAccessorValue(SequenceResult<SimpleParserValue>& result)
|
||||||
|
{
|
||||||
|
std::ostringstream accessorStream;
|
||||||
|
|
||||||
|
accessorStream << result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue();
|
||||||
|
while (result.HasNextCapture(CAPTURE_CODE_ACCESSOR))
|
||||||
|
accessorStream << '.' << result.NextCapture(CAPTURE_CODE_ACCESSOR).IdentifierValue();
|
||||||
|
|
||||||
|
return accessorStream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProcessLiteralArgument(const TechniqueParserState* state,
|
||||||
|
SequenceResult<SimpleParserValue>& result,
|
||||||
|
const CommonShaderArgCreatorDestination& destination)
|
||||||
|
{
|
||||||
|
std::array<float, 4> argValue;
|
||||||
|
for (float& i : argValue)
|
||||||
{
|
{
|
||||||
const auto& literalValueToken = result.NextCapture(CAPTURE_LITERAL_VALUE);
|
const auto& literalValueToken = result.NextCapture(CAPTURE_LITERAL_VALUE);
|
||||||
|
|
||||||
@@ -177,56 +277,30 @@ namespace techset
|
|||||||
i = static_cast<float>(literalValueToken.IntegerValue());
|
i = static_cast<float>(literalValueToken.IntegerValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShaderArgumentLiteralSource source(value);
|
auto shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderLiteralArgument(destination, argValue);
|
||||||
std::string errorMessage;
|
|
||||||
if (!state->m_acceptor->AcceptShaderLiteralArgument(state->m_current_shader, std::move(arg), source, errorMessage))
|
if (!shaderCreatorResult.has_value())
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessMaterialArgument(const TechniqueParserState* state, SequenceResult<SimpleParserValue>& result, ShaderArgument arg)
|
static void ProcessMaterialArgument(const TechniqueParserState* state,
|
||||||
|
SequenceResult<SimpleParserValue>& result,
|
||||||
|
const CommonShaderArgCreatorDestination& destination)
|
||||||
{
|
{
|
||||||
std::string errorMessage;
|
result::Expected<NoResult, std::string> shaderCreatorResult(NoResult{});
|
||||||
if (result.HasNextCapture(CAPTURE_MATERIAL_HASH))
|
if (result.HasNextCapture(CAPTURE_MATERIAL_HASH))
|
||||||
{
|
{
|
||||||
ShaderArgumentMaterialSource source(static_cast<size_t>(result.NextCapture(CAPTURE_MATERIAL_HASH).IntegerValue()));
|
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderMaterialArgument(
|
||||||
if (!state->m_acceptor->AcceptShaderMaterialArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
|
destination, static_cast<unsigned>(result.NextCapture(CAPTURE_MATERIAL_HASH).IntegerValue()));
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShaderArgumentMaterialSource source(result.NextCapture(CAPTURE_MATERIAL_NAME).IdentifierValue());
|
const auto stringValue = result.NextCapture(CAPTURE_MATERIAL_NAME).IdentifierValue();
|
||||||
if (!state->m_acceptor->AcceptShaderMaterialArgument(state->m_current_shader, std::move(arg), std::move(source), errorMessage))
|
shaderCreatorResult = state->m_shader_arg_creator.AcceptShaderMaterialArgument(destination, stringValue);
|
||||||
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(errorMessage));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
if (!shaderCreatorResult.has_value())
|
||||||
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), std::move(shaderCreatorResult.error()));
|
||||||
{
|
|
||||||
assert(state->m_in_shader == true);
|
|
||||||
|
|
||||||
const auto& shaderArgumentNameToken = result.NextCapture(CAPTURE_SHADER_ARGUMENT);
|
|
||||||
|
|
||||||
ShaderArgument arg;
|
|
||||||
if (result.HasNextCapture(CAPTURE_SHADER_INDEX))
|
|
||||||
{
|
|
||||||
const auto& shaderArgumentIndexToken = result.NextCapture(CAPTURE_SHADER_INDEX);
|
|
||||||
if (shaderArgumentIndexToken.IntegerValue() < 0)
|
|
||||||
throw ParsingException(shaderArgumentIndexToken.GetPos(), "Index cannot be negative");
|
|
||||||
const auto index = static_cast<unsigned>(shaderArgumentIndexToken.IntegerValue());
|
|
||||||
arg = ShaderArgument(shaderArgumentNameToken.IdentifierValue(), index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
arg = ShaderArgument(shaderArgumentNameToken.IdentifierValue());
|
|
||||||
|
|
||||||
const auto typeTag = result.NextTag();
|
|
||||||
assert(typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER || typeTag == TAG_LITERAL || typeTag == TAG_MATERIAL);
|
|
||||||
if (typeTag == TAG_CONSTANT || typeTag == TAG_SAMPLER)
|
|
||||||
ProcessCodeArgument(state, result, std::move(arg), typeTag == TAG_SAMPLER);
|
|
||||||
else if (typeTag == TAG_LITERAL)
|
|
||||||
ProcessLiteralArgument(state, result, std::move(arg));
|
|
||||||
else
|
|
||||||
ProcessMaterialArgument(state, result, std::move(arg));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
33
src/ObjCompiling/Techset/Parsing/TechniqueFileParser.cpp
Normal file
33
src/ObjCompiling/Techset/Parsing/TechniqueFileParser.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "TechniqueFileParser.h"
|
||||||
|
|
||||||
|
#include "Sequence/TechniqueNoScopeSequences.h"
|
||||||
|
#include "Sequence/TechniquePassScopeSequences.h"
|
||||||
|
#include "Sequence/TechniqueShaderScopeSequences.h"
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
TechniqueParser::TechniqueParser(SimpleLexer& lexer,
|
||||||
|
std::string techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& shaderArgCreator)
|
||||||
|
: AbstractParser(&lexer, std::make_unique<TechniqueParserState>(std::move(techniqueName), codeSourceInfos, routingInfos, shaderArgCreator))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CommonTechnique> TechniqueParser::GetParsingResult() const
|
||||||
|
{
|
||||||
|
return std::move(m_state->m_technique);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<TechniqueParser::sequence_t*>& TechniqueParser::GetTestsForState()
|
||||||
|
{
|
||||||
|
if (m_state->m_current_shader.has_value())
|
||||||
|
return TechniqueShaderScopeSequences::GetSequences();
|
||||||
|
|
||||||
|
if (m_state->m_current_pass.has_value())
|
||||||
|
return TechniquePassScopeSequences::GetSequences();
|
||||||
|
|
||||||
|
return TechniqueNoScopeSequences::GetSequences();
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
@@ -4,15 +4,21 @@
|
|||||||
#include "Parsing/Simple/SimpleLexer.h"
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
#include "Parsing/Simple/SimpleParserValue.h"
|
#include "Parsing/Simple/SimpleParserValue.h"
|
||||||
#include "TechniqueFileParserState.h"
|
#include "TechniqueFileParserState.h"
|
||||||
|
#include "Techset/CommonTechnique.h"
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
{
|
{
|
||||||
class TechniqueParser final : public AbstractParser<SimpleParserValue, TechniqueParserState>
|
class TechniqueParser final : public AbstractParser<SimpleParserValue, TechniqueParserState>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
TechniqueParser(SimpleLexer& lexer,
|
||||||
|
std::string techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& shaderArgCreator);
|
||||||
|
[[nodiscard]] std::unique_ptr<CommonTechnique> GetParsingResult() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||||
|
|
||||||
public:
|
|
||||||
TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor);
|
|
||||||
};
|
};
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include "TechniqueFileParserState.h"
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
TechniqueParserState::TechniqueParserState(std::string techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& shaderArgCreator)
|
||||||
|
: m_technique(std::make_unique<CommonTechnique>(std::move(techniqueName))),
|
||||||
|
m_code_source_infos(codeSourceInfos),
|
||||||
|
m_routing_infos(routingInfos),
|
||||||
|
m_shader_arg_creator(shaderArgCreator),
|
||||||
|
m_current_shader_type(CommonTechniqueShaderType::VERTEX)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
28
src/ObjCompiling/Techset/Parsing/TechniqueFileParserState.h
Normal file
28
src/ObjCompiling/Techset/Parsing/TechniqueFileParserState.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Techset/CommonShaderArgCreator.h"
|
||||||
|
#include "Techset/CommonTechnique.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
class TechniqueParserState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TechniqueParserState(std::string techniqueName,
|
||||||
|
const CommonCodeSourceInfos& codeSourceInfos,
|
||||||
|
const CommonStreamRoutingInfos& routingInfos,
|
||||||
|
CommonShaderArgCreator& shaderArgCreator);
|
||||||
|
|
||||||
|
std::unique_ptr<CommonTechnique> m_technique;
|
||||||
|
|
||||||
|
const CommonCodeSourceInfos& m_code_source_infos;
|
||||||
|
const CommonStreamRoutingInfos& m_routing_infos;
|
||||||
|
CommonShaderArgCreator& m_shader_arg_creator;
|
||||||
|
|
||||||
|
std::optional<CommonPass> m_current_pass;
|
||||||
|
std::optional<CommonTechniqueShader> m_current_shader;
|
||||||
|
CommonTechniqueShaderType m_current_shader_type;
|
||||||
|
};
|
||||||
|
} // namespace techset
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
using namespace techset;
|
using namespace techset;
|
||||||
|
|
||||||
namespace techset
|
namespace
|
||||||
{
|
{
|
||||||
class SequenceTechniqueTypeName final : public TechsetParser::sequence_t
|
class SequenceTechniqueTypeName final : public TechsetParser::sequence_t
|
||||||
{
|
{
|
||||||
@@ -26,11 +26,11 @@ namespace techset
|
|||||||
{
|
{
|
||||||
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE_NAME);
|
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE_NAME);
|
||||||
|
|
||||||
size_t techniqueTypeIndex;
|
const auto maybeTechniqueTypeIndex = state->m_technique_type_names.GetTechniqueTypeByName(typeNameToken.StringValue());
|
||||||
if (!state->FindTechniqueTypeIndex(typeNameToken.StringValue(), techniqueTypeIndex))
|
if (!maybeTechniqueTypeIndex.has_value())
|
||||||
throw ParsingException(typeNameToken.GetPos(), "Unknown technique type name");
|
throw ParsingException(typeNameToken.GetPos(), "Unknown technique type name");
|
||||||
|
|
||||||
state->m_current_technique_types.push_back(techniqueTypeIndex);
|
state->m_current_technique_types.push_back(maybeTechniqueTypeIndex.value());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,31 +64,34 @@ namespace techset
|
|||||||
techniqueNameToken.m_type == SimpleParserValueType::STRING ? techniqueNameToken.StringValue() : techniqueNameToken.IdentifierValue();
|
techniqueNameToken.m_type == SimpleParserValueType::STRING ? techniqueNameToken.StringValue() : techniqueNameToken.IdentifierValue();
|
||||||
|
|
||||||
for (const auto techniqueTypeIndex : state->m_current_technique_types)
|
for (const auto techniqueTypeIndex : state->m_current_technique_types)
|
||||||
state->m_definition->SetTechniqueByIndex(techniqueTypeIndex, techniqueName);
|
state->m_definition->m_technique_names[techniqueTypeIndex] = techniqueName;
|
||||||
state->m_current_technique_types.clear();
|
state->m_current_technique_types.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
TechsetParser::TechsetParser(SimpleLexer& lexer, std::string techsetName, const CommonTechniqueTypeNames& techniqueTypeNames)
|
||||||
|
: AbstractParser(&lexer, std::make_unique<TechsetParserState>(std::move(techsetName), techniqueTypeNames))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<TechsetParser::sequence_t*>& TechsetParser::GetTestsForState()
|
||||||
|
{
|
||||||
|
static std::vector<sequence_t*> allTests({
|
||||||
|
new SequenceTechniqueTypeName(),
|
||||||
|
new SequenceTechniqueName(),
|
||||||
|
});
|
||||||
|
static std::vector<sequence_t*> techniqueTypeNameOnlyTests({
|
||||||
|
new SequenceTechniqueTypeName(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return m_state->m_current_technique_types.empty() ? techniqueTypeNameOnlyTests : allTests;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CommonTechset> TechsetParser::GetParsingResult() const
|
||||||
|
{
|
||||||
|
return std::move(m_state->m_definition);
|
||||||
|
}
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
|
|
||||||
TechsetParser::TechsetParser(SimpleLexer* lexer, const char** validTechniqueTypeNames, const size_t validTechniqueTypeNameCount)
|
|
||||||
: AbstractParser(lexer, std::make_unique<TechsetParserState>(validTechniqueTypeNames, validTechniqueTypeNameCount))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<TechsetParser::sequence_t*>& TechsetParser::GetTestsForState()
|
|
||||||
{
|
|
||||||
static std::vector<sequence_t*> allTests({
|
|
||||||
new SequenceTechniqueTypeName(),
|
|
||||||
new SequenceTechniqueName(),
|
|
||||||
});
|
|
||||||
static std::vector<sequence_t*> techniqueTypeNameOnlyTests({
|
|
||||||
new SequenceTechniqueTypeName(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return m_state->m_current_technique_types.empty() ? techniqueTypeNameOnlyTests : allTests;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<TechsetDefinition> TechsetParser::GetTechsetDefinition() const
|
|
||||||
{
|
|
||||||
return std::move(m_state->m_definition);
|
|
||||||
}
|
|
||||||
@@ -3,19 +3,17 @@
|
|||||||
#include "Parsing/Impl/AbstractParser.h"
|
#include "Parsing/Impl/AbstractParser.h"
|
||||||
#include "Parsing/Simple/SimpleLexer.h"
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
#include "Parsing/Simple/SimpleParserValue.h"
|
#include "Parsing/Simple/SimpleParserValue.h"
|
||||||
#include "Techset/TechsetDefinition.h"
|
|
||||||
#include "TechsetFileParserState.h"
|
#include "TechsetFileParserState.h"
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
namespace techset
|
namespace techset
|
||||||
{
|
{
|
||||||
class TechsetParser final : public AbstractParser<SimpleParserValue, TechsetParserState>
|
class TechsetParser final : public AbstractParser<SimpleParserValue, TechsetParserState>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
TechsetParser(SimpleLexer& lexer, std::string techsetName, const CommonTechniqueTypeNames& techniqueTypeNames);
|
||||||
|
[[nodiscard]] std::unique_ptr<CommonTechset> GetParsingResult() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||||
|
|
||||||
public:
|
|
||||||
TechsetParser(SimpleLexer* lexer, const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount);
|
|
||||||
_NODISCARD std::unique_ptr<TechsetDefinition> GetTechsetDefinition() const;
|
|
||||||
};
|
};
|
||||||
} // namespace techset
|
} // namespace techset
|
||||||
10
src/ObjCompiling/Techset/Parsing/TechsetFileParserState.cpp
Normal file
10
src/ObjCompiling/Techset/Parsing/TechsetFileParserState.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "TechsetFileParserState.h"
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
TechsetParserState::TechsetParserState(std::string techsetName, const CommonTechniqueTypeNames& techniqueTypeNames)
|
||||||
|
: m_technique_type_names(techniqueTypeNames),
|
||||||
|
m_definition(std::make_unique<CommonTechset>(std::move(techsetName), techniqueTypeNames.GetTechniqueTypeCount()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
21
src/ObjCompiling/Techset/Parsing/TechsetFileParserState.h
Normal file
21
src/ObjCompiling/Techset/Parsing/TechsetFileParserState.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Techset/CommonTechset.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
class TechsetParserState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TechsetParserState(std::string techsetName, const CommonTechniqueTypeNames& techniqueTypeNames);
|
||||||
|
|
||||||
|
const CommonTechniqueTypeNames& m_technique_type_names;
|
||||||
|
std::unique_ptr<CommonTechset> m_definition;
|
||||||
|
std::vector<size_t> m_current_technique_types;
|
||||||
|
};
|
||||||
|
} // namespace techset
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
||||||
#include "StateMap/Parsing/StateMapParserState.h"
|
#include "Techset/StateMap/Parsing/StateMapParserState.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -4,8 +4,6 @@
|
|||||||
#include "Parsing/Simple/SimpleLexer.h"
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
#include "Parsing/Simple/SimpleParserValue.h"
|
#include "Parsing/Simple/SimpleParserValue.h"
|
||||||
#include "StateMapParserState.h"
|
#include "StateMapParserState.h"
|
||||||
#include "Techset/TechsetDefinition.h"
|
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
namespace state_map
|
namespace state_map
|
||||||
{
|
{
|
||||||
@@ -16,7 +14,7 @@ namespace state_map
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout);
|
StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout);
|
||||||
_NODISCARD std::unique_ptr<StateMapDefinition> GetStateMapDefinition() const;
|
[[nodiscard]] std::unique_ptr<StateMapDefinition> GetStateMapDefinition() const;
|
||||||
_NODISCARD StateMapParserState* GetState() const;
|
[[nodiscard]] StateMapParserState* GetState() const;
|
||||||
};
|
};
|
||||||
} // namespace state_map
|
} // namespace state_map
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StateMap/StateMapDefinition.h"
|
#include "Techset/StateMap/StateMapDefinition.h"
|
||||||
#include "StateMap/StateMapLayout.h"
|
#include "Techset/StateMap/StateMapLayout.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StateMap/StateMapDefinition.h"
|
#include "Techset/StateMap/StateMapDefinition.h"
|
||||||
#include "StateMap/StateMapLayout.h"
|
#include "Techset/StateMap/StateMapLayout.h"
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -13,7 +12,7 @@ namespace state_map
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void AddValue(std::string key, std::string value);
|
void AddValue(std::string key, std::string value);
|
||||||
_NODISCARD SimpleExpressionValue ValueByName(const std::string& name) const override;
|
[[nodiscard]] SimpleExpressionValue ValueByName(const std::string& name) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::string> m_vars;
|
std::unordered_map<std::string, std::string> m_vars;
|
||||||
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include "Parsing/IParserLineStream.h"
|
#include "Parsing/IParserLineStream.h"
|
||||||
#include "Parsing/StateMapParserState.h"
|
#include "Parsing/StateMapParserState.h"
|
||||||
#include "StateMap/StateMapLayout.h"
|
|
||||||
#include "StateMapDefinition.h"
|
#include "StateMapDefinition.h"
|
||||||
#include "Utils/ClassUtils.h"
|
#include "Techset/StateMap/StateMapLayout.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -22,7 +21,7 @@ namespace state_map
|
|||||||
public:
|
public:
|
||||||
StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout);
|
StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout);
|
||||||
|
|
||||||
_NODISCARD bool IsValidEndState(const StateMapParserState* state) const;
|
[[nodiscard]] bool IsValidEndState(const StateMapParserState* state) const;
|
||||||
_NODISCARD std::unique_ptr<StateMapDefinition> ReadStateMapDefinition() const;
|
[[nodiscard]] std::unique_ptr<StateMapDefinition> ReadStateMapDefinition() const;
|
||||||
};
|
};
|
||||||
} // namespace state_map
|
} // namespace state_map
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Asset/IZoneAssetCreationState.h"
|
#include "Asset/IZoneAssetCreationState.h"
|
||||||
#include "StateMap/StateMapDefinition.h"
|
#include "Techset/StateMap/StateMapDefinition.h"
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -13,10 +12,10 @@ namespace techset
|
|||||||
class TechniqueStateMapCache final : public IZoneAssetCreationState
|
class TechniqueStateMapCache final : public IZoneAssetCreationState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
_NODISCARD const state_map::StateMapDefinition* GetCachedStateMap(const std::string& name) const;
|
[[nodiscard]] const state_map::StateMapDefinition* GetCachedStateMap(const std::string& name) const;
|
||||||
void AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap);
|
void AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap);
|
||||||
|
|
||||||
_NODISCARD const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const;
|
[[nodiscard]] const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const;
|
||||||
void SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap);
|
void SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -67,11 +67,15 @@ AssetCreationContext::AssetCreationContext(Zone& zone, const AssetCreatorCollect
|
|||||||
: ZoneAssetCreationStateContainer(zone),
|
: ZoneAssetCreationStateContainer(zone),
|
||||||
m_zone(zone),
|
m_zone(zone),
|
||||||
m_forced_asset_pools(std::make_unique<ZoneAssetPools>(zone, zone.m_priority)),
|
m_forced_asset_pools(std::make_unique<ZoneAssetPools>(zone, zone.m_priority)),
|
||||||
m_sub_asset_pools(IGame::GetGameById(zone.m_game_id)->GetSubAssetTypeCount()),
|
|
||||||
m_creators(creators),
|
m_creators(creators),
|
||||||
m_ignored_asset_lookup(ignoredAssetLookup),
|
m_ignored_asset_lookup(ignoredAssetLookup),
|
||||||
m_forced_load_depth(0u)
|
m_forced_load_depth(0u)
|
||||||
{
|
{
|
||||||
|
const auto subAssetTypeCount = IGame::GetGameById(zone.m_game_id)->GetSubAssetTypeCount();
|
||||||
|
m_sub_asset_pools.resize(subAssetTypeCount);
|
||||||
|
|
||||||
|
for (asset_type_t subAssetType = 0; subAssetType < subAssetTypeCount; subAssetType++)
|
||||||
|
m_sub_asset_pools[subAssetType] = std::make_unique<AssetPool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
XAssetInfoGeneric* AssetCreationContext::AddAssetGeneric(GenericAssetRegistration registration) const
|
XAssetInfoGeneric* AssetCreationContext::AddAssetGeneric(GenericAssetRegistration registration) const
|
||||||
@@ -171,6 +175,10 @@ XAssetInfoGeneric* AssetCreationContext::LoadSubAssetGeneric(const asset_type_t
|
|||||||
|
|
||||||
con::error(R"(Could not load sub asset "{}" of type "{}")", assetName, *IGame::GetGameById(m_zone.m_game_id)->GetSubAssetTypeName(subAssetType));
|
con::error(R"(Could not load sub asset "{}" of type "{}")", assetName, *IGame::GetGameById(m_zone.m_game_id)->GetSubAssetTypeName(subAssetType));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
con::error(R"(Missing sub asset "{}" of type "{}")", assetName, *IGame::GetGameById(m_zone.m_game_id)->GetSubAssetTypeName(subAssetType));
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Asset/IZoneAssetCreationState.h"
|
#include "Asset/IZoneAssetCreationState.h"
|
||||||
#include "AssetRegistration.h"
|
#include "AssetRegistration.h"
|
||||||
#include "Game/IAsset.h"
|
#include "Game/IAsset.h"
|
||||||
|
#include "Pool/AssetPool.h"
|
||||||
#include "Pool/XAssetInfo.h"
|
#include "Pool/XAssetInfo.h"
|
||||||
#include "Zone/AssetList/AssetList.h"
|
#include "Zone/AssetList/AssetList.h"
|
||||||
#include "Zone/ZoneTypes.h"
|
#include "Zone/ZoneTypes.h"
|
||||||
@@ -89,6 +90,11 @@ public:
|
|||||||
|
|
||||||
XAssetInfoGeneric* ForceLoadDependencyGeneric(asset_type_t assetType, const std::string& assetName);
|
XAssetInfoGeneric* ForceLoadDependencyGeneric(asset_type_t assetType, const std::string& assetName);
|
||||||
|
|
||||||
|
template<SubAssetDefinition SubAsset_t> [[nodiscard]] AssetPoolIterators<SubAsset_t> PoolSubAssets() const
|
||||||
|
{
|
||||||
|
return AssetPoolIterators<SubAsset_t>(*m_sub_asset_pools[SubAsset_t::EnumEntry]);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] XAssetInfoGeneric* LoadDefaultAssetDependency(asset_type_t assetType, const std::string& assetName);
|
[[nodiscard]] XAssetInfoGeneric* LoadDefaultAssetDependency(asset_type_t assetType, const std::string& assetName);
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ AssetCreationResult AssetCreatorCollection::CreateDefaultAsset(const asset_type_
|
|||||||
|
|
||||||
void AssetCreatorCollection::FinalizeZone(AssetCreationContext& context) const
|
void AssetCreatorCollection::FinalizeZone(AssetCreationContext& context) const
|
||||||
{
|
{
|
||||||
|
for (const auto& creator : m_sub_asset_creators)
|
||||||
|
creator->FinalizeZone(context);
|
||||||
for (const auto& creator : m_asset_creators)
|
for (const auto& creator : m_asset_creators)
|
||||||
creator->FinalizeZone(context);
|
creator->FinalizeZone(context);
|
||||||
for (const auto& postProcessor : m_asset_post_processors)
|
for (const auto& postProcessor : m_asset_post_processors)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
class ZoneAssetCreationStateContainer
|
class ZoneAssetCreationStateContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZoneAssetCreationStateContainer(Zone& zone)
|
explicit ZoneAssetCreationStateContainer(Zone& zone)
|
||||||
: m_injection(*this, zone)
|
: m_injection(*this, zone)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "Slug/LoaderSlugT6.h"
|
#include "Slug/LoaderSlugT6.h"
|
||||||
#include "Sound/LoaderSoundBankT6.h"
|
#include "Sound/LoaderSoundBankT6.h"
|
||||||
#include "StringTable/LoaderStringTableT6.h"
|
#include "StringTable/LoaderStringTableT6.h"
|
||||||
|
#include "Techset/PixelShaderLoaderT6.h"
|
||||||
|
#include "Techset/VertexShaderLoaderT6.h"
|
||||||
#include "Tracer/GdtLoaderTracerT6.h"
|
#include "Tracer/GdtLoaderTracerT6.h"
|
||||||
#include "Tracer/RawLoaderTracerT6.h"
|
#include "Tracer/RawLoaderTracerT6.h"
|
||||||
#include "Utils/Logging/Log.h"
|
#include "Utils/Logging/Log.h"
|
||||||
@@ -434,6 +436,9 @@ namespace T6
|
|||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFootstepFxTable>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderFootstepFxTable>(memory));
|
||||||
collection.AddAssetCreator(z_barrier::CreateRawLoaderT6(memory, searchPath, zone));
|
collection.AddAssetCreator(z_barrier::CreateRawLoaderT6(memory, searchPath, zone));
|
||||||
collection.AddAssetCreator(z_barrier::CreateGdtLoaderT6(memory, searchPath, gdt, zone));
|
collection.AddAssetCreator(z_barrier::CreateGdtLoaderT6(memory, searchPath, gdt, zone));
|
||||||
|
|
||||||
|
collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderT6(memory, searchPath));
|
||||||
|
collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderT6(memory, searchPath));
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
55
src/ObjLoading/Game/T6/Techset/PixelShaderLoaderT6.cpp
Normal file
55
src/ObjLoading/Game/T6/Techset/PixelShaderLoaderT6.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "PixelShaderLoaderT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Shader/ShaderCommon.h"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class PixelShaderLoader final : public SubAssetCreator<SubAssetPixelShader>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PixelShaderLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||||
|
: m_memory(memory),
|
||||||
|
m_search_path(searchPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateSubAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto fileName = shader::GetFileNameForPixelShaderAssetName(assetName);
|
||||||
|
const auto file = m_search_path.Open(fileName);
|
||||||
|
if (!file.IsOpen())
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
auto* pixelShader = m_memory.Alloc<MaterialPixelShader>();
|
||||||
|
pixelShader->name = m_memory.Dup(assetName.c_str());
|
||||||
|
pixelShader->prog.loadDef.programSize = static_cast<decltype(GfxPixelShaderLoadDef::programSize)>(file.m_length);
|
||||||
|
pixelShader->prog.ps = nullptr;
|
||||||
|
|
||||||
|
auto* fileBuffer = m_memory.Alloc<char>(pixelShader->prog.loadDef.programSize);
|
||||||
|
file.m_stream->read(fileBuffer, pixelShader->prog.loadDef.programSize);
|
||||||
|
if (file.m_stream->gcount() != file.m_length)
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
|
pixelShader->prog.loadDef.program = fileBuffer;
|
||||||
|
return AssetCreationResult::Success(context.AddSubAsset<SubAssetPixelShader>(assetName, pixelShader));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<SubAssetCreator<SubAssetPixelShader>> CreatePixelShaderLoaderT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||||
|
{
|
||||||
|
return std::make_unique<PixelShaderLoader>(memory, searchPath);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
13
src/ObjLoading/Game/T6/Techset/PixelShaderLoaderT6.h
Normal file
13
src/ObjLoading/Game/T6/Techset/PixelShaderLoaderT6.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<SubAssetCreator<T6::SubAssetPixelShader>> CreatePixelShaderLoaderT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||||
|
} // namespace techset
|
||||||
55
src/ObjLoading/Game/T6/Techset/VertexShaderLoaderT6.cpp
Normal file
55
src/ObjLoading/Game/T6/Techset/VertexShaderLoaderT6.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "VertexShaderLoaderT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Shader/ShaderCommon.h"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class VertexShaderLoader final : public SubAssetCreator<SubAssetVertexShader>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VertexShaderLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||||
|
: m_memory(memory),
|
||||||
|
m_search_path(searchPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateSubAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto fileName = shader::GetFileNameForVertexShaderAssetName(assetName);
|
||||||
|
const auto file = m_search_path.Open(fileName);
|
||||||
|
if (!file.IsOpen())
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
auto* vertexShader = m_memory.Alloc<MaterialVertexShader>();
|
||||||
|
vertexShader->name = m_memory.Dup(assetName.c_str());
|
||||||
|
vertexShader->prog.loadDef.programSize = static_cast<decltype(GfxVertexShaderLoadDef::programSize)>(file.m_length);
|
||||||
|
vertexShader->prog.vs = nullptr;
|
||||||
|
|
||||||
|
auto* fileBuffer = m_memory.Alloc<char>(vertexShader->prog.loadDef.programSize);
|
||||||
|
file.m_stream->read(fileBuffer, vertexShader->prog.loadDef.programSize);
|
||||||
|
if (file.m_stream->gcount() != file.m_length)
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
|
vertexShader->prog.loadDef.program = fileBuffer;
|
||||||
|
return AssetCreationResult::Success(context.AddSubAsset<SubAssetVertexShader>(assetName, vertexShader));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<SubAssetCreator<SubAssetVertexShader>> CreateVertexShaderLoaderT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||||
|
{
|
||||||
|
return std::make_unique<VertexShaderLoader>(memory, searchPath);
|
||||||
|
}
|
||||||
|
} // namespace techset
|
||||||
13
src/ObjLoading/Game/T6/Techset/VertexShaderLoaderT6.h
Normal file
13
src/ObjLoading/Game/T6/Techset/VertexShaderLoaderT6.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace techset
|
||||||
|
{
|
||||||
|
std::unique_ptr<SubAssetCreator<T6::SubAssetVertexShader>> CreateVertexShaderLoaderT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||||
|
} // namespace techset
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#include "StateMapFromTechniqueExtractor.h"
|
|
||||||
|
|
||||||
using namespace state_map;
|
|
||||||
|
|
||||||
std::string StateMapFromTechniqueExtractor::RetrieveStateMap()
|
|
||||||
{
|
|
||||||
return std::move(m_state_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StateMapFromTechniqueExtractor::AcceptNextPass() {}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptEndPass(std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptStateMap(const std::string& stateMapName, std::string& errorMessage)
|
|
||||||
{
|
|
||||||
m_state_map = stateMapName;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptShaderConstantArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentCodeSource source,
|
|
||||||
std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptShaderSamplerArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentCodeSource source,
|
|
||||||
std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptShaderLiteralArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentLiteralSource source,
|
|
||||||
std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptShaderMaterialArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentMaterialSource source,
|
|
||||||
std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StateMapFromTechniqueExtractor::AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Techset/TechniqueDefinitionAcceptor.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace state_map
|
|
||||||
{
|
|
||||||
class StateMapFromTechniqueExtractor final : public techset::ITechniqueDefinitionAcceptor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string RetrieveStateMap();
|
|
||||||
|
|
||||||
void AcceptNextPass() override;
|
|
||||||
bool AcceptEndPass(std::string& errorMessage) override;
|
|
||||||
bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) override;
|
|
||||||
bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) override;
|
|
||||||
bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) override;
|
|
||||||
bool AcceptShaderConstantArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentCodeSource source,
|
|
||||||
std::string& errorMessage) override;
|
|
||||||
bool AcceptShaderSamplerArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentCodeSource source,
|
|
||||||
std::string& errorMessage) override;
|
|
||||||
bool AcceptShaderLiteralArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentLiteralSource source,
|
|
||||||
std::string& errorMessage) override;
|
|
||||||
bool AcceptShaderMaterialArgument(techset::ShaderSelector shader,
|
|
||||||
techset::ShaderArgument shaderArgument,
|
|
||||||
techset::ShaderArgumentMaterialSource source,
|
|
||||||
std::string& errorMessage) override;
|
|
||||||
bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_state_map;
|
|
||||||
};
|
|
||||||
} // namespace state_map
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#include "TechniqueFileParser.h"
|
|
||||||
|
|
||||||
#include "Sequence/TechniqueNoScopeSequences.h"
|
|
||||||
#include "Sequence/TechniquePassScopeSequences.h"
|
|
||||||
#include "Sequence/TechniqueShaderScopeSequences.h"
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechniqueParser::TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor)
|
|
||||||
: AbstractParser(lexer, std::make_unique<TechniqueParserState>(acceptor))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<TechniqueParser::sequence_t*>& TechniqueParser::GetTestsForState()
|
|
||||||
{
|
|
||||||
if (m_state->m_in_shader)
|
|
||||||
return TechniqueShaderScopeSequences::GetSequences();
|
|
||||||
|
|
||||||
if (m_state->m_in_pass)
|
|
||||||
return TechniquePassScopeSequences::GetSequences();
|
|
||||||
|
|
||||||
return TechniqueNoScopeSequences::GetSequences();
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#include "TechniqueFileParserState.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechniqueParserState::TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor)
|
|
||||||
: m_acceptor(acceptor),
|
|
||||||
m_in_pass(false),
|
|
||||||
m_in_shader(false),
|
|
||||||
m_current_shader(ShaderSelector::VERTEX_SHADER)
|
|
||||||
{
|
|
||||||
assert(acceptor);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Techset/TechniqueDefinitionAcceptor.h"
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
class TechniqueParserState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ITechniqueDefinitionAcceptor* const m_acceptor;
|
|
||||||
|
|
||||||
bool m_in_pass;
|
|
||||||
bool m_in_shader;
|
|
||||||
ShaderSelector m_current_shader;
|
|
||||||
|
|
||||||
explicit TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor);
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#include "TechsetFileParserState.h"
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechsetParserState::TechsetParserState(const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount)
|
|
||||||
: m_definition(std::make_unique<TechsetDefinition>(validTechniqueTypeNameCount))
|
|
||||||
{
|
|
||||||
for (auto i = 0u; i < validTechniqueTypeNameCount; i++)
|
|
||||||
{
|
|
||||||
m_valid_technique_type_names.emplace(std::make_pair(std::string(validTechniqueTypeNames[i]), i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TechsetParserState::FindTechniqueTypeIndex(const std::string& techniqueTypeName, size_t& techniqueTypeIndex) const
|
|
||||||
{
|
|
||||||
const auto foundTechniqueType = m_valid_technique_type_names.find(techniqueTypeName);
|
|
||||||
|
|
||||||
if (foundTechniqueType != m_valid_technique_type_names.end())
|
|
||||||
{
|
|
||||||
techniqueTypeIndex = foundTechniqueType->second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Techset/TechsetDefinition.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
class TechsetParserState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::map<std::string, size_t> m_valid_technique_type_names;
|
|
||||||
std::unique_ptr<TechsetDefinition> m_definition;
|
|
||||||
std::vector<size_t> m_current_technique_types;
|
|
||||||
|
|
||||||
TechsetParserState(const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount);
|
|
||||||
|
|
||||||
bool FindTechniqueTypeIndex(const std::string& techniqueTypeName, size_t& techniqueTypeIndex) const;
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
#include "TechniqueDefinitionAcceptor.h"
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
ShaderArgument::ShaderArgument()
|
|
||||||
: m_argument_index_specified(false),
|
|
||||||
m_argument_index(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgument::ShaderArgument(std::string argumentName)
|
|
||||||
: m_argument_name(std::move(argumentName)),
|
|
||||||
m_argument_index_specified(false),
|
|
||||||
m_argument_index(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgument::ShaderArgument(std::string argumentName, const unsigned argumentIndex)
|
|
||||||
: m_argument_name(std::move(argumentName)),
|
|
||||||
m_argument_index_specified(true),
|
|
||||||
m_argument_index(argumentIndex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentCodeSource::ShaderArgumentCodeSource()
|
|
||||||
: m_index_accessor_specified(false),
|
|
||||||
m_index_accessor(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors)
|
|
||||||
: m_accessors(std::move(accessors)),
|
|
||||||
m_index_accessor_specified(false),
|
|
||||||
m_index_accessor(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors, const unsigned indexAccessor)
|
|
||||||
: m_accessors(std::move(accessors)),
|
|
||||||
m_index_accessor_specified(true),
|
|
||||||
m_index_accessor(indexAccessor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource()
|
|
||||||
: m_value{}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(const float v0, const float v1, const float v2, const float v3)
|
|
||||||
: m_value{v0, v1, v2, v3}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(float value[4])
|
|
||||||
: m_value{value[0], value[1], value[2], value[3]}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
|
|
||||||
{
|
|
||||||
if (lhs.m_value[0] < rhs.m_value[0])
|
|
||||||
return true;
|
|
||||||
if (lhs.m_value[0] > rhs.m_value[0])
|
|
||||||
return false;
|
|
||||||
if (lhs.m_value[1] < rhs.m_value[1])
|
|
||||||
return true;
|
|
||||||
if (lhs.m_value[1] > rhs.m_value[1])
|
|
||||||
return false;
|
|
||||||
if (lhs.m_value[2] < rhs.m_value[2])
|
|
||||||
return true;
|
|
||||||
if (lhs.m_value[2] > rhs.m_value[2])
|
|
||||||
return false;
|
|
||||||
if (lhs.m_value[3] < rhs.m_value[3])
|
|
||||||
return true;
|
|
||||||
if (lhs.m_value[3] > rhs.m_value[3])
|
|
||||||
return false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
|
|
||||||
{
|
|
||||||
return !(rhs < lhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
|
|
||||||
{
|
|
||||||
return rhs < lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs < rhs);
|
|
||||||
}
|
|
||||||
} // namespace techset
|
|
||||||
|
|
||||||
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource()
|
|
||||||
: m_is_hash(false),
|
|
||||||
m_hash(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(const unsigned hash)
|
|
||||||
: m_is_hash(true),
|
|
||||||
m_hash(hash)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(std::string name)
|
|
||||||
: m_is_hash(false),
|
|
||||||
m_hash(0u),
|
|
||||||
m_name(std::move(name))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
enum class ShaderSelector
|
|
||||||
{
|
|
||||||
VERTEX_SHADER,
|
|
||||||
PIXEL_SHADER
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderArgument
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string m_argument_name;
|
|
||||||
bool m_argument_index_specified;
|
|
||||||
unsigned m_argument_index;
|
|
||||||
|
|
||||||
ShaderArgument();
|
|
||||||
explicit ShaderArgument(std::string argumentName);
|
|
||||||
ShaderArgument(std::string argumentName, unsigned argumentIndex);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderArgumentCodeSource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<std::string> m_accessors;
|
|
||||||
bool m_index_accessor_specified;
|
|
||||||
unsigned m_index_accessor;
|
|
||||||
|
|
||||||
ShaderArgumentCodeSource();
|
|
||||||
explicit ShaderArgumentCodeSource(std::vector<std::string> accessors);
|
|
||||||
ShaderArgumentCodeSource(std::vector<std::string> accessors, unsigned indexAccessor);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderArgumentLiteralSource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
float m_value[4];
|
|
||||||
|
|
||||||
ShaderArgumentLiteralSource();
|
|
||||||
ShaderArgumentLiteralSource(float v0, float v1, float v2, float v3);
|
|
||||||
explicit ShaderArgumentLiteralSource(float value[4]);
|
|
||||||
|
|
||||||
friend bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
|
|
||||||
friend bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
|
|
||||||
friend bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
|
|
||||||
friend bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderArgumentMaterialSource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShaderArgumentMaterialSource();
|
|
||||||
explicit ShaderArgumentMaterialSource(unsigned hash);
|
|
||||||
explicit ShaderArgumentMaterialSource(std::string name);
|
|
||||||
|
|
||||||
bool m_is_hash;
|
|
||||||
unsigned m_hash;
|
|
||||||
std::string m_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ITechniqueDefinitionAcceptor
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
ITechniqueDefinitionAcceptor() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~ITechniqueDefinitionAcceptor() = default;
|
|
||||||
ITechniqueDefinitionAcceptor(const ITechniqueDefinitionAcceptor& other) = default;
|
|
||||||
ITechniqueDefinitionAcceptor(ITechniqueDefinitionAcceptor&& other) noexcept = default;
|
|
||||||
ITechniqueDefinitionAcceptor& operator=(const ITechniqueDefinitionAcceptor& other) = default;
|
|
||||||
ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default;
|
|
||||||
|
|
||||||
virtual void AcceptNextPass() = 0;
|
|
||||||
virtual bool AcceptEndPass(std::string& errorMessage) = 0;
|
|
||||||
|
|
||||||
virtual bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) = 0;
|
|
||||||
|
|
||||||
virtual bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) = 0;
|
|
||||||
virtual bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) = 0;
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
AcceptShaderConstantArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
|
|
||||||
virtual bool
|
|
||||||
AcceptShaderSamplerArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
|
|
||||||
virtual bool AcceptShaderLiteralArgument(ShaderSelector shader,
|
|
||||||
ShaderArgument shaderArgument,
|
|
||||||
ShaderArgumentLiteralSource source,
|
|
||||||
std::string& errorMessage) = 0;
|
|
||||||
virtual bool AcceptShaderMaterialArgument(ShaderSelector shader,
|
|
||||||
ShaderArgument shaderArgument,
|
|
||||||
ShaderArgumentMaterialSource source,
|
|
||||||
std::string& errorMessage) = 0;
|
|
||||||
|
|
||||||
virtual bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) = 0;
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "TechniqueFileReader.h"
|
|
||||||
|
|
||||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
|
||||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
|
||||||
#include "Parsing/Simple/SimpleLexer.h"
|
|
||||||
#include "Parsing/TechniqueFileParser.h"
|
|
||||||
#include "Utils/Logging/Log.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechniqueFileReader::TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor)
|
|
||||||
: m_file_name(std::move(fileName)),
|
|
||||||
m_acceptor(acceptor)
|
|
||||||
{
|
|
||||||
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
|
|
||||||
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TechniqueFileReader::ReadTechniqueDefinition() const
|
|
||||||
{
|
|
||||||
SimpleLexer::Config lexerConfig;
|
|
||||||
lexerConfig.m_emit_new_line_tokens = false;
|
|
||||||
lexerConfig.m_read_strings = true;
|
|
||||||
lexerConfig.m_string_escape_sequences = false;
|
|
||||||
lexerConfig.m_read_integer_numbers = true;
|
|
||||||
lexerConfig.m_read_floating_point_numbers = true;
|
|
||||||
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
|
|
||||||
|
|
||||||
const auto parser = std::make_unique<TechniqueParser>(lexer.get(), m_acceptor);
|
|
||||||
|
|
||||||
const auto success = parser->Parse();
|
|
||||||
if (success)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
con::error("Parsing technique file \"{}\" failed!", m_file_name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Parsing/IParserLineStream.h"
|
|
||||||
#include "TechniqueDefinitionAcceptor.h"
|
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
class TechniqueFileReader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor);
|
|
||||||
|
|
||||||
[[nodiscard]] bool ReadTechniqueDefinition() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_file_name;
|
|
||||||
ITechniqueDefinitionAcceptor* m_acceptor;
|
|
||||||
std::unique_ptr<IParserLineStream> m_base_stream;
|
|
||||||
std::unique_ptr<IParserLineStream> m_comment_proxy;
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#include "TechsetDefinition.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechsetDefinition::TechsetDefinition(const size_t techniqueTypeCount)
|
|
||||||
: m_has_technique(techniqueTypeCount),
|
|
||||||
m_technique_names(techniqueTypeCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TechsetDefinition::GetTechniqueByIndex(const size_t index, std::string& techniqueName) const
|
|
||||||
{
|
|
||||||
assert(index < m_has_technique.size());
|
|
||||||
if (index >= m_has_technique.size() || !m_has_technique[index])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
techniqueName = m_technique_names[index];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TechsetDefinition::SetTechniqueByIndex(const size_t index, std::string techniqueName)
|
|
||||||
{
|
|
||||||
assert(index < m_has_technique.size());
|
|
||||||
if (index >= m_has_technique.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_has_technique[index] = true;
|
|
||||||
m_technique_names[index] = std::move(techniqueName);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
class TechsetDefinition
|
|
||||||
{
|
|
||||||
std::vector<bool> m_has_technique;
|
|
||||||
std::vector<std::string> m_technique_names;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit TechsetDefinition(size_t techniqueTypeCount);
|
|
||||||
bool GetTechniqueByIndex(size_t index, std::string& techniqueName) const;
|
|
||||||
void SetTechniqueByIndex(size_t index, std::string techniqueName);
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#include "TechsetDefinitionCache.h"
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechsetDefinition* TechsetDefinitionCache::GetCachedTechsetDefinition(const std::string& techsetName) const
|
|
||||||
{
|
|
||||||
const auto foundTechset = m_cache.find(techsetName);
|
|
||||||
|
|
||||||
if (foundTechset != m_cache.end())
|
|
||||||
return foundTechset->second.get();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TechsetDefinitionCache::AddTechsetDefinitionToCache(std::string name, std::unique_ptr<TechsetDefinition> definition)
|
|
||||||
{
|
|
||||||
m_cache.emplace(std::make_pair(std::move(name), std::move(definition)));
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Asset/IZoneAssetCreationState.h"
|
|
||||||
#include "TechsetDefinition.h"
|
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace techset
|
|
||||||
{
|
|
||||||
class TechsetDefinitionCache final : public IZoneAssetCreationState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
_NODISCARD TechsetDefinition* GetCachedTechsetDefinition(const std::string& techsetName) const;
|
|
||||||
void AddTechsetDefinitionToCache(std::string name, std::unique_ptr<TechsetDefinition> definition);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, std::unique_ptr<TechsetDefinition>> m_cache;
|
|
||||||
};
|
|
||||||
} // namespace techset
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#include "TechsetFileReader.h"
|
|
||||||
|
|
||||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
|
||||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
|
||||||
#include "Parsing/TechsetFileParser.h"
|
|
||||||
#include "Utils/Logging/Log.h"
|
|
||||||
|
|
||||||
#include <format>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace techset;
|
|
||||||
|
|
||||||
TechsetFileReader::TechsetFileReader(std::istream& stream, std::string fileName, const char** validTechniqueTypeNames, const size_t validTechniqueTypeNameCount)
|
|
||||||
: m_file_name(std::move(fileName)),
|
|
||||||
m_valid_technique_type_names(validTechniqueTypeNames),
|
|
||||||
m_valid_technique_type_name_count(validTechniqueTypeNameCount)
|
|
||||||
{
|
|
||||||
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
|
|
||||||
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<techset::TechsetDefinition> TechsetFileReader::ReadTechsetDefinition() const
|
|
||||||
{
|
|
||||||
SimpleLexer::Config lexerConfig;
|
|
||||||
lexerConfig.m_emit_new_line_tokens = false;
|
|
||||||
lexerConfig.m_read_strings = true;
|
|
||||||
lexerConfig.m_string_escape_sequences = false;
|
|
||||||
lexerConfig.m_read_integer_numbers = false;
|
|
||||||
lexerConfig.m_read_floating_point_numbers = false;
|
|
||||||
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
|
|
||||||
|
|
||||||
const auto parser = std::make_unique<techset::TechsetParser>(lexer.get(), m_valid_technique_type_names, m_valid_technique_type_name_count);
|
|
||||||
|
|
||||||
const auto success = parser->Parse();
|
|
||||||
if (success)
|
|
||||||
return parser->GetTechsetDefinition();
|
|
||||||
|
|
||||||
con::error("Parsing techset file \"{}\" failed!", m_file_name);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user