Compute.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using Ryujinx.Graphics.GAL.Texture;
  2. using Ryujinx.Graphics.Gpu.Image;
  3. using Ryujinx.Graphics.Gpu.State;
  4. using Ryujinx.Graphics.Shader;
  5. using System;
  6. using System.Runtime.InteropServices;
  7. namespace Ryujinx.Graphics.Gpu.Engine
  8. {
  9. partial class Methods
  10. {
  11. public void Dispatch(int argument)
  12. {
  13. uint dispatchParamsAddress = (uint)_context.State.Get<int>(MethodOffset.DispatchParamsAddress);
  14. var dispatchParams = _context.MemoryAccessor.Read<ComputeParams>((ulong)dispatchParamsAddress << 8);
  15. GpuVa shaderBaseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress);
  16. ulong shaderGpuVa = shaderBaseAddress.Pack() + (uint)dispatchParams.ShaderOffset;
  17. ComputeShader cs = _shaderCache.GetComputeShader(
  18. shaderGpuVa,
  19. dispatchParams.UnpackBlockSizeX(),
  20. dispatchParams.UnpackBlockSizeY(),
  21. dispatchParams.UnpackBlockSizeZ());
  22. _context.Renderer.Pipeline.BindProgram(cs.Interface);
  23. var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState);
  24. _textureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
  25. var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
  26. _textureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
  27. _textureManager.SetComputeTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex));
  28. ShaderProgramInfo info = cs.Shader.Info;
  29. var textureBindings = new TextureBindingInfo[info.Textures.Count];
  30. for (int index = 0; index < info.Textures.Count; index++)
  31. {
  32. var descriptor = info.Textures[index];
  33. Target target = GetTarget(descriptor.Type);
  34. textureBindings[index] = new TextureBindingInfo(target, descriptor.HandleIndex);
  35. }
  36. _textureManager.SetComputeTextures(textureBindings);
  37. var imageBindings = new TextureBindingInfo[info.Images.Count];
  38. for (int index = 0; index < info.Images.Count; index++)
  39. {
  40. var descriptor = info.Images[index];
  41. Target target = GetTarget(descriptor.Type);
  42. imageBindings[index] = new TextureBindingInfo(target, descriptor.HandleIndex);
  43. }
  44. _textureManager.SetComputeImages(imageBindings);
  45. uint sbEnableMask = 0;
  46. uint ubEnableMask = dispatchParams.UnpackUniformBuffersEnableMask();
  47. for (int index = 0; index < dispatchParams.UniformBuffers.Length; index++)
  48. {
  49. if ((ubEnableMask & (1 << index)) == 0)
  50. {
  51. continue;
  52. }
  53. ulong gpuVa = dispatchParams.UniformBuffers[index].PackAddress();
  54. ulong size = dispatchParams.UniformBuffers[index].UnpackSize();
  55. _bufferManager.SetComputeUniformBuffer(index, gpuVa, size);
  56. }
  57. for (int index = 0; index < info.SBuffers.Count; index++)
  58. {
  59. BufferDescriptor sb = info.SBuffers[index];
  60. sbEnableMask |= 1u << sb.Slot;
  61. ulong sbDescAddress = _bufferManager.GetComputeUniformBufferAddress(0);
  62. int sbDescOffset = 0x310 + sb.Slot * 0x10;
  63. sbDescAddress += (ulong)sbDescOffset;
  64. Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
  65. SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
  66. _bufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size);
  67. }
  68. ubEnableMask = 0;
  69. for (int index = 0; index < info.CBuffers.Count; index++)
  70. {
  71. ubEnableMask |= 1u << info.CBuffers[index].Slot;
  72. }
  73. _bufferManager.SetComputeStorageBufferEnableMask(sbEnableMask);
  74. _bufferManager.SetComputeUniformBufferEnableMask(ubEnableMask);
  75. _bufferManager.CommitComputeBindings();
  76. _textureManager.CommitComputeBindings();
  77. _context.Renderer.Pipeline.Dispatch(
  78. dispatchParams.UnpackGridSizeX(),
  79. dispatchParams.UnpackGridSizeY(),
  80. dispatchParams.UnpackGridSizeZ());
  81. UpdateShaderState();
  82. }
  83. }
  84. }