diff --git a/docs/SPIR-V.rst b/docs/SPIR-V.rst index 9a8150a0e8..899b587492 100644 --- a/docs/SPIR-V.rst +++ b/docs/SPIR-V.rst @@ -315,6 +315,7 @@ Supported extensions * SPV_KHR_fragment_shader_barycentric * SPV_KHR_physical_storage_buffer * SPV_KHR_vulkan_memory_model +* SPV_KHR_compute_shader_derivatives * SPV_NV_compute_shader_derivatives * SPV_KHR_maximal_reconvergence * SPV_KHR_float_controls diff --git a/tools/clang/include/clang/SPIRV/FeatureManager.h b/tools/clang/include/clang/SPIRV/FeatureManager.h index 32ee187091..7145b12db2 100644 --- a/tools/clang/include/clang/SPIRV/FeatureManager.h +++ b/tools/clang/include/clang/SPIRV/FeatureManager.h @@ -59,6 +59,7 @@ enum class Extension { KHR_physical_storage_buffer, KHR_vulkan_memory_model, NV_compute_shader_derivatives, + KHR_compute_shader_derivatives, KHR_fragment_shader_barycentric, KHR_maximal_reconvergence, KHR_float_controls, diff --git a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp index 50a7ab0905..c2b5acff53 100644 --- a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp +++ b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp @@ -852,6 +852,12 @@ bool CapabilityVisitor::visit(SpirvModule *, Visitor::Phase phase) { spv::Capability::FragmentShaderShadingRateInterlockEXT, }); + addExtensionAndCapabilitiesIfEnabled( + Extension::KHR_compute_shader_derivatives, + { + spv::Capability::ComputeDerivativeGroupQuadsKHR, + spv::Capability::ComputeDerivativeGroupLinearKHR, + }); addExtensionAndCapabilitiesIfEnabled( Extension::NV_compute_shader_derivatives, { diff --git a/tools/clang/lib/SPIRV/FeatureManager.cpp b/tools/clang/lib/SPIRV/FeatureManager.cpp index 2512984a4c..4848250dc3 100644 --- a/tools/clang/lib/SPIRV/FeatureManager.cpp +++ b/tools/clang/lib/SPIRV/FeatureManager.cpp @@ -215,6 +215,8 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) { .Case("SPV_KHR_physical_storage_buffer", Extension::KHR_physical_storage_buffer) .Case("SPV_KHR_vulkan_memory_model", Extension::KHR_vulkan_memory_model) + .Case("SPV_KHR_compute_shader_derivatives", + Extension::KHR_compute_shader_derivatives) .Case("SPV_NV_compute_shader_derivatives", Extension::NV_compute_shader_derivatives) .Case("SPV_KHR_fragment_shader_barycentric", @@ -283,6 +285,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) { return "SPV_KHR_physical_storage_buffer"; case Extension::KHR_vulkan_memory_model: return "SPV_KHR_vulkan_memory_model"; + case Extension::KHR_compute_shader_derivatives: + return "SPV_KHR_compute_shader_derivatives"; case Extension::NV_compute_shader_derivatives: return "SPV_NV_compute_shader_derivatives"; case Extension::KHR_fragment_shader_barycentric: @@ -370,6 +374,10 @@ bool FeatureManager::enabledByDefault(Extension ext) { // KHR_ray_tracing and NV_ray_tracing are mutually exclusive so enable only // KHR extension by default case Extension::NV_ray_tracing: + return false; + // KHR_compute_shader_derivatives and NV_compute_shader_derivatives are + // mutually exclusive so enable only KHR extension by default + case Extension::NV_compute_shader_derivatives: return false; // Enabling EXT_demote_to_helper_invocation changes the code generation // behavior for the 'discard' statement. Therefore we will only enable it if diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 557768f59a..429f014905 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -15036,6 +15036,10 @@ void SpirvEmitter::addDerivativeGroupExecutionMode() { // to 2D quad rules. Using derivative operations in any numthreads // configuration not matching either of these is invalid and will produce an // error. + static_assert(spv::ExecutionMode::DerivativeGroupQuadsNV == + spv::ExecutionMode::DerivativeGroupQuadsKHR); + static_assert(spv::ExecutionMode::DerivativeGroupLinearNV == + spv::ExecutionMode::DerivativeGroupLinearKHR); spv::ExecutionMode em = spv::ExecutionMode::DerivativeGroupQuadsNV; if (numThreads[0] % 4 == 0 && numThreads[1] == 1 && numThreads[2] == 1) { em = spv::ExecutionMode::DerivativeGroupLinearNV; diff --git a/tools/clang/test/CodeGenSPIRV/ddx.compute.khr.hlsl b/tools/clang/test/CodeGenSPIRV/ddx.compute.khr.hlsl new file mode 100644 index 0000000000..9e2246e6a5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/ddx.compute.khr.hlsl @@ -0,0 +1,29 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_KHR_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsKHR +// CHECK: OpExtension "SPV_KHR_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsKHR + + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(2,2,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: OpDPdx %float %float_0_5 + o[0] = ddx(0.5); + // CHECK: OpDPdxCoarse %float %float_0_5 + o[1] = ddx_coarse(0.5); + // CHECK: OpDPdy %float %float_0_5 + o[2] = ddy(0.5); + // CHECK: OpDPdyCoarse %float %float_0_5 + o[3] = ddy_coarse(0.5); + // CHECK: OpDPdxFine %float %float_0_5 + o[4] = ddx_fine(0.5); + // CHECK: OpDPdyFine %float %float_0_5 + o[5] = ddy_fine(0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/texture.calculate.lod.compute.linear.khr.hlsl b/tools/clang/test/CodeGenSPIRV/texture.calculate.lod.compute.linear.khr.hlsl new file mode 100644 index 0000000000..23f52ad4b5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/texture.calculate.lod.compute.linear.khr.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_KHR_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s --check-prefix=CHECK +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_KHR_compute_shader_derivatives %s -spirv 2>&1 | FileCheck %s --check-prefix=CHECK + +// CHECK: OpCapability ComputeDerivativeGroupLinearKHR +// CHECK: OpExtension "SPV_KHR_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearKHR + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(16,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + //CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + //CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %ss + //CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]] + //CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] %float_0_5 + //CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 0 + o[0] = t1.CalculateLevelOfDetail(ss, 0.5); +}