pub fn entry_stub(
        &self,
        instance: &Instance<'_>,
        fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
        entry_func: SpirvValue,
        name: String,
        entry: Entry,
    ) {
        let span = self.tcx.def_span(instance.def_id());
        let hir_params = {
            let fn_local_def_id = match instance.def_id().as_local() {
                Some(id) => id,
                None => {
                    self.tcx
                        .sess
                        .span_err(span, &format!("Cannot declare {} as an entry point", name));
                    return;
                }
            };
            let fn_hir_id = self.tcx.hir().local_def_id_to_hir_id(fn_local_def_id);
            let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(fn_hir_id));
            body.params
        };
        const EMPTY: ArgAttribute = ArgAttribute::empty();
        for (abi, hir_param) in fn_abi.args.iter().zip(hir_params) {
            match abi.mode {
                PassMode::Direct(_)
                | PassMode::Indirect { .. }
                // plain DST/RTA/VLA
                | PassMode::Pair(
                    ArgAttributes {
                        pointee_size: Size::ZERO,
                        ..
                    },
                    ArgAttributes { regular: EMPTY, .. },
                )
                // DST struct with fields before the DST member
                | PassMode::Pair(
                    ArgAttributes { .. },
                    ArgAttributes {
                        pointee_size: Size::ZERO,
                        ..
                    },
                ) => {}
                _ => self.tcx.sess.span_err(
                    hir_param.ty_span,
                    &format!("PassMode {:?} invalid for entry point parameter", abi.mode),
                ),
            }
        }
        if let PassMode::Ignore = fn_abi.ret.mode {
        } else {
            self.tcx.sess.span_err(
                span,
                &format!(
                    "PassMode {:?} invalid for entry point return type",
                    fn_abi.ret.mode
                ),
            )
        }
        let execution_model = entry.execution_model;
        let fn_id = if execution_model == ExecutionModel::Kernel {
            self.kernel_entry_stub(entry_func, name, execution_model)
        } else {
            self.shader_entry_stub(
                span,
                entry_func,
                &fn_abi.args,
                hir_params,
                name,
                execution_model,
            )
        };
        let mut emit = self.emit_global();
        entry
            .execution_modes
            .iter()
            .for_each(|(execution_mode, execution_mode_extra)| {
                emit.execution_mode(fn_id, *execution_mode, execution_mode_extra);
            });
    }
// Entry points declare their "interface" (all uniforms, inputs, outputs, etc.) as parameters.
// spir-v uses globals to declare the interface. So, we need to generate a lil stub for the
// "real" main that collects all those global variables and calls the user-defined main
// function.
Entry points declare their "interface" (all uniforms, inputs, outputs, etc.) as parameters.
spir-v uses globals to declare the interface. So, we need to generate a lil stub for the
"real" main that collects all those global variables and calls the user-defined main
function.
Entry points declare their " interface " ( all uniforms inputs outputs etc . ) as parameters . spir - v uses globals to declare the interface . So we need to generate a lil stub for the " real " main that collects all those global variables and calls the user - defined main function .
pub fn entry_stub(
        &self,
        instance: &Instance<'_>,
        fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
        entry_func: SpirvValue,
        name: String,
        entry: Entry,
    ) {
        let span = self.tcx.def_span(instance.def_id());
        let hir_params = {
            let fn_local_def_id = match instance.def_id().as_local() {
                Some(id) => id,
                None => {
                    self.tcx
                        .sess
                        .span_err(span, &format!("Cannot declare {} as an entry point", name));
                    return;
                }
            };
            let fn_hir_id = self.tcx.hir().local_def_id_to_hir_id(fn_local_def_id);
            let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(fn_hir_id));
            body.params
        };
        const EMPTY: ArgAttribute = ArgAttribute::empty();
        for (abi, hir_param) in fn_abi.args.iter().zip(hir_params) {
            match abi.mode {
                PassMode::Direct(_)
                | PassMode::Indirect { .. }
                // plain DST/RTA/VLA
                | PassMode::Pair(
                    ArgAttributes {
                        pointee_size: Size::ZERO,
                        ..
                    },
                    ArgAttributes { regular: EMPTY, .. },
                )
                // DST struct with fields before the DST member
                | PassMode::Pair(
                    ArgAttributes { .. },
                    ArgAttributes {
                        pointee_size: Size::ZERO,
                        ..
                    },
                ) => {}
                _ => self.tcx.sess.span_err(
                    hir_param.ty_span,
                    &format!("PassMode {:?} invalid for entry point parameter", abi.mode),
                ),
            }
        }
        if let PassMode::Ignore = fn_abi.ret.mode {
        } else {
            self.tcx.sess.span_err(
                span,
                &format!(
                    "PassMode {:?} invalid for entry point return type",
                    fn_abi.ret.mode
                ),
            )
        }
        let execution_model = entry.execution_model;
        let fn_id = if execution_model == ExecutionModel::Kernel {
            self.kernel_entry_stub(entry_func, name, execution_model)
        } else {
            self.shader_entry_stub(
                span,
                entry_func,
                &fn_abi.args,
                hir_params,
                name,
                execution_model,
            )
        };
        let mut emit = self.emit_global();
        entry
            .execution_modes
            .iter()
            .for_each(|(execution_mode, execution_mode_extra)| {
                emit.execution_mode(fn_id, *execution_mode, execution_mode_extra);
            });
    }
pub fn entry_stub ( & self , instance : & Instance < ' _ > , fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > , entry_func : SpirvValue , name : String , entry : Entry , ) { let span = self . tcx . def_span ( instance . def_id ( ) ) ; let hir_params = { let fn_local_def_id = match instance . def_id ( ) . as_local ( ) { Some ( id ) => id , None => { self . tcx . sess . span_err ( span , & format ! ( " " name ) ) ; return ; } } ; let fn_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( fn_local_def_id ) ; let body = self . tcx . hir ( ) . body ( self . tcx . hir ( ) . body_owned_by ( fn_hir_id ) ) ; body . params } ; const EMPTY : ArgAttribute = ArgAttribute :: empty ( ) ; for ( abi , hir_param ) in fn_abi . args . iter ( ) . zip ( hir_params ) { match abi . mode { PassMode :: Direct ( _ ) | PassMode :: Indirect { .. } // plain DST/RTA/VLA | PassMode :: Pair ( ArgAttributes { pointee_size : Size :: ZERO , .. } , ArgAttributes { regular : EMPTY , .. } , ) // DST struct with fields before the DST member | PassMode :: Pair ( ArgAttributes { .. } , ArgAttributes { pointee_size : Size :: ZERO , .. } , ) => { } _ => self . tcx . sess . span_err ( hir_param . ty_span , & format ! ( " " abi mode ) , ) , } } if let PassMode :: Ignore = fn_abi . ret . mode { } else { self . tcx . sess . span_err ( span , & format ! ( " " fn_abi ret mode ) , ) } let execution_model = entry . execution_model ; let fn_id = if execution_model == ExecutionModel :: Kernel { self . kernel_entry_stub ( entry_func , name , execution_model ) } else { self . shader_entry_stub ( span , entry_func , & fn_abi . args , hir_params , name , execution_model , ) } ; let mut emit = self . emit_global ( ) ; entry . execution_modes . iter ( ) . for_each ( | ( execution_mode , execution_mode_extra ) | { emit . execution_mode ( fn_id , * execution_mode , execution_mode_extra ) ; } ) ; }
Entry points declare their "interface" (all uniforms, inputs, outputs, etc.)
Entry points declare their " interface " ( all uniforms inputs outputs etc . )
&self
instance
&Instance<'_>
fn_abi
&FnAbi<'tcx, Ty<'tcx>>
entry_func
SpirvValue
name
String
entry
Entry