Refactor and optimize rendering pipeline

- Added `<IsTrimmable>` property in project files for trimming.
- Replaced bindless texture types with non-bindless equivalents.
- Refactored `ShaderDescriptor` and `ShaderPass` for better modularity.
- Introduced `ShaderDescriptorExtensions` for property size calculations.
- Simplified constant buffer handling in `Material.cs`.
- Improved resource management in `D3D12` components.
- Added support for static meshes and optimized resource barriers.
- Refactored shader code generation and property merging in `SDLCompiler`.
- Removed unused or redundant code (e.g., `IncludesBlock` parser).
- Updated comments, documentation, and error handling for clarity.
This commit is contained in:
2025-11-28 18:58:50 +09:00
parent 0720444c2c
commit bd97d233cb
49 changed files with 842 additions and 1025 deletions

View File

@@ -154,7 +154,6 @@ public ref struct GraphicsPSODescriptor
get; set;
}
public ReadOnlySpan<TextureFormat> RtvFormats
{
get; set;
@@ -267,7 +266,6 @@ public struct RectDesc
{
get; set;
}
}
public struct SubResourceData
@@ -311,6 +309,24 @@ public struct PassDepthStencilDesc
}
public struct BarrierDesc
{
public Handle<GraphicsBuffer> Resource
{
get; set;
}
public ResourceState StateBefore
{
get; set;
}
public ResourceState StateAfter
{
get; set;
}
}
public struct ResourceDesc
{
[StructLayout(LayoutKind.Explicit)]
@@ -381,13 +397,13 @@ public struct ResourceDesc
}
/// <summary>
/// Render target description
/// Render Target description
/// Supports either color OR depth rendering, not both
/// </summary>
public struct RenderTargetDesc
{
/// <summary>
/// Width of the render target
/// Width of the render Target
/// </summary>
public uint Width
{
@@ -395,7 +411,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Height of the render target
/// Height of the render Target
/// </summary>
public uint Height
{
@@ -403,7 +419,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Slice of the render target
/// Slice of the render Target
/// </summary>
public uint Slice
{
@@ -411,7 +427,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Type of render target
/// Type of render Target
/// </summary>
public RenderTargetType Type
{
@@ -419,7 +435,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Target texture format
/// Target texture Format
/// </summary>
public TextureFormat Format
{
@@ -435,7 +451,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Creation flags for the render target
/// Creation flags for the render Target
/// </summary>
public RenderTargetCreationFlags CreationFlags
{
@@ -459,7 +475,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Creates a color render target
/// Creates a color render Target
/// </summary>
public static RenderTargetDesc Color(uint width, uint height, uint slice = 1,
TextureFormat format = TextureFormat.R8G8B8A8_UNorm, TextureDimension dimension = TextureDimension.Texture2D,
@@ -481,7 +497,7 @@ public struct RenderTargetDesc
}
/// <summary>
/// Creates a depth render target
/// Creates a depth render Target
/// </summary>
public static RenderTargetDesc Depth(uint width, uint height, uint slice = 1,
TextureFormat format = TextureFormat.D24_UNorm_S8_UInt, TextureDimension dimension = TextureDimension.Texture2D,
@@ -554,7 +570,7 @@ public struct TextureDesc
}
/// <summary>
/// Texture format
/// Texture Format
/// </summary>
public TextureFormat Format
{
@@ -630,59 +646,82 @@ public struct SwapChainDesc
/// <summary>
/// Width of the swap chain
/// </summary>
public uint width;
public uint Width
{
get; set;
}
/// <summary>
/// Height of the swap chain
/// </summary>
public uint height;
/// <summary>
/// Back buffer format
/// </summary>
public TextureFormat format;
/// <summary>
/// Target for presentation (window handle or composition target)
/// </summary>
public SwapChainTarget target;
public SwapChainDesc(uint width, uint height, SwapChainTarget target, TextureFormat format = TextureFormat.B8G8R8A8_UNorm, uint bufferCount = 2)
public uint Height
{
this.width = width;
this.height = height;
this.format = format;
this.target = target;
get; set;
}
/// <summary>
/// Back buffer Format
/// </summary>
public TextureFormat Format
{
get; set;
}
/// <summary>
/// Target for presentation (window handle or composition Target)
/// </summary>
public SwapChainTarget Target
{
get; set;
}
public uint BufferCount
{
get; set;
}
}
/// <summary>
/// Swap chain target (window handle or composition surface)
/// Swap chain Target (window handle or composition surface)
/// </summary>
public struct SwapChainTarget
{
/// <summary>
/// Target type
/// </summary>
public SwapChainTargetType type;
public SwapChainTargetType Type
{
get; set;
}
/// <summary>
/// Window handle for HWND targets
/// </summary>
public nint windowHandle;
public nint WindowHandle
{
get; set;
}
/// <summary>
/// Composition surface for UWP/WinUI targets
/// </summary>
public object? compositionSurface;
public object? CompositionSurface
{
get; set;
}
public static SwapChainTarget FromWindowHandle(nint hwnd)
{
return new SwapChainTarget
{
type = SwapChainTargetType.WindowHandle,
windowHandle = hwnd,
compositionSurface = null
Type = SwapChainTargetType.WindowHandle,
WindowHandle = hwnd,
CompositionSurface = null
};
}
@@ -690,9 +729,9 @@ public struct SwapChainTarget
{
return new SwapChainTarget
{
type = SwapChainTargetType.Composition,
windowHandle = nint.Zero,
compositionSurface = surface
Type = SwapChainTargetType.Composition,
WindowHandle = 0,
CompositionSurface = surface
};
}
}

View File

@@ -53,21 +53,21 @@ public interface ICommandBuffer : IDisposable
void SetScissorRect(RectDesc rect);
/// <summary>
/// Sets the optional render targets and optional depth target for subsequent rendering operations.
/// Sets the optional render targets and optional depth Target for subsequent rendering operations.
/// </summary>
/// <remarks>
/// To specify no render targets, provide an empty span for <paramref name="renderTargets"/>.
/// Use <see cref="Handle{Texture}.Invalid"/> for <paramref name="depthTarget"/> if no depth target is required.
/// Use <see cref="Handle{Texture}.Invalid"/> for <paramref name="depthTarget"/> if no depth Target is required.
/// </remarks>
/// <param name="renderTargets">A read-only span of handles to textures that will be used as render targets.
/// The order of handles determines the order in which render targets are bound.</param>
/// <param name="depthTarget">A handle to the texture to be used as the depth target. Specify a invalid handle if no depth target is required.</param>
/// <param name="depthTarget">A handle to the texture to be used as the depth Target. Specify a invalid handle if no depth Target is required.</param>
void SetRenderTargets(ReadOnlySpan<Handle<Texture>> renderTargets, Handle<Texture> depthTarget);
/// <summary>
/// Begins a render pass with the specified render target
/// Begins a render pass with the specified render Target
/// </summary>
/// <param name="rtDescs">Render target descriptions</param>
/// <param name="rtDescs">Render Target descriptions</param>
/// <param name="depthDesc">Depth stencil description</param>
/// <param name="allowUAVWrites">Whether UAV writes are allowed during the render pass</param>
void BeginRenderPass(ReadOnlySpan<PassRenderTargetDesc> rtDescs, PassDepthStencilDesc depthDesc, bool allowUAVWrites = false);
@@ -78,12 +78,18 @@ public interface ICommandBuffer : IDisposable
void EndRenderPass();
/// <summary>
/// Inserts a resource barrier for state transitions
/// Inserts multiple resource barriers for state transitions.
/// </summary>
/// <param name="resource">Resource to transition</param>
/// <param name="before">Current resource state</param>
/// <param name="after">Target resource state</param>
void ResourceBarrier(Handle<GPUResource> resource, ResourceState before, ResourceState after);
/// <param name="barrierDescs">Resource barrier descriptions</param>
void ResourceBarrier(ReadOnlySpan<BarrierDesc> barrierDescs);
/// <summary>
/// Inserts a resource barrier for state transitions.
/// </summary>
/// <param name="resource">A handle to the GPU resource to transition.</param>
/// <param name="stateBefore">The current state of the resource before the transition.</param>
/// <param name="stateAfter">The desired state of the resource after the transition.</param>
void ResourceBarrier(Handle<GPUResource> resource, ResourceState stateBefore, ResourceState stateAfter);
/// <summary>
/// Sets the pipeline state object
@@ -176,10 +182,10 @@ public interface ICommandBuffer : IDisposable
/// </summary>
/// <param name="texture">The texture resource to which the subresource data will be uploaded. Must be a valid, initialized texture handle.</param>
/// <param name="firstSubresource">The index of the first subresource in the texture to receive data. Must be less than the total number of subresources in the texture.</param>
/// <param name="subresources">A reference to the structure containing the subresource data to upload. The data must match the format and layout expected by the texture.</param>
/// <param name="subresources">A reference to the structure containing the subresource data to upload. The data must match the Format and layout expected by the texture.</param>
/// <param name="numSubresources">The number of subresources to upload, starting from <paramref name="firstSubresource"/>.
/// Must be greater than zero and not exceed the remaining subresources in the texture.</param>
void UploadTexture(Handle<Texture> texture, params ReadOnlySpan<SubResourceData> subresources);
void UploadTexture(Handle<Texture> texture, ReadOnlySpan<SubResourceData> subresources);
/// <summary>
/// Copies a specified number of bytes from the source graphics buffer to the destination graphics buffer.

View File

@@ -23,5 +23,4 @@ public interface IPipelineLibrary : IDisposable
void InitializeLibrary(string? filePath);
void SaveLibraryToDisk(string filePath);
Result<GraphicsPipelineKey> CompilePSO(ref readonly GraphicsPSODescriptor descriptor, ref readonly GraphicsCompiledResult compiled);
Result<CBufferInfo, ResultStatus> GetCBufferInfo(ShaderPassKey passId);
}

View File

@@ -15,9 +15,9 @@ public interface IRenderer : IDisposable
}
/// <summary>
/// Sets the render target for this renderer
/// Sets the render Target for this renderer
/// </summary>
/// <param name="renderTarget">Render target to render into</param>
/// <param name="renderTarget">Render Target to render into</param>
public void SetRenderTarget(Handle<Texture> renderTarget);
/// <summary>

View File

@@ -15,9 +15,9 @@ public interface IResourceAllocator : IDisposable
public Handle<Texture> CreateTexture(ref readonly TextureDesc desc, bool tempResource = false);
/// <summary>
/// Creates a render target for off-screen rendering
/// Creates a render Target for off-screen rendering
/// </summary>
/// <param name="desc">Render target description</param>
/// <param name="desc">Render Target description</param>
/// <returns>A new texture handle point to the resource</returns>
public Handle<Texture> CreateRenderTarget(ref readonly RenderTargetDesc desc, bool tempResource = false);

View File

@@ -11,6 +11,9 @@ public interface IResourceReleasable
void ReleaseResource(IResourceDatabase database);
}
// TODO: Consider adding methods for resource enumeration, statistics, and bulk operations.
// TODO: Consider adding async resource loading and streaming support.
// TODO: Mesh, Material, Shader management could be separated into their own interfaces for better modularity because they are not bound to specific graphics API.
public interface IResourceDatabase : IDisposable
{
/*
@@ -155,18 +158,4 @@ public interface IResourceDatabase : IDisposable
/// </summary>
/// <param name="id">The identifier of the shader to release. Must refer to a valid, previously created shader.</param>
void ReleaseShader(Identifier<Shader> id);
/// <summary>
/// Adds a shader pass to the collection using the specified identifier.
/// </summary>
/// <param name="passKey">The unique identifier for the shader pass.</param>
/// <param name="pass">The shader pass to add. Cannot be null.</param>
void AddShaderPass(ShaderPassKey passKey, ShaderPass pass);
/// <summary>
/// Retrieves the shader pass associated with the specified pass identifier.
/// </summary>
/// <param name="passKey">The unique identifier of the shader pass to retrieve.</param>
/// <returns>The <see cref="ShaderPass"/> corresponding to the specified identifier, or null if no matching shader pass is found.</returns>
ShaderPass GetShaderPass(ShaderPassKey passKey);
}

View File

@@ -22,8 +22,8 @@ internal static class RHIUtility
var packed = false;
var planar = false;
var bpe = 0;
//switch (format)
//switch (Format)
//{
// case Format.BC1Typeless:
// case Format.BC1Unorm: