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);