diff --git a/src/panfrost/vulkan/panvk_shader.h b/src/panfrost/vulkan/panvk_shader.h index f4aa4a7900b..54debdeff6f 100644 --- a/src/panfrost/vulkan/panvk_shader.h +++ b/src/panfrost/vulkan/panvk_shader.h @@ -285,6 +285,7 @@ struct panvk_shader { const void *bin_ptr; uint32_t bin_size; + bool own_bin; struct panvk_priv_mem code_mem; @@ -373,4 +374,9 @@ VkResult panvk_per_arch(create_internal_shader)( struct panfrost_compile_inputs *compiler_inputs, struct panvk_internal_shader **shader_out); +VkResult panvk_per_arch(create_shader_from_binary)( + struct panvk_device *dev, const struct pan_shader_info *info, + struct pan_compute_dim local_size, const void *bin_ptr, size_t bin_size, + struct panvk_shader **shader_out); + #endif diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 4ba3ce022be..50cd8d248fd 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -1065,7 +1065,9 @@ panvk_shader_destroy(struct vk_device *vk_dev, struct vk_shader *vk_shader, } #endif - free((void *)shader->bin_ptr); + if (shader->own_bin) + free((void *)shader->bin_ptr); + vk_shader_free(&dev->vk, pAllocator, &shader->vk); } @@ -1093,6 +1095,7 @@ panvk_compile_shader(struct panvk_device *dev, if (shader == NULL) return panvk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + shader->own_bin = true; struct panfrost_compile_inputs inputs = { .gpu_id = phys_dev->kmod.props.gpu_prod_id, .no_ubo_to_push = true, @@ -1135,6 +1138,41 @@ panvk_compile_shader(struct panvk_device *dev, return result; } +VkResult +panvk_per_arch(create_shader_from_binary)(struct panvk_device *dev, + const struct pan_shader_info *info, + struct pan_compute_dim local_size, + const void *bin_ptr, size_t bin_size, + struct panvk_shader **shader_out) +{ + struct panvk_shader *shader; + VkResult result; + + shader = vk_shader_zalloc(&dev->vk, &panvk_shader_ops, info->stage, + &dev->vk.alloc, sizeof(*shader)); + if (shader == NULL) + return panvk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + shader->info = *info; + shader->local_size = local_size; + shader->bin_ptr = bin_ptr; + shader->bin_size = bin_size; + shader->own_bin = false; + shader->nir_str = NULL; + shader->asm_str = NULL; + + result = panvk_shader_upload(dev, shader, &dev->vk.alloc); + + if (result != VK_SUCCESS) { + panvk_shader_destroy(&dev->vk, &shader->vk, &dev->vk.alloc); + return result; + } + + *shader_out = shader; + + return result; +} + static VkResult panvk_compile_shaders(struct vk_device *vk_dev, uint32_t shader_count, struct vk_shader_compile_info *infos,