Vulkan: Add workarounds for MoltenVK (#4202)

* Add MVK basics.

* Use appropriate output attribute types

* 4kb vertex alignment, bunch of fixes

* Add reduced shader precision mode for mvk.

* Disable ASTC on MVK for now

* Only request robustnes2 when it is available.

* It's just the one feature actually

* Add triangle fan conversion

* Allow NullDescriptor on MVK for some reason.

* Force safe blit on MoltenVK

* Use ASTC only when formats are all available.

* Disable multilevel 3d texture views

* Filter duplicate render targets (on backend)

* Add Automatic MoltenVK Configuration

* Do not create color attachment views with formats that are not RT compatible

* Make sure that the host format matches the vertex shader input types for invalid/unknown guest formats

* FIx rebase for Vertex Attrib State

* Fix 4b alignment for vertex

* Use asynchronous queue submits for MVK

* Ensure color clear shader has correct output type

* Update MoltenVK config

* Always use MoltenVK workarounds on MacOS

* Make MVK supersede all vendors

* Fix rebase

* Various fixes on rebase

* Get portability flags from extension

* Fix some minor rebasing issues

* Style change

* Use LibraryImport for MVKConfiguration

* Rename MoltenVK vendor to Apple

Intel and AMD GPUs on moltenvk report with the those vendors - only apple silicon reports with vendor 0x106B.

* Fix features2 rebase conflict

* Rename fragment output type

* Add missing check for fragment output types

Might have caused the crash in MK8

* Only do fragment output specialization on MoltenVK

* Avoid copy when passing capabilities

* Self feedback

* Address feedback

Co-authored-by: gdk <gab.dark.100@gmail.com>
Co-authored-by: nastys <nastys@users.noreply.github.com>
This commit is contained in:
riperiperi 2023-01-13 00:31:21 +00:00 committed by GitHub
parent 30862b5ffd
commit 8fa248ceb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 739 additions and 61 deletions

View file

@ -9,6 +9,13 @@ using VkFormat = Silk.NET.Vulkan.Format;
namespace Ryujinx.Graphics.Vulkan
{
enum ComponentType
{
Float,
SignedInteger,
UnsignedInteger
}
class HelperShader : IDisposable
{
private const int UniformBufferAlignment = 256;
@ -18,7 +25,9 @@ namespace Ryujinx.Graphics.Vulkan
private readonly ISampler _samplerNearest;
private readonly IProgram _programColorBlit;
private readonly IProgram _programColorBlitClearAlpha;
private readonly IProgram _programColorClear;
private readonly IProgram _programColorClearF;
private readonly IProgram _programColorClearSI;
private readonly IProgram _programColorClearUI;
private readonly IProgram _programStrideChange;
private readonly IProgram _programConvertIndexBuffer;
private readonly IProgram _programConvertIndirectData;
@ -63,10 +72,22 @@ namespace Ryujinx.Graphics.Vulkan
Array.Empty<int>(),
Array.Empty<int>());
_programColorClear = gd.CreateProgramWithMinimalLayout(new[]
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
{
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearFFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
});
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
{
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearSIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
});
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
{
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearUIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
});
var strideChangeBindings = new ShaderBindings(
@ -242,6 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
int dstWidth,
int dstHeight,
VkFormat dstFormat,
ComponentType type,
Rectangle<int> scissor)
{
const int ClearColorBufferSize = 16;
@ -273,7 +295,22 @@ namespace Ryujinx.Graphics.Vulkan
scissors[0] = scissor;
_pipeline.SetProgram(_programColorClear);
IProgram program;
if (type == ComponentType.SignedInteger)
{
program = _programColorClearSI;
}
else if (type == ComponentType.UnsignedInteger)
{
program = _programColorClearUI;
}
else
{
program = _programColorClearF;
}
_pipeline.SetProgram(program);
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
_pipeline.SetRenderTargetColorMasks(new uint[] { componentMask });
_pipeline.SetViewports(viewports, false);
@ -948,7 +985,9 @@ namespace Ryujinx.Graphics.Vulkan
{
_programColorBlitClearAlpha.Dispose();
_programColorBlit.Dispose();
_programColorClear.Dispose();
_programColorClearF.Dispose();
_programColorClearSI.Dispose();
_programColorClearUI.Dispose();
_programStrideChange.Dispose();
_programConvertIndexBuffer.Dispose();
_programConvertIndirectData.Dispose();