Vulkan: Partially workaround MoltenVK InvalidResource error (#4880)
* Add MVK stage flags workaround * Actually do the workaround * Remove GS on VS stuff * Address feedback
This commit is contained in:
parent
95c06de4c1
commit
5fda543f84
1 changed files with 28 additions and 1 deletions
|
@ -12,6 +12,28 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ShaderStageFlags.FragmentBit |
|
ShaderStageFlags.FragmentBit |
|
||||||
ShaderStageFlags.ComputeBit;
|
ShaderStageFlags.ComputeBit;
|
||||||
|
|
||||||
|
private static ShaderStageFlags ActiveStages(uint stages)
|
||||||
|
{
|
||||||
|
ShaderStageFlags stageFlags = 0;
|
||||||
|
|
||||||
|
while (stages != 0)
|
||||||
|
{
|
||||||
|
int stage = BitOperations.TrailingZeroCount(stages);
|
||||||
|
stages &= ~(1u << stage);
|
||||||
|
|
||||||
|
stageFlags |= stage switch
|
||||||
|
{
|
||||||
|
1 => ShaderStageFlags.FragmentBit,
|
||||||
|
2 => ShaderStageFlags.GeometryBit,
|
||||||
|
3 => ShaderStageFlags.TessellationControlBit,
|
||||||
|
4 => ShaderStageFlags.TessellationEvaluationBit,
|
||||||
|
_ => ShaderStageFlags.VertexBit | ShaderStageFlags.ComputeBit
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return stageFlags;
|
||||||
|
}
|
||||||
|
|
||||||
public static unsafe DescriptorSetLayout[] Create(VulkanRenderer gd, Device device, uint stages, bool usePd, out PipelineLayout layout)
|
public static unsafe DescriptorSetLayout[] Create(VulkanRenderer gd, Device device, uint stages, bool usePd, out PipelineLayout layout)
|
||||||
{
|
{
|
||||||
int stagesCount = BitOperations.PopCount(stages);
|
int stagesCount = BitOperations.PopCount(stages);
|
||||||
|
@ -34,6 +56,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
};
|
};
|
||||||
|
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
|
var activeStages = ActiveStages(stages);
|
||||||
|
|
||||||
while (stages != 0)
|
while (stages != 0)
|
||||||
{
|
{
|
||||||
|
@ -67,12 +90,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
void SetStorage(DescriptorSetLayoutBinding* bindings, int maxPerStage, int start = 0)
|
void SetStorage(DescriptorSetLayoutBinding* bindings, int maxPerStage, int start = 0)
|
||||||
{
|
{
|
||||||
|
// There's a bug on MoltenVK where using the same buffer across different stages
|
||||||
|
// causes invalid resource errors, allow the binding on all active stages as workaround.
|
||||||
|
var flags = gd.IsMoltenVk ? activeStages : stageFlags;
|
||||||
|
|
||||||
bindings[start + iter] = new DescriptorSetLayoutBinding
|
bindings[start + iter] = new DescriptorSetLayoutBinding
|
||||||
{
|
{
|
||||||
Binding = (uint)(start + stage * maxPerStage),
|
Binding = (uint)(start + stage * maxPerStage),
|
||||||
DescriptorType = DescriptorType.StorageBuffer,
|
DescriptorType = DescriptorType.StorageBuffer,
|
||||||
DescriptorCount = (uint)maxPerStage,
|
DescriptorCount = (uint)maxPerStage,
|
||||||
StageFlags = stageFlags
|
StageFlags = flags
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue