anv: implement mesh shader queries
Mesh shader queries include mesh-primitives-generated count and task/mesh shader pipeline statistics. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29523>
This commit is contained in:
@@ -697,7 +697,7 @@ get_features(const struct anv_physical_device *pdevice,
|
|||||||
.meshShader = mesh_shader,
|
.meshShader = mesh_shader,
|
||||||
.multiviewMeshShader = false,
|
.multiviewMeshShader = false,
|
||||||
.primitiveFragmentShadingRateMeshShader = mesh_shader,
|
.primitiveFragmentShadingRateMeshShader = mesh_shader,
|
||||||
.meshShaderQueries = false,
|
.meshShaderQueries = true,
|
||||||
|
|
||||||
/* VK_EXT_mutable_descriptor_type */
|
/* VK_EXT_mutable_descriptor_type */
|
||||||
.mutableDescriptorType = true,
|
.mutableDescriptorType = true,
|
||||||
|
|||||||
@@ -1771,6 +1771,7 @@ emit_task_state(struct anv_graphics_pipeline *pipeline)
|
|||||||
anv_pipeline_emit(pipeline, final.task_control,
|
anv_pipeline_emit(pipeline, final.task_control,
|
||||||
GENX(3DSTATE_TASK_CONTROL), tc) {
|
GENX(3DSTATE_TASK_CONTROL), tc) {
|
||||||
tc.TaskShaderEnable = true;
|
tc.TaskShaderEnable = true;
|
||||||
|
tc.StatisticsEnable = true;
|
||||||
tc.ScratchSpaceBuffer =
|
tc.ScratchSpaceBuffer =
|
||||||
get_scratch_surf(&pipeline->base.base, MESA_SHADER_TASK, task_bin);
|
get_scratch_surf(&pipeline->base.base, MESA_SHADER_TASK, task_bin);
|
||||||
tc.MaximumNumberofThreadGroups = 511;
|
tc.MaximumNumberofThreadGroups = 511;
|
||||||
@@ -1831,6 +1832,7 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline)
|
|||||||
anv_pipeline_emit(pipeline, final.mesh_control,
|
anv_pipeline_emit(pipeline, final.mesh_control,
|
||||||
GENX(3DSTATE_MESH_CONTROL), mc) {
|
GENX(3DSTATE_MESH_CONTROL), mc) {
|
||||||
mc.MeshShaderEnable = true;
|
mc.MeshShaderEnable = true;
|
||||||
|
mc.StatisticsEnable = true;
|
||||||
mc.ScratchSpaceBuffer =
|
mc.ScratchSpaceBuffer =
|
||||||
get_scratch_surf(&pipeline->base.base, MESA_SHADER_MESH, mesh_bin);
|
get_scratch_surf(&pipeline->base.base, MESA_SHADER_MESH, mesh_bin);
|
||||||
mc.MaximumNumberofThreadGroups = 511;
|
mc.MaximumNumberofThreadGroups = 511;
|
||||||
|
|||||||
@@ -193,6 +193,11 @@ VkResult genX(CreateQueryPool)(
|
|||||||
uint64s_per_slot = 1 + 2 /* availability + size (PostbuildInfoSerializationDesc) */;
|
uint64s_per_slot = 1 + 2 /* availability + size (PostbuildInfoSerializationDesc) */;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
/* Query has two values: begin and end. */
|
||||||
|
uint64s_per_slot = 1 + 2;
|
||||||
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
case VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR:
|
case VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR:
|
||||||
uint64s_per_slot = 1;
|
uint64s_per_slot = 1;
|
||||||
@@ -491,6 +496,7 @@ VkResult genX(GetQueryPoolResults)(
|
|||||||
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR ||
|
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR ||
|
||||||
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR ||
|
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR ||
|
||||||
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR ||
|
pool->vk.query_type == VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR ||
|
||||||
|
pool->vk.query_type == VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT ||
|
||||||
#endif
|
#endif
|
||||||
pool->vk.query_type == VK_QUERY_TYPE_OCCLUSION ||
|
pool->vk.query_type == VK_QUERY_TYPE_OCCLUSION ||
|
||||||
pool->vk.query_type == VK_QUERY_TYPE_PIPELINE_STATISTICS ||
|
pool->vk.query_type == VK_QUERY_TYPE_PIPELINE_STATISTICS ||
|
||||||
@@ -542,7 +548,11 @@ VkResult genX(GetQueryPoolResults)(
|
|||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
switch (pool->vk.query_type) {
|
switch (pool->vk.query_type) {
|
||||||
case VK_QUERY_TYPE_OCCLUSION:
|
case VK_QUERY_TYPE_OCCLUSION:
|
||||||
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT: {
|
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#endif
|
||||||
|
{
|
||||||
uint64_t *slot = query_slot(pool, firstQuery + i);
|
uint64_t *slot = query_slot(pool, firstQuery + i);
|
||||||
if (write_results) {
|
if (write_results) {
|
||||||
/* From the Vulkan 1.2.132 spec:
|
/* From the Vulkan 1.2.132 spec:
|
||||||
@@ -751,6 +761,9 @@ emit_zero_queries(struct anv_cmd_buffer *cmd_buffer,
|
|||||||
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
||||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
||||||
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
|
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#endif
|
||||||
for (uint32_t i = 0; i < num_queries; i++) {
|
for (uint32_t i = 0; i < num_queries; i++) {
|
||||||
struct anv_address slot_addr =
|
struct anv_address slot_addr =
|
||||||
anv_query_address(pool, first_index + i);
|
anv_query_address(pool, first_index + i);
|
||||||
@@ -858,7 +871,11 @@ void genX(CmdResetQueryPool)(
|
|||||||
|
|
||||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
||||||
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
|
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
|
||||||
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT: {
|
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#endif
|
||||||
|
{
|
||||||
struct mi_builder b;
|
struct mi_builder b;
|
||||||
mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
|
mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
|
||||||
|
|
||||||
@@ -1060,6 +1077,18 @@ void genX(CmdBeginQueryIndexedEXT)(
|
|||||||
mi_reg64(GENX(CL_INVOCATION_COUNT_num)));
|
mi_reg64(GENX(CL_INVOCATION_COUNT_num)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
||||||
|
cmd_buffer->device->info,
|
||||||
|
cmd_buffer->state.current_pipeline,
|
||||||
|
ANV_PIPE_CS_STALL_BIT |
|
||||||
|
ANV_PIPE_STALL_AT_SCOREBOARD_BIT);
|
||||||
|
mi_store(&b, mi_mem64(anv_address_add(query_addr, 8)),
|
||||||
|
mi_reg64(GENX(MESH_PRIMITIVE_COUNT_num)));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS: {
|
case VK_QUERY_TYPE_PIPELINE_STATISTICS: {
|
||||||
/* TODO: This might only be necessary for certain stats */
|
/* TODO: This might only be necessary for certain stats */
|
||||||
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
||||||
@@ -1254,6 +1283,19 @@ void genX(CmdEndQueryIndexedEXT)(
|
|||||||
emit_query_mi_availability(&b, query_addr, true);
|
emit_query_mi_availability(&b, query_addr, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
||||||
|
cmd_buffer->device->info,
|
||||||
|
cmd_buffer->state.current_pipeline,
|
||||||
|
ANV_PIPE_CS_STALL_BIT |
|
||||||
|
ANV_PIPE_STALL_AT_SCOREBOARD_BIT);
|
||||||
|
mi_store(&b, mi_mem64(anv_address_add(query_addr, 16)),
|
||||||
|
mi_reg64(GENX(MESH_PRIMITIVE_COUNT_num)));
|
||||||
|
emit_query_mi_availability(&b, query_addr, true);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS: {
|
case VK_QUERY_TYPE_PIPELINE_STATISTICS: {
|
||||||
/* TODO: This might only be necessary for certain stats */
|
/* TODO: This might only be necessary for certain stats */
|
||||||
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
genx_batch_emit_pipe_control(&cmd_buffer->batch,
|
||||||
@@ -1616,6 +1658,9 @@ copy_query_results_with_cs(struct anv_cmd_buffer *cmd_buffer,
|
|||||||
switch (pool->vk.query_type) {
|
switch (pool->vk.query_type) {
|
||||||
case VK_QUERY_TYPE_OCCLUSION:
|
case VK_QUERY_TYPE_OCCLUSION:
|
||||||
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#endif
|
||||||
result = compute_query_result(&b, anv_address_add(query_addr, 8));
|
result = compute_query_result(&b, anv_address_add(query_addr, 8));
|
||||||
/* Like in the case of vkGetQueryPoolResults, if the query is
|
/* Like in the case of vkGetQueryPoolResults, if the query is
|
||||||
* unavailable and the VK_QUERY_RESULT_PARTIAL_BIT flag is set,
|
* unavailable and the VK_QUERY_RESULT_PARTIAL_BIT flag is set,
|
||||||
@@ -1812,6 +1857,9 @@ copy_query_results_with_shader(struct anv_cmd_buffer *cmd_buffer,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#if GFX_VERx10 >= 125
|
||||||
|
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
|
||||||
|
#endif
|
||||||
copy_flags |= ANV_COPY_QUERY_FLAG_DELTA;
|
copy_flags |= ANV_COPY_QUERY_FLAG_DELTA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user