refactor(shader): rewrite editor shader compilation bridge with keyword resolution
- Add AssetCatalog.EnumerateByTypes for filtered SQL queries - Thread LocalKeywordSet through IShaderCompilationBridge API so the bridge can resolve keyword bitmask to string defines at compile time - Eager/lazy popluation of shader-id-to-asset-id map eliminating full catalog scan per compilation miss - Build keyword mapping from PassDescriptor groups to reconstruct localIndex -> keywordName in the bridge - Use CompileShaderPass extension for multi-stage AS/MS/PS compilation with correct ShaderModel from descriptor - Remove double-load of shader asset in compilation flow - Update test mock to match new interface signature
This commit is contained in:
@@ -179,7 +179,7 @@ public readonly struct ShaderPass
|
||||
get; init;
|
||||
}
|
||||
|
||||
public LocalKeywordSet KeywordIDs
|
||||
public LocalKeywordSet DefinedKeywords
|
||||
{
|
||||
get; init;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ using Ghost.Core;
|
||||
|
||||
namespace Ghost.Graphics.RHI;
|
||||
|
||||
public interface IShaderCompilationBridge
|
||||
public interface IShaderCompilationBridge : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Request the bridge to recompile a shader variant or handle cache misses.
|
||||
/// This is typically called by the ShaderLibrary when a variant hash is not found.
|
||||
/// </summary>
|
||||
void RequestCompilation(ulong shaderId, int passIndex, Key64<ShaderVariant> variantKey);
|
||||
void RequestCompilation(ulong shaderId, int passIndex, Key64<ShaderVariant> variantKey, LocalKeywordSet keywordMask);
|
||||
|
||||
/// <summary>
|
||||
/// Event triggered when a shader variant has been successfully compiled and updated.
|
||||
|
||||
@@ -379,7 +379,7 @@ public readonly unsafe ref struct RenderContext
|
||||
var variantKey = RHIUtility.CreateShaderVariantKey(entryHash, in keywordSet);
|
||||
|
||||
// TODO: Refactor this into a helper method.
|
||||
var (compiledHash, error) = ShaderLibrary.GetCompiledHash(shader.UniqueID, entryIndex, variantKey);
|
||||
var (compiledHash, error) = ShaderLibrary.GetCompiledHash(shader.UniqueID, entryIndex, variantKey, keywordSet);
|
||||
if (error.IsFailure)
|
||||
{
|
||||
// TODO: Fallback to an error material.
|
||||
|
||||
@@ -119,7 +119,7 @@ public partial struct Shader : IResourceReleasable
|
||||
{
|
||||
Key = RHIUtility.GetPassID(_nameHash, i),
|
||||
DefaultState = pass.localPipeline,
|
||||
KeywordIDs = keywords,
|
||||
DefinedKeywords = keywords,
|
||||
};
|
||||
|
||||
_passIDToLocal[GetPassID(pass.name)] = (ushort)i;
|
||||
|
||||
@@ -169,10 +169,10 @@ internal sealed class RenderGraphContext : IUnsafeRenderContext
|
||||
var materialPipeline = material.GetPassPipelineOverride(material.ActivePassIndex);
|
||||
|
||||
// Mask out the keywords that are not used in this pass.
|
||||
var variantMask = material._keywordMask & pass.KeywordIDs;
|
||||
var variantMask = material._keywordMask & pass.DefinedKeywords;
|
||||
var variantKey = RHIUtility.CreateShaderVariantKey(pass.Key, in variantMask);
|
||||
|
||||
var (compiledHash, error) = _shaderLibrary.GetCompiledHash(shader.UniqueID, material.ActivePassIndex, variantKey);
|
||||
var (compiledHash, error) = _shaderLibrary.GetCompiledHash(shader.UniqueID, material.ActivePassIndex, variantKey, variantMask);
|
||||
if (error.IsFailure)
|
||||
{
|
||||
// TODO: Fallback to a default shader or show an error material.
|
||||
@@ -277,7 +277,7 @@ internal sealed class RenderGraphContext : IUnsafeRenderContext
|
||||
var keywordSet = new LocalKeywordSet(); // TODO: Support keywords in compute shader.
|
||||
var variantKey = RHIUtility.CreateShaderVariantKey(entryHash, in keywordSet);
|
||||
|
||||
var (compiledHash, error) = _shaderLibrary.GetCompiledHash(shader.UniqueID, entryIndex, variantKey);
|
||||
var (compiledHash, error) = _shaderLibrary.GetCompiledHash(shader.UniqueID, entryIndex, variantKey, keywordSet);
|
||||
if (error.IsFailure)
|
||||
{
|
||||
// TODO: Fallback to a default shader or show an error material.
|
||||
|
||||
@@ -195,14 +195,14 @@ internal unsafe class ShaderLibrary : IDisposable
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Result<ulong, Error> GetCompiledHash(ulong id, int passIndex, Key64<ShaderVariant> variantKey)
|
||||
public Result<ulong, Error> GetCompiledHash(ulong id, int passIndex, Key64<ShaderVariant> variantKey, LocalKeywordSet keywordMask = default)
|
||||
{
|
||||
if (_variantToCompiledHash.TryGetValue(variantKey, out var compiledHash))
|
||||
{
|
||||
return compiledHash;
|
||||
}
|
||||
|
||||
_shaderCompilationBridge?.RequestCompilation(id, passIndex, variantKey);
|
||||
_shaderCompilationBridge?.RequestCompilation(id, passIndex, variantKey, keywordMask);
|
||||
return Error.NotFound;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user