Skip to content

Commit 0951c1d

Browse files
Merge pull request SaschaWillems#1186 from SaschaWillems/slang_shaders
[WIP] Add Slang shaders
2 parents 746fb33 + 8a77f5f commit 0951c1d

File tree

518 files changed

+12348
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

518 files changed

+12348
-27
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,6 @@ android/.idea/**
240240

241241
libs/vulkan/*.so
242242

243-
.vscode/*
243+
.vscode/*
244+
245+
__pycache__**

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Once built, examples can be run from the bin directory. The list of available co
6868
-vs, --vsync: Enable V-Sync
6969
-f, --fullscreen: Start in fullscreen mode
7070
-w, --width: Set window width
71-
-s, --shaders: Select shader type to use (glsl or hlsl)
71+
-s, --shaders: Select shader type to use (glsl, slang, hlsl)
7272
-g, --gpu: Select GPU to run on
7373
-gl, --listgpus: Display a list of available Vulkan devices
7474
-b, --benchmark: Run example in benchmark mode
@@ -83,7 +83,7 @@ Note that some examples require specific device features, and if you are on a mu
8383

8484
## Shaders
8585

86-
Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl) but most samples also come with [HLSL](shaders/hlsl) shader sources.
86+
Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl), most samples also come with [slang](shaders/slang/) and [HLSL](shaders/hlsl) shader sources, making it easy to compare the differences between those shading languages.
8787

8888
## A note on synchronization
8989

base/vulkanexamplebase.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ VkResult VulkanExampleBase::createInstance()
8989
}
9090
}
9191

92+
// Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions
93+
if (shaderDir == "slang") {
94+
if (apiVersion < VK_API_VERSION_1_1) {
95+
apiVersion = VK_API_VERSION_1_1;
96+
}
97+
enabledDeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
98+
enabledDeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
99+
}
100+
92101
VkApplicationInfo appInfo{};
93102
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
94103
appInfo.pApplicationName = name.c_str();

examples/computecullandlod/computecullandlod.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ class VulkanExample : public VulkanExampleBase
391391
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkglTF::Vertex, color)), // Location 2: Texture coordinates
392392
// Per-Instance attributes
393393
// These are fetched for each instance rendered
394-
vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position
395-
vks::initializers::vertexInputAttributeDescription(1, 5, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale
394+
vks::initializers::vertexInputAttributeDescription(1, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position
395+
vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale
396396
};
397397
inputState.pVertexBindingDescriptions = bindingDescriptions.data();
398398
inputState.pVertexAttributeDescriptions = attributeDescriptions.data();

examples/computeheadless/computeheadless.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class VulkanExample
8282

8383
VkDebugReportCallbackEXT debugReportCallback{};
8484

85+
std::string shaderDir = "glsl";
86+
8587
VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkBuffer *buffer, VkDeviceMemory *memory, VkDeviceSize size, void *data = nullptr)
8688
{
8789
// Create the buffer handle
@@ -132,11 +134,19 @@ class VulkanExample
132134
vks::android::loadVulkanLibrary();
133135
#endif
134136

137+
if (commandLineParser.isSet("shaders")) {
138+
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
139+
}
140+
135141
VkApplicationInfo appInfo = {};
136142
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
137143
appInfo.pApplicationName = "Vulkan headless example";
138144
appInfo.pEngineName = "VulkanExample";
139145
appInfo.apiVersion = VK_API_VERSION_1_0;
146+
// Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions
147+
if (shaderDir == "slang") {
148+
appInfo.apiVersion = VK_API_VERSION_1_1;
149+
}
140150

141151
/*
142152
Vulkan instance creation (without surface extensions)
@@ -159,7 +169,7 @@ class VulkanExample
159169
bool layersAvailable = true;
160170
for (auto layerName : validationLayers) {
161171
bool layerAvailable = false;
162-
for (auto instanceLayer : instanceLayers) {
172+
for (auto& instanceLayer : instanceLayers) {
163173
if (strcmp(instanceLayer.layerName, layerName) == 0) {
164174
layerAvailable = true;
165175
break;
@@ -260,8 +270,15 @@ class VulkanExample
260270
deviceCreateInfo.queueCreateInfoCount = 1;
261271
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
262272
std::vector<const char*> deviceExtensions = {};
273+
274+
// Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions
275+
if (shaderDir == "slang") {
276+
deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
277+
deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
278+
}
279+
263280
#if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset)
264-
// SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
281+
// When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
265282
uint32_t deviceExtCount = 0;
266283
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr);
267284
if (deviceExtCount > 0)
@@ -410,10 +427,6 @@ class VulkanExample
410427
VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t));
411428
VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData);
412429

413-
std::string shaderDir = "glsl";
414-
if (commandLineParser.isSet("shaders")) {
415-
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
416-
}
417430
const std::string shadersPath = getShaderBasePath() + shaderDir + "/computeheadless/";
418431

419432
VkPipelineShaderStageCreateInfo shaderStage = {};

examples/renderheadless/renderheadless.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class VulkanExample
9797

9898
VkDebugReportCallbackEXT debugReportCallback{};
9999

100+
std::string shaderDir = "glsl";
101+
100102
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) {
101103
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
102104
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
@@ -163,11 +165,19 @@ class VulkanExample
163165
vks::android::loadVulkanLibrary();
164166
#endif
165167

168+
if (commandLineParser.isSet("shaders")) {
169+
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
170+
}
171+
166172
VkApplicationInfo appInfo = {};
167173
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
168174
appInfo.pApplicationName = "Vulkan headless example";
169175
appInfo.pEngineName = "VulkanExample";
170176
appInfo.apiVersion = VK_API_VERSION_1_0;
177+
// Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions
178+
if (shaderDir == "slang") {
179+
appInfo.apiVersion = VK_API_VERSION_1_1;
180+
}
171181

172182
/*
173183
Vulkan instance creation (without surface extensions)
@@ -190,7 +200,7 @@ class VulkanExample
190200
bool layersAvailable = true;
191201
for (auto layerName : validationLayers) {
192202
bool layerAvailable = false;
193-
for (auto instanceLayer : instanceLayers) {
203+
for (auto& instanceLayer : instanceLayers) {
194204
if (strcmp(instanceLayer.layerName, layerName) == 0) {
195205
layerAvailable = true;
196206
break;
@@ -290,8 +300,15 @@ class VulkanExample
290300
deviceCreateInfo.queueCreateInfoCount = 1;
291301
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
292302
std::vector<const char*> deviceExtensions = {};
303+
304+
// Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions
305+
if (shaderDir == "slang") {
306+
deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
307+
deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
308+
}
309+
293310
#if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset)
294-
// SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
311+
// When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
295312
uint32_t deviceExtCount = 0;
296313
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr);
297314
if (deviceExtCount > 0)
@@ -643,7 +660,6 @@ class VulkanExample
643660

644661
pipelineCreateInfo.pVertexInputState = &vertexInputState;
645662

646-
std::string shaderDir = "glsl";
647663
if (commandLineParser.isSet("shaders")) {
648664
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
649665
}

examples/shadowmappingcascade/shadowmappingcascade.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
/*
22
Vulkan Example - Cascaded shadow mapping for directional light sources
3-
Copyright by Sascha Willems - www.saschawillems.de
3+
Copyright (c) 2016-2025 by Sascha Willems - www.saschawillems.de
44
This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
5-
*/
65
7-
/*
86
This example implements projective cascaded shadow mapping. This technique splits up the camera frustum into
97
multiple frustums with each getting its own full-res shadow map, implemented as a layered depth-only image.
108
The shader then selects the proper shadow map layer depending on what split of the frustum the depth value
@@ -175,7 +173,7 @@ class VulkanExample : public VulkanExampleBase
175173
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
176174

177175
// Floor
178-
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
176+
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
179177
models.terrain.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout);
180178

181179
// Trees
@@ -189,7 +187,7 @@ class VulkanExample : public VulkanExampleBase
189187

190188
for (auto& position : positions) {
191189
pushConstBlock.position = glm::vec4(position, 0.0f);
192-
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
190+
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
193191
// This will also bind the texture images to set 1
194192
models.tree.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout);
195193
}
@@ -413,7 +411,7 @@ class VulkanExample : public VulkanExampleBase
413411
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.debugShadowMap);
414412
PushConstBlock pushConstBlock = {};
415413
pushConstBlock.cascadeIndex = displayDepthMapCascadeIndex;
416-
vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
414+
vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
417415
vkCmdDraw(drawCmdBuffers[i], 3, 1, 0, 0);
418416
}
419417

@@ -490,7 +488,7 @@ class VulkanExample : public VulkanExampleBase
490488

491489
// Shared pipeline layout (scene and depth map debug display)
492490
{
493-
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
491+
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(PushConstBlock), 0);
494492
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage };
495493
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
496494
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
@@ -500,7 +498,7 @@ class VulkanExample : public VulkanExampleBase
500498

501499
// Depth pass pipeline layout
502500
{
503-
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
501+
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(PushConstBlock), 0);
504502
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage };
505503
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
506504
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;

shaders/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# Shaders
22

3-
This folder contains the shaders used by the samples. Source files are available as GLSL and HLSL and also come with precompiled SPIR-V files that are consumed by the samples. To recompile shaders you can use the `compileshaders.py` scripts in the respective folders or any other means that can generate Vulkan SPIR-V from GLSL or HLSL. One such option is [this extension for Visual Studio](https://github.com/SaschaWillems/SPIRV-VSExtension).
3+
This folder contains the shaders used by the samples. Source files are available in GLSL, HLSL and [slang](https://shader-slang.org/) and also come with precompiled SPIR-V files that are consumed by the samples. To recompile shaders you can use the `compileshaders.py` scripts in the respective folders or any other means that can generate Vulkan SPIR-V from GLSL, HLSL or slang. One such option is [this extension for Visual Studio](https://github.com/SaschaWillems/SPIRV-VSExtension).
4+
5+
Note that not all samples may come with all shading language variants. So some samples that have GLSL source files might not come with HLSL and/or slang source files.
6+
7+
A note for using **slang** shaders: These require a different SPIR-V environment than glsl/hlsl. When selecting slang shaders, the base requirement for all samples is raised to at least Vulkan 1.1 with the SPIRV 1.4 extension.
8+
9+
If you want to compile **slang** shaders to SPIR-V, please use the latest release from [here](https://github.com/shader-slang/slang/releases) to get the latest bug fixes and features required for some of the samples.
24 Bytes
Binary file not shown.

shaders/glsl/computecullandlod/indirectdraw.vert

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ layout (location = 1) in vec3 inNormal;
66
layout (location = 2) in vec3 inColor;
77

88
// Instanced attributes
9-
layout (location = 4) in vec3 instancePos;
10-
layout (location = 5) in float instanceScale;
9+
layout (location = 3) in vec3 instancePos;
10+
layout (location = 4) in float instanceScale;
1111

1212
layout (binding = 0) uniform UBO
1313
{

0 commit comments

Comments
 (0)