summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/Texture2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/Texture2D.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/Texture2D.cpp404
1 files changed, 0 insertions, 404 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/Texture2D.cpp b/Source/Core/VideoBackends/Vulkan/Texture2D.cpp
deleted file mode 100644
index 96bfba6538..0000000000
--- a/Source/Core/VideoBackends/Vulkan/Texture2D.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2016 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#include <algorithm>
-
-#include "Common/Assert.h"
-#include "VideoBackends/Vulkan/CommandBufferManager.h"
-#include "VideoBackends/Vulkan/Texture2D.h"
-#include "VideoBackends/Vulkan/VulkanContext.h"
-
-namespace Vulkan
-{
-Texture2D::Texture2D(u32 width, u32 height, u32 levels, u32 layers, VkFormat format,
- VkSampleCountFlagBits samples, VkImageViewType view_type, VkImage image,
- VkDeviceMemory device_memory, VkImageView view)
- : m_width(width), m_height(height), m_levels(levels), m_layers(layers), m_format(format),
- m_samples(samples), m_view_type(view_type), m_image(image), m_device_memory(device_memory),
- m_view(view)
-{
-}
-
-Texture2D::~Texture2D()
-{
- g_command_buffer_mgr->DeferImageViewDestruction(m_view);
-
- // If we don't have device memory allocated, the image is not owned by us (e.g. swapchain)
- if (m_device_memory != VK_NULL_HANDLE)
- {
- g_command_buffer_mgr->DeferImageDestruction(m_image);
- g_command_buffer_mgr->DeferDeviceMemoryDestruction(m_device_memory);
- }
-}
-
-std::unique_ptr<Texture2D> Texture2D::Create(u32 width, u32 height, u32 levels, u32 layers,
- VkFormat format, VkSampleCountFlagBits samples,
- VkImageViewType view_type, VkImageTiling tiling,
- VkImageUsageFlags usage)
-{
- VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- nullptr,
- 0,
- VK_IMAGE_TYPE_2D,
- format,
- {width, height, 1},
- levels,
- layers,
- samples,
- tiling,
- usage,
- VK_SHARING_MODE_EXCLUSIVE,
- 0,
- nullptr,
- VK_IMAGE_LAYOUT_UNDEFINED};
-
- VkImage image = VK_NULL_HANDLE;
- VkResult res = vkCreateImage(g_vulkan_context->GetDevice(), &image_info, nullptr, &image);
- if (res != VK_SUCCESS)
- {
- LOG_VULKAN_ERROR(res, "vkCreateImage failed: ");
- return nullptr;
- }
-
- // Allocate memory to back this texture, we want device local memory in this case
- VkMemoryRequirements memory_requirements;
- vkGetImageMemoryRequirements(g_vulkan_context->GetDevice(), image, &memory_requirements);
-
- VkMemoryAllocateInfo memory_info = {
- VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr, memory_requirements.size,
- g_vulkan_context->GetMemoryType(memory_requirements.memoryTypeBits,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)};
-
- VkDeviceMemory device_memory;
- res = vkAllocateMemory(g_vulkan_context->GetDevice(), &memory_info, nullptr, &device_memory);
- if (res != VK_SUCCESS)
- {
- LOG_VULKAN_ERROR(res, "vkAllocateMemory failed: ");
- vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr);
- return nullptr;
- }
-
- res = vkBindImageMemory(g_vulkan_context->GetDevice(), image, device_memory, 0);
- if (res != VK_SUCCESS)
- {
- LOG_VULKAN_ERROR(res, "vkBindImageMemory failed: ");
- vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr);
- vkFreeMemory(g_vulkan_context->GetDevice(), device_memory, nullptr);
- return nullptr;
- }
-
- VkImageViewCreateInfo view_info = {
- VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- nullptr,
- 0,
- image,
- view_type,
- format,
- {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
- VK_COMPONENT_SWIZZLE_IDENTITY},
- {Util::IsDepthFormat(format) ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
- static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT),
- 0, levels, 0, layers}};
-
- VkImageView view = VK_NULL_HANDLE;
- res = vkCreateImageView(g_vulkan_context->GetDevice(), &view_info, nullptr, &view);
- if (res != VK_SUCCESS)
- {
- LOG_VULKAN_ERROR(res, "vkCreateImageView failed: ");
- vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr);
- vkFreeMemory(g_vulkan_context->GetDevice(), device_memory, nullptr);
- return nullptr;
- }
-
- return std::make_unique<Texture2D>(width, height, levels, layers, format, samples, view_type,
- image, device_memory, view);
-}
-
-std::unique_ptr<Texture2D> Texture2D::CreateFromExistingImage(u32 width, u32 height, u32 levels,
- u32 layers, VkFormat format,
- VkSampleCountFlagBits samples,
- VkImageViewType view_type,
- VkImage existing_image)
-{
- // Only need to create the image view, this is mainly for swap chains.
- VkImageViewCreateInfo view_info = {
- VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- nullptr,
- 0,
- existing_image,
- view_type,
- format,
- {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
- VK_COMPONENT_SWIZZLE_IDENTITY},
- {Util::IsDepthFormat(format) ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
- static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT),
- 0, levels, 0, layers}};
-
- // Memory is managed by the owner of the image.
- VkDeviceMemory memory = VK_NULL_HANDLE;
- VkImageView view = VK_NULL_HANDLE;
- VkResult res = vkCreateImageView(g_vulkan_context->GetDevice(), &view_info, nullptr, &view);
- if (res != VK_SUCCESS)
- {
- LOG_VULKAN_ERROR(res, "vkCreateImageView failed: ");
- return nullptr;
- }
-
- return std::make_unique<Texture2D>(width, height, levels, layers, format, samples, view_type,
- existing_image, memory, view);
-}
-
-void Texture2D::OverrideImageLayout(VkImageLayout new_layout)
-{
- m_layout = new_layout;
-}
-
-void Texture2D::TransitionToLayout(VkCommandBuffer command_buffer, VkImageLayout new_layout)
-{
- if (m_layout == new_layout)
- return;
-
- VkImageMemoryBarrier barrier = {
- VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
- nullptr, // const void* pNext
- 0, // VkAccessFlags srcAccessMask
- 0, // VkAccessFlags dstAccessMask
- m_layout, // VkImageLayout oldLayout
- new_layout, // VkImageLayout newLayout
- VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
- VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
- m_image, // VkImage image
- {Util::GetImageAspectForFormat(m_format), 0, m_levels, 0,
- m_layers} // VkImageSubresourceRange subresourceRange
- };
-
- // srcStageMask -> Stages that must complete before the barrier
- // dstStageMask -> Stages that must wait for after the barrier before beginning
- VkPipelineStageFlags srcStageMask, dstStageMask;
- switch (m_layout)
- {
- case VK_IMAGE_LAYOUT_UNDEFINED:
- // Layout undefined therefore contents undefined, and we don't care what happens to it.
- barrier.srcAccessMask = 0;
- srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_PREINITIALIZED:
- // Image has been pre-initialized by the host, so ensure all writes have completed.
- barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_HOST_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- // Image was being used as a color attachment, so ensure all writes have completed.
- barrier.srcAccessMask =
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- // Image was being used as a depthstencil attachment, so ensure all writes have completed.
- barrier.srcAccessMask =
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- srcStageMask =
- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
- // Image was being used as a shader resource, make sure all reads have finished.
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
- // Image was being used as a copy source, ensure all reads have finished.
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
- // Image was being used as a copy destination, ensure all writes have finished.
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- default:
- srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
- }
-
- switch (new_layout)
- {
- case VK_IMAGE_LAYOUT_UNDEFINED:
- barrier.dstAccessMask = 0;
- dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- barrier.dstAccessMask =
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- barrier.dstAccessMask =
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- dstStageMask =
- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
- srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
- dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
-
- default:
- dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- break;
- }
-
- // If we were using a compute layout, the stages need to reflect that
- switch (m_compute_layout)
- {
- case ComputeImageLayout::Undefined:
- break;
- case ComputeImageLayout::ReadOnly:
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- case ComputeImageLayout::WriteOnly:
- barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- case ComputeImageLayout::ReadWrite:
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- }
- m_compute_layout = ComputeImageLayout::Undefined;
-
- vkCmdPipelineBarrier(command_buffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1,
- &barrier);
-
- m_layout = new_layout;
-}
-
-void Texture2D::TransitionToLayout(VkCommandBuffer command_buffer, ComputeImageLayout new_layout)
-{
- ASSERT(new_layout != ComputeImageLayout::Undefined);
- if (m_compute_layout == new_layout)
- return;
-
- VkImageMemoryBarrier barrier = {
- VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
- nullptr, // const void* pNext
- 0, // VkAccessFlags srcAccessMask
- 0, // VkAccessFlags dstAccessMask
- m_layout, // VkImageLayout oldLayout
- VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
- VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
- VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
- m_image, // VkImage image
- {Util::GetImageAspectForFormat(m_format), 0, m_levels, 0,
- m_layers} // VkImageSubresourceRange subresourceRange
- };
-
- VkPipelineStageFlags srcStageMask, dstStageMask;
- switch (m_layout)
- {
- case VK_IMAGE_LAYOUT_UNDEFINED:
- // Layout undefined therefore contents undefined, and we don't care what happens to it.
- barrier.srcAccessMask = 0;
- srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_PREINITIALIZED:
- // Image has been pre-initialized by the host, so ensure all writes have completed.
- barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_HOST_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- // Image was being used as a color attachment, so ensure all writes have completed.
- barrier.srcAccessMask =
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- // Image was being used as a depthstencil attachment, so ensure all writes have completed.
- barrier.srcAccessMask =
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- srcStageMask =
- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
- // Image was being used as a shader resource, make sure all reads have finished.
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
- // Image was being used as a copy source, ensure all reads have finished.
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
- // Image was being used as a copy destination, ensure all writes have finished.
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- break;
-
- default:
- srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- break;
- }
-
- switch (new_layout)
- {
- case ComputeImageLayout::ReadOnly:
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- case ComputeImageLayout::WriteOnly:
- barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
- barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
- dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- case ComputeImageLayout::ReadWrite:
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
- dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- break;
- default:
- dstStageMask = 0;
- break;
- }
-
- m_layout = barrier.newLayout;
- m_compute_layout = new_layout;
-
- vkCmdPipelineBarrier(command_buffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1,
- &barrier);
-}
-
-} // namespace Vulkan