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 //memoryBarrierImage(); 84 } 85 86 barrier(); 87 88 // Search for any pixel belonging to a line. 89 // Use 32 x 4 block for the search. 90 ivec2 p = ivec2(gl_LocalInvocationID) + ivec2(0, 128); 91 vec4 c = imageLoad(img, p); 92 // Any of the pixels found by a thread will do as a starting point. 93 if (c != bg) 94 stack[0] = p; 95 96 memoryBarrierImage(); 97 barrier(); 98 99 if (gl_LocalInvocationIndex == 0 && stack[0] != ivec2(-1)) 100 { 101 imageStore(img, stack[0], marked); 102 stackPtr++; 103 } 104 105 memoryBarrierImage(); 106 barrier(); 107 108 while (!done) 109 { 110 if (gl_LocalInvocationIndex == 0 && stackPtr != 0) 111 pixel = popMarkedPixel(); 112 113 memoryBarrierImage(); 114 barrier(); 115 116 if (gl_LocalInvocationID.x < 3 && gl_LocalInvocationID.y < 3) 117 { 118 ivec2 p = pixel + ivec2(gl_LocalInvocationID) - ivec2(1); 119 if (p.x >= 0 && p.y >= 0 && p.x < w && p.y < h) 120 { 121 vec4 c = imageLoad(img, p); 122 if (c != marked && c != bg) 123 { 124 pushMarkedPixel(p); 125 } 126 } 127 } 128 129 memoryBarrierImage(); 130 barrier(); 131 132 if (gl_LocalInvocationIndex == 0 && stackPtr < 1) 133 done = true; 134 135 barrier(); 136 } 137} 138END 139 140BUFFER position DATA_TYPE R8G8B8A8_SNORM DATA 141-120 -120 0 127 142-119 120 0 127 143 120 119 0 127 144 10 20 0 127 145 -80 20 0 127 146 -80 95 0 127 147 -83 95 0 127 148 -83 -95 0 127 149 -85 95 0 127 150END 151 152BUFFER texture FORMAT R8G8B8A8_UNORM 153BUFFER framebuffer FORMAT B8G8R8A8_UNORM 154 155PIPELINE graphics pipeline 156 ATTACH vert_shader 157 ATTACH frag_shader 158 159 VERTEX_DATA position LOCATION 0 160 161 BIND BUFFER texture AS color LOCATION 0 162 FRAMEBUFFER_SIZE 256 256 163END 164 165PIPELINE graphics tex_pipeline 166 ATTACH vert_shader 167 ATTACH frag_shader_tex 168 BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 169 FRAMEBUFFER_SIZE 256 256 170 BIND BUFFER framebuffer AS color LOCATION 0 171END 172 173PIPELINE compute verification_pipeline 174 ATTACH compute_shader 175 BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0 176 FRAMEBUFFER_SIZE 256 256 177END 178 179CLEAR_COLOR pipeline 0 0 0 255 180CLEAR pipeline 181 182RUN pipeline DRAW_ARRAY AS LINE_STRIP START_IDX 0 COUNT 9 183RUN verification_pipeline 1 1 1 184RUN tex_pipeline DRAW_RECT POS 0 0 SIZE 256 256 185 186# Everything should be clear color since the checker consumes 187# the drawn pixels if they are continuous. 188EXPECT framebuffer IDX 0 0 SIZE 256 255 EQ_RGBA 0 0 0 255 189