@@ -32,10 +32,12 @@ ComputeShaderDerivatives::ComputeShaderDerivatives()
3232
3333 // Needed for feature chaining
3434 add_instance_extension (VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35- // Device extension providing the feature
35+ // Device extension providing the feature (KHR is required)
3636 add_device_extension (VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME);
37- // Toolchains may still emit SPV_NV_compute_shader_derivatives; enable NV extension if available to satisfy validation
38- add_device_extension (VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, /* optional*/ true );
37+ // Note for developers/tooling:
38+ // If your shader compiler/toolchain only emits SPV_NV_compute_shader_derivatives instead of SPV_KHR,
39+ // please update to a newer Vulkan SDK, glslang, and SPIR-V Tools that support the KHR variant.
40+ // This sample intentionally does not enable the NV extension and only targets VK_KHR_compute_shader_derivatives.
3941 // Shader draw parameters (required for SV_VertexID in Slang-generated vertex shader SPIR-V)
4042 add_device_extension (VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, /* optional*/ true );
4143}
@@ -172,13 +174,28 @@ void ComputeShaderDerivatives::create_output_buffer_and_descriptors()
172174
173175void ComputeShaderDerivatives::request_gpu_features (vkb::core::PhysicalDeviceC &gpu)
174176{
175- // Require quads derivative group (the sample shader uses layout(derivative_group_quadsNV/derivative_group_quads_khr))
176- REQUEST_REQUIRED_FEATURE (gpu, VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR, computeDerivativeGroupQuads);
177- // Users may switch to the linear mode by changing the shader qualifier
177+ // Request both derivative group modes as OPTIONAL, prefer Quads if available at runtime.
178+ // Some implementations only support computeDerivativeGroupLinear.
179+ REQUEST_OPTIONAL_FEATURE (gpu, VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR, computeDerivativeGroupQuads);
180+ REQUEST_OPTIONAL_FEATURE (gpu, VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR, computeDerivativeGroupLinear);
178181
179182 // Storage image read/write without format (required for storage images without explicit format qualifiers)
180- gpu.get_mutable_requested_features ().shaderStorageImageReadWithoutFormat = VK_TRUE;
181- gpu.get_mutable_requested_features ().shaderStorageImageWriteWithoutFormat = VK_TRUE;
183+ if (gpu.get_features ().shaderStorageImageReadWithoutFormat )
184+ {
185+ gpu.get_mutable_requested_features ().shaderStorageImageReadWithoutFormat = VK_TRUE;
186+ }
187+ else
188+ {
189+ throw std::runtime_error (" GPU does not support shaderStorageImageReadWithoutFormat feature, which is required for this sample." );
190+ }
191+ if (gpu.get_features ().shaderStorageImageWriteWithoutFormat )
192+ {
193+ gpu.get_mutable_requested_features ().shaderStorageImageWriteWithoutFormat = VK_TRUE;
194+ }
195+ else
196+ {
197+ throw std::runtime_error (" GPU does not support shaderStorageImageWriteWithoutFormat feature, which is required for this sample." );
198+ }
182199}
183200
184201void ComputeShaderDerivatives::create_compute_pipeline ()
@@ -230,8 +247,11 @@ void ComputeShaderDerivatives::create_compute_pipeline()
230247
231248 vkUpdateDescriptorSets (device, 1 , &write, 0 , nullptr );
232249
233- // Load compute shader
234- VkPipelineShaderStageCreateInfo stage = load_shader (" compute_shader_derivatives/slang/derivatives.comp.spv" , VK_SHADER_STAGE_COMPUTE_BIT);
250+ // Load compute shader based on selected derivative group mode
251+ const char *comp_path = use_quads_ ?
252+ " compute_shader_derivatives/slang/derivatives_quad.comp.spv" :
253+ " compute_shader_derivatives/slang/derivatives_linear.comp.spv" ;
254+ VkPipelineShaderStageCreateInfo stage = load_shader (comp_path, VK_SHADER_STAGE_COMPUTE_BIT);
235255
236256 VkComputePipelineCreateInfo compute_ci{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
237257 compute_ci.stage = stage;
@@ -361,15 +381,29 @@ void ComputeShaderDerivatives::create_graphics_pipeline()
361381
362382bool ComputeShaderDerivatives::prepare (const vkb::ApplicationOptions &options)
363383{
364- if (!ApiVulkanSample::prepare (options))
384+ if (!ApiVulkanSample::prepare (options))
385+ {
386+ return false ;
387+ }
388+
389+ // Decide which derivative group to use at runtime based on enabled device features.
390+ // Prefer Quads when available; otherwise, fall back to Linear.
391+ VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR csd_features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR};
392+ VkPhysicalDeviceFeatures2 features2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
393+ features2.pNext = &csd_features;
394+ vkGetPhysicalDeviceFeatures2 (get_device ().get_gpu ().get_handle (), &features2);
395+ use_quads_ = (csd_features.computeDerivativeGroupQuads == VK_TRUE);
396+ if (!use_quads_ && csd_features.computeDerivativeGroupLinear != VK_TRUE)
365397 {
398+ // Neither mode is available: cannot run this sample.
399+ LOGE (" VK_KHR_compute_shader_derivatives present but neither quads nor linear derivative groups are reported as supported." );
366400 return false ;
367401 }
368402
369- // Create resources in order: image, buffer, then pipelines
370- create_storage_image ();
371- create_output_buffer_and_descriptors ();
372- create_compute_pipeline ();
403+ // Create resources in order: image, buffer, then pipelines
404+ create_storage_image ();
405+ create_output_buffer_and_descriptors ();
406+ create_compute_pipeline ();
373407 create_graphics_pipeline ();
374408
375409 prepared = true ;
0 commit comments