Add slang shaders for headless samples
This commit is contained in:
parent
a442bdd683
commit
04ab171247
4 changed files with 104 additions and 9 deletions
|
|
@ -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 = {};
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
shaders/slang/computeheadless/headless.slang
Normal file
34
shaders/slang/computeheadless/headless.slang
Normal 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]);
|
||||||
|
}
|
||||||
|
|
||||||
32
shaders/slang/renderheadless/triangle.slang
Normal file
32
shaders/slang/renderheadless/triangle.slang
Normal 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);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue