From e9220199cfde025795d7e48bf85292341771f07e Mon Sep 17 00:00:00 2001 From: Ari Suonpaa Date: Fri, 6 Mar 2020 10:19:59 +0200 Subject: [PATCH] Added tests for line continuity The current tests verify line rasterization results quite loosely because of differences in implementations. However a line with missing pixels were still passing the tests. This adds separate tests that catch such rasterization errors. Amber has been updated to add polygon mode support. New tests: dEQP-VK.rasterization.line_continuity.line-strip dEQP-VK.rasterization.line_continuity.polygon-mode-lines VK-GL-CTS issue: 2024 Components: Vulkan Change-Id: Ibad1deb85f3a5bbc169723f0d8c00c3192447917 --- android/cts/master/vk-master-2020-03-01.txt | 2 + android/cts/master/vk-master.txt | 2 + external/fetch_sources.py | 2 +- .../rasterization/line_continuity/line-strip.amber | 182 ++++++++++++++++++++ .../line_continuity/polygon-mode-lines.amber | 187 +++++++++++++++++++++ .../modules/vulkan/amber/vktAmberTestCase.cpp | 2 + .../vulkan/rasterization/vktRasterizationTests.cpp | 34 ++++ .../mustpass/master/vk-default-no-waivers.txt | 2 + external/vulkancts/mustpass/master/vk-default.txt | 2 + 9 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 external/vulkancts/data/vulkan/amber/rasterization/line_continuity/line-strip.amber create mode 100644 external/vulkancts/data/vulkan/amber/rasterization/line_continuity/polygon-mode-lines.amber diff --git a/android/cts/master/vk-master-2020-03-01.txt b/android/cts/master/vk-master-2020-03-01.txt index c3bf2f8..5202f0f 100644 --- a/android/cts/master/vk-master-2020-03-01.txt +++ b/android/cts/master/vk-master-2020-03-01.txt @@ -157404,6 +157404,8 @@ dEQP-VK.rasterization.provoking_vertex.line_list 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 diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index fd789ab..2dfb8b5 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -507733,6 +507733,8 @@ dEQP-VK.rasterization.provoking_vertex.line_list 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 diff --git a/external/fetch_sources.py b/external/fetch_sources.py index c830835..f412f7e 100644 --- a/external/fetch_sources.py +++ b/external/fetch_sources.py @@ -332,7 +332,7 @@ PACKAGES = [ GitRepo( "https://github.com/google/amber.git", None, - "ed3e05c945aa7a3559ef616f63a798fede19f363", + "93c0348c63675edd1e51e44893d58973b0d144fd", "amber"), ] diff --git a/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/line-strip.amber b/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/line-strip.amber new file mode 100644 index 0000000..dc88e12 --- /dev/null +++ b/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/line-strip.amber @@ -0,0 +1,182 @@ +#!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 diff --git a/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/polygon-mode-lines.amber b/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/polygon-mode-lines.amber new file mode 100644 index 0000000..4bae586 --- /dev/null +++ b/external/vulkancts/data/vulkan/amber/rasterization/line_continuity/polygon-mode-lines.amber @@ -0,0 +1,187 @@ +#!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 diff --git a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp index 12793b2..299752b 100644 --- a/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp +++ b/external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp @@ -88,6 +88,8 @@ static bool isFeatureSupported(const vkt::Context& ctx, const std::string& featu 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") diff --git a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp index 173dc2b..bb252c5 100644 --- a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp +++ b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp @@ -4437,6 +4437,40 @@ void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests) 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 diff --git a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt index 86d160d..0b7cfb7 100644 --- a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt +++ b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt @@ -509693,6 +509693,8 @@ dEQP-VK.rasterization.provoking_vertex.line_list 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 diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt index 201c0e6..a0590f1 100644 --- a/external/vulkancts/mustpass/master/vk-default.txt +++ b/external/vulkancts/mustpass/master/vk-default.txt @@ -509654,6 +509654,8 @@ dEQP-VK.rasterization.provoking_vertex.line_list 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 -- 2.7.4