计算着色器不写入缓冲区?
Compute shader does not write to buffer?
我正在尝试在计算着色器上进行剔除。 我的问题是我的原子计数器似乎没有被着色器写入,或者它确实被取消了?
Renderdoc说它没有数据,但InstancesOut中有值 (见下图(
这是我的计算着色器:
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
struct Indirect
{
uint indexCount;
uint instanceCount;
uint firstIndex;
uint vertexOffset;
uint firstInstance;
};
struct Instance
{
vec4 position;
};
layout (binding = 0, std430) buffer IndirectDraws
{
Indirect indirects[];
};
layout (binding = 1) uniform UBO
{
vec4 frustum[6];
} ubo;
layout (binding = 2, std140) readonly buffer Instances
{
Instance instances[];
};
layout (binding = 3, std140) writeonly buffer InstancesOut
{
Instance instancesOut[];
};
layout (binding = 4) buffer Counter
{
uint counter;
};
bool checkFrustrum(vec4 position, float radius)
{
for(uint i = 0; i < 6; i++)
if(dot(position, ubo.frustum[i]) + radius < 0.0)
return false;
return true;
}
layout (local_size_x = 1) in;
void main()
{
uint i = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x;
uint instanceCount = 0;
if(i == 0)
atomicExchange(counter, 0);
for(uint x = 0; x < indirects[i].instanceCount; x++)
{
vec4 position = instances[indirects[i].firstInstance + x].position;
//if(checkFrustrum(position, 1.0))
//{
instancesOut[atomicAdd(counter, 1)].position = position;
instanceCount++;
//}
}
//indirects[i].instanceCount = instanceCount;
indirects[i].instanceCount = i; // testing
}
RenderDoc 中的缓冲区图片
感谢您的帮助!
似乎您对同步和工作组的工作方式产生了误解。
在计算着色器中,原子将允许您跨工作组同步。但是,不能保证工作组的执行顺序,因此atomicExchange(counter,0(;不能保证在其他工作组执行之前发生。错误#1?
工作组大小为 1 是对资源的巨大浪费,尤其是当您要经历跨工作组同步的费用时。工作组内的同步始终是最快的,它允许您实际使用 GPU 资源(大多数 GPU 被组织到包含 SIMD 处理器的模块中,这些处理器一次只能处理一个工作组的执行。如果仅使用大小为 1 的工作组,则这些处理器中的 31/32 或 63/64 将处于空闲状态。{警告,大多数相同的处理器可以同时在内存中容纳多个工作组,但在任何给定时刻只在一个工作组上执行}(。 此外,在工作组中,您可以将执行与屏障同步,确保操作顺序。错误#2?
atomicCounterIncrement 可能是更好的指令,如果你只添加一个。
在您的特定应用程序中,为什么 instanceOut 的答案是错误的? 对我来说,实际上似乎是对的,每个输入最终都会出现在输出中,没有保证的顺序(因为不能保证工作组以特定顺序执行,即这就是并行执行的工作方式(。如果您希望它们按顺序排列,请根据调用 ID 计算它?
至于为什么 renderDoc 没有在计数器中显示值,我不知道,如果映射正确,它应该有一个值。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- C++字符*缓冲区的大小
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 如何用尽可能少的数据将数据缓冲区计算为零校验和值
- 计算着色器不写入缓冲区?
- GLSL 计算着色器 使用查找表设置缓冲区会导致不写入任何数据,与其他数据设置相同的缓冲区有效
- 计算着色器不写入缓冲区
- QML:读取由计算着色器操作的缓冲区
- 计算gpu前缓冲区中像素的平均值,而无需将前缓冲区复制回系统内存
- 如何计算帧缓冲区间距
- 从缓冲区指针计算堆栈中的返回地址
- 对于 DirectX 11,我可以做些什么来不计算每个渲染()中的缓冲区
- 将顶点缓冲区绑定到计算着色器以修改数据
- 为什么 glDrawElements 在使用相同的缓冲区进行计算着色和渲染时会干扰 glGetBufferSubData
- C++ 3 台计算机上的缓冲区溢出不同
- 根据glm::项目输出计算z缓冲区