Skip to content

Commit edd5e72

Browse files
authored
Add sample demonstrating VK_KHR_shader_relaxed_extended_instruction (#1420)
* Add sample demonstrating VK_KHR_shader_relaxed_extended_instruction usage * fix copyright and clang-format * - Update README with GitHub repository link for sample * Convert shader_relaxed_extended_instruction sample from GLSL to Slang and update copyrights to 2026 * Convert shader_relaxed_extended_instruction sample from GLSL to Slang with debug info to trigger OpExtInstWithForwardRef * Update copyrights to 2026 * Convert shader_relaxed_extended_instruction sample from Slang to HLSL/DXC with UI-driven dispatch and message capture Replaces Slang shader with HLSL variant using DXC that reliably emits OpExtInstWithForwardRef patterns. Adds interactive UI with value slider and manual dispatch button, captures debugPrintf messages via debug utils callback, and eliminates per-frame dispatch to avoid console spam. Updates to Vulkan 1.3 target and pre-records UI render pass commands. * Fix extension check to query device extensions instead of instance extensions The VK_KHR_shader_relaxed_extended_instruction and VK_KHR_shader_non_semantic_info are device extensions, not instance extensions. Update the check to use `get_device().is_extension_enabled()` instead of `get_instance().is_enabled()`. * remove frustration comment :) * Improve debug printf setup and handle missing validation layer gracefully Switch to boolean `printf_enable` layer setting (removing string-based `enables`), fix indentation, and make validation layer optional in fallback path by checking availability before adding to enabled layers list. * Fix indentation from spaces to tabs in shader_relaxed_extended_instruction sample Loading * Refactor debugPrintf setup to use framework hooks with manual fallback demonstration Replaces manual instance creation with framework request hooks (`request_layer_settings`, `request_layers`, etc.) for modern VK_EXT_layer_settings path. Retains explicit VK_EXT_validation_features fallback in `create_instance()` override for educational purposes when layer settings unavailable. Adds missing `<algorithm>` and `<cstring>` includes, returns VK_API_VERSION_1_3 from `get_api_version()`, and improves logging clarity. * fix clang-format.
1 parent ac30450 commit edd5e72

9 files changed

Lines changed: 646 additions & 1 deletion

File tree

antora/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
** xref:samples/extensions/ray_tracing_position_fetch/README.adoc[Ray tracing position fetch]
9393
** xref:samples/extensions/shader_object/README.adoc[Shader Object]
9494
** xref:samples/extensions/shader_debugprintf/README.adoc[Shader Debug Printf]
95+
** xref:samples/extensions/shader_relaxed_extended_instruction/README.adoc[Shader relaxed extended instruction]
9596
** xref:samples/extensions/sparse_image/README.adoc[Sparse Image]
9697
** xref:samples/extensions/synchronization_2/README.adoc[Synchronization 2]
9798
** xref:samples/extensions/tensor_and_data_graph/README.adoc[Tensor and Data Graph]

bldsys/cmake/sample_helper.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ endif()
272272
set(SLANG_ENTRY_POINT "main")
273273
add_custom_command(
274274
OUTPUT ${OUTPUT_FILE}
275-
COMMAND ${Vulkan_slang_EXECUTABLE} ${SHADER_FILE_SLANG} -profile ${SLANG_PROFILE} -matrix-layout-column-major -target spirv -o ${OUTPUT_FILE} -entry ${SLANG_ENTRY_POINT}
275+
COMMAND ${Vulkan_slang_EXECUTABLE} ${SHADER_FILE_SLANG} -profile ${SLANG_PROFILE} -matrix-layout-column-major -target spirv -o ${OUTPUT_FILE} -entry ${SLANG_ENTRY_POINT} ${TARGET_SLANGC_ADDITIONAL_ARGUMENTS}
276276
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_FILE} ${directory}
277277
MAIN_DEPENDENCY ${SHADER_FILE_SLANG}
278278
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}

samples/extensions/README.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ Demonstrate how to use vertex input bindings and attribute descriptions dynamica
232232

233233
Demonstrate how to use depth bias, primitive restart, rasterizer discard and patch control points dynamically, which can reduce the number of pipeline objects that are needed to be created.
234234

235+
=== xref:./{extension_samplespath}shader_relaxed_extended_instruction/README.adoc[Shader Relaxed Extended Instruction]
236+
237+
*Extension*: https://docs.vulkan.org/spec/latest/appendices/extensions.html#VK_KHR_shader_relaxed_extended_instruction[`VK_KHR_shader_relaxed_extended_instruction`]
238+
239+
Demonstrate how to use VK_KHR_shader_relaxed_extended_instruction for usage of forward references on non-semantic instruction when required.
240+
235241
=== xref:./{extension_samplespath}logic_op_dynamic_state/README.adoc[Logic operations dynamic state]
236242

237243
*Extension*: https://registry.khronos.org/vulkan/specs/latest/man/html/VK_EXT_extended_dynamic_state2.html[`VK_EXT_extended_dynamic_state2`]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright (c) 2026, Holochip Inc
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
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+
# http://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+
#
17+
18+
get_filename_component(FOLDER_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
19+
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_LIST_DIR} PATH)
20+
get_filename_component(CATEGORY_NAME ${PARENT_DIR} NAME)
21+
22+
add_sample_with_tags(
23+
ID ${FOLDER_NAME}
24+
CATEGORY ${CATEGORY_NAME}
25+
AUTHOR "Holochip"
26+
NAME "Shader relaxed extended instruction"
27+
DESCRIPTION "Demonstrates enabling VK_KHR_shader_relaxed_extended_instruction and requesting its feature"
28+
SHADER_FILES_HLSL
29+
"shader_relaxed_extended_instruction/hlsl/relaxed_demo.comp.hlsl"
30+
DXC_ADDITIONAL_ARGUMENTS "-fspv-target-env=vulkan1.3 -fspv-debug=vulkan-with-source -O3"
31+
)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
////
2+
- Copyright (c) 2026, Holochip Inc.
3+
-
4+
- SPDX-License-Identifier: Apache-2.0
5+
-
6+
- Licensed under the Apache License, Version 2.0 the "License";
7+
- you may not use this file except in compliance with the License.
8+
- You may obtain a copy of the License at
9+
-
10+
- http://www.apache.org/licenses/LICENSE-2.0
11+
-
12+
- Unless required by applicable law or agreed to in writing, software
13+
- distributed under the License is distributed on an "AS IS" BASIS,
14+
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
- See the License for the specific language governing permissions and
16+
- limitations under the License.
17+
-
18+
////
19+
20+
ifdef::site-gen-antora[]
21+
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/extensions/shader_relaxed_extended[Khronos Vulkan samples github repository].
22+
endif::[]
23+
24+
= VK_KHR_shader_relaxed_extended_instruction — Enable SPIR-V relaxed extended instruction for non-semantic sets
25+
26+
This sample demonstrates the device feature VK_KHR_shader_relaxed_extended_instruction and how it relates to SPV_KHR_relaxed_extended_instruction in SPIR-V. The SPIR-V extension introduces a new instruction that allows certain forward references in extended instruction sets used by non-semantic information (for example, the NonSemantic.DebugPrintf instruction set used by GL_EXT_debug_printf). In Vulkan, those non-semantic instruction sets are allowed via VK_KHR_shader_non_semantic_info.
27+
28+
== What is it?
29+
- SPV_KHR_relaxed_extended_instruction adds a SPIR-V mechanism to relax forward‑reference rules for extended instruction sets, specifically for non‑semantic information.
30+
- VK_KHR_shader_relaxed_extended_instruction is the Vulkan device extension/feature that allows modules using that SPIR‑V extension to be consumed by the driver.
31+
- This interacts with SPV_KHR_non_semantic_info and VK_KHR_shader_non_semantic_info: the relaxed forward‑reference rule applies to non‑semantic extended instruction sets like `NonSemantic.DebugPrintf`.
32+
33+
The feature is exposed via `VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR` with a single boolean field `shaderRelaxedExtendedInstruction`.
34+
35+
== Why/when to use it
36+
- When compiling shaders that embed non‑semantic extended instruction sets (e.g., debug info or debugPrintf) that may use forward references that were previously disallowed.
37+
- When you want tool and debugging SPIR‑V to be accepted by implementations that support this relaxation, without affecting the program’s semantics (non‑semantic content does not change the observable results).
38+
- Shaders should continue to function when the feature is off; the relaxation only affects acceptance of certain SPIR‑V forms, not execution semantics.
39+
40+
== What this sample does
41+
- Enables device extensions: `VK_KHR_shader_relaxed_extended_instruction` and `VK_KHR_shader_non_semantic_info`.
42+
- Requests the feature via the framework’s feature‑chaining helper.
43+
- Builds a tiny compute pipeline whose shader calls `debugPrintfEXT` (a non‑semantic extended instruction) using a class method to demonstrate the relaxed forward‑reference pattern.
44+
- Renders a visible UI and background and only dispatches the compute shader on demand (or when a UI value changes). This avoids per‑frame logging spam while still demonstrating consumption of a module that contains non‑semantic extended instructions.
45+
46+
== How to use it
47+
- The sample shows a small UI panel with:
48+
* A `Value` slider (integer). Changing it triggers a one‑shot compute dispatch that prints the new value from the shader.
49+
* A `Dispatch once` button to manually run a one‑shot dispatch.
50+
* “Last messages” — the last 5 lines captured from `debugPrintf` via `VK_EXT_debug_utils`.
51+
- The shader prints only from thread `(0,0,0)` and only when you request a dispatch, so there is no per‑frame console spam.
52+
53+
== Required Vulkan extensions and features
54+
- Device extensions (required by this sample):
55+
* `VK_KHR_shader_relaxed_extended_instruction`
56+
* `VK_KHR_shader_non_semantic_info`
57+
- Instance extension for feature chaining: `VK_KHR_get_physical_device_properties2` (the framework enables this; the sample requests it explicitly).
58+
- Device feature (required): `VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR::shaderRelaxedExtendedInstruction = VK_TRUE`
59+
60+
NOTE: This sample relies on the Vulkan Validation Layers (VVL) to capture and display `debugPrintfEXT` output from the non‑semantic instruction set. Ensure that VVL is enabled when running the sample. Debug builds of Vulkan‑Samples automatically enable validation; on Release builds you may need to enable validation explicitly via your environment or runtime settings.
61+
62+
Code excerpt:
63+
[source,cpp]
64+
----
65+
ShaderRelaxedExtendedInstruction::ShaderRelaxedExtendedInstruction()
66+
{
67+
title = "Shader relaxed extended instruction (VK_KHR_shader_relaxed_extended_instruction)";
68+
add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
69+
add_device_extension(VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME);
70+
add_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);
71+
}
72+
73+
void ShaderRelaxedExtendedInstruction::request_gpu_features(vkb::core::PhysicalDeviceC &gpu)
74+
{
75+
REQUEST_REQUIRED_FEATURE(gpu,
76+
VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR,
77+
shaderRelaxedExtendedInstruction);
78+
}
79+
----
80+
81+
Shader (HLSL, compiled with DXC) used by this sample:
82+
[source,hlsl]
83+
----
84+
// RUN: %dxc %s -T cs_6_0 -spirv -fspv-target-env=vulkan1.3 -E main -fspv-debug=vulkan-with-source -O3
85+
86+
struct PushConstants { uint value; };
87+
[[vk::push_constant]] PushConstants pc;
88+
89+
class A {
90+
void foo(uint v) {
91+
printf("relaxed-ext-inst demo: value = %u", v);
92+
}
93+
};
94+
95+
[numthreads(1, 1, 1)]
96+
void main(uint3 gid : SV_DispatchThreadID)
97+
{
98+
A a;
99+
if (all(gid == uint3(0,0,0))) { a.foo(pc.value); }
100+
}
101+
----
102+
103+
== Why HLSL (DXC) instead of Slang or GLSL?
104+
105+
At the time of writing, Slang and glslc in the Vulkan SDK does not emit the necessary debug information patterns that lead to `OpExtInstWithForwardRef` in SPIR-V for this demonstration. The HLSL/DXC path above does emit the required SPIR-V relaxed extended instruction sequence, so this sample uses HLSL for reliability.
106+
107+
TIP: To actually see the `debugPrintfEXT` output, run with validation configured to capture debug printf (see the `shader_debugprintf` sample or use VK_EXT_layer_settings to enable `VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT`). This sample registers an INFO‑severity `VkDebugUtilsMessengerEXT` so messages are visible when validation is active.
108+
109+
NOTE: If `VK_EXT_layer_settings` is not available from the validation layer at runtime, the sample automatically falls back to `VK_EXT_validation_features` and enables `VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT` during instance creation. In that case you do not need any environment configuration to see output.
110+

0 commit comments

Comments
 (0)