Я пытаюсь написать общую реализацию гауссово-размытия общего вычислительного шейдера.Вычислительная шейдерная общая память содержит артефакты
В основном он работает, однако он содержит артефакты, которые меняют каждый кадр, даже когда сцена статична. Я провел последние несколько часов, пытаясь отладить это. Я дошел до того, что границы не превышены, разворачиваются все петли, заменяются униформы постоянными, но артефакты сохраняются.
Я тестировал исходный код с артефактами на трех разных машинах/графических процессорах (2 nvidia, 1 intel), и все они дают одинаковые результаты. Имитация развернутой/постоянной версии выполнения кодов с рабочими группами, выполненными вперед и назад с помощью простого кода на C++, не вызывает этих ошибок.
При выделении общего массива [96] [96] вместо [16] [48] можно устранить большинство из артефактов.
Это привело меня к мысли о том, что мне не хватает логической ошибки, поэтому мне удалось создать очень простой шейдер, который все еще производит ошибку в меньших масштабах, я был бы признателен, если бы кто-нибудь мог указать на причину , Я проверил много документации и не нашел ничего неправильного.
Предоставлен общий массив с поплавками 16x48, это 3072 байта, примерно 10% от минимального предела общей памяти.
Затенение запускаются в 16x16 рабочих группах, так что каждый поток будет написать 3 уникальных места, и считывается из одного уникального местоположения
текстуры затем рендерера, как ВПГ в результате чего между Vals 0-1 будет отображаться на оттенок 0-360 (красный-голубой-красный), а значения из границ будут красными.
#version 430
//Execute in 16x16 sized thread blocks
layout(local_size_x=16,local_size_y=16) in;
uniform layout (r32f) restrict writeonly image2D _imageOut;
shared float hoz[16][48];
void main()
{
//Init shared memory with a big out of bounds value we can identify
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 20000.0f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 20000.0f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 20000.0f;
//Sync shared memory
memoryBarrierShared();
//Write the values we want to actually read back
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 0.5f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 0.5f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 0.5f;
//Sync shared memory
memoryBarrierShared();
//i=0,8,16 work
//i=1-7,9-5,17 don't work (haven't bothered testing further
const int i = 17;
imageStore(_imageOut, ivec2(gl_GlobalInvocationID.xy), vec4(hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+i]));
//Sync shared memory (can't hurt)
memoryBarrierShared();
}
Запуск этого шейдера с размерами запуска больше, чем 8х8 производит артефакты в пораженной области изображения.
glDispatchCompute(9, 9, 0); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
мне пришлось останова и шаг кадров, чтобы захватить это, занимает около 14 кадров
glDispatchCompute(512/16, 512/16, 0);//Full image is 512x512 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
Снова пришлось останова и шаг кадров, чтобы захватить это, при работе с 60FPS (vsync) артефакты появлялись чаще/одновременно.
Спасибо, это исправлено. Тем не менее, слишком быстро снимать документы. – Robadob