2
0

TextureMTL.mm 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2025 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Renderer/MTL/TextureMTL.h>
  6. #include <Renderer/MTL/RendererMTL.h>
  7. #include <Renderer/MTL/FatalErrorIfFailedMTL.h>
  8. #include <Image/BlitSurface.h>
  9. TextureMTL::TextureMTL(RendererMTL *inRenderer, const Surface *inSurface) :
  10. Texture(inSurface->GetWidth(), inSurface->GetHeight()),
  11. mRenderer(inRenderer)
  12. {
  13. ESurfaceFormat format = inSurface->GetFormat();
  14. MTLPixelFormat mt_format = MTLPixelFormatBGRA8Unorm;
  15. switch (format)
  16. {
  17. case ESurfaceFormat::A4L4:
  18. case ESurfaceFormat::A8L8:
  19. case ESurfaceFormat::A4R4G4B4:
  20. case ESurfaceFormat::R8G8B8:
  21. case ESurfaceFormat::B8G8R8:
  22. case ESurfaceFormat::X8R8G8B8:
  23. case ESurfaceFormat::X8B8G8R8:
  24. case ESurfaceFormat::A8R8G8B8:
  25. case ESurfaceFormat::A8B8G8R8: mt_format = MTLPixelFormatBGRA8Unorm; format = ESurfaceFormat::A8R8G8B8; break;
  26. case ESurfaceFormat::L8: mt_format = MTLPixelFormatR8Unorm; break;
  27. case ESurfaceFormat::A8: mt_format = MTLPixelFormatA8Unorm; break;
  28. case ESurfaceFormat::R5G6B5:
  29. case ESurfaceFormat::X1R5G5B5:
  30. case ESurfaceFormat::X4R4G4B4: mt_format = MTLPixelFormatB5G6R5Unorm; format = ESurfaceFormat::R5G6B5; break;
  31. case ESurfaceFormat::A1R5G5B5: mt_format = MTLPixelFormatA1BGR5Unorm; break;
  32. case ESurfaceFormat::Invalid:
  33. default: JPH_ASSERT(false); break;
  34. }
  35. // Blit the surface to another temporary surface if the format changed
  36. const Surface *surface = inSurface;
  37. Ref<Surface> tmp;
  38. if (format != inSurface->GetFormat())
  39. {
  40. tmp = new SoftwareSurface(mWidth, mHeight, format);
  41. BlitSurface(inSurface, tmp);
  42. surface = tmp;
  43. }
  44. // Create descriptor
  45. MTLTextureDescriptor *descriptor = [[MTLTextureDescriptor alloc] init];
  46. descriptor.textureType = MTLTextureType2D;
  47. descriptor.usage = MTLTextureUsageShaderRead;
  48. descriptor.pixelFormat = mt_format;
  49. descriptor.width = mWidth;
  50. descriptor.height = mHeight;
  51. descriptor.storageMode = MTLStorageModeManaged;
  52. MTLRegion region =
  53. {
  54. { 0, 0, 0 },
  55. { NSUInteger(mWidth), NSUInteger(mHeight), 1}
  56. };
  57. // Create texture
  58. mTexture = [inRenderer->GetDevice() newTextureWithDescriptor: descriptor];
  59. surface->Lock(ESurfaceLockMode::Read);
  60. [mTexture replaceRegion: region mipmapLevel:0 withBytes: surface->GetData() bytesPerRow: surface->GetStride()];
  61. surface->UnLock();
  62. [descriptor release];
  63. }
  64. TextureMTL::TextureMTL(RendererMTL *inRenderer, int inWidth, int inHeight) :
  65. Texture(inWidth, inHeight),
  66. mRenderer(inRenderer)
  67. {
  68. MTLTextureDescriptor *descriptor = [[MTLTextureDescriptor alloc] init];
  69. descriptor.textureType = MTLTextureType2D;
  70. descriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
  71. descriptor.pixelFormat = MTLPixelFormatDepth32Float;
  72. descriptor.width = mWidth;
  73. descriptor.height = mHeight;
  74. descriptor.storageMode = MTLStorageModePrivate;
  75. mTexture = [inRenderer->GetDevice() newTextureWithDescriptor: descriptor];
  76. [descriptor release];
  77. }
  78. TextureMTL::~TextureMTL()
  79. {
  80. [mTexture release];
  81. }
  82. void TextureMTL::Bind() const
  83. {
  84. [mRenderer->GetRenderEncoder() setFragmentTexture: mTexture atIndex: 0];
  85. }