Compare commits

...

4 commits

Author SHA1 Message Date
Keaton
5d005b5785 Merge branch 'feature/vulkan-index-buff-compute' into 'master'
Vulkan: Use compute shader for non-indirect unsupported topology index buffer conversions

See merge request ryubing/ryujinx!15
2025-03-29 20:31:11 -05:00
Yeager
5d8451b41a Update Swedish in locales.json 2025-03-29 20:22:23 -05:00
Isaac Marovitz
6b51cd01a9 Fix >16 primitives 2025-03-27 18:23:15 -05:00
Isaac Marovitz
c32e8e1a57 Use compute shader for non indirect index buffer conversion 2025-03-27 18:23:15 -05:00
3 changed files with 37 additions and 71 deletions

View file

@ -874,57 +874,42 @@ namespace Ryujinx.Graphics.Vulkan
public unsafe void ConvertIndexBuffer(VulkanRenderer gd,
CommandBufferScoped cbs,
BufferHolder src,
BufferHolder dst,
BufferHolder srcIndexBuffer,
BufferHolder dstIndexBuffer,
IndexBufferPattern pattern,
int indexSize,
int srcOffset,
int indexCount)
{
// TODO: Support conversion with primitive restart enabled.
// TODO: Convert with a compute shader?
int primitiveCount = pattern.GetPrimitiveCount(indexCount);
int convertedCount = pattern.GetConvertedCount(indexCount);
int outputIndexSize = 4;
Buffer dstBuffer = dstIndexBuffer.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
Buffer srcBuffer = src.GetBuffer().Get(cbs, srcOffset, indexCount * indexSize).Value;
Buffer dstBuffer = dst.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
const int ParamsBufferSize = 16 * sizeof(int);
gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0);
Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)];
List<BufferCopy> bufferCopy = [];
int outputOffset = 0;
shaderParams[8] = pattern.PrimitiveVertices;
shaderParams[9] = pattern.PrimitiveVerticesOut;
shaderParams[10] = indexSize;
shaderParams[11] = outputIndexSize;
shaderParams[12] = pattern.BaseIndex;
shaderParams[13] = pattern.IndexStride;
shaderParams[14] = srcOffset;
shaderParams[15] = primitiveCount;
// Try to merge copies of adjacent indices to reduce copy count.
int sequenceStart = 0;
int sequenceLength = 0;
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
foreach (int index in pattern.GetIndexMapping(indexCount))
{
if (sequenceLength > 0)
{
if (index == sequenceStart + sequenceLength && indexSize == outputIndexSize)
{
sequenceLength++;
continue;
}
using var patternScoped = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
var patternBuffer = patternScoped.Holder;
// Commit the copy so far.
bufferCopy.Add(new BufferCopy((ulong)(srcOffset + sequenceStart * indexSize), (ulong)outputOffset, (ulong)(indexSize * sequenceLength)));
outputOffset += outputIndexSize * sequenceLength;
}
patternBuffer.SetDataUnchecked<int>(patternScoped.Offset, shaderParams);
sequenceStart = index;
sequenceLength = 1;
}
if (sequenceLength > 0)
{
// Commit final pending copy.
bufferCopy.Add(new BufferCopy((ulong)(srcOffset + sequenceStart * indexSize), (ulong)outputOffset, (ulong)(indexSize * sequenceLength)));
}
BufferCopy[] bufferCopyArray = bufferCopy.ToArray();
_pipeline.SetCommandBuffer(cbs);
BufferHolder.InsertBufferBarrier(
gd,
@ -937,10 +922,11 @@ namespace Ryujinx.Graphics.Vulkan
0,
convertedCount * outputIndexSize);
fixed (BufferCopy* pBufferCopy = bufferCopyArray)
{
gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, (uint)bufferCopyArray.Length, pBufferCopy);
}
_pipeline.SetUniformBuffers([new BufferAssignment(0, new BufferRange(patternScoped.Handle, patternScoped.Offset, ParamsBufferSize))]);
_pipeline.SetStorageBuffers(1, new[] { srcIndexBuffer.GetBuffer(), dstIndexBuffer.GetBuffer() });
_pipeline.SetProgram(_programConvertIndexBuffer);
_pipeline.DispatchCompute(BitUtils.DivRoundUp(primitiveCount, 16), 1, 1);
BufferHolder.InsertBufferBarrier(
gd,
@ -952,6 +938,8 @@ namespace Ryujinx.Graphics.Vulkan
PipelineStageFlags.AllCommandsBit,
0,
convertedCount * outputIndexSize);
_pipeline.Finish(gd, cbs);
}
public void CopyIncompatibleFormats(

View file

@ -47,28 +47,6 @@ namespace Ryujinx.Graphics.Vulkan
return primitiveCount * OffsetIndex.Length;
}
public IEnumerable<int> GetIndexMapping(int indexCount)
{
int primitiveCount = GetPrimitiveCount(indexCount);
int index = BaseIndex;
for (int i = 0; i < primitiveCount; i++)
{
if (RepeatStart)
{
// Used for triangle fan
yield return 0;
}
for (int j = RepeatStart ? 1 : 0; j < OffsetIndex.Length; j++)
{
yield return index + OffsetIndex[j];
}
index += IndexStride;
}
}
public BufferHandle GetRepeatingBuffer(int vertexCount, out int indexCount)
{
int primitiveCount = GetPrimitiveCount(vertexCount);

View file

@ -4939,7 +4939,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Multiplikator för turboläge:",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -4964,7 +4964,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Målvärdet för multiplikatorn i turboläget. \n\nLämna den på 200 om du är osäker.",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -4989,7 +4989,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Turboläget är en emulatorfunktion som effektivt ökar eller sänker hastigheten när ett spel inte är känsligt för bildfrekvens.\nDu kan växla denna funktion i spelet med en snabbtangent, konfigurerbar i Ryujinx inställningar för snabbtangenter.\n\nLämna den på 200 om du är osäker.",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -10014,7 +10014,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Enter (блок цифр)",
"sv_SE": "",
"sv_SE": "Enter (numerisk)",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Enter (цифровий блок)",
@ -11064,7 +11064,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Тачпад",
"sv_SE": "",
"sv_SE": "Pekplatta",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Сенсорна панель",
@ -18189,7 +18189,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "{0} bilder/s ({1}ms)",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -18214,7 +18214,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "{0} bilder/s ({1}ms), Turbo ({2}%)",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -23964,7 +23964,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Turboläge:",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -23989,7 +23989,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Snabbtangenten för turboläge.\nKonfigurera beteendet för turboläge i Ryujinx CPU-inställningar.\n\nLämna Obunden om du är osäker.",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@ -24014,7 +24014,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Endast när du trycker ner",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",