Add slang shaders for headless samples

This commit is contained in:
Sascha Willems 2025-05-15 19:04:04 +02:00
parent a442bdd683
commit 04ab171247
4 changed files with 104 additions and 9 deletions

View file

@ -82,6 +82,8 @@ public:
VkDebugReportCallbackEXT debugReportCallback{}; VkDebugReportCallbackEXT debugReportCallback{};
std::string shaderDir = "glsl";
VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkBuffer *buffer, VkDeviceMemory *memory, VkDeviceSize size, void *data = nullptr) VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkBuffer *buffer, VkDeviceMemory *memory, VkDeviceSize size, void *data = nullptr)
{ {
// Create the buffer handle // Create the buffer handle
@ -132,11 +134,19 @@ public:
vks::android::loadVulkanLibrary(); vks::android::loadVulkanLibrary();
#endif #endif
if (commandLineParser.isSet("shaders")) {
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
}
VkApplicationInfo appInfo = {}; VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan headless example"; appInfo.pApplicationName = "Vulkan headless example";
appInfo.pEngineName = "VulkanExample"; appInfo.pEngineName = "VulkanExample";
appInfo.apiVersion = VK_API_VERSION_1_0; appInfo.apiVersion = VK_API_VERSION_1_0;
// 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
if (shaderDir == "slang") {
appInfo.apiVersion = VK_API_VERSION_1_1;
}
/* /*
Vulkan instance creation (without surface extensions) Vulkan instance creation (without surface extensions)
@ -159,7 +169,7 @@ public:
bool layersAvailable = true; bool layersAvailable = true;
for (auto layerName : validationLayers) { for (auto layerName : validationLayers) {
bool layerAvailable = false; bool layerAvailable = false;
for (auto instanceLayer : instanceLayers) { for (auto& instanceLayer : instanceLayers) {
if (strcmp(instanceLayer.layerName, layerName) == 0) { if (strcmp(instanceLayer.layerName, layerName) == 0) {
layerAvailable = true; layerAvailable = true;
break; break;
@ -260,8 +270,15 @@ public:
deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
std::vector<const char*> deviceExtensions = {}; std::vector<const char*> deviceExtensions = {};
// 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
if (shaderDir == "slang") {
deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
}
#if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset) #if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset)
// SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension // When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
uint32_t deviceExtCount = 0; uint32_t deviceExtCount = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr); vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr);
if (deviceExtCount > 0) if (deviceExtCount > 0)
@ -410,10 +427,6 @@ public:
VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t));
VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData); VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData);
std::string shaderDir = "glsl";
if (commandLineParser.isSet("shaders")) {
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
}
const std::string shadersPath = getShaderBasePath() + shaderDir + "/computeheadless/"; const std::string shadersPath = getShaderBasePath() + shaderDir + "/computeheadless/";
VkPipelineShaderStageCreateInfo shaderStage = {}; VkPipelineShaderStageCreateInfo shaderStage = {};

View file

@ -97,6 +97,8 @@ public:
VkDebugReportCallbackEXT debugReportCallback{}; VkDebugReportCallbackEXT debugReportCallback{};
std::string shaderDir = "glsl";
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) { uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties deviceMemoryProperties; VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
@ -163,11 +165,19 @@ public:
vks::android::loadVulkanLibrary(); vks::android::loadVulkanLibrary();
#endif #endif
if (commandLineParser.isSet("shaders")) {
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
}
VkApplicationInfo appInfo = {}; VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan headless example"; appInfo.pApplicationName = "Vulkan headless example";
appInfo.pEngineName = "VulkanExample"; appInfo.pEngineName = "VulkanExample";
appInfo.apiVersion = VK_API_VERSION_1_0; appInfo.apiVersion = VK_API_VERSION_1_0;
// 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
if (shaderDir == "slang") {
appInfo.apiVersion = VK_API_VERSION_1_1;
}
/* /*
Vulkan instance creation (without surface extensions) Vulkan instance creation (without surface extensions)
@ -190,7 +200,7 @@ public:
bool layersAvailable = true; bool layersAvailable = true;
for (auto layerName : validationLayers) { for (auto layerName : validationLayers) {
bool layerAvailable = false; bool layerAvailable = false;
for (auto instanceLayer : instanceLayers) { for (auto& instanceLayer : instanceLayers) {
if (strcmp(instanceLayer.layerName, layerName) == 0) { if (strcmp(instanceLayer.layerName, layerName) == 0) {
layerAvailable = true; layerAvailable = true;
break; break;
@ -290,8 +300,15 @@ public:
deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
std::vector<const char*> deviceExtensions = {}; std::vector<const char*> deviceExtensions = {};
// 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
if (shaderDir == "slang") {
deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
}
#if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset) #if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset)
// SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension // When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension
uint32_t deviceExtCount = 0; uint32_t deviceExtCount = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr); vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr);
if (deviceExtCount > 0) if (deviceExtCount > 0)
@ -643,7 +660,6 @@ public:
pipelineCreateInfo.pVertexInputState = &vertexInputState; pipelineCreateInfo.pVertexInputState = &vertexInputState;
std::string shaderDir = "glsl";
if (commandLineParser.isSet("shaders")) { if (commandLineParser.isSet("shaders")) {
shaderDir = commandLineParser.getValueAsString("shaders", "glsl"); shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
} }

View file

@ -0,0 +1,34 @@
/* Copyright (c) 2025, Sascha Willems
*
* SPDX-License-Identifier: MIT
*
*/
RWStructuredBuffer<uint> values;
[[SpecializationConstant]] const uint BUFFER_ELEMENTS = 32;
uint fibonacci(uint n) {
if(n <= 1){
return n;
}
uint curr = 1;
uint prev = 1;
for(uint i = 2; i < n; ++i) {
uint temp = curr;
curr += prev;
prev = temp;
}
return curr;
}
[numthreads(1, 1, 1)]
[shader("compute")]
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
{
uint index = GlobalInvocationID.x;
if (index >= BUFFER_ELEMENTS)
return;
values[index] = fibonacci(values[index]);
}

View file

@ -0,0 +1,32 @@
/* Copyright (c) 2025, Sascha Willems
*
* SPDX-License-Identifier: MIT
*
*/
struct VSInput
{
float3 Pos;
float3 Color;
};
struct VSOutput
{
float4 Pos : SV_POSITION;
float3 Color;
};
[shader("vertex")]
VSOutput vertexMain(VSInput input, uniform float4x4 mvp)
{
VSOutput output;
output.Color = input.Color;
output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0));
return output;
}
[shader("fragment")]
float4 fragmentMain(VSOutput input)
{
return float4(input.Color, 1.0);
}