SamplerHolder.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using Ryujinx.Graphics.GAL;
  2. using Silk.NET.Vulkan;
  3. namespace Ryujinx.Graphics.Vulkan
  4. {
  5. class SamplerHolder : ISampler
  6. {
  7. private readonly VulkanRenderer _gd;
  8. private readonly Auto<DisposableSampler> _sampler;
  9. public unsafe SamplerHolder(VulkanRenderer gd, Device device, GAL.SamplerCreateInfo info)
  10. {
  11. _gd = gd;
  12. gd.Samplers.Add(this);
  13. (Filter minFilter, SamplerMipmapMode mipFilter) = EnumConversion.Convert(info.MinFilter);
  14. float minLod = info.MinLod;
  15. float maxLod = info.MaxLod;
  16. if (info.MinFilter == MinFilter.Nearest || info.MinFilter == MinFilter.Linear)
  17. {
  18. minLod = 0;
  19. maxLod = 0.25f;
  20. }
  21. var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);
  22. var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo()
  23. {
  24. SType = StructureType.SamplerCreateInfo,
  25. MagFilter = info.MagFilter.Convert(),
  26. MinFilter = minFilter,
  27. MipmapMode = mipFilter,
  28. AddressModeU = info.AddressU.Convert(),
  29. AddressModeV = info.AddressV.Convert(),
  30. AddressModeW = info.AddressP.Convert(),
  31. MipLodBias = info.MipLodBias,
  32. AnisotropyEnable = info.MaxAnisotropy != 1f,
  33. MaxAnisotropy = info.MaxAnisotropy,
  34. CompareEnable = info.CompareMode == CompareMode.CompareRToTexture,
  35. CompareOp = info.CompareOp.Convert(),
  36. MinLod = minLod,
  37. MaxLod = maxLod,
  38. BorderColor = borderColor,
  39. UnnormalizedCoordinates = false // TODO: Use unnormalized coordinates.
  40. };
  41. SamplerCustomBorderColorCreateInfoEXT customBorderColor;
  42. if (cantConstrain && gd.Capabilities.SupportsCustomBorderColor)
  43. {
  44. var color = new ClearColorValue(
  45. info.BorderColor.Red,
  46. info.BorderColor.Green,
  47. info.BorderColor.Blue,
  48. info.BorderColor.Alpha);
  49. customBorderColor = new SamplerCustomBorderColorCreateInfoEXT()
  50. {
  51. SType = StructureType.SamplerCustomBorderColorCreateInfoExt,
  52. CustomBorderColor = color
  53. };
  54. samplerCreateInfo.PNext = &customBorderColor;
  55. samplerCreateInfo.BorderColor = BorderColor.FloatCustomExt;
  56. }
  57. gd.Api.CreateSampler(device, samplerCreateInfo, null, out var sampler).ThrowOnError();
  58. _sampler = new Auto<DisposableSampler>(new DisposableSampler(gd.Api, device, sampler));
  59. }
  60. private static BorderColor GetConstrainedBorderColor(ColorF arbitraryBorderColor, out bool cantConstrain)
  61. {
  62. float r = arbitraryBorderColor.Red;
  63. float g = arbitraryBorderColor.Green;
  64. float b = arbitraryBorderColor.Blue;
  65. float a = arbitraryBorderColor.Alpha;
  66. if (r == 0f && g == 0f && b == 0f)
  67. {
  68. if (a == 1f)
  69. {
  70. cantConstrain = false;
  71. return BorderColor.FloatOpaqueBlack;
  72. }
  73. else if (a == 0f)
  74. {
  75. cantConstrain = false;
  76. return BorderColor.FloatTransparentBlack;
  77. }
  78. }
  79. else if (r == 1f && g == 1f && b == 1f && a == 1f)
  80. {
  81. cantConstrain = false;
  82. return BorderColor.FloatOpaqueWhite;
  83. }
  84. cantConstrain = true;
  85. return BorderColor.FloatOpaqueBlack;
  86. }
  87. public Auto<DisposableSampler> GetSampler()
  88. {
  89. return _sampler;
  90. }
  91. public void Dispose()
  92. {
  93. if (_gd.Samplers.Remove(this))
  94. {
  95. _sampler.Dispose();
  96. }
  97. }
  98. }
  99. }