feat(rhi): add NoAccess ops, axis conversion, meshlet color

Added NoAccess to attachment ops for depth/stencil, updated D3D12 and RenderGraph to handle new ops, and improved axis/handedness conversion in mesh loading. Enabled meshlet color hashing in test shader. Changed default rasterizer winding, added format helpers, and updated camera transform for correct mesh orientation. JobScheduler usage commented out for now.
This commit is contained in:
2026-04-01 19:57:27 +09:00
parent eb41f23582
commit e32a24739d
11 changed files with 79 additions and 51 deletions

View File

@@ -509,6 +509,7 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
AttachmentLoadOp.NoAccess => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
};
@@ -517,7 +518,8 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
{
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
AttachmentStoreOp.NoAccess => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS
};
// Map stencil load operation
@@ -526,6 +528,7 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
AttachmentLoadOp.NoAccess => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
};
@@ -534,15 +537,10 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
{
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
AttachmentStoreOp.NoAccess => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS
};
if (!depthDesc.HasStencil)
{
stencilLoadAccessType = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS;
stencilStoreAccessType = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
}
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
{
cpuDescriptor = cpuHandle,

View File

@@ -504,7 +504,7 @@ internal static unsafe class D3D12Utility
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
D3D12_FILL_MODE fillMode,
D3D12_CULL_MODE cullMode,
bool frontCounterClockwise = true,
bool frontCounterClockwise = false,
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,

View File

@@ -1359,11 +1359,13 @@ public enum AttachmentLoadOp
{
Load,
Clear,
DontCare
DontCare,
NoAccess
}
public enum AttachmentStoreOp
{
Store,
DontCare
DontCare,
NoAccess
}

View File

@@ -2,6 +2,7 @@ using Ghost.Core;
using Ghost.Core.Graphics;
using Ghost.Core.Utilities;
using System.IO.Hashing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Ghost.Graphics.RHI;
@@ -10,6 +11,7 @@ public static class RHIUtility
{
public const int MAX_RENDER_TARGETS = 8;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint GetBytesPerPixel(this TextureFormat format)
{
return format switch
@@ -24,9 +26,16 @@ public static class RHIUtility
};
}
public static uint GetTotalBytes(this TextureDesc desc)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsDepthStencilFormat(this TextureFormat format)
{
return desc.Format.GetBytesPerPixel() * desc.Width * desc.Height * desc.Slice;
return format == TextureFormat.D24_UNorm_S8_UInt || format == TextureFormat.D32_Float;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsStencilFormat(this TextureFormat format)
{
return format == TextureFormat.D24_UNorm_S8_UInt;
}
public static void GetSurfaceInfo(this TextureFormat format, uint width, uint height, out uint rowPitch, out uint slicePitch, out uint rowCount)
@@ -136,12 +145,14 @@ public static class RHIUtility
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Key64<ShaderPass> CreateShaderPassKey(string passID)
{
var passIdSpan = passID.AsSpan();
return new Key64<ShaderPass>(XxHash3.HashToUInt64(MemoryMarshal.AsBytes(passIdSpan)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Key64<ShaderVariant> CreateShaderVariantKey(Key64<ShaderPass> passKey, ref readonly LocalKeywordSet keywords)
{
var passHash = passKey.Value;
@@ -176,6 +187,7 @@ public static class RHIUtility
return new Key128<GraphicsPipeline>(new UInt128(lo, hi));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetString(this Key128<GraphicsPipeline> key, Span<char> destination)
{
return key.Value.TryFormat(destination, out var _, "X16");

View File

@@ -294,7 +294,7 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
}
}
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.WriteAll)
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.ReadWrite)
{
ThrowIfDisposed();

View File

@@ -139,18 +139,16 @@ internal sealed class RenderGraphExecutor
ClearStencil = nativePass.depthAttachment.clearStencil,
DepthLoadOp = nativePass.hasDepthAttachment
? nativePass.depthAttachment.loadOp
: AttachmentLoadOp.DontCare,
: AttachmentLoadOp.NoAccess,
DepthStoreOp = nativePass.hasDepthAttachment
? nativePass.depthAttachment.storeOp
: AttachmentStoreOp.DontCare,
: AttachmentStoreOp.NoAccess,
StencilLoadOp = nativePass.hasDepthAttachment
? nativePass.depthAttachment.stencilLoadOp
: AttachmentLoadOp.DontCare,
: AttachmentLoadOp.NoAccess,
StencilStoreOp = nativePass.hasDepthAttachment
? nativePass.depthAttachment.stencilStoreOp
: AttachmentStoreOp.DontCare,
HasStencil = nativePass.hasDepthAttachment &&
(_resources.GetResource(nativePass.depthAttachment.texture).rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt)
: AttachmentStoreOp.NoAccess,
};
commandBuffer.BeginRenderPass(new Span<PassRenderTargetDesc>(pPassRTDescs, nativePass.colorAttachmentCount), depthDesc);

View File

@@ -365,18 +365,16 @@ internal sealed class RenderGraphNativePassBuilder
attachment.storeOp = AttachmentStoreOp.Store;
}
var hasStencil = resource.rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt;
if (hasStencil)
if (resource.rgTextureDesc.format.IsStencilFormat())
{
attachment.stencilLoadOp = attachment.loadOp;
attachment.stencilStoreOp = attachment.storeOp;
}
else
{
attachment.stencilLoadOp = AttachmentLoadOp.DontCare;
attachment.stencilStoreOp = AttachmentStoreOp.DontCare;
attachment.stencilLoadOp = AttachmentLoadOp.NoAccess;
attachment.stencilStoreOp = AttachmentStoreOp.NoAccess;
}
}
}
}

View File

@@ -112,14 +112,14 @@ shader "MyShader/Standard"
// float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
// return perMaterialData.color * blendedColor + input.color;
// uint hash = PCGHash(input.meshletID);
//
// float r = float((hash & 0xFF0000u) >> 16) / 255.0;
// float g = float((hash & 0x00FF00u) >> 8) / 255.0;
// float b = float((hash & 0x0000FFu)) / 255.0;
//
// return float4(r, g, b, 1.0);
return float4(input.normal, 1.0);
uint hash = PCGHash(input.meshletID);
float r = float((hash & 0xFF0000u) >> 16) / 255.0;
float g = float((hash & 0x00FF00u) >> 8) / 255.0;
float b = float((hash & 0x0000FFu)) / 255.0;
return float4(r, g, b, 1.0);
// return float4(input.normal, 1.0);
}
}