renderer_vulkan: Allow direct allocation of images
This commit is contained in:
@@ -187,7 +187,9 @@ RasterizerVulkan::~RasterizerVulkan() {
|
||||
vmaDestroyImage(allocator, default_texture.image, default_texture.allocation);
|
||||
vmaDestroyImage(allocator, default_storage_texture.image, default_storage_texture.allocation);
|
||||
device.destroyImageView(default_texture.image_view);
|
||||
device.destroyImageView(default_texture.base_view);
|
||||
device.destroyImageView(default_storage_texture.image_view);
|
||||
device.destroyImageView(default_storage_texture.base_view);
|
||||
device.destroySampler(default_sampler);
|
||||
}
|
||||
|
||||
@@ -1635,63 +1637,14 @@ vk::Framebuffer RasterizerVulkan::CreateFramebuffer(const FramebufferInfo& info)
|
||||
}
|
||||
|
||||
void RasterizerVulkan::CreateDefaultTextures() {
|
||||
default_texture.format = vk::Format::eR8G8B8A8Unorm;
|
||||
default_storage_texture.format = vk::Format::eR8G8B8A8Uint;
|
||||
const vk::ImageUsageFlags usage = GetImageUsage(vk::ImageAspectFlagBits::eColor);
|
||||
default_texture = runtime.Allocate(1, 1, 1, 1, vk::Format::eR8G8B8A8Unorm, usage, {});
|
||||
default_storage_texture = runtime.Allocate(1, 1, 1, 1, vk::Format::eR8G8B8A8Uint, usage, {});
|
||||
|
||||
vk::ImageCreateInfo image_info = {.imageType = vk::ImageType::e2D,
|
||||
.format = default_texture.format,
|
||||
.extent = {1, 1, 1},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.samples = vk::SampleCountFlagBits::e1,
|
||||
.usage = GetImageUsage(vk::ImageAspectFlagBits::eColor)};
|
||||
|
||||
const VmaAllocationCreateInfo alloc_info = {.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE};
|
||||
|
||||
VkImage unsafe_image{};
|
||||
VkImageCreateInfo& unsafe_image_info = static_cast<VkImageCreateInfo&>(image_info);
|
||||
|
||||
VkResult result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info, &alloc_info,
|
||||
&unsafe_image, &default_texture.allocation, nullptr);
|
||||
if (result != VK_SUCCESS) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed allocating default texture with error {}", result);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
default_texture.image = vk::Image{unsafe_image};
|
||||
vk::ImageViewCreateInfo view_info = {
|
||||
.image = default_texture.image,
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = default_texture.format,
|
||||
.subresourceRange = {.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1}};
|
||||
|
||||
vk::Device device = instance.GetDevice();
|
||||
default_texture.image_view = device.createImageView(view_info);
|
||||
|
||||
// Define the default texture for storage descriptors
|
||||
image_info.format = default_storage_texture.format;
|
||||
result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info, &alloc_info, &unsafe_image,
|
||||
&default_storage_texture.allocation, nullptr);
|
||||
if (result != VK_SUCCESS) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed allocating default storage texture with error {}",
|
||||
result);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
default_storage_texture.image = vk::Image{unsafe_image};
|
||||
|
||||
view_info.format = default_storage_texture.format;
|
||||
view_info.image = default_storage_texture.image;
|
||||
default_storage_texture.image_view = device.createImageView(view_info);
|
||||
|
||||
runtime.Transition(scheduler.GetUploadCommandBuffer(), default_texture,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal, 0, 1);
|
||||
runtime.Transition(scheduler.GetUploadCommandBuffer(), default_storage_texture,
|
||||
vk::ImageLayout::eGeneral, 0, 1);
|
||||
const vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer();
|
||||
runtime.Transition(command_buffer, default_texture, vk::ImageLayout::eShaderReadOnlyOptimal, 0,
|
||||
1);
|
||||
runtime.Transition(command_buffer, default_storage_texture, vk::ImageLayout::eGeneral, 0, 1);
|
||||
}
|
||||
|
||||
void RasterizerVulkan::FlushBuffers() {
|
||||
|
@@ -100,8 +100,9 @@ void TextureRuntime::OnSlotSwitch(u32 new_slot) {
|
||||
|
||||
ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelFormat format,
|
||||
VideoCore::TextureType type) {
|
||||
|
||||
const u32 levels = std::bit_width(std::max(width, height));
|
||||
const u32 layers = type == VideoCore::TextureType::CubeMap ? 6 : 1;
|
||||
|
||||
const VideoCore::HostTextureTag key = {
|
||||
.format = format, .width = width, .height = height, .layers = layers};
|
||||
|
||||
@@ -120,17 +121,25 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
||||
const vk::Format vk_format = is_suitable ? traits.native : traits.fallback;
|
||||
const vk::ImageUsageFlags vk_usage = is_suitable ? traits.usage : GetImageUsage(aspect);
|
||||
|
||||
const u32 levels = std::bit_width(std::max(width, height));
|
||||
const vk::ImageCreateInfo image_info = {.flags = type == VideoCore::TextureType::CubeMap
|
||||
const vk::ImageCreateFlags flags = type == VideoCore::TextureType::CubeMap
|
||||
? vk::ImageCreateFlagBits::eCubeCompatible
|
||||
: vk::ImageCreateFlags{},
|
||||
: vk::ImageCreateFlags{};
|
||||
|
||||
return Allocate(width, height, layers, levels, vk_format, vk_usage, flags);
|
||||
}
|
||||
|
||||
ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, u32 layers, u32 levels,
|
||||
vk::Format format, vk::ImageUsageFlags usage,
|
||||
vk::ImageCreateFlags flags) {
|
||||
const vk::ImageAspectFlags aspect = GetImageAspect(format);
|
||||
const vk::ImageCreateInfo image_info = {.flags = flags,
|
||||
.imageType = vk::ImageType::e2D,
|
||||
.format = vk_format,
|
||||
.format = format,
|
||||
.extent = {width, height, 1},
|
||||
.mipLevels = levels,
|
||||
.arrayLayers = layers,
|
||||
.samples = vk::SampleCountFlagBits::e1,
|
||||
.usage = vk_usage};
|
||||
.usage = usage};
|
||||
|
||||
const VmaAllocationCreateInfo alloc_info = {.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE};
|
||||
|
||||
@@ -145,12 +154,14 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
const vk::ImageViewType view_type = flags & vk::ImageCreateFlagBits::eCubeCompatible
|
||||
? vk::ImageViewType::eCube
|
||||
: vk::ImageViewType::e2D;
|
||||
|
||||
vk::Image image = vk::Image{unsafe_image};
|
||||
const vk::ImageViewCreateInfo view_info = {.image = image,
|
||||
.viewType = type == VideoCore::TextureType::CubeMap
|
||||
? vk::ImageViewType::eCube
|
||||
: vk::ImageViewType::e2D,
|
||||
.format = vk_format,
|
||||
.viewType = view_type,
|
||||
.format = format,
|
||||
.subresourceRange = {.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = levels,
|
||||
@@ -158,11 +169,9 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
||||
.layerCount = layers}};
|
||||
|
||||
// Also create a base mip view in case this is used as an attachment
|
||||
const vk::ImageViewCreateInfo base_view_info = {
|
||||
.image = image,
|
||||
.viewType = type == VideoCore::TextureType::CubeMap ? vk::ImageViewType::eCube
|
||||
: vk::ImageViewType::e2D,
|
||||
.format = vk_format,
|
||||
const vk::ImageViewCreateInfo base_view_info = {.image = image,
|
||||
.viewType = view_type,
|
||||
.format = format,
|
||||
.subresourceRange = {.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
@@ -176,12 +185,11 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
||||
// Create seperate depth/stencil views in case this gets reinterpreted with a compute shader
|
||||
vk::ImageView depth_view;
|
||||
vk::ImageView stencil_view;
|
||||
if (format == VideoCore::PixelFormat::D24S8) {
|
||||
if (aspect & vk::ImageAspectFlagBits::eStencil) {
|
||||
vk::ImageViewCreateInfo view_info = {
|
||||
.image = image,
|
||||
.viewType = type == VideoCore::TextureType::CubeMap ? vk::ImageViewType::eCube
|
||||
: vk::ImageViewType::e2D,
|
||||
.format = vk_format,
|
||||
.viewType = view_type,
|
||||
.format = format,
|
||||
.subresourceRange = {.aspectMask = vk::ImageAspectFlagBits::eDepth,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = levels,
|
||||
@@ -199,7 +207,7 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
||||
.depth_view = depth_view,
|
||||
.stencil_view = stencil_view,
|
||||
.allocation = allocation,
|
||||
.format = vk_format,
|
||||
.format = format,
|
||||
.aspect = aspect,
|
||||
.levels = levels,
|
||||
.layers = layers};
|
||||
|
@@ -61,6 +61,11 @@ public:
|
||||
[[nodiscard]] ImageAlloc Allocate(u32 width, u32 height, VideoCore::PixelFormat format,
|
||||
VideoCore::TextureType type);
|
||||
|
||||
/// Allocates a vulkan image
|
||||
[[nodiscard]] ImageAlloc Allocate(u32 width, u32 height, u32 layers, u32 levels,
|
||||
vk::Format format, vk::ImageUsageFlags usage,
|
||||
vk::ImageCreateFlags flags);
|
||||
|
||||
/// Causes a GPU command flush
|
||||
void Finish();
|
||||
|
||||
|
Reference in New Issue
Block a user