Added CopyTexture support in ICommandBuffer

This commit is contained in:
2026-02-26 21:40:07 +09:00
parent 162b71f309
commit 6f802ac12b
7 changed files with 136 additions and 1325 deletions

View File

@@ -5,6 +5,7 @@ using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Utilities;
using System.Runtime.CompilerServices;
using TerraFX.Interop.DirectX;
using TerraFX.Interop.Gdiplus;
using TerraFX.Interop.Windows;
using static TerraFX.Aliases.D3D_Alias;
@@ -984,10 +985,32 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
}
}
public void CopyTexture(Handle<Texture> dst, Handle<Texture> src)
private D3D12_TEXTURE_COPY_LOCATION GetTextureCopyLocation(SharedPtr<ID3D12Resource> texture, TextureSubresource subres)
{
throw new NotImplementedException();
var flatIndex = subres.MipLevel + subres.ArrayLayer * texture.Get()->GetDesc().MipLevels;
return new D3D12_TEXTURE_COPY_LOCATION
{
pResource = texture,
Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
SubresourceIndex = flatIndex
};
}
private bool AreTexturesIdentical(SharedPtr<ID3D12Resource> tex1, SharedPtr<ID3D12Resource> tex2)
{
var desc1 = tex1.Get()->GetDesc();
var desc2 = tex2.Get()->GetDesc();
return desc1.Width == desc2.Width
&& desc1.Height == desc2.Height
&& desc1.DepthOrArraySize == desc2.DepthOrArraySize
&& desc1.MipLevels == desc2.MipLevels
&& desc1.Format == desc2.Format
&& desc1.SampleDesc.Count == desc2.SampleDesc.Count;
}
public void CopyTexture(Handle<Texture> dst, TextureRegion? dstRegion, Handle<Texture> src, TextureRegion? srcRegion)
{
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
@@ -1011,8 +1034,34 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
return;
}
// TODO
_commandList.Get()->CopyTextureRegion(null, 0, 0, 0, null, null);
if (dstRegion == null || srcRegion == null)
{
if (!AreTexturesIdentical(pDstResource, pSrcResource))
{
RecordError(nameof(CopyTexture), Error.InvalidArgument);
return;
}
_commandList.Get()->CopyResource(pDstResource, pSrcResource);
return;
}
var dstRegionV = dstRegion.Value;
var srcRegionV = srcRegion.Value;
var dstLocation = GetTextureCopyLocation(pDstResource, dstRegionV.Subresource);
var srcLocation = GetTextureCopyLocation(pSrcResource, srcRegionV.Subresource);
var srcBoc = new D3D12_BOX
{
left = srcRegionV.X,
top = srcRegionV.Y,
front = srcRegionV.Z,
right = srcRegionV.X + srcRegionV.Width,
bottom = srcRegionV.Y + srcRegionV.Height,
back = srcRegionV.Z + srcRegionV.Depth
};
_commandList.Get()->CopyTextureRegion(&dstLocation, dstRegionV.X, dstRegionV.Y, dstRegionV.Z, &srcLocation, &srcBoc);
}
public void Dispose()

View File

@@ -457,6 +457,58 @@ public struct PassDepthStencilDesc
}
public struct TextureSubresource
{
public uint MipLevel
{
get; set;
}
public uint ArrayLayer
{
get; set;
}
}
public struct TextureRegion
{
public TextureSubresource Subresource
{
get; set;
}
public uint X
{
get; set;
}
public uint Y
{
get; set;
}
public uint Z
{
get; set;
}
public uint Width
{
get; set;
}
public uint Height
{
get; set;
}
public uint Depth
{
get; set;
}
}
public struct BarrierSubresourceRange
{
public uint IndexOrFirstMipLevel

View File

@@ -65,8 +65,21 @@ public interface ICommandBuffer : IDisposable
/// <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>
/// Clears the specified render target to a given color.
/// </summary>
/// <param name="renderTarget">A handle to the render target texture to be cleared. Must reference a valid render target.</param>
/// <param name="clearColor">The color value used to clear the render target. Specifies the RGBA components to fill the target.</param>
void ClearRenderTargetView(Handle<Texture> renderTarget, Color128 clearColor);
/// <summary>
/// Clears the specified depth-stencil view by resetting its depth and/or stencil values.
/// </summary>
/// <param name="depthStencil">A handle to the depth-stencil texture to be cleared. Must reference a valid depth-stencil resource.</param>
/// <param name="inlcludeDepth">A value indicating whether the depth component should be cleared.</param>
/// <param name="includeStencil">A value indicating whether the stencil component should be cleared.</param>
/// <param name="clearDepth">The value to which the depth buffer will be set. Typically ranges from 0.0f (nearest) to 1.0f (farthest).</param>
/// <param name="clearStencil">The value to which the stencil buffer will be set. Must be a valid stencil value supported by the format.</param>
void ClearDepthStencilView(Handle<Texture> depthStencil, bool inlcludeDepth, bool includeStencil, float clearDepth = 1.0f, byte clearStencil = 0);
/// <summary>
@@ -201,4 +214,13 @@ public interface ICommandBuffer : IDisposable
/// <param name="srcOffset">The byte Offset in the source buffer at which to begin reading. Must be zero or greater.</param>
/// <param name="numBytes">The number of bytes to copy. If zero, copies the remaining bytes from the source buffer starting at <paramref name="srcOffset"/>.</param>
void CopyBuffer(Handle<GraphicsBuffer> dest, Handle<GraphicsBuffer> src, ulong destOffset = 0, ulong srcOffset = 0, ulong numBytes = 0);
/// <summary>
/// Copies a region of a source texture to a destination texture. The source and destination regions can be specified to copy a subset of the textures, or the entire textures if the regions are null.
/// </summary>
/// <param name="dst">The handle to the destination texture where data will be written.</param>
/// <param name="dstRegion">The region of the destination texture to copy to. If null, the entire texture will be used.</param>
/// <param name="src">The handle to the source texture from which data will be read.</param>
/// <param name="srcRegion">The region of the source texture to copy from. If null, the entire texture will be used.</param>
void CopyTexture(Handle<Texture> dst, TextureRegion? dstRegion, Handle<Texture> src, TextureRegion? srcRegion);
}

View File

@@ -0,0 +1,9 @@
using Ghost.Graphics.Core;
using Ghost.Graphics.RHI;
namespace Ghost.Graphics.Contracts;
public interface IRenderPipeline
{
void Render(RenderContext ctx, ReadOnlySpan<Camera> cameras);
}