VideoImageComposer.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Ryujinx.Graphics.Gpu;
  2. using Ryujinx.Graphics.VDec;
  3. namespace Ryujinx.Graphics.Vic
  4. {
  5. class VideoImageComposer
  6. {
  7. private ulong _configStructAddress;
  8. private ulong _outputSurfaceLumaAddress;
  9. private ulong _outputSurfaceChromaUAddress;
  10. private ulong _outputSurfaceChromaVAddress;
  11. private VideoDecoder _vdec;
  12. public VideoImageComposer(VideoDecoder vdec)
  13. {
  14. _vdec = vdec;
  15. }
  16. public void Process(GpuContext gpu, int methodOffset, int[] arguments)
  17. {
  18. VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset;
  19. switch (method)
  20. {
  21. case VideoImageComposerMeth.Execute: Execute(gpu); break;
  22. case VideoImageComposerMeth.SetConfigStructOffset: SetConfigStructOffset(arguments); break;
  23. case VideoImageComposerMeth.SetOutputSurfaceLumaOffset: SetOutputSurfaceLumaOffset(arguments); break;
  24. case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset: SetOutputSurfaceChromaUOffset(arguments); break;
  25. case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset: SetOutputSurfaceChromaVOffset(arguments); break;
  26. }
  27. }
  28. private void Execute(GpuContext gpu)
  29. {
  30. StructUnpacker unpacker = new StructUnpacker(gpu.MemoryAccessor, _configStructAddress + 0x20);
  31. SurfacePixelFormat pixelFormat = (SurfacePixelFormat)unpacker.Read(7);
  32. int chromaLocHoriz = unpacker.Read(2);
  33. int chromaLocVert = unpacker.Read(2);
  34. int blockLinearKind = unpacker.Read(4);
  35. int blockLinearHeightLog2 = unpacker.Read(4);
  36. int reserved0 = unpacker.Read(3);
  37. int reserved1 = unpacker.Read(10);
  38. int surfaceWidthMinus1 = unpacker.Read(14);
  39. int surfaceHeightMinus1 = unpacker.Read(14);
  40. int gobBlockHeight = 1 << blockLinearHeightLog2;
  41. int surfaceWidth = surfaceWidthMinus1 + 1;
  42. int surfaceHeight = surfaceHeightMinus1 + 1;
  43. SurfaceOutputConfig outputConfig = new SurfaceOutputConfig(
  44. pixelFormat,
  45. surfaceWidth,
  46. surfaceHeight,
  47. gobBlockHeight,
  48. _outputSurfaceLumaAddress,
  49. _outputSurfaceChromaUAddress,
  50. _outputSurfaceChromaVAddress);
  51. _vdec.CopyPlanes(gpu, outputConfig);
  52. }
  53. private void SetConfigStructOffset(int[] arguments)
  54. {
  55. _configStructAddress = GetAddress(arguments);
  56. }
  57. private void SetOutputSurfaceLumaOffset(int[] arguments)
  58. {
  59. _outputSurfaceLumaAddress = GetAddress(arguments);
  60. }
  61. private void SetOutputSurfaceChromaUOffset(int[] arguments)
  62. {
  63. _outputSurfaceChromaUAddress = GetAddress(arguments);
  64. }
  65. private void SetOutputSurfaceChromaVOffset(int[] arguments)
  66. {
  67. _outputSurfaceChromaVAddress = GetAddress(arguments);
  68. }
  69. private static ulong GetAddress(int[] arguments)
  70. {
  71. return (ulong)(uint)arguments[0] << 8;
  72. }
  73. }
  74. }