Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spv-out): add debug info for spv-out
Browse files Browse the repository at this point in the history
wicast committed Jun 13, 2023

Unverified

This user has not yet uploaded their public signing key.
1 parent 9b6e748 commit 438f3bc
Showing 10 changed files with 124 additions and 7 deletions.
21 changes: 20 additions & 1 deletion cli/src/bin/naga.rs
Original file line number Diff line number Diff line change
@@ -68,6 +68,10 @@ struct Args {
#[argh(option)]
stdin_file_path: Option<String>,

/// generate debug symbols, only works for spv-out for now
#[argh(option, short = 'g')]
generate_debug_symbols: Option<bool>,

/// show version
#[argh(switch)]
version: bool,
@@ -258,7 +262,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
}
params.keep_coordinate_space = args.keep_coordinate_space;

let (module, input_text) = match Path::new(&input_path)
let (mut module, input_text) = match Path::new(&input_path)
.extension()
.ok_or(CliError("Input filename has no extension"))?
.to_str()
@@ -316,6 +320,15 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
_ => return Err(CliError("Unknown input file extension").into()),
};

//Insert Debug infos
if args.generate_debug_symbols.unwrap_or_default() {
module.file_path = input_path
.as_os_str()
.to_str()
.map(ToString::to_string);
module.source_code = input_text.clone();
}

// Decide which capabilities our output formats can support.
let validation_caps =
output_paths
@@ -415,6 +428,12 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
};

params.spv.bounds_check_policies = params.bounds_check_policies;
if let Some(generate_debug_symbols) = args.generate_debug_symbols {
params
.spv
.flags
.set(spv::WriterFlags::DEBUG, generate_debug_symbols);
};
params.spv.flags.set(
spv::WriterFlags::ADJUST_COORDINATE_SPACE,
!params.keep_coordinate_space,
26 changes: 24 additions & 2 deletions src/back/spv/block.rs
Original file line number Diff line number Diff line change
@@ -60,6 +60,12 @@ pub enum BlockExit {
},
}

#[derive(Debug)]
pub struct DebugInfo<'a> {
pub source_code: &'a str,
pub source_file_id: Word,
}

impl Writer {
// Flip Y coordinate to adjust for coordinate space difference
// between SPIR-V and our IR.
@@ -1690,13 +1696,23 @@ impl<'w> BlockContext<'w> {
pub(super) fn write_block(
&mut self,
label_id: Word,
statements: &[crate::Statement],
naga_block: &crate::Block,
exit: BlockExit,
loop_context: LoopContext,
debug_info: Option<&DebugInfo>,
) -> Result<(), Error> {
let mut block = Block::new(label_id);

let statements = naga_block.iter();
let mut spans = naga_block.span_iter();
for statement in statements {
if let (Some(debug_info), Some((_, span))) = (debug_info, spans.next()) {
let loc: crate::SourceLocation = span.location(debug_info.source_code);
block.body.push(Instruction::line(
debug_info.source_file_id,
loc.line_number,
loc.line_position,
));
};
match *statement {
crate::Statement::Emit(ref range) => {
for handle in range.clone() {
@@ -1713,6 +1729,7 @@ impl<'w> BlockContext<'w> {
block_statements,
BlockExit::Branch { target: merge_id },
loop_context,
debug_info,
)?;

block = Block::new(merge_id);
@@ -1756,6 +1773,7 @@ impl<'w> BlockContext<'w> {
accept,
BlockExit::Branch { target: merge_id },
loop_context,
debug_info,
)?;
}
if let Some(block_id) = reject_id {
@@ -1764,6 +1782,7 @@ impl<'w> BlockContext<'w> {
reject,
BlockExit::Branch { target: merge_id },
loop_context,
debug_info,
)?;
}

@@ -1843,6 +1862,7 @@ impl<'w> BlockContext<'w> {
target: case_finish_id,
},
inner_context,
debug_info,
)?;
}

@@ -1881,6 +1901,7 @@ impl<'w> BlockContext<'w> {
continuing_id: Some(continuing_id),
break_id: Some(merge_id),
},
debug_info,
)?;

let exit = match break_if {
@@ -1901,6 +1922,7 @@ impl<'w> BlockContext<'w> {
continuing_id: None,
break_id: Some(merge_id),
},
debug_info,
)?;

block = Block::new(merge_id);
29 changes: 28 additions & 1 deletion src/back/spv/instructions.rs
Original file line number Diff line number Diff line change
@@ -21,10 +21,25 @@ impl super::Instruction {
// Debug Instructions
//

pub(super) fn source(source_language: spirv::SourceLanguage, version: u32) -> Self {
pub(super) fn string(name: &str, id: Word) -> Self {
let mut instruction = Self::new(Op::String);
instruction.set_result(id);
instruction.add_operands(helpers::string_to_words(name));
instruction
}

pub(super) fn source(
source_language: spirv::SourceLanguage,
version: u32,
source: Option<(Word, &str)>,
) -> Self {
let mut instruction = Self::new(Op::Source);
instruction.add_operand(source_language as u32);
instruction.add_operands(helpers::bytes_to_words(&version.to_le_bytes()));
if let Some((file, source)) = source {
instruction.add_operand(file);
instruction.add_operands(helpers::string_to_words(source));
}
instruction
}

@@ -43,6 +58,18 @@ impl super::Instruction {
instruction
}

pub(super) fn line(file: Word, line: Word, column: Word) -> Self {
let mut instruction = Self::new(Op::Line);
instruction.add_operand(file);
instruction.add_operand(line);
instruction.add_operand(column);
instruction
}

pub(super) const fn no_line() -> Self {
Self::new(Op::NoLine)
}

//
// Annotation Instructions
//
3 changes: 3 additions & 0 deletions src/back/spv/mod.rs
Original file line number Diff line number Diff line change
@@ -620,6 +620,9 @@ pub struct Writer {
saved_cached: CachedExpressions,

gl450_ext_inst_id: Word,

//used for OpString to track source code filename
source_file_id: Option<Word>,
// Just a temporary list of SPIR-V ids
temp_list: Vec<Word>,
}
40 changes: 37 additions & 3 deletions src/back/spv/writer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
block::DebugInfo,
helpers::{contains_builtin, global_needs_wrapper, map_storage_class},
make_local, Block, BlockContext, CachedConstant, CachedExpressions, EntryPointContext, Error,
Function, FunctionArgument, GlobalVariable, IdGenerator, Instruction, LocalType, LocalVariable,
@@ -12,7 +13,7 @@ use crate::{
valid::{FunctionInfo, ModuleInfo},
};
use spirv::Word;
use std::collections::hash_map::Entry;
use std::{collections::hash_map::Entry, path::Path};

struct FunctionInterface<'a> {
varying_ids: &'a mut Vec<Word>,
@@ -76,6 +77,7 @@ impl Writer {
binding_map: options.binding_map.clone(),
saved_cached: CachedExpressions::default(),
gl450_ext_inst_id,
source_file_id: None,
temp_list: Vec::new(),
})
}
@@ -111,6 +113,7 @@ impl Writer {
id_gen,
void_type,
gl450_ext_inst_id,
source_file_id: None,

// Recycled:
capabilities_used: take(&mut self.capabilities_used).recycle(),
@@ -688,11 +691,22 @@ impl Writer {
next_id
};

let debug_info = (|| {
if !context.writer.flags.contains(WriterFlags::DEBUG) {
return None;
}
Some(DebugInfo {
source_code: ir_module.source_code.as_ref()?,
source_file_id: context.writer.source_file_id?,
})
})();

context.write_block(
main_id,
&ir_function.body,
super::block::BlockExit::Return,
LoopContext::default(),
debug_info.as_ref(),
)?;

// Consume the `BlockContext`, ending its borrows and letting the
@@ -1772,8 +1786,28 @@ impl Writer {
.to_words(&mut self.logical_layout.ext_inst_imports);

if self.flags.contains(WriterFlags::DEBUG) {
self.debugs
.push(Instruction::source(spirv::SourceLanguage::GLSL, 450));
if let Some(file_name) = (|| {
Path::new(ir_module.file_path.as_ref()?)
.file_name()?
.to_str()
})() {
let source_file_id = self.id_gen.next();
self.source_file_id = Some(source_file_id);
self.debugs
.push(Instruction::string(file_name, source_file_id));
}

let debug_source_code = (|| {
Some((
self.source_file_id?,
ir_module.source_code.as_ref()?.as_str(),
))
})();
self.debugs.push(Instruction::source(
spirv::SourceLanguage::GLSL,
450,
debug_source_code,
));
}

self.constant_ids.resize(ir_module.constants.len(), 0);
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1941,4 +1941,9 @@ pub struct Module {
pub functions: Arena<Function>,
/// Entry points.
pub entry_points: Vec<EntryPoint>,

/// Source Code for debug
pub source_code: Option<String>,
/// File name for debug
pub file_path: Option<String>,
}
1 change: 1 addition & 0 deletions src/valid/handles.rs
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ impl super::Validator {
ref global_variables,
ref types,
ref special_types,
..
} = module;

// NOTE: Types being first is important. All other forms of validation depend on this.
2 changes: 2 additions & 0 deletions tests/out/ir/access.ron
Original file line number Diff line number Diff line change
@@ -2338,4 +2338,6 @@
),
),
],
source_code: None,
file_path: None,
)
2 changes: 2 additions & 0 deletions tests/out/ir/collatz.ron
Original file line number Diff line number Diff line change
@@ -329,4 +329,6 @@
),
),
],
source_code: None,
file_path: None,
)
2 changes: 2 additions & 0 deletions tests/out/ir/shadow.ron
Original file line number Diff line number Diff line change
@@ -1388,4 +1388,6 @@
),
),
],
source_code: None,
file_path: None,
)

0 comments on commit 438f3bc

Please sign in to comment.