VicDevice.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using Ryujinx.Graphics.Device;
  2. using Ryujinx.Graphics.Gpu.Memory;
  3. using Ryujinx.Graphics.Vic.Image;
  4. using Ryujinx.Graphics.Vic.Types;
  5. using System.Collections.Generic;
  6. namespace Ryujinx.Graphics.Vic
  7. {
  8. public class VicDevice : IDeviceState
  9. {
  10. private readonly MemoryManager _gmm;
  11. private readonly ResourceManager _rm;
  12. private readonly DeviceState<VicRegisters> _state;
  13. public VicDevice(MemoryManager gmm)
  14. {
  15. _gmm = gmm;
  16. _rm = new ResourceManager(gmm, new BufferPool<Pixel>(), new BufferPool<byte>());
  17. _state = new DeviceState<VicRegisters>(new Dictionary<string, RwCallback>
  18. {
  19. { nameof(VicRegisters.Execute), new RwCallback(Execute, null) }
  20. });
  21. }
  22. public int Read(int offset) => _state.Read(offset);
  23. public void Write(int offset, int data) => _state.Write(offset, data);
  24. private void Execute(int data)
  25. {
  26. ConfigStruct config = ReadIndirect<ConfigStruct>(_state.State.SetConfigStructOffset);
  27. using Surface output = new Surface(
  28. _rm.SurfacePool,
  29. config.OutputSurfaceConfig.OutSurfaceWidth + 1,
  30. config.OutputSurfaceConfig.OutSurfaceHeight + 1);
  31. for (int i = 0; i < config.SlotStruct.Length; i++)
  32. {
  33. ref SlotStruct slot = ref config.SlotStruct[i];
  34. if (!slot.SlotConfig.SlotEnable)
  35. {
  36. continue;
  37. }
  38. var offsets = _state.State.SetSurfacexSlotx[i][0];
  39. using Surface src = SurfaceReader.Read(_rm, ref slot.SlotSurfaceConfig, ref offsets);
  40. Blender.BlendOne(output, src, ref slot);
  41. }
  42. SurfaceWriter.Write(_rm, output, ref config.OutputSurfaceConfig, ref _state.State.SetOutputSurface);
  43. }
  44. private T ReadIndirect<T>(uint offset) where T : unmanaged
  45. {
  46. return _gmm.Read<T>((ulong)offset << 8);
  47. }
  48. }
  49. }