GL_MAP_UNSYNCHRONIZED_BIT与glMapBufferRange的行为合规性问询
GL_MAP_UNSYNCHRONIZED_BIT 与 glDraw 未定义行为判断
OpenGL 4.6 与 OpenGL ES 3.0 对
GL_MAP_UNSYNCHRONIZED_BIT的定义一致:设置该位后,GL 不会在Map*BufferRange返回前尝试同步缓冲区上的待处理操作。若待处理操作的源/修改区域与映射区域重叠,不会触发 GL 错误,但此类先前及后续操作的结果均未定义。
第一段代码分析
// 分配12个颜色的缓冲区并复制12个红色 glBufferData(GL_ARRAY_BUFFER, sizeof(twelveColorsAllRed), twelveColorsAllRed, GL_DYNAMIC_DRAW); // 映射最后6个颜色 void* p = glMapBufferRange( GL_ARRAY_BUFFER, sizeOf6Colors, // 偏移量 sizeOf6Colors, // 大小 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); // 更新最后6个颜色 memcpy(p, sixColorsAllGreen, sizeof(sixColorsAllGreen)); glUnmapBuffer(GL_ARRAY_BUFFER); // 是否为未定义行为? glDraw(... 使用最后6个颜色的参数与状态 ...)
- 结论:不属于未定义行为
- 原因:
glBufferData执行后会隐式同步所有之前的缓冲区操作并完成数据初始化,此时缓冲区无待处理的读写操作。后续映射、修改的区域与glDraw使用的区域完全一致,不存在待处理操作与映射区域重叠的情况,符合规范要求,行为确定。
第二段代码分析
// 分配12个颜色的缓冲区并复制12个红色 glBufferData(GL_ARRAY_BUFFER, sizeof(twelveColorsAllRed), twelveColorsAllRed, GL_DYNAMIC_DRAW); // 安全操作 glDraw(... 使用前6个颜色的参数与状态 ...) // 映射最后6个颜色 void* p = glMapBufferRange( GL_ARRAY_BUFFER, sizeOf6Colors, // 偏移量 sizeOf6Colors, // 大小 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); // 更新6个颜色 memcpy(p, sixColorsAllGreen, sizeof(sixColorsAllGreen)); glUnmapBuffer(GL_ARRAY_BUFFER); // 是否为未定义行为? glDraw(... 使用最后6个颜色的参数与状态 ...)
- 结论:不属于未定义行为
- 原因:中间的
glDraw使用缓冲区前6个颜色区域,与后续映射、修改的最后6个区域无重叠。映射操作时,待处理的glDraw操作和映射区域不冲突,不会触发规范中提到的未定义场景。后续修改完成后执行的glDraw使用的是明确更新后的区域,行为确定。
内容的提问来源于stack exchange,提问作者user128511
相关产品推荐
相关产品推荐

