{"id":7,"date":"2018-04-03T19:10:42","date_gmt":"2018-04-03T17:10:42","guid":{"rendered":"http:\/\/blogs.igalia.com\/nroberts\/?p=7"},"modified":"2018-04-09T12:43:58","modified_gmt":"2018-04-09T10:43:58","slug":"vkrunner-a-shader-test-tool-for-vulkan","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/nroberts\/2018\/04\/03\/vkrunner-a-shader-test-tool-for-vulkan\/","title":{"rendered":"VkRunner &#8211; a shader test tool for Vulkan"},"content":{"rendered":"<p>As part of my work in the graphics team at Igalia, I\u2019ve been helping with the effort to enable <a href=\"https:\/\/www.khronos.org\/registry\/OpenGL\/extensions\/ARB\/ARB_gl_spirv.txt\">GL_ARB_gl_spirv<\/a> for Intel\u2019s i965 driver in Mesa. Most of the functionality of the extension is already working so in order to get more test coverage and discover unknown missing features we have been working to automatically convert some Piglit GLSL tests to use SPIR-V. Most of the GLSL tests are using a tool internal to Piglit called shader_runner. This tool largely simplifies the work needed to create a test by allowing it to be specified as a simple text file that just contains the required shaders and a list of commands to execute using them. The commands are very highlevel such as <code>draw rect<\/code> to submit a rectangle or <code>probe rgba<\/code> to check for a specific colour of a pixel in the framebuffer.<\/p>\n<p>A number of times during this work I\u2019ve encountered problems that look like they are general problems with Mesa\u2019s SPIR-V compiler and aren\u2019t specific to the GL_ARB_gl_spirv work. I wanted a way to easily confirm this but writing a minimal test case from scratch in Vulkan seemed like quite a lot of hassle. Therefore I decided it would be nice to have a tool like shader_runner that works with Vulkan. I made a start on implementing this and called it <a href=\"https:\/\/github.com\/igalia\/vkrunner\">VkRunner<\/a>.<\/p>\n<h1>Example<\/h1>\n<p>Here is an example shader test file for VkRunner:<\/p>\n<pre>\n[vertex shader]\n#version 430\n\nlayout(location = 0) in vec3 pos;\n\nvoid\nmain()\n{\n        gl_Position = vec4(pos.xy * 2.0 - 1.0, 0.0, 1.0);\n}\n\n[fragment shader]\n#version 430\n\nlayout(location = 0) out vec4 color_out;\n\nlayout(std140, push_constant) uniform block {\n        vec4 color_in;\n};\n\nvoid\nmain()\n{\n        color_out = color_in;\n}\n\n[vertex data]\n0\/r32g32b32_sfloat\n\n0.25 0.0775 0.0\n0.145 0.3875 0.0\n0.25 0.3175 0.0\n\n0.25 0.0775 0.0\n0.355 0.3875 0.0\n0.25 0.3175 0.0\n\n0.0775 0.195 0.0\n0.4225 0.195 0.0\n0.25 0.3175 0.0\n\n[test]\n# Clear the framebuffer to green\nclear color 0.0 0.6 0.0 1.0\nclear\n\n# White rectangle in the topleft corner\nuniform vec4 0 1.0 1.0 1.0 1.0\ndraw rect 0 0 0.5 0.5\n\n# Green star in the topleft\nuniform vec4 0 0.0 0.6 0.0 1.0\ndraw arrays TRIANGLE_LIST 0 9\n\n# Verify a rectangle colour\nrelative probe rect rgb (0.5, 0.0, 0.5, 1.0) (0.0, 0.6, 0.0)\n<\/pre>\n<p>If this is run through VkRunner it will convert the shaders to SPIR-V on the fly by piping them through glslangValidator, create a pipeline and a framebuffer and then run the test commands. The framebuffer is just an offscreen buffer so VkRunner doesn\u2019t use any window system extensions. However you can still see the result by passing the <code>-i image.ppm<\/code> option which cause it to write a PPM image of the final rendering.<\/p>\n<p>The format is meant to be as close to shader_runner as possible but there are a few important differences. Vulkan can\u2019t have uniforms in the default buffer and there is no way to access them by name. Instead you can use a push constant buffer and refer to the individual uniform using its byte offset in the buffer. VkRunner doesn\u2019t yet support UBOs. The same goes for vertex attributes which are now specified using an explicit location rather than by name. In the vertex data section you can use names from <a href=\"https:\/\/www.khronos.org\/registry\/vulkan\/specs\/1.0\/man\/html\/VkFormat.html\">VkFormat<\/a> to specify the format with maximum flexibility, but it can also accept Piglit-style names for compatibilty.<\/p>\n<h1>Bonus features<\/h1>\n<p>VkRunner supports some extra features that shader_runner does not. Firstly you can specify a format for the framebuffer in the optional <code>[require]<\/code> section. For example you can make it use a floating-point framebuffer to be able to accurately probe results from functions.<\/p>\n<pre>\n[require]\nframebuffer R32G32B32A32_SFLOAT\n\n[vertex shader passthrough]\n\n[fragment shader]\n#version 430\n\nlayout(location = 0) out vec4 color;\n\nvoid\nmain()\n{\n        color = vec4(atan(0.0, -1.0),\n                     42.0,\n                     length(vec2(1.0, 1.0)),\n                     fma(2.0, 3.0, 1.0));\n}\n\n[test]\nclear\ndraw rect -1 -1 2 2\nprobe all rgba 3.141592653589793 42.0 1.4142135623730951 7.0\n<\/pre>\n<p>If you want to use SPIR-V instead of GLSL in the source, you can specify the shader in a <code>[fragment shader spirv]<\/code> section. This is useful to test corner cases of the driver with tweaked shaders that glslang wouldn\u2019t generate. You can get a base for the SPIR-V source by passing the <code>-d<\/code> option to VkRunner to get the disassembly of the generated SPIR-V. There is an <a href=\"https:\/\/github.com\/Igalia\/vkrunner\/blob\/master\/examples\/spirv.shader_test\">example<\/a> of this in the repo.<\/p>\n<h1>Status<\/h1>\n<p>Although it can already be used for a range of tests, VkRunner still has a lot of missing features compared to shader_runner. It does not support textures, UBOs and SSBOs. Take a look at the <a href=\"https:\/\/github.com\/Igalia\/vkrunner\/blob\/master\/README.md\">README<\/a> for the complete documentation.<\/p>\n<p>As I have been creating tests for problems that I encounter with Mesa I\u2019ve been adding them to a branch called <a href=\"https:\/\/github.com\/Igalia\/vkrunner\/tree\/tests\/examples\">tests<\/a> in the Github repo. I get the impression that Vulkan is somewhat under-tested compared to GL so it might be interesting to use these tests as a base to make a more complete Vulkan test suite. It could also potentially be merged into Piglit.<\/p>\n<p><strong>UPDATE<\/strong>: Patches to merge VkRunner into Piglit have been <a href=\"https:\/\/patchwork.freedesktop.org\/series\/41162\/\">posted to the mailing list<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As part of my work in the graphics team at Igalia, I\u2019ve been helping with the effort to enable GL_ARB_gl_spirv for Intel\u2019s i965 driver in Mesa. Most of the functionality of the extension is already working so in order to get more test coverage and discover unknown missing features we have been working to automatically &hellip; <a href=\"https:\/\/blogs.igalia.com\/nroberts\/2018\/04\/03\/vkrunner-a-shader-test-tool-for-vulkan\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;VkRunner &#8211; a shader test tool for Vulkan&#8221;<\/span><\/a><\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/posts\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":17,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/posts\/7\/revisions"}],"predecessor-version":[{"id":28,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/posts\/7\/revisions\/28"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/media?parent=7"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/categories?post=7"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/nroberts\/wp-json\/wp\/v2\/tags?post=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}