dEQP-VK.rasterization.provoking_vertex.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_strip
dEQP-VK.rasterization.provoking_vertex.line_strip_with_adjacency
+dEQP-VK.rasterization.line_continuity.line-strip
+dEQP-VK.rasterization.line_continuity.polygon-mode-lines
dEQP-VK.clipping.clip_volume.depth_clip.point_list
dEQP-VK.clipping.clip_volume.depth_clip.line_list
dEQP-VK.clipping.clip_volume.depth_clip.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_strip
dEQP-VK.rasterization.provoking_vertex.line_strip_with_adjacency
+dEQP-VK.rasterization.line_continuity.line-strip
+dEQP-VK.rasterization.line_continuity.polygon-mode-lines
dEQP-VK.clipping.clip_volume.inside.point_list
dEQP-VK.clipping.clip_volume.inside.line_list
dEQP-VK.clipping.clip_volume.inside.line_list_with_adjacency
GitRepo(
"https://github.com/google/amber.git",
None,
- "ed3e05c945aa7a3559ef616f63a798fede19f363",
+ "93c0348c63675edd1e51e44893d58973b0d144fd",
"amber"),
]
--- /dev/null
+#!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
--- /dev/null
+#!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.
+
+DEVICE_FEATURE fillModeNonSolid
+
+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, 10);
+ 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
+ 0 120
+ 120 -120
+
+ 0 0
+120 0
+ 60 -60
+
+-100 100
+ 110 100
+ 110 103
+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
+ POLYGON_MODE line
+
+ 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 TRIANGLE_LIST 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
return ctx.getDeviceFeatures().geometryShader;
if (feature == "Features.vertexPipelineStoresAndAtomics")
return ctx.getDeviceFeatures().vertexPipelineStoresAndAtomics;
+ if (feature == "Features.fillModeNonSolid")
+ return ctx.getDeviceFeatures().fillModeNonSolid;
if (feature == "VariablePointerFeatures.variablePointersStorageBuffer")
return ctx.getVariablePointersFeatures().variablePointersStorageBuffer;
if (feature == "VariablePointerFeatures.variablePointers")
provokingVertex->addChild(testCase);
}
}
+
+ // .line_continuity
+ {
+ tcu::TestCaseGroup* const lineContinuity = new tcu::TestCaseGroup(testCtx, "line_continuity", "Test line continuity");
+ static const char dataDir[] = "rasterization/line_continuity";
+
+ struct Case
+ {
+ std::string name;
+ std::string desc;
+ bool requireFillModeNonSolid;
+ };
+
+ static const Case cases[] =
+ {
+ { "line-strip", "Test line strip drawing produces continuous lines", false },
+ { "polygon-mode-lines", "Test triangles drawn with lines are continuous", true }
+ };
+
+ rasterizationTests->addChild(lineContinuity);
+
+ for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
+ {
+ const std::string fileName = cases[i].name + ".amber";
+ cts_amber::AmberTestCase* testCase = cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].desc.c_str(), dataDir, fileName);
+
+ if (cases[i].requireFillModeNonSolid)
+ {
+ testCase->addRequirement("Features.fillModeNonSolid");
+ }
+
+ lineContinuity->addChild(testCase);
+ }
+ }
}
} // anonymous
dEQP-VK.rasterization.provoking_vertex.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_strip
dEQP-VK.rasterization.provoking_vertex.line_strip_with_adjacency
+dEQP-VK.rasterization.line_continuity.line-strip
+dEQP-VK.rasterization.line_continuity.polygon-mode-lines
dEQP-VK.clipping.clip_volume.inside.point_list
dEQP-VK.clipping.clip_volume.inside.line_list
dEQP-VK.clipping.clip_volume.inside.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.line_strip
dEQP-VK.rasterization.provoking_vertex.line_strip_with_adjacency
+dEQP-VK.rasterization.line_continuity.line-strip
+dEQP-VK.rasterization.line_continuity.polygon-mode-lines
dEQP-VK.clipping.clip_volume.inside.point_list
dEQP-VK.clipping.clip_volume.inside.line_list
dEQP-VK.clipping.clip_volume.inside.line_list_with_adjacency