From f8beeeb7d3dca796d05a2ab1d7a8f1af3b7e3fb5 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 7 Feb 2023 13:55:59 -0300 Subject: [PATCH] Support safe blit on non-2D textures (#4374) * Support safe blit on non-2D textures (except multisample) * Change safe blit with different levels and layers to match CmdBlitImage path * Remove now unused variables * Multisample safe blit support --- Ryujinx.Graphics.Vulkan/HelperShader.cs | 285 ++++++++++++++---- .../ColorBlitMsFragmentShaderSource.frag | 11 + .../DepthBlitMsFragmentShaderSource.frag | 10 + .../Shaders/ShaderBinaries.cs | 176 +++++++++++ .../StencilBlitMsFragmentShaderSource.frag | 12 + Ryujinx.Graphics.Vulkan/TextureView.cs | 14 +- Ryujinx.Graphics.Vulkan/Window.cs | 2 + 7 files changed, 436 insertions(+), 74 deletions(-) create mode 100644 Ryujinx.Graphics.Vulkan/Shaders/ColorBlitMsFragmentShaderSource.frag create mode 100644 Ryujinx.Graphics.Vulkan/Shaders/DepthBlitMsFragmentShaderSource.frag create mode 100644 Ryujinx.Graphics.Vulkan/Shaders/StencilBlitMsFragmentShaderSource.frag diff --git a/Ryujinx.Graphics.Vulkan/HelperShader.cs b/Ryujinx.Graphics.Vulkan/HelperShader.cs index 658516e6..b8c21fe8 100644 --- a/Ryujinx.Graphics.Vulkan/HelperShader.cs +++ b/Ryujinx.Graphics.Vulkan/HelperShader.cs @@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly ISampler _samplerLinear; private readonly ISampler _samplerNearest; private readonly IProgram _programColorBlit; + private readonly IProgram _programColorBlitMs; private readonly IProgram _programColorBlitClearAlpha; private readonly IProgram _programColorClearF; private readonly IProgram _programColorClearSI; @@ -34,7 +35,9 @@ namespace Ryujinx.Graphics.Vulkan private readonly IProgram _programColorCopyToNonMs; private readonly IProgram _programColorDrawToMs; private readonly IProgram _programDepthBlit; + private readonly IProgram _programDepthBlitMs; private readonly IProgram _programStencilBlit; + private readonly IProgram _programStencilBlitMs; public HelperShader(VulkanRenderer gd, Device device) { @@ -62,6 +65,12 @@ namespace Ryujinx.Graphics.Vulkan new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), }); + _programColorBlitMs = gd.CreateProgramWithMinimalLayout(new[] + { + new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), + new ShaderSource(ShaderBinaries.ColorBlitMsFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), + }); + _programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[] { new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), @@ -160,6 +169,12 @@ namespace Ryujinx.Graphics.Vulkan new ShaderSource(ShaderBinaries.DepthBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), }); + _programDepthBlitMs = gd.CreateProgramWithMinimalLayout(new[] + { + new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), + new ShaderSource(ShaderBinaries.DepthBlitMsFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), + }); + if (gd.Capabilities.SupportsShaderStencilExport) { _programStencilBlit = gd.CreateProgramWithMinimalLayout(new[] @@ -167,18 +182,23 @@ namespace Ryujinx.Graphics.Vulkan new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ShaderBinaries.StencilBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), }); + + _programStencilBlitMs = gd.CreateProgramWithMinimalLayout(new[] + { + new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), + new ShaderSource(ShaderBinaries.StencilBlitMsFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), + }); } } public void Blit( VulkanRenderer gd, TextureView src, - Auto dst, - int dstWidth, - int dstHeight, - VkFormat dstFormat, + TextureView dst, Extents2D srcRegion, Extents2D dstRegion, + int layers, + int levels, bool isDepthOrStencil, bool linearFilter, bool clearAlpha = false) @@ -187,13 +207,137 @@ namespace Ryujinx.Graphics.Vulkan using var cbs = gd.CommandBufferPool.Rent(); - if (isDepthOrStencil) + var dstFormat = dst.VkFormat; + var dstSamples = dst.Info.Samples; + + for (int l = 0; l < levels; l++) { - BlitDepthStencil(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion); + int srcWidth = Math.Max(1, src.Width >> l); + int srcHeight = Math.Max(1, src.Height >> l); + + int dstWidth = Math.Max(1, dst.Width >> l); + int dstHeight = Math.Max(1, dst.Height >> l); + + var mipSrcRegion = new Extents2D( + srcRegion.X1 >> l, + srcRegion.Y1 >> l, + srcRegion.X2 >> l, + srcRegion.Y2 >> l); + + var mipDstRegion = new Extents2D( + dstRegion.X1 >> l, + dstRegion.Y1 >> l, + dstRegion.X2 >> l, + dstRegion.Y2 >> l); + + for (int z = 0; z < layers; z++) + { + var srcView = Create2DLayerView(src, z, l); + var dstView = Create2DLayerView(dst, z, l); + + if (isDepthOrStencil) + { + BlitDepthStencil( + gd, + cbs, + srcView, + dst.GetImageViewForAttachment(), + dstWidth, + dstHeight, + dstSamples, + dstFormat, + mipSrcRegion, + mipDstRegion); + } + else + { + BlitColor( + gd, + cbs, + srcView, + dst.GetImageViewForAttachment(), + dstWidth, + dstHeight, + dstSamples, + dstFormat, + false, + mipSrcRegion, + mipDstRegion, + linearFilter, + clearAlpha); + } + + if (srcView != src) + { + srcView.Release(); + } + + if (dstView != dst) + { + dstView.Release(); + } + } } - else + } + + public void CopyColor( + VulkanRenderer gd, + CommandBufferScoped cbs, + TextureView src, + TextureView dst, + int srcLayer, + int dstLayer, + int srcLevel, + int dstLevel, + int depth, + int levels) + { + for (int l = 0; l < levels; l++) { - BlitColor(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion, linearFilter, clearAlpha); + int mipSrcLevel = srcLevel + l; + int mipDstLevel = dstLevel + l; + + int srcWidth = Math.Max(1, src.Width >> mipSrcLevel); + int srcHeight = Math.Max(1, src.Height >> mipSrcLevel); + + int dstWidth = Math.Max(1, dst.Width >> mipDstLevel); + int dstHeight = Math.Max(1, dst.Height >> mipDstLevel); + + var extents = new Extents2D( + 0, + 0, + Math.Min(srcWidth, dstWidth), + Math.Min(srcHeight, dstHeight)); + + for (int z = 0; z < depth; z++) + { + var srcView = Create2DLayerView(src, srcLayer + z, mipSrcLevel); + var dstView = Create2DLayerView(dst, dstLayer + z, mipDstLevel); + + BlitColor( + gd, + cbs, + srcView, + dstView.GetImageViewForAttachment(), + dstView.Width, + dstView.Height, + dstView.Info.Samples, + dstView.VkFormat, + dstView.Info.Format.IsDepthOrStencil(), + extents, + extents, + false); + + if (srcView != src) + { + srcView.Release(); + } + + if (dstView != dst) + { + dstView.Release(); + } + } } } @@ -204,7 +348,9 @@ namespace Ryujinx.Graphics.Vulkan Auto dst, int dstWidth, int dstHeight, + int dstSamples, VkFormat dstFormat, + bool dstIsDepthOrStencil, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter, @@ -262,8 +408,25 @@ namespace Ryujinx.Graphics.Vulkan scissors[0] = new Rectangle(0, 0, dstWidth, dstHeight); - _pipeline.SetProgram(clearAlpha ? _programColorBlitClearAlpha : _programColorBlit); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat); + if (dstIsDepthOrStencil) + { + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); + _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always)); + } + else if (src.Info.Target.IsMultisample()) + { + _pipeline.SetProgram(_programColorBlitMs); + } + else if (clearAlpha) + { + _pipeline.SetProgram(_programColorBlitClearAlpha); + } + else + { + _pipeline.SetProgram(_programColorBlit); + } + + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, dstIsDepthOrStencil, dstFormat); _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }); _pipeline.SetScissors(scissors); @@ -275,6 +438,12 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetViewports(viewports, false); _pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); + + if (dstIsDepthOrStencil) + { + _pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always)); + } + _pipeline.Finish(gd, cbs); gd.BufferManager.Delete(bufferHandle); @@ -287,6 +456,7 @@ namespace Ryujinx.Graphics.Vulkan Auto dst, int dstWidth, int dstHeight, + int dstSamples, VkFormat dstFormat, Extents2D srcRegion, Extents2D dstRegion) @@ -339,7 +509,7 @@ namespace Ryujinx.Graphics.Vulkan scissors[0] = new Rectangle(0, 0, dstWidth, dstHeight); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, true, dstFormat); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat); _pipeline.SetScissors(scissors); _pipeline.SetViewports(viewports, false); _pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip); @@ -406,12 +576,12 @@ namespace Ryujinx.Graphics.Vulkan if (isDepth) { - _pipeline.SetProgram(_programDepthBlit); + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always)); } else { - _pipeline.SetProgram(_programStencilBlit); + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programStencilBlitMs : _programStencilBlit); _pipeline.SetStencilTest(CreateStencilTestDescriptor(true)); } @@ -795,33 +965,25 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); - if (src.Info.Target == Target.Texture2DMultisampleArray || - dst.Info.Target == Target.Texture2DMultisampleArray) + for (int z = 0; z < depth; z++) { - for (int z = 0; z < depth; z++) - { - var srcView = Create2DLayerView(src, srcLayer + z, format); - var dstView = Create2DLayerView(dst, dstLayer + z); - - _pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null); - _pipeline.SetImage(0, dstView, format); - - _pipeline.DispatchCompute(dispatchX, dispatchY, 1); - - srcView.Release(); - dstView.Release(); - } - } - else - { - var srcView = Create2DLayerView(src, srcLayer, format); + var srcView = Create2DLayerView(src, srcLayer + z, 0, format); + var dstView = Create2DLayerView(dst, dstLayer + z, 0); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null); - _pipeline.SetImage(0, dst, format); + _pipeline.SetImage(0, dstView, format); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); - srcView.Release(); + if (srcView != src) + { + srcView.Release(); + } + + if (dstView != dst) + { + dstView.Release(); + } } gd.BufferManager.Delete(bufferHandle); @@ -906,36 +1068,14 @@ namespace Ryujinx.Graphics.Vulkan var format = GetFormat(src.Info.BytesPerPixel); var vkFormat = FormatTable.GetFormat(format); - if (src.Info.Target == Target.Texture2DMultisampleArray || - dst.Info.Target == Target.Texture2DMultisampleArray) + for (int z = 0; z < depth; z++) { - for (int z = 0; z < depth; z++) - { - var srcView = Create2DLayerView(src, srcLayer + z, format); - var dstView = Create2DLayerView(dst, dstLayer + z); - - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null); - _pipeline.SetRenderTarget( - ((TextureView)dstView).GetView(format).GetImageViewForAttachment(), - (uint)dst.Width, - (uint)dst.Height, - (uint)samples, - false, - vkFormat); - - _pipeline.Draw(4, 1, 0, 0); - - srcView.Release(); - dstView.Release(); - } - } - else - { - var srcView = Create2DLayerView(src, srcLayer, format); + var srcView = Create2DLayerView(src, srcLayer + z, 0, format); + var dstView = Create2DLayerView(dst, dstLayer + z, 0); _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null); _pipeline.SetRenderTarget( - dst.GetView(format).GetImageViewForAttachment(), + ((TextureView)dstView).GetView(format).GetImageViewForAttachment(), (uint)dst.Width, (uint)dst.Height, (uint)samples, @@ -944,7 +1084,15 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.Draw(4, 1, 0, 0); - srcView.Release(); + if (srcView != src) + { + srcView.Release(); + } + + if (dstView != dst) + { + dstView.Release(); + } } gd.BufferManager.Delete(bufferHandle); @@ -1001,14 +1149,18 @@ namespace Ryujinx.Graphics.Vulkan return (samplesInXLog2, samplesInYLog2); } - private static ITexture Create2DLayerView(TextureView from, int layer, GAL.Format? format = null) + private static TextureView Create2DLayerView(TextureView from, int layer, int level, GAL.Format? format = null) { + if (from.Info.Target == Target.Texture2D && level == 0 && (format == null || format.Value == from.Info.Format)) + { + return from; + } + var target = from.Info.Target switch { Target.Texture1DArray => Target.Texture1D, - Target.Texture2DArray => Target.Texture2D, Target.Texture2DMultisampleArray => Target.Texture2DMultisample, - _ => from.Info.Target + _ => Target.Texture2D }; var info = new TextureCreateInfo( @@ -1028,7 +1180,7 @@ namespace Ryujinx.Graphics.Vulkan from.Info.SwizzleB, from.Info.SwizzleA); - return from.CreateView(info, layer, 0); + return from.CreateViewImpl(info, layer, level); } private static GAL.Format GetFormat(int bytesPerPixel) @@ -1177,6 +1329,7 @@ namespace Ryujinx.Graphics.Vulkan { _programColorBlitClearAlpha.Dispose(); _programColorBlit.Dispose(); + _programColorBlitMs.Dispose(); _programColorClearF.Dispose(); _programColorClearSI.Dispose(); _programColorClearUI.Dispose(); @@ -1186,7 +1339,9 @@ namespace Ryujinx.Graphics.Vulkan _programColorCopyToNonMs.Dispose(); _programColorDrawToMs.Dispose(); _programDepthBlit.Dispose(); + _programDepthBlitMs.Dispose(); _programStencilBlit?.Dispose(); + _programStencilBlitMs?.Dispose(); _samplerNearest.Dispose(); _samplerLinear.Dispose(); _pipeline.Dispose(); diff --git a/Ryujinx.Graphics.Vulkan/Shaders/ColorBlitMsFragmentShaderSource.frag b/Ryujinx.Graphics.Vulkan/Shaders/ColorBlitMsFragmentShaderSource.frag new file mode 100644 index 00000000..71145e02 --- /dev/null +++ b/Ryujinx.Graphics.Vulkan/Shaders/ColorBlitMsFragmentShaderSource.frag @@ -0,0 +1,11 @@ +#version 450 core + +layout (binding = 0, set = 2) uniform sampler2DMS tex; + +layout (location = 0) in vec2 tex_coord; +layout (location = 0) out vec4 colour; + +void main() +{ + colour = texelFetch(tex, ivec2(tex_coord * vec2(textureSize(tex).xy)), gl_SampleID); +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Vulkan/Shaders/DepthBlitMsFragmentShaderSource.frag b/Ryujinx.Graphics.Vulkan/Shaders/DepthBlitMsFragmentShaderSource.frag new file mode 100644 index 00000000..c93c7e7f --- /dev/null +++ b/Ryujinx.Graphics.Vulkan/Shaders/DepthBlitMsFragmentShaderSource.frag @@ -0,0 +1,10 @@ +#version 450 core + +layout (binding = 0, set = 2) uniform sampler2DMS texDepth; + +layout (location = 0) in vec2 tex_coord; + +void main() +{ + gl_FragDepth = texelFetch(texDepth, ivec2(tex_coord * vec2(textureSize(texDepth).xy)), gl_SampleID).r; +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Vulkan/Shaders/ShaderBinaries.cs b/Ryujinx.Graphics.Vulkan/Shaders/ShaderBinaries.cs index 5a2acf22..c9df894b 100644 --- a/Ryujinx.Graphics.Vulkan/Shaders/ShaderBinaries.cs +++ b/Ryujinx.Graphics.Vulkan/Shaders/ShaderBinaries.cs @@ -329,6 +329,61 @@ namespace Ryujinx.Graphics.Vulkan.Shaders 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, }; + public static readonly byte[] ColorBlitMsFragmentShaderSource = new byte[] + { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x63, 0x6F, 0x6C, 0x6F, 0x75, 0x72, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x00, 0x05, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x5F, + 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x67, 0x6C, 0x5F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x49, 0x44, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x1D, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x1D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, + }; + public static readonly byte[] ColorBlitVertexShaderSource = new byte[] { 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x00, 0x00, @@ -1502,6 +1557,64 @@ namespace Ryujinx.Graphics.Vulkan.Shaders 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, }; + public static readonly byte[] DepthBlitMsFragmentShaderSource = new byte[] + { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x46, + 0x72, 0x61, 0x67, 0x44, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x44, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, + 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x53, + 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x49, 0x44, 0x00, 0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x6F, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x1B, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0x1D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, + }; + public static readonly byte[] StencilBlitFragmentShaderSource = new byte[] { 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00, @@ -1549,5 +1662,68 @@ namespace Ryujinx.Graphics.Vulkan.Shaders 0x17, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, }; + + public static readonly byte[] StencilBlitMsFragmentShaderSource = new byte[] + { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F, + 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x65, + 0x78, 0x70, 0x6F, 0x72, 0x74, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xA3, 0x13, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x65, + 0x72, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x46, + 0x72, 0x61, 0x67, 0x53, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x52, 0x65, 0x66, 0x41, 0x52, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x53, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x1B, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x49, 0x44, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x96, 0x13, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x03, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x1B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, + 0x1A, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x68, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x04, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x07, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, + }; } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Vulkan/Shaders/StencilBlitMsFragmentShaderSource.frag b/Ryujinx.Graphics.Vulkan/Shaders/StencilBlitMsFragmentShaderSource.frag new file mode 100644 index 00000000..7e26672a --- /dev/null +++ b/Ryujinx.Graphics.Vulkan/Shaders/StencilBlitMsFragmentShaderSource.frag @@ -0,0 +1,12 @@ +#version 450 core + +#extension GL_ARB_shader_stencil_export : require + +layout (binding = 0, set = 2) uniform isampler2DMS texStencil; + +layout (location = 0) in vec2 tex_coord; + +void main() +{ + gl_FragStencilRefARB = texelFetch(texStencil, ivec2(tex_coord * vec2(textureSize(texStencil).xy)), gl_SampleID).r; +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Vulkan/TextureView.cs b/Ryujinx.Graphics.Vulkan/TextureView.cs index 3ee19675..e58b743d 100644 --- a/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -368,20 +368,16 @@ namespace Ryujinx.Graphics.Vulkan bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); - if (VulkanConfiguration.UseSlowSafeBlitOnAmd && - (_gd.Vendor == Vendor.Amd || _gd.IsMoltenVk) && - src.Info.Target == Target.Texture2D && - dst.Info.Target == Target.Texture2D) + if (VulkanConfiguration.UseSlowSafeBlitOnAmd && (_gd.Vendor == Vendor.Amd || _gd.IsMoltenVk)) { _gd.HelperShader.Blit( _gd, src, - dst.GetIdentityImageView(), - dst.Width, - dst.Height, - dst.VkFormat, + dst, srcRegion, dstRegion, + layers, + levels, isDepthOrStencil, linearFilter); @@ -501,7 +497,7 @@ namespace Ryujinx.Graphics.Vulkan return CreateViewImpl(info, firstLayer, firstLevel); } - private TextureView CreateViewImpl(TextureCreateInfo info, int firstLayer, int firstLevel) + public TextureView CreateViewImpl(TextureCreateInfo info, int firstLayer, int firstLevel) { return new TextureView(_gd, _device, info, Storage, FirstLayer + firstLayer, FirstLevel + firstLevel); } diff --git a/Ryujinx.Graphics.Vulkan/Window.cs b/Ryujinx.Graphics.Vulkan/Window.cs index dc4dc6be..a90a824d 100644 --- a/Ryujinx.Graphics.Vulkan/Window.cs +++ b/Ryujinx.Graphics.Vulkan/Window.cs @@ -342,7 +342,9 @@ namespace Ryujinx.Graphics.Vulkan _swapchainImageViews[nextImage], _width, _height, + 1, _format, + false, new Extents2D(srcX0, srcY0, srcX1, srcY1), new Extents2D(dstX0, dstY1, dstX1, dstY0), true,