Function of load a src file.
Set resource values.
Instance a staginBuffer.
Copy the data from texture bytes to staginBuffer.
Copy the data from staginBuffer to Image.
Release texture bytes.
Generate Image Mipmaps.
Create Image View.
Create Image Sampler.
Instance a VkBufferImageCopy.
The temp buffer image date copy to.
Instance a VkImageToMemoryCopyEXT.
Write mipmap data to ktxTexture.
Save to disk.
Set resource values.
Instance a staginBuffer.
Copy the data from texture bytes to staginBuffer.
Copy the data from staginBuffer to Image.
Release texture bytes.
Generate Image Mipmaps.
Create Image View.
Create Image Sampler.
Instance a VkBufferImageCopy.
The temp buffer image date copy to.
Instance a VkImageToMemoryCopyEXT.
Write mipmap data to ktxTexture.
Save to disk.
273 {
275
276 std::string filePath;
277 std::string binPath;
278 if (it == "")
279 {
280 assert(!isCreateCompressTexture);
281
282 filePath = fileName;
283 }
284 else
285 {
289 }
290
294 int width;
295 int height;
296 int texChannels;
297 stbi_uc* pixels = stbi_load(filePath.c_str(), &width, &height, &texChannels, STBI_rgb_alpha);
298 if (!pixels)
299 {
300 SPICES_CORE_ERROR("Failed to load texture image!")
301 }
302
307 auto resourceptr = outTexture->GetResource<VulkanImage>();
308
312 resourceptr->m_Width = width;
313 resourceptr->m_Height = height;
314 resourceptr->m_MipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(resourceptr->m_Width, resourceptr->m_Height)))) + 1;
315
316 VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT;
318 usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
319 if (hostCopy) usage |= VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
320
324 resourceptr->CreateImage(
325 resourceptr->m_VulkanState,
326 fileName ,
327 VK_IMAGE_TYPE_2D ,
328 resourceptr->m_Width ,
329 resourceptr->m_Height ,
330 1 ,
331 VK_SAMPLE_COUNT_1_BIT ,
332 VK_FORMAT_R8G8B8A8_UNORM ,
333 VK_IMAGE_TILING_OPTIMAL ,
334 usage ,
335 0 ,
336 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
337 resourceptr->m_MipLevels
338 );
339
343 resourceptr->TransitionImageLayout(
344 resourceptr->m_Format,
345 VK_IMAGE_LAYOUT_UNDEFINED,
346 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
347 );
348
353 const VkDeviceSize imageSize = static_cast<uint64_t>(resourceptr->m_Width * resourceptr->m_Height * 4 * 1);
354
358 VulkanBuffer stagingBuffer(
359 resourceptr->m_VulkanState,
360 "StagingBuffer",
361 imageSize,
362 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
363 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
364 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
365 );
366
370 stagingBuffer.WriteToBuffer(pixels);
371
375 resourceptr->CopyBufferToImage(
376 stagingBuffer.Get() ,
377 resourceptr->m_Image ,
378 static_cast<uint32_t>(resourceptr->m_Width) ,
379 static_cast<uint32_t>(resourceptr->m_Height)
380 );
381
385 stbi_image_free(pixels);
386
390 resourceptr->GenerateMipmaps(
391 resourceptr->m_Format,
392 resourceptr->m_Width,
393 resourceptr->m_Height
394 );
395
399 resourceptr->CreateImageView(
400 resourceptr->m_Format ,
401 VK_IMAGE_VIEW_TYPE_2D ,
402 VK_IMAGE_ASPECT_COLOR_BIT
403 );
404
408 resourceptr->CreateSampler();
409
410 auto deviceCopyF = [&](uint32_t w, uint32_t h, int mip, std::vector<unsigned char>& data) {
411
415 VkBufferImageCopy region{};
416 region.bufferOffset = 0;
417 region.bufferRowLength = 0;
418 region.bufferImageHeight = 0;
419
420 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
421 region.imageSubresource.mipLevel = resourceptr->m_MipLevels - 1 - mip;
422 region.imageSubresource.baseArrayLayer = 0;
423 region.imageSubresource.layerCount = resourceptr->m_Layers;
424
425 region.imageOffset.x = 0;
426 region.imageOffset.y = 0;
427 region.imageExtent = { w, h, 1 };
428
429 const uint32_t size = w * h * 4;
430
434 VulkanBuffer copyStagingBuffer(
435 resourceptr->m_VulkanState,
436 "StagingBuffer",
437 size,
438 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
439 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
440 );
441
442 resourceptr->CopyImageToBuffer(copyStagingBuffer.Get(), { region });
443
444 copyStagingBuffer.WriteFromBuffer(reinterpret_cast<void*>(data.data()));
445 };
446
447 auto hostCopyF = [&](uint32_t w, uint32_t h, int mip, std::vector<unsigned char>& data) {
448
452 VkImageToMemoryCopyEXT memoryCopy{};
453 memoryCopy.sType = VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT;
454 memoryCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
455 memoryCopy.imageSubresource.mipLevel = resourceptr->m_MipLevels - 1 - mip;
456 memoryCopy.imageSubresource.baseArrayLayer = 0;
457 memoryCopy.imageSubresource.layerCount = resourceptr->m_Layers;
458 memoryCopy.imageOffset = { 0, 0, 0 };
459 memoryCopy.imageExtent = { w, h, 1 };
460 memoryCopy.pHostPointer = data.data();
461
462 resourceptr->CopyImageToMemoryHost({ memoryCopy });
463 };
464
465 if (!isCreateCompressTexture)
466 {
467 return true;
468 }
469
471 for (uint32_t i = 0; i < resourceptr->m_MipLevels; i++)
472 {
473 const uint32_t w = std::max(1, resourceptr->m_Width >> resourceptr->m_MipLevels - 1 - i);
474 const uint32_t h = std::max(1, resourceptr->m_Height >> resourceptr->m_MipLevels - 1 - i);
475 const uint32_t size = w * h * 4;
476
477 std::vector<unsigned char> data;
478 data.resize(size);
479
480 if (hostCopy)
481 {
482 hostCopyF(w, h, i, data);
483 }
484 else
485 {
486 deviceCopyF(w, h, i, data);
487 }
488
493 }
494
499
500 return true;
501 }
#define SPICES_PROFILE_ZONE
static std::vector< std::string > SplitString(const std::string &input, char delimiter)
Split a string to a string vector container use a char.
static bool SaveToDisk(ktxTexture2 *texture, const std::string &filePath)
Save a src image data to a ktx file.
static bool WriteData(ktxTexture2 *texture, uint32_t mipLevel, const unsigned char *data, uint32_t size)
Write Data to ktxtexture.
static ktxTexture2 * CreateKTX2Texture(int &width, int &height)
Create a ktx2 Texture.
bool IsHostCopyable() const
Check if this image format can copy from host to gpu directly.
static VulkanState & GetState()
Get VulkanState in use.
const std::string binTexturePath
const std::string defaultTexturePath
Const variable: Original Image File Path.