MythTV  master
mythtexturevulkan.cpp
Go to the documentation of this file.
1 // MythTV
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 = Image->sizeInBytes();
34  if (datasize != static_cast<VkDeviceSize>(datasize2))
35  LOG(VB_GENERAL, LOG_WARNING, LOC + "Inconsistent image data size");
36 
37  const auto *data = Image->constBits();
38 
39  // Create staging buffer
40  if (!m_vulkanRender->CreateBuffer(datasize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
41  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
43  {
44  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create staging buffer");
45  return;
46  }
47 
48  // Map memory and copy data
49  void* memory = nullptr;
50  m_vulkanFuncs->vkMapMemory(m_vulkanDevice, m_stagingMemory, 0, datasize, 0, &memory);
51  memcpy(memory, data, static_cast<size_t>(datasize));
53 
54  // Create image
55  if (m_vulkanRender->CreateImage(Image->size(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL,
56  VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
57  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_image, m_deviceMemory))
58  {
59  VkCommandBuffer commandbuffer = CommandBuffer ? CommandBuffer : m_vulkanRender->CreateSingleUseCommandBuffer();
60 
61  // Transition
62  m_vulkanRender->TransitionImageLayout(m_image, VK_IMAGE_LAYOUT_UNDEFINED,
63  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandbuffer);
64  m_vulkanRender->CopyBufferToImage(m_stagingBuffer, m_image, static_cast<uint32_t>(Image->width()),
65  static_cast<uint32_t>(Image->height()), commandbuffer);
66  m_vulkanRender->TransitionImageLayout(m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
67  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, commandbuffer);
68 
69  // Create sampler if needed
70  if (!Sampler)
71  {
72  m_sampler = m_vulkanRender->CreateSampler(VK_FILTER_LINEAR, VK_FILTER_LINEAR);
73  m_createdSampler = true;
74  }
75  else
76  {
77  m_sampler = Sampler;
78  }
79 
80  // Create image view
81  VkImageViewCreateInfo viewinfo { };
82  viewinfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
83  viewinfo.image = m_image;
84  viewinfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
85  viewinfo.format = VK_FORMAT_B8G8R8A8_UNORM;
86  viewinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
87  viewinfo.subresourceRange.baseMipLevel = 0;
88  viewinfo.subresourceRange.levelCount = 1;
89  viewinfo.subresourceRange.baseArrayLayer = 0;
90  viewinfo.subresourceRange.layerCount = 1;
91  if (m_vulkanFuncs->vkCreateImageView(m_vulkanDevice, &viewinfo, nullptr, &m_view) != VK_SUCCESS)
92  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create image view");
93 
94  m_dataSize = datasize;
96 
97  if (!CommandBuffer)
99  }
100  else
101  {
102  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create texture image");
103  }
104 
105  // If this is a single use command buffer, staging is complete and we can
106  // release the staging resources
107  if (!CommandBuffer)
108  StagingFinished();
109 }
110 
112 {
113  if (m_descriptor)
114  LOG(VB_GENERAL, LOG_WARNING, LOC + "Texture has not returned descriptor");
115 
116  if (m_vulkanValid)
117  {
118  StagingFinished();
119  if (m_createdSampler)
120  m_vulkanFuncs->vkDestroySampler(m_vulkanDevice, m_sampler, nullptr);
121  m_vulkanFuncs->vkDestroyImageView(m_vulkanDevice, m_view, nullptr);
122  m_vulkanFuncs->vkDestroyImage(m_vulkanDevice, m_image, nullptr);
123  m_vulkanFuncs->vkFreeMemory(m_vulkanDevice, m_deviceMemory, nullptr);
124  }
125 }
126 
128 {
129  m_vulkanFuncs->vkDestroyBuffer(m_vulkanDevice, m_stagingBuffer, nullptr);
130  m_vulkanFuncs->vkFreeMemory(m_vulkanDevice, m_stagingMemory, nullptr);
133 }
134 
135 VkDescriptorImageInfo MythTextureVulkan::GetDescriptorImage(void) const
136 {
137  return { m_sampler, m_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
138 }
139 
140 void MythTextureVulkan::AddDescriptor(VkDescriptorSet Descriptor)
141 {
142  m_descriptor = Descriptor;
143 }
144 
146 {
147  VkDescriptorSet result = m_descriptor;
149  return result;
150 }
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:145
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:32
MYTH_NULL_DISPATCH
#define MYTH_NULL_DISPATCH
Definition: mythrendervulkan.h:29
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythRenderVulkan::CreateSingleUseCommandBuffer
VkCommandBuffer CreateSingleUseCommandBuffer(void)
Definition: mythrendervulkan.cpp:611
MythVulkanObject::m_vulkanValid
bool m_vulkanValid
Definition: mythrendervulkan.h:47
MythRenderVulkan::CreateSampler
VkSampler CreateSampler(VkFilter Min, VkFilter Mag)
Definition: mythrendervulkan.cpp:493
Image
Definition: image.h:33
MythTextureVulkan
Definition: mythtexturevulkan.h:14
MythTextureVulkan::AddDescriptor
void AddDescriptor(VkDescriptorSet Descriptor)
Definition: mythtexturevulkan.cpp:140
MythVulkanObject::m_vulkanDevice
VkDevice m_vulkanDevice
Definition: mythrendervulkan.h:49
MythVulkanObject::m_vulkanRender
MythRenderVulkan * m_vulkanRender
Definition: mythrendervulkan.h:48
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:127
MythTextureVulkan::m_dataSize
uint64_t m_dataSize
Definition: mythtexturevulkan.h:27
MythTextureVulkan::~MythTextureVulkan
~MythTextureVulkan()
Definition: mythtexturevulkan.cpp:111
MythTextureVulkan::m_createdSampler
bool m_createdSampler
Definition: mythtexturevulkan.h:40
MythVulkanObject::m_vulkanFuncs
QVulkanDeviceFunctions * m_vulkanFuncs
Definition: mythrendervulkan.h:50
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:135
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