SlideShare a Scribd company logo
VkRunner: a Vulkan shader test tool (FOSDEM 2019)
Overview
• Introduction
• History
• Examples
• Current status
• Future
• Questions
Introduction
What is VkRunner?
• Tool to test shaders on your Vulkan driver
• Inspired by Piglit’s shader_runner
• Minimal overhead to execute a script
• Just write the scripts and some simple commands
to execute them
• Standalone tool, runs the script and reports status
Example
[vertex shader passthrough]
[fragment shader]
#version 450
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = vec4(0.0, 1.0, 0.0, 1.0);
}
[test]
# Fill the framebuffer with the output from the shader
draw rect -1 -1 2 2
# Check that we got the colour we wanted
probe all rgba 1.0 0.0 0.0 1.0
Example
$ vkrunner ./simple-example.shader_test
Command failed at line 18
Probe color at (0,0)
Expected: 1.000000 0.000000 0.000000 1.000000
Observed: 0.000000 1.000000 0.000000 1.000000
PIGLIT: {"result": "fail" }
Behind the scenes
• Compiles the shader to SPIR-V by invoking glslang
as an external process.
• Creates pipelines for the state for each draw
command.
• Creates an offscreen framebuffer (no window
system support).
• Puts test commands into a command buffer and
executes it.
• Probes result.
History
ARB_gl_spirv
• VkRunner was created during Igalia’s work to add
support for ARB_gl_spirv to the i965 driver in Mesa.
• ARB_gl_spirv uses the same compiler as Intel’s
Vulkan driver.
• We were testing this with an adaptation of Piglit’s
shader_runner.
• shader_runner is the same principle as VkRunner.
• Tested ARB_gl_spirv by automatically converting
existing shader_runner tests to SPIR-V.
• Piglit has many many tests.
• This ended up testing more of the Intel SPIR-V
compiler than was tested with existing Vulkan tests.
• We wanted a quick way to verify whether test
failures were specific to SPIR-V on OpenGL or also
happen with Vulkan.
• shader_runner tests can be converted to VkRunner
with minimal changes.
• However there are differences because of how
Vulkan works.
• For GL, shader_runner can use the API to query
properties of the shader such as the uniform
names.
• This isn’t available in Vulkan.
• Instead we use explicit offsets to set uniforms and
SSBOs.
shader_runner example
[require]
GL >= 4.3
GLSL >= 4.30
[vertex shader passthrough]
[fragment shader]
#version 430
uniform vec4 color;
uniform float multiplier;
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
uniform vec4 color 0.5 0.25 0.5 1.0
uniform float multiplier 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
shader_runner example
[require]
GL >= 4.3
GLSL >= 4.30
[vertex shader passthrough]
[fragment shader]
#version 430
uniform vec4 color;
uniform float multiplier;
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
uniform vec4 color 0.5 0.25 0.5 1.0
uniform float multiplier 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
global named uniform
shader_runner example
[require]
GL >= 4.3
GLSL >= 4.30
[vertex shader passthrough]
[fragment shader]
#version 430
uniform vec4 color;
uniform float multiplier;
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
uniform vec4 color 0.5 0.25 0.5 1.0
uniform float multiplier 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
set uniform by name
VkRunner equivalent
[vertex shader passthrough]
[fragment shader]
#version 430
layout(push_constant) uniform block {
vec4 color;
float multiplier;
};
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
# Set color
uniform vec4 0 0.5 0.25 0.5 1.0
# Set multiplier
uniform float 16 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
VkRunner equivalent
[vertex shader passthrough]
[fragment shader]
#version 430
layout(push_constant) uniform block {
vec4 color;
float multiplier;
};
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
# Set color
uniform vec4 0 0.5 0.25 0.5 1.0
# Set multiplier
uniform float 16 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
no global uniforms
need to use something else
eg, push constants
VkRunner equivalent
[vertex shader passthrough]
[fragment shader]
#version 430
layout(push_constant) uniform block {
vec4 color;
float multiplier;
};
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = color * multiplier;
}
[test]
# Set color
uniform vec4 0 0.5 0.25 0.5 1.0
# Set multiplier
uniform float 16 0.5
draw rect -1 -1 2 2
probe all rgb 0.25 0.125 0.25
set uniform by byte offset
Some improvements
over shader_runner
• shader_runner code grown organically over time.
Lives in a single large C file.
• VkRunner code written from scratch with the
benefit of hindsight.
• Tries to partially automatically generate commands.
• Systematic method for setting pipeline
properties.
• Try to support all formats for vertex data and
framebuffer.
Examples
Vertex data
[vertex data]
# Position Colour
0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32
0.4 -0.4 0xff00a0ff
0.7 -0.7 0xff00a0ff
0.4 0.4 0xff00a0ff
0.7 0.7 0xff00a0ff
0.4 0.4 0xff0000ff
0.7 0.7 0xff0000ff
-0.4 0.4 0xff0000ff
-0.7 0.7 0xff0000ff
-0.4 0.4 0xff00ff00
-0.7 0.7 0xff00ff00
-0.4 -0.4 0xff00ff00
-0.7 -0.7 0xff00ff00
0.4 -0.4 0xffff0000
0.7 -0.7 0xffff0000
-0.4 -0.4 0xffff0000
-0.7 -0.7 0xffff0000
Vertex data
[vertex data]
# Position Colour
0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32
0.4 -0.4 0xff00a0ff
0.7 -0.7 0xff00a0ff
0.4 0.4 0xff00a0ff
0.7 0.7 0xff00a0ff
0.4 0.4 0xff0000ff
0.7 0.7 0xff0000ff
-0.4 0.4 0xff0000ff
-0.7 0.7 0xff0000ff
-0.4 0.4 0xff00ff00
-0.7 0.7 0xff00ff00
-0.4 -0.4 0xff00ff00
-0.7 -0.7 0xff00ff00
0.4 -0.4 0xffff0000
0.7 -0.7 0xffff0000
-0.4 -0.4 0xffff0000
-0.7 -0.7 0xffff0000
location
Vertex data
[vertex data]
# Position Colour
0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32
0.4 -0.4 0xff00a0ff
0.7 -0.7 0xff00a0ff
0.4 0.4 0xff00a0ff
0.7 0.7 0xff00a0ff
0.4 0.4 0xff0000ff
0.7 0.7 0xff0000ff
-0.4 0.4 0xff0000ff
-0.7 0.7 0xff0000ff
-0.4 0.4 0xff00ff00
-0.7 0.7 0xff00ff00
-0.4 -0.4 0xff00ff00
-0.7 -0.7 0xff00ff00
0.4 -0.4 0xffff0000
0.7 -0.7 0xffff0000
-0.4 -0.4 0xffff0000
-0.7 -0.7 0xffff0000
format names
from Vulkan enums
Vertex data
[vertex shader]
#version 450
layout(location = 0) in vec2 position;
layout(location = 1) in vec3 color_in;
layout(location = 0) out vec3 color_out;
void
main()
{
gl_Position = vec4(position, 0.0, 1.0);
color_out = color_in;
}
[vertex data]
specifes inputs
for these
Indices
[indices]
0 1 2 3 65535
4 5 6 7 65535
8 9 10 11 65535
12 13 14 15 65535
Draw command
primitiveRestartEnable true
draw arrays indexed TRIANGLE_STRIP 0 20
Vertex data
[vertex shader]
#version 450
layout(location = 0) in vec2 position;
layout(location = 1) in vec3 color_in;
layout(location = 0) out vec3 color_out;
void
main()
{
gl_Position = vec4(position, 0.0, 1.0);
color_out = color_in;
}
[fragment shader]
#version 450
layout(location = 0) in vec3 color_in;
layout(location = 0) out vec4 color_out;
void
main()
{
color_out = vec4(color_in, 1.0);
}
[vertex data]
# Position Colour
0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32
0.4 -0.4 0xff00a0ff
0.7 -0.7 0xff00a0ff
0.4 0.4 0xff00a0ff
0.7 0.7 0xff00a0ff
0.4 0.4 0xff0000ff
0.7 0.7 0xff0000ff
-0.4 0.4 0xff0000ff
-0.7 0.7 0xff0000ff
-0.4 0.4 0xff00ff00
-0.7 0.7 0xff00ff00
-0.4 -0.4 0xff00ff00
-0.7 -0.7 0xff00ff00
0.4 -0.4 0xffff0000
0.7 -0.7 0xffff0000
-0.4 -0.4 0xffff0000
-0.7 -0.7 0xffff0000
[indices]
0 1 2 3 65535
4 5 6 7 65535
8 9 10 11 65535
12 13 14 15 65535
[test]
clear
primitiveRestartEnable true
draw arrays indexed TRIANGLE_STRIP 0 20
Requires section
[require]
# Require an extension for the test to pass
VK_KHR_8bit_storage
# Change the framebuffer format
framebuffer R32_SFLOAT
fbsize 1024 768
# Require an optional Vulkan feature
shaderInt16
Compute shader
[compute shader]
#version 450
layout(binding = 0) buffer block {
float values[];
};
void
main()
{
// Calculate some square roots
values[gl_WorkGroupID.x] = sqrt(gl_WorkGroupID.x);
}
[test]
ssbo 0 4096
# Run the compute shader
compute 1024 1 1
# Probe a few points in the buffer
probe ssbo float 0 0 ~= 0 1.0 1.4142 1.7320 2.0
probe ssbo float 0 2304 ~= 24.0
SPIR-V source
[fragment shader spirv]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %color
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpDecorate %color Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Output_float = OpTypePointer Output %float
%color = OpVariable %_ptr_Output_float Output
%float_1 = OpConstant %float 1
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %color %float_1
OpReturn
OpFunctionEnd
Binary source
• Script available to precompile scripts to binary
format
./precompile-script.py -o precompiled *.shader_test
vkrunner precompiled/*.shader_test
• Useful for running on devices where running the
compiler isn’t practical.
Binary source
[require]
framebuffer R32_SFLOAT
[vertex shader passthrough]
[fragment shader binary]
7230203 10000 70000 a 0 20011 1 6000b 1 4c534c47 6474732e
3035342e 0 3000e 0 1 6000f 4 2 6e69616d 0 3 30010 2 7 30003
2 1c2 40047 3 1e 0 20013 4 30021 5 4 30016 6 20 40020 7 3 6
4003b 7 3 3 4002b 6 8 3f800000 50036 4 2 0 5 200f8 9 3003e 3
8 100fd 10038
[test]
clear
draw rect -1 -1 2 2
probe all rgb 1 0 0
Current status
Features
• All shader stages
• UBOs/SSBOs
• Vertex data, simple drawing
• Probing the framebuffer or SSBOs
Library version
#include <stdio.h>
#include <vkrunner/vkrunner.h>
int
main(int argc, char **argv)
{
struct vr_source *source =
vr_source_from_file("simple-example.shader_test");
struct vr_config *config = vr_config_new();
struct vr_executor *executor = vr_executor_new(config);
enum vr_result result = vr_executor_execute(executor, source);
vr_executor_free(executor);
vr_config_free(config);
vr_source_free(source);
return result == VR_RESULT_FAIL ? EXIT_FAILURE : EXIT_SUCCESS;
}
Integration
• Integrated into Khronos Vulkan CTS
• Currently only experimental tests
• Uses VkRunner’s API
• Integrated into Piglit
• Has real tests
• Runs on Intel’s CI
Future
Missing features
• Image / texture support
• Although there is a pull request for this
• Arrays of buffer bindings
• Probably a lot of other things
User Interface
Video?
• There’s a branch for making animations.
• Adds a magic uniform to specify the frame number.
• Can be used like an offline version of shadertoy
Amber
• Google are working on a similar tool.
• Can use the same scripting format as VkRunner.
• Yet to see which where it will lead.
github.com/Igalia/
vkrunner
Questions?

More Related Content

PDF
Pratt Parser in Python
PDF
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
PDF
What's New in ES6 for Web Devs
PDF
Appsec obfuscator reloaded
TXT
Exploit techniques - a quick review
PDF
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
TXT
Mona cheatsheet
PPTX
Elements of C++11
Pratt Parser in Python
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
What's New in ES6 for Web Devs
Appsec obfuscator reloaded
Exploit techniques - a quick review
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Mona cheatsheet
Elements of C++11

What's hot (20)

PDF
Коварный code type ITGM #9
PDF
The Ring programming language version 1.9 book - Part 101 of 210
PDF
RESTful API using scalaz (3)
KEY
Tork03 LT
PDF
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
PDF
ES6 in Production [JSConfUY2015]
PDF
Working with Cocoa and Objective-C
PDF
PHP Internals and Virtual Machine
PPTX
The operation principles of PVS-Studio static code analyzer
PDF
Big Data Day LA 2015 - Mongoose v/s Waterline: Battle of the ORM by Tim Fulme...
PDF
Hacking parse.y (RubyConf 2009)
PDF
Ethereum virtual machine for Developers Part 1
PDF
Modern Objective-C @ Pragma Night
PDF
Aspect Mining for Large Systems
DOCX
Oops pramming with examples
PDF
Rust LDN 24 7 19 Oxidising the Command Line
PDF
Explaining ES6: JavaScript History and What is to Come
PDF
Functional Algebra: Monoids Applied
PDF
Cilk Plus Parallel Reduction
PDF
What's new in PHP 8.0?
Коварный code type ITGM #9
The Ring programming language version 1.9 book - Part 101 of 210
RESTful API using scalaz (3)
Tork03 LT
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
ES6 in Production [JSConfUY2015]
Working with Cocoa and Objective-C
PHP Internals and Virtual Machine
The operation principles of PVS-Studio static code analyzer
Big Data Day LA 2015 - Mongoose v/s Waterline: Battle of the ORM by Tim Fulme...
Hacking parse.y (RubyConf 2009)
Ethereum virtual machine for Developers Part 1
Modern Objective-C @ Pragma Night
Aspect Mining for Large Systems
Oops pramming with examples
Rust LDN 24 7 19 Oxidising the Command Line
Explaining ES6: JavaScript History and What is to Come
Functional Algebra: Monoids Applied
Cilk Plus Parallel Reduction
What's new in PHP 8.0?
Ad

Similar to VkRunner: a Vulkan shader test tool (FOSDEM 2019) (20)

PDF
VkRunner: a simple Vulkan shader script test utility [Lightning Talk] (Lightn...
PDF
GLSL: Releasing the power of the GPU
PDF
Hpg2011 papers kazakov
PDF
OpenGL SC 2.0 Quick Reference
PPT
Hardware Shaders
PPTX
Getting started with open gl es 2
PDF
Dissecting and fixing Vulkan rendering issues in drivers with RenderDoc
PPT
Programmable Piplelines
PPT
CS 354 Programmable Shading
PDF
Rsltollvm
PPTX
Cg shaders with Unity3D
PDF
Inspecting Block Closures To Generate Shaders for GPU Execution
PPTX
GFX Part 6 - Introduction to Vertex and Fragment Shaders in OpenGL ES
PDF
iOS Visual F/X Using GLSL
PDF
GL Shading Language Document by OpenGL.pdf
PDF
Open gl
PDF
OpenGL ES 3.1 Reference Card
PPT
CS 354 Pixel Updating
VkRunner: a simple Vulkan shader script test utility [Lightning Talk] (Lightn...
GLSL: Releasing the power of the GPU
Hpg2011 papers kazakov
OpenGL SC 2.0 Quick Reference
Hardware Shaders
Getting started with open gl es 2
Dissecting and fixing Vulkan rendering issues in drivers with RenderDoc
Programmable Piplelines
CS 354 Programmable Shading
Rsltollvm
Cg shaders with Unity3D
Inspecting Block Closures To Generate Shaders for GPU Execution
GFX Part 6 - Introduction to Vertex and Fragment Shaders in OpenGL ES
iOS Visual F/X Using GLSL
GL Shading Language Document by OpenGL.pdf
Open gl
OpenGL ES 3.1 Reference Card
CS 354 Pixel Updating
Ad

More from Igalia (20)

PDF
Life of a Kernel Bug Fix
PDF
Unlocking the Full Potential of WPE to Build a Successful Embedded Product
PDF
Advancing WebDriver BiDi support in WebKit
PDF
Jumping Over the Garden Wall - WPE WebKit on Android
PDF
Collective Funding, Governance and Prioritiation of Browser Engine Projects
PDF
Don't let your motivation go, save time with kworkflow
PDF
Solving the world’s (localization) problems
PDF
The Whippet Embeddable Garbage Collection Library
PDF
Nobody asks "How is JavaScript?"
PDF
Getting more juice out from your Raspberry Pi GPU
PDF
WebRTC support in WebKitGTK and WPEWebKit with GStreamer: Status update
PDF
Demystifying Temporal: A Deep Dive into JavaScript New Temporal API
PDF
CSS :has() Unlimited Power
PDF
Device-Generated Commands in Vulkan
PDF
Current state of Lavapipe: Mesa's software renderer for Vulkan
PDF
Vulkan Video is Open: Application showcase
PDF
Scheme on WebAssembly: It is happening!
PDF
EBC - A new backend compiler for etnaviv
PDF
RISC-V LLVM State of the Union
PDF
Device-Generated Commands in Vulkan
Life of a Kernel Bug Fix
Unlocking the Full Potential of WPE to Build a Successful Embedded Product
Advancing WebDriver BiDi support in WebKit
Jumping Over the Garden Wall - WPE WebKit on Android
Collective Funding, Governance and Prioritiation of Browser Engine Projects
Don't let your motivation go, save time with kworkflow
Solving the world’s (localization) problems
The Whippet Embeddable Garbage Collection Library
Nobody asks "How is JavaScript?"
Getting more juice out from your Raspberry Pi GPU
WebRTC support in WebKitGTK and WPEWebKit with GStreamer: Status update
Demystifying Temporal: A Deep Dive into JavaScript New Temporal API
CSS :has() Unlimited Power
Device-Generated Commands in Vulkan
Current state of Lavapipe: Mesa's software renderer for Vulkan
Vulkan Video is Open: Application showcase
Scheme on WebAssembly: It is happening!
EBC - A new backend compiler for etnaviv
RISC-V LLVM State of the Union
Device-Generated Commands in Vulkan

Recently uploaded (20)

PDF
Electronic commerce courselecture one. Pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Big Data Technologies - Introduction.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Modernizing your data center with Dell and AMD
PPT
Teaching material agriculture food technology
Electronic commerce courselecture one. Pdf
NewMind AI Weekly Chronicles - August'25 Week I
NewMind AI Monthly Chronicles - July 2025
20250228 LYD VKU AI Blended-Learning.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Dropbox Q2 2025 Financial Results & Investor Presentation
Big Data Technologies - Introduction.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
The AUB Centre for AI in Media Proposal.docx
The Rise and Fall of 3GPP – Time for a Sabbatical?
Spectral efficient network and resource selection model in 5G networks
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation_ Review paper, used for researhc scholars
Agricultural_Statistics_at_a_Glance_2022_0.pdf
A Presentation on Artificial Intelligence
Diabetes mellitus diagnosis method based random forest with bat algorithm
Modernizing your data center with Dell and AMD
Teaching material agriculture food technology

VkRunner: a Vulkan shader test tool (FOSDEM 2019)

  • 2. Overview • Introduction • History • Examples • Current status • Future • Questions
  • 4. What is VkRunner? • Tool to test shaders on your Vulkan driver • Inspired by Piglit’s shader_runner • Minimal overhead to execute a script • Just write the scripts and some simple commands to execute them • Standalone tool, runs the script and reports status
  • 5. Example [vertex shader passthrough] [fragment shader] #version 450 layout(location = 0) out vec4 color_out; void main() { color_out = vec4(0.0, 1.0, 0.0, 1.0); } [test] # Fill the framebuffer with the output from the shader draw rect -1 -1 2 2 # Check that we got the colour we wanted probe all rgba 1.0 0.0 0.0 1.0
  • 6. Example $ vkrunner ./simple-example.shader_test Command failed at line 18 Probe color at (0,0) Expected: 1.000000 0.000000 0.000000 1.000000 Observed: 0.000000 1.000000 0.000000 1.000000 PIGLIT: {"result": "fail" }
  • 7. Behind the scenes • Compiles the shader to SPIR-V by invoking glslang as an external process. • Creates pipelines for the state for each draw command. • Creates an offscreen framebuffer (no window system support). • Puts test commands into a command buffer and executes it. • Probes result.
  • 9. ARB_gl_spirv • VkRunner was created during Igalia’s work to add support for ARB_gl_spirv to the i965 driver in Mesa. • ARB_gl_spirv uses the same compiler as Intel’s Vulkan driver. • We were testing this with an adaptation of Piglit’s shader_runner.
  • 10. • shader_runner is the same principle as VkRunner. • Tested ARB_gl_spirv by automatically converting existing shader_runner tests to SPIR-V. • Piglit has many many tests. • This ended up testing more of the Intel SPIR-V compiler than was tested with existing Vulkan tests. • We wanted a quick way to verify whether test failures were specific to SPIR-V on OpenGL or also happen with Vulkan.
  • 11. • shader_runner tests can be converted to VkRunner with minimal changes. • However there are differences because of how Vulkan works. • For GL, shader_runner can use the API to query properties of the shader such as the uniform names. • This isn’t available in Vulkan. • Instead we use explicit offsets to set uniforms and SSBOs.
  • 12. shader_runner example [require] GL >= 4.3 GLSL >= 4.30 [vertex shader passthrough] [fragment shader] #version 430 uniform vec4 color; uniform float multiplier; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] uniform vec4 color 0.5 0.25 0.5 1.0 uniform float multiplier 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25
  • 13. shader_runner example [require] GL >= 4.3 GLSL >= 4.30 [vertex shader passthrough] [fragment shader] #version 430 uniform vec4 color; uniform float multiplier; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] uniform vec4 color 0.5 0.25 0.5 1.0 uniform float multiplier 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25 global named uniform
  • 14. shader_runner example [require] GL >= 4.3 GLSL >= 4.30 [vertex shader passthrough] [fragment shader] #version 430 uniform vec4 color; uniform float multiplier; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] uniform vec4 color 0.5 0.25 0.5 1.0 uniform float multiplier 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25 set uniform by name
  • 15. VkRunner equivalent [vertex shader passthrough] [fragment shader] #version 430 layout(push_constant) uniform block { vec4 color; float multiplier; }; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] # Set color uniform vec4 0 0.5 0.25 0.5 1.0 # Set multiplier uniform float 16 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25
  • 16. VkRunner equivalent [vertex shader passthrough] [fragment shader] #version 430 layout(push_constant) uniform block { vec4 color; float multiplier; }; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] # Set color uniform vec4 0 0.5 0.25 0.5 1.0 # Set multiplier uniform float 16 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25 no global uniforms need to use something else eg, push constants
  • 17. VkRunner equivalent [vertex shader passthrough] [fragment shader] #version 430 layout(push_constant) uniform block { vec4 color; float multiplier; }; layout(location = 0) out vec4 color_out; void main() { color_out = color * multiplier; } [test] # Set color uniform vec4 0 0.5 0.25 0.5 1.0 # Set multiplier uniform float 16 0.5 draw rect -1 -1 2 2 probe all rgb 0.25 0.125 0.25 set uniform by byte offset
  • 18. Some improvements over shader_runner • shader_runner code grown organically over time. Lives in a single large C file. • VkRunner code written from scratch with the benefit of hindsight. • Tries to partially automatically generate commands. • Systematic method for setting pipeline properties. • Try to support all formats for vertex data and framebuffer.
  • 20. Vertex data [vertex data] # Position Colour 0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32 0.4 -0.4 0xff00a0ff 0.7 -0.7 0xff00a0ff 0.4 0.4 0xff00a0ff 0.7 0.7 0xff00a0ff 0.4 0.4 0xff0000ff 0.7 0.7 0xff0000ff -0.4 0.4 0xff0000ff -0.7 0.7 0xff0000ff -0.4 0.4 0xff00ff00 -0.7 0.7 0xff00ff00 -0.4 -0.4 0xff00ff00 -0.7 -0.7 0xff00ff00 0.4 -0.4 0xffff0000 0.7 -0.7 0xffff0000 -0.4 -0.4 0xffff0000 -0.7 -0.7 0xffff0000
  • 21. Vertex data [vertex data] # Position Colour 0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32 0.4 -0.4 0xff00a0ff 0.7 -0.7 0xff00a0ff 0.4 0.4 0xff00a0ff 0.7 0.7 0xff00a0ff 0.4 0.4 0xff0000ff 0.7 0.7 0xff0000ff -0.4 0.4 0xff0000ff -0.7 0.7 0xff0000ff -0.4 0.4 0xff00ff00 -0.7 0.7 0xff00ff00 -0.4 -0.4 0xff00ff00 -0.7 -0.7 0xff00ff00 0.4 -0.4 0xffff0000 0.7 -0.7 0xffff0000 -0.4 -0.4 0xffff0000 -0.7 -0.7 0xffff0000 location
  • 22. Vertex data [vertex data] # Position Colour 0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32 0.4 -0.4 0xff00a0ff 0.7 -0.7 0xff00a0ff 0.4 0.4 0xff00a0ff 0.7 0.7 0xff00a0ff 0.4 0.4 0xff0000ff 0.7 0.7 0xff0000ff -0.4 0.4 0xff0000ff -0.7 0.7 0xff0000ff -0.4 0.4 0xff00ff00 -0.7 0.7 0xff00ff00 -0.4 -0.4 0xff00ff00 -0.7 -0.7 0xff00ff00 0.4 -0.4 0xffff0000 0.7 -0.7 0xffff0000 -0.4 -0.4 0xffff0000 -0.7 -0.7 0xffff0000 format names from Vulkan enums
  • 23. Vertex data [vertex shader] #version 450 layout(location = 0) in vec2 position; layout(location = 1) in vec3 color_in; layout(location = 0) out vec3 color_out; void main() { gl_Position = vec4(position, 0.0, 1.0); color_out = color_in; } [vertex data] specifes inputs for these
  • 24. Indices [indices] 0 1 2 3 65535 4 5 6 7 65535 8 9 10 11 65535 12 13 14 15 65535
  • 25. Draw command primitiveRestartEnable true draw arrays indexed TRIANGLE_STRIP 0 20
  • 26. Vertex data [vertex shader] #version 450 layout(location = 0) in vec2 position; layout(location = 1) in vec3 color_in; layout(location = 0) out vec3 color_out; void main() { gl_Position = vec4(position, 0.0, 1.0); color_out = color_in; } [fragment shader] #version 450 layout(location = 0) in vec3 color_in; layout(location = 0) out vec4 color_out; void main() { color_out = vec4(color_in, 1.0); } [vertex data] # Position Colour 0/R32G32_SFLOAT 1/A8B8G8R8_UNORM_PACK32 0.4 -0.4 0xff00a0ff 0.7 -0.7 0xff00a0ff 0.4 0.4 0xff00a0ff 0.7 0.7 0xff00a0ff 0.4 0.4 0xff0000ff 0.7 0.7 0xff0000ff -0.4 0.4 0xff0000ff -0.7 0.7 0xff0000ff -0.4 0.4 0xff00ff00 -0.7 0.7 0xff00ff00 -0.4 -0.4 0xff00ff00 -0.7 -0.7 0xff00ff00 0.4 -0.4 0xffff0000 0.7 -0.7 0xffff0000 -0.4 -0.4 0xffff0000 -0.7 -0.7 0xffff0000 [indices] 0 1 2 3 65535 4 5 6 7 65535 8 9 10 11 65535 12 13 14 15 65535 [test] clear primitiveRestartEnable true draw arrays indexed TRIANGLE_STRIP 0 20
  • 27. Requires section [require] # Require an extension for the test to pass VK_KHR_8bit_storage # Change the framebuffer format framebuffer R32_SFLOAT fbsize 1024 768 # Require an optional Vulkan feature shaderInt16
  • 28. Compute shader [compute shader] #version 450 layout(binding = 0) buffer block { float values[]; }; void main() { // Calculate some square roots values[gl_WorkGroupID.x] = sqrt(gl_WorkGroupID.x); } [test] ssbo 0 4096 # Run the compute shader compute 1024 1 1 # Probe a few points in the buffer probe ssbo float 0 0 ~= 0 1.0 1.4142 1.7320 2.0 probe ssbo float 0 2304 ~= 24.0
  • 29. SPIR-V source [fragment shader spirv] OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %color OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpDecorate %color Location 0 %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 %_ptr_Output_float = OpTypePointer Output %float %color = OpVariable %_ptr_Output_float Output %float_1 = OpConstant %float 1 %main = OpFunction %void None %3 %5 = OpLabel OpStore %color %float_1 OpReturn OpFunctionEnd
  • 30. Binary source • Script available to precompile scripts to binary format ./precompile-script.py -o precompiled *.shader_test vkrunner precompiled/*.shader_test • Useful for running on devices where running the compiler isn’t practical.
  • 31. Binary source [require] framebuffer R32_SFLOAT [vertex shader passthrough] [fragment shader binary] 7230203 10000 70000 a 0 20011 1 6000b 1 4c534c47 6474732e 3035342e 0 3000e 0 1 6000f 4 2 6e69616d 0 3 30010 2 7 30003 2 1c2 40047 3 1e 0 20013 4 30021 5 4 30016 6 20 40020 7 3 6 4003b 7 3 3 4002b 6 8 3f800000 50036 4 2 0 5 200f8 9 3003e 3 8 100fd 10038 [test] clear draw rect -1 -1 2 2 probe all rgb 1 0 0
  • 33. Features • All shader stages • UBOs/SSBOs • Vertex data, simple drawing • Probing the framebuffer or SSBOs
  • 34. Library version #include <stdio.h> #include <vkrunner/vkrunner.h> int main(int argc, char **argv) { struct vr_source *source = vr_source_from_file("simple-example.shader_test"); struct vr_config *config = vr_config_new(); struct vr_executor *executor = vr_executor_new(config); enum vr_result result = vr_executor_execute(executor, source); vr_executor_free(executor); vr_config_free(config); vr_source_free(source); return result == VR_RESULT_FAIL ? EXIT_FAILURE : EXIT_SUCCESS; }
  • 35. Integration • Integrated into Khronos Vulkan CTS • Currently only experimental tests • Uses VkRunner’s API • Integrated into Piglit • Has real tests • Runs on Intel’s CI
  • 37. Missing features • Image / texture support • Although there is a pull request for this • Arrays of buffer bindings • Probably a lot of other things
  • 39. Video? • There’s a branch for making animations. • Adds a magic uniform to specify the frame number. • Can be used like an offline version of shadertoy
  • 40. Amber • Google are working on a similar tool. • Can use the same scripting format as VkRunner. • Yet to see which where it will lead.