MTLPipeline.mm 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "VideoBackends/Metal/MTLPipeline.h"
  4. #include "Common/MsgHandler.h"
  5. static void MarkAsUsed(u32* list, u32 start, u32 length)
  6. {
  7. for (u32 i = start; i < start + length; ++i)
  8. *list |= 1 << i;
  9. }
  10. static void GetArguments(NSArray<MTLArgument*>* arguments, u32* textures, u32* samplers,
  11. u32* buffers)
  12. {
  13. for (MTLArgument* argument in arguments)
  14. {
  15. const u32 idx = [argument index];
  16. const u32 length = [argument arrayLength];
  17. if (idx + length > 32)
  18. {
  19. PanicAlertFmt("Making a MTLPipeline with high argument index {:d}..<{:d} for {:s}", //
  20. idx, idx + length, [[argument name] UTF8String]);
  21. continue;
  22. }
  23. switch ([argument type])
  24. {
  25. case MTLArgumentTypeTexture:
  26. if (textures)
  27. MarkAsUsed(textures, idx, length);
  28. else
  29. PanicAlertFmt("Vertex function wants a texture!");
  30. break;
  31. case MTLArgumentTypeSampler:
  32. if (samplers)
  33. MarkAsUsed(samplers, idx, length);
  34. else
  35. PanicAlertFmt("Vertex function wants a sampler!");
  36. break;
  37. case MTLArgumentTypeBuffer:
  38. MarkAsUsed(buffers, idx, length);
  39. break;
  40. default:
  41. break;
  42. }
  43. }
  44. }
  45. Metal::PipelineReflection::PipelineReflection(MTLRenderPipelineReflection* reflection)
  46. {
  47. GetArguments([reflection vertexArguments], nullptr, nullptr, &vertex_buffers);
  48. GetArguments([reflection fragmentArguments], &textures, &samplers, &fragment_buffers);
  49. }
  50. Metal::Pipeline::Pipeline(const AbstractPipelineConfig& config,
  51. MRCOwned<id<MTLRenderPipelineState>> pipeline,
  52. const PipelineReflection& reflection, MTLPrimitiveType prim,
  53. MTLCullMode cull, DepthState depth, AbstractPipelineUsage usage)
  54. : AbstractPipeline(config), m_pipeline(std::move(pipeline)), m_prim(prim), m_cull(cull),
  55. m_depth_stencil(depth), m_usage(usage), m_reflection(reflection)
  56. {
  57. }
  58. Metal::ComputePipeline::ComputePipeline(ShaderStage stage, MTLComputePipelineReflection* reflection,
  59. std::string msl, MRCOwned<id<MTLFunction>> shader,
  60. MRCOwned<id<MTLComputePipelineState>> pipeline)
  61. : Shader(stage, std::move(msl), std::move(shader)), m_compute_pipeline(std::move(pipeline))
  62. {
  63. GetArguments([reflection arguments], &m_textures, &m_samplers, &m_buffers);
  64. }