Я пытаюсь преобразовать текстуру в частотную область с помощью вычислительного шейдера в единстве / CG / hlsl, т.е. я пытаюсь прочитать значения пикселей из текстуры и вывести массив коэффициентов базовой функции. как бы я это сделал? Я действительно новичок в вычислении шейдеров, поэтому я немного потерялся. Я понимаю причину состояния гонки и то, как вычислительные шейдеры разделяют рабочую нагрузку, но есть ли способ с этим справиться? В целом документация по буферам и другим вещам кажется немного разочаровывающей для тех, кто не разбирается в этом вопросе.
ошибка, которую я получаю: Shader error in 'Compute.compute': race condition writing to shared resource detected, consider making this write conditional. at kernel testBuffer at Compute.compute(xxx) (on d3d11)
упрощенный пример может заключаться в суммировании всех значений пикселей, в настоящее время мой подход будет следующим. Я пытаюсь использовать структурированные буферы, так как я не знаю, как еще я смогу впоследствии получить данные или сохранить их на графическом процессоре для доступа к глобальному шейдеру ??
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]
}
и не использую структурированный буфер, но в этом случае я не знаю, как получить данные после отправки ядра. Если дело доходит до части READ RWStructuredBuffer, которую я использую, но какой будет эквивалентный буфер, в который я могу только писать? Поскольку я действительно не читаю данные. Или общий оператор «+ =» уже вызывает состояние гонки, несмотря ни на что?
из Google я обнаружил, что решение может использовать GroupMemoryBarrierWithGroupSync();
?? но я понятия не имею, что это такое (не говоря уже о том, как это работает), и в целом результаты Google просто немного летают над моей головой в банкомате
может ли кто-нибудь привести пример того, как решить эту проблему? В противном случае я оцениваю любые указатели.