tu: Support softfloat64

DOOM Eternal uses fp64 without checking. Don't expose it, but as a
workaround lower the fp64 operations to software so that we don't choke
on them, similar to anv.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38088>
This commit is contained in:
Connor Abbott 2025-10-07 12:04:57 -04:00 committed by Marge Bot
parent 3b3954e2b8
commit 5ccbcf8a8b
5 changed files with 54 additions and 3 deletions

View file

@ -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 = [

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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);