80 ktxTexture* ktxTexture;
81 ktxResult result =
loadKTXFile(filename, &ktxTexture);
82 assert(result == KTX_SUCCESS);
84 width = ktxTexture->baseWidth;
85 height = ktxTexture->baseHeight;
88 ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
89 ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture);
92 VkFormatProperties formatProperties;
93 vkGetPhysicalDeviceFormatProperties(
ctx->physicalDeviceHandle(), format, &formatProperties);
100 VkBool32 useStaging = !forceLinear;
103 VkMemoryRequirements memReqs;
106 VkCommandBuffer copyCmd =
ctx->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY,
true);
111 VkBuffer stagingBuffer;
112 VkDeviceMemory stagingMemory;
115 bufferCreateInfo.size = ktxTextureSize;
117 bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
118 bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
120 VK_CHECK_RESULT(vkCreateBuffer(
ctx->deviceHandle(), &bufferCreateInfo,
nullptr, &stagingBuffer));
123 vkGetBufferMemoryRequirements(
ctx->deviceHandle(), stagingBuffer, &memReqs);
125 memAllocInfo.allocationSize = memReqs.size;
127 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
129 VK_CHECK_RESULT(vkAllocateMemory(
ctx->deviceHandle(), &memAllocInfo,
nullptr, &stagingMemory));
130 VK_CHECK_RESULT(vkBindBufferMemory(
ctx->deviceHandle(), stagingBuffer, stagingMemory, 0));
134 VK_CHECK_RESULT(vkMapMemory(
ctx->deviceHandle(), stagingMemory, 0, memReqs.size, 0, (
void **)&data));
135 memcpy(data, ktxTextureData, ktxTextureSize);
136 vkUnmapMemory(
ctx->deviceHandle(), stagingMemory);
139 std::vector<VkBufferImageCopy> bufferCopyRegions;
144 KTX_error_code result = ktxTexture_GetImageOffset(ktxTexture, i, 0, 0, &offset);
145 assert(result == KTX_SUCCESS);
147 VkBufferImageCopy bufferCopyRegion = {};
148 bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
149 bufferCopyRegion.imageSubresource.mipLevel = i;
150 bufferCopyRegion.imageSubresource.baseArrayLayer = 0;
151 bufferCopyRegion.imageSubresource.layerCount = 1;
152 bufferCopyRegion.imageExtent.width = std::max(1u, ktxTexture->baseWidth >> i);
153 bufferCopyRegion.imageExtent.height = std::max(1u, ktxTexture->baseHeight >> i);
154 bufferCopyRegion.imageExtent.depth = 1;
155 bufferCopyRegion.bufferOffset = offset;
157 bufferCopyRegions.push_back(bufferCopyRegion);
162 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
163 imageCreateInfo.format = format;
165 imageCreateInfo.arrayLayers = 1;
166 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
167 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
168 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
169 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
171 imageCreateInfo.usage = imageUsageFlags;
173 if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
175 imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
179 vkGetImageMemoryRequirements(
ctx->deviceHandle(),
image, &memReqs);
181 memAllocInfo.allocationSize = memReqs.size;
183 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
187 VkImageSubresourceRange subresourceRange = {};
188 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
189 subresourceRange.baseMipLevel = 0;
191 subresourceRange.layerCount = 1;
198 VK_IMAGE_LAYOUT_UNDEFINED,
199 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
203 vkCmdCopyBufferToImage(
207 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
208 static_cast<uint32_t
>(bufferCopyRegions.size()),
209 bufferCopyRegions.data()
217 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
221 ctx->flushCommandBuffer(copyCmd,
ctx->graphicsQueueHandle());
224 vkFreeMemory(
ctx->deviceHandle(), stagingMemory,
nullptr);
225 vkDestroyBuffer(
ctx->deviceHandle(), stagingBuffer,
nullptr);
234 assert(formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
236 VkImage mappableImage;
237 VkDeviceMemory mappableMemory;
240 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
241 imageCreateInfo.format = format;
243 imageCreateInfo.mipLevels = 1;
244 imageCreateInfo.arrayLayers = 1;
245 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
246 imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
247 imageCreateInfo.usage = imageUsageFlags;
248 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
249 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
252 VK_CHECK_RESULT(vkCreateImage(
ctx->deviceHandle(), &imageCreateInfo,
nullptr, &mappableImage));
256 vkGetImageMemoryRequirements(
ctx->deviceHandle(), mappableImage, &memReqs);
258 memAllocInfo.allocationSize = memReqs.size;
261 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
264 VK_CHECK_RESULT(vkAllocateMemory(
ctx->deviceHandle(), &memAllocInfo,
nullptr, &mappableMemory));
267 VK_CHECK_RESULT(vkBindImageMemory(
ctx->deviceHandle(), mappableImage, mappableMemory, 0));
271 VkImageSubresource subRes = {};
272 subRes.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
275 VkSubresourceLayout subResLayout;
280 vkGetImageSubresourceLayout(
ctx->deviceHandle(), mappableImage, &subRes, &subResLayout);
283 VK_CHECK_RESULT(vkMapMemory(
ctx->deviceHandle(), mappableMemory, 0, memReqs.size, 0, &data));
286 memcpy(data, ktxTextureData, memReqs.size);
288 vkUnmapMemory(
ctx->deviceHandle(), mappableMemory);
292 image = mappableImage;
299 ctx->flushCommandBuffer(copyCmd,
ctx->graphicsQueueHandle());
302 ktxTexture_Destroy(ktxTexture);
305 VkSamplerCreateInfo samplerCreateInfo = {};
306 samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
307 samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
308 samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
309 samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
310 samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
311 samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
312 samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
313 samplerCreateInfo.mipLodBias = 0.0f;
314 samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
315 samplerCreateInfo.minLod = 0.0f;
317 samplerCreateInfo.maxLod = (useStaging) ? (
float)
mipLevels : 0.0f;
319 samplerCreateInfo.maxAnisotropy =
ctx->enabledFeatures.samplerAnisotropy ?
ctx->properties.limits.maxSamplerAnisotropy : 1.0f;
320 samplerCreateInfo.anisotropyEnable =
ctx->enabledFeatures.samplerAnisotropy;
321 samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
328 VkImageViewCreateInfo viewCreateInfo = {};
329 viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
330 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
331 viewCreateInfo.format = format;
332 viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
333 viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
336 viewCreateInfo.subresourceRange.levelCount = (useStaging) ?
mipLevels : 1;
337 viewCreateInfo.image =
image;
358 void Texture2D::fromBuffer(
void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, VkFilter filter, VkImageUsageFlags imageUsageFlags, VkImageLayout
imageLayout)
367 VkMemoryRequirements memReqs;
370 VkCommandBuffer copyCmd =
ctx->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY,
true);
373 VkBuffer stagingBuffer;
374 VkDeviceMemory stagingMemory;
377 bufferCreateInfo.size = bufferSize;
379 bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
380 bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
382 VK_CHECK_RESULT(vkCreateBuffer(
ctx->deviceHandle(), &bufferCreateInfo,
nullptr, &stagingBuffer));
385 vkGetBufferMemoryRequirements(
ctx->deviceHandle(), stagingBuffer, &memReqs);
387 memAllocInfo.allocationSize = memReqs.size;
389 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
391 VK_CHECK_RESULT(vkAllocateMemory(
ctx->deviceHandle(), &memAllocInfo,
nullptr, &stagingMemory));
392 VK_CHECK_RESULT(vkBindBufferMemory(
ctx->deviceHandle(), stagingBuffer, stagingMemory, 0));
396 VK_CHECK_RESULT(vkMapMemory(
ctx->deviceHandle(), stagingMemory, 0, memReqs.size, 0, (
void **)&data));
397 memcpy(data, buffer, bufferSize);
398 vkUnmapMemory(
ctx->deviceHandle(), stagingMemory);
400 VkBufferImageCopy bufferCopyRegion = {};
401 bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
402 bufferCopyRegion.imageSubresource.mipLevel = 0;
403 bufferCopyRegion.imageSubresource.baseArrayLayer = 0;
404 bufferCopyRegion.imageSubresource.layerCount = 1;
405 bufferCopyRegion.imageExtent.width =
width;
406 bufferCopyRegion.imageExtent.height =
height;
407 bufferCopyRegion.imageExtent.depth = 1;
408 bufferCopyRegion.bufferOffset = 0;
412 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
413 imageCreateInfo.format = format;
415 imageCreateInfo.arrayLayers = 1;
416 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
417 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
418 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
419 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
421 imageCreateInfo.usage = imageUsageFlags;
423 if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
425 imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
429 vkGetImageMemoryRequirements(
ctx->deviceHandle(),
image, &memReqs);
431 memAllocInfo.allocationSize = memReqs.size;
433 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
437 VkImageSubresourceRange subresourceRange = {};
438 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
439 subresourceRange.baseMipLevel = 0;
441 subresourceRange.layerCount = 1;
448 VK_IMAGE_LAYOUT_UNDEFINED,
449 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
453 vkCmdCopyBufferToImage(
457 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
467 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
471 ctx->flushCommandBuffer(copyCmd,
ctx->graphicsQueueHandle());
474 vkFreeMemory(
ctx->deviceHandle(), stagingMemory,
nullptr);
475 vkDestroyBuffer(
ctx->deviceHandle(), stagingBuffer,
nullptr);
478 VkSamplerCreateInfo samplerCreateInfo = {};
479 samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
480 samplerCreateInfo.magFilter = filter;
481 samplerCreateInfo.minFilter = filter;
482 samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
483 samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
484 samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
485 samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
486 samplerCreateInfo.mipLodBias = 0.0f;
487 samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
488 samplerCreateInfo.minLod = 0.0f;
489 samplerCreateInfo.maxLod = 0.0f;
490 samplerCreateInfo.maxAnisotropy = 1.0f;
494 VkImageViewCreateInfo viewCreateInfo = {};
495 viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
496 viewCreateInfo.pNext = NULL;
497 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
498 viewCreateInfo.format = format;
499 viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
500 viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
501 viewCreateInfo.subresourceRange.levelCount = 1;
502 viewCreateInfo.image =
image;
522 ktxTexture* ktxTexture;
523 ktxResult result =
loadKTXFile(filename, &ktxTexture);
524 assert(result == KTX_SUCCESS);
526 width = ktxTexture->baseWidth;
527 height = ktxTexture->baseHeight;
531 ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
532 ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture);
535 VkMemoryRequirements memReqs;
538 VkBuffer stagingBuffer;
539 VkDeviceMemory stagingMemory;
542 bufferCreateInfo.size = ktxTextureSize;
544 bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
545 bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
547 VK_CHECK_RESULT(vkCreateBuffer(
ctx->deviceHandle(), &bufferCreateInfo,
nullptr, &stagingBuffer));
550 vkGetBufferMemoryRequirements(
ctx->deviceHandle(), stagingBuffer, &memReqs);
552 memAllocInfo.allocationSize = memReqs.size;
554 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
556 VK_CHECK_RESULT(vkAllocateMemory(
ctx->deviceHandle(), &memAllocInfo,
nullptr, &stagingMemory));
557 VK_CHECK_RESULT(vkBindBufferMemory(
ctx->deviceHandle(), stagingBuffer, stagingMemory, 0));
561 VK_CHECK_RESULT(vkMapMemory(
ctx->deviceHandle(), stagingMemory, 0, memReqs.size, 0, (
void **)&data));
562 memcpy(data, ktxTextureData, ktxTextureSize);
563 vkUnmapMemory(
ctx->deviceHandle(), stagingMemory);
566 std::vector<VkBufferImageCopy> bufferCopyRegions;
568 for (uint32_t layer = 0; layer <
layerCount; layer++)
570 for (uint32_t level = 0; level <
mipLevels; level++)
573 KTX_error_code result = ktxTexture_GetImageOffset(ktxTexture, level, layer, 0, &offset);
574 assert(result == KTX_SUCCESS);
576 VkBufferImageCopy bufferCopyRegion = {};
577 bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
578 bufferCopyRegion.imageSubresource.mipLevel = level;
579 bufferCopyRegion.imageSubresource.baseArrayLayer = layer;
580 bufferCopyRegion.imageSubresource.layerCount = 1;
581 bufferCopyRegion.imageExtent.width = ktxTexture->baseWidth >> level;
582 bufferCopyRegion.imageExtent.height = ktxTexture->baseHeight >> level;
583 bufferCopyRegion.imageExtent.depth = 1;
584 bufferCopyRegion.bufferOffset = offset;
586 bufferCopyRegions.push_back(bufferCopyRegion);
592 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
593 imageCreateInfo.format = format;
594 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
595 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
596 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
597 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
599 imageCreateInfo.usage = imageUsageFlags;
601 if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
603 imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
610 vkGetImageMemoryRequirements(
ctx->deviceHandle(),
image, &memReqs);
612 memAllocInfo.allocationSize = memReqs.size;
613 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
619 VkCommandBuffer copyCmd =
ctx->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY,
true);
623 VkImageSubresourceRange subresourceRange = {};
624 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
625 subresourceRange.baseMipLevel = 0;
632 VK_IMAGE_LAYOUT_UNDEFINED,
633 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
637 vkCmdCopyBufferToImage(
641 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
642 static_cast<uint32_t
>(bufferCopyRegions.size()),
643 bufferCopyRegions.data());
650 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
654 ctx->flushCommandBuffer(copyCmd,
ctx->graphicsQueueHandle());
658 samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
659 samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
660 samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
661 samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
662 samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
663 samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
664 samplerCreateInfo.mipLodBias = 0.0f;
665 samplerCreateInfo.maxAnisotropy =
ctx->enabledFeatures.samplerAnisotropy ?
ctx->properties.limits.maxSamplerAnisotropy : 1.0f;
666 samplerCreateInfo.anisotropyEnable =
ctx->enabledFeatures.samplerAnisotropy;
667 samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
668 samplerCreateInfo.minLod = 0.0f;
669 samplerCreateInfo.maxLod = (float)
mipLevels;
670 samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
675 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
676 viewCreateInfo.format = format;
677 viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
678 viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
679 viewCreateInfo.subresourceRange.layerCount =
layerCount;
680 viewCreateInfo.subresourceRange.levelCount =
mipLevels;
681 viewCreateInfo.image =
image;
685 ktxTexture_Destroy(ktxTexture);
686 vkFreeMemory(
ctx->deviceHandle(), stagingMemory,
nullptr);
687 vkDestroyBuffer(
ctx->deviceHandle(), stagingBuffer,
nullptr);
706 ktxTexture* ktxTexture;
707 ktxResult result =
loadKTXFile(filename, &ktxTexture);
708 assert(result == KTX_SUCCESS);
710 width = ktxTexture->baseWidth;
711 height = ktxTexture->baseHeight;
714 ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
715 ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture);
718 VkMemoryRequirements memReqs;
721 VkBuffer stagingBuffer;
722 VkDeviceMemory stagingMemory;
725 bufferCreateInfo.size = ktxTextureSize;
727 bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
728 bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
730 VK_CHECK_RESULT(vkCreateBuffer(
ctx->deviceHandle(), &bufferCreateInfo,
nullptr, &stagingBuffer));
733 vkGetBufferMemoryRequirements(
ctx->deviceHandle(), stagingBuffer, &memReqs);
735 memAllocInfo.allocationSize = memReqs.size;
737 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
739 VK_CHECK_RESULT(vkAllocateMemory(
ctx->deviceHandle(), &memAllocInfo,
nullptr, &stagingMemory));
740 VK_CHECK_RESULT(vkBindBufferMemory(
ctx->deviceHandle(), stagingBuffer, stagingMemory, 0));
744 VK_CHECK_RESULT(vkMapMemory(
ctx->deviceHandle(), stagingMemory, 0, memReqs.size, 0, (
void **)&data));
745 memcpy(data, ktxTextureData, ktxTextureSize);
746 vkUnmapMemory(
ctx->deviceHandle(), stagingMemory);
749 std::vector<VkBufferImageCopy> bufferCopyRegions;
751 for (uint32_t face = 0; face < 6; face++)
753 for (uint32_t level = 0; level <
mipLevels; level++)
756 KTX_error_code result = ktxTexture_GetImageOffset(ktxTexture, level, 0, face, &offset);
757 assert(result == KTX_SUCCESS);
759 VkBufferImageCopy bufferCopyRegion = {};
760 bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
761 bufferCopyRegion.imageSubresource.mipLevel = level;
762 bufferCopyRegion.imageSubresource.baseArrayLayer = face;
763 bufferCopyRegion.imageSubresource.layerCount = 1;
764 bufferCopyRegion.imageExtent.width = ktxTexture->baseWidth >> level;
765 bufferCopyRegion.imageExtent.height = ktxTexture->baseHeight >> level;
766 bufferCopyRegion.imageExtent.depth = 1;
767 bufferCopyRegion.bufferOffset = offset;
769 bufferCopyRegions.push_back(bufferCopyRegion);
775 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
776 imageCreateInfo.format = format;
778 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
779 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
780 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
781 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
783 imageCreateInfo.usage = imageUsageFlags;
785 if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
787 imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
790 imageCreateInfo.arrayLayers = 6;
792 imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
797 vkGetImageMemoryRequirements(
ctx->deviceHandle(),
image, &memReqs);
799 memAllocInfo.allocationSize = memReqs.size;
800 memAllocInfo.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
806 VkCommandBuffer copyCmd =
ctx->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY,
true);
810 VkImageSubresourceRange subresourceRange = {};
811 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
812 subresourceRange.baseMipLevel = 0;
814 subresourceRange.layerCount = 6;
819 VK_IMAGE_LAYOUT_UNDEFINED,
820 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
824 vkCmdCopyBufferToImage(
828 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
829 static_cast<uint32_t
>(bufferCopyRegions.size()),
830 bufferCopyRegions.data());
837 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
841 ctx->flushCommandBuffer(copyCmd,
ctx->graphicsQueueHandle());
845 samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
846 samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
847 samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
848 samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
849 samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
850 samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
851 samplerCreateInfo.mipLodBias = 0.0f;
852 samplerCreateInfo.maxAnisotropy =
ctx->enabledFeatures.samplerAnisotropy ?
ctx->properties.limits.maxSamplerAnisotropy : 1.0f;
853 samplerCreateInfo.anisotropyEnable =
ctx->enabledFeatures.samplerAnisotropy;
854 samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
855 samplerCreateInfo.minLod = 0.0f;
856 samplerCreateInfo.maxLod = (float)
mipLevels;
857 samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
862 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
863 viewCreateInfo.format = format;
864 viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
865 viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
866 viewCreateInfo.subresourceRange.layerCount = 6;
867 viewCreateInfo.subresourceRange.levelCount =
mipLevels;
868 viewCreateInfo.image =
image;
872 ktxTexture_Destroy(ktxTexture);
873 vkFreeMemory(
ctx->deviceHandle(), stagingMemory,
nullptr);
874 vkDestroyBuffer(
ctx->deviceHandle(), stagingBuffer,
nullptr);