diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h index ffa970c2c0b..dcac501fcdb 100644 --- a/include/vulkan/vulkan_core.h +++ b/include/vulkan/vulkan_core.h @@ -1455,6 +1455,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DATA_GRAPH_PIPELINE_SESSION_NEURAL_STATISTICS_CREATE_INFO_ARM = 1000676001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM = 1000676002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT = 1000678000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_COVERAGE_MASK_FEATURES_MESA = 1000690000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, // VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT is a legacy alias @@ -25754,6 +25755,13 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartIndexEXT( #endif +typedef struct VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA { + VkStructureType sType; + void* pNext; + VkBool32 fragmentCoverageMask; +} VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA; + + // VK_KHR_acceleration_structure is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_acceleration_structure 1 #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 7c49e3a56c6..e04349dbf21 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -2593,6 +2593,8 @@ nir_intrinsic_from_system_value(gl_system_value val) return nir_intrinsic_load_color0_amd; case SYSTEM_VALUE_COLOR1_AMD: return nir_intrinsic_load_color1_amd; + case SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA: + return nir_intrinsic_load_fragment_coverage_mask_in; default: return nir_num_intrinsics; } @@ -2787,6 +2789,8 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin) return SYSTEM_VALUE_COLOR0_AMD; case nir_intrinsic_load_color1_amd: return SYSTEM_VALUE_COLOR1_AMD; + case nir_intrinsic_load_fragment_coverage_mask_in: + return SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA; default: return SYSTEM_VALUE_MAX; } diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index 93e6ebfb1ab..8a7a5790aa1 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -1052,6 +1052,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) case nir_intrinsic_zs_emit_pan: case nir_intrinsic_load_return_param_amd: case nir_intrinsic_load_local_invocation_index_intel: + case nir_intrinsic_load_fragment_coverage_mask_in: is_divergent = true; break; diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index 5443adf8b4e..92eb6ef1a53 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -784,6 +784,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader) case nir_intrinsic_load_layer_id: case nir_intrinsic_load_color0_amd: case nir_intrinsic_load_color1_amd: + case nir_intrinsic_load_fragment_coverage_mask_in: BITSET_SET(shader->info.system_values_read, nir_system_value_from_intrinsic(instr->intrinsic)); break; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index f79008d76c4..7e8ca2e4376 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -1035,6 +1035,7 @@ system_value("view_index", 1) system_value("subgroup_size", 1) system_value("subgroup_invocation", 1) system_value("amplification_id_kk", 1) +system_value("fragment_coverage_mask_in", 1); # These intrinsics provide a bitmask for all invocations, with one bit per # invocation starting with the least significant bit, according to the diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c index 34061abe689..87cf223f0df 100644 --- a/src/compiler/nir/nir_lower_system_values.c +++ b/src/compiler/nir/nir_lower_system_values.c @@ -187,6 +187,7 @@ lower_system_value_instr(nir_builder *b, nir_instr *instr, void *_state) case SYSTEM_VALUE_RAY_WORLD_TO_OBJECT: case SYSTEM_VALUE_MESH_VIEW_INDICES: case SYSTEM_VALUE_RAY_TRIANGLE_VERTEX_POSITIONS: + case SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA: /* These are all single-element arrays in our implementation, and * the sysval load below just drops the 0 array index. */ diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index 0a5c386fea8..923411f49ae 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -205,6 +205,7 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count, case nir_intrinsic_ballot_relaxed: case nir_intrinsic_mbcnt_amd: case nir_intrinsic_load_push_data_intel: + case nir_intrinsic_load_fragment_coverage_mask_in: if (!alu_ok) return false; break; diff --git a/src/compiler/shader_enums.c b/src/compiler/shader_enums.c index 84ba5ef733d..4ff993131e2 100644 --- a/src/compiler/shader_enums.c +++ b/src/compiler/shader_enums.c @@ -463,6 +463,7 @@ gl_system_value_name(gl_system_value sysval) ENUM(SYSTEM_VALUE_WARP_MAX_ID_ARM), ENUM(SYSTEM_VALUE_COLOR0_AMD), ENUM(SYSTEM_VALUE_COLOR1_AMD), + ENUM(SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA), }; STATIC_ASSERT(ARRAY_SIZE(names) == SYSTEM_VALUE_MAX); return NAME(sysval); diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h index 28e4e83a26a..4ebc9389077 100644 --- a/src/compiler/shader_enums.h +++ b/src/compiler/shader_enums.h @@ -974,6 +974,9 @@ typedef enum SYSTEM_VALUE_COLOR0_AMD, SYSTEM_VALUE_COLOR1_AMD, + /* SPV_MESA_fragment_coverage_mask */ + SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA, + SYSTEM_VALUE_MAX /**< Number of values */ } gl_system_value; diff --git a/src/compiler/spirv/spirv.core.grammar.json b/src/compiler/spirv/spirv.core.grammar.json index e600c0445f7..57702f2e9f4 100644 --- a/src/compiler/spirv/spirv.core.grammar.json +++ b/src/compiler/spirv/spirv.core.grammar.json @@ -16142,6 +16142,12 @@ "capabilities" : [ "Shader" ], "version": "1.0" }, + { + "enumerant" : "FragmentCoverageMaskMESA", + "value" : 4096, + "capabilities" : [ "FragmentCoverageMESA" ], + "version": "None" + }, { "enumerant" : "CoreIDARM", "value" : 4160, @@ -17281,6 +17287,13 @@ "value" : 71, "version" : "1.6" }, + { + "enumerant" : "FragmentCoverageMESA", + "value" : 4097, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_MESA_fragment_coverage_mask" ], + "version" : "None" + }, { "enumerant" : "CoreBuiltinsARM", "value" : 4165, diff --git a/src/compiler/spirv/spirv.h b/src/compiler/spirv/spirv.h index d00cf0f4e95..91721ac04f3 100644 --- a/src/compiler/spirv/spirv.h +++ b/src/compiler/spirv/spirv.h @@ -743,6 +743,7 @@ typedef enum SpvBuiltIn_ { SpvBuiltInSubgroupLocalInvocationId = 41, SpvBuiltInVertexIndex = 42, SpvBuiltInInstanceIndex = 43, + SpvBuiltInFragmentCoverageMaskMESA = 4096, SpvBuiltInCoreIDARM = 4160, SpvBuiltInCoreCountARM = 4161, SpvBuiltInCoreMaxIDARM = 4162, @@ -1139,6 +1140,7 @@ typedef enum SpvCapability_ { SpvCapabilityShaderLayer = 69, SpvCapabilityShaderViewportIndex = 70, SpvCapabilityUniformDecoration = 71, + SpvCapabilityFragmentCoverageMESA = 4097, SpvCapabilityCoreBuiltinsARM = 4165, SpvCapabilityTileImageColorReadAccessEXT = 4166, SpvCapabilityTileImageDepthReadAccessEXT = 4167, @@ -4112,6 +4114,7 @@ inline const char* SpvBuiltInToString(SpvBuiltIn value) { case SpvBuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; case SpvBuiltInVertexIndex: return "VertexIndex"; case SpvBuiltInInstanceIndex: return "InstanceIndex"; + case SpvBuiltInFragmentCoverageMaskMESA: return "FragmentCoverageMaskMESA"; case SpvBuiltInCoreIDARM: return "CoreIDARM"; case SpvBuiltInCoreCountARM: return "CoreCountARM"; case SpvBuiltInCoreMaxIDARM: return "CoreMaxIDARM"; @@ -4310,6 +4313,7 @@ inline const char* SpvCapabilityToString(SpvCapability value) { case SpvCapabilityShaderLayer: return "ShaderLayer"; case SpvCapabilityShaderViewportIndex: return "ShaderViewportIndex"; case SpvCapabilityUniformDecoration: return "UniformDecoration"; + case SpvCapabilityFragmentCoverageMESA: return "FragmentCoverageMESA"; case SpvCapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; case SpvCapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; case SpvCapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 32f9e6cd5ec..bac4ce06af8 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -49,6 +49,7 @@ static const struct spirv_capabilities implemented_capabilities = { .BFloat16TypeKHR = true, .BitInstructions = true, .ClipDistance = true, + .FragmentCoverageMESA = true, .ComputeDerivativeGroupLinearKHR = true, .ComputeDerivativeGroupQuadsKHR = true, .ConstantDataKHR = true, diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index a5cbdca3251..a9b7ff98000 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1326,6 +1326,11 @@ vtn_get_builtin_location(struct vtn_builder *b, *location = SYSTEM_VALUE_WARP_MAX_ID_ARM, set_mode_system_value(b, mode); break; + case SpvBuiltInFragmentCoverageMaskMESA: + vtn_assert(*mode == nir_var_shader_in); + *location = SYSTEM_VALUE_FRAGMENT_COVERAGE_MASK_IN_MESA; + set_mode_system_value(b, mode); + break; case SpvBuiltInSamplerHeapEXT: *mode = nir_var_sampler_heap; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 8743845ae7e..a25f6c8fc37 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1963,6 +1963,9 @@ static void emit_sysval_intrin(struct lp_build_nir_soa_context *bld, case nir_intrinsic_load_num_subgroups: result[0] = bld->system_values.num_subgroups; break; + case nir_intrinsic_load_fragment_coverage_mask_in: + result[0] = bld->system_values.fragment_coverage_mask_in; + break; } } @@ -5069,6 +5072,7 @@ visit_intrinsic(struct lp_build_nir_soa_context *bld, case nir_intrinsic_load_subgroup_invocation: case nir_intrinsic_load_subgroup_id: case nir_intrinsic_load_num_subgroups: + case nir_intrinsic_load_fragment_coverage_mask_in: emit_sysval_intrin(bld, instr, result); break; case nir_intrinsic_load_helper_invocation: diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 8889747a1d9..7f64cf73fdf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -187,6 +187,7 @@ struct lp_bld_tgsi_system_values { LLVMValueRef view_index; LLVMValueRef subgroup_id; LLVMValueRef num_subgroups; + LLVMValueRef fragment_coverage_mask_in; }; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index b7f85b49750..a0aadf33c8d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1080,6 +1080,13 @@ generate_fs_loop(struct gallivm_state *gallivm, } else { system_values.sample_mask_in = sample_mask_in; } + + /* + * A FragmentCoverageMask is a SampleMask just before being + * reduced to a single bit for per-sample execution. + */ + system_values.fragment_coverage_mask_in = system_values.sample_mask_in; + if (key->multisample && key->min_samples > 1) { lp_build_for_loop_begin(&sample_loop_state, gallivm, lp_build_const_int32(gallivm, 0), diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index e90d30a8ca6..bdab1e08ef6 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -319,6 +319,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .GOOGLE_decorate_string = true, .GOOGLE_hlsl_functionality1 = true, .GOOGLE_user_type = true, + .MESA_fragment_coverage_mask = true, .NV_cooperative_matrix2 = true, }; diff --git a/src/vulkan/registry/vk.xml b/src/vulkan/registry/vk.xml index 02dee398103..62be3829720 100644 --- a/src/vulkan/registry/vk.xml +++ b/src/vulkan/registry/vk.xml @@ -5937,6 +5937,11 @@ typedef void* MTLSharedEvent_id; VkBool32 fragmentShaderPixelInterlock VkBool32 fragmentShaderShadingRateInterlock + + VkStructureType sType + void* pNext + VkBool32 fragmentCoverageMask + VkStructureType sType void* pNext @@ -31442,6 +31447,15 @@ endif::VK_KHR_internally_synchronized_queues[] + + + + + + + + + @@ -33241,6 +33255,9 @@ endif::VK_KHR_internally_synchronized_queues[] + + + @@ -33836,6 +33853,9 @@ endif::VK_KHR_internally_synchronized_queues[] + + +