如何解决将组共享变量读回 CPU 内存
首先,是否有可能读取群组共享数据?或者是否需要在将组共享数据传输到 cpu 内存之前将其复制到某个 RWbuffer?由于 RWbuffers 不能被分组共享(我假设这是因为您在编译时不知道缓冲区的大小)。
对于那些感兴趣的人,这是在声明组共享缓冲区时抛出的错误:
Shader error in 'FOWComputeShader': 'Result': groupshared variables cannot hold resources at kernel CSMain at ...
基本上,我在着色器中声明了一个大的 groupshared uint 数组,价值 16kb。我将主代码中的计算缓冲区链接到这个组共享数组。调度着色器,然后从缓冲区读回。可惜我读回的数据都是0。
我在一个带有计算着色器的统一环境中工作,像这样设置我的缓冲区:
// MapSize is 128 * 128,so 16kb
// sizeof(uint) is the stride size
// ComputeBufferType.Raw,because I intend to use each uint as 4 bytes later on,so I don't want funny stuff to happen to the values
ComputeBuffer FOWMapBuffer = new ComputeBuffer(MapSize,sizeof(uint),ComputeBufferType.Raw);
FOWComputeShader.SetBuffer(kernel,"_FoWMap",FOWMapBuffer);
//just the dispatch
int ThreadCount = Mathf.CeilToInt((float)FOWdata.Count / ThreadGroupSizeX);
FOWComputeShader.Dispatch(kernel,ThreadCount,1,1);
//outVisibleToFaction is a byte array of 128 * 128 size
FOWMapBuffer.GetData(outVisibleToFaction);
FOWMapBuffer.Dispose();
然后在着色器内部:
// 4096 uints * 4 bytes per uint = 16kb
#define FoWMap_Size 4096
groupshared uint _FoWMap[FoWMap_Size];
[numthreads(32,1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
for (uint i = 0; i < FoWMap_Size; i++)
{
_FoWMap[i] = i;
}
}
这是我的环境。 有谁知道是否可以读回组共享数据,如果可以,那么为什么我的缓冲区读回全为 0?
解决方法
不,您不能直接访问 CPU 上的组共享内存。组共享内存是一块片上内存,顾名思义,它仅在单个组内的线程之间共享,因此甚至没有一个单独的组共享内存,而是多个实例(可能会也可能不会) - 存在,取决于硬件和着色器)。一旦它所属的线程组完成执行(这允许硬件为下一个线程组重新使用该内存),每个组共享内存块的生命周期就会结束。例如,在您的情况下,您实际上正在分派 ThreadCount
组,因此会有许多 16 kb 组共享内存的逻辑块,每个大小为 16 kb。
所以,总而言之,组共享内存更像是一个临时缓存,您可以使用它以便线程组内的线程可以相互通信。除了线程组中的这 32 个线程之外,没有任何东西知道该内存的内容甚至存在(因为它只在这些线程当前执行时才真正存在)。
如果这 32 个线程之外的任何东西需要访问内存,则需要将其写入 RW 缓冲区。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。