venus: support VK_EXT_sample_locations

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33520>
This commit is contained in:
Yiwei Zhang 2025-02-12 14:30:07 -08:00 committed by Marge Bot
parent ae3bc10d58
commit ff64092ff3
4 changed files with 131 additions and 3 deletions

View file

@ -641,7 +641,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_EXT_queue_family_foreign DONE (anv, hasvk, nvk, lvp, panvk, radv, tu, v3dv, vn)
VK_EXT_rasterization_order_attachment_access DONE (lvp, tu, vn)
VK_EXT_robustness2 DONE (anv, hasvk, lvp, nvk, radv, tu, vn)
VK_EXT_sample_locations DONE (anv, hasvk, nvk, radv/gfx9-, tu/a650+)
VK_EXT_sample_locations DONE (anv, hasvk, nvk, radv/gfx9-, tu/a650+, vn)
VK_EXT_shader_atomic_float DONE (anv, hasvk, lvp, radv)
VK_EXT_shader_atomic_float2 DONE (anv, lvp, radv)
VK_EXT_shader_image_atomic_int64 DONE (nvk, radv)

View file

@ -2539,3 +2539,12 @@ vn_CmdSetFragmentShadingRateKHR(
VN_CMD_ENQUEUE(vkCmdSetFragmentShadingRateKHR, commandBuffer,
pFragmentSize, combinerOps);
}
void
vn_CmdSetSampleLocationsEXT(
VkCommandBuffer commandBuffer,
const VkSampleLocationsInfoEXT *pSampleLocationsInfo)
{
VN_CMD_ENQUEUE(vkCmdSetSampleLocationsEXT, commandBuffer,
pSampleLocationsInfo);
}

View file

@ -510,6 +510,7 @@ vn_physical_device_init_properties(struct vn_physical_device *physical_dev)
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info;
VkPhysicalDeviceProvokingVertexPropertiesEXT provoking_vertex;
VkPhysicalDeviceRobustness2PropertiesEXT robustness_2;
VkPhysicalDeviceSampleLocationsPropertiesEXT sample_locations;
VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback;
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT
vertex_attribute_divisor;
@ -568,6 +569,7 @@ vn_physical_device_init_properties(struct vn_physical_device *physical_dev)
VN_ADD_PNEXT_EXT(props2, PCI_BUS_INFO_PROPERTIES_EXT, local_props.pci_bus_info, exts->EXT_pci_bus_info);
VN_ADD_PNEXT_EXT(props2, PROVOKING_VERTEX_PROPERTIES_EXT, local_props.provoking_vertex, exts->EXT_provoking_vertex);
VN_ADD_PNEXT_EXT(props2, ROBUSTNESS_2_PROPERTIES_EXT, local_props.robustness_2, exts->EXT_robustness2);
VN_ADD_PNEXT_EXT(props2, SAMPLE_LOCATIONS_PROPERTIES_EXT, local_props.sample_locations, exts->EXT_sample_locations);
VN_ADD_PNEXT_EXT(props2, TRANSFORM_FEEDBACK_PROPERTIES_EXT, local_props.transform_feedback, exts->EXT_transform_feedback);
VN_ADD_PNEXT_EXT(props2, VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT, local_props.vertex_attribute_divisor, exts->EXT_vertex_attribute_divisor);
@ -630,6 +632,7 @@ vn_physical_device_init_properties(struct vn_physical_device *physical_dev)
VN_SET_VK_PROPS_EXT(props, &local_props.pci_bus_info, exts->EXT_pci_bus_info);
VN_SET_VK_PROPS_EXT(props, &local_props.provoking_vertex, exts->EXT_provoking_vertex);
VN_SET_VK_PROPS_EXT(props, &local_props.robustness_2, exts->EXT_robustness2);
VN_SET_VK_PROPS_EXT(props, &local_props.sample_locations, exts->EXT_sample_locations);
VN_SET_VK_PROPS_EXT(props, &local_props.transform_feedback, exts->EXT_transform_feedback);
VN_SET_VK_PROPS_EXT(props, &local_props.vertex_attribute_divisor, exts->EXT_vertex_attribute_divisor);
@ -1121,6 +1124,7 @@ vn_physical_device_get_passthrough_extensions(
.EXT_queue_family_foreign = true,
.EXT_rasterization_order_attachment_access = true,
.EXT_robustness2 = true,
.EXT_sample_locations = true,
.EXT_shader_stencil_export = true,
.EXT_shader_subgroup_ballot = true,
.EXT_transform_feedback = true,
@ -2743,3 +2747,18 @@ vn_GetPhysicalDeviceFragmentShadingRatesKHR(
return vn_call_vkGetPhysicalDeviceFragmentShadingRatesKHR(
ring, physicalDevice, pFragmentShadingRateCount, pFragmentShadingRates);
}
void
vn_GetPhysicalDeviceMultisamplePropertiesEXT(
VkPhysicalDevice physicalDevice,
VkSampleCountFlagBits samples,
VkMultisamplePropertiesEXT *pMultisampleProperties)
{
struct vn_physical_device *physical_dev =
vn_physical_device_from_handle(physicalDevice);
struct vn_ring *ring = physical_dev->instance->ring.ring;
/* TODO per-device cache */
vn_call_vkGetPhysicalDeviceMultisamplePropertiesEXT(
ring, physicalDevice, samples, pMultisampleProperties);
}

View file

@ -65,6 +65,10 @@ struct vn_graphics_pipeline_info_self {
/** VkPipelineMultisampleStateCreateInfo::pSampleMask */
bool multisample_state_sample_mask : 1;
/** VkPipelineMultisampleStateCreateInfo::pNext
* VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsInfo
*/
bool multisample_state_sample_locations : 1;
};
};
};
@ -158,6 +162,10 @@ struct vn_graphics_dynamic_state {
bool scissor_with_count : 1;
/** VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE */
bool rasterizer_discard_enable : 1;
/** VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT */
bool sample_locations : 1;
/** VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT */
bool sample_locations_enable : 1;
};
};
};
@ -201,6 +209,14 @@ struct vn_graphics_pipeline_state {
* Valid if and only if gpl.pre_raster_shaders is set.
*/
bool rasterizer_discard_enable;
/** VkPipelineMultisampleStateCreateInfo::pNext
* - VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable
*
* Valid if and only if multisample_state is valid along with a valid
* sample location state chained in its pNext.
*/
bool sample_locations_enable;
};
struct vn_graphics_pipeline {
@ -216,6 +232,7 @@ struct vn_graphics_pipeline {
struct vn_graphics_pipeline_fix_tmp {
VkGraphicsPipelineCreateInfo *infos;
VkPipelineMultisampleStateCreateInfo *multisample_state_infos;
VkPipelineSampleLocationsStateCreateInfoEXT *sl_infos;
VkPipelineViewportStateCreateInfo *viewport_state_infos;
/* Fixing the pNext chain
@ -637,6 +654,7 @@ vn_graphics_pipeline_fix_tmp_alloc(const VkAllocationCallbacks *alloc,
struct vn_graphics_pipeline_fix_tmp *tmp;
VkGraphicsPipelineCreateInfo *infos;
VkPipelineMultisampleStateCreateInfo *multisample_state_infos;
VkPipelineSampleLocationsStateCreateInfoEXT *sl_infos;
VkPipelineViewportStateCreateInfo *viewport_state_infos;
/* for pNext */
@ -652,6 +670,7 @@ vn_graphics_pipeline_fix_tmp_alloc(const VkAllocationCallbacks *alloc,
vk_multialloc_add(&ma, &infos, __typeof__(*infos), info_count);
vk_multialloc_add(&ma, &multisample_state_infos,
__typeof__(*multisample_state_infos), info_count);
vk_multialloc_add(&ma, &sl_infos, __typeof__(*sl_infos), info_count);
vk_multialloc_add(&ma, &viewport_state_infos,
__typeof__(*viewport_state_infos), info_count);
@ -673,6 +692,7 @@ vn_graphics_pipeline_fix_tmp_alloc(const VkAllocationCallbacks *alloc,
tmp->infos = infos;
tmp->multisample_state_infos = multisample_state_infos;
tmp->sl_infos = sl_infos;
tmp->viewport_state_infos = viewport_state_infos;
if (alloc_pnext) {
@ -771,6 +791,12 @@ vn_graphics_dynamic_state_update(
case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE:
raw.rasterizer_discard_enable = true;
break;
case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
raw.sample_locations = true;
break;
case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT:
raw.sample_locations_enable = true;
break;
default:
break;
}
@ -805,9 +831,13 @@ vn_graphics_dynamic_state_update(
}
if (direct_gpl.fragment_shader) {
dynamic->sample_mask |= raw.sample_mask;
dynamic->sample_locations |= raw.sample_locations;
dynamic->sample_locations_enable |= raw.sample_locations_enable;
}
if (direct_gpl.fragment_output) {
dynamic->sample_mask |= raw.sample_mask;
dynamic->sample_locations |= raw.sample_locations;
dynamic->sample_locations_enable |= raw.sample_locations_enable;
}
}
@ -1038,6 +1068,13 @@ vn_graphics_pipeline_state_fill(
vk_find_struct_const(info->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
const uint32_t lib_count = lib_info ? lib_info->libraryCount : 0;
const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = NULL;
if (info->pMultisampleState) {
sl_info = vk_find_struct_const(
info->pMultisampleState->pNext,
PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT);
}
/* This tracks which fields have valid values in the
* VkGraphicsPipelineCreateInfo pNext chain.
*
@ -1193,6 +1230,25 @@ vn_graphics_pipeline_state_fill(
valid.self.multisample_state_sample_mask =
!state->dynamic.sample_mask;
/* If VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT is used, the static
* sampleLocationsInfo is ignored. Whether custom sample locations
* have been enabled depends on if
* VkPipelineSampleLocationsStateCreateInfoEXT has been chained and if
* VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable
* is VK_TRUE.
*
* If VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT is not used, the static
* sampleLocationsInfo validity depends on whether
* VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT dynamic state is used
* or the static sampleLocationsEnable is true.
*/
if (!state->dynamic.sample_locations) {
if (state->dynamic.sample_locations_enable)
valid.self.multisample_state_sample_locations = true;
else if (sl_info && sl_info->sampleLocationsEnable == VK_TRUE)
valid.self.multisample_state_sample_locations = true;
}
if (state->render_pass.attachment_aspects &
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
valid.self.depth_stencil_state = true;
@ -1302,6 +1358,10 @@ vn_graphics_pipeline_state_fill(
valid.self.multisample_state &&
info->pMultisampleState &&
info->pMultisampleState->pSampleMask,
.multisample_state_sample_locations =
!valid.self.multisample_state_sample_locations &&
valid.self.multisample_state &&
sl_info && sl_info->sampleLocationsInfo.sampleLocationsCount,
.depth_stencil_state =
!valid.self.depth_stencil_state &&
info->pDepthStencilState,
@ -1331,6 +1391,37 @@ vn_graphics_pipeline_state_fill(
};
}
static void
vn_multisample_info_pnext_init(
const VkPipelineMultisampleStateCreateInfo *info,
struct vn_graphics_pipeline_fix_tmp *fix_tmp,
uint32_t index)
{
VkPipelineSampleLocationsStateCreateInfoEXT *sl =
&fix_tmp->sl_infos[index];
VkBaseOutStructure *cur = (void *)&fix_tmp->infos[index].pMultisampleState;
vk_foreach_struct_const(src, info->pNext) {
void *next = NULL;
switch (src->sType) {
case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT:
memcpy(sl, src, sizeof(*sl));
next = sl;
break;
default:
break;
}
if (next) {
cur->pNext = next;
cur = next;
}
}
cur->pNext = NULL;
}
static void
vn_fix_graphics_pipeline_create_info_self(
const struct vn_graphics_pipeline_info_self *ignore,
@ -1365,13 +1456,22 @@ vn_fix_graphics_pipeline_create_info_self(
fix_tmp->infos[index].basePipelineHandle = VK_NULL_HANDLE;
/* VkPipelineMultisampleStateCreateInfo */
if (ignore->multisample_state_sample_mask) {
if (ignore->multisample_state_sample_mask ||
ignore->multisample_state_sample_locations) {
/* Swap original pMultisampleState with temporary state. */
fix_tmp->multisample_state_infos[index] = *info->pMultisampleState;
fix_tmp->infos[index].pMultisampleState =
&fix_tmp->multisample_state_infos[index];
fix_tmp->multisample_state_infos[index].pSampleMask = NULL;
if (ignore->multisample_state_sample_mask)
fix_tmp->multisample_state_infos[index].pSampleMask = NULL;
if (ignore->multisample_state_sample_locations) {
/* initialize pNext chain with allocated tmp storage */
vn_multisample_info_pnext_init(info->pMultisampleState, fix_tmp,
index);
fix_tmp->sl_infos[index].sampleLocationsInfo.sampleLocationsCount =
0;
}
}
/* VkPipelineViewportStateCreateInfo */