My other post собирается собирать общую информацию о видах шлейфов GLSL, но, к сожалению, ничего из этого не случилось, и проблема не решена. Поэтому конкретный вопрос. Я уменьшил свою проблему до минимального примера, представленного ниже:Доступ к атомным изображениям GLSL
Тривиальная проблема создает текстуру замков и текстуру цвета размером с экран. В проходе 1 все цвета установлены на ноль (шейдер 1). В проходе два нарисованы два треугольника, которые геометрические шейдеры округляются и слегка смещаются (шейдер 2). Фрагментный шейдер атомарно увеличивает цвет текстуры. В проходе три, цвет визуализируется (шейдер 3).
шейдер 1:
//Vertex
#version 440
uniform mat4 mat_P;
in vec4 _vec_vert_a;
void main(void) {
gl_Position = mat_P*_vec_vert_a;
}
//Fragment
#version 440
layout(rgba32f) coherent uniform image2D img0;
void main(void) {
imageStore(img0,ivec2(gl_FragCoord.xy),vec4(0.0,0.0,0.0,1.0));
discard;
}
шейдер 2:
//Vertex
#version 440
in vec4 _vec_vert_a;
out vec4 vert_vg;
void main(void) {
vert_vg = _vec_vert_a;
}
//Geometry
#version 440
#define REPS 4
layout(triangles) in;
layout(triangle_strip,max_vertices=3*REPS) out;
uniform mat4 mat_P;
in vec4 vert_vg[3];
void main(void) {
for (int rep=0;rep<REPS;++rep) {
for (int i=0;i<3;++i) {
vec4 vert = vert_vg[i];
vert.xy += vec2(5.0*rep);
gl_Position = mat_P*vert; EmitVertex();
}
EndPrimitive();
}
}
//Fragment
#version 440
layout(rgba32f) coherent uniform image2D img0;
layout(r32ui) coherent uniform uimage2D img1;
void main(void) {
ivec2 coord = ivec2(gl_FragCoord.xy);
bool have_written = false;
do {
bool can_write = (imageAtomicExchange(img1,coord,1u)!=1u);
if (can_write) {
vec4 data = imageLoad(img0,coord);
data.xyz += vec3(1.0,0.0,0.0);
imageStore(img0,coord,data);
memoryBarrier();
imageAtomicExchange(img1,coord,0);
have_written = true;
}
} while (!have_written);
discard;
}
шейдер 3:
//Vertex
#version 440
uniform mat4 mat_P;
in vec4 _vec_vert_a;
void main(void) {
gl_Position = mat_P*_vec_vert_a;
}
#version 440
layout(rgba32f) coherent uniform image2D img0;
void main(void) {
vec4 data = imageLoad(img0,ivec2(gl_FragCoord.xy));
gl_FragData[0] = vec4(data.rgb/4.0, 1.0); //tonemap
}
Главный цикл:
- Enable шейдер 1
- визуализации Полноэкранный Quad
glMemoryBarrier (GL_ALL_BARRIER_BITS);
Enable шейдер 2
- Рендер два небольших треугольников
glMemoryBarrier (GL_ALL_BARRIER_BITS);
Включить Shader 3
- делают Fullscreen квадроциклов
Обратите внимание, что в пунктах 3 и 6 Я [думаю, что я] мог бы использовать GL_SHADER_IMAGE_ACCESS_BARRIER_BIT. На всякий случай, я консервативен.
Визуализированный джиттер цвета со временем и в основном довольно мал. Это показывает, что атомарности не происходит. Может ли кто-то здравомыслие проверить эту процедуру? Я что-то пропустил?
EDIT: From this page, я обнаружил, что использование discard
может сделать загрузку/сохранение изображения неопределенным во фрагменте. Я удалил сброс, но проблема все еще возникает. Я также нашел layout(early_fragment_tests) in;
, что заставляет ранние фрагментные тесты (это тоже не помогло).
Аналого буфера кода не работает (первая версия дает ошибку GL перед визуализацией ничего , о котором я сообщил, и связанный с ним просто сбой). При поиске другого примера кода я также нашел http://soconne.blogspot.com/p/demos.html, некоторые из которых произошли из-за внутренних ошибок компилятора. Я тоже пробовал цикл for. Должен быть лучший способ, чем пытаться перепрограммировать код производителя в рекламе. – imallett