mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 04:34:13 +01:00
Avoid redundant VkImageView
recreation
There are a lot of cases of `VkImageView` being recreated arbitrarily due to it being tied to the ephemeral object `TextureView` rather than `Texture`, this commit flips that by storing all `VkImageView`s inside `Texture` with `TextureView` simply holding a copy of the handle to them. Additionally, this change results in stable `VkImageView` handles and helps in paving the path for framebuffer caching when `VK_KHR_imageless_framebuffer` is unavailable.
This commit is contained in:
parent
41b2c2dc7b
commit
af7f0c301e
@ -24,10 +24,16 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
TextureView::TextureView(std::shared_ptr<Texture> texture, vk::ImageViewType type, vk::ImageSubresourceRange range, texture::Format format, vk::ComponentMapping mapping) : texture(std::move(texture)), type(type), format(format), mapping(mapping), range(range) {}
|
TextureView::TextureView(std::shared_ptr<Texture> texture, vk::ImageViewType type, vk::ImageSubresourceRange range, texture::Format format, vk::ComponentMapping mapping) : texture(std::move(texture)), type(type), format(format), mapping(mapping), range(range) {}
|
||||||
|
|
||||||
vk::ImageView TextureView::GetView() {
|
Texture::TextureViewStorage::TextureViewStorage(vk::ImageViewType type, texture::Format format, vk::ComponentMapping mapping, vk::ImageSubresourceRange range, vk::raii::ImageView &&vkView) : type(type), format(format), mapping(mapping), range(range), vkView(std::move(vkView)) {}
|
||||||
if (view)
|
|
||||||
return **view;
|
|
||||||
|
|
||||||
|
vk::ImageView TextureView::GetView() {
|
||||||
|
if (vkView)
|
||||||
|
return vkView;
|
||||||
|
|
||||||
|
auto it{std::find_if(texture->views.begin(), texture->views.end(), [this](const Texture::TextureViewStorage &view) {
|
||||||
|
return view.type == type && view.format == format && view.mapping == mapping && view.range == range;
|
||||||
|
})};
|
||||||
|
if (it == texture->views.end()) {
|
||||||
vk::ImageViewCreateInfo createInfo{
|
vk::ImageViewCreateInfo createInfo{
|
||||||
.image = texture->GetBacking(),
|
.image = texture->GetBacking(),
|
||||||
.viewType = type,
|
.viewType = type,
|
||||||
@ -36,7 +42,10 @@ namespace skyline::gpu {
|
|||||||
.subresourceRange = range,
|
.subresourceRange = range,
|
||||||
};
|
};
|
||||||
|
|
||||||
return *view.emplace(texture->gpu.vkDevice, createInfo);
|
it = texture->views.emplace(texture->views.end(), type, format, mapping, range, vk::raii::ImageView{texture->gpu.vkDevice, createInfo});
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkView = *it->vkView;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureView::lock() {
|
void TextureView::lock() {
|
||||||
@ -530,22 +539,10 @@ namespace skyline::gpu {
|
|||||||
if (!pFormat)
|
if (!pFormat)
|
||||||
pFormat = format;
|
pFormat = format;
|
||||||
|
|
||||||
for (auto viewIt{views.begin()}; viewIt != views.end();) {
|
|
||||||
auto view{viewIt->lock()};
|
|
||||||
if (view && type == view->type && pFormat == view->format && range == view->range && mapping == view->mapping)
|
|
||||||
return view;
|
|
||||||
else if (!view)
|
|
||||||
viewIt = views.erase(viewIt);
|
|
||||||
else
|
|
||||||
++viewIt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gpu.traits.quirks.vkImageMutableFormatCostly && pFormat->vkFormat != format->vkFormat)
|
if (gpu.traits.quirks.vkImageMutableFormatCostly && pFormat->vkFormat != format->vkFormat)
|
||||||
Logger::Warn("Creating a view of a texture with a different format without mutable format: {} - {}", vk::to_string(pFormat->vkFormat), vk::to_string(format->vkFormat));
|
Logger::Warn("Creating a view of a texture with a different format without mutable format: {} - {}", vk::to_string(pFormat->vkFormat), vk::to_string(format->vkFormat));
|
||||||
|
|
||||||
auto view{std::make_shared<TextureView>(shared_from_this(), type, range, pFormat, mapping)};
|
return std::make_shared<TextureView>(shared_from_this(), type, range, pFormat, mapping);
|
||||||
views.push_back(view);
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::CopyFrom(std::shared_ptr<Texture> source, const vk::ImageSubresourceRange &subresource) {
|
void Texture::CopyFrom(std::shared_ptr<Texture> source, const vk::ImageSubresourceRange &subresource) {
|
||||||
|
@ -284,7 +284,7 @@ namespace skyline::gpu {
|
|||||||
*/
|
*/
|
||||||
class TextureView : public FenceCycleDependency, public std::enable_shared_from_this<TextureView> {
|
class TextureView : public FenceCycleDependency, public std::enable_shared_from_this<TextureView> {
|
||||||
private:
|
private:
|
||||||
std::optional<vk::raii::ImageView> view;
|
vk::ImageView vkView{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<Texture> texture;
|
std::shared_ptr<Texture> texture;
|
||||||
@ -348,7 +348,20 @@ namespace skyline::gpu {
|
|||||||
GpuDirty, //!< The GPU texture has been modified but the CPU mappings have not been updated
|
GpuDirty, //!< The GPU texture has been modified but the CPU mappings have not been updated
|
||||||
} dirtyState{DirtyState::CpuDirty}; //!< The state of the CPU mappings with respect to the GPU texture
|
} dirtyState{DirtyState::CpuDirty}; //!< The state of the CPU mappings with respect to the GPU texture
|
||||||
|
|
||||||
std::vector<std::weak_ptr<TextureView>> views; //!< TextureView(s) that are backed by this Texture, used for repointing to a new Texture on deletion
|
/**
|
||||||
|
* @brief Storage for all metadata about a specific view into the buffer, used to prevent redundant view creation and duplication of VkBufferView(s)
|
||||||
|
*/
|
||||||
|
struct TextureViewStorage {
|
||||||
|
vk::ImageViewType type;
|
||||||
|
texture::Format format;
|
||||||
|
vk::ComponentMapping mapping;
|
||||||
|
vk::ImageSubresourceRange range;
|
||||||
|
vk::raii::ImageView vkView;
|
||||||
|
|
||||||
|
TextureViewStorage(vk::ImageViewType type, texture::Format format, vk::ComponentMapping mapping, vk::ImageSubresourceRange range, vk::raii::ImageView&& vkView);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<TextureViewStorage> views;
|
||||||
|
|
||||||
friend TextureManager;
|
friend TextureManager;
|
||||||
friend TextureView;
|
friend TextureView;
|
||||||
|
Loading…
Reference in New Issue
Block a user