我正在尝试通过Unity/CG/HLSL中的计算着色器将纹理转换为频域,即我正在尝试从纹理中读取像素值并输出一组基函数系数的数组。我该如何做?我对计算着色器很陌生,所以有点迷茫。我理解竞争条件的原因以及计算着色器如何分配工作负载,但是否有任何方法来处理这个问题?总的来说,对于没有相关背景的人来说,关于缓冲区和其他内容的文档似乎有些令人失望。
我得到的错误信息: “在‘Compute.compute’着色器中发现写入共享资源的竞争条件,请考虑使此写入有条件。 在Compute.compute(xxx)的testBuffer内核中(在d3d11上)”
一个简单的例子可以是将所有像素值相加,目前我的方法如下。我正在尝试使用StructuredBuffer,因为我不知道如何以其他方式检索数据或在全局着色器访问后将其存储在GPU上?
整个过程不会抛出竞态条件错误,如果将缓冲区展开为单个值,就像这样:
不要使用StructuredBuffer,但在这种情况下,我不知道如何在内核调度后检索数据。如果是我正在使用的RWStructuredBuffer的读取部分,但是有什么等效的缓冲区可以只写入?因为我实际上不读取数据。或者一般的操作符"+="是否已经引起了竞态条件无论如何?
从Google中,我发现一个解决方案可能是使用GroupMemoryBarrierWithGroupSync(); 但我不知道这是什么(更不用说它是如何工作的),而且通常Google的结果对我来说有点难以理解。
请问是否有人能提供一个如何解决此问题的示例?否则,我很感激任何指针。
我得到的错误信息: “在‘Compute.compute’着色器中发现写入共享资源的竞争条件,请考虑使此写入有条件。 在Compute.compute(xxx)的testBuffer内核中(在d3d11上)”
一个简单的例子可以是将所有像素值相加,目前我的方法如下。我正在尝试使用StructuredBuffer,因为我不知道如何以其他方式检索数据或在全局着色器访问后将其存储在GPU上?
struct valueStruct{
float4 values[someSize];
}
RWStructuredBuffer<valueStruct> valueBuffer;
// same behaviour if using RWStructuredBuffer<float3> valueBuffer;
// if using 'StructuredBuffer<float3> valueBuffer;' i get the error:
// Shader error in 'Compute.compute': l-value specifies const object at kernel testBuffer at Compute.compute(xxx) (on d3d11)
Texture2D<float4> Source;
[numthreads(8, 8, 1)]
void testBuffer(uint3 id : SV_DispatchThreadID) {
valueBuffer[0].values[0] += Source[id.xy]; // in theory the vaules
valueBuffer[0].values[1] += Source[id.xy]; // would be different
valueBuffer[0].values[2] += Source[id.xy]; // but it doesn't really
valueBuffer[0].values[3] += Source[id.xy]; // matter for this, so
valueBuffer[0].values[4] += Source[id.xy]; // they are just Source[id.xy]
//.....
}
整个过程不会抛出竞态条件错误,如果将缓冲区展开为单个值,就像这样:
float3 value0;
float3 value1;
float3 value2;
float3 value3;
float3 value4;
float3 value5;
float3 value6;
float3 value7;
float3 value8;
[numthreads(8, 8, 1)]
void testBuffer(uint3 id : SV_DispatchThreadID) {
value0 += Source[id.xy]; // in theory the vaules
value1 += Source[id.xy]; // would be different
value1 += Source[id.xy]; // but it doesn't really
value1 += Source[id.xy]; // matter for this, so
value1 += Source[id.xy]; // they are just Source[id.xy]
}
不要使用StructuredBuffer,但在这种情况下,我不知道如何在内核调度后检索数据。如果是我正在使用的RWStructuredBuffer的读取部分,但是有什么等效的缓冲区可以只写入?因为我实际上不读取数据。或者一般的操作符"+="是否已经引起了竞态条件无论如何?
从Google中,我发现一个解决方案可能是使用GroupMemoryBarrierWithGroupSync(); 但我不知道这是什么(更不用说它是如何工作的),而且通常Google的结果对我来说有点难以理解。
请问是否有人能提供一个如何解决此问题的示例?否则,我很感激任何指针。