reflect(wgsl): wgsl compile backend

This commit is contained in:
chyyran 2023-12-12 19:02:49 -05:00 committed by Ronny Chan
parent 1a16c4fadf
commit 4dfcdf2725
32 changed files with 8332 additions and 296 deletions

View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

31
.idea/librashader.iml Normal file
View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/librashader-build-script/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-cache/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-capi/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-preprocess/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-preprocess/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-presets/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-presets/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-reflect/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d11/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d11/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d12/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d12/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-gl/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-gl/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-vk/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-vk/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-wgpu/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-wgpu/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/librashader/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

307
.idea/workspace.xml Normal file
View file

@ -0,0 +1,307 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
</component>
<component name="ChangeListManager">
<list default="true" id="02471831-07cd-4975-a00c-e042450023a1" name="Changes" comment="rt(wgpu): load shaders" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ClangdSettings">
<option name="formatViaClangd" value="false" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Rust File" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/test/shaders_slang" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="z2x7agij" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 7
}</component>
<component name="ProjectId" id="2Ysjhh3i6f4DbiJQrmFUehu1xKM" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Cargo.Build `Test back::wgsl::test::test_into`.executor": "Run",
"Cargo.Build `Test reflect::cross::test::test_into`.executor": "Run",
"Cargo.Test back::wgsl::test::test_into.executor": "Run",
"Cargo.Test front::naga::test::naga_playground (1).executor": "Run",
"Cargo.Test front::naga::test::naga_playground.executor": "Run",
"Cargo.Test reflect::cross::test::test_into.executor": "Run",
"Cargo.Test triangle_wgpu.executor": "Run",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.RadMigrateCodeStyle": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"RunOnceActivity.readMode.enableVisualFormatting": "true",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
"git-widget-placeholder": "a6e11453",
"last_opened_file_path": "F:/coding/librashader",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="F:\coding\librashader\librashader-reflect\src\back\wgsl" />
<recent name="F:\coding\librashader\test" />
</key>
</component>
<component name="RunManager" selected="Cargo.Test back::wgsl::test::test_into">
<configuration name="Run librashader-build-script" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package librashader-build-script --bin librashader-build-script" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test back::wgsl::test::test_into" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="test --package librashader-reflect --lib back::wgsl::test::test_into -- --exact" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test front::naga::test::naga_playground (1)" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="test --package librashader-reflect --lib front::naga::test::naga_playground -- --exact" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test front::naga::test::naga_playground" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="test --package librashader-reflect --features=unstable-naga --lib front::naga::test::naga_playground -- --exact" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test librashader" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="test --workspace" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test reflect::cross::test::test_into" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="test --package librashader-reflect --lib reflect::cross::test::test_into -- --exact" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test triangle_wgpu" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="test --package librashader-runtime-wgpu --test triangle triangle_wgpu -- --exact" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<list>
<item itemvalue="Cargo.Run librashader-build-script" />
<item itemvalue="Cargo.Test librashader" />
<item itemvalue="Cargo.Test back::wgsl::test::test_into" />
<item itemvalue="Cargo.Test reflect::cross::test::test_into" />
<item itemvalue="Cargo.Test front::naga::test::naga_playground (1)" />
<item itemvalue="Cargo.Test front::naga::test::naga_playground" />
<item itemvalue="Cargo.Test triangle_wgpu" />
</list>
<recent_temporary>
<list>
<item itemvalue="Cargo.Test back::wgsl::test::test_into" />
<item itemvalue="Cargo.Test reflect::cross::test::test_into" />
<item itemvalue="Cargo.Test front::naga::test::naga_playground" />
<item itemvalue="Cargo.Test front::naga::test::naga_playground (1)" />
<item itemvalue="Cargo.Test triangle_wgpu" />
</list>
</recent_temporary>
</component>
<component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="D:/Runtime/Rust/cargo/bin" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="02471831-07cd-4975-a00c-e042450023a1" name="Changes" comment="" />
<created>1701321303955</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1701321303955</updated>
<workItem from="1701321304752" duration="311000" />
<workItem from="1701321897041" duration="13000" />
<workItem from="1701321923317" duration="5307000" />
<workItem from="1701411449889" duration="204000" />
<workItem from="1701412682043" duration="20000" />
<workItem from="1701414179779" duration="1478000" />
<workItem from="1701415757122" duration="150000" />
<workItem from="1701418112895" duration="439000" />
<workItem from="1701498553520" duration="6747000" />
<workItem from="1701558254529" duration="851000" />
<workItem from="1701579857592" duration="2065000" />
<workItem from="1701816737313" duration="1757000" />
<workItem from="1702100458574" duration="619000" />
<workItem from="1702163869988" duration="618000" />
<workItem from="1702419933111" duration="5007000" />
</task>
<task id="LOCAL-00001" summary="rt(wgpu): basic triangle example">
<option name="closed" value="true" />
<created>1701323569451</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1701323569451</updated>
</task>
<task id="LOCAL-00002" summary="rt(wgpu): load shaders">
<option name="closed" value="true" />
<created>1701326962929</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1701326962929</updated>
</task>
<task id="LOCAL-00003" summary="rt(wgpu): load shaders">
<option name="closed" value="true" />
<created>1701327197816</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1701327197816</updated>
</task>
<task id="LOCAL-00004" summary="rt(wgpu): load shaders">
<option name="closed" value="true" />
<created>1701327201979</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1701327201979</updated>
</task>
<option name="localTasksCounter" value="5" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VcsManagerConfiguration">
<ignored-roots>
<path value="$PROJECT_DIR$/.." />
</ignored-roots>
<MESSAGE value="rt(wgpu): basic triangle example" />
<MESSAGE value="rt(wgpu): load shaders" />
<option name="LAST_COMMIT_MESSAGE" value="rt(wgpu): load shaders" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/librashader-runtime-d3d12/src/filter_pass.rs</url>
<line>108</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

View file

@ -24,20 +24,23 @@ librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.2" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true }
naga = { version = "0.11.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
naga = { version = "0.14.2", features = ["spv-in", "wgsl-out"], optional = true }
rspirv = { version = "0.11.0+1.5.4", optional = true }
spirv = { version = "0.2.0+1.5.4", optional = true}
serde = { version = "1.0", features = ["derive"], optional = true }
indexmap = { version = "2.1.0", features = [] }
matches = { version = "0.1.10", features = [] }
[target.'cfg(windows)'.dependencies.spirv-to-dxil]
version = "0.4"
optional = true
[features]
default = ["cross", "serialize"]
unstable-naga = [ "naga", "rspirv" ]
standalone = ["shaderc/prefer-static-linking"]
default = ["cross", "wgsl", "serialize"]
standalone = ["shaderc/build-from-source", "shaderc/prefer-static-linking"]
dxil = ["cross", "spirv-to-dxil"]
wgsl = ["cross", "naga", "spirv", "rspirv"]
cross = [ "spirv_cross", "spirv_cross/glsl", "spirv_cross/hlsl" ]
serialize = [ "serde" ]

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

BIN
librashader-reflect/out.spv Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3,6 +3,7 @@ pub mod cross;
pub mod dxil;
mod spirv;
pub mod targets;
pub mod wgsl;
use crate::back::targets::OutputTarget;
use crate::error::{ShaderCompileError, ShaderReflectError};
@ -114,3 +115,14 @@ where
self.backend.reflect(pass_number, semantics)
}
}
#[cfg(test)]
mod test {
use crate::front::GlslangCompilation;
use librashader_preprocess::ShaderSource;
pub fn test() {
let result = ShaderSource::load("../test/basic.slang").unwrap();
let _cross = GlslangCompilation::compile(&result).unwrap();
}
}

View file

@ -18,16 +18,27 @@ pub struct MSL;
/// must be validated using platform APIs before usage.
pub struct DXIL;
/// Shader compiler target for WGSL.
///
/// The resulting WGSL will split sampler2Ds into
/// split textures and shaders. Shaders for each texture binding
/// will be in descriptor set 1.
#[derive(Debug)]
pub struct WGSL;
impl OutputTarget for GLSL {
type Output = String;
}
impl OutputTarget for HLSL {
type Output = String;
}
impl OutputTarget for WGSL {
type Output = String;
}
impl OutputTarget for SPIRV {
type Output = Vec<u32>;
}
#[cfg(test)]
mod test {
use crate::back::targets::GLSL;
use crate::back::FromCompilation;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,168 @@
mod lower_samplers;
use crate::back::targets::WGSL;
use crate::back::wgsl::lower_samplers::LowerCombinedImageSamplerPass;
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::GlslangCompilation;
use crate::reflect::naga::NagaReflect;
use crate::reflect::semantics::ShaderSemantics;
use crate::reflect::{ReflectShader, ShaderReflection};
use naga::back::wgsl::WriterFlags;
use naga::valid::{Capabilities, ValidationFlags};
use naga::Module;
use rspirv::binary::Assemble;
use rspirv::dr::Builder;
/// The context for a WGSL compilation via Naga
pub struct NagaWgslContext {
pub fragment: Module,
pub vertex: Module,
}
impl FromCompilation<GlslangCompilation> for WGSL {
type Target = WGSL;
type Options = Option<()>;
type Context = NagaWgslContext;
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
+ ReflectShader;
fn from_compilation(
compile: GlslangCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
fn lower_fragment_shader(words: &[u32]) -> Vec<u32> {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(words, &mut loader).unwrap();
let module = loader.module();
let mut builder = Builder::new_from_module(module);
let mut pass = LowerCombinedImageSamplerPass::new(&mut builder);
pass.ensure_op_type_sampler();
pass.do_pass();
let module = builder.module();
module.assemble()
}
let options = naga::front::spv::Options {
adjust_coordinate_space: false,
strict_capabilities: false,
block_ctx_dump_prefix: None,
};
let vertex =
naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&compile.vertex), &options)?;
let fragment = lower_fragment_shader(&compile.fragment);
let fragment = naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&fragment), &options)?;
Ok(CompilerBackend {
backend: NagaReflect { vertex, fragment },
})
}
}
impl CompileShader<WGSL> for NagaReflect {
type Options = Option<()>;
type Context = NagaWgslContext;
fn compile(
mut self,
_options: Self::Options,
) -> Result<ShaderCompilerOutput<String, Self::Context>, ShaderCompileError> {
fn write_wgsl(module: &Module) -> Result<String, ShaderCompileError> {
let mut valid =
naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty());
let info = valid.validate(&module)?;
let wgsl = naga::back::wgsl::write_string(&module, &info, WriterFlags::EXPLICIT_TYPES)?;
Ok(wgsl)
}
// Reassign shit.
let images = self
.fragment
.global_variables
.iter()
.filter(|&(_, gv)| {
let ty = &self.fragment.types[gv.ty];
match ty.inner {
naga::TypeInner::Image { .. } => true,
naga::TypeInner::BindingArray { base, .. } => {
let ty = &self.fragment.types[base];
matches!(ty.inner, naga::TypeInner::Image { .. })
}
_ => false,
}
})
.map(|(_, gv)| (gv.binding.clone(), gv.space))
.collect::<naga::FastHashSet<_>>();
self.fragment
.global_variables
.iter_mut()
.filter(|(_, gv)| {
let ty = &self.fragment.types[gv.ty];
match ty.inner {
naga::TypeInner::Sampler { .. } => true,
naga::TypeInner::BindingArray { base, .. } => {
let ty = &self.fragment.types[base];
matches!(ty.inner, naga::TypeInner::Sampler { .. })
}
_ => false,
}
})
.for_each(|(_, gv)| {
if images.contains(&(gv.binding.clone(), gv.space)) {
if let Some(binding) = &mut gv.binding {
binding.group = 1;
}
}
});
let fragment = write_wgsl(&self.fragment)?;
let vertex = write_wgsl(&self.vertex)?;
Ok(ShaderCompilerOutput {
vertex,
fragment,
context: NagaWgslContext {
fragment: self.fragment,
vertex: self.vertex,
},
})
}
}
#[cfg(test)]
mod test {
use crate::back::targets::WGSL;
use crate::back::{CompileShader, FromCompilation};
use librashader_preprocess::ShaderSource;
#[test]
pub fn test_into() {
let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap();
let wgsl = WGSL::from_compilation(compilation).unwrap();
let compiled = wgsl.compile(None).unwrap();
println!("{}", compiled.vertex);
println!("{}", compiled.fragment);
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
// let module = loader.module();
//
// let outputs: Vec<&Instruction> = module
// .types_global_values
// .iter()
// .filter(|i| i.class.opcode == Op::Variable)
// .collect();
//
// println!("{outputs:#?}");
}
}

View file

@ -26,6 +26,15 @@ pub enum ShaderCompileError {
#[cfg(all(target_os = "windows", feature = "dxil"))]
#[error("spirv-to-dxil")]
SpirvToDxilCompileError(#[from] spirv_to_dxil::SpirvToDxilError),
/// Error when transpiling from naga
#[cfg(feature = "wgsl")]
#[error("naga-wgsl")]
NagaWgslError(#[from] naga::back::wgsl::Error),
/// Error when transpiling from naga
#[cfg(feature = "wgsl")]
#[error("naga-wgsl")]
NagaValidationError(#[from] naga::WithSpan<naga::valid::ValidationError>),
}
/// The error kind encountered when reflecting shader semantics.
@ -59,11 +68,6 @@ pub enum SemanticsErrorKind {
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ShaderReflectError {
/// Compile error from naga.
#[cfg(feature = "unstable-naga")]
#[error("shader")]
NagaCompileError(#[from] naga::front::spv::Error),
/// Reflection error from spirv-cross.
#[error("spirv")]
SpirvCrossError(#[from] spirv_cross::ErrorCode),
@ -100,6 +104,11 @@ pub enum ShaderReflectError {
/// The binding number is already in use.
#[error("the binding is already in use")]
BindingInUse(u32),
/// Error when transpiling from naga
#[cfg(feature = "wgsl")]
#[error("naga-spv")]
NagaInputError(#[from] naga::front::spv::Error),
}
#[cfg(feature = "unstable-naga")]

View file

@ -1,16 +1,10 @@
use crate::error::ShaderCompileError;
use librashader_preprocess::ShaderSource;
#[cfg(feature = "unstable-naga")]
mod naga;
mod shaderc;
pub use crate::front::shaderc::GlslangCompilation;
#[cfg(feature = "unstable-naga")]
pub use crate::front::naga::NagaCompilation;
/// Trait for types that can compile shader sources into a compilation unit.
pub trait ShaderCompilation: Sized {
/// Compile the input shader source file into a compilation unit.

View file

@ -1,152 +0,0 @@
use crate::error::ShaderCompileError;
use librashader_preprocess::ShaderSource;
use naga::front::glsl::{Options, Parser};
use naga::{Module, ShaderStage};
/// A reflectable shader compilation via naga.
#[derive(Debug)]
pub struct NagaCompilation {
pub(crate) vertex: Module,
pub(crate) fragment: Module,
}
impl TryFrom<&ShaderSource> for NagaCompilation {
type Error = ShaderCompileError;
/// Tries to compile SPIR-V from the provided shader source.
fn try_from(source: &ShaderSource) -> Result<Self, Self::Error> {
compile_spirv(source)
}
}
fn compile_spirv(source: &ShaderSource) -> Result<NagaCompilation, ShaderCompileError> {
let mut parser = Parser::default();
let vertex = parser.parse(&Options::from(ShaderStage::Vertex), &source.vertex)?;
let fragment = parser.parse(&Options::from(ShaderStage::Fragment), &source.fragment)?;
Ok(NagaCompilation { vertex, fragment })
}
#[cfg(test)]
mod test {
use crate::front::naga::compile_spirv;
use crate::front::shaderc::GlslangCompilation;
use librashader_preprocess::ShaderSource;
use naga::back::glsl::{PipelineOptions, Version};
use naga::back::spv::{Capability, WriterFlags};
use naga::front::glsl::{Options, Parser};
use naga::front::spv::Options as SpvOptions;
use naga::valid::{Capabilities, ValidationFlags};
use naga::{FastHashSet, ShaderStage};
use rspirv::binary::Disassemble;
#[test]
pub fn compile_naga_test() {
let result = ShaderSource::load(
"../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
)
.unwrap();
let fragment_source = result.fragment;
let mut parser = Parser::default();
println!("{fragment_source}");
let _fragment = parser
.parse(&Options::from(ShaderStage::Fragment), &fragment_source)
.unwrap();
}
#[test]
pub fn compile_shader() {
let result = ShaderSource::load(
"../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
)
.unwrap();
let spirv = compile_spirv(&result).unwrap();
eprintln!("{spirv:?}")
}
#[test]
pub fn compile_shader_roundtrip() {
let result = ShaderSource::load("../test/basic.slang").unwrap();
let cross = GlslangCompilation::compile(&result).unwrap();
let naga_fragment =
naga::front::spv::parse_u8_slice(cross.fragment.as_binary_u8(), &SpvOptions::default())
.unwrap();
println!("{:#?}", naga_fragment.constants);
println!("{:#?}", naga_fragment.global_variables);
println!("{:#?}", naga_fragment.types);
}
#[test]
pub fn naga_playground() {
let result = ShaderSource::load("../test/basic.slang").unwrap();
let spirv = GlslangCompilation::compile(&result).unwrap();
let module =
naga::front::spv::parse_u8_slice(spirv.fragment.as_binary_u8(), &SpvOptions::default())
.unwrap();
let capability = FastHashSet::from_iter([Capability::Shader]);
let mut writer = naga::back::spv::Writer::new(&naga::back::spv::Options {
lang_version: (1, 0),
flags: WriterFlags::all(),
binding_map: Default::default(),
capabilities: Some(capability),
bounds_check_policies: Default::default(),
})
.unwrap();
let mut validator =
naga::valid::Validator::new(ValidationFlags::empty(), Capabilities::all());
let info = validator.validate(&module).unwrap();
let mut spv_out = Vec::new();
let pipe = naga::back::spv::PipelineOptions {
shader_stage: ShaderStage::Fragment,
entry_point: "main".to_string(),
};
writer
.write(&module, &info, Some(&pipe), &mut spv_out)
.unwrap();
let mut glsl_out = String::new();
let opts = naga::back::glsl::Options {
version: Version::Desktop(330),
writer_flags: naga::back::glsl::WriterFlags::all(),
binding_map: Default::default(),
};
let pipe = PipelineOptions {
shader_stage: ShaderStage::Fragment,
entry_point: "main".to_string(),
multiview: None,
};
let mut glsl_naga = naga::back::glsl::Writer::new(
&mut glsl_out,
&module,
&info,
&opts,
&pipe,
Default::default(),
)
.unwrap();
glsl_naga.write().unwrap();
let wgsl =
naga::back::wgsl::write_string(&module, &info, naga::back::wgsl::WriterFlags::all())
.unwrap();
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(&spv_out, &mut loader).unwrap();
let module = loader.module();
println!("--- spirv --");
println!("{:#}", module.disassemble());
println!("--- cross glsl --");
let loaded = spirv_cross::spirv::Module::from_words(&spv_out);
let mut ast = spirv_cross::spirv::Ast::<spirv_cross::glsl::Target>::parse(&loaded).unwrap();
println!("{:#}", ast.compile().unwrap());
println!("--- naga glsl---");
println!("{glsl_out:#}");
println!("--- naga wgsl---");
println!("{wgsl:#}")
}
}

View file

@ -922,9 +922,9 @@ mod test {
let mut opts = CompilerOptions::default();
opts.version = Version::V4_60;
opts.enable_420_pack_extension = false;
let compiled = reflect.compile(Version::V3_30).unwrap();
// eprintln!("{shader_reflection:#?}");
eprintln!("{:#}", compiled.fragment)
// let compiled: ShaderCompilerOutput<String, CrossWgslContext> = <CrossReflect<glsl::Target> as CompileShader<WGSL>>::compile(reflect, Version::V3_30).unwrap();
// // eprintln!("{shader_reflection:#?}");
// eprintln!("{}", compiled.fragment)
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap();
// let module = loader.module();

View file

@ -12,8 +12,8 @@ pub mod presets;
mod helper;
#[cfg(feature = "unstable-naga")]
mod naga;
#[cfg(feature = "wgsl")]
pub mod naga;
/// A trait for compilation outputs that can provide reflection information.
pub trait ReflectShader {

View file

@ -1,126 +1,73 @@
use crate::error::{SemanticsErrorKind, ShaderReflectError};
use crate::front::GlslangCompilation;
use crate::front::NagaCompilation;
use crate::error::ShaderReflectError;
use naga::front::spv::Options;
use naga::{GlobalVariable, Module, StructMember, Type, TypeInner};
use std::convert::Infallible;
use naga::Module;
use crate::reflect::semantics::ShaderSemantics;
use crate::reflect::{ReflectShader, ShaderReflection};
#[derive(Debug)]
pub struct NagaReflect {
vertex: Module,
fragment: Module,
pub(crate) vertex: Module,
pub(crate) fragment: Module,
}
impl TryFrom<NagaCompilation> for NagaReflect {
type Error = ShaderReflectError;
fn try_from(value: NagaCompilation) -> Result<Self, Self::Error> {
Ok(NagaReflect {
vertex: value.vertex,
fragment: value.fragment,
})
}
}
impl TryFrom<&GlslangCompilation> for NagaReflect {
type Error = ShaderReflectError;
fn try_from(value: &GlslangCompilation) -> Result<Self, Self::Error> {
let ops = Options::default();
let vertex =
naga::front::spv::Parser::new(value.vertex.clone().into_iter(), &ops).parse()?;
let fragment =
naga::front::spv::Parser::new(value.fragment.clone().into_iter(), &ops).parse()?;
Ok(NagaReflect { vertex, fragment })
}
}
struct UboData {
// id: u32,
// descriptor_set: u32,
binding: u32,
size: u32,
}
struct Ubo {
members: Vec<StructMember>,
span: u32,
}
impl TryFrom<naga::Type> for Ubo {
type Error = Infallible;
fn try_from(value: Type) -> Result<Self, Infallible> {
match value.inner {
TypeInner::Struct { members, span } => Ok(Ubo { members, span }),
// todo: make this programmer error
_ => panic!(),
}
}
}
//
// struct UboData {
// // id: u32,
// // descriptor_set: u32,
// binding: u32,
// size: u32,
// }
//
// struct Ubo {
// members: Vec<StructMember>,
// span: u32,
// }
//
// impl TryFrom<naga::Type> for Ubo {
// type Error = Infallible;
//
// fn try_from(value: Type) -> Result<Self, Infallible> {
// match value.inner {
// TypeInner::Struct { members, span } => Ok(Ubo { members, span }),
// // todo: make this programmer error
// _ => panic!(),
// }
// }
// }
impl NagaReflect {
// pub fn get_ubo_data(arena: Arena, variable: GlobalVariable, blame: SemanticErrorBlame) -> Result<UboData, ShaderReflectError> {
// let binding = match variable.binding {
// Some(ResourceBinding { group: 0, binding }) => binding,
// Some(ResourceBinding { group, .. }) => return Err(blame.error(SemanticsErrorKind::InvalidDescriptorSet(group))),
// None => return Err(blame.error(SemanticsErrorKind::InvalidDescriptorSet(u32::MAX))),
// };
//
// if binding >= MAX_BINDINGS_COUNT {
// return Err(blame.error(SemanticsErrorKind::InvalidBinding(binding)));
// }
//
// match variable.ty.as {
// Handle { .. } => {}
// }
// Ok(UboData {
// binding,
//
// })
// }
pub fn reflect_ubos(
vertex: GlobalVariable,
fragment: GlobalVariable,
) -> Result<(), ShaderReflectError> {
match (vertex.binding, fragment.binding) {
// todo: should emit for both but whatever
(None, None) | (Some(_), None) | (None, Some(_)) => {
ShaderReflectError::VertexSemanticError(SemanticsErrorKind::InvalidDescriptorSet(
u32::MAX,
))
}
(Some(_vert), Some(_frag)) => {
todo!();
}
};
todo!();
Ok(())
}
impl ReflectShader for NagaReflect {
fn reflect(
&mut self,
pass_number: usize,
semantics: &ShaderSemantics,
) -> Result<ShaderReflection, ShaderReflectError> {
todo!()
}
}
#[cfg(test)]
mod test {
use librashader_preprocess::ShaderSource;
use rspirv::dr::Instruction;
use rspirv::spirv::Op;
#[test]
pub fn test_into() {
let result = ShaderSource::load("../test/slang-shaders/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap();
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
let module = loader.module();
let outputs: Vec<&Instruction> = module
.types_global_values
.iter()
.filter(|i| i.class.opcode == Op::Variable)
.collect();
println!("{outputs:#?}");
}
// #[test]
// pub fn test_into() {
// let result = ShaderSource::load("../test/slang-shaders/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
// let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap();
//
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
// let module = loader.module();
//
// let outputs: Vec<&Instruction> = module
// .types_global_values
// .iter()
// .filter(|i| i.class.opcode == Op::Variable)
// .collect();
//
// println!("{outputs:#?}");
// }
}

View file

@ -6,12 +6,12 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.1.4" }
librashader-presets = { path = "../librashader-presets", version = "0.1.4" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.4" }
librashader-reflect = { path = "../librashader-reflect", version = "0.1.4", features = [] }
librashader-runtime = { path = "../librashader-runtime" , version = "0.1.4" }
librashader-cache = { path = "../librashader-cache", version = "0.1.4" }
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.2.0-beta.2" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.2" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.2" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.2", features = [] }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.2" }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.2" }
wgpu = { version = "0.18.0", features = ["spirv"] }
rustc-hash = "1.1.0"

View file

@ -1,14 +1,99 @@
use std::borrow::Cow;
use std::num::NonZeroU32;
use std::sync::Arc;
use wgpu::{Device, ShaderModule, ShaderSource, TextureFormat};
use wgpu::{BindGroup, BindGroupDescriptor, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BufferBindingType, BufferSize, Device, PipelineLayout, PushConstantRange, ShaderModule, ShaderSource, ShaderStages, TextureFormat};
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::UboReflection;
use librashader_reflect::reflect::ShaderReflection;
use crate::util;
pub struct WgpuGraphicsPipeline {
vertex: ShaderModule,
fragment: ShaderModule
}
pub struct PipelineLayoutObjects {
pub layout: PipelineLayout,
pub bind_groups: Vec<BindGroup>,
pub bind_group_layouts: Vec<BindGroupLayout>
}
pub fn add_ubo_binding(&mut self, ubo_meta: Option<&UboReflection>) {
}
pub fn add_texture_bindings<'a>(&mut self, textures: impl Iterator<Item = &'a TextureBinding>) {
let texture_mask = vk::ShaderStageFlags::FRAGMENT;
for texture in textures {
self.layout_bindings.push(vk::DescriptorSetLayoutBinding {
binding: texture.binding,
descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
descriptor_count: 1,
stage_flags: texture_mask,
p_immutable_samplers: std::ptr::null(),
});
self.pool_sizes.push(vk::DescriptorPoolSize {
ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
descriptor_count: self.replicas,
})
}
}
impl PipelineLayoutObjects {
pub fn new(
reflection: &ShaderReflection,
device: &Device
) -> Self {
let push_constant_range = reflection.push_constant
.as_ref()
.map(|push_constant| {
let stage_mask = util::binding_stage_to_wgpu_stage(push_constant.stage_mask);
[PushConstantRange {
stages: stage_mask,
range: 0..push_constant.size,
}]
});
let mut bind_group_layouts = Vec::new();
if let Some(ubo_meta) = reflection.ubo.as_ref() && !ubo_meta.stage_mask.is_empty() {
let ubo_mask = util::binding_stage_to_wgpu_stage(ubo_meta.stage_mask);
let ubo_bind_group = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
label: Some("ubo bind group"),
entries: &[BindGroupLayoutEntry {
binding: ubo_meta.binding,
visibility: ubo_mask,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: BufferSize::new(ubo_meta.size as u64),
},
count: Some(NonZeroU32::MIN),
}],
});
bind_group_layouts.push(ubo_bind_group)
}
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("shader pipeline layout"),
bind_group_layouts: &[],
push_constant_ranges: push_constant_range.as_ref()
.unwrap_or(&[]),
});
Self {
layout,
bind_groups: vec![],
bind_group_layouts
}
}
}
impl WgpuGraphicsPipeline {
pub fn new(
device: &Device,
@ -16,6 +101,7 @@ impl WgpuGraphicsPipeline {
reflection: &ShaderReflection,
render_pass_format: TextureFormat,
) -> Self {
// todo: naga shaders man.
let vertex = unsafe {
device.create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV {
label: Some("vertex"),
@ -30,12 +116,9 @@ impl WgpuGraphicsPipeline {
})
};
// let render_pipeline_layout =
// device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
// label: Some("Render Pipeline Layout"),
// bind_group_layouts: &[],
// push_constant_ranges: &[],
// });
Self {
vertex,
fragment

View file

@ -13,6 +13,7 @@ mod error;
mod texture;
mod filter_pass;
mod graphics_pipeline;
mod util;
pub use filter_chain::FilterChainWGPU;
pub use filter_pass::FilterPass;

View file

@ -0,0 +1,15 @@
use wgpu::ShaderStages;
use librashader_reflect::reflect::semantics::BindingStage;
pub fn binding_stage_to_wgpu_stage(stage_mask: BindingStage) -> ShaderStages {
let mut mask = ShaderStages::empty();
if stage_mask.contains(BindingStage::VERTEX) {
mask |= ShaderStages::VERTEX;
}
if stage_mask.contains(BindingStage::FRAGMENT) {
mask |= ShaderStages::FRAGMENT;
}
mask
}

24
test/extreme_basic.glsl Normal file
View file

@ -0,0 +1,24 @@
#version 450
layout(set = 0, binding = 0, std140) uniform UBO
{
mat4 MVP;
};
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) out vec4 color;
layout(binding = 1) uniform sampler2D tex;
void main() {
color = texture(tex, vec2(0.0));
}

0
test/extreme_basic.spv Normal file
View file

View file

@ -0,0 +1,9 @@
#version 450
layout(location = 0) out vec4 color;
layout(set = 0, binding = 1) uniform texture2D tex;
layout(set = 1, binding = 1) uniform sampler tex_sampler;
void main() {
color = texture(sampler2D(tex, tex_sampler), vec2(0.0));
}

View file

@ -0,0 +1,47 @@
module.dialect = spv.Module(version: 1.0, spv.Capability.{Shader, Sampled1D}, spv.MemoryModel.GLSL450)
module.debug_info = spv.Module.DebugInfo(generator: spv.Tool(id: 0, version: 28))
type T0 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown)
#[spv.Decoration.Location(Location: 0)]
global_var GV0(spv.StorageClass.Output): f32×4
#[spv.Decoration.Binding(BindingPoint: 1)]
#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
global_var GV1(spv.StorageClass.UniformConstant): T0
#[spv.Decoration.Binding(BindingPoint: 1)]
#[spv.Decoration.DescriptorSet(DescriptorSet: 1)]
global_var GV2(spv.StorageClass.UniformConstant): spv.OpTypeSampler
global_var GV3(spv.StorageClass.Private, init: f32×4(0.0, 0.0, 0.0, 0.0)): f32×4
func F0() {
v0 = spv.OpLoad(Pointer: &GV1): T0
v1 = spv.OpLoad(Pointer: &GV2): spv.OpTypeSampler
branch L0
label L0:
v2 = spv.OpSampledImage(Image: v0, Sampler: v1): spv.OpTypeSampledImage(ImageType: T0)
v3 = spv.OpImageSampleImplicitLod(SampledImage: v2, Coordinate: f32×2(0.0, 0.0)): f32×4
spv.OpStore(Pointer: &GV3, Object: v3)
return
}
#[spv.ExecutionMode.OriginUpperLeft]
func F1() {
_ = spv.OpLoad(Pointer: &GV1): T0
_ = spv.OpLoad(Pointer: &GV2): spv.OpTypeSampler
branch L0
label L0:
call F0()
v0 = spv.OpLoad(Pointer: &GV3): f32×4
spv.OpStore(Pointer: &GV0, Object: v0)
return
}
export {
spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F1,
}

View file

@ -0,0 +1,122 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d {
/* HACK(eddyb) reset default margin to something reasonable. */
margin: 1ch;
/* HACK(eddyb) avoid unnecessarily small or thin text. */
font-size: 17px;
font-weight: 500;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d a {
color: unset;
font-weight: 900;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d a:not(:hover) {
text-decoration: unset;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d sub, pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d sup {
line-height: 0;
}
/* HACK(eddyb) using a class (instead of an inline style) so that hovering
over a multiversion table cell can disable its desaturation/dimming */
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d:not(:hover) .unchanged {
filter: saturate(0.3) opacity(0.5);
}
</style>
<script>
(function() {
var params = new URLSearchParams(document.location.search);
var dark = params.has("dark"), light = params.has("light");
if(dark || light) {
if(dark && !light) {
document.documentElement.classList.add("simple-dark-theme");
// HACK(eddyb) forcefully disable Dark Reader, for two reasons:
// - its own detection of websites with built-in dark themes
// (https://github.com/darkreader/darkreader/pull/7995)
// isn't on by default, and the combination is jarring
// - it interacts badly with whole-document-replacement
// (as used by htmlpreview.github.io)
document.documentElement.removeAttribute('data-darkreader-scheme');
document.querySelectorAll('style.darkreader')
.forEach(style => style.disabled = true);
}
} else if(matchMedia("(prefers-color-scheme: dark)").matches) {
// FIXME(eddyb) also use media queries in CSS directly, to ensure dark mode
// still works with JS disabled (sadly that likely requires CSS duplication).
document.location.search += (document.location.search ? "&" : "?") + "dark";
}
})();
</script>
<style>
/* HACK(eddyb) `[data-darkreader-scheme="dark"]` is for detecting Dark Reader,
to avoid transient interactions (see also comment in the `<script>`). */
html.simple-dark-theme:not([data-darkreader-scheme="dark"]) {
background: #16181a;
color: #dbd8d6;
/* Request browser UI elements to be dark-themed if possible. */
color-scheme: dark;
}
</style>
</head>
<body><pre class="spirt-90c2056d-5b38-4644-824a-b4be1c82f14d">
<a id="module.dialect" href="#module.dialect">module.dialect</a><a id="module.dialect.start" href="#module.dialect.start"></a> = <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;">Module</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">version: </span><span style="color:#cc9944;">1</span>.<span style="color:#cc9944;">0</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Capability.</span>{<span style="color:#4499cc;">Shader</span>, <span style="color:#4499cc;">Sampled1D</span>}, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">MemoryModel.</span><span style="color:#4499cc;">GLSL450</span>)
<a id="module.debug_info" href="#module.debug_info">module.debug_info</a><a id="module.debug_info.start" href="#module.debug_info.start"></a> = <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">Module.</span><span style="color:#cc7755;">DebugInfo</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">generator: </span><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;">Tool</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">id: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">version: </span><span style="color:#cc9944;">28</span>))
<a id="T0" href="#T0">type T<sub style="font-size:0.9em;">0</sub></a> = <a id="T0.start" href="#T0.start"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">SampledType: </span><span style="color:#4466cc;">f32</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Dim.</span><span style="color:#4499cc;">2D</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Depth: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Arrayed: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">MS: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Sampled: </span><span style="color:#cc9944;">1</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ImageFormat.</span><span style="color:#4499cc;">Unknown</span>)
<a id="GV0" href="#GV0"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Location</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Location: </span><span style="color:#cc9944;">0</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV0">global_var GV<sub style="font-size:0.9em;">0</sub></a><a id="GV0.start" href="#GV0.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">Output</span>): <span style="color:#4466cc;">f32×4</span>
<a id="GV1" href="#GV1"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Binding</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">BindingPoint: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">DescriptorSet</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">DescriptorSet: </span><span style="color:#cc9944;">0</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV1">global_var GV<sub style="font-size:0.9em;">1</sub></a><a id="GV1.start" href="#GV1.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">UniformConstant</span>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
<a id="GV2" href="#GV2"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Binding</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">BindingPoint: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">DescriptorSet</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">DescriptorSet: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV2">global_var GV<sub style="font-size:0.9em;">2</sub></a><a id="GV2.start" href="#GV2.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">UniformConstant</span>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<a id="GV3" href="#GV3">global_var GV<sub style="font-size:0.9em;">3</sub></a><a id="GV3.start" href="#GV3.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">Private</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">init: </span><span style="color:#4466cc;">f32×4</span>(<span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>)): <span style="color:#4466cc;">f32×4</span>
<a id="F0" href="#F0">func F<sub style="font-size:0.9em;">0</sub></a><a id="F0.start" href="#F0.start"></a>() {
<a id="F0.AA.0" href="#F0.AA.0"></a><a id="F0.AA.1" href="#F0.AA.1"></a> <a id="F0.v0" href="#F0.v0">v<sub style="font-size:0.8em;">0</sub></a> = <a id="F0.AA.2" href="#F0.AA.2"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV1">GV<sub style="font-size:0.9em;">1</sub></a>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
<a id="F0.v1" href="#F0.v1">v<sub style="font-size:0.8em;">1</sub></a> = <a id="F0.AA.3" href="#F0.AA.3"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV2">GV<sub style="font-size:0.9em;">2</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<span style="color:#cc44cc;font-weight:700;">branch</span> <a href="#F0.L0">L<sub style="font-size:0.9em;">0</sub></a>
<a id="F0.L0" href="#F0.L0">label L<sub style="font-size:0.9em;">0</sub></a>:
<a id="F0.AA.4" href="#F0.AA.4"></a><a id="F0.AA.5" href="#F0.AA.5"></a> <a id="F0.v2" href="#F0.v2">v<sub style="font-size:0.8em;">2</sub></a> = <a id="F0.AA.6" href="#F0.AA.6"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpSampledImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Image: </span><a href="#F0.v0">v<sub style="font-size:0.8em;">0</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Sampler: </span><a href="#F0.v1">v<sub style="font-size:0.8em;">1</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampledImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">ImageType: </span><a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>)
<a id="F0.v3" href="#F0.v3">v<sub style="font-size:0.8em;">3</sub></a> = <a id="F0.AA.7" href="#F0.AA.7"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpImageSampleImplicitLod</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">SampledImage: </span><a href="#F0.v2">v<sub style="font-size:0.8em;">2</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Coordinate: </span><span style="color:#4466cc;">f32×2</span>(<span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>)): <span style="color:#4466cc;">f32×4</span>
<a id="F0.AA.8" href="#F0.AA.8"></a> <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpStore</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV3">GV<sub style="font-size:0.9em;">3</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Object: </span><a href="#F0.v3">v<sub style="font-size:0.8em;">3</sub></a>)
<span style="color:#cc44cc;font-weight:700;">return</span>
}
<a id="F1" href="#F1"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ExecutionMode.</span><span style="color:#4499cc;">OriginUpperLeft</span><span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#F1">func F<sub style="font-size:0.9em;">1</sub></a><a id="F1.start" href="#F1.start"></a>() {
<a id="F1.AA.0" href="#F1.AA.0"></a><a id="F1.AA.1" href="#F1.AA.1"></a> _ = <a id="F1.AA.2" href="#F1.AA.2"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV1">GV<sub style="font-size:0.9em;">1</sub></a>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
_ = <a id="F1.AA.3" href="#F1.AA.3"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV2">GV<sub style="font-size:0.9em;">2</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<span style="color:#cc44cc;font-weight:700;">branch</span> <a href="#F1.L0">L<sub style="font-size:0.9em;">0</sub></a>
<a id="F1.L0" href="#F1.L0">label L<sub style="font-size:0.9em;">0</sub></a>:
<a id="F1.AA.4" href="#F1.AA.4"></a><a id="F1.AA.5" href="#F1.AA.5"></a><a id="F1.AA.6" href="#F1.AA.6"></a> <span style="color:#4466cc;">call</span> <a href="#F0">F<sub style="font-size:0.9em;">0</sub></a>()
<a id="F1.v0" href="#F1.v0">v<sub style="font-size:0.8em;">0</sub></a> = <a id="F1.AA.7" href="#F1.AA.7"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV3">GV<sub style="font-size:0.9em;">3</sub></a>): <span style="color:#4466cc;">f32×4</span>
<a id="F1.AA.8" href="#F1.AA.8"></a> <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpStore</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV0">GV<sub style="font-size:0.9em;">0</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Object: </span><a href="#F1.v0">v<sub style="font-size:0.8em;">0</sub></a>)
<span style="color:#cc44cc;font-weight:700;">return</span>
}
<span style="color:#4466cc;">export</span> {
<span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpEntryPoint</span>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ExecutionModel.</span><span style="color:#4499cc;">Fragment</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Name: </span><span style="color:#cc5555;">"main"</span>): <a href="#F1">F<sub style="font-size:0.9em;">1</sub></a>,
}</pre></body>
</html>

Binary file not shown.

View file

@ -0,0 +1,39 @@
module.dialect = spv.Module(version: 1.0, spv.Capability.{Shader, Sampled1D}, spv.MemoryModel.GLSL450)
module.debug_info = spv.Module.DebugInfo(generator: spv.Tool(id: 0, version: 28))
type T0 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown)
#[spv.Decoration.Location(Location: 0)]
global_var GV0(spv.StorageClass.Output): f32×4
#[spv.Decoration.Binding(BindingPoint: 1)]
#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
global_var GV1(spv.StorageClass.UniformConstant): T0
#[spv.Decoration.Binding(BindingPoint: 1)]
#[spv.Decoration.DescriptorSet(DescriptorSet: 1)]
global_var GV2(spv.StorageClass.UniformConstant): spv.OpTypeSampler
global_var GV3(spv.StorageClass.Private, init: f32×4(0.0, 0.0, 0.0, 0.0)): f32×4
func F0() {
v0 = spv.OpLoad(Pointer: &GV1): T0
v1 = spv.OpLoad(Pointer: &GV2): spv.OpTypeSampler
v2 = spv.OpSampledImage(Image: v0, Sampler: v1): spv.OpTypeSampledImage(ImageType: T0)
v3 = spv.OpImageSampleImplicitLod(SampledImage: v2, Coordinate: f32×2(0.0, 0.0)): f32×4
spv.OpStore(Pointer: &GV3, Object: v3)
}
#[spv.ExecutionMode.OriginUpperLeft]
func F1() {
_ = spv.OpLoad(Pointer: &GV1): T0
_ = spv.OpLoad(Pointer: &GV2): spv.OpTypeSampler
call F0()
v0 = spv.OpLoad(Pointer: &GV3): f32×4
spv.OpStore(Pointer: &GV0, Object: v0)
}
export {
spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F1,
}

View file

@ -0,0 +1,114 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d {
/* HACK(eddyb) reset default margin to something reasonable. */
margin: 1ch;
/* HACK(eddyb) avoid unnecessarily small or thin text. */
font-size: 17px;
font-weight: 500;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d a {
color: unset;
font-weight: 900;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d a:not(:hover) {
text-decoration: unset;
}
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d sub, pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d sup {
line-height: 0;
}
/* HACK(eddyb) using a class (instead of an inline style) so that hovering
over a multiversion table cell can disable its desaturation/dimming */
pre.spirt-90c2056d-5b38-4644-824a-b4be1c82f14d:not(:hover) .unchanged {
filter: saturate(0.3) opacity(0.5);
}
</style>
<script>
(function() {
var params = new URLSearchParams(document.location.search);
var dark = params.has("dark"), light = params.has("light");
if(dark || light) {
if(dark && !light) {
document.documentElement.classList.add("simple-dark-theme");
// HACK(eddyb) forcefully disable Dark Reader, for two reasons:
// - its own detection of websites with built-in dark themes
// (https://github.com/darkreader/darkreader/pull/7995)
// isn't on by default, and the combination is jarring
// - it interacts badly with whole-document-replacement
// (as used by htmlpreview.github.io)
document.documentElement.removeAttribute('data-darkreader-scheme');
document.querySelectorAll('style.darkreader')
.forEach(style => style.disabled = true);
}
} else if(matchMedia("(prefers-color-scheme: dark)").matches) {
// FIXME(eddyb) also use media queries in CSS directly, to ensure dark mode
// still works with JS disabled (sadly that likely requires CSS duplication).
document.location.search += (document.location.search ? "&" : "?") + "dark";
}
})();
</script>
<style>
/* HACK(eddyb) `[data-darkreader-scheme="dark"]` is for detecting Dark Reader,
to avoid transient interactions (see also comment in the `<script>`). */
html.simple-dark-theme:not([data-darkreader-scheme="dark"]) {
background: #16181a;
color: #dbd8d6;
/* Request browser UI elements to be dark-themed if possible. */
color-scheme: dark;
}
</style>
</head>
<body><pre class="spirt-90c2056d-5b38-4644-824a-b4be1c82f14d">
<a id="module.dialect" href="#module.dialect">module.dialect</a><a id="module.dialect.start" href="#module.dialect.start"></a> = <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;">Module</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">version: </span><span style="color:#cc9944;">1</span>.<span style="color:#cc9944;">0</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Capability.</span>{<span style="color:#4499cc;">Shader</span>, <span style="color:#4499cc;">Sampled1D</span>}, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">MemoryModel.</span><span style="color:#4499cc;">GLSL450</span>)
<a id="module.debug_info" href="#module.debug_info">module.debug_info</a><a id="module.debug_info.start" href="#module.debug_info.start"></a> = <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">Module.</span><span style="color:#cc7755;">DebugInfo</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">generator: </span><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;">Tool</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">id: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">version: </span><span style="color:#cc9944;">28</span>))
<a id="T0" href="#T0">type T<sub style="font-size:0.9em;">0</sub></a> = <a id="T0.start" href="#T0.start"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">SampledType: </span><span style="color:#4466cc;">f32</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Dim.</span><span style="color:#4499cc;">2D</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Depth: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Arrayed: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">MS: </span><span style="color:#cc9944;">0</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Sampled: </span><span style="color:#cc9944;">1</span>, <span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ImageFormat.</span><span style="color:#4499cc;">Unknown</span>)
<a id="GV0" href="#GV0"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Location</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Location: </span><span style="color:#cc9944;">0</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV0">global_var GV<sub style="font-size:0.9em;">0</sub></a><a id="GV0.start" href="#GV0.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">Output</span>): <span style="color:#4466cc;">f32×4</span>
<a id="GV1" href="#GV1"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Binding</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">BindingPoint: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">DescriptorSet</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">DescriptorSet: </span><span style="color:#cc9944;">0</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV1">global_var GV<sub style="font-size:0.9em;">1</sub></a><a id="GV1.start" href="#GV1.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">UniformConstant</span>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
<a id="GV2" href="#GV2"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">Binding</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">BindingPoint: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">Decoration.</span><span style="color:#4499cc;">DescriptorSet</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">DescriptorSet: </span><span style="color:#cc9944;">1</span>)<span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#GV2">global_var GV<sub style="font-size:0.9em;">2</sub></a><a id="GV2.start" href="#GV2.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">UniformConstant</span>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<a id="GV3" href="#GV3">global_var GV<sub style="font-size:0.9em;">3</sub></a><a id="GV3.start" href="#GV3.start"></a>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">StorageClass.</span><span style="color:#4499cc;">Private</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">init: </span><span style="color:#4466cc;">f32×4</span>(<span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>)): <span style="color:#4466cc;">f32×4</span>
<a id="F0" href="#F0">func F<sub style="font-size:0.9em;">0</sub></a><a id="F0.start" href="#F0.start"></a>() {
<a id="F0.AA.0" href="#F0.AA.0"></a><a id="F0.AA.1" href="#F0.AA.1"></a> <a id="F0.v0" href="#F0.v0">v<sub style="font-size:0.8em;">0</sub></a> = <a id="F0.AA.2" href="#F0.AA.2"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV1">GV<sub style="font-size:0.9em;">1</sub></a>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
<a id="F0.v1" href="#F0.v1">v<sub style="font-size:0.8em;">1</sub></a> = <a id="F0.AA.3" href="#F0.AA.3"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV2">GV<sub style="font-size:0.9em;">2</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<a id="F0.AA.4" href="#F0.AA.4"></a> <a id="F0.v2" href="#F0.v2">v<sub style="font-size:0.8em;">2</sub></a> = <a id="F0.AA.5" href="#F0.AA.5"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpSampledImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Image: </span><a href="#F0.v0">v<sub style="font-size:0.8em;">0</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Sampler: </span><a href="#F0.v1">v<sub style="font-size:0.8em;">1</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampledImage</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">ImageType: </span><a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>)
<a id="F0.v3" href="#F0.v3">v<sub style="font-size:0.8em;">3</sub></a> = <a id="F0.AA.6" href="#F0.AA.6"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpImageSampleImplicitLod</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">SampledImage: </span><a href="#F0.v2">v<sub style="font-size:0.8em;">2</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Coordinate: </span><span style="color:#4466cc;">f32×2</span>(<span style="color:#cc9944;">0.0</span>, <span style="color:#cc9944;">0.0</span>)): <span style="color:#4466cc;">f32×4</span>
<a id="F0.AA.7" href="#F0.AA.7"></a> <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpStore</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV3">GV<sub style="font-size:0.9em;">3</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Object: </span><a href="#F0.v3">v<sub style="font-size:0.8em;">3</sub></a>)
}
<a id="F1" href="#F1"></a><span style="color:rgba(68,153,68,0.6);font-weight:300;">#[</span><span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ExecutionMode.</span><span style="color:#4499cc;">OriginUpperLeft</span><span style="color:rgba(68,153,68,0.6);font-weight:300;">]</span>
<a href="#F1">func F<sub style="font-size:0.9em;">1</sub></a><a id="F1.start" href="#F1.start"></a>() {
<a id="F1.AA.0" href="#F1.AA.0"></a><a id="F1.AA.1" href="#F1.AA.1"></a> _ = <a id="F1.AA.2" href="#F1.AA.2"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV1">GV<sub style="font-size:0.9em;">1</sub></a>): <a href="#T0">T<sub style="font-size:0.9em;">0</sub></a>
_ = <a id="F1.AA.3" href="#F1.AA.3"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV2">GV<sub style="font-size:0.9em;">2</sub></a>): <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpTypeSampler</span>
<a id="F1.AA.4" href="#F1.AA.4"></a><a id="F1.AA.5" href="#F1.AA.5"></a> <span style="color:#4466cc;">call</span> <a href="#F0">F<sub style="font-size:0.9em;">0</sub></a>()
<a id="F1.v0" href="#F1.v0">v<sub style="font-size:0.8em;">0</sub></a> = <a id="F1.AA.6" href="#F1.AA.6"></a><span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpLoad</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV3">GV<sub style="font-size:0.9em;">3</sub></a>): <span style="color:#4466cc;">f32×4</span>
<a id="F1.AA.7" href="#F1.AA.7"></a> <span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpStore</span>(<span style="color:#444444;font-size:0.5em;vertical-align:middle;">Pointer: </span>&amp;<a href="#GV0">GV<sub style="font-size:0.9em;">0</sub></a>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Object: </span><a href="#F1.v0">v<sub style="font-size:0.8em;">0</sub></a>)
}
<span style="color:#4466cc;">export</span> {
<span style="color:rgba(204,119,85,0.6);font-size:0.6em;vertical-align:middle;">spv.</span><span style="color:#cc7755;font-weight:800;">OpEntryPoint</span>(<span style="color:rgba(204,119,85,0.36);font-size:0.5em;vertical-align:middle;">spv.</span><span style="color:rgba(68,102,204,0.6);font-size:0.6em;vertical-align:middle;">ExecutionModel.</span><span style="color:#4499cc;">Fragment</span>, <span style="color:#444444;font-size:0.5em;vertical-align:middle;">Name: </span><span style="color:#cc5555;">"main"</span>): <a href="#F1">F<sub style="font-size:0.9em;">1</sub></a>,
}</pre></body>
</html>