Define Int64Atomics SPIR-V capability

This commit is contained in:
Marcin Mikołajczyk 2025-06-21 15:00:25 +01:00
parent 3c13ad8bc4
commit 6c9ce1313b
7 changed files with 41 additions and 2 deletions

View File

@ -310,6 +310,19 @@ void SetupCapabilities(const Info& info, const Profile& profile, EmitContext& ct
ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR); ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR);
ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR); ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR);
} }
if (info.uses_buffer_int64_atomics || info.uses_shared_int64_atomics) {
if (info.uses_buffer_int64_atomics) {
ASSERT_MSG(ctx.profile.supports_buffer_int64_atomics,
"Shader requires support for atomic Int64 buffer operations that your "
"Vulkan instance does not advertise");
}
if (info.uses_shared_int64_atomics) {
ASSERT_MSG(ctx.profile.supports_shared_int64_atomics,
"Shader requires support for atomic Int64 shared memory operations that "
"your Vulkan instance does not advertise");
}
ctx.AddCapability(spv::Capability::Int64Atomics);
}
} }
void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) { void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) {

View File

@ -226,6 +226,8 @@ struct Info {
bool uses_fp64{}; bool uses_fp64{};
bool uses_pack_10_11_11{}; bool uses_pack_10_11_11{};
bool uses_unpack_10_11_11{}; bool uses_unpack_10_11_11{};
bool uses_buffer_int64_atomics{};
bool uses_shared_int64_atomics{};
bool stores_tess_level_outer{}; bool stores_tess_level_outer{};
bool stores_tess_level_inner{}; bool stores_tess_level_inner{};
bool translation_failed{}; bool translation_failed{};

View File

@ -53,9 +53,11 @@ void Visit(Info& info, const IR::Inst& inst) {
case IR::Opcode::SharedAtomicXor32: case IR::Opcode::SharedAtomicXor32:
info.shared_types |= IR::Type::U32; info.shared_types |= IR::Type::U32;
break; break;
case IR::Opcode::SharedAtomicIAdd64:
info.uses_shared_int64_atomics = true;
[[fallthrough]];
case IR::Opcode::LoadSharedU64: case IR::Opcode::LoadSharedU64:
case IR::Opcode::WriteSharedU64: case IR::Opcode::WriteSharedU64:
case IR::Opcode::SharedAtomicIAdd64:
info.shared_types |= IR::Type::U64; info.shared_types |= IR::Type::U64;
break; break;
case IR::Opcode::ConvertF16F32: case IR::Opcode::ConvertF16F32:
@ -98,6 +100,11 @@ void Visit(Info& info, const IR::Inst& inst) {
case IR::Opcode::BufferAtomicFMin32: case IR::Opcode::BufferAtomicFMin32:
info.uses_buffer_atomic_float_min_max = true; info.uses_buffer_atomic_float_min_max = true;
break; break;
case IR::Opcode::BufferAtomicIAdd64:
case IR::Opcode::BufferAtomicSMax64:
case IR::Opcode::BufferAtomicUMax64:
info.uses_buffer_int64_atomics = true;
break;
case IR::Opcode::LaneId: case IR::Opcode::LaneId:
info.uses_lane_id = true; info.uses_lane_id = true;
break; break;

View File

@ -30,6 +30,8 @@ struct Profile {
bool supports_robust_buffer_access{}; bool supports_robust_buffer_access{};
bool supports_buffer_fp32_atomic_min_max{}; bool supports_buffer_fp32_atomic_min_max{};
bool supports_image_fp32_atomic_min_max{}; bool supports_image_fp32_atomic_min_max{};
bool supports_buffer_int64_atomics{};
bool supports_shared_int64_atomics{};
bool supports_workgroup_explicit_memory_layout{}; bool supports_workgroup_explicit_memory_layout{};
bool has_broken_spirv_clamp{}; bool has_broken_spirv_clamp{};
bool lower_left_origin_mode{}; bool lower_left_origin_mode{};

View File

@ -341,7 +341,7 @@ bool Instance::CreateDevice() {
const auto topology_list_restart_features = const auto topology_list_restart_features =
feature_chain.get<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>(); feature_chain.get<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
const auto vk11_features = feature_chain.get<vk::PhysicalDeviceVulkan11Features>(); const auto vk11_features = feature_chain.get<vk::PhysicalDeviceVulkan11Features>();
const auto vk12_features = feature_chain.get<vk::PhysicalDeviceVulkan12Features>(); vk12_features = feature_chain.get<vk::PhysicalDeviceVulkan12Features>();
const auto vk13_features = feature_chain.get<vk::PhysicalDeviceVulkan13Features>(); const auto vk13_features = feature_chain.get<vk::PhysicalDeviceVulkan13Features>();
vk::StructureChain device_chain = { vk::StructureChain device_chain = {
vk::DeviceCreateInfo{ vk::DeviceCreateInfo{
@ -387,6 +387,8 @@ bool Instance::CreateDevice() {
.drawIndirectCount = vk12_features.drawIndirectCount, .drawIndirectCount = vk12_features.drawIndirectCount,
.storageBuffer8BitAccess = vk12_features.storageBuffer8BitAccess, .storageBuffer8BitAccess = vk12_features.storageBuffer8BitAccess,
.uniformAndStorageBuffer8BitAccess = vk12_features.uniformAndStorageBuffer8BitAccess, .uniformAndStorageBuffer8BitAccess = vk12_features.uniformAndStorageBuffer8BitAccess,
.shaderBufferInt64Atomics = vk12_features.shaderBufferInt64Atomics,
.shaderSharedInt64Atomics = vk12_features.shaderSharedInt64Atomics,
.shaderFloat16 = vk12_features.shaderFloat16, .shaderFloat16 = vk12_features.shaderFloat16,
.shaderInt8 = vk12_features.shaderInt8, .shaderInt8 = vk12_features.shaderInt8,
.scalarBlockLayout = vk12_features.scalarBlockLayout, .scalarBlockLayout = vk12_features.scalarBlockLayout,

View File

@ -178,6 +178,16 @@ public:
return shader_atomic_float2 && shader_atomic_float2_features.shaderImageFloat32AtomicMinMax; return shader_atomic_float2 && shader_atomic_float2_features.shaderImageFloat32AtomicMinMax;
} }
/// Returns true if 64-bit integer atomic operations can be used on buffers
bool IsBufferInt64AtomicsSupported() const {
return vk12_features.shaderBufferInt64Atomics;
}
/// Returns true if 64-bit integer atomic operations can be used on shared memory
bool IsSharedInt64AtomicsSupported() const {
return vk12_features.shaderSharedInt64Atomics;
}
/// Returns true when VK_KHR_workgroup_memory_explicit_layout is supported. /// Returns true when VK_KHR_workgroup_memory_explicit_layout is supported.
bool IsWorkgroupMemoryExplicitLayoutSupported() const { bool IsWorkgroupMemoryExplicitLayoutSupported() const {
return workgroup_memory_explicit_layout && return workgroup_memory_explicit_layout &&
@ -358,6 +368,7 @@ private:
vk::PhysicalDeviceVulkan12Properties vk12_props; vk::PhysicalDeviceVulkan12Properties vk12_props;
vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props; vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props;
vk::PhysicalDeviceFeatures features; vk::PhysicalDeviceFeatures features;
vk::PhysicalDeviceVulkan12Features vk12_features;
vk::PhysicalDevicePortabilitySubsetFeaturesKHR portability_features; vk::PhysicalDevicePortabilitySubsetFeaturesKHR portability_features;
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT dynamic_state_3_features; vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT dynamic_state_3_features;
vk::PhysicalDeviceRobustness2FeaturesEXT robustness2_features; vk::PhysicalDeviceRobustness2FeaturesEXT robustness2_features;

View File

@ -219,6 +219,8 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
.supports_buffer_fp32_atomic_min_max = .supports_buffer_fp32_atomic_min_max =
instance_.IsShaderAtomicFloatBuffer32MinMaxSupported(), instance_.IsShaderAtomicFloatBuffer32MinMaxSupported(),
.supports_image_fp32_atomic_min_max = instance_.IsShaderAtomicFloatImage32MinMaxSupported(), .supports_image_fp32_atomic_min_max = instance_.IsShaderAtomicFloatImage32MinMaxSupported(),
.supports_buffer_int64_atomics = instance_.IsBufferInt64AtomicsSupported(),
.supports_shared_int64_atomics = instance_.IsSharedInt64AtomicsSupported(),
.supports_workgroup_explicit_memory_layout = .supports_workgroup_explicit_memory_layout =
instance_.IsWorkgroupMemoryExplicitLayoutSupported(), instance_.IsWorkgroupMemoryExplicitLayoutSupported(),
.needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() && .needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() &&