rendering: formalize shader keyword metadata contract

This commit is contained in:
2026-04-06 18:55:26 +08:00
parent 7acc397714
commit a8b4da16a3
16 changed files with 795 additions and 16 deletions

View File

@@ -11,9 +11,9 @@ namespace XCEngine {
namespace Resources {
constexpr Core::uint32 kTextureArtifactSchemaVersion = 1;
constexpr Core::uint32 kMaterialArtifactSchemaVersion = 2;
constexpr Core::uint32 kMaterialArtifactSchemaVersion = 3;
constexpr Core::uint32 kMeshArtifactSchemaVersion = 2;
constexpr Core::uint32 kShaderArtifactSchemaVersion = 1;
constexpr Core::uint32 kShaderArtifactSchemaVersion = 2;
constexpr Core::uint32 kUIDocumentArtifactSchemaVersion = 2;
struct TextureArtifactHeader {
@@ -46,14 +46,23 @@ struct MeshArtifactHeader {
};
struct MaterialArtifactFileHeader {
char magic[8] = { 'X', 'C', 'M', 'A', 'T', '0', '2', '\0' };
char magic[8] = { 'X', 'C', 'M', 'A', 'T', '0', '3', '\0' };
Core::uint32 schemaVersion = kMaterialArtifactSchemaVersion;
};
struct MaterialArtifactHeaderV2 {
Core::int32 renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
MaterialRenderState renderState = {};
Core::uint32 tagCount = 0;
Core::uint32 propertyCount = 0;
Core::uint32 textureBindingCount = 0;
};
struct MaterialArtifactHeader {
Core::int32 renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
MaterialRenderState renderState = {};
Core::uint32 tagCount = 0;
Core::uint32 keywordCount = 0;
Core::uint32 propertyCount = 0;
Core::uint32 textureBindingCount = 0;
};
@@ -64,7 +73,7 @@ struct MaterialPropertyArtifact {
};
struct ShaderArtifactFileHeader {
char magic[8] = { 'X', 'C', 'S', 'H', 'D', '0', '1', '\0' };
char magic[8] = { 'X', 'C', 'S', 'H', 'D', '0', '2', '\0' };
Core::uint32 schemaVersion = kShaderArtifactSchemaVersion;
};
@@ -73,9 +82,16 @@ struct ShaderArtifactHeader {
Core::uint32 passCount = 0;
};
struct ShaderPassArtifactHeaderV1 {
Core::uint32 tagCount = 0;
Core::uint32 resourceCount = 0;
Core::uint32 variantCount = 0;
};
struct ShaderPassArtifactHeader {
Core::uint32 tagCount = 0;
Core::uint32 resourceCount = 0;
Core::uint32 keywordDeclarationCount = 0;
Core::uint32 variantCount = 0;
};
@@ -96,6 +112,11 @@ struct ShaderVariantArtifactHeader {
Core::uint64 compiledBinarySize = 0;
};
struct ShaderKeywordDeclarationArtifactHeader {
Core::uint32 declarationType = 0;
Core::uint32 optionCount = 0;
};
struct UIDocumentArtifactFileHeader {
char magic[8] = { 'X', 'C', 'U', 'I', 'D', '0', '1', '\0' };
Core::uint32 schemaVersion = kUIDocumentArtifactSchemaVersion;

View File

@@ -192,6 +192,15 @@ public:
Containers::String GetTagName(Core::uint32 index) const;
Containers::String GetTagValue(Core::uint32 index) const;
const Containers::Array<MaterialTagEntry>& GetTags() const { return m_tags; }
void EnableKeyword(const Containers::String& keyword);
void DisableKeyword(const Containers::String& keyword);
void SetKeywordEnabled(const Containers::String& keyword, bool enabled);
bool IsKeywordEnabled(const Containers::String& keyword) const;
void ClearKeywords();
Core::uint32 GetKeywordCount() const { return static_cast<Core::uint32>(m_keywordSet.enabledKeywords.Size()); }
Containers::String GetKeyword(Core::uint32 index) const;
const ShaderKeywordSet& GetKeywordSet() const { return m_keywordSet; }
void SetFloat(const Containers::String& name, float value);
void SetFloat2(const Containers::String& name, const Math::Vector2& value);
@@ -242,12 +251,14 @@ private:
void ResolvePendingTextureBindings();
void MarkChanged(bool updateConstantBuffer);
void UpdateMemorySize();
void SyncShaderSchemaKeywords(bool removeUnknownKeywords);
ResourceHandle<class Shader> m_shader;
Core::int32 m_renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
MaterialRenderState m_renderState;
Containers::String m_shaderPass;
Containers::Array<MaterialTagEntry> m_tags;
ShaderKeywordSet m_keywordSet;
Containers::HashMap<Containers::String, MaterialProperty> m_properties;
Containers::Array<MaterialConstantFieldDesc> m_constantLayout;
Containers::Array<Core::uint8> m_constantBufferData;

View File

@@ -3,6 +3,7 @@
#include <XCEngine/Core/Asset/IResource.h>
#include <XCEngine/Core/Containers/Array.h>
#include <XCEngine/Core/Types.h>
#include <XCEngine/Resources/Shader/ShaderKeywordTypes.h>
namespace XCEngine {
namespace Resources {
@@ -97,6 +98,7 @@ struct ShaderPass {
Containers::String name;
Containers::Array<ShaderPassTagEntry> tags;
Containers::Array<ShaderResourceBindingDesc> resources;
Containers::Array<ShaderKeywordDeclaration> keywordDeclarations;
Containers::Array<ShaderStageVariant> variants;
};
@@ -149,9 +151,16 @@ public:
void AddPassResourceBinding(
const Containers::String& passName,
const ShaderResourceBindingDesc& binding);
void AddPassKeywordDeclaration(
const Containers::String& passName,
const ShaderKeywordDeclaration& declaration);
bool HasPass(const Containers::String& passName) const;
const ShaderPass* FindPass(const Containers::String& passName) const;
ShaderPass* FindPass(const Containers::String& passName);
bool PassDeclaresKeyword(
const Containers::String& passName,
const Containers::String& keyword) const;
bool DeclaresKeyword(const Containers::String& keyword) const;
const ShaderResourceBindingDesc* FindPassResourceBinding(
const Containers::String& passName,
const Containers::String& resourceName) const;

View File

@@ -0,0 +1,34 @@
#pragma once
#include <XCEngine/Core/Containers/Array.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Types.h>
namespace XCEngine {
namespace Resources {
enum class ShaderKeywordDeclarationType : Core::uint8 {
MultiCompile = 0,
ShaderFeature,
ShaderFeatureLocal
};
struct ShaderKeywordDeclaration {
ShaderKeywordDeclarationType type = ShaderKeywordDeclarationType::MultiCompile;
Containers::Array<Containers::String> options;
bool IsLocal() const {
return type == ShaderKeywordDeclarationType::ShaderFeatureLocal;
}
};
struct ShaderKeywordSet {
Containers::Array<Containers::String> enabledKeywords;
bool Empty() const {
return enabledKeywords.Empty();
}
};
} // namespace Resources
} // namespace XCEngine