implement compressed/uncompressed copy, fix other copies, fix int/uint output shaders (#33)
This commit is contained in:
parent
9d866ff282
commit
d22feff1d2
3 changed files with 81 additions and 26 deletions
|
@ -189,10 +189,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
dstImage,
|
dstImage,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
0,//src.FirstLayer,
|
|
||||||
0,//dst.FirstLayer,
|
|
||||||
0,//src.FirstLevel,
|
|
||||||
0,//dst.FirstLevel,
|
|
||||||
0,
|
0,
|
||||||
firstLayer,
|
firstLayer,
|
||||||
0,
|
0,
|
||||||
|
@ -234,10 +230,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
dstImage,
|
dstImage,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
0, //src.FirstLayer,
|
|
||||||
0, //dst.FirstLayer,
|
|
||||||
0, //src.FirstLevel,
|
|
||||||
0, //dst.FirstLevel,
|
|
||||||
srcLayer,
|
srcLayer,
|
||||||
dstLayer,
|
dstLayer,
|
||||||
srcLevel,
|
srcLevel,
|
||||||
|
|
|
@ -10,16 +10,61 @@ namespace Ryujinx.Graphics.Metal
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
static class TextureCopy
|
static class TextureCopy
|
||||||
{
|
{
|
||||||
|
public static ulong CopyFromOrToBuffer(
|
||||||
|
CommandBufferScoped cbs,
|
||||||
|
MTLBuffer buffer,
|
||||||
|
MTLTexture image,
|
||||||
|
TextureCreateInfo info,
|
||||||
|
bool to,
|
||||||
|
int dstLayer,
|
||||||
|
int dstLevel,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ulong offset = 0)
|
||||||
|
{
|
||||||
|
MTLBlitCommandEncoder blitCommandEncoder = cbs.Encoders.EnsureBlitEncoder();
|
||||||
|
|
||||||
|
bool is3D = info.Target == Target.Texture3D;
|
||||||
|
|
||||||
|
int blockWidth = BitUtils.DivRoundUp(width, info.BlockWidth);
|
||||||
|
int blockHeight = BitUtils.DivRoundUp(height, info.BlockHeight);
|
||||||
|
ulong bytesPerRow = (ulong)BitUtils.AlignUp(blockWidth * info.BytesPerPixel, 4);
|
||||||
|
ulong bytesPerImage = bytesPerRow * (ulong)blockHeight;
|
||||||
|
|
||||||
|
MTLOrigin origin = new MTLOrigin { x = (ulong)x, y = (ulong)y, z = is3D ? (ulong)dstLayer : 0 };
|
||||||
|
MTLSize region = new MTLSize { width = (ulong)width, height = (ulong)height, depth = 1 };
|
||||||
|
|
||||||
|
uint layer = is3D ? 0 : (uint)dstLayer;
|
||||||
|
|
||||||
|
if (to)
|
||||||
|
{
|
||||||
|
blitCommandEncoder.CopyFromTexture(
|
||||||
|
image,
|
||||||
|
layer,
|
||||||
|
(ulong)dstLevel,
|
||||||
|
origin,
|
||||||
|
region,
|
||||||
|
buffer,
|
||||||
|
offset,
|
||||||
|
bytesPerRow,
|
||||||
|
bytesPerImage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blitCommandEncoder.CopyFromBuffer(buffer, offset, bytesPerRow, bytesPerImage, region, image, layer, (ulong)dstLevel, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset + bytesPerImage;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Copy(
|
public static void Copy(
|
||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
MTLTexture srcImage,
|
MTLTexture srcImage,
|
||||||
MTLTexture dstImage,
|
MTLTexture dstImage,
|
||||||
TextureCreateInfo srcInfo,
|
TextureCreateInfo srcInfo,
|
||||||
TextureCreateInfo dstInfo,
|
TextureCreateInfo dstInfo,
|
||||||
int srcViewLayer,
|
|
||||||
int dstViewLayer,
|
|
||||||
int srcViewLevel,
|
|
||||||
int dstViewLevel,
|
|
||||||
int srcLayer,
|
int srcLayer,
|
||||||
int dstLayer,
|
int dstLayer,
|
||||||
int srcLevel,
|
int srcLevel,
|
||||||
|
@ -45,10 +90,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
dstImage,
|
dstImage,
|
||||||
srcInfo,
|
srcInfo,
|
||||||
dstInfo,
|
dstInfo,
|
||||||
srcViewLayer,
|
|
||||||
dstViewLayer,
|
|
||||||
srcViewLevel,
|
|
||||||
dstViewLevel,
|
|
||||||
srcLayer,
|
srcLayer,
|
||||||
dstLayer,
|
dstLayer,
|
||||||
srcLevel,
|
srcLevel,
|
||||||
|
@ -63,10 +104,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
MTLTexture dstImage,
|
MTLTexture dstImage,
|
||||||
TextureCreateInfo srcInfo,
|
TextureCreateInfo srcInfo,
|
||||||
TextureCreateInfo dstInfo,
|
TextureCreateInfo dstInfo,
|
||||||
int srcViewLayer,
|
|
||||||
int dstViewLayer,
|
|
||||||
int srcViewLevel,
|
|
||||||
int dstViewLevel,
|
|
||||||
int srcDepthOrLayer,
|
int srcDepthOrLayer,
|
||||||
int dstDepthOrLayer,
|
int dstDepthOrLayer,
|
||||||
int srcLevel,
|
int srcLevel,
|
||||||
|
@ -129,6 +166,17 @@ namespace Ryujinx.Graphics.Metal
|
||||||
int blockHeight = 1;
|
int blockHeight = 1;
|
||||||
bool sizeInBlocks = false;
|
bool sizeInBlocks = false;
|
||||||
|
|
||||||
|
MTLBuffer tempBuffer = default;
|
||||||
|
|
||||||
|
if (srcInfo.Format != dstInfo.Format && (srcInfo.IsCompressed || dstInfo.IsCompressed))
|
||||||
|
{
|
||||||
|
// Compressed alias copies need to happen through a temporary buffer.
|
||||||
|
// The data is copied from the source to the buffer, then the buffer to the destination.
|
||||||
|
// The length of the buffer should be the maximum slice size for the destination.
|
||||||
|
|
||||||
|
tempBuffer = blitCommandEncoder.Device.NewBuffer((ulong)dstInfo.GetMipSize2D(0), MTLResourceOptions.ResourceStorageModePrivate);
|
||||||
|
}
|
||||||
|
|
||||||
// When copying from a compressed to a non-compressed format,
|
// When copying from a compressed to a non-compressed format,
|
||||||
// the non-compressed texture will have the size of the texture
|
// the non-compressed texture will have the size of the texture
|
||||||
// in blocks (not in texels), so we must adjust that size to
|
// in blocks (not in texels), so we must adjust that size to
|
||||||
|
@ -168,7 +216,17 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
for (int layer = 0; layer < layers; layer++)
|
for (int layer = 0; layer < layers; layer++)
|
||||||
{
|
{
|
||||||
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
if (tempBuffer.NativePtr != 0)
|
||||||
|
{
|
||||||
|
// Copy through the temp buffer
|
||||||
|
CopyFromOrToBuffer(cbs, tempBuffer, srcImage, srcInfo, true, srcLayer + layer, srcLevel + level, 0, 0, copyWidth, copyHeight);
|
||||||
|
|
||||||
|
int dstBufferWidth = sizeInBlocks ? copyWidth * blockWidth : BitUtils.DivRoundUp(copyWidth, blockWidth);
|
||||||
|
int dstBufferHeight = sizeInBlocks ? copyHeight * blockHeight : BitUtils.DivRoundUp(copyHeight, blockHeight);
|
||||||
|
|
||||||
|
CopyFromOrToBuffer(cbs, tempBuffer, dstImage, dstInfo, false, dstLayer + layer, dstLevel + level, 0, 0, dstBufferWidth, dstBufferHeight);
|
||||||
|
}
|
||||||
|
else if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
|
@ -178,13 +236,13 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
blitCommandEncoder.CopyFromTexture(
|
blitCommandEncoder.CopyFromTexture(
|
||||||
srcImage,
|
srcImage,
|
||||||
(ulong)(srcViewLevel + srcLevel + level),
|
(ulong)(srcLayer + layer),
|
||||||
(ulong)(srcViewLayer + srcLayer + layer),
|
(ulong)(srcLevel + level),
|
||||||
new MTLOrigin { z = (ulong)srcZ },
|
new MTLOrigin { z = (ulong)srcZ },
|
||||||
new MTLSize { width = (ulong)copyWidth, height = (ulong)copyHeight, depth = (ulong)srcDepth },
|
new MTLSize { width = (ulong)copyWidth, height = (ulong)copyHeight, depth = (ulong)srcDepth },
|
||||||
dstImage,
|
dstImage,
|
||||||
(ulong)(dstViewLevel + dstLevel + level),
|
(ulong)(dstLayer + layer),
|
||||||
(ulong)(dstViewLayer + dstLayer + layer),
|
(ulong)(dstLevel + level),
|
||||||
new MTLOrigin { z = (ulong)dstZ });
|
new MTLOrigin { z = (ulong)dstZ });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,6 +255,11 @@ namespace Ryujinx.Graphics.Metal
|
||||||
srcDepth = Math.Max(1, srcDepth >> 1);
|
srcDepth = Math.Max(1, srcDepth >> 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tempBuffer.NativePtr != 0)
|
||||||
|
{
|
||||||
|
tempBuffer.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||||
IoVariable.BaseVertex => ("base_vertex", AggregateType.U32),
|
IoVariable.BaseVertex => ("base_vertex", AggregateType.U32),
|
||||||
IoVariable.CtaId => ("threadgroup_position_in_grid", AggregateType.Vector3 | AggregateType.U32),
|
IoVariable.CtaId => ("threadgroup_position_in_grid", AggregateType.Vector3 | AggregateType.U32),
|
||||||
IoVariable.ClipDistance => ("clip_distance", AggregateType.Array | AggregateType.FP32),
|
IoVariable.ClipDistance => ("clip_distance", AggregateType.Array | AggregateType.FP32),
|
||||||
IoVariable.FragmentOutputColor => ($"out.color{location}", AggregateType.Vector4 | AggregateType.FP32),
|
IoVariable.FragmentOutputColor => ($"out.color{location}", definitions.GetFragmentOutputColorType(location)),
|
||||||
IoVariable.FragmentOutputDepth => ("out.depth", AggregateType.FP32),
|
IoVariable.FragmentOutputDepth => ("out.depth", AggregateType.FP32),
|
||||||
IoVariable.FrontFacing => ("in.front_facing", AggregateType.Bool),
|
IoVariable.FrontFacing => ("in.front_facing", AggregateType.Bool),
|
||||||
IoVariable.GlobalId => ("thread_position_in_grid", AggregateType.Vector3 | AggregateType.U32),
|
IoVariable.GlobalId => ("thread_position_in_grid", AggregateType.Vector3 | AggregateType.U32),
|
||||||
|
|
Loading…
Reference in a new issue