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[]
+
+
+