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,
|
Offset = 0,
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
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);
|
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||||
|
|
|
@ -65,6 +65,22 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return flushStorage.GetDataStorage(0, size);
|
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()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_flushStorage.Dispose();
|
_flushStorage.Dispose();
|
||||||
|
|
|
@ -41,16 +41,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private ShaderCollection _program;
|
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>[] _renderScale = new Vector4<float>[65];
|
||||||
private Vector4<float>[] _cpRenderScale = new Vector4<float>[64];
|
private int _fragmentScaleCount;
|
||||||
|
|
||||||
protected FramebufferParams FramebufferParams;
|
protected FramebufferParams FramebufferParams;
|
||||||
private Auto<DisposableFramebuffer> _framebuffer;
|
private Auto<DisposableFramebuffer> _framebuffer;
|
||||||
|
@ -63,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly BufferState[] _transformFeedbackBuffers;
|
private readonly BufferState[] _transformFeedbackBuffers;
|
||||||
private readonly BufferState[] _vertexBuffers;
|
private readonly BufferState[] _vertexBuffers;
|
||||||
|
|
||||||
public BufferHolder RenderScaleBuffer { get; }
|
public SupportBufferUpdater SupportBufferUpdater;
|
||||||
|
|
||||||
private bool _needsIndexBufferRebind;
|
private bool _needsIndexBufferRebind;
|
||||||
private bool _needsTransformFeedbackBuffersRebind;
|
private bool _needsTransformFeedbackBuffersRebind;
|
||||||
|
@ -100,9 +92,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
||||||
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
||||||
|
|
||||||
RenderScaleBuffer = gd.BufferManager.Create(gd, SupportBuffer.RequiredSize);
|
SupportBufferUpdater = new SupportBufferUpdater(gd);
|
||||||
|
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount);
|
||||||
SetSupportBufferDataCpu<Vector4<float>>(SupportBuffer.GraphicsRenderScaleOffset, _renderScale, SupportBuffer.RenderScaleMaxCount);
|
|
||||||
|
|
||||||
_newState.Initialize();
|
_newState.Initialize();
|
||||||
_newState.LineWidth = 1f;
|
_newState.LineWidth = 1f;
|
||||||
|
@ -295,6 +286,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
if (texture is TextureView srcTexture)
|
if (texture is TextureView srcTexture)
|
||||||
{
|
{
|
||||||
|
SupportBufferUpdater.Commit();
|
||||||
|
|
||||||
var oldCullMode = _newState.CullMode;
|
var oldCullMode = _newState.CullMode;
|
||||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||||
|
@ -622,7 +615,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public void SetRenderTargetScale(float scale)
|
public void SetRenderTargetScale(float scale)
|
||||||
{
|
{
|
||||||
_renderScale[0].X = 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)
|
public void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
||||||
|
@ -875,11 +868,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
TextureBarrier();
|
TextureBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int textureCount, int imageCount)
|
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
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])
|
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)
|
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()
|
protected void SignalCommandBufferChange()
|
||||||
{
|
{
|
||||||
_needsIndexBufferRebind = true;
|
_needsIndexBufferRebind = true;
|
||||||
|
@ -1052,6 +1042,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// Take the opportunity to process any pending work requested by other threads.
|
// Take the opportunity to process any pending work requested by other threads.
|
||||||
_dynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
|
_dynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
|
||||||
|
|
||||||
|
// Commit changes to the support buffer before drawing.
|
||||||
|
SupportBufferUpdater.Commit();
|
||||||
|
|
||||||
if (_stateDirty || Pbp != pbp)
|
if (_stateDirty || Pbp != pbp)
|
||||||
{
|
{
|
||||||
CreatePipeline(pbp);
|
CreatePipeline(pbp);
|
||||||
|
@ -1203,7 +1196,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Gd.Api.DestroyPipelineCache(Device, _pipelineCache, null);
|
Gd.Api.DestroyPipelineCache(Device, _pipelineCache, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderScaleBuffer.Dispose();
|
SupportBufferUpdater.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Binding = 0,
|
Binding = 0,
|
||||||
DescriptorType = DescriptorType.UniformBuffer,
|
DescriptorType = DescriptorType.UniformBuffer,
|
||||||
DescriptorCount = 1,
|
DescriptorCount = 1,
|
||||||
StageFlags = ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
|
StageFlags = ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
|
||||||
};
|
};
|
||||||
|
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
|
|
|
@ -679,7 +679,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public ReadOnlySpan<byte> GetData(int layer, int level)
|
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)
|
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)
|
||||||
|
@ -697,6 +708,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return GetDataFromBuffer(result, size, result);
|
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)
|
public void SetData(ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
SetData(data, 0, 0, Info.GetLayers(), Info.Levels, singleSlice: false);
|
SetData(data, 0, 0, Info.GetLayers(), Info.Levels, singleSlice: false);
|
||||||
|
@ -799,9 +818,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bool singleSlice)
|
bool singleSlice)
|
||||||
{
|
{
|
||||||
bool is3D = Info.Target == Target.Texture3D;
|
bool is3D = Info.Target == Target.Texture3D;
|
||||||
int width = Info.Width;
|
int width = Math.Max(1, Info.Width >> dstLevel);
|
||||||
int height = Info.Height;
|
int height = Math.Max(1, Info.Height >> dstLevel);
|
||||||
int depth = is3D && !singleSlice ? Info.Depth : 1;
|
int depth = is3D && !singleSlice ? Math.Max(1, Info.Depth >> dstLevel) : 1;
|
||||||
int layer = is3D ? 0 : dstLayer;
|
int layer = is3D ? 0 : dstLayer;
|
||||||
int layers = dstLayers;
|
int layers = dstLayers;
|
||||||
int levels = dstLevels;
|
int levels = dstLevels;
|
||||||
|
@ -810,7 +829,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
for (int level = 0; level < levels; level++)
|
for (int level = 0; level < levels; level++)
|
||||||
{
|
{
|
||||||
int mipSize = GetBufferDataLength(Info.GetMipSize(level));
|
int mipSize = GetBufferDataLength(Info.GetMipSize(dstLevel + level));
|
||||||
|
|
||||||
int endOffset = offset + mipSize;
|
int endOffset = offset + mipSize;
|
||||||
|
|
||||||
|
@ -819,7 +838,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
break;
|
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();
|
var aspectFlags = Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue