c++ - 在 Vulkan 中加载非二次幂纹理

标签 c++ image graphics vulkan

如果我的纹理尺寸是二次方,我的 2D 纹理加载器工作正常,但如果不是,纹理数据显示为倾斜。我该如何解决?我认为这个问题与内存对齐和行距有关。这是我的加载程序代码的相关部分:

VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements( GfxDeviceGlobal::device, mappableImage, &memReqs );

VkMemoryAllocateInfo memAllocInfo = {};
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAllocInfo.pNext = nullptr;
memAllocInfo.memoryTypeIndex = 0;
memAllocInfo.allocationSize = memReqs.size;

GetMemoryType( memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAllocInfo.memoryTypeIndex );

VkDeviceMemory mappableMemory;
err = vkAllocateMemory( GfxDeviceGlobal::device, &memAllocInfo, nullptr, &mappableMemory );
CheckVulkanResult( err, "vkAllocateMemory in Texture2D" );

err = vkBindImageMemory( GfxDeviceGlobal::device, mappableImage, mappableMemory, 0 );
CheckVulkanResult( err, "vkBindImageMemory in Texture2D" );

VkImageSubresource subRes = {};
subRes.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subRes.mipLevel = 0;
subRes.arrayLayer = 0;

VkSubresourceLayout subResLayout;
vkGetImageSubresourceLayout( GfxDeviceGlobal::device, mappableImage, &subRes, &subResLayout );

void* mapped;
err = vkMapMemory( GfxDeviceGlobal::device, mappableMemory, 0, memReqs.size, 0, &mapped );
CheckVulkanResult( err, "vkMapMemory in Texture2D" );

const int bytesPerPixel = 4;
std::size_t dataSize = bytesPerPixel * width * height;
std::memcpy( mapped, data, dataSize );

vkUnmapMemory( GfxDeviceGlobal::device, mappableMemory );

最佳答案

您从 vkGetImageSubresourceLayout 获得的 VkSubresourceLayout 将在 rowPitch 成员中包含纹理的间距。它很可能不等于 width,因此,当您对整个数据 block 执行 memcpy 时,您会将相关数据复制到纹理的填充部分.

相反,您需要逐行memcpy,跳过映射纹理中的填充内存:

const int bytesPerPixel = 4;
std::size_t dataRowSize = bytesPerPixel * width;
char* mappedBytes = (char*)mapped;
for(int i = 0; i < height; ++i)
{
    std::memcpy(mapped, data, dataSize);
    mappedBytes += rowPitch;
    data += dataRowSize;
}

(此代码假定数据也是 char * - 未给出其声明)

关于c++ - 在 Vulkan 中加载非二次幂纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36028497/

相关文章:

c# - 文件存在总是返回 false

java - JMD 的替代方案

opengl - 可移植 YUV 绘图上下文

c++ - 从 std::vector 的开头移除

c++ - 在C++中使用1-d索引数组访问n-d数组元素的更好方法?

java - 在Java中将字符串绘制到图像

c++ - 如何计算网格的法线?

wpf - 我可以从 WPF 窗口获取 HDC 以便我可以使用 Gdi+ API 绘制它吗?

c++ - 括号和空格的位置会影响编译时间和/或运行时间吗?

c++ - 无法将 argv 传递给在 main 中调用的函数