mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-01 15:39:47 +08:00
fix(gpu): decode Gen5 R16 and RG32 render-target formats
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -218,6 +218,13 @@ internal static class MetalGuestFormats
|
|||||||
{
|
{
|
||||||
var format = (dataFormat, numberType) switch
|
var format = (dataFormat, numberType) switch
|
||||||
{
|
{
|
||||||
|
// Early G-buffer / scene targets (R16 + RG32). Keep in sync with
|
||||||
|
// VulkanVideoPresenter.TryDecodeRenderTargetFormat.
|
||||||
|
(2, 0) => MtlPixelFormat.R16Unorm,
|
||||||
|
(2, 1) => MtlPixelFormat.R16Snorm,
|
||||||
|
(2, 4) => MtlPixelFormat.R16Uint,
|
||||||
|
(2, 5) => MtlPixelFormat.R16Sint,
|
||||||
|
(2, 7) => MtlPixelFormat.R16Float,
|
||||||
(4, 4) => MtlPixelFormat.R32Uint,
|
(4, 4) => MtlPixelFormat.R32Uint,
|
||||||
(4, 5) => MtlPixelFormat.R32Sint,
|
(4, 5) => MtlPixelFormat.R32Sint,
|
||||||
(4, 7) => MtlPixelFormat.R32Float,
|
(4, 7) => MtlPixelFormat.R32Float,
|
||||||
@@ -230,6 +237,8 @@ internal static class MetalGuestFormats
|
|||||||
(10, 5) => MtlPixelFormat.Rgba8Sint,
|
(10, 5) => MtlPixelFormat.Rgba8Sint,
|
||||||
(10, 9) => MtlPixelFormat.Rgba8UnormSrgb,
|
(10, 9) => MtlPixelFormat.Rgba8UnormSrgb,
|
||||||
(10, _) => MtlPixelFormat.Rgba8Unorm,
|
(10, _) => MtlPixelFormat.Rgba8Unorm,
|
||||||
|
(11, 4) => MtlPixelFormat.Rg32Uint,
|
||||||
|
(11, 5) => MtlPixelFormat.Rg32Sint,
|
||||||
(11, 7) => MtlPixelFormat.Rg32Float,
|
(11, 7) => MtlPixelFormat.Rg32Float,
|
||||||
(12, 4) => MtlPixelFormat.Rgba16Uint,
|
(12, 4) => MtlPixelFormat.Rgba16Uint,
|
||||||
(12, 5) => MtlPixelFormat.Rgba16Sint,
|
(12, 5) => MtlPixelFormat.Rgba16Sint,
|
||||||
@@ -258,10 +267,12 @@ internal static class MetalGuestFormats
|
|||||||
|
|
||||||
var outputKind = format switch
|
var outputKind = format switch
|
||||||
{
|
{
|
||||||
MtlPixelFormat.R8Uint or MtlPixelFormat.R32Uint or MtlPixelFormat.Rg16Uint or
|
MtlPixelFormat.R8Uint or MtlPixelFormat.R16Uint or MtlPixelFormat.R32Uint or
|
||||||
MtlPixelFormat.Rgba8Uint or MtlPixelFormat.Rgba16Uint => Gen5PixelOutputKind.Uint,
|
MtlPixelFormat.Rg16Uint or MtlPixelFormat.Rg32Uint or MtlPixelFormat.Rgba8Uint or
|
||||||
MtlPixelFormat.R32Sint or MtlPixelFormat.Rg16Sint or MtlPixelFormat.Rgba8Sint or
|
MtlPixelFormat.Rgba16Uint => Gen5PixelOutputKind.Uint,
|
||||||
MtlPixelFormat.Rgba16Sint => Gen5PixelOutputKind.Sint,
|
MtlPixelFormat.R16Sint or MtlPixelFormat.R32Sint or MtlPixelFormat.Rg16Sint or
|
||||||
|
MtlPixelFormat.Rg32Sint or MtlPixelFormat.Rgba8Sint or MtlPixelFormat.Rgba16Sint =>
|
||||||
|
Gen5PixelOutputKind.Sint,
|
||||||
_ => Gen5PixelOutputKind.Float,
|
_ => Gen5PixelOutputKind.Float,
|
||||||
};
|
};
|
||||||
result = new MetalRenderTargetFormat(format, outputKind);
|
result = new MetalRenderTargetFormat(format, outputKind);
|
||||||
|
|||||||
@@ -2025,6 +2025,15 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
{
|
{
|
||||||
var format = (dataFormat, numberType) switch
|
var format = (dataFormat, numberType) switch
|
||||||
{
|
{
|
||||||
|
// Early G-buffer / scene targets (R16 + RG32). GTA V Enhanced hits
|
||||||
|
// these as color targets; texture decode already knew them.
|
||||||
|
(2, 0) => Format.R16Unorm,
|
||||||
|
(2, 1) => Format.R16SNorm,
|
||||||
|
(2, 2) => Format.R16Uscaled,
|
||||||
|
(2, 3) => Format.R16Sscaled,
|
||||||
|
(2, 4) => Format.R16Uint,
|
||||||
|
(2, 5) => Format.R16Sint,
|
||||||
|
(2, 7) => Format.R16Sfloat,
|
||||||
(4, 4) => Format.R32Uint,
|
(4, 4) => Format.R32Uint,
|
||||||
(4, 5) => Format.R32Sint,
|
(4, 5) => Format.R32Sint,
|
||||||
(4, 7) => Format.R32Sfloat,
|
(4, 7) => Format.R32Sfloat,
|
||||||
@@ -2037,6 +2046,8 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
(10, 5) => Format.R8G8B8A8Sint,
|
(10, 5) => Format.R8G8B8A8Sint,
|
||||||
(10, 9) => Format.R8G8B8A8Srgb,
|
(10, 9) => Format.R8G8B8A8Srgb,
|
||||||
(10, _) => Format.R8G8B8A8Unorm,
|
(10, _) => Format.R8G8B8A8Unorm,
|
||||||
|
(11, 4) => Format.R32G32Uint,
|
||||||
|
(11, 5) => Format.R32G32Sint,
|
||||||
(11, 7) => Format.R32G32Sfloat,
|
(11, 7) => Format.R32G32Sfloat,
|
||||||
(12, 4) => Format.R16G16B16A16Uint,
|
(12, 4) => Format.R16G16B16A16Uint,
|
||||||
(12, 5) => Format.R16G16B16A16Sint,
|
(12, 5) => Format.R16G16B16A16Sint,
|
||||||
@@ -2065,10 +2076,11 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
|
|
||||||
var outputKind = format switch
|
var outputKind = format switch
|
||||||
{
|
{
|
||||||
Format.R8Uint or Format.R32Uint or Format.R16G16Uint or
|
Format.R8Uint or Format.R16Uint or Format.R32Uint or Format.R16G16Uint or
|
||||||
Format.R8G8B8A8Uint or Format.R16G16B16A16Uint => Gen5PixelOutputKind.Uint,
|
Format.R32G32Uint or Format.R8G8B8A8Uint or Format.R16G16B16A16Uint =>
|
||||||
Format.R32Sint or Format.R16G16Sint or Format.R8G8B8A8Sint or
|
Gen5PixelOutputKind.Uint,
|
||||||
Format.R16G16B16A16Sint => Gen5PixelOutputKind.Sint,
|
Format.R16Sint or Format.R32Sint or Format.R16G16Sint or Format.R32G32Sint or
|
||||||
|
Format.R8G8B8A8Sint or Format.R16G16B16A16Sint => Gen5PixelOutputKind.Sint,
|
||||||
_ => Gen5PixelOutputKind.Float,
|
_ => Gen5PixelOutputKind.Float,
|
||||||
};
|
};
|
||||||
result = new VulkanRenderTargetFormat(format, outputKind);
|
result = new VulkanRenderTargetFormat(format, outputKind);
|
||||||
|
|||||||
@@ -56,4 +56,26 @@ public sealed class VulkanPresentEncodeFormatTests
|
|||||||
{
|
{
|
||||||
Assert.False(VulkanVideoPresenter.IsLinearFloatPresentSource(sourceFormat));
|
Assert.False(VulkanVideoPresenter.IsLinearFloatPresentSource(sourceFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GTA V Enhanced early G-buffer color targets observed as COMPAT failures
|
||||||
|
// when missing from TryDecodeRenderTargetFormat (format=2 / format=11).
|
||||||
|
[Theory]
|
||||||
|
[InlineData(2u, 0u, Format.R16Unorm)]
|
||||||
|
[InlineData(2u, 4u, Format.R16Uint)]
|
||||||
|
[InlineData(2u, 7u, Format.R16Sfloat)]
|
||||||
|
[InlineData(11u, 4u, Format.R32G32Uint)]
|
||||||
|
[InlineData(11u, 5u, Format.R32G32Sint)]
|
||||||
|
[InlineData(11u, 7u, Format.R32G32Sfloat)]
|
||||||
|
public void TryDecodeRenderTargetFormat_DecodesGen5R16AndRg32(
|
||||||
|
uint dataFormat,
|
||||||
|
uint numberType,
|
||||||
|
Format expected)
|
||||||
|
{
|
||||||
|
Assert.True(
|
||||||
|
VulkanVideoPresenter.TryDecodeRenderTargetFormat(
|
||||||
|
dataFormat,
|
||||||
|
numberType,
|
||||||
|
out var decoded));
|
||||||
|
Assert.Equal(expected, decoded.Format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user