一个粒子太多:生成 GL_INVALID_VALUE 错误。 <start> 不满足着色器存储缓冲区的最低对齐要求
One Particle too much: GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers
我的粒子系统出现了一个奇怪的错误。我动态设置缓冲区的大小,并且可以根据需要更改粒子的数量。我正在玩 30k、40k 以及介于两者之间的所有数字。最大值达到 40800... 然后我从输出终端的标题中得到错误。
这是代码:
Log::logInfo(m_Name, "Bind particle buffers...");
/// ssbo sizes
constexpr ptrdiff_t positionSSBOsize = sizeof(glm::vec4) * NUM_PARTICLES;
constexpr ptrdiff_t velocitySSBOsize = sizeof(glm::vec2) * NUM_PARTICLES;
constexpr ptrdiff_t forceSSBOsize = sizeof(glm::vec2) * NUM_PARTICLES;
constexpr ptrdiff_t densitySSBOsize = sizeof(float) * NUM_PARTICLES;
constexpr ptrdiff_t pressureSSBOsize = sizeof(float) * NUM_PARTICLES;
/// total size
constexpr ptrdiff_t packedBufferSize = positionSSBOsize + velocitySSBOsize + forceSSBOsize + densitySSBOsize + pressureSSBOsize;
/// ssbo offsets
constexpr ptrdiff_t positionSSBOoffset = 0;
constexpr ptrdiff_t velocitySSBOoffset = positionSSBOsize;
constexpr ptrdiff_t forceSSBOoffset = velocitySSBOoffset + velocitySSBOsize;
constexpr ptrdiff_t densitySSBOoffset = forceSSBOoffset + forceSSBOsize;
constexpr ptrdiff_t pressureSSBOoffset = densitySSBOoffset + densitySSBOsize;
/// set inital positions
this->initParticleSeeds(packedBufferSize, positionSSBOsize, m_PackedParticlesBufferHandle);
/// bind to inital positions data
this->bindBufferToVertexArrayObject(m_ParticlePositionVaoHandle, m_PackedParticlesBufferHandle, PARTICLE_SEEDS_NR);
/// bindings
//@TODO: Here we got a problem after increasing NUM_PARTICLES, the error that the MAX_SHADER_STORAGE_BUFFER_BINDINGS are reached, thats why INVALID_ERROR is thrown
Log::logInfo(m_Name, "Bind particle buffers: positions");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_POS_NR, m_PackedParticlesBufferHandle, positionSSBOoffset, positionSSBOsize); /// Particle Positions
Log::logInfo(m_Name, "Bind particle buffers: velocities");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_VEL_NR, m_PackedParticlesBufferHandle, velocitySSBOoffset, velocitySSBOsize); /// Particle Velocities
Log::logInfo(m_Name, "Bind particle buffers: force");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_FRC_NR, m_PackedParticlesBufferHandle, forceSSBOoffset, forceSSBOsize); /// Particle Force
Log::logInfo(m_Name, "Bind particle buffers: density");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_DNS_NR, m_PackedParticlesBufferHandle, densitySSBOoffset, densitySSBOsize); /// Particle Density
Log::logInfo(m_Name, "Bind particle buffers: pressure");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_PRS_NR, m_PackedParticlesBufferHandle, pressureSSBOoffset, pressureSSBOsize); /// Particle Pressure
Log::logInitSucc(m_Name, "particle buffers");
正如我所说,除了在 40801 粒子时,我的日志中出现以下错误并且我的一些缓冲区不再加载外,一切正常:
[APPLICATION]:: Bind particle buffers...
[APPLICATION]:: Init particle seeds ...
[APPLICATION]:: Save data in buffer ...
[SOURCE_API]:: [TYPE_OTHER][131185] [SEVERITY_NOTIFICATION] Buffer detailed info: Buffer object 3 (bound to GL_SHADER_STORAGE_BUFFER, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
[APPLICATION]:: Init particle seeds SUCCESS!
[APPLICATION]:: Bind vertex array object (VAO) to buffer ...
[APPLICATION]:: Init VAO SUCCESS!
[APPLICATION]:: Bind particle buffers: positions
[APPLICATION]:: Bind particle buffers: velocities
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
[APPLICATION]:: Bind particle buffers: force
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
[APPLICATION]:: Bind particle buffers: density
[APPLICATION]:: Bind particle buffers: pressure
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
无法使用 glBindBufferRange
将任意偏移量寻址到缓冲区中。偏移量必须是相应缓冲区偏移对齐的倍数,这取决于所使用的缓冲区类型。此限制取决于平台,由 GPU 上的底层内存架构强加。
对于SSBO(此处使用),相关对齐方式可通过以下代码查询:
glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
中找到更多详细信息
我的粒子系统出现了一个奇怪的错误。我动态设置缓冲区的大小,并且可以根据需要更改粒子的数量。我正在玩 30k、40k 以及介于两者之间的所有数字。最大值达到 40800... 然后我从输出终端的标题中得到错误。
这是代码:
Log::logInfo(m_Name, "Bind particle buffers...");
/// ssbo sizes
constexpr ptrdiff_t positionSSBOsize = sizeof(glm::vec4) * NUM_PARTICLES;
constexpr ptrdiff_t velocitySSBOsize = sizeof(glm::vec2) * NUM_PARTICLES;
constexpr ptrdiff_t forceSSBOsize = sizeof(glm::vec2) * NUM_PARTICLES;
constexpr ptrdiff_t densitySSBOsize = sizeof(float) * NUM_PARTICLES;
constexpr ptrdiff_t pressureSSBOsize = sizeof(float) * NUM_PARTICLES;
/// total size
constexpr ptrdiff_t packedBufferSize = positionSSBOsize + velocitySSBOsize + forceSSBOsize + densitySSBOsize + pressureSSBOsize;
/// ssbo offsets
constexpr ptrdiff_t positionSSBOoffset = 0;
constexpr ptrdiff_t velocitySSBOoffset = positionSSBOsize;
constexpr ptrdiff_t forceSSBOoffset = velocitySSBOoffset + velocitySSBOsize;
constexpr ptrdiff_t densitySSBOoffset = forceSSBOoffset + forceSSBOsize;
constexpr ptrdiff_t pressureSSBOoffset = densitySSBOoffset + densitySSBOsize;
/// set inital positions
this->initParticleSeeds(packedBufferSize, positionSSBOsize, m_PackedParticlesBufferHandle);
/// bind to inital positions data
this->bindBufferToVertexArrayObject(m_ParticlePositionVaoHandle, m_PackedParticlesBufferHandle, PARTICLE_SEEDS_NR);
/// bindings
//@TODO: Here we got a problem after increasing NUM_PARTICLES, the error that the MAX_SHADER_STORAGE_BUFFER_BINDINGS are reached, thats why INVALID_ERROR is thrown
Log::logInfo(m_Name, "Bind particle buffers: positions");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_POS_NR, m_PackedParticlesBufferHandle, positionSSBOoffset, positionSSBOsize); /// Particle Positions
Log::logInfo(m_Name, "Bind particle buffers: velocities");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_VEL_NR, m_PackedParticlesBufferHandle, velocitySSBOoffset, velocitySSBOsize); /// Particle Velocities
Log::logInfo(m_Name, "Bind particle buffers: force");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_FRC_NR, m_PackedParticlesBufferHandle, forceSSBOoffset, forceSSBOsize); /// Particle Force
Log::logInfo(m_Name, "Bind particle buffers: density");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_DNS_NR, m_PackedParticlesBufferHandle, densitySSBOoffset, densitySSBOsize); /// Particle Density
Log::logInfo(m_Name, "Bind particle buffers: pressure");
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SHADER_PART_PRS_NR, m_PackedParticlesBufferHandle, pressureSSBOoffset, pressureSSBOsize); /// Particle Pressure
Log::logInitSucc(m_Name, "particle buffers");
正如我所说,除了在 40801 粒子时,我的日志中出现以下错误并且我的一些缓冲区不再加载外,一切正常:
[APPLICATION]:: Bind particle buffers...
[APPLICATION]:: Init particle seeds ...
[APPLICATION]:: Save data in buffer ...
[SOURCE_API]:: [TYPE_OTHER][131185] [SEVERITY_NOTIFICATION] Buffer detailed info: Buffer object 3 (bound to GL_SHADER_STORAGE_BUFFER, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
[APPLICATION]:: Init particle seeds SUCCESS!
[APPLICATION]:: Bind vertex array object (VAO) to buffer ...
[APPLICATION]:: Init VAO SUCCESS!
[APPLICATION]:: Bind particle buffers: positions
[APPLICATION]:: Bind particle buffers: velocities
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
[APPLICATION]:: Bind particle buffers: force
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
[APPLICATION]:: Bind particle buffers: density
[APPLICATION]:: Bind particle buffers: pressure
[SOURCE_API]:: [TYPE_ERROR][1281] [SEVERITY_HIGH] GL_INVALID_VALUE error generated. <start> does not meet minimum alignment requirements for shader storage buffers.
无法使用 glBindBufferRange
将任意偏移量寻址到缓冲区中。偏移量必须是相应缓冲区偏移对齐的倍数,这取决于所使用的缓冲区类型。此限制取决于平台,由 GPU 上的底层内存架构强加。
对于SSBO(此处使用),相关对齐方式可通过以下代码查询:
glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
中找到更多详细信息