2
3
4
5
13#include "Render/Vulkan/VulkanRenderBackend.h"
19 const std::string& name ,
24 VkSampleCountFlagBits numSamples ,
26 VkImageTiling tiling ,
27 VkImageUsageFlags usage ,
28 VkImageCreateFlags flags ,
29 VkMemoryPropertyFlags properties ,
33 ,
m_Width(
static_cast<
int>(width))
42
43
66
67
71
72
73 vkDestroySampler(m_VulkanState.m_Device, m_TextureSampler,
nullptr);
75 for (
int i = 0; i < m_ImageViews.size(); i++)
77 vkDestroyImageView(m_VulkanState.m_Device, m_ImageViews[i],
nullptr);
83
84
85 vmaDestroyImage(m_VulkanState.m_VmaAllocator, m_Image, m_Alloc);
90
91
92 vkDestroyImage(m_VulkanState.m_Device, m_Image,
nullptr);
93 vkFreeMemory(m_VulkanState.m_Device, m_ImageMemory,
nullptr);
103 m_ImageInfo.imageLayout = imageLayout;
104 m_ImageInfo.imageView = m_ImageViews[mipLevel];
105 m_ImageInfo.sampler = m_TextureSampler;
112 VkImageLayout oldLayout ,
113 VkImageLayout newLayout
118 VkPipelineStageFlags sourceStage;
119 VkPipelineStageFlags destinationStage;
122
123
124 VkImageMemoryBarrier barrier{};
125 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
126 barrier.oldLayout = oldLayout;
127 barrier.newLayout = newLayout;
128 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
129 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
130 barrier.image = m_Image;
131 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
132 barrier.subresourceRange.baseMipLevel = 0;
133 barrier.subresourceRange.levelCount = m_MipLevels;
134 barrier.subresourceRange.baseArrayLayer = 0;
135 barrier.subresourceRange.layerCount = m_Layers;
136 barrier.srcAccessMask = 0;
137 barrier.dstAccessMask = 0;
140
141
142
143 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
145 barrier.srcAccessMask = 0;
146 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
149 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
152 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
156
157
158
159 else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
161 barrier.srcAccessMask = 0;
162 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
165 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
168 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
172
173
174
175 else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
177 barrier.srcAccessMask = 0;
178 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
181 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
184 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
188
189
190
191 else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
193 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
194 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
197 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
200 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
204
205
206
207 else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
209 barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
210 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
213 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
216 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
220
221
222
223 else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
225 barrier.srcAccessMask = 0;
226 barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
228 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
229 destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
233
234
235
236 else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL)
238 barrier.srcAccessMask = 0;
239 barrier.dstAccessMask = VK_IMAGE_ASPECT_NONE;
241 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
242 destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
246 SPICES_CORE_WARN(
"Unsupported layout transition!");
249 if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
251 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
253 if (format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT)
255 barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
260 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
264
265
267 vkCmdPipelineBarrier(
283 VkCommandBuffer commandBuffer ,
284 VkAccessFlags srcAccessMask ,
285 VkAccessFlags dstAccessMask ,
286 VkPipelineStageFlags srcStageMask ,
287 VkPipelineStageFlags dstStageMask ,
288 uint32_t srcQueueFamilyIndex ,
289 uint32_t dstQueueFamilyIndex
294 VkImageSubresourceRange range{};
295 range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
296 range.baseMipLevel = 0;
297 range.levelCount = m_MipLevels;
298 range.baseArrayLayer = 0;
299 range.layerCount = m_Layers;
301 VkImageMemoryBarrier imageBarrier {};
302 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
303 imageBarrier.srcAccessMask = srcAccessMask;
304 imageBarrier.dstAccessMask = dstAccessMask;
305 imageBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
306 imageBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
307 imageBarrier.image = m_Image;
308 imageBarrier.subresourceRange = range;
310 vkCmdPipelineBarrier(
332
333
334 VkBufferImageCopy region{};
335 region.bufferOffset = 0;
336 region.bufferRowLength = 0;
337 region.bufferImageHeight = 0;
339 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
340 region.imageSubresource.mipLevel = 0;
341 region.imageSubresource.baseArrayLayer = 0;
342 region.imageSubresource.layerCount = m_Layers;
344 region.imageOffset = { 0, 0, 0 };
345 region.imageExtent = { width, height, 1 };
348
349
351 vkCmdCopyBufferToImage(
355 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
367 const std::vector<VkBufferImageCopy>& regions
374
375
377 vkCmdCopyBufferToImage(
381 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
382 static_cast<uint32_t>(regions.size()),
393
394
395 VkCopyMemoryToImageInfoEXT copyInfo{};
396 copyInfo.sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT;
397 copyInfo.dstImage = m_Image;
398 copyInfo.dstImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
399 copyInfo.regionCount =
static_cast<uint32_t>(copies.size());
400 copyInfo.pRegions = copies.data();
402 m_VulkanState.m_VkFunc.vkCopyMemoryToImageEXT(m_VulkanState.m_Device, ©Info);
410
411
412 VkMemoryToImageCopyEXT memoryCopy{};
413 memoryCopy.sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT;
414 memoryCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
415 memoryCopy.imageSubresource.mipLevel = 0;
416 memoryCopy.imageSubresource.baseArrayLayer = 0;
417 memoryCopy.imageSubresource.layerCount = 1;
418 memoryCopy.imageExtent.width = m_Width;
419 memoryCopy.imageExtent.height = m_Height;
420 memoryCopy.imageExtent.depth = m_Layers;
421 memoryCopy.pHostPointer = data;
424
425
426 VkCopyMemoryToImageInfoEXT copyInfo{};
427 copyInfo.sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT;
428 copyInfo.dstImage = m_Image;
429 copyInfo.dstImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
430 copyInfo.regionCount = 1;
431 copyInfo.pRegions = &memoryCopy;
433 m_VulkanState.m_VkFunc.vkCopyMemoryToImageEXT(m_VulkanState.m_Device, ©Info);
440 uint32_t channelize = 4;
443
444
447 case VK_FORMAT_B8G8R8A8_UNORM:
450 case VK_FORMAT_R32_SFLOAT:
453 case VK_FORMAT_R32G32B32A32_SFLOAT:
461
462
467 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
468 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
472
473
474 TransitionImageLayout(
476 VK_IMAGE_LAYOUT_UNDEFINED,
477 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
481
482
483 VkBufferImageCopy region{};
484 region.bufferOffset = 0;
485 region.bufferRowLength = 0;
486 region.bufferImageHeight = 0;
488 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
489 region.imageSubresource.mipLevel = 0;
490 region.imageSubresource.baseArrayLayer = 0;
491 region.imageSubresource.layerCount = m_Layers;
493 region.imageOffset.x =
static_cast<int32_t>(x);
494 region.imageOffset.y =
static_cast<int32_t>(y);
495 region.imageExtent = { 1, 1, 1 };
498
499
501 vkCmdCopyImageToBuffer(commandBuffer, m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer.Get(), 1, ®ion);
505
506
507
508
509
510 TransitionImageLayout(
512 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
513 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
517
518
519 stagingBuffer.WriteFromBuffer(out_rgba);
527
528
529 TransitionImageLayout(
531 VK_IMAGE_LAYOUT_UNDEFINED,
532 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
536
537
539 vkCmdCopyImageToBuffer(commandBuffer, m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuffer, regions.size(), regions.data());
543
544
545
546
547
548 TransitionImageLayout(
550 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
551 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
559 VkImageToMemoryCopyEXT memoryCopy{};
560 memoryCopy.sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT;
561 memoryCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
562 memoryCopy.imageSubresource.mipLevel = 0;
563 memoryCopy.imageSubresource.baseArrayLayer = 0;
564 memoryCopy.imageSubresource.layerCount = 1;
565 memoryCopy.imageOffset = { 0, 0, 0 };
566 memoryCopy.imageExtent.width = m_Width;
567 memoryCopy.imageExtent.height = m_Height;
568 memoryCopy.imageExtent.depth = m_Layers;
569 memoryCopy.pHostPointer = data;
572
573
574 VkCopyImageToMemoryInfoEXT copyInfo{};
575 copyInfo.sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT;
576 copyInfo.srcImage = m_Image;
577 copyInfo.srcImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
578 copyInfo.regionCount = 1;
579 copyInfo.pRegions = &memoryCopy;
581 m_VulkanState.m_VkFunc.vkCopyImageToMemoryEXT(m_VulkanState.m_Device, ©Info);
589
590
591 VkCopyImageToMemoryInfoEXT copyInfo{};
592 copyInfo.sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT;
593 copyInfo.srcImage = m_Image;
594 copyInfo.srcImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
595 copyInfo.regionCount =
static_cast<uint32_t>(copies.size());
596 copyInfo.pRegions = copies.data();
598 m_VulkanState.m_VkFunc.vkCopyImageToMemoryEXT(m_VulkanState.m_Device, ©Info);
606
607
608 VkFormatProperties formatProperties;
609 vkGetPhysicalDeviceFormatProperties(m_VulkanState.m_PhysicalDevice, imageFormat, &formatProperties);
612
613
614 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
615 (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) &&
616 (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
618 SPICES_CORE_ERROR(
"texture image format does not support linear blitting!")
622
623
624 VkImageMemoryBarrier barrier{};
625 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
626 barrier.image = m_Image;
627 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
628 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
629 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
630 barrier.subresourceRange.baseArrayLayer = 0;
631 barrier.subresourceRange.layerCount = m_Layers;
632 barrier.subresourceRange.levelCount = 1;
635
636
640
641
644 const int pw = std::max(1, (
m_Width >> (i - 1)));
645 const int ph = std::max(1, (
m_Height >> (i - 1)));
647 const int w = std::max(1,
m_Width >> i);
648 const int h = std::max(1,
m_Height >> i);
650 barrier.subresourceRange.baseMipLevel = i - 1;
651 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
652 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
653 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
654 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
657
658
659 vkCmdPipelineBarrier(commandBuffer,
660 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
667
668
670 blit.srcOffsets[0] = { 0, 0, 0 };
671 blit.srcOffsets[1] = { pw, ph, 1 };
672 blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
673 blit.srcSubresource.mipLevel = i - 1;
674 blit.srcSubresource.baseArrayLayer = 0;
675 blit.srcSubresource.layerCount = m_Layers;
676 blit.dstOffsets[0] = { 0, 0, 0 };
677 blit.dstOffsets[1] = { w, h, 1 };
678 blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
679 blit.dstSubresource.mipLevel = i;
680 blit.dstSubresource.baseArrayLayer = 0;
681 blit.dstSubresource.layerCount = m_Layers;
684
685
686 vkCmdBlitImage(commandBuffer,
687 m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
688 m_Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
693 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
694 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
695 barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
696 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
699
700
701 vkCmdPipelineBarrier(commandBuffer,
702 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
709 barrier.subresourceRange.baseMipLevel = m_MipLevels - 1;
710 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
711 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
712 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
713 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
716
717
718 vkCmdPipelineBarrier(commandBuffer,
719 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
731 uint32_t count = isCreateMipmapView ?
m_MipLevels : 1;
733 m_ImageViews.resize(count);
734 for(
int i = 0; i < count; i++)
737
738
739 VkImageViewCreateInfo viewInfo{};
740 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
741 viewInfo.image = m_Image;
742 viewInfo.viewType = viewType;
743 viewInfo.format = format;
744 viewInfo.subresourceRange.aspectMask = aspectFlags;
745 viewInfo.subresourceRange.baseMipLevel = i;
746 viewInfo.subresourceRange.levelCount = isCreateMipmapView ? 1 : m_MipLevels;
747 viewInfo.subresourceRange.baseArrayLayer = 0;
748 viewInfo.subresourceRange.layerCount = m_Layers;
751
752
753 VK_CHECK(vkCreateImageView(m_VulkanState.m_Device, &viewInfo,
nullptr, &m_ImageViews[i]))
754 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_IMAGE_VIEW,
reinterpret_cast<uint64_t>(m_ImageViews[i]), m_VulkanState.m_Device,
"ImageView")
763
764
765 VkSamplerCreateInfo samplerInfo{};
766 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
767 samplerInfo.magFilter = VK_FILTER_LINEAR;
768 samplerInfo.minFilter = VK_FILTER_LINEAR;
769 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
770 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
771 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
772 samplerInfo.anisotropyEnable = VK_TRUE;
775
776
777 VkPhysicalDeviceProperties properties{};
778 vkGetPhysicalDeviceProperties(m_VulkanState.m_PhysicalDevice, &properties);
780 samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
781 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
782 samplerInfo.unnormalizedCoordinates = VK_FALSE;
783 samplerInfo.compareEnable = VK_FALSE;
784 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
786 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
787 samplerInfo.mipLodBias = 0.0f;
788 samplerInfo.minLod = 0;
789 samplerInfo.maxLod =
static_cast<
float>(m_MipLevels);
792
793
794 VK_CHECK(vkCreateSampler(m_VulkanState.m_Device, &samplerInfo,
nullptr, &m_TextureSampler))
795 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SAMPLER,
reinterpret_cast<uint64_t>(m_TextureSampler), m_VulkanState.m_Device,
"ImageSampler")
800 const std::string& name ,
805 VkSampleCountFlagBits numSamples ,
807 VkImageTiling tiling ,
808 VkImageUsageFlags usage ,
809 VkImageCreateFlags flags ,
810 VkMemoryPropertyFlags properties ,
816 m_Width =
static_cast<
int>(width);
817 m_Height =
static_cast<
int>(height);
824
825
826 VkImageCreateInfo imageInfo{};
827 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
828 imageInfo.imageType = type;
829 imageInfo.extent.width = width;
830 imageInfo.extent.height = height;
831 imageInfo.extent.depth = 1;
832 imageInfo.mipLevels = mipLevels;
833 imageInfo.arrayLayers = layers;
834 imageInfo.format = format;
835 imageInfo.tiling = tiling;
836 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
837 imageInfo.usage = usage;
838 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
839 imageInfo.samples = numSamples;
840 imageInfo.flags = flags;
845
846
847 VmaAllocationCreateInfo createInfo{};
848 createInfo.usage = VMA_MEMORY_USAGE_AUTO;
851
852
853 VK_CHECK(vmaCreateImage(vulkanState.m_VmaAllocator, &imageInfo, &createInfo, &m_Image, &m_Alloc,
nullptr))
854 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_IMAGE,
reinterpret_cast<uint64_t>(m_Image), m_VulkanState.m_Device, name)
859
860
861 VK_CHECK(vkCreateImage(vulkanState.m_Device, &imageInfo,
nullptr, &m_Image));
862 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_IMAGE, (uint64_t)m_Image, m_VulkanState.m_Device, name)
865
866
867 VkMemoryRequirements memRequirements;
868 vkGetImageMemoryRequirements(vulkanState.m_Device, m_Image, &memRequirements);
871
872
873 VkMemoryAllocateInfo allocInfo{};
874 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
875 allocInfo.allocationSize = memRequirements.size;
878
879
880 VkPhysicalDeviceMemoryProperties memProperties;
881 vkGetPhysicalDeviceMemoryProperties(vulkanState.m_PhysicalDevice, &memProperties);
884
885
886 allocInfo.memoryTypeIndex = 0;
887 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++)
889 if (memRequirements.memoryTypeBits & (1 << i) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
891 allocInfo.memoryTypeIndex = i;
896
897
898 VK_CHECK(vkAllocateMemory(vulkanState.m_Device, &allocInfo,
nullptr, &m_ImageMemory))
901
902
903 vkBindImageMemory(vulkanState.m_Device, m_Image, m_ImageMemory, 0);
914
915
921
922
923 VkDescriptorSetLayoutBinding samplerLayoutBinding{};
924 samplerLayoutBinding.binding = binding;
925 samplerLayoutBinding.descriptorCount = 1;
926 samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
927 samplerLayoutBinding.pImmutableSamplers =
nullptr;
928 samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
930 VkDescriptorBindingFlags setBindingFlags;
931 setBindingFlags = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
934
935
936 VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlags{};
937 bindingFlags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
938 bindingFlags.pNext =
nullptr;
939 bindingFlags.pBindingFlags = &setBindingFlags;
940 bindingFlags.bindingCount = 1;
943
944
945 VkDescriptorSetLayoutCreateInfo layoutInfo{};
946 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
947 layoutInfo.bindingCount = 1;
948 layoutInfo.pBindings = &samplerLayoutBinding;
949 layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
950 layoutInfo.pNext = &bindingFlags;
953
954
955 VK_CHECK(vkCreateDescriptorSetLayout(m_VulkanState.m_Device, &layoutInfo,
nullptr, &m_DescriptorSetLayout))
956 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
reinterpret_cast<uint64_t>(m_DescriptorSetLayout), m_VulkanState.m_Device,
"DescriptorSetLayoutImage")
959
960
961 VkDescriptorSetAllocateInfo allocInfo{};
962 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
963 allocInfo.descriptorPool = VulkanRenderBackend::GetDescriptorPool()->GetPool();
964 allocInfo.descriptorSetCount = 1;
965 allocInfo.pSetLayouts = &m_DescriptorSetLayout;
968
969
970 VK_CHECK(vkAllocateDescriptorSets(m_VulkanState.m_Device, &allocInfo, &m_DescriptorSet))
971 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET,
reinterpret_cast<uint64_t>(m_DescriptorSet), m_VulkanState.m_Device,
"DescriptorSetImage")
974
975
976 VkDescriptorImageInfo imageInfo{};
977 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
978 imageInfo.imageView = m_ImageViews[0];
979 imageInfo.sampler = m_TextureSampler;
982
983
984 VkWriteDescriptorSet descriptorWrite{};
985 descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
986 descriptorWrite.dstSet = m_DescriptorSet;
987 descriptorWrite.dstBinding = binding;
988 descriptorWrite.dstArrayElement = 0;
989 descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
990 descriptorWrite.descriptorCount = 1;
991 descriptorWrite.pImageInfo = &imageInfo;
994
995
996 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &descriptorWrite, 0,
nullptr);
1004
1005
1006 VkFormatProperties3 formatProperties3{};
1007 formatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR;
1010
1011
1012 VkFormatProperties2 formatProperties2{};
1013 formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1014 formatProperties2.pNext = &formatProperties3;
1017
1018
1019 vkGetPhysicalDeviceFormatProperties2(m_VulkanState.m_PhysicalDevice, m_Format, &formatProperties2);
1021 return formatProperties3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT &&
VKImageHostOperation;
1029
1030
1031 VkFormatProperties3 formatProperties3{};
1032 formatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR;
1035
1036
1037 VkFormatProperties2 formatProperties2{};
1038 formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1039 formatProperties2.pNext = &formatProperties3;
1042
1043
1044 vkGetPhysicalDeviceFormatProperties2(state.m_PhysicalDevice, format, &formatProperties2);
1046 return formatProperties3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT &&
VKImageHostOperation;
1056
1057
1058 vkDestroyDescriptorSetLayout(m_VulkanState.m_Device, m_DescriptorSetLayout,
nullptr);
#define SPICES_PROFILE_ZONE
#define VMA_ALLOCATOR
Use VMA for memory allocate.
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
#define VKImageHostOperation
Disable Host Image copy for host memory heap is too smaller.
This Class is a Wrapper of VulkanBuffer.
VulkanCommandBuffer Class. This class defines the VulkanCommandBuffer behaves. This class is just a w...
void CopyImageToMemoryHost(const std::vector< VkImageToMemoryCopyEXT > &copies) const
bool IsHostCopyable() const
Check if this image format can copy from host to gpu directly.
void CreateDescriptorSet(uint32_t binding)
Create DescriptorSet with single image.
void CopyImageToMemoryHost(void *data) const
VkDescriptorImageInfo * GetImageInfo(VkImageLayout imageLayout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, uint32_t mipLevel=0)
void CopyMemoryToImageHost(const void *data) const
Copy the Memory's data to this VkImage.
void CreateSampler()
Create a Sampler.
void CopyImageToBuffer(VkBuffer dstBuffer, const std::vector< VkBufferImageCopy > ®ions)
void CopyImageTexelToBuffer(uint32_t x, uint32_t y, void *out_rgba)
void CreateImage(VulkanState &vulkanState, const std::string &name, VkImageType type, uint32_t width, uint32_t height, uint32_t layers, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkMemoryPropertyFlags properties, uint32_t mipLevels)
void DestroyDescriptorSetLayout() const
Destroy the DescriptorSetLayout if Created a DescriptorSet.
void CopyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height, const std::vector< VkBufferImageCopy > ®ions) const
Copy the Buffer's data to this VkImage. Used to create image data (include mipmaps),...
void CopyMemoryToImageHost(const std::vector< VkMemoryToImageCopyEXT > &copies) const
Copy the Memory's data to this VkImage. Used to create image data (include mipmaps),...
bool m_IsCreateSet
True if Called Create DescriptorSet.
virtual ~VulkanImage() override
Destructor Function.
VulkanImage(VulkanState &vulkanState, const std::string &name, VkImageType type, uint32_t width, uint32_t height, uint32_t layers, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkMemoryPropertyFlags properties, uint32_t mipLevels)
uint32_t m_MipLevels
Image mipmaps num.
void CreateImageView(VkFormat format, VkImageViewType viewType, VkImageAspectFlags aspectFlags, bool isCreateMipmapView=false)
Create Image View.
int m_Height
Image height.
void Barrier(VkCommandBuffer commandBuffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t srcQueueFamilyIndex, uint32_t dstQueueFamilyIndex) const
Wrapper of Call vkCmdImageBarrier.
void TransitionImageLayout(VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
void CopyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) const
Copy the Buffer's data to this VkImage.
uint32_t m_Layers
Image layer(texture cube: 6).
void GenerateMipmaps(VkFormat imageFormat, int32_t texWidth, int32_t texHeight) const
Generate mipmaps with the VkImage.
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VulkanObject(VulkanState &vulkanState)
Constructor Function. Init member variables.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
This struct contains all Vulkan object in used global.