mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-25 19:02:45 -06:00
renderer_vulkan: Use VMA for images
This commit is contained in:
parent
c60eed36b7
commit
48e39756f1
16 changed files with 119 additions and 91 deletions
|
@ -173,7 +173,7 @@ void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& fr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
|
const Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
|
||||||
vk::Image staging_image = device.GetLogical().CreateImage(VkImageCreateInfo{
|
vk::Image staging_image = memory_allocator.CreateImage(VkImageCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
|
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
|
||||||
|
@ -196,7 +196,6 @@ void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& fr
|
||||||
.pQueueFamilyIndices = nullptr,
|
.pQueueFamilyIndices = nullptr,
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
});
|
});
|
||||||
const auto image_commit = memory_allocator.Commit(staging_image, MemoryUsage::DeviceLocal);
|
|
||||||
|
|
||||||
const vk::ImageView dst_view = device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
const vk::ImageView dst_view = device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
|
|
|
@ -1071,12 +1071,8 @@ void BlitScreen::ReleaseRawImages() {
|
||||||
scheduler.Wait(tick);
|
scheduler.Wait(tick);
|
||||||
}
|
}
|
||||||
raw_images.clear();
|
raw_images.clear();
|
||||||
raw_buffer_commits.clear();
|
|
||||||
|
|
||||||
aa_image_view.reset();
|
aa_image_view.reset();
|
||||||
aa_image.reset();
|
aa_image.reset();
|
||||||
aa_commit = MemoryCommit{};
|
|
||||||
|
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
buffer_commit = MemoryCommit{};
|
buffer_commit = MemoryCommit{};
|
||||||
}
|
}
|
||||||
|
@ -1101,13 +1097,12 @@ void BlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer
|
||||||
void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||||
raw_images.resize(image_count);
|
raw_images.resize(image_count);
|
||||||
raw_image_views.resize(image_count);
|
raw_image_views.resize(image_count);
|
||||||
raw_buffer_commits.resize(image_count);
|
|
||||||
|
|
||||||
const auto create_image = [&](bool used_on_framebuffer = false, u32 up_scale = 1,
|
const auto create_image = [&](bool used_on_framebuffer = false, u32 up_scale = 1,
|
||||||
u32 down_shift = 0) {
|
u32 down_shift = 0) {
|
||||||
u32 extra_usages = used_on_framebuffer ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
u32 extra_usages = used_on_framebuffer ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
||||||
: VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
: VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
return device.GetLogical().CreateImage(VkImageCreateInfo{
|
return memory_allocator.CreateImage(VkImageCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -1130,9 +1125,6 @@ void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const auto create_commit = [&](vk::Image& image) {
|
|
||||||
return memory_allocator.Commit(image, MemoryUsage::DeviceLocal);
|
|
||||||
};
|
|
||||||
const auto create_image_view = [&](vk::Image& image, bool used_on_framebuffer = false) {
|
const auto create_image_view = [&](vk::Image& image, bool used_on_framebuffer = false) {
|
||||||
return device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
return device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
|
@ -1161,7 +1153,6 @@ void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||||
|
|
||||||
for (size_t i = 0; i < image_count; ++i) {
|
for (size_t i = 0; i < image_count; ++i) {
|
||||||
raw_images[i] = create_image();
|
raw_images[i] = create_image();
|
||||||
raw_buffer_commits[i] = create_commit(raw_images[i]);
|
|
||||||
raw_image_views[i] = create_image_view(raw_images[i]);
|
raw_image_views[i] = create_image_view(raw_images[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,7 +1160,6 @@ void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||||
const u32 up_scale = Settings::values.resolution_info.up_scale;
|
const u32 up_scale = Settings::values.resolution_info.up_scale;
|
||||||
const u32 down_shift = Settings::values.resolution_info.down_shift;
|
const u32 down_shift = Settings::values.resolution_info.down_shift;
|
||||||
aa_image = create_image(true, up_scale, down_shift);
|
aa_image = create_image(true, up_scale, down_shift);
|
||||||
aa_commit = create_commit(aa_image);
|
|
||||||
aa_image_view = create_image_view(aa_image, true);
|
aa_image_view = create_image_view(aa_image, true);
|
||||||
VkExtent2D size{
|
VkExtent2D size{
|
||||||
.width = (up_scale * framebuffer.width) >> down_shift,
|
.width = (up_scale * framebuffer.width) >> down_shift,
|
||||||
|
|
|
@ -148,7 +148,6 @@ private:
|
||||||
|
|
||||||
std::vector<vk::Image> raw_images;
|
std::vector<vk::Image> raw_images;
|
||||||
std::vector<vk::ImageView> raw_image_views;
|
std::vector<vk::ImageView> raw_image_views;
|
||||||
std::vector<MemoryCommit> raw_buffer_commits;
|
|
||||||
|
|
||||||
vk::DescriptorPool aa_descriptor_pool;
|
vk::DescriptorPool aa_descriptor_pool;
|
||||||
vk::DescriptorSetLayout aa_descriptor_set_layout;
|
vk::DescriptorSetLayout aa_descriptor_set_layout;
|
||||||
|
@ -159,7 +158,6 @@ private:
|
||||||
vk::DescriptorSets aa_descriptor_sets;
|
vk::DescriptorSets aa_descriptor_sets;
|
||||||
vk::Image aa_image;
|
vk::Image aa_image;
|
||||||
vk::ImageView aa_image_view;
|
vk::ImageView aa_image_view;
|
||||||
MemoryCommit aa_commit;
|
|
||||||
|
|
||||||
u32 raw_width = 0;
|
u32 raw_width = 0;
|
||||||
u32 raw_height = 0;
|
u32 raw_height = 0;
|
||||||
|
|
|
@ -205,10 +205,9 @@ void FSR::CreateDescriptorSets() {
|
||||||
void FSR::CreateImages() {
|
void FSR::CreateImages() {
|
||||||
images.resize(image_count * 2);
|
images.resize(image_count * 2);
|
||||||
image_views.resize(image_count * 2);
|
image_views.resize(image_count * 2);
|
||||||
buffer_commits.resize(image_count * 2);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < image_count * 2; ++i) {
|
for (size_t i = 0; i < image_count * 2; ++i) {
|
||||||
images[i] = device.GetLogical().CreateImage(VkImageCreateInfo{
|
images[i] = memory_allocator.CreateImage(VkImageCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -231,7 +230,6 @@ void FSR::CreateImages() {
|
||||||
.pQueueFamilyIndices = nullptr,
|
.pQueueFamilyIndices = nullptr,
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
});
|
});
|
||||||
buffer_commits[i] = memory_allocator.Commit(images[i], MemoryUsage::DeviceLocal);
|
|
||||||
image_views[i] = device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
image_views[i] = device.GetLogical().CreateImageView(VkImageViewCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
|
|
|
@ -47,7 +47,6 @@ private:
|
||||||
vk::Sampler sampler;
|
vk::Sampler sampler;
|
||||||
std::vector<vk::Image> images;
|
std::vector<vk::Image> images;
|
||||||
std::vector<vk::ImageView> image_views;
|
std::vector<vk::ImageView> image_views;
|
||||||
std::vector<MemoryCommit> buffer_commits;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -181,7 +181,7 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, bool is_
|
||||||
frame->height = height;
|
frame->height = height;
|
||||||
frame->is_srgb = is_srgb;
|
frame->is_srgb = is_srgb;
|
||||||
|
|
||||||
frame->image = dld.CreateImage({
|
frame->image = memory_allocator.CreateImage({
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
|
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
|
||||||
|
@ -204,8 +204,6 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, bool is_
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
});
|
});
|
||||||
|
|
||||||
frame->image_commit = memory_allocator.Commit(frame->image, MemoryUsage::DeviceLocal);
|
|
||||||
|
|
||||||
frame->image_view = dld.CreateImageView({
|
frame->image_view = dld.CreateImageView({
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
|
|
|
@ -29,7 +29,6 @@ struct Frame {
|
||||||
vk::Image image;
|
vk::Image image;
|
||||||
vk::ImageView image_view;
|
vk::ImageView image_view;
|
||||||
vk::Framebuffer framebuffer;
|
vk::Framebuffer framebuffer;
|
||||||
MemoryCommit image_commit;
|
|
||||||
vk::CommandBuffer cmdbuf;
|
vk::CommandBuffer cmdbuf;
|
||||||
vk::Semaphore render_ready;
|
vk::Semaphore render_ready;
|
||||||
vk::Fence present_done;
|
vk::Fence present_done;
|
||||||
|
|
|
@ -25,9 +25,7 @@ namespace {
|
||||||
|
|
||||||
#define ARRAY_TO_SPAN(a) std::span(a, (sizeof(a) / sizeof(a[0])))
|
#define ARRAY_TO_SPAN(a) std::span(a, (sizeof(a) / sizeof(a[0])))
|
||||||
|
|
||||||
std::pair<vk::Image, MemoryCommit> CreateWrappedImage(const Device& device,
|
vk::Image CreateWrappedImage(MemoryAllocator& allocator, VkExtent2D dimensions, VkFormat format) {
|
||||||
MemoryAllocator& allocator,
|
|
||||||
VkExtent2D dimensions, VkFormat format) {
|
|
||||||
const VkImageCreateInfo image_ci{
|
const VkImageCreateInfo image_ci{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
|
@ -46,11 +44,7 @@ std::pair<vk::Image, MemoryCommit> CreateWrappedImage(const Device& device,
|
||||||
.pQueueFamilyIndices = nullptr,
|
.pQueueFamilyIndices = nullptr,
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
};
|
};
|
||||||
|
return allocator.CreateImage(image_ci);
|
||||||
auto image = device.GetLogical().CreateImage(image_ci);
|
|
||||||
auto commit = allocator.Commit(image, Vulkan::MemoryUsage::DeviceLocal);
|
|
||||||
|
|
||||||
return std::make_pair(std::move(image), std::move(commit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout,
|
void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout,
|
||||||
|
@ -531,10 +525,8 @@ void SMAA::CreateImages() {
|
||||||
static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
|
static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
|
||||||
static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
|
static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
|
||||||
|
|
||||||
std::tie(m_static_images[Area], m_static_buffer_commits[Area]) =
|
m_static_images[Area] = CreateWrappedImage(m_allocator, area_extent, VK_FORMAT_R8G8_UNORM);
|
||||||
CreateWrappedImage(m_device, m_allocator, area_extent, VK_FORMAT_R8G8_UNORM);
|
m_static_images[Search] = CreateWrappedImage(m_allocator, search_extent, VK_FORMAT_R8_UNORM);
|
||||||
std::tie(m_static_images[Search], m_static_buffer_commits[Search]) =
|
|
||||||
CreateWrappedImage(m_device, m_allocator, search_extent, VK_FORMAT_R8_UNORM);
|
|
||||||
|
|
||||||
m_static_image_views[Area] =
|
m_static_image_views[Area] =
|
||||||
CreateWrappedImageView(m_device, m_static_images[Area], VK_FORMAT_R8G8_UNORM);
|
CreateWrappedImageView(m_device, m_static_images[Area], VK_FORMAT_R8G8_UNORM);
|
||||||
|
@ -544,12 +536,11 @@ void SMAA::CreateImages() {
|
||||||
for (u32 i = 0; i < m_image_count; i++) {
|
for (u32 i = 0; i < m_image_count; i++) {
|
||||||
Images& images = m_dynamic_images.emplace_back();
|
Images& images = m_dynamic_images.emplace_back();
|
||||||
|
|
||||||
std::tie(images.images[Blend], images.buffer_commits[Blend]) =
|
images.images[Blend] =
|
||||||
CreateWrappedImage(m_device, m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
std::tie(images.images[Edges], images.buffer_commits[Edges]) =
|
images.images[Edges] = CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16_SFLOAT);
|
||||||
CreateWrappedImage(m_device, m_allocator, m_extent, VK_FORMAT_R16G16_SFLOAT);
|
images.images[Output] =
|
||||||
std::tie(images.images[Output], images.buffer_commits[Output]) =
|
CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
CreateWrappedImage(m_device, m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
|
||||||
|
|
||||||
images.image_views[Blend] =
|
images.image_views[Blend] =
|
||||||
CreateWrappedImageView(m_device, images.images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT);
|
CreateWrappedImageView(m_device, images.images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
|
|
|
@ -66,13 +66,11 @@ private:
|
||||||
std::array<vk::Pipeline, MaxSMAAStage> m_pipelines{};
|
std::array<vk::Pipeline, MaxSMAAStage> m_pipelines{};
|
||||||
std::array<vk::RenderPass, MaxSMAAStage> m_renderpasses{};
|
std::array<vk::RenderPass, MaxSMAAStage> m_renderpasses{};
|
||||||
|
|
||||||
std::array<MemoryCommit, MaxStaticImage> m_static_buffer_commits;
|
|
||||||
std::array<vk::Image, MaxStaticImage> m_static_images{};
|
std::array<vk::Image, MaxStaticImage> m_static_images{};
|
||||||
std::array<vk::ImageView, MaxStaticImage> m_static_image_views{};
|
std::array<vk::ImageView, MaxStaticImage> m_static_image_views{};
|
||||||
|
|
||||||
struct Images {
|
struct Images {
|
||||||
vk::DescriptorSets descriptor_sets{};
|
vk::DescriptorSets descriptor_sets{};
|
||||||
std::array<MemoryCommit, MaxDynamicImage> buffer_commits;
|
|
||||||
std::array<vk::Image, MaxDynamicImage> images{};
|
std::array<vk::Image, MaxDynamicImage> images{};
|
||||||
std::array<vk::ImageView, MaxDynamicImage> image_views{};
|
std::array<vk::ImageView, MaxDynamicImage> image_views{};
|
||||||
std::array<vk::Framebuffer, MaxSMAAStage> framebuffers{};
|
std::array<vk::Framebuffer, MaxSMAAStage> framebuffers{};
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "video_core/renderer_vulkan/blit_image.h"
|
#include "video_core/renderer_vulkan/blit_image.h"
|
||||||
#include "video_core/renderer_vulkan/maxwell_to_vk.h"
|
#include "video_core/renderer_vulkan/maxwell_to_vk.h"
|
||||||
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
||||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
|
||||||
#include "video_core/renderer_vulkan/vk_render_pass_cache.h"
|
#include "video_core/renderer_vulkan/vk_render_pass_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
|
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
|
||||||
|
@ -163,11 +162,12 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] vk::Image MakeImage(const Device& device, const ImageInfo& info) {
|
[[nodiscard]] vk::Image MakeImage(const Device& device, const MemoryAllocator& allocator,
|
||||||
|
const ImageInfo& info) {
|
||||||
if (info.type == ImageType::Buffer) {
|
if (info.type == ImageType::Buffer) {
|
||||||
return vk::Image{};
|
return vk::Image{};
|
||||||
}
|
}
|
||||||
return device.GetLogical().CreateImage(MakeImageCreateInfo(device, info));
|
return allocator.CreateImage(MakeImageCreateInfo(device, info));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] VkImageAspectFlags ImageAspectMask(PixelFormat format) {
|
[[nodiscard]] VkImageAspectFlags ImageAspectMask(PixelFormat format) {
|
||||||
|
@ -1266,8 +1266,8 @@ void TextureCacheRuntime::TickFrame() {}
|
||||||
Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_,
|
Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_,
|
||||||
VAddr cpu_addr_)
|
VAddr cpu_addr_)
|
||||||
: VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler},
|
: VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler},
|
||||||
runtime{&runtime_}, original_image(MakeImage(runtime_.device, info)),
|
runtime{&runtime_},
|
||||||
commit(runtime_.memory_allocator.Commit(original_image, MemoryUsage::DeviceLocal)),
|
original_image(MakeImage(runtime_.device, runtime_.memory_allocator, info)),
|
||||||
aspect_mask(ImageAspectMask(info.format)) {
|
aspect_mask(ImageAspectMask(info.format)) {
|
||||||
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
|
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
|
||||||
if (Settings::values.async_astc.GetValue()) {
|
if (Settings::values.async_astc.GetValue()) {
|
||||||
|
@ -1467,9 +1467,7 @@ bool Image::ScaleUp(bool ignore) {
|
||||||
auto scaled_info = info;
|
auto scaled_info = info;
|
||||||
scaled_info.size.width = scaled_width;
|
scaled_info.size.width = scaled_width;
|
||||||
scaled_info.size.height = scaled_height;
|
scaled_info.size.height = scaled_height;
|
||||||
scaled_image = MakeImage(runtime->device, scaled_info);
|
scaled_image = MakeImage(runtime->device, runtime->memory_allocator, scaled_info);
|
||||||
auto& allocator = runtime->memory_allocator;
|
|
||||||
scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal));
|
|
||||||
ignore = false;
|
ignore = false;
|
||||||
}
|
}
|
||||||
current_image = *scaled_image;
|
current_image = *scaled_image;
|
||||||
|
|
|
@ -180,12 +180,10 @@ private:
|
||||||
TextureCacheRuntime* runtime{};
|
TextureCacheRuntime* runtime{};
|
||||||
|
|
||||||
vk::Image original_image;
|
vk::Image original_image;
|
||||||
MemoryCommit commit;
|
|
||||||
std::vector<vk::ImageView> storage_image_views;
|
std::vector<vk::ImageView> storage_image_views;
|
||||||
VkImageAspectFlags aspect_mask = 0;
|
VkImageAspectFlags aspect_mask = 0;
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
vk::Image scaled_image{};
|
vk::Image scaled_image{};
|
||||||
MemoryCommit scaled_commit{};
|
|
||||||
VkImage current_image{};
|
VkImage current_image{};
|
||||||
|
|
||||||
std::unique_ptr<Framebuffer> scale_framebuffer;
|
std::unique_ptr<Framebuffer> scale_framebuffer;
|
||||||
|
|
|
@ -210,6 +210,11 @@ public:
|
||||||
return dld;
|
return dld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the VMA allocator.
|
||||||
|
VmaAllocator GetAllocator() const {
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the logical device.
|
/// Returns the logical device.
|
||||||
const vk::Device& GetLogical() const {
|
const vk::Device& GetLogical() const {
|
||||||
return logical;
|
return logical;
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
||||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
namespace {
|
namespace {
|
||||||
struct Range {
|
struct Range {
|
||||||
|
@ -180,6 +184,24 @@ MemoryAllocator::MemoryAllocator(const Device& device_)
|
||||||
|
|
||||||
MemoryAllocator::~MemoryAllocator() = default;
|
MemoryAllocator::~MemoryAllocator() = default;
|
||||||
|
|
||||||
|
vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const {
|
||||||
|
const VmaAllocationCreateInfo alloc_info = {
|
||||||
|
.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT,
|
||||||
|
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||||
|
.requiredFlags = 0,
|
||||||
|
.preferredFlags = 0,
|
||||||
|
.pool = VK_NULL_HANDLE,
|
||||||
|
.pUserData = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImage handle{};
|
||||||
|
VmaAllocation allocation{};
|
||||||
|
vk::Check(
|
||||||
|
vmaCreateImage(device.GetAllocator(), &ci, &alloc_info, &handle, &allocation, nullptr));
|
||||||
|
return vk::Image(handle, *device.GetLogical(), device.GetAllocator(), allocation,
|
||||||
|
device.GetDispatchLoader());
|
||||||
|
}
|
||||||
|
|
||||||
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) {
|
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) {
|
||||||
// Find the fastest memory flags we can afford with the current requirements
|
// Find the fastest memory flags we can afford with the current requirements
|
||||||
const u32 type_mask = requirements.memoryTypeBits;
|
const u32 type_mask = requirements.memoryTypeBits;
|
||||||
|
@ -205,14 +227,6 @@ MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage
|
||||||
return commit;
|
return commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) {
|
|
||||||
VkMemoryRequirements requirements = device.GetLogical().GetImageMemoryRequirements(*image);
|
|
||||||
requirements.size = Common::AlignUp(requirements.size, buffer_image_granularity);
|
|
||||||
auto commit = Commit(requirements, usage);
|
|
||||||
image.BindMemory(commit.Memory(), commit.Offset());
|
|
||||||
return commit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) {
|
bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) {
|
||||||
const u32 type = FindType(flags, type_mask).value();
|
const u32 type = FindType(flags, type_mask).value();
|
||||||
vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({
|
vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({
|
||||||
|
|
|
@ -80,6 +80,8 @@ public:
|
||||||
MemoryAllocator& operator=(const MemoryAllocator&) = delete;
|
MemoryAllocator& operator=(const MemoryAllocator&) = delete;
|
||||||
MemoryAllocator(const MemoryAllocator&) = delete;
|
MemoryAllocator(const MemoryAllocator&) = delete;
|
||||||
|
|
||||||
|
vk::Image CreateImage(const VkImageCreateInfo& ci) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commits a memory with the specified requirements.
|
* Commits a memory with the specified requirements.
|
||||||
*
|
*
|
||||||
|
@ -93,9 +95,6 @@ public:
|
||||||
/// Commits memory required by the buffer and binds it.
|
/// Commits memory required by the buffer and binds it.
|
||||||
MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage);
|
MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage);
|
||||||
|
|
||||||
/// Commits memory required by the image and binds it.
|
|
||||||
MemoryCommit Commit(const vk::Image& image, MemoryUsage usage);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Tries to allocate a chunk of memory.
|
/// Tries to allocate a chunk of memory.
|
||||||
bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size);
|
bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size);
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
|
|
||||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
namespace Vulkan::vk {
|
namespace Vulkan::vk {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -547,6 +551,16 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger(
|
||||||
return DebugUtilsMessenger(object, handle, *dld);
|
return DebugUtilsMessenger(object, handle, *dld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::SetObjectNameEXT(const char* name) const {
|
||||||
|
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::Release() const noexcept {
|
||||||
|
if (handle) {
|
||||||
|
vmaDestroyImage(allocator, handle, allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const {
|
void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const {
|
||||||
Check(dld->vkBindBufferMemory(owner, handle, memory, offset));
|
Check(dld->vkBindBufferMemory(owner, handle, memory, offset));
|
||||||
}
|
}
|
||||||
|
@ -559,14 +573,6 @@ void BufferView::SetObjectNameEXT(const char* name) const {
|
||||||
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name);
|
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const {
|
|
||||||
Check(dld->vkBindImageMemory(owner, handle, memory, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::SetObjectNameEXT(const char* name) const {
|
|
||||||
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageView::SetObjectNameEXT(const char* name) const {
|
void ImageView::SetObjectNameEXT(const char* name) const {
|
||||||
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name);
|
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name);
|
||||||
}
|
}
|
||||||
|
@ -713,12 +719,6 @@ BufferView Device::CreateBufferView(const VkBufferViewCreateInfo& ci) const {
|
||||||
return BufferView(object, handle, *dld);
|
return BufferView(object, handle, *dld);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image Device::CreateImage(const VkImageCreateInfo& ci) const {
|
|
||||||
VkImage object;
|
|
||||||
Check(dld->vkCreateImage(handle, &ci, nullptr, &object));
|
|
||||||
return Image(object, handle, *dld);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const {
|
ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const {
|
||||||
VkImageView object;
|
VkImageView object;
|
||||||
Check(dld->vkCreateImageView(handle, &ci, nullptr, &object));
|
Check(dld->vkCreateImageView(handle, &ci, nullptr, &object));
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#pragma warning(disable : 26812) // Disable prefer enum class over enum
|
#pragma warning(disable : 26812) // Disable prefer enum class over enum
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
|
VK_DEFINE_HANDLE(VmaAllocation)
|
||||||
|
|
||||||
namespace Vulkan::vk {
|
namespace Vulkan::vk {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -616,6 +619,60 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Image {
|
||||||
|
public:
|
||||||
|
explicit Image(VkImage handle_, VkDevice owner_, VmaAllocator allocator_,
|
||||||
|
VmaAllocation allocation_, const DeviceDispatch& dld_) noexcept
|
||||||
|
: handle{handle_}, owner{owner_}, allocator{allocator_},
|
||||||
|
allocation{allocation_}, dld{&dld_} {}
|
||||||
|
Image() = default;
|
||||||
|
|
||||||
|
Image(const Image&) = delete;
|
||||||
|
Image& operator=(const Image&) = delete;
|
||||||
|
|
||||||
|
Image(Image&& rhs) noexcept
|
||||||
|
: handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator},
|
||||||
|
allocation{rhs.allocation}, dld{rhs.dld} {}
|
||||||
|
|
||||||
|
Image& operator=(Image&& rhs) noexcept {
|
||||||
|
Release();
|
||||||
|
handle = std::exchange(rhs.handle, nullptr);
|
||||||
|
owner = rhs.owner;
|
||||||
|
allocator = rhs.allocator;
|
||||||
|
allocation = rhs.allocation;
|
||||||
|
dld = rhs.dld;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Image() noexcept {
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImage operator*() const noexcept {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() noexcept {
|
||||||
|
Release();
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept {
|
||||||
|
return handle != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetObjectNameEXT(const char* name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Release() const noexcept;
|
||||||
|
|
||||||
|
VkImage handle = nullptr;
|
||||||
|
VkDevice owner = nullptr;
|
||||||
|
VmaAllocator allocator = nullptr;
|
||||||
|
VmaAllocation allocation = nullptr;
|
||||||
|
const DeviceDispatch* dld = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
class Queue {
|
class Queue {
|
||||||
public:
|
public:
|
||||||
/// Construct an empty queue handle.
|
/// Construct an empty queue handle.
|
||||||
|
@ -658,17 +715,6 @@ public:
|
||||||
void SetObjectNameEXT(const char* name) const;
|
void SetObjectNameEXT(const char* name) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Image : public Handle<VkImage, VkDevice, DeviceDispatch> {
|
|
||||||
using Handle<VkImage, VkDevice, DeviceDispatch>::Handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Attaches a memory allocation.
|
|
||||||
void BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const;
|
|
||||||
|
|
||||||
/// Set object name.
|
|
||||||
void SetObjectNameEXT(const char* name) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImageView : public Handle<VkImageView, VkDevice, DeviceDispatch> {
|
class ImageView : public Handle<VkImageView, VkDevice, DeviceDispatch> {
|
||||||
using Handle<VkImageView, VkDevice, DeviceDispatch>::Handle;
|
using Handle<VkImageView, VkDevice, DeviceDispatch>::Handle;
|
||||||
|
|
||||||
|
@ -844,8 +890,6 @@ public:
|
||||||
|
|
||||||
BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const;
|
BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const;
|
||||||
|
|
||||||
Image CreateImage(const VkImageCreateInfo& ci) const;
|
|
||||||
|
|
||||||
ImageView CreateImageView(const VkImageViewCreateInfo& ci) const;
|
ImageView CreateImageView(const VkImageViewCreateInfo& ci) const;
|
||||||
|
|
||||||
Semaphore CreateSemaphore() const;
|
Semaphore CreateSemaphore() const;
|
||||||
|
|
Loading…
Reference in a new issue