Updated for SD 90e87bc

This commit is contained in:
DarthAffe 2026-06-11 21:11:25 +02:00
parent c56e65ab6f
commit 37e36bb000
17 changed files with 246 additions and 17 deletions

View File

@ -50,6 +50,7 @@ enum sample_method_t {
TCD_SAMPLE_METHOD,
RES_MULTISTEP_SAMPLE_METHOD,
RES_2S_SAMPLE_METHOD,
ER_SDE_SAMPLE_METHOD,
SAMPLE_METHOD_COUNT
};
@ -120,7 +121,8 @@ enum sd_type_t {
// SD_TYPE_IQ4_NL_4_8 = 37,
// SD_TYPE_IQ4_NL_8_8 = 38,
SD_TYPE_MXFP4 = 39, // MXFP4 (1 block)
SD_TYPE_COUNT = 40,
SD_TYPE_NVFP4 = 40, // NVFP4 (4 blocks, E4M3 scale)
SD_TYPE_COUNT = 41,
};
enum sd_log_level_t {
@ -201,7 +203,7 @@ typedef struct {
bool chroma_use_t5_mask;
int chroma_t5_mask_pad;
bool qwen_image_zero_cond_t;
float max_vram;
} sd_ctx_params_t;
typedef struct {
@ -252,6 +254,7 @@ enum sd_cache_mode_t {
SD_CACHE_DBCACHE,
SD_CACHE_TAYLORSEER,
SD_CACHE_CACHE_DIT,
SD_CACHE_SPECTRUM,
};
typedef struct {
@ -272,6 +275,13 @@ typedef struct {
int taylorseer_skip_interval;
const char* scm_mask;
bool scm_policy_dynamic;
float spectrum_w;
int spectrum_m;
float spectrum_lam;
int spectrum_window_size;
float spectrum_flex_window;
int spectrum_warmup_steps;
float spectrum_stop_percent;
} sd_cache_params_t;
typedef struct {
@ -280,6 +290,32 @@ typedef struct {
const char* path;
} sd_lora_t;
enum sd_hires_upscaler_t {
SD_HIRES_UPSCALER_NONE,
SD_HIRES_UPSCALER_LATENT,
SD_HIRES_UPSCALER_LATENT_NEAREST,
SD_HIRES_UPSCALER_LATENT_NEAREST_EXACT,
SD_HIRES_UPSCALER_LATENT_ANTIALIASED,
SD_HIRES_UPSCALER_LATENT_BICUBIC,
SD_HIRES_UPSCALER_LATENT_BICUBIC_ANTIALIASED,
SD_HIRES_UPSCALER_LANCZOS,
SD_HIRES_UPSCALER_NEAREST,
SD_HIRES_UPSCALER_MODEL,
SD_HIRES_UPSCALER_COUNT,
};
typedef struct {
bool enabled;
enum sd_hires_upscaler_t upscaler;
const char* model_path;
float scale;
int target_width;
int target_height;
int steps;
float denoising_strength;
int upscale_tile_size;
} sd_hires_params_t;
typedef struct {
const sd_lora_t* loras;
uint32_t lora_count;
@ -303,6 +339,7 @@ typedef struct {
sd_pm_params_t pm_params;
sd_tiling_params_t vae_tiling_params;
sd_cache_params_t cache;
sd_hires_params_t hires;
} sd_img_gen_params_t;
typedef struct {
@ -339,6 +376,8 @@ SD_API void sd_set_progress_callback(sd_progress_cb_t cb, void* data);
SD_API void sd_set_preview_callback(sd_preview_cb_t cb, enum preview_t mode, int interval, bool denoised, bool noisy, void* data);
SD_API int32_t sd_get_num_physical_cores();
SD_API const char* sd_get_system_info();
SD_API bool sd_ctx_supports_image_generation(const sd_ctx_t* sd_ctx);
SD_API bool sd_ctx_supports_video_generation(const sd_ctx_t* sd_ctx);
SD_API const char* sd_type_name(enum sd_type_t type);
SD_API enum sd_type_t str_to_sd_type(const char* str);
@ -354,8 +393,11 @@ SD_API const char* sd_preview_name(enum preview_t preview);
SD_API enum preview_t str_to_preview(const char* str);
SD_API const char* sd_lora_apply_mode_name(enum lora_apply_mode_t mode);
SD_API enum lora_apply_mode_t str_to_lora_apply_mode(const char* str);
SD_API const char* sd_hires_upscaler_name(enum sd_hires_upscaler_t upscaler);
SD_API enum sd_hires_upscaler_t str_to_sd_hires_upscaler(const char* str);
SD_API void sd_cache_params_init(sd_cache_params_t* cache_params);
SD_API void sd_hires_params_init(sd_hires_params_t* hires_params);
SD_API void sd_ctx_params_init(sd_ctx_params_t* sd_ctx_params);
SD_API char* sd_ctx_params_to_str(const sd_ctx_params_t* sd_ctx_params);
@ -412,4 +454,4 @@ SD_API const char* sd_version(void);
}
#endif
#endif // __STABLE_DIFFUSION_H__
#endif // __STABLE_DIFFUSION_H__

View File

@ -8,4 +8,5 @@ public enum CacheMode
DBCache,
Taylorseer,
CacheDit,
Spectrum,
}

View File

@ -0,0 +1,15 @@
namespace StableDiffusion.NET;
public enum HiresUpscaler
{
None,
Latent,
LatentNearest,
LatentNearestExact,
LatentAntialiased,
LatentBicubic,
LatentBicubicAntialiased,
Lanczos,
Nearest,
Model,
}

View File

@ -42,7 +42,8 @@ public enum Quantization
// SD_TYPE_IQ4_NL_4_4 = 36,
// SD_TYPE_IQ4_NL_4_8 = 37,
// SD_TYPE_IQ4_NL_8_8 = 38,
SD_TYPE_MXFP4 = 39,
SMXFP4 = 39,
NVFP4 = 40,
Unspecified = 40
Unspecified = 41
}

View File

@ -16,5 +16,6 @@ public enum Sampler
TCD,
ResMultistep,
Res2S,
ER_SDE,
Default
}

View File

@ -15,6 +15,9 @@ public sealed unsafe class DiffusionModel : IDisposable
private Native.Types.sd_ctx_t* _ctx;
public bool SupportsImageGeneration => Native.sd_ctx_supports_image_generation(_ctx);
public bool SupportsVideoGeneration => Native.sd_ctx_supports_video_generation(_ctx);
#endregion
#region Constructors
@ -50,7 +53,7 @@ public sealed unsafe class DiffusionModel : IDisposable
if (_ctx == null) throw new NullReferenceException("The model is not initialized.");
parameter.Validate();
Native.Types.sd_image_t* result = Native.generate_image(_ctx, parameter);
if (result == null) return null;

View File

@ -22,6 +22,13 @@ public sealed class CacheParameter
public int TaylorseerSkipInterval { get; set; } = 1;
public string? ScmMask { get; set; } = null;
public bool ScmPolicyDynamic { get; set; } = true;
public float SpectrumW { get; set; }
public int SpectrumM { get; set; }
public float SpectrumLam { get; set; }
public int SpectrumWindowSize { get; set; }
public float SpectrumFlexWindow { get; set; }
public int SpectrumWarmupSteps { get; set; }
public float SpectrumStopPercent { get; set; }
internal CacheParameter() { }
}

View File

@ -150,5 +150,7 @@ public sealed class DiffusionModelParameter
public bool QwenImageZeroCondT { get; set; } = false;
public float MaxVRam { get; set; }
public static DiffusionModelParameter Create() => new();
}

View File

@ -0,0 +1,19 @@
using JetBrains.Annotations;
namespace StableDiffusion.NET;
[PublicAPI]
public sealed class HiresParameter
{
public bool Enabled { get; set; }
public HiresUpscaler Upscaler { get; set; }
public string? ModelPath { get; set; }
public float Scale { get; set; }
public int TargetWidth { get; set; }
public int TargetHeight { get; set; }
public int Steps { get; set; }
public float DenoisingStrength { get; set; }
public int UpscaleTileSize { get; set; }
internal HiresParameter() { }
}

View File

@ -62,6 +62,8 @@ public sealed class ImageGenerationParameter
public CacheParameter Cache { get; internal init; } = new();
public HiresParameter Hires { get; internal set; } = new();
public List<Lora> Loras { get; } = [];
#endregion

View File

@ -30,7 +30,14 @@ internal static unsafe class CacheParameterMarshaller
TaylorseerNDerivatives = unmanaged.taylorseer_n_derivatives,
TaylorseerSkipInterval = unmanaged.taylorseer_skip_interval,
ScmMask = AnsiStringMarshaller.ConvertToManaged(unmanaged.scm_mask),
ScmPolicyDynamic = unmanaged.scm_policy_dynamic == 1
ScmPolicyDynamic = unmanaged.scm_policy_dynamic == 1,
SpectrumW = unmanaged.spectrum_w,
SpectrumM = unmanaged.spectrum_m,
SpectrumLam = unmanaged.spectrum_lam,
SpectrumWindowSize = unmanaged.spectrum_window_size,
SpectrumFlexWindow = unmanaged.spectrum_flex_window,
SpectrumWarmupSteps = unmanaged.spectrum_warmup_steps,
SpectrumStopPercent = unmanaged.spectrum_stop_percent
};
return parameter;
@ -39,7 +46,7 @@ internal static unsafe class CacheParameterMarshaller
internal ref struct CacheParameterMarshallerIn
{
private Native.Types.sd_cache_params_t _cacheParams;
public void FromManaged(CacheParameter managed)
{
@ -61,7 +68,14 @@ internal static unsafe class CacheParameterMarshaller
taylorseer_n_derivatives = managed.TaylorseerNDerivatives,
taylorseer_skip_interval = managed.TaylorseerSkipInterval,
scm_mask = AnsiStringMarshaller.ConvertToUnmanaged(managed.ScmMask),
scm_policy_dynamic = (sbyte)(managed.ScmPolicyDynamic ? 1 : 0)
scm_policy_dynamic = (sbyte)(managed.ScmPolicyDynamic ? 1 : 0),
spectrum_w = managed.SpectrumW,
spectrum_m = managed.SpectrumM,
spectrum_lam = managed.SpectrumLam,
spectrum_window_size = managed.SpectrumWindowSize,
spectrum_flex_window = managed.SpectrumFlexWindow,
spectrum_warmup_steps = managed.SpectrumWarmupSteps,
spectrum_stop_percent = managed.SpectrumStopPercent
};
}

View File

@ -51,6 +51,7 @@ internal static unsafe class DiffusionModelParameterMarshaller
ChromaEnableT5Map = unmanaged.chroma_use_t5_mask == 1,
ChromaT5MaskPad = unmanaged.chroma_t5_mask_pad,
QwenImageZeroCondT = unmanaged.qwen_image_zero_cond_t == 1,
MaxVRam = unmanaged.max_vram
};
for (int i = 0; i < unmanaged.embedding_count; i++)
@ -131,7 +132,8 @@ internal static unsafe class DiffusionModelParameterMarshaller
chroma_use_dit_mask = (sbyte)(managed.ChromaUseDitMap ? 1 : 0),
chroma_use_t5_mask = (sbyte)(managed.ChromaEnableT5Map ? 1 : 0),
chroma_t5_mask_pad = managed.ChromaT5MaskPad,
qwen_image_zero_cond_t = (sbyte)(managed.QwenImageZeroCondT ? 1 : 0)
qwen_image_zero_cond_t = (sbyte)(managed.QwenImageZeroCondT ? 1 : 0),
max_vram = managed.MaxVRam
};
}

View File

@ -0,0 +1,71 @@
// ReSharper disable MemberCanBeMadeStatic.Global
using System;
using System.Runtime.InteropServices.Marshalling;
namespace StableDiffusion.NET;
[CustomMarshaller(typeof(HiresParameter), MarshalMode.ManagedToUnmanagedIn, typeof(HiresParameterMarshallerIn))]
[CustomMarshaller(typeof(HiresParameter), MarshalMode.ManagedToUnmanagedOut, typeof(HiresParameterMarshaller))]
[CustomMarshaller(typeof(HiresParameter), MarshalMode.ManagedToUnmanagedRef, typeof(HiresParameterMarshallerRef))]
internal static unsafe class HiresParameterMarshaller
{
public static HiresParameter ConvertToManaged(Native.Types.sd_hires_params_t unmanaged)
{
HiresParameter parameter = new()
{
Enabled = unmanaged.enabled == 1,
Upscaler = unmanaged.upscaler,
ModelPath = AnsiStringMarshaller.ConvertToManaged(unmanaged.model_path),
Scale = unmanaged.scale,
TargetWidth = unmanaged.target_width,
TargetHeight = unmanaged.target_height,
Steps = unmanaged.steps,
DenoisingStrength = unmanaged.denoising_strength,
UpscaleTileSize = unmanaged.upscale_tile_size
};
return parameter;
}
internal ref struct HiresParameterMarshallerIn
{
private Native.Types.sd_hires_params_t _hiresParams;
public void FromManaged(HiresParameter managed)
{
_hiresParams = new Native.Types.sd_hires_params_t
{
enabled = (sbyte)(managed.Enabled ? 1 : 0),
upscaler = managed.Upscaler,
model_path = AnsiStringMarshaller.ConvertToUnmanaged(managed.ModelPath),
scale = managed.Scale,
target_width = managed.TargetWidth,
target_height = managed.TargetHeight,
steps = managed.Steps,
denoising_strength = managed.DenoisingStrength,
};
}
public Native.Types.sd_hires_params_t ToUnmanaged() => _hiresParams;
public void Free()
{
AnsiStringMarshaller.Free(_hiresParams.model_path);
}
}
internal ref struct HiresParameterMarshallerRef()
{
private HiresParameterMarshallerIn _inMarshaller = new();
private HiresParameter? _parameter;
public void FromManaged(HiresParameter managed) => _inMarshaller.FromManaged(managed);
public Native.Types.sd_hires_params_t ToUnmanaged() => _inMarshaller.ToUnmanaged();
public void FromUnmanaged(Native.Types.sd_hires_params_t unmanaged) => _parameter = ConvertToManaged(unmanaged);
public HiresParameter ToManaged() => _parameter ?? throw new NullReferenceException($"{nameof(FromUnmanaged)} needs to be called before ToManaged.");
public void Free() => _inMarshaller.Free();
}
}

View File

@ -39,7 +39,8 @@ internal static unsafe class ImageGenerationParameterMarshaller
StyleStrength = unmanaged.pm_params.style_strength,
},
VaeTiling = TilingParameterMarshaller.ConvertToManaged(unmanaged.vae_tiling_params),
Cache = CacheParameterMarshaller.ConvertToManaged(unmanaged.cache)
Cache = CacheParameterMarshaller.ConvertToManaged(unmanaged.cache),
Hires = HiresParameterMarshaller.ConvertToManaged(unmanaged.hires)
};
for (int i = 0; i < unmanaged.lora_count; i++)
@ -61,6 +62,7 @@ internal static unsafe class ImageGenerationParameterMarshaller
private SampleParameterMarshaller.SampleParameterMarshallerIn _sampleParameterMarshaller = new();
private TilingParameterMarshaller.TilingParameterMarshallerIn _tilingParameterMarshaller = new();
private CacheParameterMarshaller.CacheParameterMarshallerIn _cacheParameterMarshaller = new();
private HiresParameterMarshaller.HiresParameterMarshallerIn _hiresParameterMarshaller = new();
private Native.Types.sd_img_gen_params_t _imgGenParams;
private Native.Types.sd_image_t _initImage;
@ -77,6 +79,7 @@ internal static unsafe class ImageGenerationParameterMarshaller
_sampleParameterMarshaller.FromManaged(managed.SampleParameter);
_tilingParameterMarshaller.FromManaged(managed.VaeTiling);
_cacheParameterMarshaller.FromManaged(managed.Cache);
_hiresParameterMarshaller.FromManaged(managed.Hires);
_initImage = managed.InitImage?.ToSdImage() ?? new Native.Types.sd_image_t();
_controlNetImage = managed.ControlNet.Image?.ToSdImage() ?? new Native.Types.sd_image_t();
@ -140,6 +143,7 @@ internal static unsafe class ImageGenerationParameterMarshaller
pm_params = photoMakerParams,
vae_tiling_params = _tilingParameterMarshaller.ToUnmanaged(),
cache = _cacheParameterMarshaller.ToUnmanaged(),
hires = _hiresParameterMarshaller.ToUnmanaged(),
loras = _loras,
lora_count = (uint)managed.Loras.Count,
};
@ -166,6 +170,7 @@ internal static unsafe class ImageGenerationParameterMarshaller
_sampleParameterMarshaller.Free();
_tilingParameterMarshaller.Free();
_cacheParameterMarshaller.Free();
_hiresParameterMarshaller.Free();
for (int i = 0; i < _imgGenParams.lora_count; i++)
AnsiStringMarshaller.Free(_imgGenParams.loras[i].path);

View File

@ -11,22 +11,24 @@ namespace StableDiffusion.NET;
using int32_t = int;
using int64_t = long;
using lora_apply_mode_t = LoraApplyMode;
using prediction_t = Prediction;
using preview_t = Preview;
using rng_type_t = RngType;
using sample_method_t = Sampler;
using scheduler_t = Scheduler;
using prediction_t = Prediction;
using sd_cache_mode_t = CacheMode;
using sd_cache_params_t = CacheParameter;
using sd_hires_params_t = HiresParameter;
using sd_ctx_params_t = DiffusionModelParameter;
using sd_ctx_t = Native.Types.sd_ctx_t;
using sd_hires_upscaler_t = HiresUpscaler;
using sd_image_t = Native.Types.sd_image_t;
using sd_sample_params_t = SampleParameter;
using sd_img_gen_params_t = ImageGenerationParameter;
using sd_log_level_t = LogLevel;
using sd_sample_params_t = SampleParameter;
using sd_type_t = Quantization;
using sd_vid_gen_params_t = VideoGenerationParameter;
using lora_apply_mode_t = LoraApplyMode;
using preview_t = Preview;
using size_t = nuint;
using uint32_t = uint;
using uint8_t = byte;
@ -104,6 +106,7 @@ internal unsafe partial class Native
public sbyte chroma_use_t5_mask;
public int chroma_t5_mask_pad;
public sbyte qwen_image_zero_cond_t;
public float max_vram;
}
[StructLayout(LayoutKind.Sequential)]
@ -177,6 +180,13 @@ internal unsafe partial class Native
public int taylorseer_skip_interval;
public byte* scm_mask;
public sbyte scm_policy_dynamic;
public float spectrum_w;
public int spectrum_m;
public float spectrum_lam;
public int spectrum_window_size;
public float spectrum_flex_window;
public int spectrum_warmup_steps;
public float spectrum_stop_percent;
}
[StructLayout(LayoutKind.Sequential)]
@ -187,6 +197,20 @@ internal unsafe partial class Native
public byte* path;
}
[StructLayout(LayoutKind.Sequential)]
internal struct sd_hires_params_t
{
public sbyte enabled;
public sd_hires_upscaler_t upscaler;
public byte* model_path;
public float scale;
public int target_width;
public int target_height;
public int steps;
public float denoising_strength;
public int upscale_tile_size;
}
[StructLayout(LayoutKind.Sequential)]
internal struct sd_img_gen_params_t
{
@ -212,6 +236,7 @@ internal unsafe partial class Native
public sd_pm_params_t pm_params;
public sd_tiling_params_t vae_tiling_params;
public sd_cache_params_t cache;
public sd_hires_params_t hires;
}
[StructLayout(LayoutKind.Sequential)]
@ -269,6 +294,15 @@ internal unsafe partial class Native
[return: MarshalAs(UnmanagedType.LPStr)]
internal static partial string sd_get_system_info();
[LibraryImport(LIB_NAME, EntryPoint = "sd_ctx_supports_image_generation")]
[return: MarshalAs(UnmanagedType.I1)]
internal static partial bool sd_ctx_supports_image_generation(sd_ctx_t* sd_ctx);
[LibraryImport(LIB_NAME, EntryPoint = "sd_ctx_supports_video_generation")]
[return: MarshalAs(UnmanagedType.I1)]
internal static partial bool sd_ctx_supports_video_generation(sd_ctx_t* sd_ctx);
//
[LibraryImport(LIB_NAME, EntryPoint = "sd_type_name")]
@ -320,9 +354,19 @@ internal unsafe partial class Native
[LibraryImport(LIB_NAME, EntryPoint = "str_to_lora_apply_mode")]
internal static partial lora_apply_mode_t str_to_lora_apply_mode([MarshalAs(UnmanagedType.LPStr)] string str);
[LibraryImport(LIB_NAME, EntryPoint = "sd_hires_upscaler_name")]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static partial string sd_hires_upscaler_name(sd_hires_upscaler_t upscaler);
[LibraryImport(LIB_NAME, EntryPoint = "str_to_sd_hires_upscaler")]
internal static partial sd_hires_upscaler_t str_to_sd_hires_upscaler([MarshalAs(UnmanagedType.LPStr)] string str);
[LibraryImport(LIB_NAME, EntryPoint = "sd_cache_params_init")]
internal static partial void sd_cache_params_init([MarshalUsing(typeof(CacheParameterMarshaller))] ref sd_cache_params_t cache_params);
[LibraryImport(LIB_NAME, EntryPoint = "sd_hires_params_init")]
internal static partial void sd_hires_params_init([MarshalUsing(typeof(HiresParameterMarshaller))] ref sd_hires_params_t hires_params);
//
[LibraryImport(LIB_NAME, EntryPoint = "sd_ctx_params_init")]

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0</TargetFrameworks>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

View File

@ -16,7 +16,7 @@ public static unsafe class StableDiffusionCpp
private static Native.sd_preview_cb_t? _previewCallback;
// ReSharper restore NotAccessedField.Local
public static string ExpectedSDCommit => "5792c66";
public static string ExpectedSDCommit => "90e87bc";
#endregion