Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/Graphics/Swapchain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Graphics/Surface.hpp"
#include "Graphics/Enums.hpp"
#include "Graphics/Drawable.hpp"
#include "Graphics/Texture.hpp"

#include <cstdint>
#include <memory>
Expand All @@ -38,9 +39,8 @@ class Swapchain
Swapchain(const Swapchain&) = delete;
Swapchain(Swapchain&&) = delete;

virtual uint32_t width() const = 0;
virtual uint32_t height() const = 0;
virtual PixelFormat pixelFormat() const = 0;
// descriptor used to create textures for drawables
virtual const Texture::Descriptor& drawablesTextureDescriptor() const = 0;

virtual std::shared_ptr<Drawable> nextDrawable() = 0;

Expand Down
11 changes: 8 additions & 3 deletions src/Metal/MetalDrawable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#define METALDRAWABLE_HPP

#include "Graphics/Drawable.hpp"
#include "Metal/MetalTexture.hpp"

#include <memory>

#if !defined(__OBJC__)
#error this file can only by used in objective c
Expand All @@ -28,16 +31,18 @@ class MetalDrawable : public Drawable
MetalDrawable(const MetalDrawable&) = delete;
MetalDrawable(MetalDrawable&&) = delete;

MetalDrawable(id<CAMetalDrawable>);
MetalDrawable(const Texture::Descriptor&);

std::shared_ptr<Texture> texture() const override;

id<CAMetalDrawable> mtlDrawable() const { return m_mtlDrawable; }
inline id<CAMetalDrawable> mtlDrawable() const { return m_mtlDrawable; }
void setMtlDrawable(const id<CAMetalDrawable>& d);

~MetalDrawable() override = default;

private:
id<CAMetalDrawable> m_mtlDrawable;
id<CAMetalDrawable> m_mtlDrawable = nil;
std::shared_ptr<MetalTexture> m_texture = nullptr;

public:
MetalDrawable& operator=(const MetalDrawable&) = delete;
Expand Down
24 changes: 12 additions & 12 deletions src/Metal/MetalDrawable.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@
#include "Metal/MetalEnums.hpp"
#include "Metal/MetalTexture.hpp"

#include <memory>

namespace gfx
{

MetalDrawable::MetalDrawable(id<CAMetalDrawable> mtlDrawable)
: m_mtlDrawable(mtlDrawable)
MetalDrawable::MetalDrawable(const Texture::Descriptor& textureDescriptor)
: m_texture(std::make_shared<MetalTexture>(textureDescriptor))
{
}

std::shared_ptr<Texture> MetalDrawable::texture() const { @autoreleasepool
{
id<MTLTexture> mtlTexture = m_mtlDrawable.texture;
Texture::Descriptor desc = {
.type = TextureType::texture2d,
.width = static_cast<uint32_t>(mtlTexture.width),
.height = static_cast<uint32_t>(mtlTexture.height),
.pixelFormat = toPixelFormat(mtlTexture.pixelFormat),
.usages = TextureUsage::colorAttachment,
.storageMode = ResourceStorageMode::deviceLocal
};
return std::make_shared<MetalTexture>(m_mtlDrawable.texture, desc);
m_texture->setMtlTexture(m_mtlDrawable.texture);
return m_texture;
}}

void MetalDrawable::setMtlDrawable(const id<CAMetalDrawable>& drawable)
{
m_mtlDrawable = drawable;
m_texture->setMtlTexture(nil);
}

}
13 changes: 7 additions & 6 deletions src/Metal/MetalSwapchain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "Graphics/Swapchain.hpp"
#include "Graphics/Drawable.hpp"
#include "Metal/MetalDrawable.hpp"
#include "Metal/MetalTexture.hpp"

#if !defined(__OBJC__)
#error this file can only by used in objective c
Expand All @@ -30,19 +32,18 @@ class MetalSwapchain : public Swapchain

MetalSwapchain(const MetalDevice&, const Swapchain::Descriptor&);

inline uint32_t width() const override { return m_width; }
inline uint32_t height() const override { return m_height; }
inline PixelFormat pixelFormat() const override { return m_pixelFormat; };
inline const Texture::Descriptor& drawablesTextureDescriptor() const override { return m_swapchainImagesDescriptor; }

std::shared_ptr<Drawable> nextDrawable() override;

~MetalSwapchain() override = default;

private:
uint32_t m_width;
uint32_t m_height;
Texture::Descriptor m_swapchainImagesDescriptor;

CAMetalLayer* m_mtlLayer;
PixelFormat m_pixelFormat;
std::vector<std::shared_ptr<MetalDrawable>> m_drawables;
uint32_t m_nextDrawableIndex = 0;

public:
MetalSwapchain& operator=(const MetalSwapchain&) = delete;
Expand Down
42 changes: 29 additions & 13 deletions src/Metal/MetalSwapchain.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,45 @@
#include "Metal/MetalSurface.hpp"

#import "Metal/MetalEnums.hpp"
#include <memory>

namespace gfx
{

MetalSwapchain::MetalSwapchain(const MetalDevice& device, const Swapchain::Descriptor& desc)
: m_width(desc.width)
, m_height(desc.height)
, m_pixelFormat(desc.pixelFormat) { @autoreleasepool
: m_swapchainImagesDescriptor{
.type = TextureType::texture2d,
.width = desc.width,
.height = desc.height,
.pixelFormat = desc.pixelFormat,
.usages = TextureUsage::colorAttachment,
.storageMode = ResourceStorageMode::deviceLocal
}
{
assert(desc.surface);
auto* mtlSurface = dynamic_cast<MetalSurface*>(desc.surface);
assert(mtlSurface);

m_mtlLayer = mtlSurface->mtlLayer();
m_mtlLayer.device = device.mtlDevice();
m_mtlLayer.drawableSize = CGSize{CGFloat(desc.width), CGFloat(desc.height)};
m_mtlLayer.pixelFormat = toMTLPixelFormat(desc.pixelFormat);
}}
@autoreleasepool {
assert(desc.surface);
auto* mtlSurface = dynamic_cast<MetalSurface*>(desc.surface);
assert(mtlSurface);

m_mtlLayer = mtlSurface->mtlLayer();
m_mtlLayer.device = device.mtlDevice();
m_mtlLayer.drawableSize = CGSize{CGFloat(desc.width), CGFloat(desc.height)};
m_mtlLayer.pixelFormat = toMTLPixelFormat(desc.pixelFormat);

m_drawables.resize(desc.drawableCount);
for (auto& drawable : m_drawables)
drawable = std::make_shared<MetalDrawable>(m_swapchainImagesDescriptor);

}
}

std::shared_ptr<Drawable> MetalSwapchain::nextDrawable() { @autoreleasepool
{
ZoneScoped;
return std::make_shared<MetalDrawable>([m_mtlLayer nextDrawable]);
std::shared_ptr<MetalDrawable> nextDrawable = m_drawables.at(m_nextDrawableIndex);
m_nextDrawableIndex = (m_nextDrawableIndex + 1) % m_drawables.size();
nextDrawable->setMtlDrawable([m_mtlLayer nextDrawable]);
return nextDrawable;
}}

}
3 changes: 2 additions & 1 deletion src/Metal/MetalTexture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MetalTexture : public Texture
MetalTexture(const MetalTexture&) = delete;
MetalTexture(MetalTexture&&) = delete;

MetalTexture(const id<MTLTexture>&, const Texture::Descriptor&);
MetalTexture(const Texture::Descriptor&);
MetalTexture(const MetalDevice&, const Texture::Descriptor&);

TextureType type() const override;
Expand All @@ -42,6 +42,7 @@ class MetalTexture : public Texture
inline ResourceStorageMode storageMode() const override { return m_storageMode; };

inline id<MTLTexture> mtltexture() const { return m_mtlTexture; }
inline void setMtlTexture(const id<MTLTexture>& t) { m_mtlTexture = t; }

~MetalTexture() override = default;

Expand Down
17 changes: 11 additions & 6 deletions src/Metal/MetalTexture.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@

#import "Metal/MetalEnums.hpp"

#include <cassert>

namespace gfx
{

MetalTexture::MetalTexture(const id<MTLTexture>& mtltexture, const Texture::Descriptor& desc)
MetalTexture::MetalTexture(const Texture::Descriptor& desc)
: m_usages(desc.usages)
, m_storageMode(desc.storageMode)
, m_mtlTexture(mtltexture)
{
}

Expand All @@ -44,22 +45,26 @@

TextureType MetalTexture::type() const { @autoreleasepool
{
return toTextureType([mtltexture() textureType]);
assert(m_mtlTexture);
return toTextureType([m_mtlTexture textureType]);
}}

uint32_t MetalTexture::width() const { @autoreleasepool
{
return static_cast<uint32_t>(mtltexture().width);
assert(m_mtlTexture);
return static_cast<uint32_t>(m_mtlTexture.width);
}}

uint32_t MetalTexture::height() const { @autoreleasepool
{
return static_cast<uint32_t>(mtltexture().height);
assert(m_mtlTexture);
return static_cast<uint32_t>(m_mtlTexture.height);
}}

PixelFormat MetalTexture::pixelFormat() const { @autoreleasepool
{
return toPixelFormat([mtltexture() pixelFormat]);
assert(m_mtlTexture);
return toPixelFormat([m_mtlTexture pixelFormat]);
}}

}
20 changes: 10 additions & 10 deletions src/Vulkan/VulkanSwapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
#include "Vulkan/VulkanSurface.hpp"
#include "Vulkan/VulkanEnums.hpp"
#include "Vulkan/VulkanDrawable.hpp"
#include "vulkan/vulkan.hpp"

namespace gfx
{

VulkanSwapchain::VulkanSwapchain(const VulkanDevice* device, const Descriptor& desc)
: m_device(device)
, m_pixelFormat(desc.pixelFormat)
VulkanSwapchain::VulkanSwapchain(const VulkanDevice* device, const Descriptor& desc) : m_device(device)
{
assert(desc.surface);
const vk::SurfaceKHR& vkSurface = dynamic_cast<const VulkanSurface&>(*desc.surface).vkSurface();
Expand All @@ -40,12 +39,13 @@ VulkanSwapchain::VulkanSwapchain(const VulkanDevice* device, const Descriptor& d
std::vector<vk::PresentModeKHR> surfacePresentModes = vkPhysicalDevice.getSurfacePresentModesKHR(vkSurface);
assert(std::ranges::any_of(surfacePresentModes, [&desc](auto& m){return m == toVkPresentModeKHR(desc.presentMode);}));

vk::Extent2D extent;
if (surfaceCapabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
m_extent = surfaceCapabilities.currentExtent;
extent = surfaceCapabilities.currentExtent;
else
{
m_extent.width = std::clamp(desc.width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
m_extent.height = std::clamp(desc.height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
extent.width = std::clamp(desc.width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
extent.height = std::clamp(desc.height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
}


Expand All @@ -54,7 +54,7 @@ VulkanSwapchain::VulkanSwapchain(const VulkanDevice* device, const Descriptor& d
.setMinImageCount(desc.imageCount)
.setImageFormat(toVkFormat(desc.pixelFormat))
.setImageColorSpace(toVkColorSpaceKHR(desc.pixelFormat))
.setImageExtent(m_extent)
.setImageExtent(extent)
.setImageArrayLayers(1)
.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment)
.setPreTransform(surfaceCapabilities.currentTransform)
Expand All @@ -76,15 +76,15 @@ VulkanSwapchain::VulkanSwapchain(const VulkanDevice* device, const Descriptor& d
m_vkSwapchain = vkSwapchainPtr.get();
s_oldSwapchains[&vkSurface] = *m_vkSwapchain;

Texture::Descriptor swapchainImageTexDesc = {
.width = m_extent.width, .height = m_extent.height,
m_swapchainImagesDescriptor = {
.width = extent.width, .height = extent.height,
.pixelFormat = desc.pixelFormat,
.usages = TextureUsage::colorAttachment,
.storageMode = ResourceStorageMode::deviceLocal
};

m_swapchainImages = m_device->vkDevice().getSwapchainImagesKHR(*vkSwapchainPtr)
| std::views::transform([&](vk::Image& vkImage) { return std::make_shared<SwapchainImage>(m_device, std::move(vkImage), vkSwapchainPtr, swapchainImageTexDesc); })
| std::views::transform([&](vk::Image& vkImage) { return std::make_shared<SwapchainImage>(m_device, std::move(vkImage), vkSwapchainPtr, m_swapchainImagesDescriptor); })
| std::ranges::to<std::vector>();

m_drawables.resize(desc.drawableCount);
Expand Down
7 changes: 2 additions & 5 deletions src/Vulkan/VulkanSwapchain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,15 @@ class VulkanSwapchain : public Swapchain

VulkanSwapchain(const VulkanDevice*, const Swapchain::Descriptor&);

inline uint32_t width() const override { return m_extent.width; }
inline uint32_t height() const override { return m_extent.height; }
inline PixelFormat pixelFormat() const override { return m_pixelFormat; };
inline const Texture::Descriptor& drawablesTextureDescriptor() const override { return m_swapchainImagesDescriptor; }

std::shared_ptr<Drawable> nextDrawable() override;

~VulkanSwapchain() override = default;

private:
const VulkanDevice* m_device;
vk::Extent2D m_extent;
PixelFormat m_pixelFormat;
Texture::Descriptor m_swapchainImagesDescriptor;

vk::SwapchainKHR* m_vkSwapchain;
std::vector<std::shared_ptr<SwapchainImage>> m_swapchainImages;
Expand Down