MythTV  master
mythtexturevulkan.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythlogging.h"
4 
5 #define LOC QString("VulkanTex: ")
6 
8  VkSampler Sampler, VkCommandBuffer CommandBuffer)
9 {
10  MythTextureVulkan* result = nullptr;
11  if (Image)
12  result = new MythTextureVulkan(Vulkan, Image, Sampler, CommandBuffer);
13 
14  if (result && !result->IsValidVulkan())
15  {
16  delete result;
17  result = nullptr;
18  }
19  return result;
20 }
21 
23  QImage *Image, VkSampler Sampler,
24  VkCommandBuffer CommandBuffer)
25  : MythVulkanObject(Vulkan),
26  MythComboBufferVulkan(Image->width(), Image->height())
27 {
28  if (!m_vulkanValid)
29  return;
30 
31  // retrieve and check Image data
32  auto datasize = static_cast<VkDeviceSize>((Image->width() * Image->height() * Image->depth()) >> 3);
33  auto datasize2 =
34 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
35  Image->sizeInBytes();
36 #else
37  Image->byteCount();
38 #endif
39  if (datasize != static_cast<VkDeviceSize>(datasize2))
40  LOG(VB_GENERAL, LOG_WARNING, LOC + "Inconsistent image data size");
41 
42  const auto *data = Image->constBits();
43 
44  // Create staging buffer
45  if (!m_vulkanRender->CreateBuffer(datasize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
46  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
48  {
49  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create staging buffer");
50  return;
51  }
52 
53  // Map memory and copy data
54  void* memory = nullptr;
55  m_vulkanFuncs->vkMapMemory(m_vulkanDevice, m_stagingMemory, 0, datasize, 0, &memory);
56  memcpy(memory, data, static_cast<size_t>(datasize));
58 
59  // Create image
60  if (m_vulkanRender->CreateImage(Image->size(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL,
61  VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
62  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_image, m_deviceMemory))
63  {
64  VkCommandBuffer commandbuffer = CommandBuffer ? CommandBuffer : m_vulkanRender->CreateSingleUseCommandBuffer();
65 
66  // Transition
67  m_vulkanRender->TransitionImageLayout(m_image, VK_IMAGE_LAYOUT_UNDEFINED,
68  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandbuffer);
69  m_vulkanRender->CopyBufferToImage(m_stagingBuffer, m_image, static_cast<uint32_t>(Image->width()),
70  static_cast<uint32_t>(Image->height()), commandbuffer);
71  m_vulkanRender->TransitionImageLayout(m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
72  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, commandbuffer);
73 
74  // Create sampler if needed
75  if (!Sampler)
76  {
77  m_sampler = m_vulkanRender->CreateSampler(VK_FILTER_LINEAR, VK_FILTER_LINEAR);
78  m_createdSampler = true;
79  }
80  else
81  {
82  m_sampler = Sampler;
83  }
84 
85  // Create image view
86  VkImageViewCreateInfo viewinfo { };
87  viewinfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
88  viewinfo.image = m_image;
89  viewinfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
90  viewinfo.format = VK_FORMAT_B8G8R8A8_UNORM;
91  viewinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
92  viewinfo.subresourceRange.baseMipLevel = 0;
93  viewinfo.subresourceRange.levelCount = 1;
94  viewinfo.subresourceRange.baseArrayLayer = 0;
95  viewinfo.subresourceRange.layerCount = 1;
96  if (m_vulkanFuncs->vkCreateImageView(m_vulkanDevice, &viewinfo, nullptr, &m_view) != VK_SUCCESS)
97  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create image view");
98 
99  m_dataSize = datasize;
101 
102  if (!CommandBuffer)
104  }
105  else
106  {
107  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create texture image");
108  }
109 
110  // If this is a single use command buffer, staging is complete and we can
111  // release the staging resources
112  if (!CommandBuffer)
113  StagingFinished();
114 }
115 
117 {
118  if (m_descriptor)
119  LOG(VB_GENERAL, LOG_WARNING, LOC + "Texture has not returned descriptor");
120 
121  if (m_vulkanValid)
122  {
123  StagingFinished();
124  if (m_createdSampler)
125  m_vulkanFuncs->vkDestroySampler(m_vulkanDevice, m_sampler, nullptr);
126  m_vulkanFuncs->vkDestroyImageView(m_vulkanDevice, m_view, nullptr);
127  m_vulkanFuncs->vkDestroyImage(m_vulkanDevice, m_image, nullptr);
128  m_vulkanFuncs->vkFreeMemory(m_vulkanDevice, m_deviceMemory, nullptr);
129  }
130 }
131 
133 {
134  m_vulkanFuncs->vkDestroyBuffer(m_vulkanDevice, m_stagingBuffer, nullptr);
135  m_vulkanFuncs->vkFreeMemory(m_vulkanDevice, m_stagingMemory, nullptr);
138 }
139 
140 VkDescriptorImageInfo MythTextureVulkan::GetDescriptorImage(void) const
141 {
142  return { m_sampler, m_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
143 }
144 
145 void MythTextureVulkan::AddDescriptor(VkDescriptorSet Descriptor)
146 {
147  m_descriptor = Descriptor;
148 }
149 
151 {
152  VkDescriptorSet result = m_descriptor;
154  return result;
155 }
MythTextureVulkan::Create
static MythTextureVulkan * Create(MythVulkanObject *Vulkan, QImage *Image, VkSampler Sampler, VkCommandBuffer CommandBuffer=nullptr)
Definition: mythtexturevulkan.cpp:7
MythTextureVulkan::TakeDescriptor
VkDescriptorSet TakeDescriptor(void)
Definition: mythtexturevulkan.cpp:150
mythtexturevulkan.h
MythTextureVulkan::m_image
VkImage m_image
Definition: mythtexturevulkan.h:38
MythTextureVulkan::m_stagingBuffer
VkBuffer m_stagingBuffer
Definition: mythtexturevulkan.h:36
MythRenderVulkan::CopyBufferToImage
void CopyBufferToImage(VkBuffer Buffer, VkImage Image, uint32_t Width, uint32_t Height, VkCommandBuffer CommandBuffer=nullptr)
Definition: mythrendervulkan.cpp:413
MythVulkanObject
Definition: mythrendervulkan.h:29
MYTH_NULL_DISPATCH
#define MYTH_NULL_DISPATCH
Definition: mythrendervulkan.h:26
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythRenderVulkan::CreateSingleUseCommandBuffer
VkCommandBuffer CreateSingleUseCommandBuffer(void)
Definition: mythrendervulkan.cpp:611
MythVulkanObject::m_vulkanValid
bool m_vulkanValid
Definition: mythrendervulkan.h:44
MythRenderVulkan::CreateSampler
VkSampler CreateSampler(VkFilter Min, VkFilter Mag)
Definition: mythrendervulkan.cpp:493
Image
Definition: image.h:30
MythTextureVulkan
Definition: mythtexturevulkan.h:14
MythTextureVulkan::AddDescriptor
void AddDescriptor(VkDescriptorSet Descriptor)
Definition: mythtexturevulkan.cpp:145
MythVulkanObject::m_vulkanDevice
VkDevice m_vulkanDevice
Definition: mythrendervulkan.h:46
MythVulkanObject::m_vulkanRender
MythRenderVulkan * m_vulkanRender
Definition: mythrendervulkan.h:45
mythlogging.h
MythTextureVulkan::m_sampler
VkSampler m_sampler
Definition: mythtexturevulkan.h:41
MythRenderVulkan::CreateImage
bool CreateImage(QSize Size, VkFormat Format, VkImageTiling Tiling, VkImageUsageFlags Usage, VkMemoryPropertyFlags Properties, VkImage &Image, VkDeviceMemory &ImageMemory)
Definition: mythrendervulkan.cpp:539
MythTextureVulkan::MythTextureVulkan
MythTextureVulkan(MythVulkanObject *Vulkan, QImage *Image, VkSampler Sampler, VkCommandBuffer CommandBuffer=nullptr)
Definition: mythtexturevulkan.cpp:22
MythTextureVulkan::StagingFinished
void StagingFinished(void)
Definition: mythtexturevulkan.cpp:132
MythTextureVulkan::m_dataSize
uint64_t m_dataSize
Definition: mythtexturevulkan.h:27
MythTextureVulkan::~MythTextureVulkan
~MythTextureVulkan()
Definition: mythtexturevulkan.cpp:116
MythTextureVulkan::m_createdSampler
bool m_createdSampler
Definition: mythtexturevulkan.h:40
MythVulkanObject::m_vulkanFuncs
QVulkanDeviceFunctions * m_vulkanFuncs
Definition: mythrendervulkan.h:47
MythTextureVulkan::m_stagingMemory
VkDeviceMemory m_stagingMemory
Definition: mythtexturevulkan.h:37
LOC
#define LOC
Definition: mythtexturevulkan.cpp:5
MythComboBufferVulkan
Definition: mythcombobuffervulkan.h:26
MythVulkanObject::IsValidVulkan
bool IsValidVulkan() const
Definition: mythrendervulkan.cpp:63
MythTextureVulkan::GetDescriptorImage
VkDescriptorImageInfo GetDescriptorImage(void) const
Definition: mythtexturevulkan.cpp:140
MythRenderVulkan::FinishSingleUseCommandBuffer
void FinishSingleUseCommandBuffer(VkCommandBuffer &Buffer)
Definition: mythrendervulkan.cpp:627
MythRenderVulkan::TransitionImageLayout
void TransitionImageLayout(VkImage &Image, VkImageLayout OldLayout, VkImageLayout NewLayout, VkCommandBuffer CommandBuffer=nullptr)
Definition: mythrendervulkan.cpp:365
MythTextureVulkan::m_deviceMemory
VkDeviceMemory m_deviceMemory
Definition: mythtexturevulkan.h:39
MythRenderVulkan::CreateBuffer
bool CreateBuffer(VkDeviceSize Size, VkBufferUsageFlags Usage, VkMemoryPropertyFlags Properties, VkBuffer &Buffer, VkDeviceMemory &Memory)
Definition: mythrendervulkan.cpp:450
MythTextureVulkan::m_view
VkImageView m_view
Definition: mythtexturevulkan.h:42
MythTextureVulkan::m_descriptor
VkDescriptorSet m_descriptor
Definition: mythtexturevulkan.h:26