mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-21 16:43:35 +00:00
Use SupportBufferUpdater, add single layer flush
This commit is contained in:
parent
db5ac3488a
commit
d14dbb0cff
5 changed files with 64 additions and 36 deletions
|
@ -320,7 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
Offset = 0,
|
||||
Range = (ulong)SupportBuffer.RequiredSize,
|
||||
Buffer = _pipeline.RenderScaleBuffer.GetBuffer().Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
||||
};
|
||||
|
||||
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||
|
|
|
@ -65,6 +65,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
return flushStorage.GetDataStorage(0, size);
|
||||
}
|
||||
|
||||
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size, int layer, int level)
|
||||
{
|
||||
var flushStorage = ResizeIfNeeded(size);
|
||||
|
||||
using (var cbs = cbp.Rent())
|
||||
{
|
||||
var buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
||||
var image = view.GetImage().Get(cbs).Value;
|
||||
|
||||
view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
|
||||
}
|
||||
|
||||
flushStorage.WaitForFences();
|
||||
return flushStorage.GetDataStorage(0, size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_flushStorage.Dispose();
|
||||
|
|
|
@ -41,16 +41,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
private ShaderCollection _program;
|
||||
|
||||
private struct Vector4<T>
|
||||
{
|
||||
public T X;
|
||||
public T Y;
|
||||
public T Z;
|
||||
public T W;
|
||||
}
|
||||
|
||||
private Vector4<float>[] _renderScale = new Vector4<float>[65];
|
||||
private Vector4<float>[] _cpRenderScale = new Vector4<float>[64];
|
||||
private int _fragmentScaleCount;
|
||||
|
||||
protected FramebufferParams FramebufferParams;
|
||||
private Auto<DisposableFramebuffer> _framebuffer;
|
||||
|
@ -63,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
private readonly BufferState[] _transformFeedbackBuffers;
|
||||
private readonly BufferState[] _vertexBuffers;
|
||||
|
||||
public BufferHolder RenderScaleBuffer { get; }
|
||||
public SupportBufferUpdater SupportBufferUpdater;
|
||||
|
||||
private bool _needsIndexBufferRebind;
|
||||
private bool _needsTransformFeedbackBuffersRebind;
|
||||
|
@ -100,9 +92,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
||||
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
||||
|
||||
RenderScaleBuffer = gd.BufferManager.Create(gd, SupportBuffer.RequiredSize);
|
||||
|
||||
SetSupportBufferDataCpu<Vector4<float>>(SupportBuffer.GraphicsRenderScaleOffset, _renderScale, SupportBuffer.RenderScaleMaxCount);
|
||||
SupportBufferUpdater = new SupportBufferUpdater(gd);
|
||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount);
|
||||
|
||||
_newState.Initialize();
|
||||
_newState.LineWidth = 1f;
|
||||
|
@ -295,6 +286,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
if (texture is TextureView srcTexture)
|
||||
{
|
||||
SupportBufferUpdater.Commit();
|
||||
|
||||
var oldCullMode = _newState.CullMode;
|
||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||
|
@ -622,7 +615,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
public void SetRenderTargetScale(float scale)
|
||||
{
|
||||
_renderScale[0].X = scale;
|
||||
SetSupportBufferData<Vector4<float>>(SupportBuffer.GraphicsRenderScaleOffset, _renderScale, 1); // Just the first element.
|
||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1); // Just the first element.
|
||||
}
|
||||
|
||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
||||
|
@ -875,11 +868,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
TextureBarrier();
|
||||
}
|
||||
|
||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int textureCount, int imageCount)
|
||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for (int index = 0; index < textureCount + imageCount; index++)
|
||||
for (int index = 0; index < totalCount; index++)
|
||||
{
|
||||
if (_renderScale[1 + index].X != scales[index])
|
||||
{
|
||||
|
@ -888,22 +881,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
}
|
||||
}
|
||||
|
||||
// Only update fragment count if there are scales after it for the vertex stage.
|
||||
if (fragmentCount != totalCount && fragmentCount != _fragmentScaleCount)
|
||||
{
|
||||
_fragmentScaleCount = fragmentCount;
|
||||
SupportBufferUpdater.UpdateFragmentRenderScaleCount(_fragmentScaleCount);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
SetSupportBufferData<Vector4<float>>(SupportBuffer.GraphicsRenderScaleOffset, _renderScale, 1 + textureCount + imageCount);
|
||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1 + totalCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetSupportBufferData<T>(int offset, ReadOnlySpan<T> data, int count) where T : unmanaged
|
||||
{
|
||||
RenderScaleBuffer.SetDataInline(Cbs, EndRenderPass, offset, MemoryMarshal.Cast<T, byte>(data.Slice(0, count)));
|
||||
}
|
||||
|
||||
private void SetSupportBufferDataCpu<T>(int offset, ReadOnlySpan<T> data, int count) where T : unmanaged
|
||||
{
|
||||
RenderScaleBuffer.SetDataUnchecked(offset, MemoryMarshal.Cast<T, byte>(data.Slice(0, count)));
|
||||
}
|
||||
|
||||
protected void SignalCommandBufferChange()
|
||||
{
|
||||
_needsIndexBufferRebind = true;
|
||||
|
@ -1052,6 +1042,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
// Take the opportunity to process any pending work requested by other threads.
|
||||
_dynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
|
||||
|
||||
// Commit changes to the support buffer before drawing.
|
||||
SupportBufferUpdater.Commit();
|
||||
|
||||
if (_stateDirty || Pbp != pbp)
|
||||
{
|
||||
CreatePipeline(pbp);
|
||||
|
@ -1203,7 +1196,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
Gd.Api.DestroyPipelineCache(Device, _pipelineCache, null);
|
||||
}
|
||||
|
||||
RenderScaleBuffer.Dispose();
|
||||
SupportBufferUpdater.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
Binding = 0,
|
||||
DescriptorType = DescriptorType.UniformBuffer,
|
||||
DescriptorCount = 1,
|
||||
StageFlags = ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
|
||||
StageFlags = ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
|
||||
};
|
||||
|
||||
int iter = 0;
|
||||
|
|
|
@ -679,7 +679,18 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public ReadOnlySpan<byte> GetData(int layer, int level)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
BackgroundResource resources = _gd.BackgroundResources.Get();
|
||||
|
||||
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
|
||||
return GetData(_gd.CommandBufferPool, resources.GetFlushBuffer(), layer, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level);
|
||||
}
|
||||
}
|
||||
|
||||
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)
|
||||
|
@ -697,6 +708,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
return GetDataFromBuffer(result, size, result);
|
||||
}
|
||||
|
||||
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer, int layer, int level)
|
||||
{
|
||||
int size = GetBufferDataLength(Info.GetMipSize(level));
|
||||
|
||||
Span<byte> result = flushBuffer.GetTextureData(cbp, this, size, layer, level);
|
||||
return GetDataFromBuffer(result, size, result);
|
||||
}
|
||||
|
||||
public void SetData(ReadOnlySpan<byte> data)
|
||||
{
|
||||
SetData(data, 0, 0, Info.GetLayers(), Info.Levels, singleSlice: false);
|
||||
|
@ -799,9 +818,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
bool singleSlice)
|
||||
{
|
||||
bool is3D = Info.Target == Target.Texture3D;
|
||||
int width = Info.Width;
|
||||
int height = Info.Height;
|
||||
int depth = is3D && !singleSlice ? Info.Depth : 1;
|
||||
int width = Math.Max(1, Info.Width >> dstLevel);
|
||||
int height = Math.Max(1, Info.Height >> dstLevel);
|
||||
int depth = is3D && !singleSlice ? Math.Max(1, Info.Depth >> dstLevel) : 1;
|
||||
int layer = is3D ? 0 : dstLayer;
|
||||
int layers = dstLayers;
|
||||
int levels = dstLevels;
|
||||
|
@ -810,7 +829,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
for (int level = 0; level < levels; level++)
|
||||
{
|
||||
int mipSize = GetBufferDataLength(Info.GetMipSize(level));
|
||||
int mipSize = GetBufferDataLength(Info.GetMipSize(dstLevel + level));
|
||||
|
||||
int endOffset = offset + mipSize;
|
||||
|
||||
|
@ -819,7 +838,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
break;
|
||||
}
|
||||
|
||||
int rowLength = (Info.GetMipStride(level) / Info.BytesPerPixel) * Info.BlockWidth;
|
||||
int rowLength = (Info.GetMipStride(dstLevel + level) / Info.BytesPerPixel) * Info.BlockWidth;
|
||||
|
||||
var aspectFlags = Info.Format.ConvertAspectFlags();
|
||||
|
||||
|
|
Loading…
Reference in a new issue