From 8d440ece643ceea1007a8f08a873a3565e789c79 Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Thu, 9 May 2024 18:40:05 +0100 Subject: [PATCH] pvr: add shader compilation stubs Signed-off-by: Simon Perretta Acked-by: Frank Binns Part-of: --- src/imagination/vulkan/meson.build | 1 + src/imagination/vulkan/pvr_nir.c | 24 ++++++++++ src/imagination/vulkan/pvr_nir.h | 18 ++++++++ src/imagination/vulkan/pvr_pipeline.c | 65 ++++++++++++++++++++++++++- src/imagination/vulkan/pvr_private.h | 2 +- 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 src/imagination/vulkan/pvr_nir.c create mode 100644 src/imagination/vulkan/pvr_nir.h diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index 2e418a0aa2a..97073f0fe51 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -43,6 +43,7 @@ pvr_files = files( 'pvr_job_context.c', 'pvr_job_render.c', 'pvr_job_transfer.c', + 'pvr_nir.c', 'pvr_pass.c', 'pvr_pipeline.c', 'pvr_transfer_frag_store.c', diff --git a/src/imagination/vulkan/pvr_nir.c b/src/imagination/vulkan/pvr_nir.c new file mode 100644 index 00000000000..4cd16d247e8 --- /dev/null +++ b/src/imagination/vulkan/pvr_nir.c @@ -0,0 +1,24 @@ +/* + * Copyright © 2024 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: MIT + */ + +#include "pvr_nir.h" +#include "util/macros.h" + +#include + +/** + * \brief Performs Vulkan-specific lowering on a NIR shader. + * + * \param[in] ctx PCO compiler context. + * \param[in] layout Graphics/compute pipeline layout. + * \param[in,out] nir NIR shader. + */ +void pvr_lower_nir(pco_ctx *ctx, + struct pvr_pipeline_layout *layout, + nir_shader *nir) +{ + puts("finishme: pvr_lower_nir"); +} diff --git a/src/imagination/vulkan/pvr_nir.h b/src/imagination/vulkan/pvr_nir.h new file mode 100644 index 00000000000..993da5725e6 --- /dev/null +++ b/src/imagination/vulkan/pvr_nir.h @@ -0,0 +1,18 @@ +/* + * Copyright © 2024 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef PVR_NIR_H +#define PVR_NIR_H + +#include "nir/nir.h" +#include "pco/pco.h" +#include "pvr_private.h" + +void pvr_lower_nir(pco_ctx *ctx, + struct pvr_pipeline_layout *layout, + nir_shader *nir); + +#endif /* PVR_NIR_H */ diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index fb9b4651b78..4dfa9210fb4 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -38,6 +38,7 @@ #include "pvr_csb.h" #include "pvr_csb_enum_helpers.h" #include "pvr_hardcode.h" +#include "pvr_nir.h" #include "pvr_pds.h" #include "pvr_private.h" #include "pvr_robustness.h" @@ -1641,9 +1642,19 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device, const uint32_t cache_line_size = rogue_get_slc_cache_line_size(&device->pdevice->dev_info); struct rogue_compiler *compiler = device->pdevice->compiler; - struct rogue_build_ctx *ctx; + struct rogue_build_ctx *ctx = NULL; VkResult result; + pco_ctx *pco_ctx = device->pdevice->pco_ctx; + const struct spirv_to_nir_options *spirv_options = + pco_spirv_options(pco_ctx); + const nir_shader_compiler_options *nir_options = pco_nir_options(pco_ctx); + + nir_shader *producer = NULL; + nir_shader *nir_shaders[MESA_SHADER_STAGES] = { 0 }; + pco_shader *pco_shaders[MESA_SHADER_STAGES] = { 0 }; + void *shader_mem_ctx = ralloc_context(NULL); + /* Vars needed for the new path. */ struct pvr_pds_vertex_dma vtx_dma_descriptions[PVR_MAX_VERTEX_ATTRIB_DMAS]; uint32_t vtx_dma_count = 0; @@ -1657,6 +1668,56 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device, uint32_t sh_count[PVR_STAGE_ALLOCATION_COUNT] = { 0 }; + for (gl_shader_stage stage = 0; stage < MESA_SHADER_STAGES; ++stage) { + nir_shader **nir = &nir_shaders[stage]; + size_t stage_index = gfx_pipeline->stage_indices[stage]; + const VkPipelineShaderStageCreateInfo *create_info = + &pCreateInfo->pStages[stage_index]; + + /* Skip unused/inactive stages. */ + if (stage_index == ~0) + continue; + + result = vk_pipeline_shader_stage_to_nir(&device->vk, + 0, + create_info, + spirv_options, + nir_options, + shader_mem_ctx, + nir); + if (result != VK_SUCCESS) + goto err_free_build_context; + + pco_preprocess_nir(pco_ctx, *nir); + if (producer) + pco_link_nir(pco_ctx, producer, *nir); + + pco_lower_nir(pco_ctx, *nir); + pvr_lower_nir(pco_ctx, layout, *nir); + + pco_postprocess_nir(pco_ctx, *nir); + + producer = *nir; + } + + for (gl_shader_stage stage = 0; stage < MESA_SHADER_STAGES; ++stage) { + pco_shader **pco = &pco_shaders[stage]; + + /* Skip unused/inactive stages. */ + if (!nir_shaders[stage]) + continue; + + *pco = pco_trans_nir(pco_ctx, nir_shaders[stage], shader_mem_ctx); + if (!*pco) { + result = VK_ERROR_INITIALIZATION_FAILED; + goto err_free_build_context; + } + + pco_process_ir(pco_ctx, *pco); + pco_encode_ir(pco_ctx, *pco); + pco_shader_finalize(pco_ctx, *pco); + } + /* Setup shared build context. */ ctx = rogue_build_context_create(compiler, layout); if (!ctx) @@ -1852,6 +1913,7 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device, /* assert(pvr_pds_descriptor_program_variables.temp_buff_total_size == 0); */ /* TODO: Implement spilling with the above. */ + ralloc_free(shader_mem_ctx); ralloc_free(ctx); return VK_SUCCESS; @@ -1882,6 +1944,7 @@ err_free_vertex_bo: pvr_bo_suballoc_free(gfx_pipeline->shader_state.vertex.bo); err_free_build_context: ralloc_free(ctx); + ralloc_free(shader_mem_ctx); return result; } diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index aaccee5aeea..5fd414758de 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -963,7 +963,7 @@ struct pvr_graphics_pipeline { struct vk_dynamic_graphics_state dynamic_state; /* Derived and other state */ - size_t stage_indices[MESA_SHADER_FRAGMENT + 1]; + size_t stage_indices[MESA_SHADER_STAGES]; struct { struct pvr_vertex_shader_state vertex;