[Vk] Keep one depth attachment layout for draws that do not sample it
The depth attachment layout followed each draw's depth/stencil write mask, so a draw sequence that toggles depth writes — opaque geometry, then decals and translucency — changed the layout every few draws, and every layout change ended the rendering scope. The read-only attachment layouts are only required when the draw also samples the attachment. Every other draw now uses the writable layout for the aspects the format has, and the write mask alone selects the access, so the layout stays constant and the scope survives. The presenter answers whether a texture bound for the draw being prepared views the depth attachment's subresources, defaulting to yes for hosts that do not track it.
This commit is contained in:
parent
ff3221c770
commit
4e536b18d9
|
|
@ -63,6 +63,19 @@ public readonly record struct DepthStencilState(
|
|||
|
||||
public bool IsReadOnly(Format format) => AttachmentWriteAspects(format) == ImageAspectFlags.None;
|
||||
|
||||
// The layout for an attachment the draw does not also sample: writable in every aspect the
|
||||
// format has, so draws that toggle depth or stencil writes keep one layout (and one rendering
|
||||
// scope). Only a sampled attachment needs the read-only layouts of AttachmentLayout.
|
||||
public static ImageLayout WritableAttachmentLayout(Format format)
|
||||
{
|
||||
var available = ViewFormatRules.DepthAspects(format);
|
||||
var hasDepth = (available & ImageAspectFlags.DepthBit) != 0;
|
||||
var hasStencil = (available & ImageAspectFlags.StencilBit) != 0;
|
||||
return hasDepth && hasStencil ? ImageLayout.DepthStencilAttachmentOptimal
|
||||
: hasStencil ? ImageLayout.StencilAttachmentOptimal
|
||||
: ImageLayout.DepthAttachmentOptimal;
|
||||
}
|
||||
|
||||
public ImageLayout AttachmentLayout(Format format)
|
||||
{
|
||||
var available = ViewFormatRules.DepthAspects(format);
|
||||
|
|
|
|||
|
|
@ -137,6 +137,9 @@ public interface IRenderHost
|
|||
|
||||
void EndRendering();
|
||||
|
||||
// Whether a texture bound for the draw being prepared reads the depth attachment's subresources.
|
||||
bool SamplesDepthAttachment(in DepthAttachmentState depth) => true;
|
||||
|
||||
// The next draw stores to buffers or storage images; called before its BeginRendering.
|
||||
void PrepareMemoryWritingDraw() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -251,7 +251,9 @@ public sealed partial class RenderExecutor
|
|||
}
|
||||
|
||||
var loadState = depth.LoadState;
|
||||
var layout = loadState.AttachmentLayout(target.Format);
|
||||
var layout = _host.SamplesDepthAttachment(in depth)
|
||||
? loadState.AttachmentLayout(target.Format)
|
||||
: DepthStencilState.WritableAttachmentLayout(target.Format);
|
||||
_host.TransitionDepthAttachment(in depth, layout, loadState.AttachmentWriteAspects(target.Format));
|
||||
var view = target.Request.View;
|
||||
rendering.Width = Math.Min(rendering.Width, target.Width);
|
||||
|
|
|
|||
|
|
@ -400,6 +400,28 @@ internal static unsafe partial class VulkanVideoPresenter
|
|||
BindBuffers(stage);
|
||||
ObtainDeviceAddressRanges(stage);
|
||||
BindImages(stage);
|
||||
_preparedTextures.Add(stage.Textures);
|
||||
}
|
||||
|
||||
// Textures bound for the draw being prepared; cleared when its preparation closes.
|
||||
private readonly List<TextureResource[]> _preparedTextures = new();
|
||||
|
||||
bool IRenderHost.SamplesDepthAttachment(in DepthAttachmentState depth)
|
||||
{
|
||||
var image = _imageCache.GetImage(depth.Image);
|
||||
var attachmentView = depth.Target.Target.Request.View;
|
||||
foreach (var textures in _preparedTextures)
|
||||
{
|
||||
foreach (var texture in textures)
|
||||
{
|
||||
if (!texture.IsHostMovie && ReferenceEquals(texture.CachedImage, image) && ViewsOverlap(texture.Request.View, attachmentView))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private BufferView NullStorageBuffer() => new(_bufferCache.GetBuffer(GuestBufferCache.NullBufferId).Handle, 0, NullStorageBufferBytes);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ internal static unsafe partial class VulkanVideoPresenter
|
|||
}
|
||||
|
||||
owner._preparation = null;
|
||||
owner._preparedTextures.Clear();
|
||||
streamRetention.Dispose();
|
||||
if (StencilStorageImages is { } stencilImages)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue