| #!amber |
| # Copyright 2020 The Amber Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| SHADER vertex vert_shader PASSTHROUGH |
| |
| SHADER fragment frag_shader GLSL |
| #version 430 |
| |
| layout(location = 0) out vec4 color; |
| |
| void main() |
| { |
| color = vec4(1); |
| } |
| END |
| |
| SHADER fragment frag_shader_tex GLSL |
| #version 430 |
| layout(location = 0) out vec4 color_out; |
| uniform layout(set=0, binding=0, rgba8) readonly image2D texture; |
| void main() |
| { |
| color_out = imageLoad(texture, ivec2(gl_FragCoord.xy)); |
| } |
| END |
| |
| SHADER compute compute_shader GLSL |
| #version 430 |
| layout(local_size_x=32, local_size_y=4) in; |
| uniform layout (set=0, binding=0, rgba8) image2D img; |
| |
| int w = 256; |
| int h = 256; |
| vec4 bg = vec4(0, 0, 0, 1); |
| vec4 marked = vec4(0, 1, 1, 1); |
| vec4 error = vec4(1, 0, 0, 1); |
| |
| shared ivec2 stack[256]; |
| shared int stackPtr; |
| shared bool done; |
| shared ivec2 pixel; |
| |
| void pushMarkedPixel(ivec2 p) |
| { |
| imageStore(img, p, marked); |
| int slot = atomicAdd(stackPtr, 1); |
| stack[slot] = p; |
| } |
| |
| ivec2 popMarkedPixel() |
| { |
| int slot = atomicAdd(stackPtr, -1) - 1; |
| ivec2 p = stack[slot]; |
| imageStore(img, p, bg); |
| |
| return p; |
| } |
| |
| void main () |
| { |
| if (gl_LocalInvocationIndex == 0) |
| { |
| stack[0] = ivec2(-1); |
| stackPtr = 0; |
| done = false; |
| |
| // Use this to break the lines and verify the checker is correct. |
| //for (int x = 0; x < w; x++) |
| // imageStore(img, ivec2(x, 128), bg); |
| } |
| |
| barrier(); |
| |
| // Search for any pixel belonging to a line. |
| // Use 32 x 4 block for the search. |
| ivec2 p = ivec2(gl_LocalInvocationID) + ivec2(0, 128); |
| vec4 c = imageLoad(img, p); |
| // Any of the pixels found by a thread will do as a starting point. |
| if (c != bg) |
| stack[0] = p; |
| |
| barrier(); |
| |
| if (gl_LocalInvocationIndex == 0 && stack[0] != ivec2(-1)) |
| { |
| imageStore(img, stack[0], marked); |
| stackPtr++; |
| } |
| |
| barrier(); |
| |
| while (!done) |
| { |
| if (gl_LocalInvocationIndex == 0 && stackPtr != 0) |
| pixel = popMarkedPixel(); |
| |
| barrier(); |
| |
| if (gl_LocalInvocationID.x < 3 && gl_LocalInvocationID.y < 3) |
| { |
| ivec2 p = pixel + ivec2(gl_LocalInvocationID) - ivec2(1); |
| if (p.x >= 0 && p.y >= 0 && p.x < w && p.y < h) |
| { |
| vec4 c = imageLoad(img, p); |
| if (c != marked && c != bg) |
| { |
| pushMarkedPixel(p); |
| } |
| } |
| } |
| |
| barrier(); |
| |
| if (gl_LocalInvocationIndex == 0 && stackPtr < 1) |
| done = true; |
| |
| barrier(); |
| } |
| } |
| END |
| |
| BUFFER position DATA_TYPE R8G8_SNORM DATA |
| -120 -120 |
| -119 120 |
| 120 119 |
| 10 20 |
| -80 20 |
| -80 95 |
| -83 95 |
| -83 -95 |
| -85 95 |
| END |
| |
| BUFFER texture FORMAT R8G8B8A8_UNORM |
| BUFFER framebuffer FORMAT B8G8R8A8_UNORM |
| |
| PIPELINE graphics pipeline |
| ATTACH vert_shader |
| ATTACH frag_shader |
| |
| VERTEX_DATA position LOCATION 0 |
| |
| BIND BUFFER texture AS color LOCATION 0 |
| FRAMEBUFFER_SIZE 256 256 |
| END |
| |
| PIPELINE graphics tex_pipeline |
| ATTACH vert_shader |
| ATTACH frag_shader_tex |
| BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 |
| FRAMEBUFFER_SIZE 256 256 |
| BIND BUFFER framebuffer AS color LOCATION 0 |
| END |
| |
| PIPELINE compute verification_pipeline |
| ATTACH compute_shader |
| BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 |
| FRAMEBUFFER_SIZE 256 256 |
| END |
| |
| CLEAR_COLOR pipeline 0 0 0 255 |
| CLEAR pipeline |
| |
| RUN pipeline DRAW_ARRAY AS LINE_STRIP START_IDX 0 COUNT 9 |
| RUN verification_pipeline 1 1 1 |
| RUN tex_pipeline DRAW_RECT POS 0 0 SIZE 256 256 |
| |
| # Everything should be clear color since the checker consumes |
| # the drawn pixels if they are continuous. |
| EXPECT framebuffer IDX 0 0 SIZE 256 255 EQ_RGBA 0 0 0 255 |