Refactor D3D12 Resource Management

Refactored and renamed components related to D3D12 graphics programming, replacing "descriptor" with "viewGroup" to improve resource grouping and management. Updated `D3D12CommandBuffer`, `D3D12DescriptorAllocator`, and `D3D12PipelineLibrary` to reflect these changes. Simplified material and shader creation in `D3D12ResourceAllocator`. Enhanced `D3D12ResourceDatabase` with resource naming for debugging and improved management. Refactored `Shader` and `ShaderPass` to use modern C# features and `IResourceReleasable` interface. Introduced `D3D12Utility` for centralized utility methods. Updated `Material` class for efficient buffer creation. Renamed `ShaderCompiler` to `SDLCompiler` with improved error handling. Updated `MeshRenderPass` to use new shader compilation process. Various improvements in error handling, code readability, and utility methods.
This commit is contained in:
2025-10-23 14:42:53 +09:00
parent d2d9f5feb7
commit 28c386b0bb
28 changed files with 393 additions and 306 deletions

View File

@@ -1,4 +1,5 @@
using Misaki.HighPerformance.Utilities;
using Ghost.Graphics.D3D12.Utilities;
using Misaki.HighPerformance.Utilities;
using System.IO.Hashing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -74,7 +75,7 @@ internal struct GraphicsPipelineHash
data[1] = rtvCount;
data[2] = (ulong)dsvFormat;
for (int i = 0; i < 8; i++)
for (var i = 0; i < 8; i++)
{
data[3 + i] = (ulong)rtvFormats[i];
}
@@ -425,18 +426,88 @@ public struct BufferDesc
}
}
public static class TextureDimensionExtension
/// <summary>
/// Swap chain description
/// </summary>
public struct SwapChainDesc
{
public static TextureDimension ToTextureDimension(this D3D12_RESOURCE_DIMENSION dimension)
/// <summary>
/// Width of the swap chain
/// </summary>
public uint width;
/// <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)
{
return dimension switch
this.width = width;
this.height = height;
this.format = format;
this.target = target;
}
}
/// <summary>
/// Swap chain target (window handle or composition surface)
/// </summary>
public struct SwapChainTarget
{
/// <summary>
/// Target type
/// </summary>
public SwapChainTargetType type;
/// <summary>
/// Window handle for HWND targets
/// </summary>
public nint windowHandle;
/// <summary>
/// Composition surface for UWP/WinUI targets
/// </summary>
public object? compositionSurface;
public static SwapChainTarget FromWindowHandle(nint hwnd)
{
return new SwapChainTarget
{
D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_TEXTURE1D => TextureDimension.Texture2D,
D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_TEXTURE2D => TextureDimension.Texture2D,
D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_TEXTURE3D => TextureDimension.Texture3D,
_ => TextureDimension.Unknown,
type = SwapChainTargetType.WindowHandle,
windowHandle = hwnd,
compositionSurface = null
};
}
public static SwapChainTarget FromCompositionSurface(object surface)
{
return new SwapChainTarget
{
type = SwapChainTargetType.Composition,
windowHandle = nint.Zero,
compositionSurface = surface
};
}
}
/// <summary>
/// Swap chain target types
/// </summary>
public enum SwapChainTargetType
{
WindowHandle,
Composition
}

View File

@@ -1,4 +1,5 @@
using Ghost.Core;
using Ghost.Core.Graphics;
using Ghost.Graphics.Data;
using Misaki.HighPerformance.LowLevel.Collections;
@@ -46,7 +47,8 @@ public interface IResourceAllocator
/// Creates a new shader and returns its unique identifier.
/// </summary>
/// <returns>An <see cref="Identifier{Shader}"/> representing the newly created shader.</returns>
public Identifier<Shader> CreateShader();
/// <param name="descriptor">The viewGroup containing the shader's properties and passes.</param>
public Identifier<Shader> CreateShader(ShaderDescriptor descriptor);
/// <summary>
/// Release a resource given its handle

View File

@@ -13,6 +13,7 @@ public interface IResourceReleasable
public interface IResourceDatabase
{
/*
/// <summary>
/// Imports an external unmanaged resource and returns a handle for use within the resource management system.
/// </summary>
@@ -20,8 +21,9 @@ public interface IResourceDatabase
/// <param name="resourcePtr">A pointer to the external unmanaged resource to be imported. Must remain valid for the duration of the resource's usage.</param>
/// <param name="initialState">The initial state to assign to the imported resource.</param>
/// <returns>A handle representing the imported resource, which can be used for subsequent operations.</returns>
unsafe Handle<GPUResource> ImportExternalResource<T>(T resourcePtr, ResourceState initialState)
unsafe Handle<GPUResource> ImportExternalResource<T>(T resourcePtr, ResourceState initialState, string? name = null)
where T : unmanaged;
*/
/// <summary>
/// Retrieves the current state of the specified resource.
@@ -51,6 +53,16 @@ public interface IResourceDatabase
/// <returns>The bindless index corresponding to the specified GPU resource handle. -1 if the resource does not support bindless access or is not found.</returns>
int GetBindlessIndex(Handle<GPUResource> handle);
/// <summary>
/// Retrieves the name of the GPU resource associated with the specified handle.
/// </summary>
/// <remarks>
/// You should only use this method in debug builds or inside engine editor.
/// </remarks>
/// <param name="handle">A handle to the GPU resource for which to obtain the name. Must reference a valid resource.</param>
/// <returns>The name of the GPU resource associated with the specified handle, or null if the resource does not have a name.</returns>
string? GetResourceName(Handle<GPUResource> handle);
/// <summary>
/// Removes a resource from the database using its handle.
/// </summary>
@@ -116,7 +128,7 @@ public interface IResourceDatabase
/// </summary>
/// <param name="shader">The shader to add. The shader is passed by read-only reference and will not be modified.</param>
/// <returns>The <see cref="Identifier{Shader}"/> representing the newly added shader.</returns>
Identifier<Shader> AddShader(ref readonly Shader shader);
Identifier<Shader> AddShader(Shader shader);
/// <summary>
/// Determines whether a shader with the specified identifier exists in the collection.
@@ -130,7 +142,7 @@ public interface IResourceDatabase
/// </summary>
/// <param name="id">The identifier of the shader to retrieve. Must refer to a valid shader.</param>
/// <returns>A reference to the shader corresponding to the specified identifier.</returns>
ref Shader GetShaderReference(Identifier<Shader> id);
Shader GetShaderReference(Identifier<Shader> id);
/// <summary>
/// Releases the shader associated with the specified identifier, freeing any resources allocated to it.

View File

@@ -50,88 +50,4 @@ public interface ISwapChain : IDisposable
/// <param name="width">New width</param>
/// <param name="height">New height</param>
public void Resize(uint width, uint height);
}
/// <summary>
/// Swap chain description
/// </summary>
public struct SwapChainDesc
{
/// <summary>
/// Width of the swap chain
/// </summary>
public uint width;
/// <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)
{
this.width = width;
this.height = height;
this.format = format;
this.target = target;
}
}
/// <summary>
/// Swap chain target (window handle or composition surface)
/// </summary>
public struct SwapChainTarget
{
/// <summary>
/// Target type
/// </summary>
public SwapChainTargetType type;
/// <summary>
/// Window handle for HWND targets
/// </summary>
public nint windowHandle;
/// <summary>
/// Composition surface for UWP/WinUI targets
/// </summary>
public object? compositionSurface;
public static SwapChainTarget FromWindowHandle(nint hwnd)
{
return new SwapChainTarget
{
type = SwapChainTargetType.WindowHandle,
windowHandle = hwnd,
compositionSurface = null
};
}
public static SwapChainTarget FromCompositionSurface(object surface)
{
return new SwapChainTarget
{
type = SwapChainTargetType.Composition,
windowHandle = nint.Zero,
compositionSurface = surface
};
}
}
/// <summary>
/// Swap chain target types
/// </summary>
public enum SwapChainTargetType
{
WindowHandle,
Composition
}

View File

@@ -1,37 +1,9 @@
using TerraFX.Interop.DirectX;
using TerraFX.Interop.DirectX;
namespace Ghost.Graphics.RHI;
internal static class TextureFormatExtensions
internal static class RHIUtility
{
public static DXGI_FORMAT ToD3D12Format(this TextureFormat format)
{
return format switch
{
TextureFormat.R8G8B8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM,
TextureFormat.B8G8R8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM,
TextureFormat.R16G16B16A16_Float => DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT,
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT,
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT,
TextureFormat.D32_Float => DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT,
_ => throw new NotSupportedException($"Texture format {format} is not supported."),
};
}
public static TextureFormat ToTextureFormat(this DXGI_FORMAT format)
{
return format switch
{
DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM => TextureFormat.R8G8B8A8_UNorm,
DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM => TextureFormat.B8G8R8A8_UNorm,
DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT => TextureFormat.R16G16B16A16_Float,
DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float,
_ => TextureFormat.Unknown,
};
}
public static int GetBytesPerPixel(this TextureFormat format)
{
return format switch