Remove legacy shader pass and artifact fallbacks

This commit is contained in:
2026-04-08 04:59:49 +08:00
parent 2c1c815072
commit efdd6bd68f
9 changed files with 186 additions and 273 deletions

View File

@@ -2,7 +2,6 @@
#include <XCEngine/Core/Asset/ArtifactFormats.h>
#include <XCEngine/Debug/Logger.h>
#include <XCEngine/Rendering/Builtin/BuiltinPassMetadataUtils.h>
#include <XCEngine/Resources/Material/MaterialLoader.h>
#include <XCEngine/Resources/Mesh/MeshLoader.h>
#include <XCEngine/Resources/Shader/ShaderLoader.h>
@@ -11,6 +10,7 @@
#include <algorithm>
#include <cctype>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <sstream>
@@ -108,6 +108,22 @@ void AddUniqueDependencyPath(const fs::path& path,
}
}
bool IsCurrentShaderArtifactFile(const fs::path& artifactPath) {
std::ifstream input(artifactPath, std::ios::binary);
if (!input.is_open()) {
return false;
}
ShaderArtifactFileHeader header = {};
input.read(reinterpret_cast<char*>(&header), sizeof(header));
if (!input || input.gcount() != static_cast<std::streamsize>(sizeof(header))) {
return false;
}
return std::memcmp(header.magic, "XCSHD05", 7) == 0 &&
header.schemaVersion == kShaderArtifactSchemaVersion;
}
std::string TrimCopy(const std::string& text) {
const auto begin = std::find_if_not(text.begin(), text.end(), [](unsigned char ch) {
return std::isspace(ch) != 0;
@@ -425,19 +441,6 @@ Containers::String ResolveTextureBindingPath(
return NormalizeArtifactPathString(material.GetTextureBindingPath(bindingIndex));
}
Containers::String ResolveSerializedLegacyMaterialShaderPassHint(const Material& material) {
const Containers::String& shaderPass = material.GetLegacyShaderPassHint();
if (shaderPass.Empty()) {
return Containers::String();
}
if (Rendering::IsRedundantLegacyMaterialShaderPassHint(material.GetShader(), shaderPass)) {
return Containers::String();
}
return shaderPass;
}
bool WriteMaterialArtifactFile(
const fs::path& artifactPath,
const Material& material,
@@ -459,7 +462,6 @@ bool WriteMaterialArtifactFile(
material.GetShader() != nullptr
? material.GetShader()->GetPath()
: Containers::String());
WriteString(output, ResolveSerializedLegacyMaterialShaderPassHint(material));
MaterialArtifactHeader header;
header.renderQueue = material.GetRenderQueue();
@@ -1454,6 +1456,11 @@ bool AssetDatabase::ShouldReimport(const SourceAssetRecord& sourceRecord,
return true;
}
if (artifactRecord->resourceType == ResourceType::Shader &&
!IsCurrentShaderArtifactFile(artifactMainPath)) {
return true;
}
return artifactRecord->importerVersion != sourceRecord.importerVersion ||
artifactRecord->sourceHash != sourceRecord.sourceHash ||
artifactRecord->metaHash != sourceRecord.metaHash ||

View File

@@ -291,7 +291,6 @@ BuiltinDepthStylePassBase::ResolvedShaderPass BuiltinDepthStylePassBase::Resolve
return false;
}
const bool shaderHasExplicitBuiltinMetadata = ShaderHasExplicitBuiltinMetadata(*shader);
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, ownerMaterial);
auto tryAcceptPass =

View File

@@ -37,7 +37,6 @@ const Resources::ShaderPass* FindCompatibleSurfacePass(
const Resources::Material* material,
BuiltinMaterialPass pass,
Resources::ShaderBackend backend) {
const bool shaderHasExplicitBuiltinMetadata = ShaderHasExplicitBuiltinMetadata(shader);
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, material);
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
@@ -51,43 +50,6 @@ const Resources::ShaderPass* FindCompatibleSurfacePass(
}
}
if (shaderHasExplicitBuiltinMetadata) {
return nullptr;
}
if (pass != BuiltinMaterialPass::ForwardLit) {
return nullptr;
}
const Resources::ShaderPass* defaultPass = shader.FindPass("ForwardLit");
if (defaultPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
defaultPass->name,
backend,
keywordSet)) {
return defaultPass;
}
defaultPass = shader.FindPass("Default");
if (defaultPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
defaultPass->name,
backend,
keywordSet)) {
return defaultPass;
}
if (shader.GetPassCount() > 0 &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
shader.GetPasses()[0].name,
backend,
keywordSet)) {
return &shader.GetPasses()[0];
}
return nullptr;
}

View File

@@ -48,23 +48,6 @@ bool ReadShaderArtifactString(
return true;
}
MaterialRenderState ExpandSerializedMaterialRenderStateV4(const SerializedMaterialRenderStateV4& legacyState) {
MaterialRenderState renderState = {};
renderState.blendEnable = legacyState.blendEnable;
renderState.srcBlend = legacyState.srcBlend;
renderState.dstBlend = legacyState.dstBlend;
renderState.srcBlendAlpha = legacyState.srcBlendAlpha;
renderState.dstBlendAlpha = legacyState.dstBlendAlpha;
renderState.blendOp = legacyState.blendOp;
renderState.blendOpAlpha = legacyState.blendOpAlpha;
renderState.colorWriteMask = legacyState.colorWriteMask;
renderState.depthTestEnable = legacyState.depthTestEnable;
renderState.depthWriteEnable = legacyState.depthWriteEnable;
renderState.depthFunc = legacyState.depthFunc;
renderState.cullMode = legacyState.cullMode;
return renderState;
}
} // namespace
LoadResult LoadShaderArtifact(const Containers::String& path) {
@@ -80,13 +63,9 @@ LoadResult LoadShaderArtifact(const Containers::String& path) {
}
const std::string magic(fileHeader.magic, fileHeader.magic + 7);
const bool isLegacySchema = magic == "XCSHD01" && fileHeader.schemaVersion == 1u;
const bool isSchemaV2 = magic == "XCSHD02" && fileHeader.schemaVersion == 2u;
const bool isSchemaV3 = magic == "XCSHD03" && fileHeader.schemaVersion == 3u;
const bool isSchemaV4 = magic == "XCSHD04" && fileHeader.schemaVersion == 4u;
const bool isCurrentSchema =
magic == "XCSHD05" && fileHeader.schemaVersion == kShaderArtifactSchemaVersion;
if (!isLegacySchema && !isSchemaV2 && !isSchemaV3 && !isSchemaV4 && !isCurrentSchema) {
if (!isCurrentSchema) {
return LoadResult("Invalid shader artifact header: " + path);
}
@@ -96,10 +75,7 @@ LoadResult LoadShaderArtifact(const Containers::String& path) {
Containers::String shaderSourcePath;
Containers::String shaderFallback;
if (!ReadShaderArtifactString(data, offset, shaderName) ||
!ReadShaderArtifactString(data, offset, shaderSourcePath)) {
return LoadResult("Failed to parse shader artifact strings: " + path);
}
if ((isSchemaV4 || isCurrentSchema) &&
!ReadShaderArtifactString(data, offset, shaderSourcePath) ||
!ReadShaderArtifactString(data, offset, shaderFallback)) {
return LoadResult("Failed to parse shader artifact strings: " + path);
}
@@ -141,51 +117,18 @@ LoadResult LoadShaderArtifact(const Containers::String& path) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
if (isLegacySchema) {
ShaderPassArtifactHeaderV1 passHeader = {};
if (!ReadShaderArtifactValue(data, offset, passHeader)) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
tagCount = passHeader.tagCount;
resourceCount = passHeader.resourceCount;
variantCount = passHeader.variantCount;
} else if (isSchemaV2 || isSchemaV3) {
ShaderPassArtifactHeader passHeader = {};
if (!ReadShaderArtifactValue(data, offset, passHeader)) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
tagCount = passHeader.tagCount;
resourceCount = passHeader.resourceCount;
keywordDeclarationCount = passHeader.keywordDeclarationCount;
variantCount = passHeader.variantCount;
} else if (isSchemaV4) {
ShaderPassArtifactHeaderV4 passHeader = {};
if (!ReadShaderArtifactValue(data, offset, passHeader)) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
tagCount = passHeader.tagCount;
resourceCount = passHeader.resourceCount;
keywordDeclarationCount = passHeader.keywordDeclarationCount;
variantCount = passHeader.variantCount;
hasFixedFunctionState = passHeader.hasFixedFunctionState;
fixedFunctionState = ExpandSerializedMaterialRenderStateV4(passHeader.fixedFunctionState);
} else {
ShaderPassArtifactHeaderV5 passHeader = {};
if (!ReadShaderArtifactValue(data, offset, passHeader)) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
tagCount = passHeader.tagCount;
resourceCount = passHeader.resourceCount;
keywordDeclarationCount = passHeader.keywordDeclarationCount;
variantCount = passHeader.variantCount;
hasFixedFunctionState = passHeader.hasFixedFunctionState;
fixedFunctionState = passHeader.fixedFunctionState;
ShaderPassArtifactHeaderV5 passHeader = {};
if (!ReadShaderArtifactValue(data, offset, passHeader)) {
return LoadResult("Failed to read shader artifact passes: " + path);
}
tagCount = passHeader.tagCount;
resourceCount = passHeader.resourceCount;
keywordDeclarationCount = passHeader.keywordDeclarationCount;
variantCount = passHeader.variantCount;
hasFixedFunctionState = passHeader.hasFixedFunctionState;
fixedFunctionState = passHeader.fixedFunctionState;
ShaderPass pass = {};
pass.name = passName;
pass.hasFixedFunctionState = hasFixedFunctionState != 0u;
@@ -244,29 +187,17 @@ LoadResult LoadShaderArtifact(const Containers::String& path) {
ShaderStageVariant variant = {};
Core::uint64 compiledBinarySize = 0;
Core::uint32 keywordCount = 0;
if (isSchemaV4 || isCurrentSchema) {
ShaderVariantArtifactHeader variantHeader = {};
if (!ReadShaderArtifactValue(data, offset, variantHeader)) {
return LoadResult("Failed to read shader artifact variants: " + path);
}
variant.stage = static_cast<ShaderType>(variantHeader.stage);
variant.language = static_cast<ShaderLanguage>(variantHeader.language);
variant.backend = static_cast<ShaderBackend>(variantHeader.backend);
keywordCount = variantHeader.keywordCount;
compiledBinarySize = variantHeader.compiledBinarySize;
} else {
ShaderVariantArtifactHeaderV2 variantHeader = {};
if (!ReadShaderArtifactValue(data, offset, variantHeader)) {
return LoadResult("Failed to read shader artifact variants: " + path);
}
variant.stage = static_cast<ShaderType>(variantHeader.stage);
variant.language = static_cast<ShaderLanguage>(variantHeader.language);
variant.backend = static_cast<ShaderBackend>(variantHeader.backend);
compiledBinarySize = variantHeader.compiledBinarySize;
ShaderVariantArtifactHeader variantHeader = {};
if (!ReadShaderArtifactValue(data, offset, variantHeader)) {
return LoadResult("Failed to read shader artifact variants: " + path);
}
variant.stage = static_cast<ShaderType>(variantHeader.stage);
variant.language = static_cast<ShaderLanguage>(variantHeader.language);
variant.backend = static_cast<ShaderBackend>(variantHeader.backend);
keywordCount = variantHeader.keywordCount;
compiledBinarySize = variantHeader.compiledBinarySize;
if (!ReadShaderArtifactString(data, offset, variant.entryPoint) ||
!ReadShaderArtifactString(data, offset, variant.profile) ||
!ReadShaderArtifactString(data, offset, variant.sourceCode)) {