Android平台Vulkan中BC1纹理压缩无法正常工作的问题求助
问题:BC1压缩纹理在Vulkan中无法正常显示
我是Vulkan新手,修改谷歌的Android Vulkan教程示例,尝试用BC1压缩纹理绘制简单四边形。使用VK_FORMAT_R8G8B8A8_UNORM时显示正常,但切换到VK_FORMAT_BC1_RGB_UNORM_BLOCK后无法正常渲染。
我怀疑问题出在这段纹理数据拷贝代码:
if (!compressed) { for (int32_t y = 0; y < imgHeight; y++) { unsigned char *row = (unsigned char *) ((char *) data + layout.rowPitch * y); for (int32_t x = 0; x < imgWidth; x++) { row[x * 4] = imageData[(x + y * imgWidth) * 4]; row[x * 4 + 1] = imageData[(x + y * imgWidth) * 4 + 1]; row[x * 4 + 2] = imageData[(x + y * imgWidth) * 4 + 2]; row[x * 4 + 3] = imageData[(x + y * imgWidth) * 4 + 3]; } } } else { memcpy((void*)data, (void*)imageData, tiny_bc1_texture_size); } vkUnmapMemory(device.device_, tex_obj->mem);
未压缩纹理处理时考虑了rowPitch,但BC1纹理是用PVRTexTool生成的8x8小纹理,压缩后仅32字节,我直接用memcpy拷贝,认为内存对齐没问题。纹理数据已保存为C数组引入项目:
static const unsigned char tiny_bc1_texture[] = { /* Texture Data */ 0xff,0xff,0x00,0xf8,0x00,0x14,0x14,0x00,0xff,0xff,0xe0,0x07,0x00,0x14,0x14,0x00,0xff,0xff,0x1f,0x00,0x04,0x54,0x54,0x00,0xff,0xff,0x1f,0x00,0x10,0x15,0x15,0x00, }; static const unsigned char tiny_bc1_texture_w = 8; static const unsigned char tiny_bc1_texture_h = 8; static const unsigned char tiny_bc1_texture_size = sizeof(tiny_bc1_texture);
使用BC1纹理时画面显示异常(色块错乱,无正确纹理),未压缩纹理则显示正常。完整测试项目核心文件为VulkanMain.cpp,纹理创建逻辑从485行开始。
解决思路
- 检查内存布局与对齐:压缩纹理的内存写入不能仅依赖
memcpy,需通过vkGetImageSubresourceLayout获取正确的rowPitch(压缩纹理的rowPitch按块计算,而非像素),即使是8x8纹理,也要确认设备要求的块对齐,按布局的偏移和间距写入数据。 - 验证设备格式支持:调用
vkGetPhysicalDeviceFormatProperties,确认目标设备是否支持VK_FORMAT_BC1_RGB_UNORM_BLOCK作为采样图像格式——部分Android设备优先支持ETC2或ASTC,对BC系列格式支持有限。 - 核对图像创建参数:创建纹理时,确保
VkImageCreateInfo的tiling设置为VK_IMAGE_TILING_OPTIMAL(压缩纹理通常不支持线性平铺),同时usage包含VK_IMAGE_USAGE_SAMPLED_BIT;图像视图的格式必须和图像格式严格匹配。 - 确认纹理数据有效性:用PVRTexTool重新导出BC1纹理,明确选择RGB无alpha的格式,避免导出时默认添加alpha通道导致格式不匹配;可通过工具预览纹理,确认导出的字节流正确。
- 调整采样器设置:测试将采样器的过滤模式改为
VK_FILTER_NEAREST,若能正常显示,说明设备不支持BC1纹理的线性过滤,需保持使用邻近过滤。
内容的提问来源于stack exchange,提问作者gmmo
相关产品推荐
相关产品推荐

