有人可以告诉我DirectX 11是否可以使用以下计算着色器?
我希望Dispatch中的第一个线程访问缓冲区中的元素(g_positionsGrid),以便将该元素与临时值设置(比较交换),以表示它正在采取某些操作。
在这种情况下,临时值为0xffffffff,第一个线程将继续运行,并从结构化的附加缓冲区(g_positions)中分配一个值,并将其分配给该元素。
所以到目前为止一切正常,但是调度中的其他线程可以进入比较交换和第一个线程的分配之间,因此需要等到分配索引可用。我这样做是为了忙碌的等待,即while循环。
然而遗憾的是,这只是锁定GPU,因为我假设第一个线程写入的值不会传播到插入while循环中的其他线程。
有没有办法让这些线程看到这个值?
感谢您的帮助!
RWStructuredBuffer<float3> g_positions : register(u1);
RWBuffer<uint> g_positionsGrid : register(u2);
void AddPosition( uint address, float3 pos )
{
uint token = 0;
// Assign a temp value to signify first thread has accessed this particular element
InterlockedCompareExchange(g_positionsGrid[address], 0, 0xffffffff, token);
if(token == 0)
{
//If first thread in here allocate index and assign value which
//hopefully the other threads will pick up
uint index = g_positions.IncrementCounter();
g_positionsGrid[address] = index;
g_positions[index].m_position = pos;
}
else
{
if(token == 0xffffffff)
{
uint index = g_positionsGrid[address];
//This never meets its condition
[allow_uav_condition]
while(index == 0xffffffff)
{
//For some reason this thread never gets the assignment
//from the first thread assigned above
index = g_positionsGrid[address];
}
g_positions[index].m_position = pos;
}
else
{
//Just assign value as the first thread has already allocated a valid slot
g_positions[token].m_position = pos;
}
}
}
答案 0 :(得分:2)
DirectCompute中的线程同步非常简单,但与CPU线程相同的功能相比,非常不灵活。 AFAIK是在计算着色器中线程之间同步数据的唯一方法是使用groupshared
内存和GroupMemoryBarrierWithGroupSync()
。这意味着,您可以:
groupshared
内存中创建小型临时缓冲区groupshared
缓冲区GroupMemoryBarrierWithGroupSync()
groupshared
读取并以某种方式使用它要实现所有这些东西,您需要正确的数组索引。但是你可以从哪里拿走它?在Dispatch中传递的DirectCompute值和可以在着色器中获得的系统值(SV_GroupIndex,SV_DispatchThreadID,SV_GroupThreadID,SV_GroupID)related。使用该值,您可以计算索引以评估缓冲区。
计算着色器没有详细记录,并且没有简单的方法,但至少可以找到更多信息:
截至您的代码。好吧,可能你可以重新设计一下。
所有线程执行相同任务总是好的。对称加载。实际上,您不能像在CPU代码中那样为线程分配不同的任务。
如果您的数据首先需要一些预处理和进一步处理,您可能希望将其划分为您将按顺序调用的不同Dispatch()调用(不同着色器):
preprocessShader
从缓冲区inputData
读取并写入preprocessedData
calculateShader
来自preprocessedData
并且写入finalData
在这种情况下,您可以删除任何慢线程同步和慢速组共享内存。
请看上面提到的“线程缩减”技巧。
希望它有所帮助!快乐的编码!