Alright, I’ve modified the triangle demo from the SDK, and the same problem occurs. I haven’t done any changes to the demo, other than this function (My changes are inside the ‘// DDS’ blocks:
static void
demo_prepare_texture_image(struct demo *demo, const uint32_t *tex_colors,
struct texture_object *tex_obj, VkImageTiling tiling,
VkImageUsageFlags usage, VkFlags required_props) {
// DDS
tiling = VK_IMAGE_TILING_LINEAR;
struct dds ddsData = load_dds("image.dds");
VkFormat tex_format = ddsData.format; // tex_format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK (133)
int32_t tex_width = ddsData.width; // tex_width = 512
int32_t tex_height = ddsData.height; // tex_height = 512
unsigned int blockSize = ddsData.blockSize; // blockSize = 8
//
VkResult U_ASSERT_ONLY err;
bool U_ASSERT_ONLY pass;
tex_obj->tex_width = tex_width;
tex_obj->tex_height = tex_height;
const VkImageCreateInfo image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = NULL,
.imageType = VK_IMAGE_TYPE_2D,
.format = tex_format,
.extent = {tex_width, tex_height, 1},
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = tiling,
.usage = usage,
.flags = 0,
.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED
};
VkMemoryAllocateInfo mem_alloc = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = NULL,
.allocationSize = 0,
.memoryTypeIndex = 0,
};
VkMemoryRequirements mem_reqs;
err =
vkCreateImage(demo->device, &image_create_info, NULL, &tex_obj->image);
assert(!err);
vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs);
mem_alloc.allocationSize = mem_reqs.size;
pass =
memory_type_from_properties(demo, mem_reqs.memoryTypeBits,
required_props, &mem_alloc.memoryTypeIndex);
assert(pass);
/* allocate memory */
err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &tex_obj->mem);
assert(!err);
/* bind memory */
err = vkBindImageMemory(demo->device, tex_obj->image, tex_obj->mem, 0);
assert(!err);
if (required_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
const VkImageSubresource subres = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.arrayLayer = 0,
};
VkSubresourceLayout layout;
void *data;
int32_t x, y;
vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres,
&layout);
err = vkMapMemory(demo->device, tex_obj->mem, 0,
mem_alloc.allocationSize, 0, &data);
assert(!err);
// DDS
// Same code as in my first post, except in C
int32_t w = tex_width;
int32_t h = tex_height;
uint8_t *srcData = (uint8_t*)(ddsData.data);
uint8_t *destData = (uint8_t*)(data); // Pointer to mapped memory of VkImage
destData += layout.offset; // layout = VkImageLayout of the image
assert((w %4) == 0);
assert((h %4) == 0);
assert(blockSize == 8); // S3TC BC1
uint32_t wBlocks = w /4;
uint32_t hBlocks = h /4;
for(uint32_t y=0;y<hBlocks;++y)
{
uint8_t *rowDest = destData +y *layout.rowPitch;
uint8_t *rowSrc = srcData +y *(wBlocks *blockSize);
for(uint32_t x=0;x<wBlocks;++x)
{
uint8_t *pxDest = rowDest +x *blockSize;
uint8_t *pxSrc = rowSrc +x *blockSize; // 4x4 image block
memcpy(pxDest,pxSrc,blockSize); // 64Bit per block
}
}
//
// Original Triangle demo code
/* for (y = 0; y < tex_height; y++) {
uint32_t *row = (uint32_t *)((char *)data + layout.rowPitch * y);
for (x = 0; x < tex_width; x++)
row[x] = tex_colors[(x & 1) ^ (y & 1)];
}*/
//
vkUnmapMemory(demo->device, tex_obj->mem);
}
tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
demo_set_image_layout(demo, tex_obj->image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_PREINITIALIZED, tex_obj->imageLayout,
VK_ACCESS_HOST_WRITE_BIT);
/* setting the image layout does not reference the actual memory so no need
* to add a mem ref */
}
I’ve attached the entire file to this post, minus the code for actually loading the dds-file. (Which has dependencies on several external libraries.)