【发布时间】:2022-01-26 06:37:14
【问题描述】:
我在将统一缓冲区数据从 CPU 传输到 GPU 端时遇到问题。这似乎与 CPU/GPU 之间的内存对齐有关。我定义了一个统一的缓冲区对象如下:
const int MAX_LIGHTS_NUM = 32;
struct Lights {
glm::vec3 Position;
glm::vec3 Color;
float Linear;
float Quadratic;
float intensity;
};
struct UniformBufferObject {
glm::mat4 mvp;
glm::mat4 model;
glm::vec3 camPos;
int RealLightsNum;
Lights lights[MAX_LIGHTS_NUM];
};
在着色器代码中,它定义为:
layout(binding = 0) uniform UniformBufferObject {
mat4 mvp;
mat4 mMatrix;
vec3 CameraPosition;
int RealLightsNum;
Light lights[MAX_LIGHTS_NUM];
} ubo;
我将 MAX_LIGHTS_NUM 定义为 32。当我从 CPU 端复制内存时,我打印所有 ubo 数据并确认 CPU 端的所有数据都是正确的:
void printUBO(UniformBufferObject &ubo) {
LOGD("%s:%d Model matrix:%s", __FUNCTION__, __LINE__, glm::to_string(ubo.model).c_str());
LOGD("%s:%d MVP matrix:%s", __FUNCTION__, __LINE__, glm::to_string(ubo.mvp).c_str());
LOGD("%s:%d camPos:%s", __FUNCTION__, __LINE__, glm::to_string(ubo.camPos).c_str());
LOGD("%s:%d ubo size:%d, RealLightsNum:%d", __FUNCTION__, __LINE__, sizeof(ubo), ubo.RealLightsNum);
for (int i = 0; i < ubo.RealLightsNum; i++) {
LOGD("%s:%d Light[%d].pos: %s",
__FUNCTION__, __LINE__, i, glm::to_string(ubo.lights[i].Position).c_str());
LOGD("%s:%d Light[%d].color: %s",
__FUNCTION__, __LINE__, i, glm::to_string(ubo.lights[i].Color).c_str());
LOGD("%s:%d Light[%d].(intensity/linear/quadratic: %f, %f, %f",
__FUNCTION__, __LINE__, i, ubo.lights[i].intensity, ubo.lights[i].Linear, ubo.lights[i].Quadratic);
}
}
void VulkanHal::drawPrimitive(int nodeId, unsigned int index, size_t offset, int mode, int count,
int type) {
if (initialized == false) return;
// LOGD("%s:%d nodeId:%d, index:%u offset:%u, mode:%d, count:%d, type:%d",
// __FUNCTION__, __LINE__, nodeId, index, offset, mode, count, type);
// LOGD("%s:%d -", __FUNCTION__, __LINE__);
// LOGD("%s:%d ubo size:%d, RealLightsNum:%d", __FUNCTION__, __LINE__, sizeof(ubo), ubo.RealLightsNum);
printUBO(ubo);
int primIndex = getPrimitiveIndex(nodeId, index);
void* data;
vkMapMemory(device, uniformBuffersMemory[imageIndex][primIndex], 0, sizeof(ubo), 0, &data);
memcpy(data, &ubo, sizeof(ubo));
vkUnmapMemory(device, uniformBuffersMemory[imageIndex][primIndex]);
}
我捕获renderdoc ubo数据,发现直到RealLightsNum的数据都是正确的,但是Light数据只有第一个是部分正确的,这意味着位置正确,但是颜色第三通道不正确。
我怀疑这是内存对齐问题,但无法正确解决。有人可以帮忙吗,在此先感谢。
【问题讨论】: