Image binding support
Kirby still has a problem with NaN 3D Texture
This commit is contained in:
parent
4e5cf38009
commit
650f309b58
4 changed files with 99 additions and 5 deletions
|
@ -26,6 +26,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public const uint ConstantBuffersIndex = 20;
|
public const uint ConstantBuffersIndex = 20;
|
||||||
public const uint StorageBuffersIndex = 21;
|
public const uint StorageBuffersIndex = 21;
|
||||||
public const uint TexturesIndex = 22;
|
public const uint TexturesIndex = 22;
|
||||||
public const uint ImagessIndex = 23;
|
public const uint ImagesIndex = 23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,18 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record struct ImageRef
|
||||||
|
{
|
||||||
|
public ShaderStage Stage;
|
||||||
|
public Texture Storage;
|
||||||
|
|
||||||
|
public ImageRef(ShaderStage stage, Texture storage)
|
||||||
|
{
|
||||||
|
Stage = stage;
|
||||||
|
Storage = storage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PredrawState
|
struct PredrawState
|
||||||
{
|
{
|
||||||
public MTLCullMode CullMode;
|
public MTLCullMode CullMode;
|
||||||
|
@ -92,6 +104,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public readonly BufferRef[] UniformBufferRefs = new BufferRef[Constants.MaxUniformBufferBindings];
|
public readonly BufferRef[] UniformBufferRefs = new BufferRef[Constants.MaxUniformBufferBindings];
|
||||||
public readonly BufferRef[] StorageBufferRefs = new BufferRef[Constants.MaxStorageBufferBindings];
|
public readonly BufferRef[] StorageBufferRefs = new BufferRef[Constants.MaxStorageBufferBindings];
|
||||||
public readonly TextureRef[] TextureRefs = new TextureRef[Constants.MaxTextureBindings];
|
public readonly TextureRef[] TextureRefs = new TextureRef[Constants.MaxTextureBindings];
|
||||||
|
public readonly ImageRef[] ImageRefs = new ImageRef[Constants.MaxTextureBindings];
|
||||||
|
|
||||||
public IndexBufferState IndexBuffer = default;
|
public IndexBufferState IndexBuffer = default;
|
||||||
|
|
||||||
|
|
|
@ -821,6 +821,20 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_currentState.Dirty |= DirtyFlags.Textures;
|
_currentState.Dirty |= DirtyFlags.Textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly void UpdateImage(ShaderStage stage, ulong binding, TextureBase texture)
|
||||||
|
{
|
||||||
|
if (texture is Texture view)
|
||||||
|
{
|
||||||
|
_currentState.ImageRefs[binding] = new(stage, view);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentState.ImageRefs[binding] = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentState.Dirty |= DirtyFlags.Images;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly void SetDepthStencilState(MTLRenderCommandEncoder renderCommandEncoder)
|
private readonly void SetDepthStencilState(MTLRenderCommandEncoder renderCommandEncoder)
|
||||||
{
|
{
|
||||||
MTLDepthStencilState state = _depthStencilCache.GetOrCreate(_currentState.DepthStencilUid);
|
MTLDepthStencilState state = _depthStencilCache.GetOrCreate(_currentState.DepthStencilUid);
|
||||||
|
@ -1171,7 +1185,42 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MetalRenderer.ImageSetIndex:
|
case MetalRenderer.ImageSetIndex:
|
||||||
// TODO: Images
|
if (!segment.IsArray)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
int index = binding + i;
|
||||||
|
|
||||||
|
ref var image = ref _currentState.ImageRefs[index];
|
||||||
|
|
||||||
|
var storage = image.Storage;
|
||||||
|
|
||||||
|
if (storage == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mtlTexture = storage.GetHandle();
|
||||||
|
|
||||||
|
MTLRenderStages renderStages = 0;
|
||||||
|
|
||||||
|
if ((segment.Stages & ResourceStages.Vertex) != 0)
|
||||||
|
{
|
||||||
|
vertResourceIds[vertResourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
|
vertResourceIdIndex++;
|
||||||
|
renderStages |= MTLRenderStages.RenderStageVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((segment.Stages & ResourceStages.Fragment) != 0)
|
||||||
|
{
|
||||||
|
fragResourceIds[fragResourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
|
fragResourceIdIndex++;
|
||||||
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1336,7 +1385,34 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MetalRenderer.ImageSetIndex:
|
case MetalRenderer.ImageSetIndex:
|
||||||
// TODO: Images
|
if (!segment.IsArray)
|
||||||
|
{
|
||||||
|
if (segment.Type != ResourceType.BufferTexture)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
int index = binding + i;
|
||||||
|
|
||||||
|
ref var image = ref _currentState.ImageRefs[index];
|
||||||
|
|
||||||
|
var storage = image.Storage;
|
||||||
|
|
||||||
|
if (storage == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mtlTexture = storage.GetHandle();
|
||||||
|
|
||||||
|
if (segment.Stages.HasFlag(ResourceStages.Compute))
|
||||||
|
{
|
||||||
|
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write);
|
||||||
|
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
|
resourceIdIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1356,7 +1432,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
MetalRenderer.UniformSetIndex => Constants.ConstantBuffersIndex,
|
MetalRenderer.UniformSetIndex => Constants.ConstantBuffersIndex,
|
||||||
MetalRenderer.StorageSetIndex => Constants.StorageBuffersIndex,
|
MetalRenderer.StorageSetIndex => Constants.StorageBuffersIndex,
|
||||||
MetalRenderer.TextureSetIndex => Constants.TexturesIndex,
|
MetalRenderer.TextureSetIndex => Constants.TexturesIndex,
|
||||||
MetalRenderer.ImageSetIndex => Constants.ImagessIndex,
|
MetalRenderer.ImageSetIndex => Constants.ImagesIndex,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,12 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetImage(ShaderStage stage, int binding, ITexture texture, Format imageFormat)
|
public void SetImage(ShaderStage stage, int binding, ITexture texture, Format imageFormat)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
|
if (texture is TextureBase tex)
|
||||||
|
{
|
||||||
|
var index = (ulong)binding;
|
||||||
|
|
||||||
|
_encoderStateManager.UpdateImage(stage, index, tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImageArray(ShaderStage stage, int binding, IImageArray array)
|
public void SetImageArray(ShaderStage stage, int binding, IImageArray array)
|
||||||
|
|
Loading…
Reference in a new issue