diff --git a/Ryujinx.Graphics.Vulkan/PipelineConverter.cs b/Ryujinx.Graphics.Vulkan/PipelineConverter.cs index 26d34e54..5c9193fa 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineConverter.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineConverter.cs @@ -27,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan int attachmentCount = 0; int colorCount = 0; + int maxColorAttachmentIndex = -1; for (int i = 0; i < state.AttachmentEnable.Length; i++) { @@ -36,6 +37,7 @@ namespace Ryujinx.Graphics.Vulkan attachmentIndices[attachmentCount++] = i; colorCount++; + maxColorAttachmentIndex = i; } } @@ -73,12 +75,11 @@ namespace Ryujinx.Graphics.Vulkan if (colorAttachmentsCount != 0) { - int maxAttachmentIndex = Constants.MaxRenderTargets - 1; - subpass.ColorAttachmentCount = (uint)maxAttachmentIndex + 1; + subpass.ColorAttachmentCount = (uint)maxColorAttachmentIndex + 1; subpass.PColorAttachments = &attachmentReferences[0]; // Fill with VK_ATTACHMENT_UNUSED to cover any gaps. - for (int i = 0; i <= maxAttachmentIndex; i++) + for (int i = 0; i <= maxColorAttachmentIndex; i++) { subpass.PColorAttachments[i] = new AttachmentReference(Vk.AttachmentUnused, ImageLayout.Undefined); } diff --git a/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/Ryujinx.Graphics.Vulkan/PipelineFull.cs index 94fd2441..d8e8cdfb 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineFull.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineFull.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan { private const ulong MinByteWeightForFlush = 256 * 1024 * 1024; // MiB - private readonly List _activeQueries; + private readonly List<(QueryPool, bool)> _activeQueries; private CounterQueueEvent _activeConditionalRender; private readonly List _pendingQueryCopies; @@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vulkan public PipelineFull(VulkanRenderer gd, Device device) : base(gd, device) { - _activeQueries = new List(); + _activeQueries = new List<(QueryPool, bool)>(); _pendingQueryCopies = new(); CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer; @@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Vulkan AutoFlush.RegisterFlush(DrawCount); EndRenderPass(); - foreach (var queryPool in _activeQueries) + foreach ((var queryPool, _) in _activeQueries) { Gd.Api.CmdEndQuery(CommandBuffer, queryPool, 0); } @@ -220,10 +220,12 @@ namespace Ryujinx.Graphics.Vulkan // Restore per-command buffer state. - foreach (var queryPool in _activeQueries) + foreach ((var queryPool, var isOcclusion) in _activeQueries) { + bool isPrecise = Gd.Capabilities.SupportsPreciseOcclusionQueries && isOcclusion; + Gd.Api.CmdResetQueryPool(CommandBuffer, queryPool, 0, 1); - Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, Gd.Capabilities.SupportsPreciseOcclusionQueries ? QueryControlFlags.PreciseBit : 0); + Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, isPrecise ? QueryControlFlags.PreciseBit : 0); } Gd.ResetCounterPool(); @@ -231,7 +233,7 @@ namespace Ryujinx.Graphics.Vulkan Restore(); } - public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset, bool fromSamplePool) + public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset, bool isOcclusion, bool fromSamplePool) { if (needsReset) { @@ -247,16 +249,24 @@ namespace Ryujinx.Graphics.Vulkan } } - Gd.Api.CmdBeginQuery(CommandBuffer, pool, 0, Gd.Capabilities.SupportsPreciseOcclusionQueries ? QueryControlFlags.PreciseBit : 0); + bool isPrecise = Gd.Capabilities.SupportsPreciseOcclusionQueries && isOcclusion; + Gd.Api.CmdBeginQuery(CommandBuffer, pool, 0, isPrecise ? QueryControlFlags.PreciseBit : 0); - _activeQueries.Add(pool); + _activeQueries.Add((pool, isOcclusion)); } public void EndQuery(QueryPool pool) { Gd.Api.CmdEndQuery(CommandBuffer, pool, 0); - _activeQueries.Remove(pool); + for (int i = 0; i < _activeQueries.Count; i++) + { + if (_activeQueries[i].Item1.Handle == pool.Handle) + { + _activeQueries.RemoveAt(i); + break; + } + } } public void CopyQueryResults(BufferedQuery query) diff --git a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs index abb43eb5..29efd8e7 100644 --- a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs +++ b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs @@ -100,7 +100,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries if (_isSupported) { bool needsReset = resetSequence == null || _resetSequence == null || resetSequence.Value != _resetSequence.Value; - _pipeline.BeginQuery(this, _queryPool, needsReset, _type == CounterType.SamplesPassed && resetSequence != null); + bool isOcclusion = _type == CounterType.SamplesPassed; + _pipeline.BeginQuery(this, _queryPool, needsReset, isOcclusion, isOcclusion && resetSequence != null); } _resetSequence = null; } diff --git a/Ryujinx.Graphics.Vulkan/TextureView.cs b/Ryujinx.Graphics.Vulkan/TextureView.cs index e58b743d..d60ce39b 100644 --- a/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan var componentMapping = new ComponentMapping(swizzleR, swizzleG, swizzleB, swizzleA); var aspectFlags = info.Format.ConvertAspectFlags(info.DepthStencilMode); - var aspectFlagsDepth = info.Format.ConvertAspectFlags(DepthStencilMode.Depth); + var aspectFlagsDepth = info.Format.ConvertAspectFlags(); var subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, layers); var subresourceRangeDepth = new ImageSubresourceRange(aspectFlagsDepth, (uint)firstLevel, levels, (uint)firstLayer, layers);