rusticl/spirv: add SPIRVToNirOptions type

Makes it easier to pass around the options needed.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41703>
This commit is contained in:
Karol Herbst 2026-05-20 01:52:38 +02:00 committed by Marge Bot
parent 37faa2c56f
commit 3cb3e9890d
3 changed files with 26 additions and 14 deletions

View file

@ -9,6 +9,7 @@ use crate::core::util::*;
use crate::core::version::*;
use crate::impl_cl_type_trait_base;
use mesa_rust::compiler::clc::spirv::SPIRVToNirOptions;
use mesa_rust::compiler::clc::*;
use mesa_rust::compiler::nir::*;
use mesa_rust::pipe::context::*;
@ -1386,6 +1387,13 @@ impl DeviceBase {
pub fn uuid_supported(&self) -> bool {
self.screen().device_uuid().is_some() && self.screen().driver_uuid().is_some()
}
pub fn spirv_to_nir_opts(&self) -> SPIRVToNirOptions {
SPIRVToNirOptions {
caps: &self.spirv_caps,
address_bits: self.address_bits(),
}
}
}
impl Device {
@ -1441,11 +1449,14 @@ impl Device {
// Libclc depends on a few caps which must always be enabled. At runtime we should never
// actually pass relevant functionality down to drivers, so this should be fine.
let mut spirv_caps = dev_base.spirv_caps;
let mut spirv_to_nir_opts = dev_base.spirv_to_nir_opts();
let mut spirv_caps = *spirv_to_nir_opts.caps;
spirv_caps.Float64 = true;
spirv_caps.Int64 = true;
spirv_to_nir_opts.caps = &spirv_caps;
let lib_clc = spirv::SPIRVBin::get_lib_clc(dev_base.screen(), &spirv_caps);
let lib_clc = spirv::SPIRVBin::get_lib_clc(dev_base.screen(), spirv_to_nir_opts);
if lib_clc.is_none() {
eprintln!("Libclc failed to load. Please make sure it is installed and provides spirv-mesa3d-.spv and/or spirv64-mesa3d-.spv");
}

View file

@ -257,10 +257,9 @@ impl DeviceProgramBuild {
device
.screen
.nir_shader_compiler_options(mesa_shader_stage::MESA_SHADER_COMPUTE),
&device.spirv_caps,
device.spirv_to_nir_opts(),
&device.lib_clc,
&mut spec_constants,
device.address_bits(),
log.as_mut(),
);

View file

@ -90,6 +90,11 @@ fn create_clc_logger(msgs: &mut Vec<String>) -> clc_logger {
}
}
pub struct SPIRVToNirOptions<'a> {
pub caps: &'a spirv_capabilities,
pub address_bits: u32,
}
impl SPIRVBin {
pub fn from_clc(
source: &CString,
@ -281,14 +286,13 @@ impl SPIRVBin {
fn get_spirv_options(
library: bool,
clc_shader: *const nir_shader,
address_bits: u32,
caps: &spirv_capabilities,
options: SPIRVToNirOptions,
log: Option<&mut Vec<String>>,
) -> spirv_to_nir_options {
let global_addr_format;
let offset_addr_format;
if address_bits == 32 {
if options.address_bits == 32 {
global_addr_format = nir_address_format::nir_address_format_32bit_global;
offset_addr_format = nir_address_format::nir_address_format_32bit_offset;
} else {
@ -308,7 +312,7 @@ impl SPIRVBin {
clc_shader: clc_shader,
float_controls_execution_mode: float_controls,
printf: true,
capabilities: caps,
capabilities: options.caps,
constant_addr_format: global_addr_format,
global_addr_format: global_addr_format,
shared_addr_format: offset_addr_format,
@ -323,15 +327,14 @@ impl SPIRVBin {
&self,
entry_point: &str,
nir_options: *const nir_shader_compiler_options,
spirv_caps: &spirv_capabilities,
spirv_to_nir_options: SPIRVToNirOptions,
libclc: &NirShader,
spec_constants: &mut nir_spirv_specialization,
address_bits: u32,
log: Option<&mut Vec<String>>,
) -> Option<NirShader> {
let c_entry = CString::new(entry_point.as_bytes()).unwrap();
let spirv_options =
Self::get_spirv_options(false, libclc.get_nir(), address_bits, spirv_caps, log);
Self::get_spirv_options(false, libclc.get_nir(), spirv_to_nir_options, log);
let nir = unsafe {
spirv_to_nir(
@ -348,12 +351,11 @@ impl SPIRVBin {
NirShader::new(nir)
}
pub fn get_lib_clc(screen: &PipeScreen, spirv_caps: &spirv_capabilities) -> Option<NirShader> {
pub fn get_lib_clc(screen: &PipeScreen, options: SPIRVToNirOptions) -> Option<NirShader> {
let nir_options =
screen.nir_shader_compiler_options(mesa_shader_stage::MESA_SHADER_COMPUTE);
let address_bits = screen.compute_caps().address_bits;
let spirv_options =
Self::get_spirv_options(false, ptr::null(), address_bits, spirv_caps, None);
let spirv_options = Self::get_spirv_options(false, ptr::null(), options, None);
let shader_cache = DiskCacheBorrowed::as_ptr(&screen.shader_cache());
NirShader::new(unsafe {