mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
pvr: Add support for VK_KHR_pipeline_executable_properties
This adds support for receiving additional statistics about PowerVR shaders for the Rogue architecture. vkGetPipelineExecutablePropertiesKHR and vkGetPipelineExecutableStatisticsKHR are fully supported. vkGetPipelineExecutableInternalRepresentationsKHR does not currently return any internal representations. Tests used: dEQP-VK.pipeline.monolithic.executable_properties.* Signed-off-by: Duncan Brawley <duncan.brawley@imgtec.com> Reviewed-by: Simon Perretta <simon.perretta@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39607>
This commit is contained in:
parent
693a3e1c50
commit
dfddb3fef1
5 changed files with 217 additions and 1 deletions
|
|
@ -563,7 +563,7 @@ Khronos extensions that are not part of any Vulkan version:
|
||||||
VK_KHR_maintenance10 DONE (anv, nvk, radv)
|
VK_KHR_maintenance10 DONE (anv, nvk, radv)
|
||||||
VK_KHR_performance_query DONE (anv, radv/gfx10.3+, tu, v3dv)
|
VK_KHR_performance_query DONE (anv, radv/gfx10.3+, tu, v3dv)
|
||||||
VK_KHR_pipeline_binary DONE (anv, hk, nvk, panvk, radv)
|
VK_KHR_pipeline_binary DONE (anv, hk, nvk, panvk, radv)
|
||||||
VK_KHR_pipeline_executable_properties DONE (anv, hk, nvk, panvk, hasvk, radv, tu, v3dv)
|
VK_KHR_pipeline_executable_properties DONE (anv, hasvk, hk, nvk, panvk, pvr, radv, tu, v3dv)
|
||||||
VK_KHR_pipeline_library DONE (anv, hk, lvp, nvk, panvk, radv, tu, vn)
|
VK_KHR_pipeline_library DONE (anv, hk, lvp, nvk, panvk, radv, tu, vn)
|
||||||
VK_KHR_present_id DONE (anv, hk, nvk, panvk, radv, tu, vn)
|
VK_KHR_present_id DONE (anv, hk, nvk, panvk, radv, tu, vn)
|
||||||
VK_KHR_present_id2 DONE (anv, hk, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
VK_KHR_present_id2 DONE (anv, hk, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@ VK_KHR_get_display_properties2 on panvk
|
||||||
VK_EXT_acquire_drm_display on panvk
|
VK_EXT_acquire_drm_display on panvk
|
||||||
VK_KHR_present_id on panvk
|
VK_KHR_present_id on panvk
|
||||||
VK_KHR_present_wait on panvk
|
VK_KHR_present_wait on panvk
|
||||||
|
VK_KHR_pipeline_executable_properties on pvr
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
#include "util/ralloc.h"
|
#include "util/ralloc.h"
|
||||||
|
#include "util/shader_stats.h"
|
||||||
#include "util/u_dynarray.h"
|
#include "util/u_dynarray.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
#include "vk_alloc.h"
|
#include "vk_alloc.h"
|
||||||
|
|
@ -1044,6 +1045,21 @@ static VkResult pvr_compute_pipeline_compile(
|
||||||
|
|
||||||
pvr_compute_state_save(compute_pipeline, cs);
|
pvr_compute_state_save(compute_pipeline, cs);
|
||||||
|
|
||||||
|
if (pCreateInfo->flags & VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR) {
|
||||||
|
struct pvr_stats stats = pco_get_pvr_stats(cs);
|
||||||
|
compute_pipeline->cs_stats =
|
||||||
|
vk_zalloc2(&device->vk.alloc,
|
||||||
|
allocator,
|
||||||
|
sizeof(stats),
|
||||||
|
8,
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
|
|
||||||
|
if (!compute_pipeline->cs_stats)
|
||||||
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
|
memcpy(compute_pipeline->cs_stats, &stats, sizeof(stats));
|
||||||
|
}
|
||||||
|
|
||||||
result = pvr_gpu_upload_usc(device,
|
result = pvr_gpu_upload_usc(device,
|
||||||
pco_shader_binary_data(cs),
|
pco_shader_binary_data(cs),
|
||||||
pco_shader_binary_size(cs),
|
pco_shader_binary_size(cs),
|
||||||
|
|
@ -1191,6 +1207,8 @@ static void pvr_compute_pipeline_destroy(
|
||||||
|
|
||||||
pvr_pipeline_finish(device, &compute_pipeline->base);
|
pvr_pipeline_finish(device, &compute_pipeline->base);
|
||||||
|
|
||||||
|
vk_free2(&device->vk.alloc, allocator, compute_pipeline->cs_stats);
|
||||||
|
|
||||||
vk_free2(&device->vk.alloc, allocator, compute_pipeline);
|
vk_free2(&device->vk.alloc, allocator, compute_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1275,6 +1293,9 @@ pvr_graphics_pipeline_destroy(struct pvr_device *const device,
|
||||||
pvr_pipeline_destroy_shader_data(&gfx_pipeline->vs_data);
|
pvr_pipeline_destroy_shader_data(&gfx_pipeline->vs_data);
|
||||||
pvr_pipeline_destroy_shader_data(&gfx_pipeline->fs_data);
|
pvr_pipeline_destroy_shader_data(&gfx_pipeline->fs_data);
|
||||||
|
|
||||||
|
vk_free2(&device->vk.alloc, allocator, gfx_pipeline->vs_stats);
|
||||||
|
vk_free2(&device->vk.alloc, allocator, gfx_pipeline->fs_stats);
|
||||||
|
|
||||||
vk_free2(&device->vk.alloc, allocator, gfx_pipeline);
|
vk_free2(&device->vk.alloc, allocator, gfx_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2913,6 +2934,20 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
||||||
|
|
||||||
pvr_vertex_state_save(gfx_pipeline, *vs);
|
pvr_vertex_state_save(gfx_pipeline, *vs);
|
||||||
|
|
||||||
|
if (pCreateInfo->flags & VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR) {
|
||||||
|
struct pvr_stats stats = pco_get_pvr_stats(*vs);
|
||||||
|
gfx_pipeline->vs_stats = vk_zalloc2(&device->vk.alloc,
|
||||||
|
allocator,
|
||||||
|
sizeof(stats),
|
||||||
|
8,
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
|
|
||||||
|
if (!gfx_pipeline->vs_stats)
|
||||||
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
|
memcpy(gfx_pipeline->vs_stats, &stats, sizeof(stats));
|
||||||
|
}
|
||||||
|
|
||||||
pvr_graphics_pipeline_setup_vertex_dma(gfx_pipeline,
|
pvr_graphics_pipeline_setup_vertex_dma(gfx_pipeline,
|
||||||
pCreateInfo->pVertexInputState,
|
pCreateInfo->pVertexInputState,
|
||||||
state->vi,
|
state->vi,
|
||||||
|
|
@ -2930,6 +2965,20 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
||||||
if (*fs) {
|
if (*fs) {
|
||||||
pvr_fragment_state_save(gfx_pipeline, *fs);
|
pvr_fragment_state_save(gfx_pipeline, *fs);
|
||||||
|
|
||||||
|
if (pCreateInfo->flags & VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR) {
|
||||||
|
struct pvr_stats stats = pco_get_pvr_stats(*fs);
|
||||||
|
gfx_pipeline->fs_stats = vk_zalloc2(&device->vk.alloc,
|
||||||
|
allocator,
|
||||||
|
sizeof(stats),
|
||||||
|
8,
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
|
|
||||||
|
if (!gfx_pipeline->fs_stats)
|
||||||
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
|
memcpy(gfx_pipeline->fs_stats, &stats, sizeof(stats));
|
||||||
|
}
|
||||||
|
|
||||||
pvr_graphics_pipeline_setup_fragment_coeff_program(
|
pvr_graphics_pipeline_setup_fragment_coeff_program(
|
||||||
gfx_pipeline,
|
gfx_pipeline,
|
||||||
nir_shaders[MESA_SHADER_FRAGMENT]);
|
nir_shaders[MESA_SHADER_FRAGMENT]);
|
||||||
|
|
@ -3303,3 +3352,157 @@ void PVR_PER_ARCH(DestroyPipeline)(VkDevice _device,
|
||||||
UNREACHABLE("Unknown pipeline type.");
|
UNREACHABLE("Unknown pipeline type.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t pvr_get_executable_count(struct pvr_pipeline *pipeline)
|
||||||
|
{
|
||||||
|
uint32_t exe_count = 0;
|
||||||
|
|
||||||
|
switch (pipeline->type) {
|
||||||
|
case PVR_PIPELINE_TYPE_GRAPHICS: {
|
||||||
|
struct pvr_graphics_pipeline *const gfx_pipeline =
|
||||||
|
to_pvr_graphics_pipeline(pipeline);
|
||||||
|
|
||||||
|
for (mesa_shader_stage stage = 0; stage < MESA_SHADER_STAGES; ++stage) {
|
||||||
|
size_t stage_index = gfx_pipeline->stage_indices[stage];
|
||||||
|
|
||||||
|
if (stage_index != ~0)
|
||||||
|
exe_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PVR_PIPELINE_TYPE_COMPUTE: {
|
||||||
|
/* Compute pipelines always only have one executable. */
|
||||||
|
exe_count = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE("Unknown pipeline type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return exe_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult pvr_GetPipelineExecutableStatisticsKHR(
|
||||||
|
UNUSED VkDevice _device,
|
||||||
|
const VkPipelineExecutableInfoKHR *pExecutableInfo,
|
||||||
|
uint32_t *pStatisticCount,
|
||||||
|
VkPipelineExecutableStatisticKHR *pStatistics)
|
||||||
|
{
|
||||||
|
VK_FROM_HANDLE(pvr_pipeline, pipeline, pExecutableInfo->pipeline);
|
||||||
|
VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableStatisticKHR,
|
||||||
|
out,
|
||||||
|
pStatistics,
|
||||||
|
pStatisticCount);
|
||||||
|
|
||||||
|
switch (pipeline->type) {
|
||||||
|
case PVR_PIPELINE_TYPE_GRAPHICS: {
|
||||||
|
struct pvr_graphics_pipeline *const gfx_pipeline =
|
||||||
|
to_pvr_graphics_pipeline(pipeline);
|
||||||
|
|
||||||
|
if (pExecutableInfo->executableIndex == 0) {
|
||||||
|
vk_add_pvr_stats(out, gfx_pipeline->vs_stats);
|
||||||
|
} else {
|
||||||
|
assert(pExecutableInfo->executableIndex == 1);
|
||||||
|
vk_add_pvr_stats(out, gfx_pipeline->fs_stats);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PVR_PIPELINE_TYPE_COMPUTE: {
|
||||||
|
struct pvr_compute_pipeline *const compute_pipeline =
|
||||||
|
to_pvr_compute_pipeline(pipeline);
|
||||||
|
|
||||||
|
assert(pExecutableInfo->executableIndex == 0);
|
||||||
|
vk_add_pvr_stats(out, compute_pipeline->cs_stats);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE("Unknown pipeline type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return vk_outarray_status(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult pvr_GetPipelineExecutablePropertiesKHR(
|
||||||
|
VkDevice _device,
|
||||||
|
const VkPipelineInfoKHR *pPipelineInfo,
|
||||||
|
uint32_t *pExecutableCount,
|
||||||
|
VkPipelineExecutablePropertiesKHR *pProperties)
|
||||||
|
{
|
||||||
|
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||||
|
VK_FROM_HANDLE(pvr_pipeline, pipeline, pPipelineInfo->pipeline);
|
||||||
|
ASSERTED uint32_t actualExeCount = pvr_get_executable_count(pipeline);
|
||||||
|
|
||||||
|
/* Due to individual shaders currently being stored as individual members
|
||||||
|
* of pvr_graphics_pipeline, if support is added for a new shader stage,
|
||||||
|
* this code will need to be updated.
|
||||||
|
*/
|
||||||
|
assert(actualExeCount >= 1 && actualExeCount <= 2);
|
||||||
|
|
||||||
|
VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutablePropertiesKHR,
|
||||||
|
out,
|
||||||
|
pProperties,
|
||||||
|
pExecutableCount);
|
||||||
|
|
||||||
|
switch (pipeline->type) {
|
||||||
|
case PVR_PIPELINE_TYPE_GRAPHICS: {
|
||||||
|
struct pvr_graphics_pipeline *const gfx_pipeline =
|
||||||
|
to_pvr_graphics_pipeline(pipeline);
|
||||||
|
|
||||||
|
vk_outarray_append_typed (VkPipelineExecutablePropertiesKHR,
|
||||||
|
&out,
|
||||||
|
vertProps) {
|
||||||
|
vertProps->stages |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
VK_COPY_STR(vertProps->name, "vertex");
|
||||||
|
VK_COPY_STR(vertProps->description, "Vulkan Vertex Shader");
|
||||||
|
vertProps->subgroupSize = device->pdevice->vk.properties.subgroupSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gfx_pipeline->stage_indices[MESA_SHADER_FRAGMENT] != ~0) {
|
||||||
|
vk_outarray_append_typed (VkPipelineExecutablePropertiesKHR,
|
||||||
|
&out,
|
||||||
|
fragProps) {
|
||||||
|
fragProps->stages |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
VK_COPY_STR(fragProps->name, "fragment");
|
||||||
|
VK_COPY_STR(fragProps->description, "Vulkan Fragment Shader");
|
||||||
|
fragProps->subgroupSize =
|
||||||
|
device->pdevice->vk.properties.subgroupSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PVR_PIPELINE_TYPE_COMPUTE: {
|
||||||
|
vk_outarray_append_typed (VkPipelineExecutablePropertiesKHR,
|
||||||
|
&out,
|
||||||
|
compProps) {
|
||||||
|
compProps->stages = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
|
VK_COPY_STR(compProps->name, "compute");
|
||||||
|
VK_COPY_STR(compProps->description, "Vulkan Compute Shader");
|
||||||
|
compProps->subgroupSize = device->pdevice->vk.properties.subgroupSize;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE("Unknown pipeline type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return vk_outarray_status(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult pvr_GetPipelineExecutableInternalRepresentationsKHR(
|
||||||
|
UNUSED VkDevice _device,
|
||||||
|
UNUSED const VkPipelineExecutableInfoKHR *pExecutableInfo,
|
||||||
|
uint32_t *pInternalRepresentationCount,
|
||||||
|
UNUSED VkPipelineExecutableInternalRepresentationKHR
|
||||||
|
*pInternalRepresentations)
|
||||||
|
{
|
||||||
|
pvr_finishme("Add support for requesting intermediate representations.");
|
||||||
|
*pInternalRepresentationCount = 0;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ static void pvr_physical_device_get_supported_extensions(
|
||||||
.KHR_maintenance3 = true,
|
.KHR_maintenance3 = true,
|
||||||
.KHR_map_memory2 = true,
|
.KHR_map_memory2 = true,
|
||||||
.KHR_multiview = true,
|
.KHR_multiview = true,
|
||||||
|
.KHR_pipeline_executable_properties = true,
|
||||||
.KHR_present_id2 = PVR_USE_WSI_PLATFORM,
|
.KHR_present_id2 = PVR_USE_WSI_PLATFORM,
|
||||||
.KHR_present_wait2 = PVR_USE_WSI_PLATFORM,
|
.KHR_present_wait2 = PVR_USE_WSI_PLATFORM,
|
||||||
.KHR_relaxed_block_layout = true,
|
.KHR_relaxed_block_layout = true,
|
||||||
|
|
@ -468,6 +469,9 @@ static void pvr_physical_device_get_supported_features(
|
||||||
|
|
||||||
/* Vulkan 1.2 / VK_KHR_dynamic_rendering */
|
/* Vulkan 1.2 / VK_KHR_dynamic_rendering */
|
||||||
.dynamicRendering = true,
|
.dynamicRendering = true,
|
||||||
|
|
||||||
|
/* VK_KHR_pipeline_executable_properties */
|
||||||
|
.pipelineExecutableInfo = true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "pvr_common.h"
|
#include "pvr_common.h"
|
||||||
#include "pvr_csb.h"
|
#include "pvr_csb.h"
|
||||||
#include "pvr_pds.h"
|
#include "pvr_pds.h"
|
||||||
|
#include "util/shader_stats.h"
|
||||||
|
|
||||||
struct pvr_suballoc_bo;
|
struct pvr_suballoc_bo;
|
||||||
|
|
||||||
|
|
@ -109,6 +110,9 @@ struct pvr_compute_pipeline {
|
||||||
uint32_t num_workgroups_data_patching_offset;
|
uint32_t num_workgroups_data_patching_offset;
|
||||||
uint32_t num_workgroups_indirect_src_patching_offset;
|
uint32_t num_workgroups_indirect_src_patching_offset;
|
||||||
uint32_t num_workgroups_indirect_src_dma_patching_offset;
|
uint32_t num_workgroups_indirect_src_dma_patching_offset;
|
||||||
|
|
||||||
|
/* Debug Info */
|
||||||
|
struct pvr_stats *cs_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pvr_graphics_pipeline {
|
struct pvr_graphics_pipeline {
|
||||||
|
|
@ -126,6 +130,10 @@ struct pvr_graphics_pipeline {
|
||||||
struct pvr_vertex_shader_state vertex;
|
struct pvr_vertex_shader_state vertex;
|
||||||
struct pvr_fragment_shader_state fragment;
|
struct pvr_fragment_shader_state fragment;
|
||||||
} shader_state;
|
} shader_state;
|
||||||
|
|
||||||
|
/* Debug Info */
|
||||||
|
struct pvr_stats *vs_stats;
|
||||||
|
struct pvr_stats *fs_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pvr_private_compute_pipeline {
|
struct pvr_private_compute_pipeline {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue