Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert Image<> parameters from enums to integers to make spirv-std build on stable #761

Merged
merged 3 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 41 additions & 31 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use std::collections::hash_map::Entry;
use std::fmt;

use num_traits::cast::FromPrimitive;
use rspirv::spirv;

/// If a struct contains a pointer to itself, even indirectly, then doing a naiive recursive walk
/// of the fields will result in an infinite loop. Because pointers are the only thing that are
Expand Down Expand Up @@ -715,17 +714,17 @@ fn trans_intrinsic_type<'tcx>(
return Err(ErrorReported);
}

fn type_from_variant_discriminant<'tcx, P: FromPrimitive>(
cx: &CodegenCx<'tcx>,
const_: &'tcx Const<'tcx>,
) -> P {
let adt_def = const_.ty.ty_adt_def().unwrap();
assert!(adt_def.is_enum());
let destructured = cx.tcx.destructure_const(ParamEnv::reveal_all().and(const_));
let idx = destructured.variant.unwrap();
let value = const_.ty.discriminant_for_variant(cx.tcx, idx).unwrap().val as u64;
<_>::from_u64(value).unwrap()
}
// fn type_from_variant_discriminant<'tcx, P: FromPrimitive>(
// cx: &CodegenCx<'tcx>,
// const_: &'tcx Const<'tcx>,
// ) -> P {
// let adt_def = const_.ty.ty_adt_def().unwrap();
// assert!(adt_def.is_enum());
// let destructured = cx.tcx.destructure_const(ParamEnv::reveal_all().and(const_));
// let idx = destructured.variant.unwrap();
// let value = const_.ty.discriminant_for_variant(cx.tcx, idx).unwrap().val as u64;
// <_>::from_u64(value).unwrap()
// }

let sampled_type = match substs.type_at(0).kind() {
TyKind::Int(int) => match int {
Expand Down Expand Up @@ -760,25 +759,37 @@ fn trans_intrinsic_type<'tcx>(
}
};

let dim: spirv::Dim = type_from_variant_discriminant(cx, substs.const_at(1));
let depth: u32 = type_from_variant_discriminant(cx, substs.const_at(2));
let arrayed: u32 = type_from_variant_discriminant(cx, substs.const_at(3));
let multisampled: u32 = type_from_variant_discriminant(cx, substs.const_at(4));
let sampled: u32 = type_from_variant_discriminant(cx, substs.const_at(5));
let image_format: spirv::ImageFormat =
type_from_variant_discriminant(cx, substs.const_at(6));

let access_qualifier = {
let option = cx
.tcx
.destructure_const(ParamEnv::reveal_all().and(substs.const_at(7)));

match option.variant.map(|i| i.as_u32()).unwrap_or(0) {
0 => None,
1 => Some(type_from_variant_discriminant(cx, option.fields[0])),
_ => unreachable!(),
// let dim: spirv::Dim = type_from_variant_discriminant(cx, substs.const_at(1));
// let depth: u32 = type_from_variant_discriminant(cx, substs.const_at(2));
// let arrayed: u32 = type_from_variant_discriminant(cx, substs.const_at(3));
// let multisampled: u32 = type_from_variant_discriminant(cx, substs.const_at(4));
// let sampled: u32 = type_from_variant_discriminant(cx, substs.const_at(5));
// let image_format: spirv::ImageFormat =
// type_from_variant_discriminant(cx, substs.const_at(6));

fn const_int_value<'tcx, P: FromPrimitive>(
cx: &CodegenCx<'tcx>,
const_: &'tcx Const<'tcx>,
) -> Result<P, ErrorReported> {
assert!(const_.ty.is_integral());
let value = const_.eval_bits(cx.tcx, ParamEnv::reveal_all(), const_.ty);
match P::from_u128(value) {
Some(v) => Ok(v),
None => {
cx.tcx
.sess
.err(&format!("Invalid value for Image const generic: {}", value));
Err(ErrorReported)
}
}
};
}

let dim = const_int_value(cx, substs.const_at(1))?;
let depth = const_int_value(cx, substs.const_at(2))?;
let arrayed = const_int_value(cx, substs.const_at(3))?;
let multisampled = const_int_value(cx, substs.const_at(4))?;
let sampled = const_int_value(cx, substs.const_at(5))?;
let image_format = const_int_value(cx, substs.const_at(6))?;

let ty = SpirvType::Image {
sampled_type,
Expand All @@ -788,7 +799,6 @@ fn trans_intrinsic_type<'tcx>(
multisampled,
sampled,
image_format,
access_qualifier,
};
Ok(ty.def(span, cx))
}
Expand Down
1 change: 0 additions & 1 deletion crates/rustc_codegen_spirv/src/builder/spirv_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,6 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
multisampled: inst.operands[4].unwrap_literal_int32(),
sampled: inst.operands[5].unwrap_literal_int32(),
image_format: inst.operands[6].unwrap_image_format(),
access_qualifier: None,
}
.def(self.span(), self),
Op::TypeSampledImage => SpirvType::SampledImage {
Expand Down
12 changes: 2 additions & 10 deletions crates/rustc_codegen_spirv/src/spirv_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use crate::codegen_cx::CodegenCx;
use bimap::BiHashMap;
use indexmap::IndexSet;
use rspirv::dr::Operand;
use rspirv::spirv::{
AccessQualifier, Capability, Decoration, Dim, ImageFormat, StorageClass, Word,
};
use rspirv::spirv::{Capability, Decoration, Dim, ImageFormat, StorageClass, Word};
use rustc_data_structures::fx::FxHashMap;
use rustc_span::def_id::DefId;
use rustc_span::Span;
Expand Down Expand Up @@ -75,7 +73,6 @@ pub enum SpirvType {
multisampled: u32,
sampled: u32,
image_format: ImageFormat,
access_qualifier: Option<AccessQualifier>,
},
Sampler,
SampledImage {
Expand Down Expand Up @@ -243,7 +240,6 @@ impl SpirvType {
multisampled,
sampled,
image_format,
access_qualifier,
} => cx.emit_global().type_image_id(
id,
sampled_type,
Expand All @@ -253,7 +249,7 @@ impl SpirvType {
multisampled,
sampled,
image_format,
access_qualifier,
None,
),
Self::Sampler => cx.emit_global().type_sampler_id(id),
Self::AccelerationStructureKhr => {
Expand Down Expand Up @@ -513,7 +509,6 @@ impl fmt::Debug for SpirvTypePrinter<'_, '_> {
multisampled,
sampled,
image_format,
access_qualifier,
} => f
.debug_struct("Image")
.field("id", &self.id)
Expand All @@ -524,7 +519,6 @@ impl fmt::Debug for SpirvTypePrinter<'_, '_> {
.field("multisampled", &multisampled)
.field("sampled", &sampled)
.field("image_format", &image_format)
.field("access_qualifier", &access_qualifier)
.finish(),
SpirvType::Sampler => f.debug_struct("Sampler").field("id", &self.id).finish(),
SpirvType::SampledImage { image_type } => f
Expand Down Expand Up @@ -670,7 +664,6 @@ impl SpirvTypePrinter<'_, '_> {
multisampled,
sampled,
image_format,
access_qualifier,
} => f
.debug_struct("Image")
.field("sampled_type", &self.cx.debug_type(sampled_type))
Expand All @@ -680,7 +673,6 @@ impl SpirvTypePrinter<'_, '_> {
.field("multisampled", &multisampled)
.field("sampled", &sampled)
.field("image_format", &image_format)
.field("access_qualifier", &access_qualifier)
.finish(),
SpirvType::Sampler => f.write_str("Sampler"),
SpirvType::SampledImage { image_type } => f
Expand Down
55 changes: 7 additions & 48 deletions crates/spirv-std/macros/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type, or use `format` to set the image to a specific image format.";

/// Creates an `Image` type using the following syntax.
pub struct ImageType {
access_qualifier: Option<AccessQualifier>,
arrayed: Arrayed,
crate_root: Option<syn::Path>,
depth: ImageDepth,
Expand All @@ -38,7 +37,6 @@ pub struct ImageType {

impl Parse for ImageType {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let mut access_qualifier = None;
let mut sampled_type = None;
let mut dimensionality = None;
let mut arrayed = None;
Expand Down Expand Up @@ -86,20 +84,7 @@ impl Parse for ImageType {
} else if input.peek(syn::Ident) {
let ident = input.parse::<Ident>().unwrap();

if ident == "access" {
let value = peek_and_eat_value!(syn::Ident)
.as_ref()
.map(|i| params::access_qualifier_from_str(&i.to_string()));

if value.is_none() {
return Err(syn::Error::new(
ident.span(),
"Expected argument for `access`.",
));
}

access_qualifier = value.unwrap().ok();
} else if ident == "buffer" {
if ident == "buffer" {
set_unique!(dimensionality = Dimensionality::Buffer);
} else if ident == "cube" {
set_unique!(dimensionality = Dimensionality::Cube);
Expand Down Expand Up @@ -302,7 +287,6 @@ impl Parse for ImageType {
let sampled = sampled.unwrap_or(Sampled::Unknown);

Ok(Self {
access_qualifier,
arrayed,
crate_root,
depth,
Expand All @@ -326,13 +310,6 @@ impl quote::ToTokens for ImageType {
punct
},
});
let access_qualifier = match self.access_qualifier {
Some(aq) => {
let aq = params::access_qualifier_to_tokens(&aq);
quote!(Some(#crate_root::image::#aq))
}
None => quote!(None),
};
let dimensionality = params::dimensionality_to_tokens(&self.dimensionality);
let arrayed = params::arrayed_to_tokens(&self.arrayed);
let depth = params::image_depth_to_tokens(&self.depth);
Expand All @@ -344,13 +321,12 @@ impl quote::ToTokens for ImageType {
tokens.append_all(quote::quote! {
#crate_root::image::Image<
#crate_root::image::__private::#sampled_type,
{ #crate_root::image::#dimensionality },
{ #crate_root::image::#depth },
{ #crate_root::image::#arrayed },
{ #crate_root::image::#multisampled },
{ #crate_root::image::#sampled },
{ #crate_root::image::#format },
{ #access_qualifier },
{ #crate_root::image::#dimensionality as u32 },
{ #crate_root::image::#depth as u32 },
{ #crate_root::image::#arrayed as u32 },
{ #crate_root::image::#multisampled as u32 },
{ #crate_root::image::#sampled as u32 },
{ #crate_root::image::#format as u32 },
>
});
}
Expand All @@ -360,15 +336,6 @@ mod params {
use super::*;
use proc_macro2::TokenStream;

pub fn access_qualifier_from_str(s: &str) -> Result<AccessQualifier, &'static str> {
match s {
"read" => Ok(AccessQualifier::ReadOnly),
"write" => Ok(AccessQualifier::WriteOnly),
"read_write" => Ok(AccessQualifier::ReadWrite),
_ => Err("Invalid access qualifier."),
}
}

pub fn image_format_from_str(s: &str) -> Result<ImageFormat, &'static str> {
Ok(match s {
"rgba32f" => ImageFormat::Rgba32f,
Expand Down Expand Up @@ -449,14 +416,6 @@ mod params {
}
}

pub fn access_qualifier_to_tokens(aq: &AccessQualifier) -> TokenStream {
match aq {
AccessQualifier::ReadOnly => quote!(AccessQualifier::ReadOnly),
AccessQualifier::WriteOnly => quote!(AccessQualifier::WriteOnly),
AccessQualifier::ReadWrite => quote!(AccessQualifier::ReadWrite),
}
}

pub fn image_depth_to_tokens(id: &ImageDepth) -> TokenStream {
match id {
ImageDepth::True => quote!(ImageDepth::True),
Expand Down
Loading