Skip to content

Commit 587b62d

Browse files
teoxoyjimblandy
authored andcommitted
[wgsl-in] add support for override declarations
[ir] split overrides from constants
1 parent 3c37716 commit 587b62d

37 files changed

+510
-26
lines changed

naga/src/back/dot/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ fn write_function_expressions(
404404
let (label, color_id) = match *expression {
405405
E::Literal(_) => ("Literal".into(), 2),
406406
E::Constant(_) => ("Constant".into(), 2),
407+
E::Override(_) => ("Override".into(), 2),
407408
E::ZeroValue(_) => ("ZeroValue".into(), 2),
408409
E::Compose { ref components, .. } => {
409410
payload = Some(Payload::Arguments(components));

naga/src/back/glsl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,6 +2525,7 @@ impl<'a, W: Write> Writer<'a, W> {
25252525
|writer, expr| writer.write_expr(expr, ctx),
25262526
)?;
25272527
}
2528+
Expression::Override(_) => return Err(Error::Custom("overrides are WIP".into())),
25282529
// `Access` is applied to arrays, vectors and matrices and is written as indexing
25292530
Expression::Access { base, index } => {
25302531
self.write_expr(base, ctx)?;

naga/src/back/hlsl/writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
21512151
|writer, expr| writer.write_expr(module, expr, func_ctx),
21522152
)?;
21532153
}
2154+
Expression::Override(_) => {
2155+
return Err(Error::Unimplemented("overrides are WIP".into()))
2156+
}
21542157
// All of the multiplication can be expressed as `mul`,
21552158
// except vector * vector, which needs to use the "*" operator.
21562159
Expression::Binary {

naga/src/back/msl/writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,9 @@ impl<W: Write> Writer<W> {
13941394
|writer, context, expr| writer.put_expression(expr, context, true),
13951395
)?;
13961396
}
1397+
crate::Expression::Override(_) => {
1398+
return Err(Error::FeatureNotImplemented("overrides are WIP".into()))
1399+
}
13971400
crate::Expression::Access { base, .. }
13981401
| crate::Expression::AccessIndex { base, .. } => {
13991402
// This is an acceptable place to generate a `ReadZeroSkipWrite` check.

naga/src/back/spv/block.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ impl<'w> BlockContext<'w> {
239239
let init = self.ir_module.constants[handle].init;
240240
self.writer.constant_ids[init.index()]
241241
}
242+
crate::Expression::Override(_) => {
243+
return Err(Error::FeatureNotImplemented("overrides are WIP"))
244+
}
242245
crate::Expression::ZeroValue(_) => self.writer.get_constant_null(result_type_id),
243246
crate::Expression::Compose { ty, ref components } => {
244247
self.temp_list.clear();

naga/src/back/wgsl/writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,9 @@ impl<W: Write> Writer<W> {
11801180
|writer, expr| writer.write_expr(module, expr, func_ctx),
11811181
)?;
11821182
}
1183+
Expression::Override(_) => {
1184+
return Err(Error::Unimplemented("overrides are WIP".into()))
1185+
}
11831186
Expression::FunctionArgument(pos) => {
11841187
let name_key = func_ctx.argument_key(pos);
11851188
let name = &self.names[&name_key];

naga/src/compact/expressions.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::arena::{Arena, Handle};
33

44
pub struct ExpressionTracer<'tracer> {
55
pub constants: &'tracer Arena<crate::Constant>,
6+
pub overrides: &'tracer Arena<crate::Override>,
67

78
/// The arena in which we are currently tracing expressions.
89
pub expressions: &'tracer Arena<crate::Expression>,
@@ -13,6 +14,9 @@ pub struct ExpressionTracer<'tracer> {
1314
/// The used map for `constants`.
1415
pub constants_used: &'tracer mut HandleSet<crate::Constant>,
1516

17+
/// The used map for `overrides`.
18+
pub overrides_used: &'tracer mut HandleSet<crate::Override>,
19+
1620
/// The used set for `arena`.
1721
///
1822
/// This points to whatever arena holds the expressions we are
@@ -88,6 +92,22 @@ impl<'tracer> ExpressionTracer<'tracer> {
8892
None => self.expressions_used.insert(init),
8993
}
9094
}
95+
Ex::Override(handle) => {
96+
self.overrides_used.insert(handle);
97+
// Overrides and expressions are mutually recursive, which
98+
// complicates our nice one-pass algorithm. However, since
99+
// overrides don't refer to each other, we can get around
100+
// this by looking *through* each override and marking its
101+
// initializer as used. Since `expr` refers to the override,
102+
// and the override refers to the initializer, it must
103+
// precede `expr` in the arena.
104+
if let Some(init) = self.overrides[handle].init {
105+
match self.const_expressions_used {
106+
Some(ref mut used) => used.insert(init),
107+
None => self.expressions_used.insert(init),
108+
}
109+
}
110+
}
91111
Ex::ZeroValue(ty) => self.types_used.insert(ty),
92112
Ex::Compose { ty, ref components } => {
93113
self.types_used.insert(ty);
@@ -221,6 +241,7 @@ impl ModuleMap {
221241

222242
// Expressions that contain handles that need to be adjusted.
223243
Ex::Constant(ref mut constant) => self.constants.adjust(constant),
244+
Ex::Override(ref mut override_) => self.overrides.adjust(override_),
224245
Ex::ZeroValue(ref mut ty) => self.types.adjust(ty),
225246
Ex::Compose {
226247
ref mut ty,

naga/src/compact/functions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use super::{FunctionMap, ModuleMap};
44
pub struct FunctionTracer<'a> {
55
pub function: &'a crate::Function,
66
pub constants: &'a crate::Arena<crate::Constant>,
7+
pub overrides: &'a crate::Arena<crate::Override>,
78

89
pub types_used: &'a mut HandleSet<crate::Type>,
910
pub constants_used: &'a mut HandleSet<crate::Constant>,
11+
pub overrides_used: &'a mut HandleSet<crate::Override>,
1012
pub const_expressions_used: &'a mut HandleSet<crate::Expression>,
1113

1214
/// Function-local expressions used.
@@ -47,10 +49,12 @@ impl<'a> FunctionTracer<'a> {
4749
fn as_expression(&mut self) -> super::expressions::ExpressionTracer {
4850
super::expressions::ExpressionTracer {
4951
constants: self.constants,
52+
overrides: self.overrides,
5053
expressions: &self.function.expressions,
5154

5255
types_used: self.types_used,
5356
constants_used: self.constants_used,
57+
overrides_used: self.overrides_used,
5458
expressions_used: &mut self.expressions_used,
5559
const_expressions_used: Some(&mut self.const_expressions_used),
5660
}

naga/src/compact/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ pub fn compact(module: &mut crate::Module) {
5454
}
5555
}
5656

57+
// We treat all overrides as used by definition.
58+
for (handle, override_) in module.overrides.iter() {
59+
module_tracer.overrides_used.insert(handle);
60+
if let Some(init) = override_.init {
61+
module_tracer.const_expressions_used.insert(init);
62+
}
63+
}
64+
5765
// We assume that all functions are used.
5866
//
5967
// Observe which types, constant expressions, constants, and
@@ -99,6 +107,11 @@ pub fn compact(module: &mut crate::Module) {
99107
module_tracer.types_used.insert(constant.ty);
100108
}
101109
}
110+
for (handle, override_) in module.overrides.iter() {
111+
if module_tracer.overrides_used.contains(handle) {
112+
module_tracer.types_used.insert(override_.ty);
113+
}
114+
}
102115

103116
// Treat all named types as used.
104117
for (handle, ty) in module.types.iter() {
@@ -158,6 +171,20 @@ pub fn compact(module: &mut crate::Module) {
158171
}
159172
});
160173

174+
// Drop unused overrides in place, reusing existing storage.
175+
log::trace!("adjusting overrides");
176+
module.overrides.retain_mut(|handle, override_| {
177+
if module_map.overrides.used(handle) {
178+
module_map.types.adjust(&mut override_.ty);
179+
if let Some(init) = override_.init.as_mut() {
180+
module_map.const_expressions.adjust(init);
181+
}
182+
true
183+
} else {
184+
false
185+
}
186+
});
187+
161188
// Adjust global variables' types and initializers.
162189
log::trace!("adjusting global variables");
163190
for (_, global) in module.global_variables.iter_mut() {
@@ -193,6 +220,7 @@ struct ModuleTracer<'module> {
193220
module: &'module crate::Module,
194221
types_used: HandleSet<crate::Type>,
195222
constants_used: HandleSet<crate::Constant>,
223+
overrides_used: HandleSet<crate::Override>,
196224
const_expressions_used: HandleSet<crate::Expression>,
197225
}
198226

@@ -202,6 +230,7 @@ impl<'module> ModuleTracer<'module> {
202230
module,
203231
types_used: HandleSet::for_arena(&module.types),
204232
constants_used: HandleSet::for_arena(&module.constants),
233+
overrides_used: HandleSet::for_arena(&module.overrides),
205234
const_expressions_used: HandleSet::for_arena(&module.const_expressions),
206235
}
207236
}
@@ -235,8 +264,10 @@ impl<'module> ModuleTracer<'module> {
235264
expressions::ExpressionTracer {
236265
expressions: &self.module.const_expressions,
237266
constants: &self.module.constants,
267+
overrides: &self.module.overrides,
238268
types_used: &mut self.types_used,
239269
constants_used: &mut self.constants_used,
270+
overrides_used: &mut self.overrides_used,
240271
expressions_used: &mut self.const_expressions_used,
241272
const_expressions_used: None,
242273
}
@@ -249,8 +280,10 @@ impl<'module> ModuleTracer<'module> {
249280
FunctionTracer {
250281
function,
251282
constants: &self.module.constants,
283+
overrides: &self.module.overrides,
252284
types_used: &mut self.types_used,
253285
constants_used: &mut self.constants_used,
286+
overrides_used: &mut self.overrides_used,
254287
const_expressions_used: &mut self.const_expressions_used,
255288
expressions_used: HandleSet::for_arena(&function.expressions),
256289
}
@@ -260,6 +293,7 @@ impl<'module> ModuleTracer<'module> {
260293
struct ModuleMap {
261294
types: HandleMap<crate::Type>,
262295
constants: HandleMap<crate::Constant>,
296+
overrides: HandleMap<crate::Override>,
263297
const_expressions: HandleMap<crate::Expression>,
264298
}
265299

@@ -268,6 +302,7 @@ impl From<ModuleTracer<'_>> for ModuleMap {
268302
ModuleMap {
269303
types: HandleMap::from_set(used.types_used),
270304
constants: HandleMap::from_set(used.constants_used),
305+
overrides: HandleMap::from_set(used.overrides_used),
271306
const_expressions: HandleMap::from_set(used.const_expressions_used),
272307
}
273308
}

naga/src/front/spv/function.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> {
128128
expressions: &mut fun.expressions,
129129
local_arena: &mut fun.local_variables,
130130
const_arena: &mut module.constants,
131+
overrides: &mut module.overrides,
131132
const_expressions: &mut module.const_expressions,
132133
type_arena: &module.types,
133134
global_arena: &module.global_variables,
@@ -573,6 +574,7 @@ impl<'function> BlockContext<'function> {
573574
crate::proc::GlobalCtx {
574575
types: self.type_arena,
575576
constants: self.const_arena,
577+
overrides: self.overrides,
576578
const_expressions: self.const_expressions,
577579
}
578580
}

naga/src/front/spv/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ struct BlockContext<'function> {
532532
local_arena: &'function mut Arena<crate::LocalVariable>,
533533
/// Constants arena of the module being processed
534534
const_arena: &'function mut Arena<crate::Constant>,
535+
overrides: &'function mut Arena<crate::Override>,
535536
const_expressions: &'function mut Arena<crate::Expression>,
536537
/// Type arena of the module being processed
537538
type_arena: &'function UniqueArena<crate::Type>,
@@ -3933,7 +3934,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
39333934
Op::TypeImage => self.parse_type_image(inst, &mut module),
39343935
Op::TypeSampledImage => self.parse_type_sampled_image(inst),
39353936
Op::TypeSampler => self.parse_type_sampler(inst, &mut module),
3936-
Op::Constant | Op::SpecConstant => self.parse_constant(inst, &mut module),
3937+
Op::Constant => self.parse_constant(inst, &mut module),
39373938
Op::ConstantComposite => self.parse_composite_constant(inst, &mut module),
39383939
Op::ConstantNull | Op::Undef => self.parse_null_constant(inst, &mut module),
39393940
Op::ConstantTrue => self.parse_bool_constant(inst, true, &mut module),

naga/src/front/wgsl/error.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub enum Error<'a> {
190190
expected: String,
191191
got: String,
192192
},
193-
MissingType(Span),
193+
DeclMissingTypeAndInit(Span),
194194
MissingAttribute(&'static str, Span),
195195
InvalidAtomicPointer(Span),
196196
InvalidAtomicOperandType(Span),
@@ -251,6 +251,7 @@ pub enum Error<'a> {
251251
ExpectedPositiveArrayLength(Span),
252252
MissingWorkgroupSize(Span),
253253
ConstantEvaluatorError(ConstantEvaluatorError, Span),
254+
PipelineConstantIDValue(Span),
254255
}
255256

256257
impl<'a> Error<'a> {
@@ -500,11 +501,11 @@ impl<'a> Error<'a> {
500501
notes: vec![],
501502
}
502503
}
503-
Error::MissingType(name_span) => ParseError {
504-
message: format!("variable `{}` needs a type", &source[name_span]),
504+
Error::DeclMissingTypeAndInit(name_span) => ParseError {
505+
message: format!("declaration of `{}` needs a type specifier or initializer", &source[name_span]),
505506
labels: vec![(
506507
name_span,
507-
format!("definition of `{}`", &source[name_span]).into(),
508+
"needs a type specifier or initializer".into(),
508509
)],
509510
notes: vec![],
510511
},
@@ -712,6 +713,14 @@ impl<'a> Error<'a> {
712713
)],
713714
notes: vec![],
714715
},
716+
Error::PipelineConstantIDValue(span) => ParseError {
717+
message: "pipeline constant ID must be between 0 and 65535 inclusive".to_string(),
718+
labels: vec![(
719+
span,
720+
"must be between 0 and 65535 inclusive".into(),
721+
)],
722+
notes: vec![],
723+
},
715724
}
716725
}
717726
}

naga/src/front/wgsl/index.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ const fn decl_ident<'a>(decl: &ast::GlobalDecl<'a>) -> ast::Ident<'a> {
187187
ast::GlobalDeclKind::Fn(ref f) => f.name,
188188
ast::GlobalDeclKind::Var(ref v) => v.name,
189189
ast::GlobalDeclKind::Const(ref c) => c.name,
190+
ast::GlobalDeclKind::Override(ref o) => o.name,
190191
ast::GlobalDeclKind::Struct(ref s) => s.name,
191192
ast::GlobalDeclKind::Type(ref t) => t.name,
192193
}

0 commit comments

Comments
 (0)