mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-30 22:49:53 +08:00
fix(gpu): support Gen5 flat memory and 3D images (#587)
Vector-mesh UI text samples type-10 volume LUTs; treat MIMG DIM=2 as Dim3D and transport depth through AGC and Vulkan so Z slices no longer collapse into a single 2D plane.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using SharpEmu.Libs.Agc;
|
||||
using SharpEmu.Libs.Gpu;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Agc;
|
||||
|
||||
public sealed class AgcTextureTransportTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(10u, 4u, 4u)]
|
||||
[InlineData(10u, 0u, 1u)]
|
||||
[InlineData(9u, 4u, 1u)]
|
||||
[InlineData(13u, 4u, 1u)]
|
||||
public void GetTextureVolumeDepth_OnlyUsesDescriptorDepthFor3D(
|
||||
uint type,
|
||||
uint descriptorDepth,
|
||||
uint expectedDepth)
|
||||
{
|
||||
Assert.Equal(
|
||||
expectedDepth,
|
||||
AgcExports.GetTextureVolumeDepth(type, descriptorDepth));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTextureByteCount_MultipliesUncompressedVolumeDepth()
|
||||
{
|
||||
Assert.Equal(
|
||||
4UL * 8 * 6 * 5,
|
||||
AgcExports.GetTextureByteCount(
|
||||
format: 10,
|
||||
width: 8,
|
||||
height: 6,
|
||||
depth: 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTextureByteCount_MultipliesBlockCompressedVolumeDepth()
|
||||
{
|
||||
// Format 169 uses one eight-byte BC block for each 4x4 texel block.
|
||||
Assert.Equal(
|
||||
2UL * 2 * 8 * 3,
|
||||
AgcExports.GetTextureByteCount(
|
||||
format: 169,
|
||||
width: 7,
|
||||
height: 5,
|
||||
depth: 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTextureByteCount_LeavesTwoDimensionalSizingUnchanged()
|
||||
{
|
||||
Assert.Equal(
|
||||
AgcExports.GetTextureByteCount(10, 8, 6),
|
||||
AgcExports.GetTextureByteCount(10, 8, 6, depth: 1));
|
||||
Assert.Equal(
|
||||
AgcExports.GetTextureByteCount(10, 8, 6),
|
||||
AgcExports.GetTextureByteCount(10, 8, 6, depth: 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GuestDrawTexture_CarriesRawTypeAndNormalizedDepth()
|
||||
{
|
||||
var texture = new GuestDrawTexture(
|
||||
Address: 0x1234,
|
||||
Width: 8,
|
||||
Height: 6,
|
||||
Format: 10,
|
||||
NumberType: 0,
|
||||
RgbaPixels: [],
|
||||
IsFallback: false,
|
||||
IsStorage: false,
|
||||
Type: 10,
|
||||
Depth: 5);
|
||||
|
||||
Assert.Equal(10u, texture.Type);
|
||||
Assert.Equal(5u, texture.Depth);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TextureContentIdentity_DistinguishesTypeAndDepth()
|
||||
{
|
||||
var twoDimensional = CreateIdentity(type: 9, depth: 1);
|
||||
var threeDimensional = CreateIdentity(type: 10, depth: 1);
|
||||
var deeperThreeDimensional = CreateIdentity(type: 10, depth: 5);
|
||||
|
||||
Assert.NotEqual(twoDimensional, threeDimensional);
|
||||
Assert.NotEqual(threeDimensional, deeperThreeDimensional);
|
||||
}
|
||||
|
||||
private static TextureContentIdentity CreateIdentity(uint type, uint depth) =>
|
||||
new(
|
||||
Address: 0x1234,
|
||||
Width: 8,
|
||||
Height: 6,
|
||||
Format: 10,
|
||||
NumberType: 0,
|
||||
DstSelect: 0xFAC,
|
||||
TileMode: 0,
|
||||
Pitch: 8,
|
||||
Sampler: default,
|
||||
Type: type,
|
||||
Depth: depth);
|
||||
}
|
||||
@@ -36,4 +36,23 @@ public sealed class VulkanGuestImageByteCountTests
|
||||
expected,
|
||||
VulkanVideoPresenter.GetGuestImageByteCount(format, width, height));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(10u, 8u, 4u, 3u, 384UL)]
|
||||
[InlineData(169u, 5u, 5u, 7u, 224UL)]
|
||||
public void MultipliesSurfaceSizeByVolumeDepth(
|
||||
uint format,
|
||||
uint width,
|
||||
uint height,
|
||||
uint depth,
|
||||
ulong expected)
|
||||
{
|
||||
Assert.Equal(
|
||||
expected,
|
||||
VulkanVideoPresenter.GetGuestImageByteCount(
|
||||
format,
|
||||
width,
|
||||
height,
|
||||
depth));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using Silk.NET.Vulkan;
|
||||
using SharpEmu.Libs.VideoOut;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.VideoOut;
|
||||
|
||||
public sealed class VulkanGuestImageTypeTests
|
||||
{
|
||||
[Fact]
|
||||
public void ThreeDimensionalDescriptorsMapToVolumeImageAndViewTypes()
|
||||
{
|
||||
Assert.Equal(
|
||||
ImageType.Type3D,
|
||||
VulkanVideoPresenter.GetGuestTextureImageType(
|
||||
VulkanVideoPresenter.Gen5TextureType3D));
|
||||
Assert.Equal(
|
||||
ImageViewType.Type3D,
|
||||
VulkanVideoPresenter.GetGuestTextureViewType(
|
||||
VulkanVideoPresenter.Gen5TextureType3D,
|
||||
arrayedView: true));
|
||||
Assert.Equal(
|
||||
7u,
|
||||
VulkanVideoPresenter.GetGuestTextureDepth(
|
||||
VulkanVideoPresenter.Gen5TextureType3D,
|
||||
7));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoDimensionalArraysKeepLayersSeparateFromImageDepth()
|
||||
{
|
||||
Assert.Equal(
|
||||
ImageType.Type2D,
|
||||
VulkanVideoPresenter.GetGuestTextureImageType(
|
||||
VulkanVideoPresenter.Gen5TextureType2D));
|
||||
Assert.Equal(
|
||||
ImageViewType.Type2DArray,
|
||||
VulkanVideoPresenter.GetGuestTextureViewType(
|
||||
VulkanVideoPresenter.Gen5TextureType2D,
|
||||
arrayedView: true));
|
||||
Assert.Equal(
|
||||
1u,
|
||||
VulkanVideoPresenter.GetGuestTextureDepth(
|
||||
VulkanVideoPresenter.Gen5TextureType2D,
|
||||
7));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user