SamplerHolder.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. }
  56. gd.Api.CreateSampler(device, samplerCreateInfo, null, out var sampler).ThrowOnError();
  57. _sampler = new Auto<DisposableSampler>(new DisposableSampler(gd.Api, device, sampler));
  58. }
  59. private static BorderColor GetConstrainedBorderColor(ColorF arbitraryBorderColor, out bool cantConstrain)
  60. {
  61. float r = arbitraryBorderColor.Red;
  62. float g = arbitraryBorderColor.Green;
  63. float b = arbitraryBorderColor.Blue;
  64. float a = arbitraryBorderColor.Alpha;
  65. if (r == 0f && g == 0f && b == 0f)
  66. {
  67. if (a == 1f)
  68. {
  69. cantConstrain = false;
  70. return BorderColor.FloatOpaqueBlack;
  71. }
  72. else if (a == 0f)
  73. {
  74. cantConstrain = false;
  75. return BorderColor.FloatTransparentBlack;
  76. }
  77. }
  78. else if (r == 1f && g == 1f && b == 1f && a == 1f)
  79. {
  80. cantConstrain = false;
  81. return BorderColor.FloatOpaqueWhite;
  82. }
  83. cantConstrain = true;
  84. return BorderColor.FloatOpaqueBlack;
  85. }
  86. public Auto<DisposableSampler> GetSampler()
  87. {
  88. return _sampler;
  89. }
  90. public void Dispose()
  91. {
  92. if (_gd.Samplers.Remove(this))
  93. {
  94. _sampler.Dispose();
  95. }
  96. }
  97. }
  98. }