TextureSlice and TextureRegion API

what_if_no_video_threads
cosmonaut 2024-02-29 23:53:11 -08:00
parent e0f4c19dc2
commit 0e723514df
10 changed files with 264 additions and 280 deletions

@ -1 +1 @@
Subproject commit 031ad4c04781fe4a0d98a177333ebf7764d2fe91
Subproject commit 020e76782a2aba7861a8e356d1d212a2bffb2d2e

View File

@ -1,17 +0,0 @@
namespace MoonWorks.Graphics
{
/// <summary>
/// A texture-level pair to be used when binding compute textures.
/// </summary>
public struct TextureLevelBinding
{
public Texture Texture;
public uint MipLevel;
public TextureLevelBinding(Texture texture, uint mipLevel = 0)
{
Texture = texture;
MipLevel = mipLevel;
}
}
}

View File

@ -157,9 +157,9 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = false;
colorAttachmentSampleCount = colorAttachmentInfo.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 1;
colorFormatOne = colorAttachmentInfo.Texture.Format;
colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -182,7 +182,7 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[2];
@ -200,10 +200,10 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = false;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 2;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
#endif
}
@ -232,8 +232,8 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoThree.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[3];
@ -252,11 +252,11 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = false;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 3;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
#endif
}
@ -290,9 +290,9 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoFour);
AssertColorTarget(colorAttachmentInfoFour);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoThree.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoFour.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoFour.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[4];
@ -312,12 +312,12 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = false;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 4;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.Texture.Format;
colorFormatFour = colorAttachmentInfoFour.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format;
#endif
}
@ -348,8 +348,8 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = true;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.Texture.SampleCount;
depthStencilFormat = depthStencilAttachmentInfo.Texture.Format;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -370,7 +370,7 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfo);
AssertColorTarget(colorAttachmentInfo);
AssertSameSampleCount(colorAttachmentInfo.Texture, depthStencilAttachmentInfo.Texture);
AssertSameSampleCount(colorAttachmentInfo.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[1];
@ -389,11 +389,11 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = true;
colorAttachmentSampleCount = colorAttachmentInfo.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 1;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.Texture.SampleCount;
colorFormatOne = colorAttachmentInfo.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.Texture.Format;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -420,8 +420,8 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, depthStencilAttachmentInfo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[2];
@ -441,11 +441,11 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = true;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 2;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -477,9 +477,9 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, depthStencilAttachmentInfo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[3];
@ -500,12 +500,12 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = true;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 3;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -542,10 +542,10 @@ namespace MoonWorks.Graphics
AssertTextureNotNull(colorAttachmentInfoFour);
AssertColorTarget(colorAttachmentInfoFour);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoTwo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoThree.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, colorAttachmentInfoFour.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.Texture, depthStencilAttachmentInfo.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoFour.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[4];
@ -567,13 +567,13 @@ namespace MoonWorks.Graphics
#if DEBUG
renderPassActive = true;
hasDepthStencilAttachment = true;
colorAttachmentSampleCount = colorAttachmentInfoOne.Texture.SampleCount;
colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
colorAttachmentCount = 4;
colorFormatOne = colorAttachmentInfoOne.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.Texture.Format;
colorFormatFour = colorAttachmentInfoFour.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.Texture.Format;
colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format;
depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
}
@ -1662,9 +1662,9 @@ namespace MoonWorks.Graphics
/// <summary>
/// Binds a texture to be used in the compute shader.
/// </summary>
/// <param name="binding">A texture-level pair to bind.</param>
/// <param name="slice">A texture slice to bind.</param>
public unsafe void BindComputeTextures(
TextureLevelBinding binding
TextureSlice slice
) {
#if DEBUG
AssertNotSubmitted();
@ -1673,28 +1673,24 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(1);
#endif
var texturePtrs = stackalloc IntPtr[1];
texturePtrs[0] = binding.Texture.Handle;
var mipLevels = stackalloc uint[1];
mipLevels[0] = binding.MipLevel;
var textureSlicePtrs = stackalloc Refresh.TextureSlice[1];
textureSlicePtrs[0] = slice.ToRefreshTextureSlice();
Refresh.Refresh_BindComputeTextures(
Device.Handle,
Handle,
(IntPtr) texturePtrs,
(IntPtr) mipLevels
(IntPtr) textureSlicePtrs
);
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures(
TextureLevelBinding bindingOne,
TextureLevelBinding bindingTwo
TextureSlice sliceOne,
TextureSlice sliceTwo
) {
#if DEBUG
AssertNotSubmitted();
@ -1703,32 +1699,27 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(2);
#endif
var texturePtrs = stackalloc IntPtr[2];
texturePtrs[0] = bindingOne.Texture.Handle;
texturePtrs[1] = bindingTwo.Texture.Handle;
var mipLevels = stackalloc uint[2];
mipLevels[0] = bindingOne.MipLevel;
mipLevels[1] = bindingTwo.MipLevel;
var textureSlicePtrs = stackalloc Refresh.TextureSlice[2];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice();
Refresh.Refresh_BindComputeTextures(
Device.Handle,
Handle,
(IntPtr) texturePtrs,
(IntPtr) mipLevels
(IntPtr) textureSlicePtrs
);
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
/// <param name="bindingThree">A texture-level pair to bind.</param>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
/// <param name="sliceThree">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures(
TextureLevelBinding bindingOne,
TextureLevelBinding bindingTwo,
TextureLevelBinding bindingThree
TextureSlice sliceOne,
TextureSlice sliceTwo,
TextureSlice sliceThree
) {
#if DEBUG
AssertNotSubmitted();
@ -1737,36 +1728,30 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(3);
#endif
var texturePtrs = stackalloc IntPtr[3];
texturePtrs[0] = bindingOne.Texture.Handle;
texturePtrs[1] = bindingTwo.Texture.Handle;
texturePtrs[2] = bindingThree.Texture.Handle;
var mipLevels = stackalloc uint[3];
mipLevels[0] = bindingOne.MipLevel;
mipLevels[1] = bindingTwo.MipLevel;
mipLevels[2] = bindingThree.MipLevel;
var textureSlicePtrs = stackalloc Refresh.TextureSlice[3];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice();
textureSlicePtrs[2] = sliceThree.ToRefreshTextureSlice();
Refresh.Refresh_BindComputeTextures(
Device.Handle,
Handle,
(IntPtr) texturePtrs,
(IntPtr) mipLevels
(IntPtr) textureSlicePtrs
);
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
/// <param name="bindingThree">A texture-level pair to bind.</param>
/// <param name="bindingFour">A texture-level pair to bind.</param>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
/// <param name="sliceThree">A texture-level pair to bind.</param>
/// <param name="sliceFour">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures(
TextureLevelBinding bindingOne,
TextureLevelBinding bindingTwo,
TextureLevelBinding bindingThree,
TextureLevelBinding bindingFour
TextureSlice sliceOne,
TextureSlice sliceTwo,
TextureSlice sliceThree,
TextureSlice sliceFour
) {
#if DEBUG
AssertNotSubmitted();
@ -1775,55 +1760,49 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(4);
#endif
var texturePtrs = stackalloc IntPtr[4];
texturePtrs[0] = bindingOne.Texture.Handle;
texturePtrs[1] = bindingTwo.Texture.Handle;
texturePtrs[2] = bindingThree.Texture.Handle;
texturePtrs[3] = bindingFour.Texture.Handle;
var mipLevels = stackalloc uint[4];
mipLevels[0] = bindingOne.MipLevel;
mipLevels[1] = bindingTwo.MipLevel;
mipLevels[2] = bindingThree.MipLevel;
mipLevels[3] = bindingFour.MipLevel;
var textureSlicePtrs = stackalloc Refresh.TextureSlice[4];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice();
textureSlicePtrs[2] = sliceThree.ToRefreshTextureSlice();
textureSlicePtrs[3] = sliceFour.ToRefreshTextureSlice();
Refresh.Refresh_BindComputeTextures(
Device.Handle,
Handle,
(IntPtr) texturePtrs,
(IntPtr) mipLevels
(IntPtr) textureSlicePtrs
);
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="bindings">A set of texture-level pairs to bind.</param>
/// <param name="slices">A set of texture-level pairs to bind.</param>
public unsafe void BindComputeTextures(
in Span<TextureLevelBinding> bindings
in Span<TextureSlice> slices
) {
#if DEBUG
AssertNotSubmitted();
AssertInComputePass("Cannot bind compute textures outside of compute pass!");
AssertComputePipelineBound();
AssertComputeTextureCount(bindings.Length);
AssertComputeTextureCount(slices.Length);
#endif
var texturePtrs = stackalloc IntPtr[bindings.Length];
var mipLevels = stackalloc uint[bindings.Length];
Refresh.TextureSlice* textureSlicePtrs = (Refresh.TextureSlice*) NativeMemory.Alloc(
(nuint) (Marshal.SizeOf<Refresh.TextureSlice>() * slices.Length)
);
for (var i = 0; i < bindings.Length; i += 1)
for (var i = 0; i < slices.Length; i += 1)
{
texturePtrs[i] = bindings[i].Texture.Handle;
mipLevels[i] = bindings[i].MipLevel;
textureSlicePtrs[i] = slices[i].ToRefreshTextureSlice();
}
Refresh.Refresh_BindComputeTextures(
Device.Handle,
Handle,
(IntPtr) texturePtrs,
(IntPtr) mipLevels
(IntPtr) textureSlicePtrs
);
NativeMemory.Free(textureSlicePtrs);
}
/// <summary>
@ -1948,7 +1927,7 @@ namespace MoonWorks.Graphics
/// </summary>
public void UploadToTexture(
TransferBuffer transferBuffer,
in TextureSlice textureSlice,
in TextureRegion textureRegion,
in BufferImageCopy copyParams,
CopyOptions option
)
@ -1956,14 +1935,14 @@ namespace MoonWorks.Graphics
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot upload to texture outside of copy pass!");
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureSlice.Size);
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
#endif
Refresh.Refresh_UploadToTexture(
Device.Handle,
Handle,
transferBuffer.Handle,
textureSlice.ToRefreshTextureSlice(),
textureRegion.ToRefreshTextureRegion(),
copyParams.ToRefresh(),
(Refresh.CopyOptions) option
);
@ -1979,7 +1958,7 @@ namespace MoonWorks.Graphics
) {
UploadToTexture(
transferBuffer,
new TextureSlice(texture),
new TextureRegion(texture),
new BufferImageCopy(0, 0, 0),
option
);
@ -2070,7 +2049,7 @@ namespace MoonWorks.Graphics
/// fully copied until the command buffer has finished execution.
/// </summary>
public void DownloadFromTexture(
in TextureSlice textureSlice,
in TextureRegion textureRegion,
TransferBuffer transferBuffer,
in BufferImageCopy copyParams,
TransferOptions option
@ -2078,13 +2057,13 @@ namespace MoonWorks.Graphics
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot download from texture outside of copy pass!");
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureSlice.Size);
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
#endif
Refresh.Refresh_DownloadFromTexture(
Device.Handle,
Handle,
textureSlice.ToRefreshTextureSlice(),
textureRegion.ToRefreshTextureRegion(),
transferBuffer.Handle,
copyParams.ToRefresh(),
(Refresh.TransferOptions) option
@ -2100,7 +2079,7 @@ namespace MoonWorks.Graphics
TransferOptions option
) {
DownloadFromTexture(
new TextureSlice(texture),
new TextureRegion(texture),
transferBuffer,
new BufferImageCopy(0, 0, 0),
option
@ -2164,8 +2143,8 @@ namespace MoonWorks.Graphics
/// You MAY assume that the copy has finished in subsequent commands.
/// </summary>
public void CopyTextureToTexture(
in TextureSlice source,
in TextureSlice destination,
in TextureRegion source,
in TextureRegion destination,
CopyOptions option
) {
#if DEBUG
@ -2177,8 +2156,8 @@ namespace MoonWorks.Graphics
Refresh.Refresh_CopyTextureToTexture(
Device.Handle,
Handle,
source.ToRefreshTextureSlice(),
destination.ToRefreshTextureSlice(),
source.ToRefreshTextureRegion(),
destination.ToRefreshTextureRegion(),
(Refresh.CopyOptions) option
);
}
@ -2193,8 +2172,8 @@ namespace MoonWorks.Graphics
CopyOptions option
) {
CopyTextureToTexture(
new TextureSlice(source),
new TextureSlice(destination),
new TextureRegion(source),
new TextureRegion(destination),
option
);
}
@ -2206,7 +2185,7 @@ namespace MoonWorks.Graphics
/// You MAY assume that the copy has finished in subsequent commands.
/// </summary>
public void CopyTextureToBuffer(
in TextureSlice textureSlice,
in TextureRegion textureRegion,
GpuBuffer buffer,
in BufferImageCopy copyParams,
CopyOptions option
@ -2214,13 +2193,13 @@ namespace MoonWorks.Graphics
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot download from texture outside of copy pass!");
AssertBufferBoundsCheck(buffer.Size, copyParams.BufferOffset, textureSlice.Size);
AssertBufferBoundsCheck(buffer.Size, copyParams.BufferOffset, textureRegion.Size);
#endif
Refresh.Refresh_CopyTextureToBuffer(
Device.Handle,
Handle,
textureSlice.ToRefreshTextureSlice(),
textureRegion.ToRefreshTextureRegion(),
buffer.Handle,
copyParams.ToRefresh(),
(Refresh.CopyOptions) option
@ -2236,7 +2215,7 @@ namespace MoonWorks.Graphics
CopyOptions option
) {
CopyTextureToBuffer(
new TextureSlice(texture),
new TextureRegion(texture),
buffer,
new BufferImageCopy(0, 0, 0),
option
@ -2251,21 +2230,21 @@ namespace MoonWorks.Graphics
/// </summary>
public void CopyBufferToTexture(
GpuBuffer gpuBuffer,
in TextureSlice textureSlice,
in TextureRegion textureRegion,
in BufferImageCopy copyParams,
CopyOptions option
) {
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot download from texture outside of copy pass!");
AssertBufferBoundsCheck(gpuBuffer.Size, copyParams.BufferOffset, textureSlice.Size);
AssertBufferBoundsCheck(gpuBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
#endif
Refresh.Refresh_CopyBufferToTexture(
Device.Handle,
Handle,
gpuBuffer.Handle,
textureSlice.ToRefreshTextureSlice(),
textureRegion.ToRefreshTextureRegion(),
copyParams.ToRefresh(),
(Refresh.CopyOptions) option
);
@ -2281,7 +2260,7 @@ namespace MoonWorks.Graphics
) {
CopyBufferToTexture(
buffer,
new TextureSlice(texture),
new TextureRegion(texture),
new BufferImageCopy(0, 0, 0),
option
);
@ -2458,7 +2437,7 @@ namespace MoonWorks.Graphics
private void AssertTextureNotNull(ColorAttachmentInfo colorAttachmentInfo)
{
if (colorAttachmentInfo.Texture == null || colorAttachmentInfo.Texture.Handle == IntPtr.Zero)
if (colorAttachmentInfo.TextureSlice.Texture == null || colorAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
{
throw new System.ArgumentException("Render pass color attachment Texture cannot be null!");
}
@ -2466,7 +2445,7 @@ namespace MoonWorks.Graphics
private void AssertColorTarget(ColorAttachmentInfo colorAttachmentInfo)
{
if ((colorAttachmentInfo.Texture.UsageFlags & TextureUsageFlags.ColorTarget) == 0)
if ((colorAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.ColorTarget) == 0)
{
throw new System.ArgumentException("Render pass color attachment UsageFlags must include TextureUsageFlags.ColorTarget!");
}
@ -2482,13 +2461,13 @@ namespace MoonWorks.Graphics
private void AssertValidDepthAttachment(DepthStencilAttachmentInfo depthStencilAttachmentInfo)
{
if (depthStencilAttachmentInfo.Texture == null ||
depthStencilAttachmentInfo.Texture.Handle == IntPtr.Zero)
if (depthStencilAttachmentInfo.TextureSlice.Texture == null ||
depthStencilAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
{
throw new System.ArgumentException("Render pass depth stencil attachment Texture cannot be null!");
}
if ((depthStencilAttachmentInfo.Texture.UsageFlags & TextureUsageFlags.DepthStencilTarget) == 0)
if ((depthStencilAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.DepthStencilTarget) == 0)
{
throw new System.ArgumentException("Render pass depth stencil attachment UsageFlags must include TextureUsageFlags.DepthStencilTarget!");
}

View File

@ -174,40 +174,33 @@ namespace MoonWorks.Graphics
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ColorAttachmentInfo
{
public Texture Texture;
public uint Depth;
public uint Layer;
public uint Level;
public TextureSlice TextureSlice;
public Color ClearColor;
public LoadOp LoadOp;
public StoreOp StoreOp;
public bool SafeDiscard;
public ColorAttachmentInfo(
Texture texture,
TextureSlice textureSlice,
Color clearColor,
bool safeDiscard = true,
StoreOp storeOp = StoreOp.Store
) {
Texture = texture;
Depth = 0;
Layer = 0;
Level = 0;
TextureSlice = textureSlice;
ClearColor = clearColor;
LoadOp = LoadOp.Clear;
StoreOp = storeOp;
SafeDiscard = safeDiscard;
}
public ColorAttachmentInfo(
Texture texture,
TextureSlice textureSlice,
LoadOp loadOp = LoadOp.DontCare,
StoreOp storeOp = StoreOp.Store
) {
Texture = texture;
Depth = 0;
Layer = 0;
Level = 0;
TextureSlice = textureSlice;
ClearColor = Color.White;
LoadOp = loadOp;
StoreOp = storeOp;
@ -217,10 +210,7 @@ namespace MoonWorks.Graphics
{
return new Refresh.ColorAttachmentInfo
{
texture = Texture.Handle,
depth = Depth,
layer = Layer,
level = Level,
textureSlice = TextureSlice.ToRefreshTextureSlice(),
clearColor = new Refresh.Vec4
{
x = ClearColor.R / 255f,
@ -229,53 +219,46 @@ namespace MoonWorks.Graphics
w = ClearColor.A / 255f
},
loadOp = (Refresh.LoadOp) LoadOp,
storeOp = (Refresh.StoreOp) StoreOp
storeOp = (Refresh.StoreOp) StoreOp,
safeDiscard = Conversions.BoolToByte(SafeDiscard)
};
}
}
[StructLayout(LayoutKind.Sequential)]
public struct DepthStencilAttachmentInfo
{
public Texture Texture;
public uint Depth;
public uint Layer;
public uint Level;
public TextureSlice TextureSlice;
public DepthStencilValue DepthStencilClearValue;
public LoadOp LoadOp;
public StoreOp StoreOp;
public LoadOp StencilLoadOp;
public StoreOp StencilStoreOp;
public bool SafeDiscard;
public DepthStencilAttachmentInfo(
Texture texture,
TextureSlice textureSlice,
DepthStencilValue clearValue,
bool safeDiscard = true,
StoreOp depthStoreOp = StoreOp.Store,
StoreOp stencilStoreOp = StoreOp.Store
)
{
Texture = texture;
Depth = 0;
Layer = 0;
Level = 0;
){
TextureSlice = textureSlice;
DepthStencilClearValue = clearValue;
LoadOp = LoadOp.Clear;
StoreOp = depthStoreOp;
StencilLoadOp = LoadOp.Clear;
StencilStoreOp = stencilStoreOp;
SafeDiscard = safeDiscard;
}
public DepthStencilAttachmentInfo(
Texture texture,
TextureSlice textureSlice,
LoadOp loadOp = LoadOp.DontCare,
StoreOp storeOp = StoreOp.Store,
LoadOp stencilLoadOp = LoadOp.DontCare,
StoreOp stencilStoreOp = StoreOp.Store
) {
Texture = texture;
Depth = 0;
Layer = 0;
Level = 0;
TextureSlice = textureSlice;
DepthStencilClearValue = new DepthStencilValue();
LoadOp = loadOp;
StoreOp = storeOp;
@ -283,38 +266,17 @@ namespace MoonWorks.Graphics
StencilStoreOp = stencilStoreOp;
}
public DepthStencilAttachmentInfo(
Texture texture,
DepthStencilValue depthStencilValue,
LoadOp loadOp,
StoreOp storeOp,
LoadOp stencilLoadOp,
StoreOp stencilStoreOp
) {
Texture = texture;
Depth = 0;
Layer = 0;
Level = 0;
DepthStencilClearValue = depthStencilValue;
LoadOp = loadOp;
StoreOp = storeOp;
StencilLoadOp = stencilLoadOp;
StencilStoreOp = stencilStoreOp;
}
public Refresh.DepthStencilAttachmentInfo ToRefresh()
{
return new Refresh.DepthStencilAttachmentInfo
{
texture = Texture.Handle,
depth = Depth,
layer = Layer,
level = Level,
textureSlice = TextureSlice.ToRefreshTextureSlice(),
depthStencilClearValue = DepthStencilClearValue.ToRefresh(),
loadOp = (Refresh.LoadOp) LoadOp,
storeOp = (Refresh.StoreOp) StoreOp,
stencilLoadOp = (Refresh.LoadOp) StencilLoadOp,
stencilStoreOp = (Refresh.StoreOp) StencilStoreOp
stencilStoreOp = (Refresh.StoreOp) StencilStoreOp,
safeDiscard = Conversions.BoolToByte(SafeDiscard)
};
}
}

View File

@ -22,7 +22,7 @@ namespace MoonWorks.Graphics
uint dataSize = 1024;
List<(GpuBuffer, BufferCopy, CopyOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, CopyOptions)>();
List<(TextureSlice, uint, CopyOptions)> TextureUploads = new List<(TextureSlice, uint, CopyOptions)>();
List<(TextureRegion, uint, CopyOptions)> TextureUploads = new List<(TextureRegion, uint, CopyOptions)>();
public ResourceUploader(GraphicsDevice device) : base(device)
{
@ -142,12 +142,14 @@ namespace MoonWorks.Graphics
var byteSpan = new Span<byte>(byteBuffer, levelSize);
stream.ReadExactly(byteSpan);
var textureSlice = new TextureSlice
var textureRegion = new TextureRegion
{
TextureSlice = new TextureSlice
{
Texture = texture,
MipLevel = (uint) level,
BaseLayer = (uint) face,
LayerCount = 1,
Layer = (uint) face,
MipLevel = (uint) level
},
X = 0,
Y = 0,
Z = 0,
@ -156,7 +158,7 @@ namespace MoonWorks.Graphics
Depth = 1
};
SetTextureData(textureSlice, byteSpan, CopyOptions.SafeOverwrite);
SetTextureData(textureRegion, byteSpan, CopyOptions.SafeOverwrite);
NativeMemory.Free(byteBuffer);
}
@ -174,36 +176,36 @@ namespace MoonWorks.Graphics
return CreateTextureFromDDS(stream);
}
public void SetTextureDataFromCompressed(TextureSlice textureSlice, Span<byte> compressedImageData)
public void SetTextureDataFromCompressed(TextureRegion textureRegion, Span<byte> compressedImageData)
{
var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes);
var pixelSpan = new Span<byte>((void*) pixelData, (int) sizeInBytes);
SetTextureData(textureSlice, pixelSpan, CopyOptions.SafeOverwrite);
SetTextureData(textureRegion, pixelSpan, CopyOptions.SafeOverwrite);
ImageUtils.FreePixelData(pixelData);
}
public void SetTextureDataFromCompressed(TextureSlice textureSlice, Stream compressedImageStream)
public void SetTextureDataFromCompressed(TextureRegion textureRegion, Stream compressedImageStream)
{
var length = compressedImageStream.Length;
var buffer = NativeMemory.Alloc((nuint) length);
var span = new Span<byte>(buffer, (int) length);
compressedImageStream.ReadExactly(span);
SetTextureDataFromCompressed(textureSlice, span);
SetTextureDataFromCompressed(textureRegion, span);
NativeMemory.Free(buffer);
}
public void SetTextureDataFromCompressed(TextureSlice textureSlice, string compressedImageFilePath)
public void SetTextureDataFromCompressed(TextureRegion textureRegion, string compressedImageFilePath)
{
var fileStream = new FileStream(compressedImageFilePath, FileMode.Open, FileAccess.Read);
SetTextureDataFromCompressed(textureSlice, fileStream);
SetTextureDataFromCompressed(textureRegion, fileStream);
}
/// <summary>
/// Prepares upload of pixel data into a TextureSlice.
/// </summary>
public void SetTextureData<T>(TextureSlice textureSlice, Span<T> data, CopyOptions option) where T : unmanaged
public void SetTextureData<T>(TextureRegion textureRegion, Span<T> data, CopyOptions option) where T : unmanaged
{
var elementSize = Marshal.SizeOf<T>();
var dataLengthInBytes = (uint) (elementSize * data.Length);
@ -211,10 +213,10 @@ namespace MoonWorks.Graphics
uint resourceOffset;
fixed (T* dataPtr = data)
{
resourceOffset = CopyDataAligned(dataPtr, dataLengthInBytes, Texture.TexelSize(textureSlice.Texture.Format));
resourceOffset = CopyDataAligned(dataPtr, dataLengthInBytes, Texture.TexelSize(textureRegion.TextureSlice.Texture.Format));
}
TextureUploads.Add((textureSlice, resourceOffset, option));
TextureUploads.Add((textureRegion, resourceOffset, option));
}
// Upload
@ -274,11 +276,11 @@ namespace MoonWorks.Graphics
);
}
foreach (var (textureSlice, offset, option) in TextureUploads)
foreach (var (textureRegion, offset, option) in TextureUploads)
{
commandBuffer.UploadToTexture(
TransferBuffer,
textureSlice,
textureRegion,
new BufferImageCopy(
offset,
0,

View File

@ -14,6 +14,7 @@ namespace MoonWorks.Graphics
public uint Depth { get; }
public TextureFormat Format { get; internal set; }
public bool IsCube { get; }
public uint LayerCount { get; }
public uint LevelCount { get; }
public SampleCount SampleCount { get; }
public TextureUsageFlags UsageFlags { get; }
@ -46,6 +47,7 @@ namespace MoonWorks.Graphics
Height = height,
Depth = 1,
IsCube = false,
LayerCount = 1,
LevelCount = levelCount,
SampleCount = sampleCount,
Format = format,
@ -56,15 +58,43 @@ namespace MoonWorks.Graphics
}
/// <summary>
/// Creates a 3D texture.
/// Creates a 2D texture array.
/// </summary>
/// <param name="device">An initialized GraphicsDevice.</param>
/// <param name="width">The width of the texture.</param>
/// <param name="height">The height of the texture.</param>
/// <param name="depth">The depth of the texture.</param>
/// <param name="layerCount">The layer count of the texture.</param>
/// <param name="format">The format of the texture.</param>
/// <param name="usageFlags">Specifies how the texture will be used.</param>
/// <param name="levelCount">Specifies the number of mip levels.</param>
public static Texture CreateTexture2DArray(
GraphicsDevice device,
uint width,
uint height,
uint layerCount,
TextureFormat format,
TextureUsageFlags usageFlags,
uint levelCount = 1
) {
var textureCreateInfo = new TextureCreateInfo
{
Width = width,
Height = height,
Depth = 1,
IsCube = false,
LayerCount = layerCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, textureCreateInfo);
}
/// <summary>
/// Creates a 3D texture.
/// Note that the width, height and depth all form one slice and cannot be subdivided in a texture slice.
/// </summary>
public static Texture CreateTexture3D(
GraphicsDevice device,
uint width,
@ -80,6 +110,7 @@ namespace MoonWorks.Graphics
Height = height,
Depth = depth,
IsCube = false,
LayerCount = 1,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
@ -109,6 +140,7 @@ namespace MoonWorks.Graphics
Height = size,
Depth = 1,
IsCube = true,
LayerCount = 6,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
@ -137,14 +169,13 @@ namespace MoonWorks.Graphics
Height = textureCreateInfo.Height;
Depth = textureCreateInfo.Depth;
IsCube = textureCreateInfo.IsCube;
LayerCount = textureCreateInfo.LayerCount;
LevelCount = textureCreateInfo.LevelCount;
SampleCount = textureCreateInfo.SampleCount;
UsageFlags = textureCreateInfo.UsageFlags;
Size = Width * Height * BytesPerPixel(Format) / BlockSizeSquared(Format);
}
public static implicit operator TextureSlice(Texture t) => new TextureSlice(t);
// Used by AcquireSwapchainTexture.
// Should not be tracked, because swapchain textures are managed by Vulkan.
internal Texture(
@ -270,5 +301,8 @@ namespace MoonWorks.Graphics
return 0;
}
}
public static implicit operator TextureSlice(Texture t) => new TextureSlice(t);
public static implicit operator TextureRegion(Texture t) => new TextureRegion(t);
}
}

View File

@ -11,6 +11,7 @@ namespace MoonWorks.Graphics
public uint Height;
public uint Depth;
public bool IsCube;
public uint LayerCount;
public uint LevelCount;
public SampleCount SampleCount;
public TextureFormat Format;
@ -24,6 +25,7 @@ namespace MoonWorks.Graphics
height = Height,
depth = Depth,
isCube = Conversions.BoolToByte(IsCube),
layerCount = LayerCount,
levelCount = LevelCount,
sampleCount = (Refresh.SampleCount) SampleCount,
format = (Refresh.TextureFormat) Format,

View File

@ -0,0 +1,46 @@
using RefreshCS;
namespace MoonWorks.Graphics
{
/// <summary>
/// A texture region specifies a subregion of a texture.
/// These are used by copy commands.
/// </summary>
public struct TextureRegion
{
public TextureSlice TextureSlice;
public uint X;
public uint Y;
public uint Z;
public uint Width;
public uint Height;
public uint Depth;
public uint Size => (Width * Height * Depth * Texture.BytesPerPixel(TextureSlice.Texture.Format) / Texture.BlockSizeSquared(TextureSlice.Texture.Format)) >> (int) TextureSlice.MipLevel;
public TextureRegion(Texture texture)
{
TextureSlice = new TextureSlice(texture);
X = 0;
Y = 0;
Z = 0;
Width = texture.Width;
Height = texture.Height;
Depth = texture.Depth;
}
public Refresh.TextureRegion ToRefreshTextureRegion()
{
return new Refresh.TextureRegion
{
textureSlice = TextureSlice.ToRefreshTextureSlice(),
x = X,
y = Y,
z = Z,
w = Width,
h = Height,
d = Depth
};
}
}
}

View File

@ -3,55 +3,31 @@
namespace MoonWorks.Graphics
{
/// <summary>
/// A texture slice specifies a subregion of a texture.
/// Many operations can use texture slices in place of textures for the sake of convenience.
/// A texture slice specifies a subresource of a texture.
/// </summary>
public struct TextureSlice
{
public Texture Texture;
public uint MipLevel;
public uint BaseLayer;
public uint LayerCount;
public uint X;
public uint Y;
public uint Z;
public uint Width;
public uint Height;
public uint Depth;
public uint Layer;
public uint Size => (Width * Height * Depth * LayerCount * Texture.BytesPerPixel(Texture.Format) / Texture.BlockSizeSquared(Texture.Format)) >> (int) MipLevel;
public uint Size => (Texture.Width * Texture.Height * Texture.Depth * Texture.BytesPerPixel(Texture.Format) / Texture.BlockSizeSquared(Texture.Format)) >> (int) MipLevel;
public TextureSlice(Texture texture)
{
Texture = texture;
MipLevel = 0;
BaseLayer = 0;
LayerCount = (uint) (texture.IsCube ? 6 : 1);
X = 0;
Y = 0;
Z = 0;
Width = texture.Width;
Height = texture.Height;
Depth = texture.Depth;
Layer = 0;
}
public Refresh.TextureSlice ToRefreshTextureSlice()
{
Refresh.TextureSlice textureSlice = new Refresh.TextureSlice
return new Refresh.TextureSlice
{
texture = Texture.Handle,
mipLevel = MipLevel,
baseLayer = BaseLayer,
layerCount = LayerCount,
x = X,
y = Y,
z = Z,
w = Width,
h = Height,
d = Depth
layer = Layer
};
return textureSlice;
}
}
}

View File

@ -287,7 +287,7 @@ namespace MoonWorks.Video
commandBuffer.EndCopyPass();
commandBuffer.BeginRenderPass(
new ColorAttachmentInfo(RenderTexture, Color.Black)
new ColorAttachmentInfo(RenderTexture, Color.Black, true)
);
commandBuffer.BindGraphicsPipeline(Device.VideoPipeline);