anv: only load fp64 software shader when needed
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14665
Reviewed-by: Allen Ballway <ballway@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39341>
This commit is contained in:
Lionel Landwerlin 2026-01-16 09:48:45 +02:00 committed by Marge Bot
parent beb0ffc069
commit 7d3b62e13d
6 changed files with 79 additions and 67 deletions

View file

@ -107,7 +107,7 @@ static nir_shader *
get_fp64_nir(struct blorp_context *context)
{
struct anv_device *device = context->driver_ctx;
return device->fp64_nir;
return anv_ensure_fp64_shader(device);
}
static uint64_t

View file

@ -1118,10 +1118,6 @@ VkResult anv_CreateDevice(
goto fail_default_pipeline_cache;
}
/* The device (currently is ICL/TGL) does not have float64 support. */
if (!device->info->has_64bit_float)
anv_load_fp64_shader(device);
if (anv_needs_printf_buffer()) {
result = anv_device_print_init(device);
if (result != VK_SUCCESS)
@ -1244,6 +1240,7 @@ VkResult anv_CreateDevice(
device->vk.disable_lto = device->physical->instance->disable_lto;
simple_mtx_init(&device->accel_struct_build.mutex, mtx_plain);
simple_mtx_init(&device->fp64_mutex, mtx_plain);
*pDevice = anv_device_to_handle(device);
@ -1469,6 +1466,7 @@ void anv_DestroyDevice(
pthread_mutex_destroy(&device->mutex);
simple_mtx_destroy(&device->accel_struct_build.mutex);
simple_mtx_destroy(&device->fp64_mutex);
ralloc_free(device->fp64_nir);

View file

@ -33,7 +33,6 @@
#include "nir/nir_xfb_info.h"
#include "vk_util.h"
#include "compiler/spirv/nir_spirv.h"
#include "shaders/float64_spv.h"
#include "util/u_printf.h"
@ -315,60 +314,3 @@ anv_device_upload_nir(struct anv_device *device,
vk_pipeline_cache_add_nir(cache, blake3_key, BLAKE3_KEY_LEN, nir);
}
void
anv_load_fp64_shader(struct anv_device *device)
{
const nir_shader_compiler_options *nir_options =
&device->physical->compiler->nir_options[MESA_SHADER_VERTEX];
const char* shader_name = "float64_spv_lib";
blake3_hasher blake3_ctx;
uint8_t blake3[BLAKE3_KEY_LEN];
_mesa_blake3_init(&blake3_ctx);
_mesa_blake3_update(&blake3_ctx, shader_name, strlen(shader_name));
_mesa_blake3_final(&blake3_ctx, blake3);
device->fp64_nir =
anv_device_search_for_nir(device, device->internal_cache,
nir_options, blake3, NULL);
/* The shader found, no need to call spirv_to_nir() again. */
if (device->fp64_nir)
return;
const struct spirv_capabilities spirv_caps = {
.Addresses = true,
.Float64 = true,
.Int8 = true,
.Int16 = true,
.Int64 = true,
.Shader = true,
};
struct spirv_to_nir_options spirv_options = {
.capabilities = &spirv_caps,
.environment = NIR_SPIRV_VULKAN,
.create_library = true
};
nir_shader* nir =
spirv_to_nir(float64_spv_source, sizeof(float64_spv_source) / 4,
NULL, MESA_SHADER_VERTEX, "main",
&spirv_options, nir_options);
assert(nir != NULL);
nir_validate_shader(nir, "after spirv_to_nir");
NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS(_, nir, nir_lower_returns);
NIR_PASS(_, nir, nir_inline_functions);
nir_sweep(nir);
anv_device_upload_nir(device, device->internal_cache,
nir, blake3);
device->fp64_nir = nir;
}

View file

@ -1920,8 +1920,8 @@ anv_device_upload_nir(struct anv_device *device,
const struct nir_shader *nir,
unsigned char blake3_key[BLAKE3_KEY_LEN]);
void
anv_load_fp64_shader(struct anv_device *device);
nir_shader *
anv_ensure_fp64_shader(struct anv_device *device);
/**
* This enum tracks the various HW instructions that hold graphics state
@ -2727,6 +2727,7 @@ struct anv_device {
struct intel_ds_device ds;
simple_mtx_t fp64_mutex;
nir_shader *fp64_nir;
uint32_t draw_call_count;

View file

@ -1434,14 +1434,16 @@ anv_shader_lower_nir(struct anv_device *device,
/* Workaround for apps that need fp64 support */
if (device->fp64_nir) {
NIR_PASS(_, nir, nir_lower_doubles, device->fp64_nir,
nir_shader *fp64_nir = anv_ensure_fp64_shader(device);
NIR_PASS(_, nir, nir_lower_doubles, fp64_nir,
nir->options->lower_doubles_options);
bool fp_conv = false;
NIR_PASS(fp_conv, nir, nir_lower_int64_float_conversions);
if (fp_conv) {
NIR_PASS(_, nir, nir_opt_algebraic);
NIR_PASS(_, nir, nir_lower_doubles, device->fp64_nir,
NIR_PASS(_, nir, nir_lower_doubles, fp64_nir,
nir->options->lower_doubles_options);
}
}

View file

@ -35,6 +35,7 @@
#include "vk_enum_to_str.h"
#include "compiler/brw/brw_nir_rt.h"
#include "shaders/float64_spv.h"
#ifdef NO_REGEX
typedef int regex_t;
@ -667,3 +668,71 @@ anv_cmd_buffer_dump_commands(struct anv_cmd_buffer *cmd_buffer,
"post gfx cmd dump");
anv_genX(device->info, cmd_buffer_apply_pipe_flushes)(cmd_buffer);
}
nir_shader *
anv_ensure_fp64_shader(struct anv_device *device)
{
assert(!device->info->has_64bit_float);
if (device->fp64_nir)
return device->fp64_nir;
simple_mtx_unlock(&device->fp64_mutex);
if (!device->fp64_nir) {
const nir_shader_compiler_options *nir_options =
&device->physical->compiler->nir_options[MESA_SHADER_VERTEX];
const char* shader_name = "float64_spv_lib";
blake3_hasher blake3_ctx;
uint8_t blake3[BLAKE3_KEY_LEN];
_mesa_blake3_init(&blake3_ctx);
_mesa_blake3_update(&blake3_ctx, shader_name, strlen(shader_name));
_mesa_blake3_final(&blake3_ctx, blake3);
device->fp64_nir =
anv_device_search_for_nir(device, device->internal_cache,
nir_options, blake3, NULL);
/* The shader found, no need to call spirv_to_nir() again. */
if (!device->fp64_nir) {
const struct spirv_capabilities spirv_caps = {
.Addresses = true,
.Float64 = true,
.Int8 = true,
.Int16 = true,
.Int64 = true,
.Shader = true,
};
struct spirv_to_nir_options spirv_options = {
.capabilities = &spirv_caps,
.environment = NIR_SPIRV_VULKAN,
.create_library = true
};
nir_shader* nir =
spirv_to_nir(float64_spv_source, sizeof(float64_spv_source) / 4,
NULL, MESA_SHADER_VERTEX, "main",
&spirv_options, nir_options);
assert(nir != NULL);
nir_validate_shader(nir, "after spirv_to_nir");
NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS(_, nir, nir_lower_returns);
NIR_PASS(_, nir, nir_inline_functions);
nir_sweep(nir);
anv_device_upload_nir(device, device->internal_cache, nir, blake3);
device->fp64_nir = nir;
}
}
simple_mtx_unlock(&device->fp64_mutex);
return device->fp64_nir;
}