Compute.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using Ryujinx.Graphics.Gpu.State;
  2. using Ryujinx.Graphics.Shader;
  3. using System;
  4. using System.Runtime.InteropServices;
  5. namespace Ryujinx.Graphics.Gpu.Engine
  6. {
  7. partial class Methods
  8. {
  9. public void Dispatch(int argument)
  10. {
  11. uint dispatchParamsAddress = (uint)_context.State.Get<int>(MethodOffset.DispatchParamsAddress);
  12. var dispatchParams = _context.MemoryAccessor.Read<ComputeParams>((ulong)dispatchParamsAddress << 8);
  13. GpuVa shaderBaseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress);
  14. ulong shaderGpuVa = shaderBaseAddress.Pack() + (uint)dispatchParams.ShaderOffset;
  15. ComputeShader cs = _shaderCache.GetComputeShader(
  16. shaderGpuVa,
  17. dispatchParams.UnpackBlockSizeX(),
  18. dispatchParams.UnpackBlockSizeY(),
  19. dispatchParams.UnpackBlockSizeZ());
  20. _context.Renderer.ComputePipeline.SetProgram(cs.Interface);
  21. ShaderProgramInfo info = cs.Shader.Info;
  22. uint sbEnableMask = 0;
  23. uint ubEnableMask = dispatchParams.UnpackUniformBuffersEnableMask();
  24. for (int index = 0; index < dispatchParams.UniformBuffers.Length; index++)
  25. {
  26. if ((ubEnableMask & (1 << index)) == 0)
  27. {
  28. continue;
  29. }
  30. ulong gpuVa = dispatchParams.UniformBuffers[index].PackAddress();
  31. ulong size = dispatchParams.UniformBuffers[index].UnpackSize();
  32. _bufferManager.SetComputeUniformBuffer(index, gpuVa, size);
  33. }
  34. for (int index = 0; index < info.SBuffers.Count; index++)
  35. {
  36. BufferDescriptor sb = info.SBuffers[index];
  37. sbEnableMask |= 1u << sb.Slot;
  38. ulong sbDescAddress = _bufferManager.GetComputeUniformBufferAddress(0);
  39. int sbDescOffset = 0x310 + sb.Slot * 0x10;
  40. sbDescAddress += (ulong)sbDescOffset;
  41. Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
  42. SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
  43. _bufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size);
  44. }
  45. ubEnableMask = 0;
  46. for (int index = 0; index < info.CBuffers.Count; index++)
  47. {
  48. ubEnableMask |= 1u << info.CBuffers[index].Slot;
  49. }
  50. _bufferManager.SetComputeStorageBufferEnableMask(sbEnableMask);
  51. _bufferManager.SetComputeUniformBufferEnableMask(ubEnableMask);
  52. _bufferManager.CommitComputeBindings();
  53. _context.Renderer.ComputePipeline.Dispatch(
  54. dispatchParams.UnpackGridSizeX(),
  55. dispatchParams.UnpackGridSizeY(),
  56. dispatchParams.UnpackGridSizeZ());
  57. }
  58. }
  59. }