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
This commit is contained in:
gdkchan 2023-02-07 13:55:59 -03:00 committed by GitHub
parent cb250162cb
commit f8beeeb7d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 436 additions and 74 deletions

View file

@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly ISampler _samplerLinear; private readonly ISampler _samplerLinear;
private readonly ISampler _samplerNearest; private readonly ISampler _samplerNearest;
private readonly IProgram _programColorBlit; private readonly IProgram _programColorBlit;
private readonly IProgram _programColorBlitMs;
private readonly IProgram _programColorBlitClearAlpha; private readonly IProgram _programColorBlitClearAlpha;
private readonly IProgram _programColorClearF; private readonly IProgram _programColorClearF;
private readonly IProgram _programColorClearSI; private readonly IProgram _programColorClearSI;
@ -34,7 +35,9 @@ namespace Ryujinx.Graphics.Vulkan
private readonly IProgram _programColorCopyToNonMs; private readonly IProgram _programColorCopyToNonMs;
private readonly IProgram _programColorDrawToMs; private readonly IProgram _programColorDrawToMs;
private readonly IProgram _programDepthBlit; private readonly IProgram _programDepthBlit;
private readonly IProgram _programDepthBlitMs;
private readonly IProgram _programStencilBlit; private readonly IProgram _programStencilBlit;
private readonly IProgram _programStencilBlitMs;
public HelperShader(VulkanRenderer gd, Device device) public HelperShader(VulkanRenderer gd, Device device)
{ {
@ -62,6 +65,12 @@ namespace Ryujinx.Graphics.Vulkan
new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv), 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[] _programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), 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), 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) if (gd.Capabilities.SupportsShaderStencilExport)
{ {
_programStencilBlit = gd.CreateProgramWithMinimalLayout(new[] _programStencilBlit = gd.CreateProgramWithMinimalLayout(new[]
@ -167,18 +182,23 @@ namespace Ryujinx.Graphics.Vulkan
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.StencilBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, 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( public void Blit(
VulkanRenderer gd, VulkanRenderer gd,
TextureView src, TextureView src,
Auto<DisposableImageView> dst, TextureView dst,
int dstWidth,
int dstHeight,
VkFormat dstFormat,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion, Extents2D dstRegion,
int layers,
int levels,
bool isDepthOrStencil, bool isDepthOrStencil,
bool linearFilter, bool linearFilter,
bool clearAlpha = false) bool clearAlpha = false)
@ -187,13 +207,137 @@ namespace Ryujinx.Graphics.Vulkan
using var cbs = gd.CommandBufferPool.Rent(); using var cbs = gd.CommandBufferPool.Rent();
var dstFormat = dst.VkFormat;
var dstSamples = dst.Info.Samples;
for (int l = 0; l < levels; l++)
{
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) if (isDepthOrStencil)
{ {
BlitDepthStencil(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion); BlitDepthStencil(
gd,
cbs,
srcView,
dst.GetImageViewForAttachment(),
dstWidth,
dstHeight,
dstSamples,
dstFormat,
mipSrcRegion,
mipDstRegion);
} }
else else
{ {
BlitColor(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion, linearFilter, clearAlpha); 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();
}
}
}
}
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++)
{
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<DisposableImageView> dst, Auto<DisposableImageView> dst,
int dstWidth, int dstWidth,
int dstHeight, int dstHeight,
int dstSamples,
VkFormat dstFormat, VkFormat dstFormat,
bool dstIsDepthOrStencil,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion, Extents2D dstRegion,
bool linearFilter, bool linearFilter,
@ -262,8 +408,25 @@ namespace Ryujinx.Graphics.Vulkan
scissors[0] = new Rectangle<int>(0, 0, dstWidth, dstHeight); scissors[0] = new Rectangle<int>(0, 0, dstWidth, dstHeight);
_pipeline.SetProgram(clearAlpha ? _programColorBlitClearAlpha : _programColorBlit); if (dstIsDepthOrStencil)
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat); {
_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.SetRenderTargetColorMasks(new uint[] { 0xf });
_pipeline.SetScissors(scissors); _pipeline.SetScissors(scissors);
@ -275,6 +438,12 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetViewports(viewports, false); _pipeline.SetViewports(viewports, false);
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip); _pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
_pipeline.Draw(4, 1, 0, 0); _pipeline.Draw(4, 1, 0, 0);
if (dstIsDepthOrStencil)
{
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
}
_pipeline.Finish(gd, cbs); _pipeline.Finish(gd, cbs);
gd.BufferManager.Delete(bufferHandle); gd.BufferManager.Delete(bufferHandle);
@ -287,6 +456,7 @@ namespace Ryujinx.Graphics.Vulkan
Auto<DisposableImageView> dst, Auto<DisposableImageView> dst,
int dstWidth, int dstWidth,
int dstHeight, int dstHeight,
int dstSamples,
VkFormat dstFormat, VkFormat dstFormat,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion) Extents2D dstRegion)
@ -339,7 +509,7 @@ namespace Ryujinx.Graphics.Vulkan
scissors[0] = new Rectangle<int>(0, 0, dstWidth, dstHeight); scissors[0] = new Rectangle<int>(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.SetScissors(scissors);
_pipeline.SetViewports(viewports, false); _pipeline.SetViewports(viewports, false);
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip); _pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
@ -406,12 +576,12 @@ namespace Ryujinx.Graphics.Vulkan
if (isDepth) if (isDepth)
{ {
_pipeline.SetProgram(_programDepthBlit); _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always)); _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
} }
else else
{ {
_pipeline.SetProgram(_programStencilBlit); _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programStencilBlitMs : _programStencilBlit);
_pipeline.SetStencilTest(CreateStencilTestDescriptor(true)); _pipeline.SetStencilTest(CreateStencilTestDescriptor(true));
} }
@ -795,34 +965,26 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); _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 srcView = Create2DLayerView(src, srcLayer + z, 0, format);
var dstView = Create2DLayerView(dst, dstLayer + z); var dstView = Create2DLayerView(dst, dstLayer + z, 0);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null);
_pipeline.SetImage(0, dstView, format); _pipeline.SetImage(0, dstView, format);
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
if (srcView != src)
{
srcView.Release(); srcView.Release();
}
if (dstView != dst)
{
dstView.Release(); dstView.Release();
} }
} }
else
{
var srcView = Create2DLayerView(src, srcLayer, format);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null);
_pipeline.SetImage(0, dst, format);
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
srcView.Release();
}
gd.BufferManager.Delete(bufferHandle); gd.BufferManager.Delete(bufferHandle);
@ -906,13 +1068,10 @@ namespace Ryujinx.Graphics.Vulkan
var format = GetFormat(src.Info.BytesPerPixel); var format = GetFormat(src.Info.BytesPerPixel);
var vkFormat = FormatTable.GetFormat(format); 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 srcView = Create2DLayerView(src, srcLayer + z, 0, format);
var dstView = Create2DLayerView(dst, dstLayer + z); var dstView = Create2DLayerView(dst, dstLayer + z, 0);
_pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null); _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null);
_pipeline.SetRenderTarget( _pipeline.SetRenderTarget(
@ -925,27 +1084,16 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.Draw(4, 1, 0, 0); _pipeline.Draw(4, 1, 0, 0);
if (srcView != src)
{
srcView.Release(); srcView.Release();
}
if (dstView != dst)
{
dstView.Release(); dstView.Release();
} }
} }
else
{
var srcView = Create2DLayerView(src, srcLayer, format);
_pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null);
_pipeline.SetRenderTarget(
dst.GetView(format).GetImageViewForAttachment(),
(uint)dst.Width,
(uint)dst.Height,
(uint)samples,
false,
vkFormat);
_pipeline.Draw(4, 1, 0, 0);
srcView.Release();
}
gd.BufferManager.Delete(bufferHandle); gd.BufferManager.Delete(bufferHandle);
@ -1001,14 +1149,18 @@ namespace Ryujinx.Graphics.Vulkan
return (samplesInXLog2, samplesInYLog2); 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 var target = from.Info.Target switch
{ {
Target.Texture1DArray => Target.Texture1D, Target.Texture1DArray => Target.Texture1D,
Target.Texture2DArray => Target.Texture2D,
Target.Texture2DMultisampleArray => Target.Texture2DMultisample, Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
_ => from.Info.Target _ => Target.Texture2D
}; };
var info = new TextureCreateInfo( var info = new TextureCreateInfo(
@ -1028,7 +1180,7 @@ namespace Ryujinx.Graphics.Vulkan
from.Info.SwizzleB, from.Info.SwizzleB,
from.Info.SwizzleA); from.Info.SwizzleA);
return from.CreateView(info, layer, 0); return from.CreateViewImpl(info, layer, level);
} }
private static GAL.Format GetFormat(int bytesPerPixel) private static GAL.Format GetFormat(int bytesPerPixel)
@ -1177,6 +1329,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_programColorBlitClearAlpha.Dispose(); _programColorBlitClearAlpha.Dispose();
_programColorBlit.Dispose(); _programColorBlit.Dispose();
_programColorBlitMs.Dispose();
_programColorClearF.Dispose(); _programColorClearF.Dispose();
_programColorClearSI.Dispose(); _programColorClearSI.Dispose();
_programColorClearUI.Dispose(); _programColorClearUI.Dispose();
@ -1186,7 +1339,9 @@ namespace Ryujinx.Graphics.Vulkan
_programColorCopyToNonMs.Dispose(); _programColorCopyToNonMs.Dispose();
_programColorDrawToMs.Dispose(); _programColorDrawToMs.Dispose();
_programDepthBlit.Dispose(); _programDepthBlit.Dispose();
_programDepthBlitMs.Dispose();
_programStencilBlit?.Dispose(); _programStencilBlit?.Dispose();
_programStencilBlitMs?.Dispose();
_samplerNearest.Dispose(); _samplerNearest.Dispose();
_samplerLinear.Dispose(); _samplerLinear.Dispose();
_pipeline.Dispose(); _pipeline.Dispose();

View file

@ -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);
}

View file

@ -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;
}

View file

@ -329,6 +329,61 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, 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[] public static readonly byte[] ColorBlitVertexShaderSource = new byte[]
{ {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x00, 0x00, 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, 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[] public static readonly byte[] StencilBlitFragmentShaderSource = new byte[]
{ {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00, 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, 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, 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,
};
} }
} }

View file

@ -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;
}

View file

@ -368,20 +368,16 @@ namespace Ryujinx.Graphics.Vulkan
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
if (VulkanConfiguration.UseSlowSafeBlitOnAmd && if (VulkanConfiguration.UseSlowSafeBlitOnAmd && (_gd.Vendor == Vendor.Amd || _gd.IsMoltenVk))
(_gd.Vendor == Vendor.Amd || _gd.IsMoltenVk) &&
src.Info.Target == Target.Texture2D &&
dst.Info.Target == Target.Texture2D)
{ {
_gd.HelperShader.Blit( _gd.HelperShader.Blit(
_gd, _gd,
src, src,
dst.GetIdentityImageView(), dst,
dst.Width,
dst.Height,
dst.VkFormat,
srcRegion, srcRegion,
dstRegion, dstRegion,
layers,
levels,
isDepthOrStencil, isDepthOrStencil,
linearFilter); linearFilter);
@ -501,7 +497,7 @@ namespace Ryujinx.Graphics.Vulkan
return CreateViewImpl(info, firstLayer, firstLevel); 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); return new TextureView(_gd, _device, info, Storage, FirstLayer + firstLayer, FirstLevel + firstLevel);
} }

View file

@ -342,7 +342,9 @@ namespace Ryujinx.Graphics.Vulkan
_swapchainImageViews[nextImage], _swapchainImageViews[nextImage],
_width, _width,
_height, _height,
1,
_format, _format,
false,
new Extents2D(srcX0, srcY0, srcX1, srcY1), new Extents2D(srcX0, srcY0, srcX1, srcY1),
new Extents2D(dstX0, dstY1, dstX1, dstY0), new Extents2D(dstX0, dstY1, dstX1, dstY0),
true, true,