Merge branch 'mesa-fragment-coverage-mask' into 'main'

Draft: lavapipe: Implement MESA_fragment_coverage_mask extension

See merge request mesa/mesa!41423
This commit is contained in:
Michał Król 2026-05-08 02:09:59 +02:00
commit 54ad889081
18 changed files with 77 additions and 0 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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.
*/

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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";

View file

@ -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,

View file

@ -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;

View file

@ -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:

View file

@ -187,6 +187,7 @@ struct lp_bld_tgsi_system_values {
LLVMValueRef view_index;
LLVMValueRef subgroup_id;
LLVMValueRef num_subgroups;
LLVMValueRef fragment_coverage_mask_in;
};

View file

@ -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),

View file

@ -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,
};

View file

@ -5937,6 +5937,11 @@ typedef void* <name>MTLSharedEvent_id</name>;
<member><type>VkBool32</type> <name>fragmentShaderPixelInterlock</name></member>
<member><type>VkBool32</type> <name>fragmentShaderShadingRateInterlock</name></member>
</type>
<type category="struct" name="VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_COVERAGE_MASK_FEATURES_MESA"><type>VkStructureType</type> <name>sType</name></member>
<member optional="true"><type>void</type>* <name>pNext</name></member>
<member><type>VkBool32</type> <name>fragmentCoverageMask</name></member>
</type>
<type category="struct" name="VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES"><type>VkStructureType</type> <name>sType</name></member>
<member optional="true"><type>void</type>* <name>pNext</name></member>
@ -31442,6 +31447,15 @@ endif::VK_KHR_internally_synchronized_queues[]
<enum value="&quot;VK_NV_extension_690&quot;" name="VK_NV_EXTENSION_690_EXTENSION_NAME"/>
</require>
</extension>
<extension name="VK_MESA_fragment_coverage_mask" number="691" type="device" depends="VK_KHR_get_physical_device_properties2,VK_VERSION_1_1" author="MESA" contact="Michal Krol @mjkrol" supported="vulkan">
<require>
<enum value="1" name="VK_MESA_FRAGMENT_COVERAGE_MASK_SPEC_VERSION"/>
<enum value="&quot;VK_MESA_fragment_coverage_mask&quot;" name="VK_MESA_FRAGMENT_COVERAGE_MASK_EXTENSION_NAME"/>
<enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_COVERAGE_MASK_FEATURES_MESA"/>
<type name="VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA"/>
<feature name="fragmentCoverageMask" struct="VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA"/>
</require>
</extension>
</extensions>
<formats>
<format name="VK_FORMAT_R4G4_UNORM_PACK8" class="8-bit" blockSize="1" texelsPerBlock="1" packed="8">
@ -33241,6 +33255,9 @@ endif::VK_KHR_internally_synchronized_queues[]
<spirvextension name="SPV_EXT_fragment_shader_interlock">
<enable extension="VK_EXT_fragment_shader_interlock"/>
</spirvextension>
<spirvextension name="SPV_MESA_fragment_coverage_mask">
<enable extension="VK_MESA_fragment_coverage_mask"/>
</spirvextension>
<spirvextension name="SPV_EXT_demote_to_helper_invocation">
<enable version="VK_VERSION_1_3"/>
<enable extension="VK_EXT_shader_demote_to_helper_invocation"/>
@ -33836,6 +33853,9 @@ endif::VK_KHR_internally_synchronized_queues[]
<enable struct="VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT" feature="fragmentShaderShadingRateInterlock" requires="VK_EXT_fragment_shader_interlock"/>
<enable struct="VkPhysicalDeviceShadingRateImageFeaturesNV" feature="shadingRateImage" requires="VK_NV_shading_rate_image"/>
</spirvcapability>
<spirvcapability name="FragmentCoverageMESA">
<enable struct="VkPhysicalDeviceFragmentCoverageMaskFeaturesMESA" feature="fragmentCoverageMask" requires="VK_MESA_fragment_coverage_mask"/>
</spirvcapability>
<spirvcapability name="DemoteToHelperInvocation">
<enable struct="VkPhysicalDeviceVulkan13Features" feature="shaderDemoteToHelperInvocation" requires="VK_VERSION_1_3,VK_EXT_shader_demote_to_helper_invocation"/>
<enable struct="VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT" feature="shaderDemoteToHelperInvocation" requires="VK_EXT_shader_demote_to_helper_invocation"/>