diff --git a/src/freedreno/vulkan/meson.build b/src/freedreno/vulkan/meson.build index 0f6daa01e7c..3c96a1ee4cf 100644 --- a/src/freedreno/vulkan/meson.build +++ b/src/freedreno/vulkan/meson.build @@ -62,6 +62,21 @@ libtu_files += custom_target( depfile : 'float32_spv.h.d', ) +libtu_files += custom_target( + 'float64_spv.h', + input : [glsl2spirv, float64_glsl_file], + output : 'float64_spv.h', + command : [ + prog_python, '@INPUT@', '@OUTPUT@', + prog_glslang, + '--vn', 'float64_spv_source', + '--glsl-version', '450', + '-Olib', + glslang_depfile, + ], + depfile : 'float64_spv.h.d', +) + subdir('bvh') libtu_includes = [ diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index 375f38757ee..ff9a41a1bbe 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -3144,7 +3144,7 @@ tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) vk_meta_device_finish(&device->vk, &device->meta); - tu_destroy_softfloat32(device); + tu_destroy_softfloat(device); ir3_compiler_destroy(device->compiler); diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index 5f1d570feab..dabe8e75696 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -322,6 +322,7 @@ struct tu_device struct vk_meta_device meta; struct nir_shader *float32_shader; + struct nir_shader *float64_shader; mtx_t softfloat_mutex; radix_sort_vk_t *radix_sort; diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index eaff774c767..d4e36041d6c 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -129,6 +129,8 @@ static const uint32_t float32_spv[] = { #include "float32_spv.h" }; +#include "float64_spv.h" + void tu_init_softfloat32(struct tu_device *dev) { @@ -144,10 +146,26 @@ tu_init_softfloat32(struct tu_device *dev) } void -tu_destroy_softfloat32(struct tu_device *dev) +tu_init_softfloat64(struct tu_device *dev) +{ + if (dev->float64_shader) + return; + + mtx_lock(&dev->softfloat_mutex); + if (!dev->float64_shader) { + dev->float64_shader = tu_spirv_to_nir_library(dev, float64_spv_source, + ARRAY_SIZE(float64_spv_source)); + } + mtx_unlock(&dev->softfloat_mutex); +} + +void +tu_destroy_softfloat(struct tu_device *dev) { if (dev->float32_shader) ralloc_free(dev->float32_shader); + if (dev->float64_shader) + ralloc_free(dev->float64_shader); } static void @@ -162,6 +180,19 @@ tu_nir_lower_softfloat32(struct tu_device *dev, nir_shader *nir) ir3_optimize_loop(dev->compiler, &optimize_options, nir); } +static void +tu_nir_lower_softfloat64(struct tu_device *dev, nir_shader *nir) +{ + tu_init_softfloat64(dev); + + NIR_PASS(_, nir, nir_lower_doubles, dev->float64_shader, + nir_lower_fp64_full_software); + + /* Cleanup the result before linking to minimize shader size. */ + struct ir3_optimize_options optimize_options = {}; + ir3_optimize_loop(dev->compiler, &optimize_options, nir); +} + nir_shader * tu_spirv_to_nir(struct tu_device *dev, void *mem_ctx, @@ -252,6 +283,10 @@ tu_spirv_to_nir(struct tu_device *dev, tu_nir_lower_softfloat32(dev, nir); } + if (nir->info.bit_sizes_float & 64) { + tu_nir_lower_softfloat64(dev, nir); + } + return nir; } diff --git a/src/freedreno/vulkan/tu_shader.h b/src/freedreno/vulkan/tu_shader.h index 33ea0a3b0f2..61887585b02 100644 --- a/src/freedreno/vulkan/tu_shader.h +++ b/src/freedreno/vulkan/tu_shader.h @@ -134,7 +134,7 @@ struct tu_shader_key { extern const struct vk_pipeline_cache_object_ops tu_shader_ops; void -tu_destroy_softfloat32(struct tu_device *device); +tu_destroy_softfloat(struct tu_device *device); bool tu_nir_lower_multiview(nir_shader *nir, uint32_t mask, struct tu_device *dev);