1#!amber 2# Copyright 2020 Google LLC. 3# Copyright 2020 The Khronos Group Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# https://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17SHADER vertex vert_shader PASSTHROUGH 18 19SHADER fragment frag_shader GLSL 20#version 430 21 22layout(location = 0) out vec4 color; 23 24void main() 25{ 26 color = vec4(1); 27} 28END 29 30SHADER fragment frag_shader_tex GLSL 31#version 430 32layout(location = 0) out vec4 color_out; 33uniform layout(set=0, binding=0, rgba8) readonly image2D texture; 34void main() 35{ 36 color_out = imageLoad(texture, ivec2(gl_FragCoord.xy)); 37} 38END 39 40SHADER compute compute_shader GLSL 41#version 430 42layout(local_size_x=32, local_size_y=4) in; 43uniform layout (set=0, binding=0, rgba8) image2D img; 44 45int w = 256; 46int h = 256; 47vec4 bg = vec4(0, 0, 0, 1); 48vec4 marked = vec4(0, 1, 1, 1); 49vec4 error = vec4(1, 0, 0, 1); 50 51shared ivec2 stack[256]; 52shared int stackPtr; 53shared bool done; 54shared ivec2 pixel; 55 56void pushMarkedPixel(ivec2 p) 57{ 58 imageStore(img, p, marked); 59 int slot = atomicAdd(stackPtr, 1); 60 stack[slot] = p; 61} 62 63ivec2 popMarkedPixel() 64{ 65 int slot = atomicAdd(stackPtr, -1) - 1; 66 ivec2 p = stack[slot]; 67 imageStore(img, p, bg); 68 69 return p; 70} 71 72void main () 73{ 74 if (gl_LocalInvocationIndex == 0) 75 { 76 stack[0] = ivec2(-1); 77 stackPtr = 0; 78 done = false; 79 80 // Use this to break the lines and verify the checker is correct. 81 //for (int x = 0; x < w; x++) 82 // imageStore(img, ivec2(x, 128), bg); 83 } 84 85 barrier(); 86 87 // Search for any pixel belonging to a line. 88 // Use 32 x 4 block for the search. 89 ivec2 p = ivec2(gl_LocalInvocationID) + ivec2(0, 128); 90 vec4 c = imageLoad(img, p); 91 // Any of the pixels found by a thread will do as a starting point. 92 if (c != bg) 93 stack[0] = p; 94 95 barrier(); 96 97 if (gl_LocalInvocationIndex == 0 && stack[0] != ivec2(-1)) 98 { 99 imageStore(img, stack[0], marked); 100 stackPtr++; 101 } 102 103 barrier(); 104 105 while (!done) 106 { 107 if (gl_LocalInvocationIndex == 0 && stackPtr != 0) 108 pixel = popMarkedPixel(); 109 110 barrier(); 111 112 if (gl_LocalInvocationID.x < 3 && gl_LocalInvocationID.y < 3) 113 { 114 ivec2 p = pixel + ivec2(gl_LocalInvocationID) - ivec2(1); 115 if (p.x >= 0 && p.y >= 0 && p.x < w && p.y < h) 116 { 117 vec4 c = imageLoad(img, p); 118 if (c != marked && c != bg) 119 { 120 pushMarkedPixel(p); 121 } 122 } 123 } 124 125 barrier(); 126 127 if (gl_LocalInvocationIndex == 0 && stackPtr < 1) 128 done = true; 129 130 barrier(); 131 } 132} 133END 134 135BUFFER position DATA_TYPE R8G8_SNORM DATA 136-120 -120 137-119 120 138 120 119 139 10 20 140 -80 20 141 -80 95 142 -83 95 143 -83 -95 144 -85 95 145END 146 147BUFFER texture FORMAT R8G8B8A8_UNORM 148BUFFER framebuffer FORMAT B8G8R8A8_UNORM 149 150PIPELINE graphics pipeline 151 ATTACH vert_shader 152 ATTACH frag_shader 153 154 VERTEX_DATA position LOCATION 0 155 156 BIND BUFFER texture AS color LOCATION 0 157 FRAMEBUFFER_SIZE 256 256 158END 159 160PIPELINE graphics tex_pipeline 161 ATTACH vert_shader 162 ATTACH frag_shader_tex 163 BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 164 FRAMEBUFFER_SIZE 256 256 165 BIND BUFFER framebuffer AS color LOCATION 0 166END 167 168PIPELINE compute verification_pipeline 169 ATTACH compute_shader 170 BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 171 FRAMEBUFFER_SIZE 256 256 172END 173 174CLEAR_COLOR pipeline 0 0 0 255 175CLEAR pipeline 176 177RUN pipeline DRAW_ARRAY AS LINE_STRIP START_IDX 0 COUNT 9 178RUN verification_pipeline 1 1 1 179RUN tex_pipeline DRAW_RECT POS 0 0 SIZE 256 256 180 181# Everything should be clear color since the checker consumes 182# the drawn pixels if they are continuous. 183EXPECT framebuffer IDX 0 0 SIZE 256 255 EQ_RGBA 0 0 0 255 184