From 91c86c31cd3f15c01bdf7290aca5e233093da63e Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 23 Sep 2024 16:37:38 +0200 Subject: [PATCH] panvk: Add an helper to create internal shaders Blend and framebuffer preload shaders will be created as internal shaders and added to the vk_meta object list. Signed-off-by: Boris Brezillon Reviewed-by: Mary Guillemard Part-of: --- src/panfrost/vulkan/panvk_shader.h | 28 +++++++++++++ src/panfrost/vulkan/panvk_vX_shader.c | 60 +++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/src/panfrost/vulkan/panvk_shader.h b/src/panfrost/vulkan/panvk_shader.h index e9bd75de30a..64865f7327f 100644 --- a/src/panfrost/vulkan/panvk_shader.h +++ b/src/panfrost/vulkan/panvk_shader.h @@ -199,4 +199,32 @@ bool panvk_per_arch(nir_lower_descriptors)( struct vk_descriptor_set_layout *const *set_layouts, struct panvk_shader *shader); +enum panvk_internal_shader_type { + PANVK_INTERNAL_SHADER_BLEND, + PANVK_INTERNAL_SHADER_FB_PRELOAD, +}; + +/* This a stripped-down version of panvk_shader for internal shaders that + * are managed by vk_meta (blend and preload shaders). Those don't need the + * complexity inherent to user provided shaders as they're not exposed. */ +struct panvk_internal_shader { + struct vk_shader vk; + struct pan_shader_info info; + struct panvk_priv_mem code_mem; + +#if PAN_ARCH <= 7 + struct panvk_priv_mem rsd; +#else + struct panvk_priv_mem spd; +#endif +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_internal_shader, vk.base, VkShaderEXT, + VK_OBJECT_TYPE_SHADER_EXT) + +VkResult panvk_per_arch(create_internal_shader)( + struct panvk_device *dev, nir_shader *nir, + struct panfrost_compile_inputs *compiler_inputs, + struct panvk_internal_shader **shader_out); + #endif diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 0dc33be0c6f..36b66d07202 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -1445,3 +1445,63 @@ const struct vk_device_shader_ops panvk_per_arch(device_shader_ops) = { .cmd_set_dynamic_graphics_state = vk_cmd_set_dynamic_graphics_state, .cmd_bind_shaders = panvk_cmd_bind_shaders, }; + +static void +panvk_internal_shader_destroy(struct vk_device *vk_dev, + struct vk_shader *vk_shader, + const VkAllocationCallbacks *pAllocator) +{ + struct panvk_device *dev = to_panvk_device(vk_dev); + struct panvk_internal_shader *shader = + container_of(vk_shader, struct panvk_internal_shader, vk); + + panvk_pool_free_mem(&dev->mempools.exec, shader->code_mem); + +#if PAN_ARCH <= 7 + panvk_pool_free_mem(&dev->mempools.exec, shader->rsd); +#else + panvk_pool_free_mem(&dev->mempools.exec, shader->spd); +#endif + + vk_shader_free(&dev->vk, pAllocator, &shader->vk); +} + +static const struct vk_shader_ops panvk_internal_shader_ops = { + .destroy = panvk_internal_shader_destroy, +}; + +VkResult +panvk_per_arch(create_internal_shader)( + struct panvk_device *dev, nir_shader *nir, + struct panfrost_compile_inputs *compiler_inputs, + struct panvk_internal_shader **shader_out) +{ + struct panvk_internal_shader *shader = + vk_shader_zalloc(&dev->vk, &panvk_internal_shader_ops, nir->info.stage, + NULL, sizeof(*shader)); + if (shader == NULL) + return panvk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + VkResult result; + struct util_dynarray binary; + + util_dynarray_init(&binary, nir); + GENX(pan_shader_compile)(nir, compiler_inputs, &binary, &shader->info); + + unsigned bin_size = util_dynarray_num_elements(&binary, uint8_t); + if (bin_size) { + shader->code_mem = panvk_pool_upload_aligned(&dev->mempools.exec, + binary.data, bin_size, 128); + if (!panvk_priv_mem_dev_addr(shader->code_mem)) { + result = panvk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY); + goto err_free_shader; + } + } + + *shader_out = shader; + return VK_SUCCESS; + +err_free_shader: + vk_shader_free(&dev->vk, NULL, &shader->vk); + return result; +}