forked from Mirror/Ryujinx
Implement safe depth-stencil blit using stencil export extension (#4356)
* Implement safe depth-stencil blit using stencil export extension * Delete depth-stencil blit with buffer path
This commit is contained in:
parent
43081c16c4
commit
7528f94536
10 changed files with 330 additions and 213 deletions
|
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_device = device;
|
_device = device;
|
||||||
_attachments = new[] { view };
|
_attachments = new[] { view };
|
||||||
_validColorAttachments = 1u;
|
_validColorAttachments = isDepthStencil ? 0u : 1u;
|
||||||
|
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
|
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
AttachmentSamples = new[] { samples };
|
AttachmentSamples = new[] { samples };
|
||||||
AttachmentFormats = new[] { format };
|
AttachmentFormats = new[] { format };
|
||||||
AttachmentIndices = new[] { 0 };
|
AttachmentIndices = isDepthStencil ? Array.Empty<int>() : new[] { 0 };
|
||||||
|
|
||||||
AttachmentsCount = 1;
|
AttachmentsCount = 1;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
public readonly bool SupportsSubgroupSizeControl;
|
public readonly bool SupportsSubgroupSizeControl;
|
||||||
public readonly bool SupportsShaderInt8;
|
public readonly bool SupportsShaderInt8;
|
||||||
|
public readonly bool SupportsShaderStencilExport;
|
||||||
public readonly bool SupportsConditionalRendering;
|
public readonly bool SupportsConditionalRendering;
|
||||||
public readonly bool SupportsExtendedDynamicState;
|
public readonly bool SupportsExtendedDynamicState;
|
||||||
public readonly bool SupportsMultiView;
|
public readonly bool SupportsMultiView;
|
||||||
|
@ -48,6 +49,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
bool supportsSubgroupSizeControl,
|
bool supportsSubgroupSizeControl,
|
||||||
bool supportsShaderInt8,
|
bool supportsShaderInt8,
|
||||||
|
bool supportsShaderStencilExport,
|
||||||
bool supportsConditionalRendering,
|
bool supportsConditionalRendering,
|
||||||
bool supportsExtendedDynamicState,
|
bool supportsExtendedDynamicState,
|
||||||
bool supportsMultiView,
|
bool supportsMultiView,
|
||||||
|
@ -71,6 +73,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
SupportsSubgroupSizeControl = supportsSubgroupSizeControl;
|
SupportsSubgroupSizeControl = supportsSubgroupSizeControl;
|
||||||
SupportsShaderInt8 = supportsShaderInt8;
|
SupportsShaderInt8 = supportsShaderInt8;
|
||||||
|
SupportsShaderStencilExport = supportsShaderStencilExport;
|
||||||
SupportsConditionalRendering = supportsConditionalRendering;
|
SupportsConditionalRendering = supportsConditionalRendering;
|
||||||
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
||||||
SupportsMultiView = supportsMultiView;
|
SupportsMultiView = supportsMultiView;
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly IProgram _programConvertIndirectData;
|
private readonly IProgram _programConvertIndirectData;
|
||||||
private readonly IProgram _programColorCopyToNonMs;
|
private readonly IProgram _programColorCopyToNonMs;
|
||||||
private readonly IProgram _programColorDrawToMs;
|
private readonly IProgram _programColorDrawToMs;
|
||||||
|
private readonly IProgram _programDepthBlit;
|
||||||
|
private readonly IProgram _programStencilBlit;
|
||||||
|
|
||||||
public HelperShader(VulkanRenderer gd, Device device)
|
public HelperShader(VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
|
@ -42,13 +44,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_samplerLinear = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_samplerLinear = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
_samplerNearest = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
_samplerNearest = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||||
|
|
||||||
var colorBlitVertexBindings = new ShaderBindings(
|
var blitVertexBindings = new ShaderBindings(
|
||||||
new[] { 1 },
|
new[] { 1 },
|
||||||
Array.Empty<int>(),
|
Array.Empty<int>(),
|
||||||
Array.Empty<int>(),
|
Array.Empty<int>(),
|
||||||
Array.Empty<int>());
|
Array.Empty<int>());
|
||||||
|
|
||||||
var colorBlitFragmentBindings = new ShaderBindings(
|
var blitFragmentBindings = new ShaderBindings(
|
||||||
Array.Empty<int>(),
|
Array.Empty<int>(),
|
||||||
Array.Empty<int>(),
|
Array.Empty<int>(),
|
||||||
new[] { 0 },
|
new[] { 0 },
|
||||||
|
@ -56,14 +58,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programColorBlit = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, colorBlitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
_programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitClearAlphaFragmentShaderSource, colorBlitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorBlitClearAlphaFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
var colorClearFragmentBindings = new ShaderBindings(
|
var colorClearFragmentBindings = new ShaderBindings(
|
||||||
|
@ -74,19 +76,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearFFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearFFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearSIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearSIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, colorBlitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearUIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ColorClearUIFragmentShaderSource, colorClearFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,6 +153,21 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ConvertIndirectDataShaderSource, convertIndirectDataBindings, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ShaderBinaries.ConvertIndirectDataShaderSource, convertIndirectDataBindings, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_programDepthBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
|
{
|
||||||
|
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
|
new ShaderSource(ShaderBinaries.DepthBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (gd.Capabilities.SupportsShaderStencilExport)
|
||||||
|
{
|
||||||
|
_programStencilBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
|
{
|
||||||
|
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, blitVertexBindings, ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
|
new ShaderSource(ShaderBinaries.StencilBlitFragmentShaderSource, blitFragmentBindings, ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Blit(
|
public void Blit(
|
||||||
|
@ -162,6 +179,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
VkFormat dstFormat,
|
VkFormat dstFormat,
|
||||||
Extents2D srcRegion,
|
Extents2D srcRegion,
|
||||||
Extents2D dstRegion,
|
Extents2D dstRegion,
|
||||||
|
bool isDepthOrStencil,
|
||||||
bool linearFilter,
|
bool linearFilter,
|
||||||
bool clearAlpha = false)
|
bool clearAlpha = false)
|
||||||
{
|
{
|
||||||
|
@ -169,10 +187,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
using var cbs = gd.CommandBufferPool.Rent();
|
using var cbs = gd.CommandBufferPool.Rent();
|
||||||
|
|
||||||
Blit(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion, linearFilter, clearAlpha);
|
if (isDepthOrStencil)
|
||||||
|
{
|
||||||
|
BlitDepthStencil(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BlitColor(gd, cbs, src, dst, dstWidth, dstHeight, dstFormat, srcRegion, dstRegion, linearFilter, clearAlpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Blit(
|
public void BlitColor(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
TextureView src,
|
TextureView src,
|
||||||
|
@ -255,6 +280,173 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
gd.BufferManager.Delete(bufferHandle);
|
gd.BufferManager.Delete(bufferHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BlitDepthStencil(
|
||||||
|
VulkanRenderer gd,
|
||||||
|
CommandBufferScoped cbs,
|
||||||
|
TextureView src,
|
||||||
|
Auto<DisposableImageView> dst,
|
||||||
|
int dstWidth,
|
||||||
|
int dstHeight,
|
||||||
|
VkFormat dstFormat,
|
||||||
|
Extents2D srcRegion,
|
||||||
|
Extents2D dstRegion)
|
||||||
|
{
|
||||||
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
|
const int RegionBufferSize = 16;
|
||||||
|
|
||||||
|
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];
|
||||||
|
|
||||||
|
region[0] = (float)srcRegion.X1 / src.Width;
|
||||||
|
region[1] = (float)srcRegion.X2 / src.Width;
|
||||||
|
region[2] = (float)srcRegion.Y1 / src.Height;
|
||||||
|
region[3] = (float)srcRegion.Y2 / src.Height;
|
||||||
|
|
||||||
|
if (dstRegion.X1 > dstRegion.X2)
|
||||||
|
{
|
||||||
|
(region[0], region[1]) = (region[1], region[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstRegion.Y1 > dstRegion.Y2)
|
||||||
|
{
|
||||||
|
(region[2], region[3]) = (region[3], region[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize, false);
|
||||||
|
|
||||||
|
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||||
|
|
||||||
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||||
|
|
||||||
|
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||||
|
|
||||||
|
var rect = new Rectangle<float>(
|
||||||
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
|
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||||
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
|
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||||
|
|
||||||
|
viewports[0] = new GAL.Viewport(
|
||||||
|
rect,
|
||||||
|
ViewportSwizzle.PositiveX,
|
||||||
|
ViewportSwizzle.PositiveY,
|
||||||
|
ViewportSwizzle.PositiveZ,
|
||||||
|
ViewportSwizzle.PositiveW,
|
||||||
|
0f,
|
||||||
|
1f);
|
||||||
|
|
||||||
|
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
||||||
|
|
||||||
|
scissors[0] = new Rectangle<int>(0, 0, dstWidth, dstHeight);
|
||||||
|
|
||||||
|
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, true, dstFormat);
|
||||||
|
_pipeline.SetScissors(scissors);
|
||||||
|
_pipeline.SetViewports(viewports, false);
|
||||||
|
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
|
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
|
if (aspectFlags.HasFlag(ImageAspectFlags.DepthBit))
|
||||||
|
{
|
||||||
|
var depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
|
||||||
|
|
||||||
|
BlitDepthStencilDraw(depthTexture, isDepth: true);
|
||||||
|
|
||||||
|
if (depthTexture != src)
|
||||||
|
{
|
||||||
|
depthTexture.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aspectFlags.HasFlag(ImageAspectFlags.StencilBit) && _programStencilBlit != null)
|
||||||
|
{
|
||||||
|
var stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
|
||||||
|
|
||||||
|
BlitDepthStencilDraw(stencilTexture, isDepth: false);
|
||||||
|
|
||||||
|
if (stencilTexture != src)
|
||||||
|
{
|
||||||
|
stencilTexture.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_pipeline.Finish(gd, cbs);
|
||||||
|
|
||||||
|
gd.BufferManager.Delete(bufferHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextureView CreateDepthOrStencilView(TextureView depthStencilTexture, DepthStencilMode depthStencilMode)
|
||||||
|
{
|
||||||
|
if (depthStencilTexture.Info.DepthStencilMode == depthStencilMode)
|
||||||
|
{
|
||||||
|
return depthStencilTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TextureView)depthStencilTexture.CreateView(new TextureCreateInfo(
|
||||||
|
depthStencilTexture.Info.Width,
|
||||||
|
depthStencilTexture.Info.Height,
|
||||||
|
depthStencilTexture.Info.Depth,
|
||||||
|
depthStencilTexture.Info.Levels,
|
||||||
|
depthStencilTexture.Info.Samples,
|
||||||
|
depthStencilTexture.Info.BlockWidth,
|
||||||
|
depthStencilTexture.Info.BlockHeight,
|
||||||
|
depthStencilTexture.Info.BytesPerPixel,
|
||||||
|
depthStencilTexture.Info.Format,
|
||||||
|
depthStencilMode,
|
||||||
|
depthStencilTexture.Info.Target,
|
||||||
|
SwizzleComponent.Red,
|
||||||
|
SwizzleComponent.Green,
|
||||||
|
SwizzleComponent.Blue,
|
||||||
|
SwizzleComponent.Alpha), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BlitDepthStencilDraw(TextureView src, bool isDepth)
|
||||||
|
{
|
||||||
|
_pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, _samplerNearest);
|
||||||
|
|
||||||
|
if (isDepth)
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programDepthBlit);
|
||||||
|
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pipeline.SetProgram(_programStencilBlit);
|
||||||
|
_pipeline.SetStencilTest(CreateStencilTestDescriptor(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
|
|
||||||
|
if (isDepth)
|
||||||
|
{
|
||||||
|
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pipeline.SetStencilTest(CreateStencilTestDescriptor(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StencilTestDescriptor CreateStencilTestDescriptor(bool enabled)
|
||||||
|
{
|
||||||
|
return new StencilTestDescriptor(
|
||||||
|
enabled,
|
||||||
|
GAL.CompareOp.Always,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
0,
|
||||||
|
0xff,
|
||||||
|
0xff,
|
||||||
|
GAL.CompareOp.Always,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
GAL.StencilOp.Replace,
|
||||||
|
0,
|
||||||
|
0xff,
|
||||||
|
0xff);
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear(
|
public void Clear(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
Auto<DisposableImageView> dst,
|
Auto<DisposableImageView> dst,
|
||||||
|
@ -993,6 +1185,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_programConvertIndirectData.Dispose();
|
_programConvertIndirectData.Dispose();
|
||||||
_programColorCopyToNonMs.Dispose();
|
_programColorCopyToNonMs.Dispose();
|
||||||
_programColorDrawToMs.Dispose();
|
_programColorDrawToMs.Dispose();
|
||||||
|
_programDepthBlit.Dispose();
|
||||||
|
_programStencilBlit?.Dispose();
|
||||||
_samplerNearest.Dispose();
|
_samplerNearest.Dispose();
|
||||||
_samplerLinear.Dispose();
|
_samplerLinear.Dispose();
|
||||||
_pipeline.Dispose();
|
_pipeline.Dispose();
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (binding = 0, set = 2) uniform sampler2D texDepth;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragDepth = texture(texDepth, tex_coord).r;
|
||||||
|
}
|
|
@ -1459,5 +1459,95 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x3B, 0x01, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xE3, 0x00, 0x00, 0x00,
|
0x3B, 0x01, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xE3, 0x00, 0x00, 0x00,
|
||||||
0xF8, 0x00, 0x02, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xF8, 0x00, 0x02, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static readonly byte[] DepthBlitFragmentShaderSource = new byte[]
|
||||||
|
{
|
||||||
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 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, 0x07, 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, 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,
|
||||||
|
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,
|
||||||
|
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, 0x00, 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,
|
||||||
|
0x17, 0x00, 0x04, 0x00, 0x12, 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, 0x57, 0x00, 0x05, 0x00,
|
||||||
|
0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||||
|
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x16, 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,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 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, 0x07, 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, 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, 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, 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, 0x00, 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, 0x13, 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, 0x57, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||||
|
0x0D, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
#extension GL_ARB_shader_stencil_export : require
|
||||||
|
|
||||||
|
layout (binding = 0, set = 2) uniform isampler2D texStencil;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragStencilRefARB = texture(texStencil, tex_coord).r;
|
||||||
|
}
|
|
@ -362,21 +362,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
levels,
|
levels,
|
||||||
linearFilter);
|
linearFilter);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (srcFormat == GAL.Format.D32FloatS8Uint && srcFormat == dstFormat && SupportsBlitFromD32FS8ToD32FAndS8())
|
|
||||||
{
|
|
||||||
BlitDepthStencilWithBuffer(_gd, cbs, src, dst, srcRegion, dstRegion);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 &&
|
src.Info.Target == Target.Texture2D &&
|
||||||
dst.Info.Target == Target.Texture2D &&
|
dst.Info.Target == Target.Texture2D)
|
||||||
!dst.Info.Format.IsDepthOrStencil())
|
|
||||||
{
|
{
|
||||||
_gd.HelperShader.Blit(
|
_gd.HelperShader.Blit(
|
||||||
_gd,
|
_gd,
|
||||||
|
@ -387,6 +382,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
dst.VkFormat,
|
dst.VkFormat,
|
||||||
srcRegion,
|
srcRegion,
|
||||||
dstRegion,
|
dstRegion,
|
||||||
|
isDepthOrStencil,
|
||||||
linearFilter);
|
linearFilter);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -395,7 +391,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Auto<DisposableImage> srcImage;
|
Auto<DisposableImage> srcImage;
|
||||||
Auto<DisposableImage> dstImage;
|
Auto<DisposableImage> dstImage;
|
||||||
|
|
||||||
if (dst.Info.Format.IsDepthOrStencil())
|
if (isDepthOrStencil)
|
||||||
{
|
{
|
||||||
srcImage = src.Storage.CreateAliasedColorForDepthStorageUnsafe(srcFormat).GetImage();
|
srcImage = src.Storage.CreateAliasedColorForDepthStorageUnsafe(srcFormat).GetImage();
|
||||||
dstImage = dst.Storage.CreateAliasedColorForDepthStorageUnsafe(dstFormat).GetImage();
|
dstImage = dst.Storage.CreateAliasedColorForDepthStorageUnsafe(dstFormat).GetImage();
|
||||||
|
@ -426,189 +422,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ImageAspectFlags.ColorBit);
|
ImageAspectFlags.ColorBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void BlitDepthStencilWithBuffer(
|
|
||||||
VulkanRenderer gd,
|
|
||||||
CommandBufferScoped cbs,
|
|
||||||
TextureView src,
|
|
||||||
TextureView dst,
|
|
||||||
Extents2D srcRegion,
|
|
||||||
Extents2D dstRegion)
|
|
||||||
{
|
|
||||||
int drBaseX = Math.Min(dstRegion.X1, dstRegion.X2);
|
|
||||||
int drBaseY = Math.Min(dstRegion.Y1, dstRegion.Y2);
|
|
||||||
int drWidth = Math.Abs(dstRegion.X2 - dstRegion.X1);
|
|
||||||
int drHeight = Math.Abs(dstRegion.Y2 - dstRegion.Y1);
|
|
||||||
|
|
||||||
var drOriginZero = new Extents2D(
|
|
||||||
dstRegion.X1 - drBaseX,
|
|
||||||
dstRegion.Y1 - drBaseY,
|
|
||||||
dstRegion.X2 - drBaseX,
|
|
||||||
dstRegion.Y2 - drBaseY);
|
|
||||||
|
|
||||||
var d32SrcStorageInfo = TextureStorage.NewCreateInfoWith(ref src._info, GAL.Format.D32Float, 4);
|
|
||||||
var d32DstStorageInfo = TextureStorage.NewCreateInfoWith(ref dst._info, GAL.Format.D32Float, 4, drWidth, drHeight);
|
|
||||||
var s8SrcStorageInfo = TextureStorage.NewCreateInfoWith(ref src._info, GAL.Format.S8Uint, 1);
|
|
||||||
var s8DstStorageInfo = TextureStorage.NewCreateInfoWith(ref dst._info, GAL.Format.S8Uint, 1, drWidth, drHeight);
|
|
||||||
|
|
||||||
using var d32SrcStorage = gd.CreateTextureStorage(d32SrcStorageInfo, src.Storage.ScaleFactor);
|
|
||||||
using var d32DstStorage = gd.CreateTextureStorage(d32DstStorageInfo, dst.Storage.ScaleFactor);
|
|
||||||
using var s8SrcStorage = gd.CreateTextureStorage(s8SrcStorageInfo, src.Storage.ScaleFactor);
|
|
||||||
using var s8DstStorage = gd.CreateTextureStorage(s8DstStorageInfo, dst.Storage.ScaleFactor);
|
|
||||||
|
|
||||||
void SlowBlit(TextureStorage srcTemp, TextureStorage dstTemp, ImageAspectFlags aspectFlags)
|
|
||||||
{
|
|
||||||
int levels = Math.Min(src.Info.Levels, dst.Info.Levels);
|
|
||||||
|
|
||||||
int srcSize = 0;
|
|
||||||
int dstSize = 0;
|
|
||||||
|
|
||||||
for (int l = 0; l < levels; l++)
|
|
||||||
{
|
|
||||||
srcSize += srcTemp.Info.GetMipSize2D(l);
|
|
||||||
dstSize += dstTemp.Info.GetMipSize2D(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
using var srcTempBuffer = gd.BufferManager.Create(gd, srcSize, deviceLocal: true);
|
|
||||||
using var dstTempBuffer = gd.BufferManager.Create(gd, dstSize, deviceLocal: true);
|
|
||||||
|
|
||||||
src.Storage.CopyFromOrToBuffer(
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcTempBuffer.GetBuffer().Get(cbs, 0, srcSize).Value,
|
|
||||||
src.GetImage().Get(cbs).Value,
|
|
||||||
srcSize,
|
|
||||||
to: true,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
src.FirstLayer,
|
|
||||||
src.FirstLevel,
|
|
||||||
1,
|
|
||||||
levels,
|
|
||||||
true,
|
|
||||||
aspectFlags,
|
|
||||||
false);
|
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
|
||||||
gd,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcTempBuffer.GetBuffer().Get(cbs, 0, srcSize).Value,
|
|
||||||
AccessFlags.TransferWriteBit,
|
|
||||||
AccessFlags.TransferReadBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
0,
|
|
||||||
srcSize);
|
|
||||||
|
|
||||||
srcTemp.CopyFromOrToBuffer(
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcTempBuffer.GetBuffer().Get(cbs, 0, srcSize).Value,
|
|
||||||
srcTemp.GetImage().Get(cbs).Value,
|
|
||||||
srcSize,
|
|
||||||
to: false,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
levels,
|
|
||||||
true,
|
|
||||||
aspectFlags,
|
|
||||||
false);
|
|
||||||
|
|
||||||
InsertImageBarrier(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcTemp.GetImage().Get(cbs).Value,
|
|
||||||
AccessFlags.TransferWriteBit,
|
|
||||||
AccessFlags.TransferReadBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
aspectFlags,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
levels);
|
|
||||||
|
|
||||||
TextureCopy.Blit(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
srcTemp.GetImage().Get(cbs).Value,
|
|
||||||
dstTemp.GetImage().Get(cbs).Value,
|
|
||||||
srcTemp.Info,
|
|
||||||
dstTemp.Info,
|
|
||||||
srcRegion,
|
|
||||||
drOriginZero,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
levels,
|
|
||||||
false,
|
|
||||||
aspectFlags,
|
|
||||||
aspectFlags);
|
|
||||||
|
|
||||||
InsertImageBarrier(
|
|
||||||
gd.Api,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
dstTemp.GetImage().Get(cbs).Value,
|
|
||||||
AccessFlags.TransferWriteBit,
|
|
||||||
AccessFlags.TransferReadBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
aspectFlags,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
levels);
|
|
||||||
|
|
||||||
dstTemp.CopyFromOrToBuffer(
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
dstTempBuffer.GetBuffer().Get(cbs, 0, dstSize).Value,
|
|
||||||
dstTemp.GetImage().Get(cbs).Value,
|
|
||||||
dstSize,
|
|
||||||
to: true,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
levels,
|
|
||||||
true,
|
|
||||||
aspectFlags,
|
|
||||||
false);
|
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
|
||||||
gd,
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
dstTempBuffer.GetBuffer().Get(cbs, 0, dstSize).Value,
|
|
||||||
AccessFlags.TransferWriteBit,
|
|
||||||
AccessFlags.TransferReadBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
PipelineStageFlags.TransferBit,
|
|
||||||
0,
|
|
||||||
dstSize);
|
|
||||||
|
|
||||||
dst.Storage.CopyFromOrToBuffer(
|
|
||||||
cbs.CommandBuffer,
|
|
||||||
dstTempBuffer.GetBuffer().Get(cbs, 0, dstSize).Value,
|
|
||||||
dst.GetImage().Get(cbs).Value,
|
|
||||||
dstSize,
|
|
||||||
to: false,
|
|
||||||
drBaseX,
|
|
||||||
drBaseY,
|
|
||||||
dst.FirstLayer,
|
|
||||||
dst.FirstLevel,
|
|
||||||
1,
|
|
||||||
levels,
|
|
||||||
true,
|
|
||||||
aspectFlags,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SlowBlit(d32SrcStorage, d32DstStorage, ImageAspectFlags.DepthBit);
|
|
||||||
SlowBlit(s8SrcStorage, s8DstStorage, ImageAspectFlags.StencilBit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void InsertImageBarrier(
|
public static unsafe void InsertImageBarrier(
|
||||||
Vk api,
|
Vk api,
|
||||||
CommandBuffer commandBuffer,
|
CommandBuffer commandBuffer,
|
||||||
|
@ -649,13 +462,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
memoryBarrier);
|
memoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SupportsBlitFromD32FS8ToD32FAndS8()
|
|
||||||
{
|
|
||||||
var formatFeatureFlags = FormatFeatureFlags.BlitSrcBit | FormatFeatureFlags.BlitDstBit;
|
|
||||||
return _gd.FormatCapabilities.OptimalFormatSupports(formatFeatureFlags, GAL.Format.D32Float) &&
|
|
||||||
_gd.FormatCapabilities.OptimalFormatSupports(formatFeatureFlags, GAL.Format.S8Uint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextureView GetView(GAL.Format format)
|
public TextureView GetView(GAL.Format format)
|
||||||
{
|
{
|
||||||
if (format == Info.Format)
|
if (format == Info.Format)
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
"VK_EXT_fragment_shader_interlock",
|
"VK_EXT_fragment_shader_interlock",
|
||||||
"VK_EXT_index_type_uint8",
|
"VK_EXT_index_type_uint8",
|
||||||
"VK_EXT_robustness2",
|
"VK_EXT_robustness2",
|
||||||
|
"VK_EXT_shader_stencil_export",
|
||||||
"VK_KHR_shader_float16_int8",
|
"VK_KHR_shader_float16_int8",
|
||||||
"VK_EXT_shader_subgroup_ballot",
|
"VK_EXT_shader_subgroup_ballot",
|
||||||
"VK_EXT_subgroup_size_control",
|
"VK_EXT_subgroup_size_control",
|
||||||
|
|
|
@ -263,6 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
|
supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
|
||||||
supportedExtensions.Contains("VK_EXT_subgroup_size_control"),
|
supportedExtensions.Contains("VK_EXT_subgroup_size_control"),
|
||||||
featuresShaderInt8.ShaderInt8,
|
featuresShaderInt8.ShaderInt8,
|
||||||
|
supportedExtensions.Contains("VK_EXT_shader_stencil_export"),
|
||||||
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
|
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
|
||||||
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
||||||
features2.Features.MultiViewport,
|
features2.Features.MultiViewport,
|
||||||
|
|
|
@ -335,7 +335,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY;
|
int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY;
|
||||||
int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY;
|
int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY;
|
||||||
|
|
||||||
_gd.HelperShader.Blit(
|
_gd.HelperShader.BlitColor(
|
||||||
_gd,
|
_gd,
|
||||||
cbs,
|
cbs,
|
||||||
view,
|
view,
|
||||||
|
|
Loading…
Reference in a new issue