diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/librashader.iml b/.idea/librashader.iml new file mode 100644 index 0000000..b3ffd65 --- /dev/null +++ b/.idea/librashader.iml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..8a8c1d3 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + { + "customColor": "", + "associatedIndex": 7 +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1701321303955 + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/librashader-runtime-d3d12/src/filter_pass.rs + 108 + + + + + \ No newline at end of file diff --git a/librashader-reflect/Cargo.toml b/librashader-reflect/Cargo.toml index 857dac6..5e1554d 100644 --- a/librashader-reflect/Cargo.toml +++ b/librashader-reflect/Cargo.toml @@ -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" ] diff --git a/librashader-reflect/basic.spv b/librashader-reflect/basic.spv new file mode 100644 index 0000000..b06f8fb Binary files /dev/null and b/librashader-reflect/basic.spv differ diff --git a/librashader-reflect/out.spirt b/librashader-reflect/out.spirt new file mode 100644 index 0000000..a0dd624 --- /dev/null +++ b/librashader-reflect/out.spirt @@ -0,0 +1,1549 @@ +module.dialect = spv.Module(version: 1.0, spv.Capability.Shader, spv.MemoryModel.GLSL450) + +module.debug_info = spv.Module.DebugInfo( + generator: spv.Tool(id: 15), + source_languages: { + spv.SourceLanguage.GLSL(version: 450): {}, + }, + source_extensions: ["GL_GOOGLE_cpp_style_line_directive", "GL_GOOGLE_include_directive"], +) + +type T0 = spv.OpTypePointer(spv.StorageClass.Function, f32×3) + +type T1 = spv.OpTypePointer(spv.StorageClass.Function, f32×2) + +type T2 = spv.OpTypePointer(spv.StorageClass.Function, f32) + +type T3 = spv.OpTypePointer(spv.StorageClass.Function, f32×4) + +type T4 = spv.OpTypePointer(spv.StorageClass.PushConstant, f32) + +#[spv.OpMemberName(Member: 0, Name: "SourceSize")] +#[spv.OpMemberName(Member: 1, Name: "OriginalSize")] +#[spv.OpMemberName(Member: 2, Name: "OutputSize")] +#[spv.OpMemberName(Member: 3, Name: "VERTICAL_SCANLINESSize")] +#[spv.OpMemberName(Member: 4, Name: "BLOOM_APPROXSize")] +#[spv.OpMemberName(Member: 5, Name: "HALATION_BLURSize")] +#[spv.OpMemberName(Member: 6, Name: "MASK_RESIZESize")] +#[spv.Decoration.Block] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))] +#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 16))] +#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 32))] +#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 48))] +#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 64))] +#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))] +#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 96))] +type T`Push` = spv.OpTypeStruct(f32×4, f32×4, f32×4, f32×4, f32×4, f32×4, f32×4) + +type T5 = spv.OpTypePointer(spv.StorageClass.Uniform, f32) + +#[spv.OpMemberName(Member: 0, Name: "MVP")] +#[spv.OpMemberName(Member: 1, Name: "crt_gamma")] +#[spv.OpMemberName(Member: 2, Name: "lcd_gamma")] +#[spv.OpMemberName(Member: 3, Name: "levels_contrast")] +#[spv.OpMemberName(Member: 4, Name: "halation_weight")] +#[spv.OpMemberName(Member: 5, Name: "diffusion_weight")] +#[spv.OpMemberName(Member: 6, Name: "bloom_underestimate_levels")] +#[spv.OpMemberName(Member: 7, Name: "bloom_excess")] +#[spv.OpMemberName(Member: 8, Name: "beam_min_sigma")] +#[spv.OpMemberName(Member: 9, Name: "beam_max_sigma")] +#[spv.OpMemberName(Member: 10, Name: "beam_spot_power")] +#[spv.OpMemberName(Member: 11, Name: "beam_min_shape")] +#[spv.OpMemberName(Member: 12, Name: "beam_max_shape")] +#[spv.OpMemberName(Member: 13, Name: "beam_shape_power")] +#[spv.OpMemberName(Member: 14, Name: "beam_horiz_filter")] +#[spv.OpMemberName(Member: 15, Name: "beam_horiz_sigma")] +#[spv.OpMemberName(Member: 16, Name: "beam_horiz_linear_rgb_weight")] +#[spv.OpMemberName(Member: 17, Name: "convergence_offset_x_r")] +#[spv.OpMemberName(Member: 18, Name: "convergence_offset_x_g")] +#[spv.OpMemberName(Member: 19, Name: "convergence_offset_x_b")] +#[spv.OpMemberName(Member: 20, Name: "convergence_offset_y_r")] +#[spv.OpMemberName(Member: 21, Name: "convergence_offset_y_g")] +#[spv.OpMemberName(Member: 22, Name: "convergence_offset_y_b")] +#[spv.OpMemberName(Member: 23, Name: "mask_type")] +#[spv.OpMemberName(Member: 24, Name: "mask_sample_mode_desired")] +#[spv.OpMemberName(Member: 25, Name: "mask_num_triads_desired")] +#[spv.OpMemberName(Member: 26, Name: "mask_triad_size_desired")] +#[spv.OpMemberName(Member: 27, Name: "mask_specify_num_triads")] +#[spv.OpMemberName(Member: 28, Name: "aa_subpixel_r_offset_x_runtime")] +#[spv.OpMemberName(Member: 29, Name: "aa_subpixel_r_offset_y_runtime")] +#[spv.OpMemberName(Member: 30, Name: "aa_cubic_c")] +#[spv.OpMemberName(Member: 31, Name: "aa_gauss_sigma")] +#[spv.OpMemberName(Member: 32, Name: "geom_mode_runtime")] +#[spv.OpMemberName(Member: 33, Name: "geom_radius")] +#[spv.OpMemberName(Member: 34, Name: "geom_view_dist")] +#[spv.OpMemberName(Member: 35, Name: "geom_tilt_angle_x")] +#[spv.OpMemberName(Member: 36, Name: "geom_tilt_angle_y")] +#[spv.OpMemberName(Member: 37, Name: "geom_aspect_ratio_x")] +#[spv.OpMemberName(Member: 38, Name: "geom_aspect_ratio_y")] +#[spv.OpMemberName(Member: 39, Name: "geom_overscan_x")] +#[spv.OpMemberName(Member: 40, Name: "geom_overscan_y")] +#[spv.OpMemberName(Member: 41, Name: "border_size")] +#[spv.OpMemberName(Member: 42, Name: "border_darkness")] +#[spv.OpMemberName(Member: 43, Name: "border_compress")] +#[spv.OpMemberName(Member: 44, Name: "interlace_bff")] +#[spv.OpMemberName(Member: 45, Name: "interlace_1080i")] +#[spv.OpMemberName(Member: 46, Name: "interlace_detect_toggle")] +#[spv.Decoration.Block] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.ColMajor)] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.MatrixStride(MatrixStride: 16))] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))] +#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 64))] +#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 68))] +#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 72))] +#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 76))] +#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))] +#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 84))] +#[spv.OpMemberDecorate(Member: 7, spv.Decoration.Offset(ByteOffset: 88))] +#[spv.OpMemberDecorate(Member: 8, spv.Decoration.Offset(ByteOffset: 92))] +#[spv.OpMemberDecorate(Member: 9, spv.Decoration.Offset(ByteOffset: 96))] +#[spv.OpMemberDecorate(Member: 10, spv.Decoration.Offset(ByteOffset: 100))] +#[spv.OpMemberDecorate(Member: 11, spv.Decoration.Offset(ByteOffset: 104))] +#[spv.OpMemberDecorate(Member: 12, spv.Decoration.Offset(ByteOffset: 108))] +#[spv.OpMemberDecorate(Member: 13, spv.Decoration.Offset(ByteOffset: 112))] +#[spv.OpMemberDecorate(Member: 14, spv.Decoration.Offset(ByteOffset: 116))] +#[spv.OpMemberDecorate(Member: 15, spv.Decoration.Offset(ByteOffset: 120))] +#[spv.OpMemberDecorate(Member: 16, spv.Decoration.Offset(ByteOffset: 124))] +#[spv.OpMemberDecorate(Member: 17, spv.Decoration.Offset(ByteOffset: 128))] +#[spv.OpMemberDecorate(Member: 18, spv.Decoration.Offset(ByteOffset: 132))] +#[spv.OpMemberDecorate(Member: 19, spv.Decoration.Offset(ByteOffset: 136))] +#[spv.OpMemberDecorate(Member: 20, spv.Decoration.Offset(ByteOffset: 140))] +#[spv.OpMemberDecorate(Member: 21, spv.Decoration.Offset(ByteOffset: 144))] +#[spv.OpMemberDecorate(Member: 22, spv.Decoration.Offset(ByteOffset: 148))] +#[spv.OpMemberDecorate(Member: 23, spv.Decoration.Offset(ByteOffset: 152))] +#[spv.OpMemberDecorate(Member: 24, spv.Decoration.Offset(ByteOffset: 156))] +#[spv.OpMemberDecorate(Member: 25, spv.Decoration.Offset(ByteOffset: 160))] +#[spv.OpMemberDecorate(Member: 26, spv.Decoration.Offset(ByteOffset: 164))] +#[spv.OpMemberDecorate(Member: 27, spv.Decoration.Offset(ByteOffset: 168))] +#[spv.OpMemberDecorate(Member: 28, spv.Decoration.Offset(ByteOffset: 172))] +#[spv.OpMemberDecorate(Member: 29, spv.Decoration.Offset(ByteOffset: 176))] +#[spv.OpMemberDecorate(Member: 30, spv.Decoration.Offset(ByteOffset: 180))] +#[spv.OpMemberDecorate(Member: 31, spv.Decoration.Offset(ByteOffset: 184))] +#[spv.OpMemberDecorate(Member: 32, spv.Decoration.Offset(ByteOffset: 188))] +#[spv.OpMemberDecorate(Member: 33, spv.Decoration.Offset(ByteOffset: 192))] +#[spv.OpMemberDecorate(Member: 34, spv.Decoration.Offset(ByteOffset: 196))] +#[spv.OpMemberDecorate(Member: 35, spv.Decoration.Offset(ByteOffset: 200))] +#[spv.OpMemberDecorate(Member: 36, spv.Decoration.Offset(ByteOffset: 204))] +#[spv.OpMemberDecorate(Member: 37, spv.Decoration.Offset(ByteOffset: 208))] +#[spv.OpMemberDecorate(Member: 38, spv.Decoration.Offset(ByteOffset: 212))] +#[spv.OpMemberDecorate(Member: 39, spv.Decoration.Offset(ByteOffset: 216))] +#[spv.OpMemberDecorate(Member: 40, spv.Decoration.Offset(ByteOffset: 220))] +#[spv.OpMemberDecorate(Member: 41, spv.Decoration.Offset(ByteOffset: 224))] +#[spv.OpMemberDecorate(Member: 42, spv.Decoration.Offset(ByteOffset: 228))] +#[spv.OpMemberDecorate(Member: 43, spv.Decoration.Offset(ByteOffset: 232))] +#[spv.OpMemberDecorate(Member: 44, spv.Decoration.Offset(ByteOffset: 236))] +#[spv.OpMemberDecorate(Member: 45, spv.Decoration.Offset(ByteOffset: 240))] +#[spv.OpMemberDecorate(Member: 46, spv.Decoration.Offset(ByteOffset: 244))] +type T`UBO` = spv.OpTypeStruct( + spv.OpTypeMatrix(ColumnType: f32×4, ColumnCount: 4), + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, +) + +type T6 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown) + +type T7 = spv.OpTypeSampledImage(ImageType: T6) + +type T8 = spv.OpTypePointer(spv.StorageClass.UniformConstant, T7) + +type T9 = spv.OpTypePointer(spv.StorageClass.UniformConstant, spv.OpTypeSampler) + +#[spv.Decoration.Location(Location: 1)] +global_var GV`scanline_tex_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 4)] +global_var GV`scanline_texture_size_inv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 0)] +global_var GV`video_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 6)] +global_var GV`mask_tiles_per_screen`(spv.StorageClass.Input): f32×2 + +#[name = "mask_tile_start_uv_and_size"] +#[spv.Decoration.Location(Location: 5)] +global_var GV0(spv.StorageClass.Input): f32×4 + +#[spv.Decoration.Location(Location: 3)] +global_var GV`halation_tex_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 0)] +global_var GV`FragColor`(spv.StorageClass.Output): f32×4 + +#[spv.Decoration.Location(Location: 2)] +global_var GV`blur3x3_tex_uv`(spv.StorageClass.Input): f32×2 + +global_var GV`params`(spv.StorageClass.PushConstant): T`Push` + +global_var GV`bloom_approx_scale_x`(spv.StorageClass.Private): f32 + +global_var GV`crt_gamma_static`(spv.StorageClass.Private): f32 + +global_var GV`lcd_gamma_static`(spv.StorageClass.Private): f32 + +global_var GV`levels_contrast_static`(spv.StorageClass.Private): f32 + +global_var GV`levels_autodim_temp`(spv.StorageClass.Private): f32 + +global_var GV`halation_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`diffusion_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_underestimate_levels_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_excess_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_filter_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_num_scanlines`(spv.StorageClass.Private): f32 + +global_var GV`beam_generalized_gaussian`(spv.StorageClass.Private): bool + +global_var GV`beam_antialias_level`(spv.StorageClass.Private): f32 + +global_var GV`beam_min_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_max_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_spot_shape_function`(spv.StorageClass.Private): f32 + +global_var GV`beam_spot_power_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_min_shape_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_max_shape_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_shape_power_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_filter_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_linear_rgb_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_misconvergence`(spv.StorageClass.Private): bool + +global_var GV`convergence_offsets_r_static`(spv.StorageClass.Private): f32×2 + +global_var GV`convergence_offsets_g_static`(spv.StorageClass.Private): f32×2 + +global_var GV`convergence_offsets_b_static`(spv.StorageClass.Private): f32×2 + +global_var GV`interlace_detect_static`(spv.StorageClass.Private): bool + +global_var GV`interlace_1080i_static`(spv.StorageClass.Private): bool + +global_var GV`interlace_bff_static`(spv.StorageClass.Private): bool + +global_var GV`aa_level`(spv.StorageClass.Private): f32 + +global_var GV`aa_filter`(spv.StorageClass.Private): f32 + +global_var GV`aa_temporal`(spv.StorageClass.Private): bool + +global_var GV`aa_subpixel_r_offset_static`(spv.StorageClass.Private): f32×2 + +global_var GV`aa_cubic_c_static`(spv.StorageClass.Private): f32 + +global_var GV`aa_gauss_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_type_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_sample_mode_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_specify_num_triads_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_triad_size_desired_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_num_triads_desired_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_sinc_lobes`(spv.StorageClass.Private): f32 + +global_var GV`mask_min_allowed_triad_size`(spv.StorageClass.Private): f32 + +global_var GV`geom_mode_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_radius_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_view_dist_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_tilt_angle_static`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_aspect_ratio_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_overscan_static`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_force_correct_tangent_matrix`(spv.StorageClass.Private): bool + +global_var GV`border_size_static`(spv.StorageClass.Private): f32 + +global_var GV`border_darkness_static`(spv.StorageClass.Private): f32 + +global_var GV`border_compress_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_size_x`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_size_x_for_fake`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_viewport_scale`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_max_aspect_ratio`(spv.StorageClass.Private): f32 + +global_var GV`mask_texture_small_size`(spv.StorageClass.Private): f32×2 + +global_var GV`mask_texture_large_size`(spv.StorageClass.Private): f32×2 + +global_var GV`mask_triads_per_tile`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille14_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille15_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_slot_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_shadow_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_filter`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_src_lut_size`(spv.StorageClass.Private): f32×2 + +global_var GV`max_aa_base_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_aniso_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_tiled_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_mask_texel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_mask_tile_border`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_num_tiles`(spv.StorageClass.Private): f32 + +global_var GV`mask_start_texels`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_num_triads`(spv.StorageClass.Private): f32 + +global_var GV`min_allowed_viewport_triads`(spv.StorageClass.Private): f32×2 + +global_var GV`pi`(spv.StorageClass.Private): f32 + +global_var GV`under_half`(spv.StorageClass.Private): f32 + +global_var GV`gba_gamma`(spv.StorageClass.Private): f32 + +#[spv.Decoration.Binding(BindingPoint: 0)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`global`(spv.StorageClass.Uniform): T`UBO` + +global_var GV`interlace_detect`(spv.StorageClass.Private): bool + +global_var GV`ntsc_gamma`(spv.StorageClass.Private): f32 + +global_var GV`pal_gamma`(spv.StorageClass.Private): f32 + +global_var GV`crt_reference_gamma_high`(spv.StorageClass.Private): f32 + +global_var GV`crt_reference_gamma_low`(spv.StorageClass.Private): f32 + +global_var GV`lcd_reference_gamma`(spv.StorageClass.Private): f32 + +global_var GV`crt_office_gamma`(spv.StorageClass.Private): f32 + +global_var GV`lcd_office_gamma`(spv.StorageClass.Private): f32 + +global_var GV`assume_opaque_alpha`(spv.StorageClass.Private): bool + +global_var GV`linearize_input`(spv.StorageClass.Private): bool + +global_var GV`gamma_encode_output`(spv.StorageClass.Private): bool + +global_var GV`gamma_aware_bilinear`(spv.StorageClass.Private): bool + +global_var GV`mask_min_allowed_tile_size`(spv.StorageClass.Private): f32 + +global_var GV`mask_min_expected_tile_size`(spv.StorageClass.Private): f32 + +global_var GV`pi_over_lobes`(spv.StorageClass.Private): f32 + +global_var GV`max_sinc_resize_samples_float`(spv.StorageClass.Private): f32 + +global_var GV`max_sinc_resize_samples_m4`(spv.StorageClass.Private): f32 + +global_var GV`blur3_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur4_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur5_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur6_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur7_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur8_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur9_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur10_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur11_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur12_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur17_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur25_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur31_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur43_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`error_blurring`(spv.StorageClass.Private): f32 + +global_var GV`bloom_diff_thresh`(spv.StorageClass.Private): f32 + +func F`get_convergence_offsets_x_vector(`() -> f32×3 { + v0 = spv.OpAccessChain(Base: &GV`global`, 17s32): T5 + v1 = spv.OpLoad(Pointer: v0): f32 + v2 = spv.OpAccessChain(Base: &GV`global`, 18s32): T5 + v3 = spv.OpLoad(Pointer: v2): f32 + v4 = spv.OpAccessChain(Base: &GV`global`, 19s32): T5 + v5 = spv.OpLoad(Pointer: v4): f32 + v6 = vec.new(v1, v3, v5): f32×3 + return v6 +} + +func F`get_intermediate_gamma(`() -> f32 { + v0 = spv.OpLoad(Pointer: &GV`ntsc_gamma`): f32 + return v0 +} + +func F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`( + #[name = "color0"] + v0: T0, + #[name = "color1"] + v1: T0, + #[name = "color2"] + v2: T0, + #[name = "color3"] + v3: T0, + #[name = "weights"] + v4: T3, +) -> f32×3 { + v5 = spv.OpLoad(Pointer: v0): f32×3 + v6 = spv.OpLoad(Pointer: v1): f32×3 + v7 = spv.OpLoad(Pointer: v2): f32×3 + v8 = spv.OpLoad(Pointer: v3): f32×3 + v9 = vec.extract(v5, 0): f32 + v10 = vec.extract(v5, 1): f32 + v11 = vec.extract(v5, 2): f32 + v12 = vec.extract(v6, 0): f32 + v13 = vec.extract(v6, 1): f32 + v14 = vec.extract(v6, 2): f32 + v15 = vec.extract(v7, 0): f32 + v16 = vec.extract(v7, 1): f32 + v17 = vec.extract(v7, 2): f32 + v18 = vec.extract(v8, 0): f32 + v19 = vec.extract(v8, 1): f32 + v20 = vec.extract(v8, 2): f32 + v21 = vec.new(v9, v10, v11): f32×3 + v22 = vec.new(v12, v13, v14): f32×3 + v23 = vec.new(v15, v16, v17): f32×3 + v24 = vec.new(v18, v19, v20): f32×3 + v25 = vec.new(v21, v22, v23, v24): spv.OpTypeMatrix(ColumnType: f32×3, ColumnCount: 4) + v26 = spv.OpLoad(Pointer: v4): f32×4 + v27 = spv.OpMatrixTimesVector(Matrix: v25, Vector: v26): f32×3 + v28 = vec.new(0.0f32, 0.0f32, 0.0f32): f32×3 + v29 = spv.extinst."GLSL.std.450".FMax(X: v27, Y: v28): f32×3 + return v29 +} + +func F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`( + #[name = "color0"] + v0: T0, + #[name = "color1"] + v1: T0, + #[name = "color2"] + v2: T0, + #[name = "color3"] + v3: T0, + #[name = "weights"] + v4: T3, +) -> f32×3 { + v`intermediate_gamma` = spv.OpVariable(spv.StorageClass.Function): T2 + v`linear_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T3 + v`gamma_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v14 = spv.OpVariable(spv.StorageClass.Function): T3 + v15 = call F`get_intermediate_gamma(`(): f32 + spv.OpStore(Pointer: v`intermediate_gamma`, Object: v15) + v16 = spv.OpLoad(Pointer: v0): f32×3 + spv.OpStore(Pointer: v5, Object: v16) + v17 = spv.OpLoad(Pointer: v1): f32×3 + spv.OpStore(Pointer: v6, Object: v17) + v18 = spv.OpLoad(Pointer: v2): f32×3 + spv.OpStore(Pointer: v7, Object: v18) + v19 = spv.OpLoad(Pointer: v3): f32×3 + spv.OpStore(Pointer: v8, Object: v19) + v20 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v9, Object: v20) + v21 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v5, v6, v7, v8, v9): f32×3 + spv.OpStore(Pointer: v`linear_mixed_color`, Object: v21) + v22 = spv.OpLoad(Pointer: v0): f32×3 + v23 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v24 = f.div(1.0f32, v23): f32 + v25 = vec.new(v24, v24, v24): f32×3 + v26 = spv.extinst."GLSL.std.450".Pow(X: v22, Y: v25): f32×3 + v27 = spv.OpLoad(Pointer: v1): f32×3 + v28 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v29 = f.div(1.0f32, v28): f32 + v30 = vec.new(v29, v29, v29): f32×3 + v31 = spv.extinst."GLSL.std.450".Pow(X: v27, Y: v30): f32×3 + v32 = spv.OpLoad(Pointer: v2): f32×3 + v33 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v34 = f.div(1.0f32, v33): f32 + v35 = vec.new(v34, v34, v34): f32×3 + v36 = spv.extinst."GLSL.std.450".Pow(X: v32, Y: v35): f32×3 + v37 = spv.OpLoad(Pointer: v3): f32×3 + v38 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v39 = f.div(1.0f32, v38): f32 + v40 = vec.new(v39, v39, v39): f32×3 + v41 = spv.extinst."GLSL.std.450".Pow(X: v37, Y: v40): f32×3 + spv.OpStore(Pointer: v10, Object: v26) + spv.OpStore(Pointer: v11, Object: v31) + spv.OpStore(Pointer: v12, Object: v36) + spv.OpStore(Pointer: v13, Object: v41) + v42 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v14, Object: v42) + v43 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v10, v11, v12, v13, v14): f32×3 + spv.OpStore(Pointer: v`gamma_mixed_color`, Object: v43) + v44 = spv.OpLoad(Pointer: v`gamma_mixed_color`): f32×3 + v45 = spv.OpLoad(Pointer: v`linear_mixed_color`): f32×3 + v46 = spv.OpAccessChain(Base: &GV`global`, 16s32): T5 + v47 = spv.OpLoad(Pointer: v46): f32 + v48 = vec.new(v47, v47, v47): f32×3 + v49 = spv.extinst."GLSL.std.450".FMix(X: v44, Y: v45, A: v48): f32×3 + return v49 +} + +func F`get_scanline_color(s21;vf2;vf2;vf4;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "scanline_uv"] + v2: T1, + #[name = "uv_step_x"] + v3: T1, + #[name = "weights"] + v4: T3, +) -> f32×3 { + #[name = "color1"] + v5 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color2"] + v6 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color0"] + v7 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color3"] + v8 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T3 + v14 = spv.OpLoad(Pointer: v0): T6 + v15 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v16 = spv.OpSampledImage(Image: v14, Sampler: v15): T7 + v17 = spv.OpLoad(Pointer: v2): f32×2 + v18 = spv.OpImageSampleImplicitLod(SampledImage: v16, Coordinate: v17): f32×4 + v19 = spv.OpVectorShuffle(Vector1: v18, Vector2: v18, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v5, Object: v19) + v20 = spv.OpLoad(Pointer: v0): T6 + v21 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v22 = spv.OpSampledImage(Image: v20, Sampler: v21): T7 + v23 = spv.OpLoad(Pointer: v2): f32×2 + v24 = spv.OpLoad(Pointer: v3): f32×2 + v25 = vec.distribute(f.add)(v23, v24): f32×2 + v26 = spv.OpImageSampleImplicitLod(SampledImage: v22, Coordinate: v25): f32×4 + v27 = spv.OpVectorShuffle(Vector1: v26, Vector2: v26, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v6, Object: v27) + spv.OpStore(Pointer: v7, Object: f32×3(0.0, 0.0, 0.0)) + spv.OpStore(Pointer: v8, Object: f32×3(0.0, 0.0, 0.0)) + v28 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v29 = spv.OpLoad(Pointer: v28): f32 + v30 = f.gt(v29, 0.5f32): bool + if v30 { + branch L0 + } else { + branch L1 + } + + label L0: + v31 = spv.OpLoad(Pointer: v0): T6 + v32 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v33 = spv.OpSampledImage(Image: v31, Sampler: v32): T7 + v34 = spv.OpLoad(Pointer: v2): f32×2 + v35 = spv.OpLoad(Pointer: v3): f32×2 + v36 = vec.distribute(f.sub)(v34, v35): f32×2 + v37 = spv.OpImageSampleImplicitLod(SampledImage: v33, Coordinate: v36): f32×4 + v38 = spv.OpVectorShuffle(Vector1: v37, Vector2: v37, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v7, Object: v38) + v39 = spv.OpLoad(Pointer: v0): T6 + v40 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v41 = spv.OpSampledImage(Image: v39, Sampler: v40): T7 + v42 = spv.OpLoad(Pointer: v2): f32×2 + v43 = spv.OpLoad(Pointer: v3): f32×2 + v44 = vec.mul(v43, 2.0f32): f32×2 + v45 = vec.distribute(f.add)(v42, v44): f32×2 + v46 = spv.OpImageSampleImplicitLod(SampledImage: v41, Coordinate: v45): f32×4 + v47 = spv.OpVectorShuffle(Vector1: v46, Vector2: v46, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v8, Object: v47) + branch L1 + + label L1: + v48 = spv.OpLoad(Pointer: v7): f32×3 + spv.OpStore(Pointer: v9, Object: v48) + v49 = spv.OpLoad(Pointer: v5): f32×3 + spv.OpStore(Pointer: v10, Object: v49) + v50 = spv.OpLoad(Pointer: v6): f32×3 + spv.OpStore(Pointer: v11, Object: v50) + v51 = spv.OpLoad(Pointer: v8): f32×3 + spv.OpStore(Pointer: v12, Object: v51) + v52 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v13, Object: v52) + v53 = call F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(v9, v10, v11, v12, v13): f32×3 + return v53 +} + +func F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, + #[name = "tex_size"] + v3: T1, + #[name = "texture_size_inv"] + v4: T1, +) -> f32×3 { + v`curr_texel` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel_hor` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel_hor_uv` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_dist` = spv.OpVariable(spv.StorageClass.Function): T2 + v`sample_dists` = spv.OpVariable(spv.StorageClass.Function): T3 + v`x` = spv.OpVariable(spv.StorageClass.Function): T2 + v`w2` = spv.OpVariable(spv.StorageClass.Function): T2 + #[name = "weights"] + v5 = spv.OpVariable(spv.StorageClass.Function): T3 + v`inner_denom_inv` = spv.OpVariable(spv.StorageClass.Function): T2 + v`pi_dists` = spv.OpVariable(spv.StorageClass.Function): T3 + v`final_weights` = spv.OpVariable(spv.StorageClass.Function): T3 + #[name = "uv_step_x"] + v6 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T3 + v10 = spv.OpLoad(Pointer: v2): f32×2 + v11 = spv.OpLoad(Pointer: v3): f32×2 + v12 = vec.distribute(f.mul)(v10, v11): f32×2 + spv.OpStore(Pointer: v`curr_texel`, Object: v12) + v13 = spv.OpLoad(Pointer: v`curr_texel`): f32×2 + v14 = spv.OpLoad(Pointer: &GV`under_half`): f32 + v15 = vec.new(v14, v14): f32×2 + v16 = vec.distribute(f.sub)(v13, v15): f32×2 + v17 = spv.extinst."GLSL.std.450".Floor(X: v16): f32×2 + v18 = vec.distribute(f.add)(v17, f32×2(0.5, 0.5)): f32×2 + spv.OpStore(Pointer: v`prev_texel`, Object: v18) + v19 = spv.OpAccessChain(Base: v`prev_texel`, 0u32): T2 + v20 = spv.OpLoad(Pointer: v19): f32 + v21 = spv.OpAccessChain(Base: v`curr_texel`, 1u32): T2 + v22 = spv.OpLoad(Pointer: v21): f32 + v23 = vec.new(v20, v22): f32×2 + spv.OpStore(Pointer: v`prev_texel_hor`, Object: v23) + v24 = spv.OpLoad(Pointer: v`prev_texel_hor`): f32×2 + v25 = spv.OpLoad(Pointer: v4): f32×2 + v26 = vec.distribute(f.mul)(v24, v25): f32×2 + spv.OpStore(Pointer: v`prev_texel_hor_uv`, Object: v26) + v27 = spv.OpAccessChain(Base: v`curr_texel`, 0u32): T2 + v28 = spv.OpLoad(Pointer: v27): f32 + v29 = spv.OpAccessChain(Base: v`prev_texel_hor`, 0u32): T2 + v30 = spv.OpLoad(Pointer: v29): f32 + v31 = f.sub(v28, v30): f32 + spv.OpStore(Pointer: v`prev_dist`, Object: v31) + v32 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v33 = f.add(1.0f32, v32): f32 + v34 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v35 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v36 = f.sub(1.0f32, v35): f32 + v37 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v38 = f.sub(2.0f32, v37): f32 + v39 = vec.new(v33, v34, v36, v38): f32×4 + spv.OpStore(Pointer: v`sample_dists`, Object: v39) + v40 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v41 = spv.OpLoad(Pointer: v40): f32 + v42 = f.lt(v41, 0.5f32): bool + if v42 { + branch L0 + } else { + branch L1 + } + + label L0: + v43 = spv.OpAccessChain(Base: v`sample_dists`, 1u32): T2 + v44 = spv.OpLoad(Pointer: v43): f32 + spv.OpStore(Pointer: v`x`, Object: v44) + v45 = spv.OpLoad(Pointer: v`x`): f32 + v46 = spv.OpLoad(Pointer: v`x`): f32 + v47 = f.mul(v45, v46): f32 + v48 = spv.OpLoad(Pointer: v`x`): f32 + v49 = f.mul(v47, v48): f32 + v50 = spv.OpLoad(Pointer: v`x`): f32 + v51 = spv.OpLoad(Pointer: v`x`): f32 + v52 = f.mul(v51, 6.0f32): f32 + v53 = f.sub(v52, 15.0f32): f32 + v54 = f.mul(v50, v53): f32 + v55 = f.add(v54, 10.0f32): f32 + v56 = f.mul(v49, v55): f32 + spv.OpStore(Pointer: v`w2`, Object: v56) + v57 = spv.OpLoad(Pointer: v`w2`): f32 + v58 = f.sub(1.0f32, v57): f32 + v59 = spv.OpLoad(Pointer: v`w2`): f32 + v60 = vec.new(0.0f32, v58, v59, 0.0f32): f32×4 + spv.OpStore(Pointer: v5, Object: v60) + branch L5 + + label L1: + v61 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v62 = spv.OpLoad(Pointer: v61): f32 + v63 = f.lt(v62, 1.5f32): bool + if v63 { + branch L2 + } else { + branch L3 + } + + label L2: + v64 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5 + v65 = spv.OpLoad(Pointer: v64): f32 + v66 = f.mul(2.0f32, v65): f32 + v67 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5 + v68 = spv.OpLoad(Pointer: v67): f32 + v69 = f.mul(v66, v68): f32 + v70 = f.div(1.0f32, v69): f32 + spv.OpStore(Pointer: v`inner_denom_inv`, Object: v70) + v71 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v72 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v73 = vec.distribute(f.mul)(v71, v72): f32×4 + v74 = vec.distribute(f.neg)(v73): f32×4 + v75 = spv.OpLoad(Pointer: v`inner_denom_inv`): f32 + v76 = vec.mul(v74, v75): f32×4 + v77 = spv.extinst."GLSL.std.450".Exp(X: v76): f32×4 + spv.OpStore(Pointer: v5, Object: v77) + branch L4 + + label L3: + v78 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v79 = spv.OpLoad(Pointer: &GV`pi`): f32 + v80 = vec.mul(v78, v79): f32×4 + v81 = spv.extinst."GLSL.std.450".FAbs(X: v80): f32×4 + v82 = vec.new(1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32): f32×4 + v83 = spv.extinst."GLSL.std.450".FMax(X: v81, Y: v82): f32×4 + spv.OpStore(Pointer: v`pi_dists`, Object: v83) + v84 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v85 = spv.extinst."GLSL.std.450".Sin(X: v84): f32×4 + v86 = vec.mul(v85, 2.0f32): f32×4 + v87 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v88 = vec.mul(v87, 0.5f32): f32×4 + v89 = spv.extinst."GLSL.std.450".Sin(X: v88): f32×4 + v90 = vec.distribute(f.mul)(v86, v89): f32×4 + v91 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v92 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v93 = vec.distribute(f.mul)(v91, v92): f32×4 + v94 = vec.distribute(f.div)(v90, v93): f32×4 + spv.OpStore(Pointer: v5, Object: v94) + branch L4 + + label L4: + branch L5 + + label L5: + v95 = spv.OpLoad(Pointer: v5): f32×4 + v96 = spv.OpLoad(Pointer: v5): f32×4 + v97 = vec.dot(v96, f32×4(1.0, 1.0, 1.0, 1.0)): f32 + v98 = vec.new(v97, v97, v97, v97): f32×4 + v99 = vec.distribute(f.div)(v95, v98): f32×4 + spv.OpStore(Pointer: v`final_weights`, Object: v99) + v100 = spv.OpAccessChain(Base: v4, 0u32): T2 + v101 = spv.OpLoad(Pointer: v100): f32 + v102 = vec.new(v101, 0.0f32): f32×2 + spv.OpStore(Pointer: v6, Object: v102) + v103 = spv.OpLoad(Pointer: v`prev_texel_hor_uv`): f32×2 + spv.OpStore(Pointer: v7, Object: v103) + v104 = spv.OpLoad(Pointer: v6): f32×2 + spv.OpStore(Pointer: v8, Object: v104) + v105 = spv.OpLoad(Pointer: v`final_weights`): f32×4 + spv.OpStore(Pointer: v9, Object: v105) + v106 = call F`get_scanline_color(s21;vf2;vf2;vf4;`(v0, v1, v7, v8, v9): f32×3 + return v106 +} + +func F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, + #[name = "tex_size"] + v3: T1, + #[name = "texture_size_inv"] + v4: T1, +) -> f32×3 { + v`convergence_offsets_rgb` = spv.OpVariable(spv.StorageClass.Function): T0 + v`offset_u_rgb` = spv.OpVariable(spv.StorageClass.Function): T0 + v`scanline_uv_r` = spv.OpVariable(spv.StorageClass.Function): T1 + v`scanline_uv_g` = spv.OpVariable(spv.StorageClass.Function): T1 + v`scanline_uv_b` = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_r` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_g` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_b` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v14 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v15 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v16 = spv.OpVariable(spv.StorageClass.Function): T1 + v17 = spv.OpLoad(Pointer: &GV`beam_misconvergence`): bool + if v17 { + branch L0 + } else { + branch L1 + } + + label L0: + v18 = call F`get_convergence_offsets_x_vector(`(): f32×3 + spv.OpStore(Pointer: v`convergence_offsets_rgb`, Object: v18) + v19 = spv.OpLoad(Pointer: v`convergence_offsets_rgb`): f32×3 + v20 = spv.OpLoad(Pointer: v4): f32×2 + v21 = spv.OpVectorShuffle(Vector1: v20, Vector2: v20, 0, 0, 0): f32×3 + v22 = vec.distribute(f.mul)(v19, v21): f32×3 + spv.OpStore(Pointer: v`offset_u_rgb`, Object: v22) + v23 = spv.OpLoad(Pointer: v2): f32×2 + v24 = spv.OpAccessChain(Base: v`offset_u_rgb`, 0u32): T2 + v25 = spv.OpLoad(Pointer: v24): f32 + v26 = vec.new(v25, 0.0f32): f32×2 + v27 = vec.distribute(f.sub)(v23, v26): f32×2 + spv.OpStore(Pointer: v`scanline_uv_r`, Object: v27) + v28 = spv.OpLoad(Pointer: v2): f32×2 + v29 = spv.OpAccessChain(Base: v`offset_u_rgb`, 1u32): T2 + v30 = spv.OpLoad(Pointer: v29): f32 + v31 = vec.new(v30, 0.0f32): f32×2 + v32 = vec.distribute(f.sub)(v28, v31): f32×2 + spv.OpStore(Pointer: v`scanline_uv_g`, Object: v32) + v33 = spv.OpLoad(Pointer: v2): f32×2 + v34 = spv.OpAccessChain(Base: v`offset_u_rgb`, 2u32): T2 + v35 = spv.OpLoad(Pointer: v34): f32 + v36 = vec.new(v35, 0.0f32): f32×2 + v37 = vec.distribute(f.sub)(v33, v36): f32×2 + spv.OpStore(Pointer: v`scanline_uv_b`, Object: v37) + v38 = spv.OpLoad(Pointer: v`scanline_uv_r`): f32×2 + spv.OpStore(Pointer: v5, Object: v38) + v39 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v6, Object: v39) + v40 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v7, Object: v40) + v41 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v5, v6, v7): f32×3 + spv.OpStore(Pointer: v`sample_r`, Object: v41) + v42 = spv.OpLoad(Pointer: v`scanline_uv_g`): f32×2 + spv.OpStore(Pointer: v8, Object: v42) + v43 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v9, Object: v43) + v44 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v10, Object: v44) + v45 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v8, v9, v10): f32×3 + spv.OpStore(Pointer: v`sample_g`, Object: v45) + v46 = spv.OpLoad(Pointer: v`scanline_uv_b`): f32×2 + spv.OpStore(Pointer: v11, Object: v46) + v47 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v12, Object: v47) + v48 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v13, Object: v48) + v49 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v11, v12, v13): f32×3 + spv.OpStore(Pointer: v`sample_b`, Object: v49) + v50 = spv.OpAccessChain(Base: v`sample_r`, 0u32): T2 + v51 = spv.OpLoad(Pointer: v50): f32 + v52 = spv.OpAccessChain(Base: v`sample_g`, 1u32): T2 + v53 = spv.OpLoad(Pointer: v52): f32 + v54 = spv.OpAccessChain(Base: v`sample_b`, 2u32): T2 + v55 = spv.OpLoad(Pointer: v54): f32 + v56 = vec.new(v51, v53, v55): f32×3 + return v56 + + label L1: + v57 = spv.OpLoad(Pointer: v2): f32×2 + spv.OpStore(Pointer: v14, Object: v57) + v58 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v15, Object: v58) + v59 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v16, Object: v59) + v60 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v14, v15, v16): f32×3 + return v60 +} + +#[spv.Decoration.Binding(BindingPoint: 6)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`VERTICAL_SCANLINES`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 6)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_VERTICAL_SCANLINES_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`get_mask_sample_mode(`() -> f32 { + v0 = spv.OpAccessChain(Base: &GV`global`, 24s32): T5 + v1 = spv.OpLoad(Pointer: v0): f32 + return v1 +} + +func F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`( + #[name = "tile_uv_wrap"] + v0: T1, + #[name = "mask_tile_start_uv_and_size"] + v1: T3, +) -> f32×2 { + v`tile_uv` = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "mask_tex_uv"] + v2 = spv.OpVariable(spv.StorageClass.Function): T1 + v3 = call F`get_mask_sample_mode(`(): f32 + v4 = f.lt(v3, 0.5f32): bool + if v4 { + branch L0 + } else { + branch L1 + } + + label L0: + v5 = spv.OpLoad(Pointer: v0): f32×2 + v6 = vec.mul(v5, 0.5f32): f32×2 + v7 = spv.extinst."GLSL.std.450".Fract(X: v6): f32×2 + v8 = vec.mul(v7, 2.0f32): f32×2 + spv.OpStore(Pointer: v`tile_uv`, Object: v8) + v9 = spv.OpLoad(Pointer: v1): f32×4 + v10 = spv.OpVectorShuffle(Vector1: v9, Vector2: v9, 0, 1): f32×2 + v11 = spv.OpLoad(Pointer: v`tile_uv`): f32×2 + v12 = spv.OpLoad(Pointer: v1): f32×4 + v13 = spv.OpVectorShuffle(Vector1: v12, Vector2: v12, 2, 3): f32×2 + v14 = vec.distribute(f.mul)(v11, v13): f32×2 + v15 = vec.distribute(f.add)(v10, v14): f32×2 + spv.OpStore(Pointer: v2, Object: v15) + v16 = spv.OpLoad(Pointer: v2): f32×2 + return v16 + + label L1: + v17 = spv.OpLoad(Pointer: v0): f32×2 + return v17 +} + +func F`get_pass_input_gamma(`() -> f32 { + return 1.0f32 +} + +func F`decode_input(vf4;`( + #[name = "color"] + v0: T3, +) -> f32×4 { + v1 = spv.OpLoad(Pointer: &GV`linearize_input`): bool + if v1 { + branch L0 + } else { + branch L3 + } + + label L0: + v2 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool + if v2 { + branch L1 + } else { + branch L2 + } + + label L1: + v3 = spv.OpLoad(Pointer: v0): f32×4 + v4 = spv.OpVectorShuffle(Vector1: v3, Vector2: v3, 0, 1, 2): f32×3 + v5 = call F`get_pass_input_gamma(`(): f32 + v6 = vec.new(v5, v5, v5): f32×3 + v7 = spv.extinst."GLSL.std.450".Pow(X: v4, Y: v6): f32×3 + v8 = vec.extract(v7, 0): f32 + v9 = vec.extract(v7, 1): f32 + v10 = vec.extract(v7, 2): f32 + v11 = vec.new(v8, v9, v10, 1.0f32): f32×4 + return v11 + + label L2: + v12 = spv.OpLoad(Pointer: v0): f32×4 + v13 = spv.OpVectorShuffle(Vector1: v12, Vector2: v12, 0, 1, 2): f32×3 + v14 = call F`get_pass_input_gamma(`(): f32 + v15 = vec.new(v14, v14, v14): f32×3 + v16 = spv.extinst."GLSL.std.450".Pow(X: v13, Y: v15): f32×3 + v17 = spv.OpAccessChain(Base: v0, 3u32): T2 + v18 = spv.OpLoad(Pointer: v17): f32 + v19 = vec.extract(v16, 0): f32 + v20 = vec.extract(v16, 1): f32 + v21 = vec.extract(v16, 2): f32 + v22 = vec.new(v19, v20, v21, v18): f32×4 + return v22 + + label L3: + v23 = spv.OpLoad(Pointer: v0): f32×4 + return v23 +} + +func F`tex2D_linearize(s21;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + v2: T9, + #[name = "tex_coords"] + v3: T1, +) -> f32×4 { + #[name = "param"] + v4 = spv.OpVariable(spv.StorageClass.Function): T3 + v5 = spv.OpLoad(Pointer: v0): T6 + v6 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v7 = spv.OpSampledImage(Image: v5, Sampler: v6): T7 + v8 = spv.OpLoad(Pointer: v2): spv.OpTypeSampler + v9 = spv.OpSampledImage(Image: v7, Sampler: v8): T7 + v10 = spv.OpLoad(Pointer: v3): f32×2 + v11 = spv.OpImageSampleImplicitLod(SampledImage: v9, Coordinate: v10): f32×4 + spv.OpStore(Pointer: v4, Object: v11) + v12 = call F`decode_input(vf4;`(v4): f32×4 + return v12 +} + +#[spv.Decoration.Binding(BindingPoint: 3)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_grille_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 3)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_grille_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 4)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_slot_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 4)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_slot_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 5)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_shadow_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 5)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_shadow_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`tex2Dtiled_mask_linearize(s21;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, +) -> f32×4 { + #[name = "param"] + v3 = spv.OpVariable(spv.StorageClass.Function): T1 + v4 = spv.OpLoad(Pointer: v2): f32×2 + spv.OpStore(Pointer: v3, Object: v4) + v5 = call F`tex2D_linearize(s21;vf2;`(v0, v1, v3): f32×4 + return v5 +} + +#[spv.Decoration.Binding(BindingPoint: 9)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`MASK_RESIZE`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 9)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_MASK_RESIZE_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 8)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`HALATION_BLUR`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 8)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_HALATION_BLUR_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`get_pass_output_gamma(`() -> f32 { + return 1.0f32 +} + +func F`encode_output(vf4;`( + #[name = "color"] + v0: T3, +) -> f32×4 { + v1 = spv.OpLoad(Pointer: &GV`gamma_encode_output`): bool + if v1 { + branch L0 + } else { + branch L3 + } + + label L0: + v2 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool + if v2 { + branch L1 + } else { + branch L2 + } + + label L1: + v3 = spv.OpLoad(Pointer: v0): f32×4 + v4 = spv.OpVectorShuffle(Vector1: v3, Vector2: v3, 0, 1, 2): f32×3 + v5 = call F`get_pass_output_gamma(`(): f32 + v6 = f.div(1.0f32, v5): f32 + v7 = vec.new(v6, v6, v6): f32×3 + v8 = spv.extinst."GLSL.std.450".Pow(X: v4, Y: v7): f32×3 + v9 = vec.extract(v8, 0): f32 + v10 = vec.extract(v8, 1): f32 + v11 = vec.extract(v8, 2): f32 + v12 = vec.new(v9, v10, v11, 1.0f32): f32×4 + return v12 + + label L2: + v13 = spv.OpLoad(Pointer: v0): f32×4 + v14 = spv.OpVectorShuffle(Vector1: v13, Vector2: v13, 0, 1, 2): f32×3 + v15 = call F`get_pass_output_gamma(`(): f32 + v16 = f.div(1.0f32, v15): f32 + v17 = vec.new(v16, v16, v16): f32×3 + v18 = spv.extinst."GLSL.std.450".Pow(X: v14, Y: v17): f32×3 + v19 = spv.OpAccessChain(Base: v0, 3u32): T2 + v20 = spv.OpLoad(Pointer: v19): f32 + v21 = vec.extract(v18, 0): f32 + v22 = vec.extract(v18, 1): f32 + v23 = vec.extract(v18, 2): f32 + v24 = vec.new(v21, v22, v23, v20): f32×4 + return v24 + + label L3: + v25 = spv.OpLoad(Pointer: v0): f32×4 + return v25 +} + +#[spv.ExecutionMode.OriginUpperLeft] +func F`main`() { + v`scanline_color_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v0 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v1 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v2 = spv.OpVariable(spv.StorageClass.Function): T1 + v`auto_dim_factor` = spv.OpVariable(spv.StorageClass.Function): T2 + #[name = "tile_uv_wrap"] + v3 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "mask_tex_uv"] + v4 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T3 + v`sample_orig_luts` = spv.OpVariable(spv.StorageClass.Function): spv.OpTypePointer(spv.StorageClass.Function, bool) + v`phosphor_mask_sample` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T1 + v`halation_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T1 + v`halation_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`electron_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`phosphor_emission_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`pixel_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T3 + v13 = spv.OpAccessChain(Base: &GV`params`, 2s32, 0u32): T4 + v14 = spv.OpLoad(Pointer: v13): f32 + v15 = spv.OpAccessChain(Base: &GV`params`, 0s32, 1u32): T4 + v16 = spv.OpLoad(Pointer: v15): f32 + v17 = f.div(v14, v16): f32 + spv.OpStore(Pointer: &GV`bloom_approx_scale_x`, Object: v17) + spv.OpStore(Pointer: &GV`crt_gamma_static`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`lcd_gamma_static`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`levels_contrast_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`levels_autodim_temp`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`halation_weight_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`diffusion_weight_static`, Object: 0.075f32) + spv.OpStore(Pointer: &GV`bloom_underestimate_levels_static`, Object: 0.8f32) + spv.OpStore(Pointer: &GV`bloom_excess_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`bloom_approx_filter_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`beam_num_scanlines`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`beam_generalized_gaussian`, Object: true) + spv.OpStore(Pointer: &GV`beam_antialias_level`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`beam_min_sigma_static`, Object: 0.02f32) + spv.OpStore(Pointer: &GV`beam_max_sigma_static`, Object: 0.3f32) + spv.OpStore(Pointer: &GV`beam_spot_shape_function`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`beam_spot_power_static`, Object: 0.33333334f32) + spv.OpStore(Pointer: &GV`beam_min_shape_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`beam_max_shape_static`, Object: 4.0f32) + spv.OpStore(Pointer: &GV`beam_shape_power_static`, Object: 0.25f32) + spv.OpStore(Pointer: &GV`beam_horiz_filter_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`beam_horiz_sigma_static`, Object: 0.35f32) + spv.OpStore(Pointer: &GV`beam_horiz_linear_rgb_weight_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`beam_misconvergence`, Object: true) + spv.OpStore(Pointer: &GV`convergence_offsets_r_static`, Object: f32×2(0.1, 0.2)) + spv.OpStore(Pointer: &GV`convergence_offsets_g_static`, Object: f32×2(0.3, 0.4)) + spv.OpStore(Pointer: &GV`convergence_offsets_b_static`, Object: f32×2(0.5, 0.6)) + spv.OpStore(Pointer: &GV`interlace_detect_static`, Object: true) + spv.OpStore(Pointer: &GV`interlace_1080i_static`, Object: false) + spv.OpStore(Pointer: &GV`interlace_bff_static`, Object: false) + spv.OpStore(Pointer: &GV`aa_level`, Object: 12.0f32) + spv.OpStore(Pointer: &GV`aa_filter`, Object: 6.0f32) + spv.OpStore(Pointer: &GV`aa_temporal`, Object: false) + spv.OpStore(Pointer: &GV`aa_subpixel_r_offset_static`, Object: f32×2(-0.33333334, 0.0)) + spv.OpStore(Pointer: &GV`aa_cubic_c_static`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`aa_gauss_sigma_static`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`mask_type_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`mask_sample_mode_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`mask_specify_num_triads_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`mask_triad_size_desired_static`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`mask_num_triads_desired_static`, Object: 480.0f32) + spv.OpStore(Pointer: &GV`mask_sinc_lobes`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`mask_min_allowed_triad_size`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_mode_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`geom_radius_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_view_dist_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_tilt_angle_static`, Object: f32×2(0.0, 0.0)) + spv.OpStore(Pointer: &GV`geom_aspect_ratio_static`, Object: 1.3130699f32) + spv.OpStore(Pointer: &GV`geom_overscan_static`, Object: f32×2(1.0, 1.0)) + spv.OpStore(Pointer: &GV`geom_force_correct_tangent_matrix`, Object: true) + spv.OpStore(Pointer: &GV`border_size_static`, Object: 0.015f32) + spv.OpStore(Pointer: &GV`border_darkness_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`border_compress_static`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`bloom_approx_size_x`, Object: 320.0f32) + spv.OpStore(Pointer: &GV`bloom_approx_size_x_for_fake`, Object: 400.0f32) + spv.OpStore(Pointer: &GV`mask_resize_viewport_scale`, Object: f32×2(0.0625, 0.0625)) + spv.OpStore(Pointer: &GV`geom_max_aspect_ratio`, Object: 1.3333334f32) + spv.OpStore(Pointer: &GV`mask_texture_small_size`, Object: f32×2(64.0, 64.0)) + spv.OpStore(Pointer: &GV`mask_texture_large_size`, Object: f32×2(512.0, 512.0)) + spv.OpStore(Pointer: &GV`mask_triads_per_tile`, Object: 8.0f32) + spv.OpStore(Pointer: &GV`mask_grille14_avg_color`, Object: 0.19869281f32) + spv.OpStore(Pointer: &GV`mask_grille15_avg_color`, Object: 0.20784314f32) + spv.OpStore(Pointer: &GV`mask_slot_avg_color`, Object: 0.18039216f32) + spv.OpStore(Pointer: &GV`mask_shadow_avg_color`, Object: 0.16078432f32) + v18 = spv.OpLoad(Pointer: &GV`mask_grille15_avg_color`): f32 + spv.OpStore(Pointer: &GV`mask_grille_avg_color`, Object: v18) + v19 = spv.OpLoad(Pointer: &GV`bloom_approx_filter_static`): f32 + spv.OpStore(Pointer: &GV`bloom_approx_filter`, Object: v19) + v20 = spv.OpLoad(Pointer: &GV`mask_texture_small_size`): f32×2 + spv.OpStore(Pointer: &GV`mask_resize_src_lut_size`, Object: v20) + spv.OpStore(Pointer: &GV`max_aa_base_pixel_border`, Object: 0.0f32) + v21 = spv.OpLoad(Pointer: &GV`max_aa_base_pixel_border`): f32 + v22 = f.add(v21, 0.5f32): f32 + spv.OpStore(Pointer: &GV`max_aniso_pixel_border`, Object: v22) + v23 = spv.OpLoad(Pointer: &GV`max_aniso_pixel_border`): f32 + spv.OpStore(Pointer: &GV`max_tiled_pixel_border`, Object: v23) + v24 = spv.OpLoad(Pointer: &GV`max_tiled_pixel_border`): f32 + v25 = spv.extinst."GLSL.std.450".Ceil(X: v24): f32 + spv.OpStore(Pointer: &GV`max_mask_texel_border`, Object: v25) + v26 = spv.OpLoad(Pointer: &GV`max_mask_texel_border`): f32 + v27 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32 + v28 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v29 = f.mul(v27, v28): f32 + v30 = f.div(v26, v29): f32 + spv.OpStore(Pointer: &GV`max_mask_tile_border`, Object: v30) + spv.OpStore(Pointer: &GV`mask_resize_num_tiles`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`mask_start_texels`, Object: 0.0f32) + v31 = spv.OpLoad(Pointer: &GV`mask_resize_num_tiles`): f32 + v32 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v33 = f.mul(v31, v32): f32 + spv.OpStore(Pointer: &GV`mask_resize_num_triads`, Object: v33) + v34 = spv.OpLoad(Pointer: &GV`mask_resize_num_triads`): f32 + v35 = vec.new(v34, v34): f32×2 + v36 = spv.OpLoad(Pointer: &GV`mask_resize_viewport_scale`): f32×2 + v37 = vec.distribute(f.div)(v35, v36): f32×2 + spv.OpStore(Pointer: &GV`min_allowed_viewport_triads`, Object: v37) + spv.OpStore(Pointer: &GV`pi`, Object: 3.1415927f32) + spv.OpStore(Pointer: &GV`under_half`, Object: 0.4995f32) + spv.OpStore(Pointer: &GV`gba_gamma`, Object: 3.5f32) + v38 = spv.OpAccessChain(Base: &GV`global`, 46s32): T5 + v39 = spv.OpLoad(Pointer: v38): f32 + v40 = f.ne_or_unord(v39, 0.0f32): bool + spv.OpStore(Pointer: &GV`interlace_detect`, Object: v40) + spv.OpStore(Pointer: &GV`ntsc_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`pal_gamma`, Object: 2.8f32) + spv.OpStore(Pointer: &GV`crt_reference_gamma_high`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`crt_reference_gamma_low`, Object: 2.35f32) + spv.OpStore(Pointer: &GV`lcd_reference_gamma`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`crt_office_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`lcd_office_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`assume_opaque_alpha`, Object: false) + spv.OpStore(Pointer: &GV`linearize_input`, Object: false) + spv.OpStore(Pointer: &GV`gamma_encode_output`, Object: false) + v41 = spv.OpLoad(Pointer: &GV`linearize_input`): bool + v42 = bool.not(v41): bool + spv.OpStore(Pointer: &GV`gamma_aware_bilinear`, Object: v42) + v43 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32 + v44 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v45 = f.mul(v43, v44): f32 + v46 = spv.extinst."GLSL.std.450".Ceil(X: v45): f32 + spv.OpStore(Pointer: &GV`mask_min_allowed_tile_size`, Object: v46) + v47 = spv.OpLoad(Pointer: &GV`mask_min_allowed_tile_size`): f32 + spv.OpStore(Pointer: &GV`mask_min_expected_tile_size`, Object: v47) + v48 = spv.OpLoad(Pointer: &GV`pi`): f32 + v49 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32 + v50 = f.div(v48, v49): f32 + spv.OpStore(Pointer: &GV`pi_over_lobes`, Object: v50) + v51 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32 + v52 = f.mul(2.0f32, v51): f32 + v53 = spv.OpAccessChain(Base: &GV`mask_resize_src_lut_size`, 0u32): spv.OpTypePointer(spv.StorageClass.Private, f32) + v54 = spv.OpLoad(Pointer: v53): f32 + v55 = f.mul(v52, v54): f32 + v56 = spv.OpLoad(Pointer: &GV`mask_min_expected_tile_size`): f32 + v57 = f.div(v55, v56): f32 + spv.OpStore(Pointer: &GV`max_sinc_resize_samples_float`, Object: v57) + v58 = spv.OpLoad(Pointer: &GV`max_sinc_resize_samples_float`): f32 + v59 = f.mul(v58, 0.25f32): f32 + v60 = spv.extinst."GLSL.std.450".Ceil(X: v59): f32 + v61 = f.mul(v60, 4.0f32): f32 + spv.OpStore(Pointer: &GV`max_sinc_resize_samples_m4`, Object: v61) + spv.OpStore(Pointer: &GV`blur3_std_dev`, Object: 0.62666017f32) + spv.OpStore(Pointer: &GV`blur4_std_dev`, Object: 0.6617187f32) + spv.OpStore(Pointer: &GV`blur5_std_dev`, Object: 0.9845703f32) + spv.OpStore(Pointer: &GV`blur6_std_dev`, Object: 1.0262696f32) + spv.OpStore(Pointer: &GV`blur7_std_dev`, Object: 1.3610351f32) + spv.OpStore(Pointer: &GV`blur8_std_dev`, Object: 1.4080079f32) + spv.OpStore(Pointer: &GV`blur9_std_dev`, Object: 1.7533203f32) + spv.OpStore(Pointer: &GV`blur10_std_dev`, Object: 1.8047851f32) + spv.OpStore(Pointer: &GV`blur11_std_dev`, Object: 2.1598632f32) + spv.OpStore(Pointer: &GV`blur12_std_dev`, Object: 2.2152343f32) + spv.OpStore(Pointer: &GV`blur17_std_dev`, Object: 3.455356f32) + spv.OpStore(Pointer: &GV`blur25_std_dev`, Object: 5.3409576f32) + spv.OpStore(Pointer: &GV`blur31_std_dev`, Object: 6.8648806f32) + spv.OpStore(Pointer: &GV`blur43_std_dev`, Object: 10.185205f32) + spv.OpStore(Pointer: &GV`error_blurring`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`bloom_diff_thresh`, Object: 0.00390625f32) + v62 = spv.OpLoad(Pointer: &GV`scanline_tex_uv`): f32×2 + spv.OpStore(Pointer: v0, Object: v62) + v63 = spv.OpAccessChain(Base: &GV`params`, 3s32): spv.OpTypePointer(spv.StorageClass.PushConstant, f32×4) + v64 = spv.OpLoad(Pointer: v63): f32×4 + v65 = spv.OpVectorShuffle(Vector1: v64, Vector2: v64, 0, 1): f32×2 + spv.OpStore(Pointer: v1, Object: v65) + v66 = spv.OpLoad(Pointer: &GV`scanline_texture_size_inv`): f32×2 + spv.OpStore(Pointer: v2, Object: v66) + v67 = call F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(&GV`VERTICAL_SCANLINES`, &GV`_VERTICAL_SCANLINES_sampler`, v0, v1, v2): + f32×3 + spv.OpStore(Pointer: v`scanline_color_dim`, Object: v67) + v68 = spv.OpLoad(Pointer: &GV`levels_autodim_temp`): f32 + spv.OpStore(Pointer: v`auto_dim_factor`, Object: v68) + v69 = spv.OpLoad(Pointer: &GV`video_uv`): f32×2 + v70 = spv.OpLoad(Pointer: &GV`mask_tiles_per_screen`): f32×2 + v71 = vec.distribute(f.mul)(v69, v70): f32×2 + spv.OpStore(Pointer: v3, Object: v71) + v72 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v5, Object: v72) + v73 = spv.OpLoad(Pointer: &GV0): f32×4 + spv.OpStore(Pointer: v6, Object: v73) + v74 = call F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(v5, v6): f32×2 + spv.OpStore(Pointer: v4, Object: v74) + v75 = call F`get_mask_sample_mode(`(): f32 + v76 = f.gt(v75, 0.5f32): bool + spv.OpStore(Pointer: v`sample_orig_luts`, Object: v76) + v77 = spv.OpLoad(Pointer: v`sample_orig_luts`): bool + if v77 { + branch L0 + } else { + branch L7 + } + + label L0: + v78 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5 + v79 = spv.OpLoad(Pointer: v78): f32 + v80 = f.lt(v79, 0.5f32): bool + if v80 { + branch L1 + } else { + branch L2 + } + + label L1: + v81 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v7, Object: v81) + v82 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_grille_texture_large`, &GV`_mask_grille_texture_large_sampler`, v7): f32×4 + v83 = spv.OpVectorShuffle(Vector1: v82, Vector2: v82, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v83) + branch L6 + + label L2: + v84 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5 + v85 = spv.OpLoad(Pointer: v84): f32 + v86 = f.lt(v85, 1.5f32): bool + if v86 { + branch L3 + } else { + branch L4 + } + + label L3: + v87 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v8, Object: v87) + v88 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_slot_texture_large`, &GV`_mask_slot_texture_large_sampler`, v8): f32×4 + v89 = spv.OpVectorShuffle(Vector1: v88, Vector2: v88, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v89) + branch L5 + + label L4: + v90 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v9, Object: v90) + v91 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_shadow_texture_large`, &GV`_mask_shadow_texture_large_sampler`, v9): f32×4 + v92 = spv.OpVectorShuffle(Vector1: v91, Vector2: v91, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v92) + branch L5 + + label L5: + branch L6 + + label L6: + branch L8 + + label L7: + v93 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v10, Object: v93) + v94 = call F`tex2Dtiled_mask_linearize(s21;vf2;`(&GV`MASK_RESIZE`, &GV`_MASK_RESIZE_sampler`, v10): f32×4 + v95 = spv.OpVectorShuffle(Vector1: v94, Vector2: v94, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v95) + branch L8 + + label L8: + v96 = spv.OpLoad(Pointer: &GV`halation_tex_uv`): f32×2 + spv.OpStore(Pointer: v11, Object: v96) + v97 = call F`tex2D_linearize(s21;vf2;`(&GV`HALATION_BLUR`, &GV`_HALATION_BLUR_sampler`, v11): f32×4 + v98 = spv.OpVectorShuffle(Vector1: v97, Vector2: v97, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`halation_color`, Object: v98) + v99 = spv.OpLoad(Pointer: v`halation_color`): f32×3 + v100 = spv.OpLoad(Pointer: v`auto_dim_factor`): f32 + v101 = f.div(v100, 3.0f32): f32 + v102 = vec.new(v101, v101, v101): f32×3 + v103 = vec.dot(v99, v102): f32 + v104 = vec.new(v103, v103, v103): f32×3 + spv.OpStore(Pointer: v`halation_intensity_dim`, Object: v104) + v105 = spv.OpLoad(Pointer: v`scanline_color_dim`): f32×3 + v106 = spv.OpLoad(Pointer: v`halation_intensity_dim`): f32×3 + v107 = spv.OpAccessChain(Base: &GV`global`, 4s32): T5 + v108 = spv.OpLoad(Pointer: v107): f32 + v109 = vec.new(v108, v108, v108): f32×3 + v110 = spv.extinst."GLSL.std.450".FMix(X: v105, Y: v106, A: v109): f32×3 + spv.OpStore(Pointer: v`electron_intensity_dim`, Object: v110) + v111 = spv.OpLoad(Pointer: v`electron_intensity_dim`): f32×3 + v112 = spv.OpLoad(Pointer: v`phosphor_mask_sample`): f32×3 + v113 = vec.distribute(f.mul)(v111, v112): f32×3 + spv.OpStore(Pointer: v`phosphor_emission_dim`, Object: v113) + v114 = spv.OpLoad(Pointer: v`phosphor_emission_dim`): f32×3 + spv.OpStore(Pointer: v`pixel_color`, Object: v114) + v115 = spv.OpLoad(Pointer: v`pixel_color`): f32×3 + v116 = vec.extract(v115, 0): f32 + v117 = vec.extract(v115, 1): f32 + v118 = vec.extract(v115, 2): f32 + v119 = vec.new(v116, v117, v118, 1.0f32): f32×4 + spv.OpStore(Pointer: v12, Object: v119) + v120 = call F`encode_output(vf4;`(v12): f32×4 + spv.OpStore(Pointer: &GV`FragColor`, Object: v120) + return +} + +export { + spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F`main`, +} \ No newline at end of file diff --git a/librashader-reflect/out.spirt.html b/librashader-reflect/out.spirt.html new file mode 100644 index 0000000..f5a05dd --- /dev/null +++ b/librashader-reflect/out.spirt.html @@ -0,0 +1,1624 @@ + + + + + + + + + + + + + +
+module.dialect = spv.Module(version: 1.0, spv.Capability.Shader, spv.MemoryModel.GLSL450)
+
+module.debug_info = spv.Module.DebugInfo(
+  generator: spv.Tool(id: 15),
+  source_languages: {
+    spv.SourceLanguage.GLSL(version: 450): {},
+  },
+  source_extensions: ["GL_GOOGLE_cpp_style_line_directive", "GL_GOOGLE_include_directive"],
+)
+
+type T0 = spv.OpTypePointer(spv.StorageClass.Function, f32×3)
+
+type T1 = spv.OpTypePointer(spv.StorageClass.Function, f32×2)
+
+type T2 = spv.OpTypePointer(spv.StorageClass.Function, f32)
+
+type T3 = spv.OpTypePointer(spv.StorageClass.Function, f32×4)
+
+type T4 = spv.OpTypePointer(spv.StorageClass.PushConstant, f32)
+
+#[spv.OpMemberName(Member: 0, Name: "SourceSize")]
+#[spv.OpMemberName(Member: 1, Name: "OriginalSize")]
+#[spv.OpMemberName(Member: 2, Name: "OutputSize")]
+#[spv.OpMemberName(Member: 3, Name: "VERTICAL_SCANLINESSize")]
+#[spv.OpMemberName(Member: 4, Name: "BLOOM_APPROXSize")]
+#[spv.OpMemberName(Member: 5, Name: "HALATION_BLURSize")]
+#[spv.OpMemberName(Member: 6, Name: "MASK_RESIZESize")]
+#[spv.Decoration.Block]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))]
+#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 16))]
+#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 32))]
+#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 48))]
+#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 64))]
+#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))]
+#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 96))]
+type T`Push` = spv.OpTypeStruct(f32×4, f32×4, f32×4, f32×4, f32×4, f32×4, f32×4)
+
+type T5 = spv.OpTypePointer(spv.StorageClass.Uniform, f32)
+
+#[spv.OpMemberName(Member: 0, Name: "MVP")]
+#[spv.OpMemberName(Member: 1, Name: "crt_gamma")]
+#[spv.OpMemberName(Member: 2, Name: "lcd_gamma")]
+#[spv.OpMemberName(Member: 3, Name: "levels_contrast")]
+#[spv.OpMemberName(Member: 4, Name: "halation_weight")]
+#[spv.OpMemberName(Member: 5, Name: "diffusion_weight")]
+#[spv.OpMemberName(Member: 6, Name: "bloom_underestimate_levels")]
+#[spv.OpMemberName(Member: 7, Name: "bloom_excess")]
+#[spv.OpMemberName(Member: 8, Name: "beam_min_sigma")]
+#[spv.OpMemberName(Member: 9, Name: "beam_max_sigma")]
+#[spv.OpMemberName(Member: 10, Name: "beam_spot_power")]
+#[spv.OpMemberName(Member: 11, Name: "beam_min_shape")]
+#[spv.OpMemberName(Member: 12, Name: "beam_max_shape")]
+#[spv.OpMemberName(Member: 13, Name: "beam_shape_power")]
+#[spv.OpMemberName(Member: 14, Name: "beam_horiz_filter")]
+#[spv.OpMemberName(Member: 15, Name: "beam_horiz_sigma")]
+#[spv.OpMemberName(Member: 16, Name: "beam_horiz_linear_rgb_weight")]
+#[spv.OpMemberName(Member: 17, Name: "convergence_offset_x_r")]
+#[spv.OpMemberName(Member: 18, Name: "convergence_offset_x_g")]
+#[spv.OpMemberName(Member: 19, Name: "convergence_offset_x_b")]
+#[spv.OpMemberName(Member: 20, Name: "convergence_offset_y_r")]
+#[spv.OpMemberName(Member: 21, Name: "convergence_offset_y_g")]
+#[spv.OpMemberName(Member: 22, Name: "convergence_offset_y_b")]
+#[spv.OpMemberName(Member: 23, Name: "mask_type")]
+#[spv.OpMemberName(Member: 24, Name: "mask_sample_mode_desired")]
+#[spv.OpMemberName(Member: 25, Name: "mask_num_triads_desired")]
+#[spv.OpMemberName(Member: 26, Name: "mask_triad_size_desired")]
+#[spv.OpMemberName(Member: 27, Name: "mask_specify_num_triads")]
+#[spv.OpMemberName(Member: 28, Name: "aa_subpixel_r_offset_x_runtime")]
+#[spv.OpMemberName(Member: 29, Name: "aa_subpixel_r_offset_y_runtime")]
+#[spv.OpMemberName(Member: 30, Name: "aa_cubic_c")]
+#[spv.OpMemberName(Member: 31, Name: "aa_gauss_sigma")]
+#[spv.OpMemberName(Member: 32, Name: "geom_mode_runtime")]
+#[spv.OpMemberName(Member: 33, Name: "geom_radius")]
+#[spv.OpMemberName(Member: 34, Name: "geom_view_dist")]
+#[spv.OpMemberName(Member: 35, Name: "geom_tilt_angle_x")]
+#[spv.OpMemberName(Member: 36, Name: "geom_tilt_angle_y")]
+#[spv.OpMemberName(Member: 37, Name: "geom_aspect_ratio_x")]
+#[spv.OpMemberName(Member: 38, Name: "geom_aspect_ratio_y")]
+#[spv.OpMemberName(Member: 39, Name: "geom_overscan_x")]
+#[spv.OpMemberName(Member: 40, Name: "geom_overscan_y")]
+#[spv.OpMemberName(Member: 41, Name: "border_size")]
+#[spv.OpMemberName(Member: 42, Name: "border_darkness")]
+#[spv.OpMemberName(Member: 43, Name: "border_compress")]
+#[spv.OpMemberName(Member: 44, Name: "interlace_bff")]
+#[spv.OpMemberName(Member: 45, Name: "interlace_1080i")]
+#[spv.OpMemberName(Member: 46, Name: "interlace_detect_toggle")]
+#[spv.Decoration.Block]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.ColMajor)]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.MatrixStride(MatrixStride: 16))]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))]
+#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 64))]
+#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 68))]
+#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 72))]
+#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 76))]
+#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))]
+#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 84))]
+#[spv.OpMemberDecorate(Member: 7, spv.Decoration.Offset(ByteOffset: 88))]
+#[spv.OpMemberDecorate(Member: 8, spv.Decoration.Offset(ByteOffset: 92))]
+#[spv.OpMemberDecorate(Member: 9, spv.Decoration.Offset(ByteOffset: 96))]
+#[spv.OpMemberDecorate(Member: 10, spv.Decoration.Offset(ByteOffset: 100))]
+#[spv.OpMemberDecorate(Member: 11, spv.Decoration.Offset(ByteOffset: 104))]
+#[spv.OpMemberDecorate(Member: 12, spv.Decoration.Offset(ByteOffset: 108))]
+#[spv.OpMemberDecorate(Member: 13, spv.Decoration.Offset(ByteOffset: 112))]
+#[spv.OpMemberDecorate(Member: 14, spv.Decoration.Offset(ByteOffset: 116))]
+#[spv.OpMemberDecorate(Member: 15, spv.Decoration.Offset(ByteOffset: 120))]
+#[spv.OpMemberDecorate(Member: 16, spv.Decoration.Offset(ByteOffset: 124))]
+#[spv.OpMemberDecorate(Member: 17, spv.Decoration.Offset(ByteOffset: 128))]
+#[spv.OpMemberDecorate(Member: 18, spv.Decoration.Offset(ByteOffset: 132))]
+#[spv.OpMemberDecorate(Member: 19, spv.Decoration.Offset(ByteOffset: 136))]
+#[spv.OpMemberDecorate(Member: 20, spv.Decoration.Offset(ByteOffset: 140))]
+#[spv.OpMemberDecorate(Member: 21, spv.Decoration.Offset(ByteOffset: 144))]
+#[spv.OpMemberDecorate(Member: 22, spv.Decoration.Offset(ByteOffset: 148))]
+#[spv.OpMemberDecorate(Member: 23, spv.Decoration.Offset(ByteOffset: 152))]
+#[spv.OpMemberDecorate(Member: 24, spv.Decoration.Offset(ByteOffset: 156))]
+#[spv.OpMemberDecorate(Member: 25, spv.Decoration.Offset(ByteOffset: 160))]
+#[spv.OpMemberDecorate(Member: 26, spv.Decoration.Offset(ByteOffset: 164))]
+#[spv.OpMemberDecorate(Member: 27, spv.Decoration.Offset(ByteOffset: 168))]
+#[spv.OpMemberDecorate(Member: 28, spv.Decoration.Offset(ByteOffset: 172))]
+#[spv.OpMemberDecorate(Member: 29, spv.Decoration.Offset(ByteOffset: 176))]
+#[spv.OpMemberDecorate(Member: 30, spv.Decoration.Offset(ByteOffset: 180))]
+#[spv.OpMemberDecorate(Member: 31, spv.Decoration.Offset(ByteOffset: 184))]
+#[spv.OpMemberDecorate(Member: 32, spv.Decoration.Offset(ByteOffset: 188))]
+#[spv.OpMemberDecorate(Member: 33, spv.Decoration.Offset(ByteOffset: 192))]
+#[spv.OpMemberDecorate(Member: 34, spv.Decoration.Offset(ByteOffset: 196))]
+#[spv.OpMemberDecorate(Member: 35, spv.Decoration.Offset(ByteOffset: 200))]
+#[spv.OpMemberDecorate(Member: 36, spv.Decoration.Offset(ByteOffset: 204))]
+#[spv.OpMemberDecorate(Member: 37, spv.Decoration.Offset(ByteOffset: 208))]
+#[spv.OpMemberDecorate(Member: 38, spv.Decoration.Offset(ByteOffset: 212))]
+#[spv.OpMemberDecorate(Member: 39, spv.Decoration.Offset(ByteOffset: 216))]
+#[spv.OpMemberDecorate(Member: 40, spv.Decoration.Offset(ByteOffset: 220))]
+#[spv.OpMemberDecorate(Member: 41, spv.Decoration.Offset(ByteOffset: 224))]
+#[spv.OpMemberDecorate(Member: 42, spv.Decoration.Offset(ByteOffset: 228))]
+#[spv.OpMemberDecorate(Member: 43, spv.Decoration.Offset(ByteOffset: 232))]
+#[spv.OpMemberDecorate(Member: 44, spv.Decoration.Offset(ByteOffset: 236))]
+#[spv.OpMemberDecorate(Member: 45, spv.Decoration.Offset(ByteOffset: 240))]
+#[spv.OpMemberDecorate(Member: 46, spv.Decoration.Offset(ByteOffset: 244))]
+type T`UBO` = spv.OpTypeStruct(
+  spv.OpTypeMatrix(ColumnType: f32×4, ColumnCount: 4),
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+)
+
+type T6 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown)
+
+type T7 = spv.OpTypeSampledImage(ImageType: T6)
+
+type T8 = spv.OpTypePointer(spv.StorageClass.UniformConstant, T7)
+
+type T9 = spv.OpTypePointer(spv.StorageClass.UniformConstant, spv.OpTypeSampler)
+
+#[spv.Decoration.Location(Location: 1)]
+global_var GV`scanline_tex_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 4)]
+global_var GV`scanline_texture_size_inv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 0)]
+global_var GV`video_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 6)]
+global_var GV`mask_tiles_per_screen`(spv.StorageClass.Input): f32×2
+
+#[name = "mask_tile_start_uv_and_size"]
+#[spv.Decoration.Location(Location: 5)]
+global_var GV0(spv.StorageClass.Input): f32×4
+
+#[spv.Decoration.Location(Location: 3)]
+global_var GV`halation_tex_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 0)]
+global_var GV`FragColor`(spv.StorageClass.Output): f32×4
+
+#[spv.Decoration.Location(Location: 2)]
+global_var GV`blur3x3_tex_uv`(spv.StorageClass.Input): f32×2
+
+global_var GV`params`(spv.StorageClass.PushConstant): T`Push`
+
+global_var GV`bloom_approx_scale_x`(spv.StorageClass.Private): f32
+
+global_var GV`crt_gamma_static`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_gamma_static`(spv.StorageClass.Private): f32
+
+global_var GV`levels_contrast_static`(spv.StorageClass.Private): f32
+
+global_var GV`levels_autodim_temp`(spv.StorageClass.Private): f32
+
+global_var GV`halation_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`diffusion_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_underestimate_levels_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_excess_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_filter_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_num_scanlines`(spv.StorageClass.Private): f32
+
+global_var GV`beam_generalized_gaussian`(spv.StorageClass.Private): bool
+
+global_var GV`beam_antialias_level`(spv.StorageClass.Private): f32
+
+global_var GV`beam_min_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_max_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_spot_shape_function`(spv.StorageClass.Private): f32
+
+global_var GV`beam_spot_power_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_min_shape_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_max_shape_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_shape_power_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_filter_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_linear_rgb_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_misconvergence`(spv.StorageClass.Private): bool
+
+global_var GV`convergence_offsets_r_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`convergence_offsets_g_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`convergence_offsets_b_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`interlace_detect_static`(spv.StorageClass.Private): bool
+
+global_var GV`interlace_1080i_static`(spv.StorageClass.Private): bool
+
+global_var GV`interlace_bff_static`(spv.StorageClass.Private): bool
+
+global_var GV`aa_level`(spv.StorageClass.Private): f32
+
+global_var GV`aa_filter`(spv.StorageClass.Private): f32
+
+global_var GV`aa_temporal`(spv.StorageClass.Private): bool
+
+global_var GV`aa_subpixel_r_offset_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`aa_cubic_c_static`(spv.StorageClass.Private): f32
+
+global_var GV`aa_gauss_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_type_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_sample_mode_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_specify_num_triads_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_triad_size_desired_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_num_triads_desired_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_sinc_lobes`(spv.StorageClass.Private): f32
+
+global_var GV`mask_min_allowed_triad_size`(spv.StorageClass.Private): f32
+
+global_var GV`geom_mode_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_radius_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_view_dist_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_tilt_angle_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_aspect_ratio_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_overscan_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_force_correct_tangent_matrix`(spv.StorageClass.Private): bool
+
+global_var GV`border_size_static`(spv.StorageClass.Private): f32
+
+global_var GV`border_darkness_static`(spv.StorageClass.Private): f32
+
+global_var GV`border_compress_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_size_x`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_size_x_for_fake`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_viewport_scale`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_max_aspect_ratio`(spv.StorageClass.Private): f32
+
+global_var GV`mask_texture_small_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`mask_texture_large_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`mask_triads_per_tile`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille14_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille15_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_slot_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_shadow_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_filter`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_src_lut_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`max_aa_base_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_aniso_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_tiled_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_mask_texel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_mask_tile_border`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_num_tiles`(spv.StorageClass.Private): f32
+
+global_var GV`mask_start_texels`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_num_triads`(spv.StorageClass.Private): f32
+
+global_var GV`min_allowed_viewport_triads`(spv.StorageClass.Private): f32×2
+
+global_var GV`pi`(spv.StorageClass.Private): f32
+
+global_var GV`under_half`(spv.StorageClass.Private): f32
+
+global_var GV`gba_gamma`(spv.StorageClass.Private): f32
+
+#[spv.Decoration.Binding(BindingPoint: 0)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`global`(spv.StorageClass.Uniform): T`UBO`
+
+global_var GV`interlace_detect`(spv.StorageClass.Private): bool
+
+global_var GV`ntsc_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`pal_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`crt_reference_gamma_high`(spv.StorageClass.Private): f32
+
+global_var GV`crt_reference_gamma_low`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_reference_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`crt_office_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_office_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`assume_opaque_alpha`(spv.StorageClass.Private): bool
+
+global_var GV`linearize_input`(spv.StorageClass.Private): bool
+
+global_var GV`gamma_encode_output`(spv.StorageClass.Private): bool
+
+global_var GV`gamma_aware_bilinear`(spv.StorageClass.Private): bool
+
+global_var GV`mask_min_allowed_tile_size`(spv.StorageClass.Private): f32
+
+global_var GV`mask_min_expected_tile_size`(spv.StorageClass.Private): f32
+
+global_var GV`pi_over_lobes`(spv.StorageClass.Private): f32
+
+global_var GV`max_sinc_resize_samples_float`(spv.StorageClass.Private): f32
+
+global_var GV`max_sinc_resize_samples_m4`(spv.StorageClass.Private): f32
+
+global_var GV`blur3_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur4_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur5_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur6_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur7_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur8_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur9_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur10_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur11_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur12_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur17_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur25_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur31_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur43_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`error_blurring`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_diff_thresh`(spv.StorageClass.Private): f32
+
+func F`get_convergence_offsets_x_vector(`() -> f32×3 {
+    v0 = spv.OpAccessChain(Base: &GV`global`, 17s32): T5
+    v1 = spv.OpLoad(Pointer: v0): f32
+    v2 = spv.OpAccessChain(Base: &GV`global`, 18s32): T5
+    v3 = spv.OpLoad(Pointer: v2): f32
+    v4 = spv.OpAccessChain(Base: &GV`global`, 19s32): T5
+    v5 = spv.OpLoad(Pointer: v4): f32
+    v6 = vec.new(v1, v3, v5): f32×3
+  return v6
+}
+
+func F`get_intermediate_gamma(`() -> f32 {
+    v0 = spv.OpLoad(Pointer: &GV`ntsc_gamma`): f32
+  return v0
+}
+
+func F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(
+  #[name = "color0"]
+  v0: T0,
+  #[name = "color1"]
+  v1: T0,
+  #[name = "color2"]
+  v2: T0,
+  #[name = "color3"]
+  v3: T0,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+    v5 = spv.OpLoad(Pointer: v0): f32×3
+    v6 = spv.OpLoad(Pointer: v1): f32×3
+    v7 = spv.OpLoad(Pointer: v2): f32×3
+    v8 = spv.OpLoad(Pointer: v3): f32×3
+    v9 = vec.extract(v5, 0): f32
+    v10 = vec.extract(v5, 1): f32
+    v11 = vec.extract(v5, 2): f32
+    v12 = vec.extract(v6, 0): f32
+    v13 = vec.extract(v6, 1): f32
+    v14 = vec.extract(v6, 2): f32
+    v15 = vec.extract(v7, 0): f32
+    v16 = vec.extract(v7, 1): f32
+    v17 = vec.extract(v7, 2): f32
+    v18 = vec.extract(v8, 0): f32
+    v19 = vec.extract(v8, 1): f32
+    v20 = vec.extract(v8, 2): f32
+    v21 = vec.new(v9, v10, v11): f32×3
+    v22 = vec.new(v12, v13, v14): f32×3
+    v23 = vec.new(v15, v16, v17): f32×3
+    v24 = vec.new(v18, v19, v20): f32×3
+    v25 = vec.new(v21, v22, v23, v24): spv.OpTypeMatrix(ColumnType: f32×3, ColumnCount: 4)
+    v26 = spv.OpLoad(Pointer: v4): f32×4
+    v27 = spv.OpMatrixTimesVector(Matrix: v25, Vector: v26): f32×3
+    v28 = vec.new(0.0f32, 0.0f32, 0.0f32): f32×3
+    v29 = spv.extinst."GLSL.std.450".FMax(X: v27, Y: v28): f32×3
+  return v29
+}
+
+func F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(
+  #[name = "color0"]
+  v0: T0,
+  #[name = "color1"]
+  v1: T0,
+  #[name = "color2"]
+  v2: T0,
+  #[name = "color3"]
+  v3: T0,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+    v`intermediate_gamma` = spv.OpVariable(spv.StorageClass.Function): T2
+    v`linear_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v5 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v6 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v7 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v8 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v9 = spv.OpVariable(spv.StorageClass.Function): T3
+    v`gamma_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v10 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v11 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v12 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v13 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v14 = spv.OpVariable(spv.StorageClass.Function): T3
+    v15 = call F`get_intermediate_gamma(`(): f32
+    spv.OpStore(Pointer: v`intermediate_gamma`, Object: v15)
+    v16 = spv.OpLoad(Pointer: v0): f32×3
+    spv.OpStore(Pointer: v5, Object: v16)
+    v17 = spv.OpLoad(Pointer: v1): f32×3
+    spv.OpStore(Pointer: v6, Object: v17)
+    v18 = spv.OpLoad(Pointer: v2): f32×3
+    spv.OpStore(Pointer: v7, Object: v18)
+    v19 = spv.OpLoad(Pointer: v3): f32×3
+    spv.OpStore(Pointer: v8, Object: v19)
+    v20 = spv.OpLoad(Pointer: v4): f32×4
+    spv.OpStore(Pointer: v9, Object: v20)
+    v21 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v5, v6, v7, v8, v9): f32×3
+    spv.OpStore(Pointer: v`linear_mixed_color`, Object: v21)
+    v22 = spv.OpLoad(Pointer: v0): f32×3
+    v23 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+    v24 = f.div(1.0f32, v23): f32
+    v25 = vec.new(v24, v24, v24): f32×3
+    v26 = spv.extinst."GLSL.std.450".Pow(X: v22, Y: v25): f32×3
+    v27 = spv.OpLoad(Pointer: v1): f32×3
+    v28 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+    v29 = f.div(1.0f32, v28): f32
+    v30 = vec.new(v29, v29, v29): f32×3
+    v31 = spv.extinst."GLSL.std.450".Pow(X: v27, Y: v30): f32×3
+    v32 = spv.OpLoad(Pointer: v2): f32×3
+    v33 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+    v34 = f.div(1.0f32, v33): f32
+    v35 = vec.new(v34, v34, v34): f32×3
+    v36 = spv.extinst."GLSL.std.450".Pow(X: v32, Y: v35): f32×3
+    v37 = spv.OpLoad(Pointer: v3): f32×3
+    v38 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+    v39 = f.div(1.0f32, v38): f32
+    v40 = vec.new(v39, v39, v39): f32×3
+    v41 = spv.extinst."GLSL.std.450".Pow(X: v37, Y: v40): f32×3
+    spv.OpStore(Pointer: v10, Object: v26)
+    spv.OpStore(Pointer: v11, Object: v31)
+    spv.OpStore(Pointer: v12, Object: v36)
+    spv.OpStore(Pointer: v13, Object: v41)
+    v42 = spv.OpLoad(Pointer: v4): f32×4
+    spv.OpStore(Pointer: v14, Object: v42)
+    v43 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v10, v11, v12, v13, v14): f32×3
+    spv.OpStore(Pointer: v`gamma_mixed_color`, Object: v43)
+    v44 = spv.OpLoad(Pointer: v`gamma_mixed_color`): f32×3
+    v45 = spv.OpLoad(Pointer: v`linear_mixed_color`): f32×3
+    v46 = spv.OpAccessChain(Base: &GV`global`, 16s32): T5
+    v47 = spv.OpLoad(Pointer: v46): f32
+    v48 = vec.new(v47, v47, v47): f32×3
+    v49 = spv.extinst."GLSL.std.450".FMix(X: v44, Y: v45, A: v48): f32×3
+  return v49
+}
+
+func F`get_scanline_color(s21;vf2;vf2;vf4;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "scanline_uv"]
+  v2: T1,
+  #[name = "uv_step_x"]
+  v3: T1,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+    #[name = "color1"]
+    v5 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "color2"]
+    v6 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "color0"]
+    v7 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "color3"]
+    v8 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v9 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v10 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v11 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v12 = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v13 = spv.OpVariable(spv.StorageClass.Function): T3
+    v14 = spv.OpLoad(Pointer: v0): T6
+    v15 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v16 = spv.OpSampledImage(Image: v14, Sampler: v15): T7
+    v17 = spv.OpLoad(Pointer: v2): f32×2
+    v18 = spv.OpImageSampleImplicitLod(SampledImage: v16, Coordinate: v17): f32×4
+    v19 = spv.OpVectorShuffle(Vector1: v18, Vector2: v18, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v5, Object: v19)
+    v20 = spv.OpLoad(Pointer: v0): T6
+    v21 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v22 = spv.OpSampledImage(Image: v20, Sampler: v21): T7
+    v23 = spv.OpLoad(Pointer: v2): f32×2
+    v24 = spv.OpLoad(Pointer: v3): f32×2
+    v25 = vec.distribute(f.add)(v23, v24): f32×2
+    v26 = spv.OpImageSampleImplicitLod(SampledImage: v22, Coordinate: v25): f32×4
+    v27 = spv.OpVectorShuffle(Vector1: v26, Vector2: v26, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v6, Object: v27)
+    spv.OpStore(Pointer: v7, Object: f32×3(0.0, 0.0, 0.0))
+    spv.OpStore(Pointer: v8, Object: f32×3(0.0, 0.0, 0.0))
+    v28 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+    v29 = spv.OpLoad(Pointer: v28): f32
+    v30 = f.gt(v29, 0.5f32): bool
+  if v30 {
+    branch L0
+  } else {
+    branch L1
+  }
+
+  label L0:
+    v31 = spv.OpLoad(Pointer: v0): T6
+    v32 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v33 = spv.OpSampledImage(Image: v31, Sampler: v32): T7
+    v34 = spv.OpLoad(Pointer: v2): f32×2
+    v35 = spv.OpLoad(Pointer: v3): f32×2
+    v36 = vec.distribute(f.sub)(v34, v35): f32×2
+    v37 = spv.OpImageSampleImplicitLod(SampledImage: v33, Coordinate: v36): f32×4
+    v38 = spv.OpVectorShuffle(Vector1: v37, Vector2: v37, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v7, Object: v38)
+    v39 = spv.OpLoad(Pointer: v0): T6
+    v40 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v41 = spv.OpSampledImage(Image: v39, Sampler: v40): T7
+    v42 = spv.OpLoad(Pointer: v2): f32×2
+    v43 = spv.OpLoad(Pointer: v3): f32×2
+    v44 = vec.mul(v43, 2.0f32): f32×2
+    v45 = vec.distribute(f.add)(v42, v44): f32×2
+    v46 = spv.OpImageSampleImplicitLod(SampledImage: v41, Coordinate: v45): f32×4
+    v47 = spv.OpVectorShuffle(Vector1: v46, Vector2: v46, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v8, Object: v47)
+  branch L1
+
+  label L1:
+    v48 = spv.OpLoad(Pointer: v7): f32×3
+    spv.OpStore(Pointer: v9, Object: v48)
+    v49 = spv.OpLoad(Pointer: v5): f32×3
+    spv.OpStore(Pointer: v10, Object: v49)
+    v50 = spv.OpLoad(Pointer: v6): f32×3
+    spv.OpStore(Pointer: v11, Object: v50)
+    v51 = spv.OpLoad(Pointer: v8): f32×3
+    spv.OpStore(Pointer: v12, Object: v51)
+    v52 = spv.OpLoad(Pointer: v4): f32×4
+    spv.OpStore(Pointer: v13, Object: v52)
+    v53 = call F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(v9, v10, v11, v12, v13): f32×3
+  return v53
+}
+
+func F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+  #[name = "tex_size"]
+  v3: T1,
+  #[name = "texture_size_inv"]
+  v4: T1,
+) -> f32×3 {
+    v`curr_texel` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`prev_texel` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`prev_texel_hor` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`prev_texel_hor_uv` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`prev_dist` = spv.OpVariable(spv.StorageClass.Function): T2
+    v`sample_dists` = spv.OpVariable(spv.StorageClass.Function): T3
+    v`x` = spv.OpVariable(spv.StorageClass.Function): T2
+    v`w2` = spv.OpVariable(spv.StorageClass.Function): T2
+    #[name = "weights"]
+    v5 = spv.OpVariable(spv.StorageClass.Function): T3
+    v`inner_denom_inv` = spv.OpVariable(spv.StorageClass.Function): T2
+    v`pi_dists` = spv.OpVariable(spv.StorageClass.Function): T3
+    v`final_weights` = spv.OpVariable(spv.StorageClass.Function): T3
+    #[name = "uv_step_x"]
+    v6 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v7 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v8 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v9 = spv.OpVariable(spv.StorageClass.Function): T3
+    v10 = spv.OpLoad(Pointer: v2): f32×2
+    v11 = spv.OpLoad(Pointer: v3): f32×2
+    v12 = vec.distribute(f.mul)(v10, v11): f32×2
+    spv.OpStore(Pointer: v`curr_texel`, Object: v12)
+    v13 = spv.OpLoad(Pointer: v`curr_texel`): f32×2
+    v14 = spv.OpLoad(Pointer: &GV`under_half`): f32
+    v15 = vec.new(v14, v14): f32×2
+    v16 = vec.distribute(f.sub)(v13, v15): f32×2
+    v17 = spv.extinst."GLSL.std.450".Floor(X: v16): f32×2
+    v18 = vec.distribute(f.add)(v17, f32×2(0.5, 0.5)): f32×2
+    spv.OpStore(Pointer: v`prev_texel`, Object: v18)
+    v19 = spv.OpAccessChain(Base: v`prev_texel`, 0u32): T2
+    v20 = spv.OpLoad(Pointer: v19): f32
+    v21 = spv.OpAccessChain(Base: v`curr_texel`, 1u32): T2
+    v22 = spv.OpLoad(Pointer: v21): f32
+    v23 = vec.new(v20, v22): f32×2
+    spv.OpStore(Pointer: v`prev_texel_hor`, Object: v23)
+    v24 = spv.OpLoad(Pointer: v`prev_texel_hor`): f32×2
+    v25 = spv.OpLoad(Pointer: v4): f32×2
+    v26 = vec.distribute(f.mul)(v24, v25): f32×2
+    spv.OpStore(Pointer: v`prev_texel_hor_uv`, Object: v26)
+    v27 = spv.OpAccessChain(Base: v`curr_texel`, 0u32): T2
+    v28 = spv.OpLoad(Pointer: v27): f32
+    v29 = spv.OpAccessChain(Base: v`prev_texel_hor`, 0u32): T2
+    v30 = spv.OpLoad(Pointer: v29): f32
+    v31 = f.sub(v28, v30): f32
+    spv.OpStore(Pointer: v`prev_dist`, Object: v31)
+    v32 = spv.OpLoad(Pointer: v`prev_dist`): f32
+    v33 = f.add(1.0f32, v32): f32
+    v34 = spv.OpLoad(Pointer: v`prev_dist`): f32
+    v35 = spv.OpLoad(Pointer: v`prev_dist`): f32
+    v36 = f.sub(1.0f32, v35): f32
+    v37 = spv.OpLoad(Pointer: v`prev_dist`): f32
+    v38 = f.sub(2.0f32, v37): f32
+    v39 = vec.new(v33, v34, v36, v38): f32×4
+    spv.OpStore(Pointer: v`sample_dists`, Object: v39)
+    v40 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+    v41 = spv.OpLoad(Pointer: v40): f32
+    v42 = f.lt(v41, 0.5f32): bool
+  if v42 {
+    branch L0
+  } else {
+    branch L1
+  }
+
+  label L0:
+    v43 = spv.OpAccessChain(Base: v`sample_dists`, 1u32): T2
+    v44 = spv.OpLoad(Pointer: v43): f32
+    spv.OpStore(Pointer: v`x`, Object: v44)
+    v45 = spv.OpLoad(Pointer: v`x`): f32
+    v46 = spv.OpLoad(Pointer: v`x`): f32
+    v47 = f.mul(v45, v46): f32
+    v48 = spv.OpLoad(Pointer: v`x`): f32
+    v49 = f.mul(v47, v48): f32
+    v50 = spv.OpLoad(Pointer: v`x`): f32
+    v51 = spv.OpLoad(Pointer: v`x`): f32
+    v52 = f.mul(v51, 6.0f32): f32
+    v53 = f.sub(v52, 15.0f32): f32
+    v54 = f.mul(v50, v53): f32
+    v55 = f.add(v54, 10.0f32): f32
+    v56 = f.mul(v49, v55): f32
+    spv.OpStore(Pointer: v`w2`, Object: v56)
+    v57 = spv.OpLoad(Pointer: v`w2`): f32
+    v58 = f.sub(1.0f32, v57): f32
+    v59 = spv.OpLoad(Pointer: v`w2`): f32
+    v60 = vec.new(0.0f32, v58, v59, 0.0f32): f32×4
+    spv.OpStore(Pointer: v5, Object: v60)
+  branch L5
+
+  label L1:
+    v61 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+    v62 = spv.OpLoad(Pointer: v61): f32
+    v63 = f.lt(v62, 1.5f32): bool
+  if v63 {
+    branch L2
+  } else {
+    branch L3
+  }
+
+  label L2:
+    v64 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5
+    v65 = spv.OpLoad(Pointer: v64): f32
+    v66 = f.mul(2.0f32, v65): f32
+    v67 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5
+    v68 = spv.OpLoad(Pointer: v67): f32
+    v69 = f.mul(v66, v68): f32
+    v70 = f.div(1.0f32, v69): f32
+    spv.OpStore(Pointer: v`inner_denom_inv`, Object: v70)
+    v71 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+    v72 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+    v73 = vec.distribute(f.mul)(v71, v72): f32×4
+    v74 = vec.distribute(f.neg)(v73): f32×4
+    v75 = spv.OpLoad(Pointer: v`inner_denom_inv`): f32
+    v76 = vec.mul(v74, v75): f32×4
+    v77 = spv.extinst."GLSL.std.450".Exp(X: v76): f32×4
+    spv.OpStore(Pointer: v5, Object: v77)
+  branch L4
+
+  label L3:
+    v78 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+    v79 = spv.OpLoad(Pointer: &GV`pi`): f32
+    v80 = vec.mul(v78, v79): f32×4
+    v81 = spv.extinst."GLSL.std.450".FAbs(X: v80): f32×4
+    v82 = vec.new(1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32): f32×4
+    v83 = spv.extinst."GLSL.std.450".FMax(X: v81, Y: v82): f32×4
+    spv.OpStore(Pointer: v`pi_dists`, Object: v83)
+    v84 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+    v85 = spv.extinst."GLSL.std.450".Sin(X: v84): f32×4
+    v86 = vec.mul(v85, 2.0f32): f32×4
+    v87 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+    v88 = vec.mul(v87, 0.5f32): f32×4
+    v89 = spv.extinst."GLSL.std.450".Sin(X: v88): f32×4
+    v90 = vec.distribute(f.mul)(v86, v89): f32×4
+    v91 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+    v92 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+    v93 = vec.distribute(f.mul)(v91, v92): f32×4
+    v94 = vec.distribute(f.div)(v90, v93): f32×4
+    spv.OpStore(Pointer: v5, Object: v94)
+  branch L4
+
+  label L4:
+  branch L5
+
+  label L5:
+    v95 = spv.OpLoad(Pointer: v5): f32×4
+    v96 = spv.OpLoad(Pointer: v5): f32×4
+    v97 = vec.dot(v96, f32×4(1.0, 1.0, 1.0, 1.0)): f32
+    v98 = vec.new(v97, v97, v97, v97): f32×4
+    v99 = vec.distribute(f.div)(v95, v98): f32×4
+    spv.OpStore(Pointer: v`final_weights`, Object: v99)
+    v100 = spv.OpAccessChain(Base: v4, 0u32): T2
+    v101 = spv.OpLoad(Pointer: v100): f32
+    v102 = vec.new(v101, 0.0f32): f32×2
+    spv.OpStore(Pointer: v6, Object: v102)
+    v103 = spv.OpLoad(Pointer: v`prev_texel_hor_uv`): f32×2
+    spv.OpStore(Pointer: v7, Object: v103)
+    v104 = spv.OpLoad(Pointer: v6): f32×2
+    spv.OpStore(Pointer: v8, Object: v104)
+    v105 = spv.OpLoad(Pointer: v`final_weights`): f32×4
+    spv.OpStore(Pointer: v9, Object: v105)
+    v106 = call F`get_scanline_color(s21;vf2;vf2;vf4;`(v0, v1, v7, v8, v9): f32×3
+  return v106
+}
+
+func F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+  #[name = "tex_size"]
+  v3: T1,
+  #[name = "texture_size_inv"]
+  v4: T1,
+) -> f32×3 {
+    v`convergence_offsets_rgb` = spv.OpVariable(spv.StorageClass.Function): T0
+    v`offset_u_rgb` = spv.OpVariable(spv.StorageClass.Function): T0
+    v`scanline_uv_r` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`scanline_uv_g` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`scanline_uv_b` = spv.OpVariable(spv.StorageClass.Function): T1
+    v`sample_r` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v5 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v6 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v7 = spv.OpVariable(spv.StorageClass.Function): T1
+    v`sample_g` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v8 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v9 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v10 = spv.OpVariable(spv.StorageClass.Function): T1
+    v`sample_b` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v11 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v12 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v13 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v14 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v15 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v16 = spv.OpVariable(spv.StorageClass.Function): T1
+    v17 = spv.OpLoad(Pointer: &GV`beam_misconvergence`): bool
+  if v17 {
+    branch L0
+  } else {
+    branch L1
+  }
+
+  label L0:
+    v18 = call F`get_convergence_offsets_x_vector(`(): f32×3
+    spv.OpStore(Pointer: v`convergence_offsets_rgb`, Object: v18)
+    v19 = spv.OpLoad(Pointer: v`convergence_offsets_rgb`): f32×3
+    v20 = spv.OpLoad(Pointer: v4): f32×2
+    v21 = spv.OpVectorShuffle(Vector1: v20, Vector2: v20, 0, 0, 0): f32×3
+    v22 = vec.distribute(f.mul)(v19, v21): f32×3
+    spv.OpStore(Pointer: v`offset_u_rgb`, Object: v22)
+    v23 = spv.OpLoad(Pointer: v2): f32×2
+    v24 = spv.OpAccessChain(Base: v`offset_u_rgb`, 0u32): T2
+    v25 = spv.OpLoad(Pointer: v24): f32
+    v26 = vec.new(v25, 0.0f32): f32×2
+    v27 = vec.distribute(f.sub)(v23, v26): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_r`, Object: v27)
+    v28 = spv.OpLoad(Pointer: v2): f32×2
+    v29 = spv.OpAccessChain(Base: v`offset_u_rgb`, 1u32): T2
+    v30 = spv.OpLoad(Pointer: v29): f32
+    v31 = vec.new(v30, 0.0f32): f32×2
+    v32 = vec.distribute(f.sub)(v28, v31): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_g`, Object: v32)
+    v33 = spv.OpLoad(Pointer: v2): f32×2
+    v34 = spv.OpAccessChain(Base: v`offset_u_rgb`, 2u32): T2
+    v35 = spv.OpLoad(Pointer: v34): f32
+    v36 = vec.new(v35, 0.0f32): f32×2
+    v37 = vec.distribute(f.sub)(v33, v36): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_b`, Object: v37)
+    v38 = spv.OpLoad(Pointer: v`scanline_uv_r`): f32×2
+    spv.OpStore(Pointer: v5, Object: v38)
+    v39 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v6, Object: v39)
+    v40 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v7, Object: v40)
+    v41 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v5, v6, v7): f32×3
+    spv.OpStore(Pointer: v`sample_r`, Object: v41)
+    v42 = spv.OpLoad(Pointer: v`scanline_uv_g`): f32×2
+    spv.OpStore(Pointer: v8, Object: v42)
+    v43 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v9, Object: v43)
+    v44 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v10, Object: v44)
+    v45 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v8, v9, v10): f32×3
+    spv.OpStore(Pointer: v`sample_g`, Object: v45)
+    v46 = spv.OpLoad(Pointer: v`scanline_uv_b`): f32×2
+    spv.OpStore(Pointer: v11, Object: v46)
+    v47 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v12, Object: v47)
+    v48 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v13, Object: v48)
+    v49 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v11, v12, v13): f32×3
+    spv.OpStore(Pointer: v`sample_b`, Object: v49)
+    v50 = spv.OpAccessChain(Base: v`sample_r`, 0u32): T2
+    v51 = spv.OpLoad(Pointer: v50): f32
+    v52 = spv.OpAccessChain(Base: v`sample_g`, 1u32): T2
+    v53 = spv.OpLoad(Pointer: v52): f32
+    v54 = spv.OpAccessChain(Base: v`sample_b`, 2u32): T2
+    v55 = spv.OpLoad(Pointer: v54): f32
+    v56 = vec.new(v51, v53, v55): f32×3
+  return v56
+
+  label L1:
+    v57 = spv.OpLoad(Pointer: v2): f32×2
+    spv.OpStore(Pointer: v14, Object: v57)
+    v58 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v15, Object: v58)
+    v59 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v16, Object: v59)
+    v60 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v14, v15, v16): f32×3
+  return v60
+}
+
+#[spv.Decoration.Binding(BindingPoint: 6)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`VERTICAL_SCANLINES`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 6)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_VERTICAL_SCANLINES_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`get_mask_sample_mode(`() -> f32 {
+    v0 = spv.OpAccessChain(Base: &GV`global`, 24s32): T5
+    v1 = spv.OpLoad(Pointer: v0): f32
+  return v1
+}
+
+func F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(
+  #[name = "tile_uv_wrap"]
+  v0: T1,
+  #[name = "mask_tile_start_uv_and_size"]
+  v1: T3,
+) -> f32×2 {
+    v`tile_uv` = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "mask_tex_uv"]
+    v2 = spv.OpVariable(spv.StorageClass.Function): T1
+    v3 = call F`get_mask_sample_mode(`(): f32
+    v4 = f.lt(v3, 0.5f32): bool
+  if v4 {
+    branch L0
+  } else {
+    branch L1
+  }
+
+  label L0:
+    v5 = spv.OpLoad(Pointer: v0): f32×2
+    v6 = vec.mul(v5, 0.5f32): f32×2
+    v7 = spv.extinst."GLSL.std.450".Fract(X: v6): f32×2
+    v8 = vec.mul(v7, 2.0f32): f32×2
+    spv.OpStore(Pointer: v`tile_uv`, Object: v8)
+    v9 = spv.OpLoad(Pointer: v1): f32×4
+    v10 = spv.OpVectorShuffle(Vector1: v9, Vector2: v9, 0, 1): f32×2
+    v11 = spv.OpLoad(Pointer: v`tile_uv`): f32×2
+    v12 = spv.OpLoad(Pointer: v1): f32×4
+    v13 = spv.OpVectorShuffle(Vector1: v12, Vector2: v12, 2, 3): f32×2
+    v14 = vec.distribute(f.mul)(v11, v13): f32×2
+    v15 = vec.distribute(f.add)(v10, v14): f32×2
+    spv.OpStore(Pointer: v2, Object: v15)
+    v16 = spv.OpLoad(Pointer: v2): f32×2
+  return v16
+
+  label L1:
+    v17 = spv.OpLoad(Pointer: v0): f32×2
+  return v17
+}
+
+func F`get_pass_input_gamma(`() -> f32 {
+  return 1.0f32
+}
+
+func F`decode_input(vf4;`(
+  #[name = "color"]
+  v0: T3,
+) -> f32×4 {
+    v1 = spv.OpLoad(Pointer: &GV`linearize_input`): bool
+  if v1 {
+    branch L0
+  } else {
+    branch L3
+  }
+
+  label L0:
+    v2 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool
+  if v2 {
+    branch L1
+  } else {
+    branch L2
+  }
+
+  label L1:
+    v3 = spv.OpLoad(Pointer: v0): f32×4
+    v4 = spv.OpVectorShuffle(Vector1: v3, Vector2: v3, 0, 1, 2): f32×3
+    v5 = call F`get_pass_input_gamma(`(): f32
+    v6 = vec.new(v5, v5, v5): f32×3
+    v7 = spv.extinst."GLSL.std.450".Pow(X: v4, Y: v6): f32×3
+    v8 = vec.extract(v7, 0): f32
+    v9 = vec.extract(v7, 1): f32
+    v10 = vec.extract(v7, 2): f32
+    v11 = vec.new(v8, v9, v10, 1.0f32): f32×4
+  return v11
+
+  label L2:
+    v12 = spv.OpLoad(Pointer: v0): f32×4
+    v13 = spv.OpVectorShuffle(Vector1: v12, Vector2: v12, 0, 1, 2): f32×3
+    v14 = call F`get_pass_input_gamma(`(): f32
+    v15 = vec.new(v14, v14, v14): f32×3
+    v16 = spv.extinst."GLSL.std.450".Pow(X: v13, Y: v15): f32×3
+    v17 = spv.OpAccessChain(Base: v0, 3u32): T2
+    v18 = spv.OpLoad(Pointer: v17): f32
+    v19 = vec.extract(v16, 0): f32
+    v20 = vec.extract(v16, 1): f32
+    v21 = vec.extract(v16, 2): f32
+    v22 = vec.new(v19, v20, v21, v18): f32×4
+  return v22
+
+  label L3:
+    v23 = spv.OpLoad(Pointer: v0): f32×4
+  return v23
+}
+
+func F`tex2D_linearize(s21;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  v2: T9,
+  #[name = "tex_coords"]
+  v3: T1,
+) -> f32×4 {
+    #[name = "param"]
+    v4 = spv.OpVariable(spv.StorageClass.Function): T3
+    v5 = spv.OpLoad(Pointer: v0): T6
+    v6 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v7 = spv.OpSampledImage(Image: v5, Sampler: v6): T7
+    v8 = spv.OpLoad(Pointer: v2): spv.OpTypeSampler
+    v9 = spv.OpSampledImage(Image: v7, Sampler: v8): T7
+    v10 = spv.OpLoad(Pointer: v3): f32×2
+    v11 = spv.OpImageSampleImplicitLod(SampledImage: v9, Coordinate: v10): f32×4
+    spv.OpStore(Pointer: v4, Object: v11)
+    v12 = call F`decode_input(vf4;`(v4): f32×4
+  return v12
+}
+
+#[spv.Decoration.Binding(BindingPoint: 3)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_grille_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 3)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_grille_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 4)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_slot_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 4)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_slot_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 5)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_shadow_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 5)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_shadow_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`tex2Dtiled_mask_linearize(s21;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+) -> f32×4 {
+    #[name = "param"]
+    v3 = spv.OpVariable(spv.StorageClass.Function): T1
+    v4 = spv.OpLoad(Pointer: v2): f32×2
+    spv.OpStore(Pointer: v3, Object: v4)
+    v5 = call F`tex2D_linearize(s21;vf2;`(v0, v1, v3): f32×4
+  return v5
+}
+
+#[spv.Decoration.Binding(BindingPoint: 9)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`MASK_RESIZE`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 9)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_MASK_RESIZE_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 8)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`HALATION_BLUR`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 8)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_HALATION_BLUR_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`get_pass_output_gamma(`() -> f32 {
+  return 1.0f32
+}
+
+func F`encode_output(vf4;`(
+  #[name = "color"]
+  v0: T3,
+) -> f32×4 {
+    v1 = spv.OpLoad(Pointer: &GV`gamma_encode_output`): bool
+  if v1 {
+    branch L0
+  } else {
+    branch L3
+  }
+
+  label L0:
+    v2 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool
+  if v2 {
+    branch L1
+  } else {
+    branch L2
+  }
+
+  label L1:
+    v3 = spv.OpLoad(Pointer: v0): f32×4
+    v4 = spv.OpVectorShuffle(Vector1: v3, Vector2: v3, 0, 1, 2): f32×3
+    v5 = call F`get_pass_output_gamma(`(): f32
+    v6 = f.div(1.0f32, v5): f32
+    v7 = vec.new(v6, v6, v6): f32×3
+    v8 = spv.extinst."GLSL.std.450".Pow(X: v4, Y: v7): f32×3
+    v9 = vec.extract(v8, 0): f32
+    v10 = vec.extract(v8, 1): f32
+    v11 = vec.extract(v8, 2): f32
+    v12 = vec.new(v9, v10, v11, 1.0f32): f32×4
+  return v12
+
+  label L2:
+    v13 = spv.OpLoad(Pointer: v0): f32×4
+    v14 = spv.OpVectorShuffle(Vector1: v13, Vector2: v13, 0, 1, 2): f32×3
+    v15 = call F`get_pass_output_gamma(`(): f32
+    v16 = f.div(1.0f32, v15): f32
+    v17 = vec.new(v16, v16, v16): f32×3
+    v18 = spv.extinst."GLSL.std.450".Pow(X: v14, Y: v17): f32×3
+    v19 = spv.OpAccessChain(Base: v0, 3u32): T2
+    v20 = spv.OpLoad(Pointer: v19): f32
+    v21 = vec.extract(v18, 0): f32
+    v22 = vec.extract(v18, 1): f32
+    v23 = vec.extract(v18, 2): f32
+    v24 = vec.new(v21, v22, v23, v20): f32×4
+  return v24
+
+  label L3:
+    v25 = spv.OpLoad(Pointer: v0): f32×4
+  return v25
+}
+
+#[spv.ExecutionMode.OriginUpperLeft]
+func F`main`() {
+    v`scanline_color_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v0 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v1 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v2 = spv.OpVariable(spv.StorageClass.Function): T1
+    v`auto_dim_factor` = spv.OpVariable(spv.StorageClass.Function): T2
+    #[name = "tile_uv_wrap"]
+    v3 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "mask_tex_uv"]
+    v4 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v5 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v6 = spv.OpVariable(spv.StorageClass.Function): T3
+    v`sample_orig_luts` = spv.OpVariable(spv.StorageClass.Function): spv.OpTypePointer(spv.StorageClass.Function, bool)
+    v`phosphor_mask_sample` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v7 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v8 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v9 = spv.OpVariable(spv.StorageClass.Function): T1
+    #[name = "param"]
+    v10 = spv.OpVariable(spv.StorageClass.Function): T1
+    v`halation_color` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v11 = spv.OpVariable(spv.StorageClass.Function): T1
+    v`halation_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+    v`electron_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+    v`phosphor_emission_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+    v`pixel_color` = spv.OpVariable(spv.StorageClass.Function): T0
+    #[name = "param"]
+    v12 = spv.OpVariable(spv.StorageClass.Function): T3
+    v13 = spv.OpAccessChain(Base: &GV`params`, 2s32, 0u32): T4
+    v14 = spv.OpLoad(Pointer: v13): f32
+    v15 = spv.OpAccessChain(Base: &GV`params`, 0s32, 1u32): T4
+    v16 = spv.OpLoad(Pointer: v15): f32
+    v17 = f.div(v14, v16): f32
+    spv.OpStore(Pointer: &GV`bloom_approx_scale_x`, Object: v17)
+    spv.OpStore(Pointer: &GV`crt_gamma_static`, Object: 2.5f32)
+    spv.OpStore(Pointer: &GV`lcd_gamma_static`, Object: 2.2f32)
+    spv.OpStore(Pointer: &GV`levels_contrast_static`, Object: 1.0f32)
+    spv.OpStore(Pointer: &GV`levels_autodim_temp`, Object: 0.5f32)
+    spv.OpStore(Pointer: &GV`halation_weight_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`diffusion_weight_static`, Object: 0.075f32)
+    spv.OpStore(Pointer: &GV`bloom_underestimate_levels_static`, Object: 0.8f32)
+    spv.OpStore(Pointer: &GV`bloom_excess_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`bloom_approx_filter_static`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`beam_num_scanlines`, Object: 3.0f32)
+    spv.OpStore(Pointer: &GV`beam_generalized_gaussian`, Object: true)
+    spv.OpStore(Pointer: &GV`beam_antialias_level`, Object: 1.0f32)
+    spv.OpStore(Pointer: &GV`beam_min_sigma_static`, Object: 0.02f32)
+    spv.OpStore(Pointer: &GV`beam_max_sigma_static`, Object: 0.3f32)
+    spv.OpStore(Pointer: &GV`beam_spot_shape_function`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`beam_spot_power_static`, Object: 0.33333334f32)
+    spv.OpStore(Pointer: &GV`beam_min_shape_static`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`beam_max_shape_static`, Object: 4.0f32)
+    spv.OpStore(Pointer: &GV`beam_shape_power_static`, Object: 0.25f32)
+    spv.OpStore(Pointer: &GV`beam_horiz_filter_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`beam_horiz_sigma_static`, Object: 0.35f32)
+    spv.OpStore(Pointer: &GV`beam_horiz_linear_rgb_weight_static`, Object: 1.0f32)
+    spv.OpStore(Pointer: &GV`beam_misconvergence`, Object: true)
+    spv.OpStore(Pointer: &GV`convergence_offsets_r_static`, Object: f32×2(0.1, 0.2))
+    spv.OpStore(Pointer: &GV`convergence_offsets_g_static`, Object: f32×2(0.3, 0.4))
+    spv.OpStore(Pointer: &GV`convergence_offsets_b_static`, Object: f32×2(0.5, 0.6))
+    spv.OpStore(Pointer: &GV`interlace_detect_static`, Object: true)
+    spv.OpStore(Pointer: &GV`interlace_1080i_static`, Object: false)
+    spv.OpStore(Pointer: &GV`interlace_bff_static`, Object: false)
+    spv.OpStore(Pointer: &GV`aa_level`, Object: 12.0f32)
+    spv.OpStore(Pointer: &GV`aa_filter`, Object: 6.0f32)
+    spv.OpStore(Pointer: &GV`aa_temporal`, Object: false)
+    spv.OpStore(Pointer: &GV`aa_subpixel_r_offset_static`, Object: f32×2(-0.33333334, 0.0))
+    spv.OpStore(Pointer: &GV`aa_cubic_c_static`, Object: 0.5f32)
+    spv.OpStore(Pointer: &GV`aa_gauss_sigma_static`, Object: 0.5f32)
+    spv.OpStore(Pointer: &GV`mask_type_static`, Object: 1.0f32)
+    spv.OpStore(Pointer: &GV`mask_sample_mode_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`mask_specify_num_triads_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`mask_triad_size_desired_static`, Object: 3.0f32)
+    spv.OpStore(Pointer: &GV`mask_num_triads_desired_static`, Object: 480.0f32)
+    spv.OpStore(Pointer: &GV`mask_sinc_lobes`, Object: 3.0f32)
+    spv.OpStore(Pointer: &GV`mask_min_allowed_triad_size`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`geom_mode_static`, Object: 0.0f32)
+    spv.OpStore(Pointer: &GV`geom_radius_static`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`geom_view_dist_static`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`geom_tilt_angle_static`, Object: f32×2(0.0, 0.0))
+    spv.OpStore(Pointer: &GV`geom_aspect_ratio_static`, Object: 1.3130699f32)
+    spv.OpStore(Pointer: &GV`geom_overscan_static`, Object: f32×2(1.0, 1.0))
+    spv.OpStore(Pointer: &GV`geom_force_correct_tangent_matrix`, Object: true)
+    spv.OpStore(Pointer: &GV`border_size_static`, Object: 0.015f32)
+    spv.OpStore(Pointer: &GV`border_darkness_static`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`border_compress_static`, Object: 2.5f32)
+    spv.OpStore(Pointer: &GV`bloom_approx_size_x`, Object: 320.0f32)
+    spv.OpStore(Pointer: &GV`bloom_approx_size_x_for_fake`, Object: 400.0f32)
+    spv.OpStore(Pointer: &GV`mask_resize_viewport_scale`, Object: f32×2(0.0625, 0.0625))
+    spv.OpStore(Pointer: &GV`geom_max_aspect_ratio`, Object: 1.3333334f32)
+    spv.OpStore(Pointer: &GV`mask_texture_small_size`, Object: f32×2(64.0, 64.0))
+    spv.OpStore(Pointer: &GV`mask_texture_large_size`, Object: f32×2(512.0, 512.0))
+    spv.OpStore(Pointer: &GV`mask_triads_per_tile`, Object: 8.0f32)
+    spv.OpStore(Pointer: &GV`mask_grille14_avg_color`, Object: 0.19869281f32)
+    spv.OpStore(Pointer: &GV`mask_grille15_avg_color`, Object: 0.20784314f32)
+    spv.OpStore(Pointer: &GV`mask_slot_avg_color`, Object: 0.18039216f32)
+    spv.OpStore(Pointer: &GV`mask_shadow_avg_color`, Object: 0.16078432f32)
+    v18 = spv.OpLoad(Pointer: &GV`mask_grille15_avg_color`): f32
+    spv.OpStore(Pointer: &GV`mask_grille_avg_color`, Object: v18)
+    v19 = spv.OpLoad(Pointer: &GV`bloom_approx_filter_static`): f32
+    spv.OpStore(Pointer: &GV`bloom_approx_filter`, Object: v19)
+    v20 = spv.OpLoad(Pointer: &GV`mask_texture_small_size`): f32×2
+    spv.OpStore(Pointer: &GV`mask_resize_src_lut_size`, Object: v20)
+    spv.OpStore(Pointer: &GV`max_aa_base_pixel_border`, Object: 0.0f32)
+    v21 = spv.OpLoad(Pointer: &GV`max_aa_base_pixel_border`): f32
+    v22 = f.add(v21, 0.5f32): f32
+    spv.OpStore(Pointer: &GV`max_aniso_pixel_border`, Object: v22)
+    v23 = spv.OpLoad(Pointer: &GV`max_aniso_pixel_border`): f32
+    spv.OpStore(Pointer: &GV`max_tiled_pixel_border`, Object: v23)
+    v24 = spv.OpLoad(Pointer: &GV`max_tiled_pixel_border`): f32
+    v25 = spv.extinst."GLSL.std.450".Ceil(X: v24): f32
+    spv.OpStore(Pointer: &GV`max_mask_texel_border`, Object: v25)
+    v26 = spv.OpLoad(Pointer: &GV`max_mask_texel_border`): f32
+    v27 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32
+    v28 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+    v29 = f.mul(v27, v28): f32
+    v30 = f.div(v26, v29): f32
+    spv.OpStore(Pointer: &GV`max_mask_tile_border`, Object: v30)
+    spv.OpStore(Pointer: &GV`mask_resize_num_tiles`, Object: 2.0f32)
+    spv.OpStore(Pointer: &GV`mask_start_texels`, Object: 0.0f32)
+    v31 = spv.OpLoad(Pointer: &GV`mask_resize_num_tiles`): f32
+    v32 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+    v33 = f.mul(v31, v32): f32
+    spv.OpStore(Pointer: &GV`mask_resize_num_triads`, Object: v33)
+    v34 = spv.OpLoad(Pointer: &GV`mask_resize_num_triads`): f32
+    v35 = vec.new(v34, v34): f32×2
+    v36 = spv.OpLoad(Pointer: &GV`mask_resize_viewport_scale`): f32×2
+    v37 = vec.distribute(f.div)(v35, v36): f32×2
+    spv.OpStore(Pointer: &GV`min_allowed_viewport_triads`, Object: v37)
+    spv.OpStore(Pointer: &GV`pi`, Object: 3.1415927f32)
+    spv.OpStore(Pointer: &GV`under_half`, Object: 0.4995f32)
+    spv.OpStore(Pointer: &GV`gba_gamma`, Object: 3.5f32)
+    v38 = spv.OpAccessChain(Base: &GV`global`, 46s32): T5
+    v39 = spv.OpLoad(Pointer: v38): f32
+    v40 = f.ne_or_unord(v39, 0.0f32): bool
+    spv.OpStore(Pointer: &GV`interlace_detect`, Object: v40)
+    spv.OpStore(Pointer: &GV`ntsc_gamma`, Object: 2.2f32)
+    spv.OpStore(Pointer: &GV`pal_gamma`, Object: 2.8f32)
+    spv.OpStore(Pointer: &GV`crt_reference_gamma_high`, Object: 2.5f32)
+    spv.OpStore(Pointer: &GV`crt_reference_gamma_low`, Object: 2.35f32)
+    spv.OpStore(Pointer: &GV`lcd_reference_gamma`, Object: 2.5f32)
+    spv.OpStore(Pointer: &GV`crt_office_gamma`, Object: 2.2f32)
+    spv.OpStore(Pointer: &GV`lcd_office_gamma`, Object: 2.2f32)
+    spv.OpStore(Pointer: &GV`assume_opaque_alpha`, Object: false)
+    spv.OpStore(Pointer: &GV`linearize_input`, Object: false)
+    spv.OpStore(Pointer: &GV`gamma_encode_output`, Object: false)
+    v41 = spv.OpLoad(Pointer: &GV`linearize_input`): bool
+    v42 = bool.not(v41): bool
+    spv.OpStore(Pointer: &GV`gamma_aware_bilinear`, Object: v42)
+    v43 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32
+    v44 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+    v45 = f.mul(v43, v44): f32
+    v46 = spv.extinst."GLSL.std.450".Ceil(X: v45): f32
+    spv.OpStore(Pointer: &GV`mask_min_allowed_tile_size`, Object: v46)
+    v47 = spv.OpLoad(Pointer: &GV`mask_min_allowed_tile_size`): f32
+    spv.OpStore(Pointer: &GV`mask_min_expected_tile_size`, Object: v47)
+    v48 = spv.OpLoad(Pointer: &GV`pi`): f32
+    v49 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32
+    v50 = f.div(v48, v49): f32
+    spv.OpStore(Pointer: &GV`pi_over_lobes`, Object: v50)
+    v51 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32
+    v52 = f.mul(2.0f32, v51): f32
+    v53 = spv.OpAccessChain(Base: &GV`mask_resize_src_lut_size`, 0u32): spv.OpTypePointer(spv.StorageClass.Private, f32)
+    v54 = spv.OpLoad(Pointer: v53): f32
+    v55 = f.mul(v52, v54): f32
+    v56 = spv.OpLoad(Pointer: &GV`mask_min_expected_tile_size`): f32
+    v57 = f.div(v55, v56): f32
+    spv.OpStore(Pointer: &GV`max_sinc_resize_samples_float`, Object: v57)
+    v58 = spv.OpLoad(Pointer: &GV`max_sinc_resize_samples_float`): f32
+    v59 = f.mul(v58, 0.25f32): f32
+    v60 = spv.extinst."GLSL.std.450".Ceil(X: v59): f32
+    v61 = f.mul(v60, 4.0f32): f32
+    spv.OpStore(Pointer: &GV`max_sinc_resize_samples_m4`, Object: v61)
+    spv.OpStore(Pointer: &GV`blur3_std_dev`, Object: 0.62666017f32)
+    spv.OpStore(Pointer: &GV`blur4_std_dev`, Object: 0.6617187f32)
+    spv.OpStore(Pointer: &GV`blur5_std_dev`, Object: 0.9845703f32)
+    spv.OpStore(Pointer: &GV`blur6_std_dev`, Object: 1.0262696f32)
+    spv.OpStore(Pointer: &GV`blur7_std_dev`, Object: 1.3610351f32)
+    spv.OpStore(Pointer: &GV`blur8_std_dev`, Object: 1.4080079f32)
+    spv.OpStore(Pointer: &GV`blur9_std_dev`, Object: 1.7533203f32)
+    spv.OpStore(Pointer: &GV`blur10_std_dev`, Object: 1.8047851f32)
+    spv.OpStore(Pointer: &GV`blur11_std_dev`, Object: 2.1598632f32)
+    spv.OpStore(Pointer: &GV`blur12_std_dev`, Object: 2.2152343f32)
+    spv.OpStore(Pointer: &GV`blur17_std_dev`, Object: 3.455356f32)
+    spv.OpStore(Pointer: &GV`blur25_std_dev`, Object: 5.3409576f32)
+    spv.OpStore(Pointer: &GV`blur31_std_dev`, Object: 6.8648806f32)
+    spv.OpStore(Pointer: &GV`blur43_std_dev`, Object: 10.185205f32)
+    spv.OpStore(Pointer: &GV`error_blurring`, Object: 0.5f32)
+    spv.OpStore(Pointer: &GV`bloom_diff_thresh`, Object: 0.00390625f32)
+    v62 = spv.OpLoad(Pointer: &GV`scanline_tex_uv`): f32×2
+    spv.OpStore(Pointer: v0, Object: v62)
+    v63 = spv.OpAccessChain(Base: &GV`params`, 3s32): spv.OpTypePointer(spv.StorageClass.PushConstant, f32×4)
+    v64 = spv.OpLoad(Pointer: v63): f32×4
+    v65 = spv.OpVectorShuffle(Vector1: v64, Vector2: v64, 0, 1): f32×2
+    spv.OpStore(Pointer: v1, Object: v65)
+    v66 = spv.OpLoad(Pointer: &GV`scanline_texture_size_inv`): f32×2
+    spv.OpStore(Pointer: v2, Object: v66)
+    v67 = call F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(&GV`VERTICAL_SCANLINES`, &GV`_VERTICAL_SCANLINES_sampler`, v0, v1, v2):
+      f32×3
+    spv.OpStore(Pointer: v`scanline_color_dim`, Object: v67)
+    v68 = spv.OpLoad(Pointer: &GV`levels_autodim_temp`): f32
+    spv.OpStore(Pointer: v`auto_dim_factor`, Object: v68)
+    v69 = spv.OpLoad(Pointer: &GV`video_uv`): f32×2
+    v70 = spv.OpLoad(Pointer: &GV`mask_tiles_per_screen`): f32×2
+    v71 = vec.distribute(f.mul)(v69, v70): f32×2
+    spv.OpStore(Pointer: v3, Object: v71)
+    v72 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v5, Object: v72)
+    v73 = spv.OpLoad(Pointer: &GV0): f32×4
+    spv.OpStore(Pointer: v6, Object: v73)
+    v74 = call F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(v5, v6): f32×2
+    spv.OpStore(Pointer: v4, Object: v74)
+    v75 = call F`get_mask_sample_mode(`(): f32
+    v76 = f.gt(v75, 0.5f32): bool
+    spv.OpStore(Pointer: v`sample_orig_luts`, Object: v76)
+    v77 = spv.OpLoad(Pointer: v`sample_orig_luts`): bool
+  if v77 {
+    branch L0
+  } else {
+    branch L7
+  }
+
+  label L0:
+    v78 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5
+    v79 = spv.OpLoad(Pointer: v78): f32
+    v80 = f.lt(v79, 0.5f32): bool
+  if v80 {
+    branch L1
+  } else {
+    branch L2
+  }
+
+  label L1:
+    v81 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v7, Object: v81)
+    v82 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_grille_texture_large`, &GV`_mask_grille_texture_large_sampler`, v7): f32×4
+    v83 = spv.OpVectorShuffle(Vector1: v82, Vector2: v82, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v83)
+  branch L6
+
+  label L2:
+    v84 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5
+    v85 = spv.OpLoad(Pointer: v84): f32
+    v86 = f.lt(v85, 1.5f32): bool
+  if v86 {
+    branch L3
+  } else {
+    branch L4
+  }
+
+  label L3:
+    v87 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v8, Object: v87)
+    v88 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_slot_texture_large`, &GV`_mask_slot_texture_large_sampler`, v8): f32×4
+    v89 = spv.OpVectorShuffle(Vector1: v88, Vector2: v88, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v89)
+  branch L5
+
+  label L4:
+    v90 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v9, Object: v90)
+    v91 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_shadow_texture_large`, &GV`_mask_shadow_texture_large_sampler`, v9): f32×4
+    v92 = spv.OpVectorShuffle(Vector1: v91, Vector2: v91, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v92)
+  branch L5
+
+  label L5:
+  branch L6
+
+  label L6:
+  branch L8
+
+  label L7:
+    v93 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v10, Object: v93)
+    v94 = call F`tex2Dtiled_mask_linearize(s21;vf2;`(&GV`MASK_RESIZE`, &GV`_MASK_RESIZE_sampler`, v10): f32×4
+    v95 = spv.OpVectorShuffle(Vector1: v94, Vector2: v94, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v95)
+  branch L8
+
+  label L8:
+    v96 = spv.OpLoad(Pointer: &GV`halation_tex_uv`): f32×2
+    spv.OpStore(Pointer: v11, Object: v96)
+    v97 = call F`tex2D_linearize(s21;vf2;`(&GV`HALATION_BLUR`, &GV`_HALATION_BLUR_sampler`, v11): f32×4
+    v98 = spv.OpVectorShuffle(Vector1: v97, Vector2: v97, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`halation_color`, Object: v98)
+    v99 = spv.OpLoad(Pointer: v`halation_color`): f32×3
+    v100 = spv.OpLoad(Pointer: v`auto_dim_factor`): f32
+    v101 = f.div(v100, 3.0f32): f32
+    v102 = vec.new(v101, v101, v101): f32×3
+    v103 = vec.dot(v99, v102): f32
+    v104 = vec.new(v103, v103, v103): f32×3
+    spv.OpStore(Pointer: v`halation_intensity_dim`, Object: v104)
+    v105 = spv.OpLoad(Pointer: v`scanline_color_dim`): f32×3
+    v106 = spv.OpLoad(Pointer: v`halation_intensity_dim`): f32×3
+    v107 = spv.OpAccessChain(Base: &GV`global`, 4s32): T5
+    v108 = spv.OpLoad(Pointer: v107): f32
+    v109 = vec.new(v108, v108, v108): f32×3
+    v110 = spv.extinst."GLSL.std.450".FMix(X: v105, Y: v106, A: v109): f32×3
+    spv.OpStore(Pointer: v`electron_intensity_dim`, Object: v110)
+    v111 = spv.OpLoad(Pointer: v`electron_intensity_dim`): f32×3
+    v112 = spv.OpLoad(Pointer: v`phosphor_mask_sample`): f32×3
+    v113 = vec.distribute(f.mul)(v111, v112): f32×3
+    spv.OpStore(Pointer: v`phosphor_emission_dim`, Object: v113)
+    v114 = spv.OpLoad(Pointer: v`phosphor_emission_dim`): f32×3
+    spv.OpStore(Pointer: v`pixel_color`, Object: v114)
+    v115 = spv.OpLoad(Pointer: v`pixel_color`): f32×3
+    v116 = vec.extract(v115, 0): f32
+    v117 = vec.extract(v115, 1): f32
+    v118 = vec.extract(v115, 2): f32
+    v119 = vec.new(v116, v117, v118, 1.0f32): f32×4
+    spv.OpStore(Pointer: v12, Object: v119)
+    v120 = call F`encode_output(vf4;`(v12): f32×4
+    spv.OpStore(Pointer: &GV`FragColor`, Object: v120)
+  return
+}
+
+export {
+  spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F`main`,
+}
+ diff --git a/librashader-reflect/out.spv b/librashader-reflect/out.spv new file mode 100644 index 0000000..90efc17 Binary files /dev/null and b/librashader-reflect/out.spv differ diff --git a/librashader-reflect/out.structured.spirt b/librashader-reflect/out.structured.spirt new file mode 100644 index 0000000..7cf176c --- /dev/null +++ b/librashader-reflect/out.structured.spirt @@ -0,0 +1,1461 @@ +module.dialect = spv.Module(version: 1.0, spv.Capability.Shader, spv.MemoryModel.GLSL450) + +module.debug_info = spv.Module.DebugInfo( + generator: spv.Tool(id: 15), + source_languages: { + spv.SourceLanguage.GLSL(version: 450): {}, + }, + source_extensions: ["GL_GOOGLE_cpp_style_line_directive", "GL_GOOGLE_include_directive"], +) + +type T0 = spv.OpTypePointer(spv.StorageClass.Function, f32×3) + +type T1 = spv.OpTypePointer(spv.StorageClass.Function, f32×2) + +type T2 = spv.OpTypePointer(spv.StorageClass.Function, f32) + +type T3 = spv.OpTypePointer(spv.StorageClass.Function, f32×4) + +type T4 = spv.OpTypePointer(spv.StorageClass.PushConstant, f32) + +#[spv.OpMemberName(Member: 0, Name: "SourceSize")] +#[spv.OpMemberName(Member: 1, Name: "OriginalSize")] +#[spv.OpMemberName(Member: 2, Name: "OutputSize")] +#[spv.OpMemberName(Member: 3, Name: "VERTICAL_SCANLINESSize")] +#[spv.OpMemberName(Member: 4, Name: "BLOOM_APPROXSize")] +#[spv.OpMemberName(Member: 5, Name: "HALATION_BLURSize")] +#[spv.OpMemberName(Member: 6, Name: "MASK_RESIZESize")] +#[spv.Decoration.Block] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))] +#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 16))] +#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 32))] +#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 48))] +#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 64))] +#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))] +#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 96))] +type T`Push` = spv.OpTypeStruct(f32×4, f32×4, f32×4, f32×4, f32×4, f32×4, f32×4) + +type T5 = spv.OpTypePointer(spv.StorageClass.Uniform, f32) + +#[spv.OpMemberName(Member: 0, Name: "MVP")] +#[spv.OpMemberName(Member: 1, Name: "crt_gamma")] +#[spv.OpMemberName(Member: 2, Name: "lcd_gamma")] +#[spv.OpMemberName(Member: 3, Name: "levels_contrast")] +#[spv.OpMemberName(Member: 4, Name: "halation_weight")] +#[spv.OpMemberName(Member: 5, Name: "diffusion_weight")] +#[spv.OpMemberName(Member: 6, Name: "bloom_underestimate_levels")] +#[spv.OpMemberName(Member: 7, Name: "bloom_excess")] +#[spv.OpMemberName(Member: 8, Name: "beam_min_sigma")] +#[spv.OpMemberName(Member: 9, Name: "beam_max_sigma")] +#[spv.OpMemberName(Member: 10, Name: "beam_spot_power")] +#[spv.OpMemberName(Member: 11, Name: "beam_min_shape")] +#[spv.OpMemberName(Member: 12, Name: "beam_max_shape")] +#[spv.OpMemberName(Member: 13, Name: "beam_shape_power")] +#[spv.OpMemberName(Member: 14, Name: "beam_horiz_filter")] +#[spv.OpMemberName(Member: 15, Name: "beam_horiz_sigma")] +#[spv.OpMemberName(Member: 16, Name: "beam_horiz_linear_rgb_weight")] +#[spv.OpMemberName(Member: 17, Name: "convergence_offset_x_r")] +#[spv.OpMemberName(Member: 18, Name: "convergence_offset_x_g")] +#[spv.OpMemberName(Member: 19, Name: "convergence_offset_x_b")] +#[spv.OpMemberName(Member: 20, Name: "convergence_offset_y_r")] +#[spv.OpMemberName(Member: 21, Name: "convergence_offset_y_g")] +#[spv.OpMemberName(Member: 22, Name: "convergence_offset_y_b")] +#[spv.OpMemberName(Member: 23, Name: "mask_type")] +#[spv.OpMemberName(Member: 24, Name: "mask_sample_mode_desired")] +#[spv.OpMemberName(Member: 25, Name: "mask_num_triads_desired")] +#[spv.OpMemberName(Member: 26, Name: "mask_triad_size_desired")] +#[spv.OpMemberName(Member: 27, Name: "mask_specify_num_triads")] +#[spv.OpMemberName(Member: 28, Name: "aa_subpixel_r_offset_x_runtime")] +#[spv.OpMemberName(Member: 29, Name: "aa_subpixel_r_offset_y_runtime")] +#[spv.OpMemberName(Member: 30, Name: "aa_cubic_c")] +#[spv.OpMemberName(Member: 31, Name: "aa_gauss_sigma")] +#[spv.OpMemberName(Member: 32, Name: "geom_mode_runtime")] +#[spv.OpMemberName(Member: 33, Name: "geom_radius")] +#[spv.OpMemberName(Member: 34, Name: "geom_view_dist")] +#[spv.OpMemberName(Member: 35, Name: "geom_tilt_angle_x")] +#[spv.OpMemberName(Member: 36, Name: "geom_tilt_angle_y")] +#[spv.OpMemberName(Member: 37, Name: "geom_aspect_ratio_x")] +#[spv.OpMemberName(Member: 38, Name: "geom_aspect_ratio_y")] +#[spv.OpMemberName(Member: 39, Name: "geom_overscan_x")] +#[spv.OpMemberName(Member: 40, Name: "geom_overscan_y")] +#[spv.OpMemberName(Member: 41, Name: "border_size")] +#[spv.OpMemberName(Member: 42, Name: "border_darkness")] +#[spv.OpMemberName(Member: 43, Name: "border_compress")] +#[spv.OpMemberName(Member: 44, Name: "interlace_bff")] +#[spv.OpMemberName(Member: 45, Name: "interlace_1080i")] +#[spv.OpMemberName(Member: 46, Name: "interlace_detect_toggle")] +#[spv.Decoration.Block] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.ColMajor)] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.MatrixStride(MatrixStride: 16))] +#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))] +#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 64))] +#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 68))] +#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 72))] +#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 76))] +#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))] +#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 84))] +#[spv.OpMemberDecorate(Member: 7, spv.Decoration.Offset(ByteOffset: 88))] +#[spv.OpMemberDecorate(Member: 8, spv.Decoration.Offset(ByteOffset: 92))] +#[spv.OpMemberDecorate(Member: 9, spv.Decoration.Offset(ByteOffset: 96))] +#[spv.OpMemberDecorate(Member: 10, spv.Decoration.Offset(ByteOffset: 100))] +#[spv.OpMemberDecorate(Member: 11, spv.Decoration.Offset(ByteOffset: 104))] +#[spv.OpMemberDecorate(Member: 12, spv.Decoration.Offset(ByteOffset: 108))] +#[spv.OpMemberDecorate(Member: 13, spv.Decoration.Offset(ByteOffset: 112))] +#[spv.OpMemberDecorate(Member: 14, spv.Decoration.Offset(ByteOffset: 116))] +#[spv.OpMemberDecorate(Member: 15, spv.Decoration.Offset(ByteOffset: 120))] +#[spv.OpMemberDecorate(Member: 16, spv.Decoration.Offset(ByteOffset: 124))] +#[spv.OpMemberDecorate(Member: 17, spv.Decoration.Offset(ByteOffset: 128))] +#[spv.OpMemberDecorate(Member: 18, spv.Decoration.Offset(ByteOffset: 132))] +#[spv.OpMemberDecorate(Member: 19, spv.Decoration.Offset(ByteOffset: 136))] +#[spv.OpMemberDecorate(Member: 20, spv.Decoration.Offset(ByteOffset: 140))] +#[spv.OpMemberDecorate(Member: 21, spv.Decoration.Offset(ByteOffset: 144))] +#[spv.OpMemberDecorate(Member: 22, spv.Decoration.Offset(ByteOffset: 148))] +#[spv.OpMemberDecorate(Member: 23, spv.Decoration.Offset(ByteOffset: 152))] +#[spv.OpMemberDecorate(Member: 24, spv.Decoration.Offset(ByteOffset: 156))] +#[spv.OpMemberDecorate(Member: 25, spv.Decoration.Offset(ByteOffset: 160))] +#[spv.OpMemberDecorate(Member: 26, spv.Decoration.Offset(ByteOffset: 164))] +#[spv.OpMemberDecorate(Member: 27, spv.Decoration.Offset(ByteOffset: 168))] +#[spv.OpMemberDecorate(Member: 28, spv.Decoration.Offset(ByteOffset: 172))] +#[spv.OpMemberDecorate(Member: 29, spv.Decoration.Offset(ByteOffset: 176))] +#[spv.OpMemberDecorate(Member: 30, spv.Decoration.Offset(ByteOffset: 180))] +#[spv.OpMemberDecorate(Member: 31, spv.Decoration.Offset(ByteOffset: 184))] +#[spv.OpMemberDecorate(Member: 32, spv.Decoration.Offset(ByteOffset: 188))] +#[spv.OpMemberDecorate(Member: 33, spv.Decoration.Offset(ByteOffset: 192))] +#[spv.OpMemberDecorate(Member: 34, spv.Decoration.Offset(ByteOffset: 196))] +#[spv.OpMemberDecorate(Member: 35, spv.Decoration.Offset(ByteOffset: 200))] +#[spv.OpMemberDecorate(Member: 36, spv.Decoration.Offset(ByteOffset: 204))] +#[spv.OpMemberDecorate(Member: 37, spv.Decoration.Offset(ByteOffset: 208))] +#[spv.OpMemberDecorate(Member: 38, spv.Decoration.Offset(ByteOffset: 212))] +#[spv.OpMemberDecorate(Member: 39, spv.Decoration.Offset(ByteOffset: 216))] +#[spv.OpMemberDecorate(Member: 40, spv.Decoration.Offset(ByteOffset: 220))] +#[spv.OpMemberDecorate(Member: 41, spv.Decoration.Offset(ByteOffset: 224))] +#[spv.OpMemberDecorate(Member: 42, spv.Decoration.Offset(ByteOffset: 228))] +#[spv.OpMemberDecorate(Member: 43, spv.Decoration.Offset(ByteOffset: 232))] +#[spv.OpMemberDecorate(Member: 44, spv.Decoration.Offset(ByteOffset: 236))] +#[spv.OpMemberDecorate(Member: 45, spv.Decoration.Offset(ByteOffset: 240))] +#[spv.OpMemberDecorate(Member: 46, spv.Decoration.Offset(ByteOffset: 244))] +type T`UBO` = spv.OpTypeStruct( + spv.OpTypeMatrix(ColumnType: f32×4, ColumnCount: 4), + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, + f32, +) + +type T6 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown) + +type T7 = spv.OpTypeSampledImage(ImageType: T6) + +type T8 = spv.OpTypePointer(spv.StorageClass.UniformConstant, T7) + +type T9 = spv.OpTypePointer(spv.StorageClass.UniformConstant, spv.OpTypeSampler) + +#[spv.Decoration.Location(Location: 1)] +global_var GV`scanline_tex_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 4)] +global_var GV`scanline_texture_size_inv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 0)] +global_var GV`video_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 6)] +global_var GV`mask_tiles_per_screen`(spv.StorageClass.Input): f32×2 + +#[name = "mask_tile_start_uv_and_size"] +#[spv.Decoration.Location(Location: 5)] +global_var GV0(spv.StorageClass.Input): f32×4 + +#[spv.Decoration.Location(Location: 3)] +global_var GV`halation_tex_uv`(spv.StorageClass.Input): f32×2 + +#[spv.Decoration.Location(Location: 0)] +global_var GV`FragColor`(spv.StorageClass.Output): f32×4 + +#[spv.Decoration.Location(Location: 2)] +global_var GV`blur3x3_tex_uv`(spv.StorageClass.Input): f32×2 + +global_var GV`params`(spv.StorageClass.PushConstant): T`Push` + +global_var GV`bloom_approx_scale_x`(spv.StorageClass.Private): f32 + +global_var GV`crt_gamma_static`(spv.StorageClass.Private): f32 + +global_var GV`lcd_gamma_static`(spv.StorageClass.Private): f32 + +global_var GV`levels_contrast_static`(spv.StorageClass.Private): f32 + +global_var GV`levels_autodim_temp`(spv.StorageClass.Private): f32 + +global_var GV`halation_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`diffusion_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_underestimate_levels_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_excess_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_filter_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_num_scanlines`(spv.StorageClass.Private): f32 + +global_var GV`beam_generalized_gaussian`(spv.StorageClass.Private): bool + +global_var GV`beam_antialias_level`(spv.StorageClass.Private): f32 + +global_var GV`beam_min_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_max_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_spot_shape_function`(spv.StorageClass.Private): f32 + +global_var GV`beam_spot_power_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_min_shape_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_max_shape_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_shape_power_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_filter_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_horiz_linear_rgb_weight_static`(spv.StorageClass.Private): f32 + +global_var GV`beam_misconvergence`(spv.StorageClass.Private): bool + +global_var GV`convergence_offsets_r_static`(spv.StorageClass.Private): f32×2 + +global_var GV`convergence_offsets_g_static`(spv.StorageClass.Private): f32×2 + +global_var GV`convergence_offsets_b_static`(spv.StorageClass.Private): f32×2 + +global_var GV`interlace_detect_static`(spv.StorageClass.Private): bool + +global_var GV`interlace_1080i_static`(spv.StorageClass.Private): bool + +global_var GV`interlace_bff_static`(spv.StorageClass.Private): bool + +global_var GV`aa_level`(spv.StorageClass.Private): f32 + +global_var GV`aa_filter`(spv.StorageClass.Private): f32 + +global_var GV`aa_temporal`(spv.StorageClass.Private): bool + +global_var GV`aa_subpixel_r_offset_static`(spv.StorageClass.Private): f32×2 + +global_var GV`aa_cubic_c_static`(spv.StorageClass.Private): f32 + +global_var GV`aa_gauss_sigma_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_type_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_sample_mode_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_specify_num_triads_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_triad_size_desired_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_num_triads_desired_static`(spv.StorageClass.Private): f32 + +global_var GV`mask_sinc_lobes`(spv.StorageClass.Private): f32 + +global_var GV`mask_min_allowed_triad_size`(spv.StorageClass.Private): f32 + +global_var GV`geom_mode_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_radius_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_view_dist_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_tilt_angle_static`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_aspect_ratio_static`(spv.StorageClass.Private): f32 + +global_var GV`geom_overscan_static`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_force_correct_tangent_matrix`(spv.StorageClass.Private): bool + +global_var GV`border_size_static`(spv.StorageClass.Private): f32 + +global_var GV`border_darkness_static`(spv.StorageClass.Private): f32 + +global_var GV`border_compress_static`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_size_x`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_size_x_for_fake`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_viewport_scale`(spv.StorageClass.Private): f32×2 + +global_var GV`geom_max_aspect_ratio`(spv.StorageClass.Private): f32 + +global_var GV`mask_texture_small_size`(spv.StorageClass.Private): f32×2 + +global_var GV`mask_texture_large_size`(spv.StorageClass.Private): f32×2 + +global_var GV`mask_triads_per_tile`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille14_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille15_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_slot_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_shadow_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`mask_grille_avg_color`(spv.StorageClass.Private): f32 + +global_var GV`bloom_approx_filter`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_src_lut_size`(spv.StorageClass.Private): f32×2 + +global_var GV`max_aa_base_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_aniso_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_tiled_pixel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_mask_texel_border`(spv.StorageClass.Private): f32 + +global_var GV`max_mask_tile_border`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_num_tiles`(spv.StorageClass.Private): f32 + +global_var GV`mask_start_texels`(spv.StorageClass.Private): f32 + +global_var GV`mask_resize_num_triads`(spv.StorageClass.Private): f32 + +global_var GV`min_allowed_viewport_triads`(spv.StorageClass.Private): f32×2 + +global_var GV`pi`(spv.StorageClass.Private): f32 + +global_var GV`under_half`(spv.StorageClass.Private): f32 + +global_var GV`gba_gamma`(spv.StorageClass.Private): f32 + +#[spv.Decoration.Binding(BindingPoint: 0)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`global`(spv.StorageClass.Uniform): T`UBO` + +global_var GV`interlace_detect`(spv.StorageClass.Private): bool + +global_var GV`ntsc_gamma`(spv.StorageClass.Private): f32 + +global_var GV`pal_gamma`(spv.StorageClass.Private): f32 + +global_var GV`crt_reference_gamma_high`(spv.StorageClass.Private): f32 + +global_var GV`crt_reference_gamma_low`(spv.StorageClass.Private): f32 + +global_var GV`lcd_reference_gamma`(spv.StorageClass.Private): f32 + +global_var GV`crt_office_gamma`(spv.StorageClass.Private): f32 + +global_var GV`lcd_office_gamma`(spv.StorageClass.Private): f32 + +global_var GV`assume_opaque_alpha`(spv.StorageClass.Private): bool + +global_var GV`linearize_input`(spv.StorageClass.Private): bool + +global_var GV`gamma_encode_output`(spv.StorageClass.Private): bool + +global_var GV`gamma_aware_bilinear`(spv.StorageClass.Private): bool + +global_var GV`mask_min_allowed_tile_size`(spv.StorageClass.Private): f32 + +global_var GV`mask_min_expected_tile_size`(spv.StorageClass.Private): f32 + +global_var GV`pi_over_lobes`(spv.StorageClass.Private): f32 + +global_var GV`max_sinc_resize_samples_float`(spv.StorageClass.Private): f32 + +global_var GV`max_sinc_resize_samples_m4`(spv.StorageClass.Private): f32 + +global_var GV`blur3_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur4_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur5_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur6_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur7_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur8_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur9_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur10_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur11_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur12_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur17_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur25_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur31_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`blur43_std_dev`(spv.StorageClass.Private): f32 + +global_var GV`error_blurring`(spv.StorageClass.Private): f32 + +global_var GV`bloom_diff_thresh`(spv.StorageClass.Private): f32 + +func F`get_convergence_offsets_x_vector(`() -> f32×3 { + v0 = spv.OpAccessChain(Base: &GV`global`, 17s32): T5 + v1 = spv.OpLoad(Pointer: v0): f32 + v2 = spv.OpAccessChain(Base: &GV`global`, 18s32): T5 + v3 = spv.OpLoad(Pointer: v2): f32 + v4 = spv.OpAccessChain(Base: &GV`global`, 19s32): T5 + v5 = spv.OpLoad(Pointer: v4): f32 + v6 = vec.new(v1, v3, v5): f32×3 + v6 +} + +func F`get_intermediate_gamma(`() -> f32 { + v0 = spv.OpLoad(Pointer: &GV`ntsc_gamma`): f32 + v0 +} + +func F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`( + #[name = "color0"] + v0: T0, + #[name = "color1"] + v1: T0, + #[name = "color2"] + v2: T0, + #[name = "color3"] + v3: T0, + #[name = "weights"] + v4: T3, +) -> f32×3 { + v5 = spv.OpLoad(Pointer: v0): f32×3 + v6 = spv.OpLoad(Pointer: v1): f32×3 + v7 = spv.OpLoad(Pointer: v2): f32×3 + v8 = spv.OpLoad(Pointer: v3): f32×3 + v9 = vec.extract(v5, 0): f32 + v10 = vec.extract(v5, 1): f32 + v11 = vec.extract(v5, 2): f32 + v12 = vec.extract(v6, 0): f32 + v13 = vec.extract(v6, 1): f32 + v14 = vec.extract(v6, 2): f32 + v15 = vec.extract(v7, 0): f32 + v16 = vec.extract(v7, 1): f32 + v17 = vec.extract(v7, 2): f32 + v18 = vec.extract(v8, 0): f32 + v19 = vec.extract(v8, 1): f32 + v20 = vec.extract(v8, 2): f32 + v21 = vec.new(v9, v10, v11): f32×3 + v22 = vec.new(v12, v13, v14): f32×3 + v23 = vec.new(v15, v16, v17): f32×3 + v24 = vec.new(v18, v19, v20): f32×3 + v25 = vec.new(v21, v22, v23, v24): spv.OpTypeMatrix(ColumnType: f32×3, ColumnCount: 4) + v26 = spv.OpLoad(Pointer: v4): f32×4 + v27 = spv.OpMatrixTimesVector(Matrix: v25, Vector: v26): f32×3 + v28 = vec.new(0.0f32, 0.0f32, 0.0f32): f32×3 + v29 = spv.extinst."GLSL.std.450".FMax(X: v27, Y: v28): f32×3 + v29 +} + +func F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`( + #[name = "color0"] + v0: T0, + #[name = "color1"] + v1: T0, + #[name = "color2"] + v2: T0, + #[name = "color3"] + v3: T0, + #[name = "weights"] + v4: T3, +) -> f32×3 { + v`intermediate_gamma` = spv.OpVariable(spv.StorageClass.Function): T2 + v`linear_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T3 + v`gamma_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v14 = spv.OpVariable(spv.StorageClass.Function): T3 + v15 = call F`get_intermediate_gamma(`(): f32 + spv.OpStore(Pointer: v`intermediate_gamma`, Object: v15) + v16 = spv.OpLoad(Pointer: v0): f32×3 + spv.OpStore(Pointer: v5, Object: v16) + v17 = spv.OpLoad(Pointer: v1): f32×3 + spv.OpStore(Pointer: v6, Object: v17) + v18 = spv.OpLoad(Pointer: v2): f32×3 + spv.OpStore(Pointer: v7, Object: v18) + v19 = spv.OpLoad(Pointer: v3): f32×3 + spv.OpStore(Pointer: v8, Object: v19) + v20 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v9, Object: v20) + v21 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v5, v6, v7, v8, v9): f32×3 + spv.OpStore(Pointer: v`linear_mixed_color`, Object: v21) + v22 = spv.OpLoad(Pointer: v0): f32×3 + v23 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v24 = f.div(1.0f32, v23): f32 + v25 = vec.new(v24, v24, v24): f32×3 + v26 = spv.extinst."GLSL.std.450".Pow(X: v22, Y: v25): f32×3 + v27 = spv.OpLoad(Pointer: v1): f32×3 + v28 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v29 = f.div(1.0f32, v28): f32 + v30 = vec.new(v29, v29, v29): f32×3 + v31 = spv.extinst."GLSL.std.450".Pow(X: v27, Y: v30): f32×3 + v32 = spv.OpLoad(Pointer: v2): f32×3 + v33 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v34 = f.div(1.0f32, v33): f32 + v35 = vec.new(v34, v34, v34): f32×3 + v36 = spv.extinst."GLSL.std.450".Pow(X: v32, Y: v35): f32×3 + v37 = spv.OpLoad(Pointer: v3): f32×3 + v38 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32 + v39 = f.div(1.0f32, v38): f32 + v40 = vec.new(v39, v39, v39): f32×3 + v41 = spv.extinst."GLSL.std.450".Pow(X: v37, Y: v40): f32×3 + spv.OpStore(Pointer: v10, Object: v26) + spv.OpStore(Pointer: v11, Object: v31) + spv.OpStore(Pointer: v12, Object: v36) + spv.OpStore(Pointer: v13, Object: v41) + v42 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v14, Object: v42) + v43 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v10, v11, v12, v13, v14): f32×3 + spv.OpStore(Pointer: v`gamma_mixed_color`, Object: v43) + v44 = spv.OpLoad(Pointer: v`gamma_mixed_color`): f32×3 + v45 = spv.OpLoad(Pointer: v`linear_mixed_color`): f32×3 + v46 = spv.OpAccessChain(Base: &GV`global`, 16s32): T5 + v47 = spv.OpLoad(Pointer: v46): f32 + v48 = vec.new(v47, v47, v47): f32×3 + v49 = spv.extinst."GLSL.std.450".FMix(X: v44, Y: v45, A: v48): f32×3 + v49 +} + +func F`get_scanline_color(s21;vf2;vf2;vf4;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "scanline_uv"] + v2: T1, + #[name = "uv_step_x"] + v3: T1, + #[name = "weights"] + v4: T3, +) -> f32×3 { + #[name = "color1"] + v5 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color2"] + v6 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color0"] + v7 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "color3"] + v8 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T3 + v14 = spv.OpLoad(Pointer: v0): T6 + v15 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v16 = spv.OpSampledImage(Image: v14, Sampler: v15): T7 + v17 = spv.OpLoad(Pointer: v2): f32×2 + v18 = spv.OpImageSampleImplicitLod(SampledImage: v16, Coordinate: v17): f32×4 + v19 = spv.OpVectorShuffle(Vector1: v18, Vector2: v18, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v5, Object: v19) + v20 = spv.OpLoad(Pointer: v0): T6 + v21 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v22 = spv.OpSampledImage(Image: v20, Sampler: v21): T7 + v23 = spv.OpLoad(Pointer: v2): f32×2 + v24 = spv.OpLoad(Pointer: v3): f32×2 + v25 = vec.distribute(f.add)(v23, v24): f32×2 + v26 = spv.OpImageSampleImplicitLod(SampledImage: v22, Coordinate: v25): f32×4 + v27 = spv.OpVectorShuffle(Vector1: v26, Vector2: v26, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v6, Object: v27) + spv.OpStore(Pointer: v7, Object: f32×3(0.0, 0.0, 0.0)) + spv.OpStore(Pointer: v8, Object: f32×3(0.0, 0.0, 0.0)) + v28 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v29 = spv.OpLoad(Pointer: v28): f32 + v30 = f.gt(v29, 0.5f32): bool + if v30 { + v37 = spv.OpLoad(Pointer: v0): T6 + v38 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v39 = spv.OpSampledImage(Image: v37, Sampler: v38): T7 + v40 = spv.OpLoad(Pointer: v2): f32×2 + v41 = spv.OpLoad(Pointer: v3): f32×2 + v42 = vec.distribute(f.sub)(v40, v41): f32×2 + v43 = spv.OpImageSampleImplicitLod(SampledImage: v39, Coordinate: v42): f32×4 + v44 = spv.OpVectorShuffle(Vector1: v43, Vector2: v43, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v7, Object: v44) + v45 = spv.OpLoad(Pointer: v0): T6 + v46 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v47 = spv.OpSampledImage(Image: v45, Sampler: v46): T7 + v48 = spv.OpLoad(Pointer: v2): f32×2 + v49 = spv.OpLoad(Pointer: v3): f32×2 + v50 = vec.mul(v49, 2.0f32): f32×2 + v51 = vec.distribute(f.add)(v48, v50): f32×2 + v52 = spv.OpImageSampleImplicitLod(SampledImage: v47, Coordinate: v51): f32×4 + v53 = spv.OpVectorShuffle(Vector1: v52, Vector2: v52, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v8, Object: v53) + } else { + } + v31 = spv.OpLoad(Pointer: v7): f32×3 + spv.OpStore(Pointer: v9, Object: v31) + v32 = spv.OpLoad(Pointer: v5): f32×3 + spv.OpStore(Pointer: v10, Object: v32) + v33 = spv.OpLoad(Pointer: v6): f32×3 + spv.OpStore(Pointer: v11, Object: v33) + v34 = spv.OpLoad(Pointer: v8): f32×3 + spv.OpStore(Pointer: v12, Object: v34) + v35 = spv.OpLoad(Pointer: v4): f32×4 + spv.OpStore(Pointer: v13, Object: v35) + v36 = call F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(v9, v10, v11, v12, v13): f32×3 + v36 +} + +func F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, + #[name = "tex_size"] + v3: T1, + #[name = "texture_size_inv"] + v4: T1, +) -> f32×3 { + v`curr_texel` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel_hor` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_texel_hor_uv` = spv.OpVariable(spv.StorageClass.Function): T1 + v`prev_dist` = spv.OpVariable(spv.StorageClass.Function): T2 + v`sample_dists` = spv.OpVariable(spv.StorageClass.Function): T3 + v`x` = spv.OpVariable(spv.StorageClass.Function): T2 + v`w2` = spv.OpVariable(spv.StorageClass.Function): T2 + #[name = "weights"] + v5 = spv.OpVariable(spv.StorageClass.Function): T3 + v`inner_denom_inv` = spv.OpVariable(spv.StorageClass.Function): T2 + v`pi_dists` = spv.OpVariable(spv.StorageClass.Function): T3 + v`final_weights` = spv.OpVariable(spv.StorageClass.Function): T3 + #[name = "uv_step_x"] + v6 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T3 + v10 = spv.OpLoad(Pointer: v2): f32×2 + v11 = spv.OpLoad(Pointer: v3): f32×2 + v12 = vec.distribute(f.mul)(v10, v11): f32×2 + spv.OpStore(Pointer: v`curr_texel`, Object: v12) + v13 = spv.OpLoad(Pointer: v`curr_texel`): f32×2 + v14 = spv.OpLoad(Pointer: &GV`under_half`): f32 + v15 = vec.new(v14, v14): f32×2 + v16 = vec.distribute(f.sub)(v13, v15): f32×2 + v17 = spv.extinst."GLSL.std.450".Floor(X: v16): f32×2 + v18 = vec.distribute(f.add)(v17, f32×2(0.5, 0.5)): f32×2 + spv.OpStore(Pointer: v`prev_texel`, Object: v18) + v19 = spv.OpAccessChain(Base: v`prev_texel`, 0u32): T2 + v20 = spv.OpLoad(Pointer: v19): f32 + v21 = spv.OpAccessChain(Base: v`curr_texel`, 1u32): T2 + v22 = spv.OpLoad(Pointer: v21): f32 + v23 = vec.new(v20, v22): f32×2 + spv.OpStore(Pointer: v`prev_texel_hor`, Object: v23) + v24 = spv.OpLoad(Pointer: v`prev_texel_hor`): f32×2 + v25 = spv.OpLoad(Pointer: v4): f32×2 + v26 = vec.distribute(f.mul)(v24, v25): f32×2 + spv.OpStore(Pointer: v`prev_texel_hor_uv`, Object: v26) + v27 = spv.OpAccessChain(Base: v`curr_texel`, 0u32): T2 + v28 = spv.OpLoad(Pointer: v27): f32 + v29 = spv.OpAccessChain(Base: v`prev_texel_hor`, 0u32): T2 + v30 = spv.OpLoad(Pointer: v29): f32 + v31 = f.sub(v28, v30): f32 + spv.OpStore(Pointer: v`prev_dist`, Object: v31) + v32 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v33 = f.add(1.0f32, v32): f32 + v34 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v35 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v36 = f.sub(1.0f32, v35): f32 + v37 = spv.OpLoad(Pointer: v`prev_dist`): f32 + v38 = f.sub(2.0f32, v37): f32 + v39 = vec.new(v33, v34, v36, v38): f32×4 + spv.OpStore(Pointer: v`sample_dists`, Object: v39) + v40 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v41 = spv.OpLoad(Pointer: v40): f32 + v42 = f.lt(v41, 0.5f32): bool + if v42 { + v55 = spv.OpAccessChain(Base: v`sample_dists`, 1u32): T2 + v56 = spv.OpLoad(Pointer: v55): f32 + spv.OpStore(Pointer: v`x`, Object: v56) + v57 = spv.OpLoad(Pointer: v`x`): f32 + v58 = spv.OpLoad(Pointer: v`x`): f32 + v59 = f.mul(v57, v58): f32 + v60 = spv.OpLoad(Pointer: v`x`): f32 + v61 = f.mul(v59, v60): f32 + v62 = spv.OpLoad(Pointer: v`x`): f32 + v63 = spv.OpLoad(Pointer: v`x`): f32 + v64 = f.mul(v63, 6.0f32): f32 + v65 = f.sub(v64, 15.0f32): f32 + v66 = f.mul(v62, v65): f32 + v67 = f.add(v66, 10.0f32): f32 + v68 = f.mul(v61, v67): f32 + spv.OpStore(Pointer: v`w2`, Object: v68) + v69 = spv.OpLoad(Pointer: v`w2`): f32 + v70 = f.sub(1.0f32, v69): f32 + v71 = spv.OpLoad(Pointer: v`w2`): f32 + v72 = vec.new(0.0f32, v70, v71, 0.0f32): f32×4 + spv.OpStore(Pointer: v5, Object: v72) + } else { + v73 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5 + v74 = spv.OpLoad(Pointer: v73): f32 + v75 = f.lt(v74, 1.5f32): bool + if v75 { + v76 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5 + v77 = spv.OpLoad(Pointer: v76): f32 + v78 = f.mul(2.0f32, v77): f32 + v79 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5 + v80 = spv.OpLoad(Pointer: v79): f32 + v81 = f.mul(v78, v80): f32 + v82 = f.div(1.0f32, v81): f32 + spv.OpStore(Pointer: v`inner_denom_inv`, Object: v82) + v83 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v84 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v85 = vec.distribute(f.mul)(v83, v84): f32×4 + v86 = vec.distribute(f.neg)(v85): f32×4 + v87 = spv.OpLoad(Pointer: v`inner_denom_inv`): f32 + v88 = vec.mul(v86, v87): f32×4 + v89 = spv.extinst."GLSL.std.450".Exp(X: v88): f32×4 + spv.OpStore(Pointer: v5, Object: v89) + } else { + v90 = spv.OpLoad(Pointer: v`sample_dists`): f32×4 + v91 = spv.OpLoad(Pointer: &GV`pi`): f32 + v92 = vec.mul(v90, v91): f32×4 + v93 = spv.extinst."GLSL.std.450".FAbs(X: v92): f32×4 + v94 = vec.new(1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32): f32×4 + v95 = spv.extinst."GLSL.std.450".FMax(X: v93, Y: v94): f32×4 + spv.OpStore(Pointer: v`pi_dists`, Object: v95) + v96 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v97 = spv.extinst."GLSL.std.450".Sin(X: v96): f32×4 + v98 = vec.mul(v97, 2.0f32): f32×4 + v99 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v100 = vec.mul(v99, 0.5f32): f32×4 + v101 = spv.extinst."GLSL.std.450".Sin(X: v100): f32×4 + v102 = vec.distribute(f.mul)(v98, v101): f32×4 + v103 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v104 = spv.OpLoad(Pointer: v`pi_dists`): f32×4 + v105 = vec.distribute(f.mul)(v103, v104): f32×4 + v106 = vec.distribute(f.div)(v102, v105): f32×4 + spv.OpStore(Pointer: v5, Object: v106) + } + } + v43 = spv.OpLoad(Pointer: v5): f32×4 + v44 = spv.OpLoad(Pointer: v5): f32×4 + v45 = vec.dot(v44, f32×4(1.0, 1.0, 1.0, 1.0)): f32 + v46 = vec.new(v45, v45, v45, v45): f32×4 + v47 = vec.distribute(f.div)(v43, v46): f32×4 + spv.OpStore(Pointer: v`final_weights`, Object: v47) + v48 = spv.OpAccessChain(Base: v4, 0u32): T2 + v49 = spv.OpLoad(Pointer: v48): f32 + v50 = vec.new(v49, 0.0f32): f32×2 + spv.OpStore(Pointer: v6, Object: v50) + v51 = spv.OpLoad(Pointer: v`prev_texel_hor_uv`): f32×2 + spv.OpStore(Pointer: v7, Object: v51) + v52 = spv.OpLoad(Pointer: v6): f32×2 + spv.OpStore(Pointer: v8, Object: v52) + v53 = spv.OpLoad(Pointer: v`final_weights`): f32×4 + spv.OpStore(Pointer: v9, Object: v53) + v54 = call F`get_scanline_color(s21;vf2;vf2;vf4;`(v0, v1, v7, v8, v9): f32×3 + v54 +} + +func F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, + #[name = "tex_size"] + v3: T1, + #[name = "texture_size_inv"] + v4: T1, +) -> f32×3 { + v`convergence_offsets_rgb` = spv.OpVariable(spv.StorageClass.Function): T0 + v`offset_u_rgb` = spv.OpVariable(spv.StorageClass.Function): T0 + v`scanline_uv_r` = spv.OpVariable(spv.StorageClass.Function): T1 + v`scanline_uv_g` = spv.OpVariable(spv.StorageClass.Function): T1 + v`scanline_uv_b` = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_r` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_g` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T1 + v`sample_b` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v13 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v14 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v15 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v16 = spv.OpVariable(spv.StorageClass.Function): T1 + v17 = spv.OpLoad(Pointer: &GV`beam_misconvergence`): bool + v18: f32×3 = if v17 { + v19 = call F`get_convergence_offsets_x_vector(`(): f32×3 + spv.OpStore(Pointer: v`convergence_offsets_rgb`, Object: v19) + v20 = spv.OpLoad(Pointer: v`convergence_offsets_rgb`): f32×3 + v21 = spv.OpLoad(Pointer: v4): f32×2 + v22 = spv.OpVectorShuffle(Vector1: v21, Vector2: v21, 0, 0, 0): f32×3 + v23 = vec.distribute(f.mul)(v20, v22): f32×3 + spv.OpStore(Pointer: v`offset_u_rgb`, Object: v23) + v24 = spv.OpLoad(Pointer: v2): f32×2 + v25 = spv.OpAccessChain(Base: v`offset_u_rgb`, 0u32): T2 + v26 = spv.OpLoad(Pointer: v25): f32 + v27 = vec.new(v26, 0.0f32): f32×2 + v28 = vec.distribute(f.sub)(v24, v27): f32×2 + spv.OpStore(Pointer: v`scanline_uv_r`, Object: v28) + v29 = spv.OpLoad(Pointer: v2): f32×2 + v30 = spv.OpAccessChain(Base: v`offset_u_rgb`, 1u32): T2 + v31 = spv.OpLoad(Pointer: v30): f32 + v32 = vec.new(v31, 0.0f32): f32×2 + v33 = vec.distribute(f.sub)(v29, v32): f32×2 + spv.OpStore(Pointer: v`scanline_uv_g`, Object: v33) + v34 = spv.OpLoad(Pointer: v2): f32×2 + v35 = spv.OpAccessChain(Base: v`offset_u_rgb`, 2u32): T2 + v36 = spv.OpLoad(Pointer: v35): f32 + v37 = vec.new(v36, 0.0f32): f32×2 + v38 = vec.distribute(f.sub)(v34, v37): f32×2 + spv.OpStore(Pointer: v`scanline_uv_b`, Object: v38) + v39 = spv.OpLoad(Pointer: v`scanline_uv_r`): f32×2 + spv.OpStore(Pointer: v5, Object: v39) + v40 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v6, Object: v40) + v41 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v7, Object: v41) + v42 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v5, v6, v7): f32×3 + spv.OpStore(Pointer: v`sample_r`, Object: v42) + v43 = spv.OpLoad(Pointer: v`scanline_uv_g`): f32×2 + spv.OpStore(Pointer: v8, Object: v43) + v44 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v9, Object: v44) + v45 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v10, Object: v45) + v46 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v8, v9, v10): f32×3 + spv.OpStore(Pointer: v`sample_g`, Object: v46) + v47 = spv.OpLoad(Pointer: v`scanline_uv_b`): f32×2 + spv.OpStore(Pointer: v11, Object: v47) + v48 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v12, Object: v48) + v49 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v13, Object: v49) + v50 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v11, v12, v13): f32×3 + spv.OpStore(Pointer: v`sample_b`, Object: v50) + v51 = spv.OpAccessChain(Base: v`sample_r`, 0u32): T2 + v52 = spv.OpLoad(Pointer: v51): f32 + v53 = spv.OpAccessChain(Base: v`sample_g`, 1u32): T2 + v54 = spv.OpLoad(Pointer: v53): f32 + v55 = spv.OpAccessChain(Base: v`sample_b`, 2u32): T2 + v56 = spv.OpLoad(Pointer: v55): f32 + v57 = vec.new(v52, v54, v56): f32×3 + v57 + } else { + v58 = spv.OpLoad(Pointer: v2): f32×2 + spv.OpStore(Pointer: v14, Object: v58) + v59 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v15, Object: v59) + v60 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v16, Object: v60) + v61 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v14, v15, v16): f32×3 + v61 + } + v18 +} + +#[spv.Decoration.Binding(BindingPoint: 6)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`VERTICAL_SCANLINES`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 6)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_VERTICAL_SCANLINES_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`get_mask_sample_mode(`() -> f32 { + v0 = spv.OpAccessChain(Base: &GV`global`, 24s32): T5 + v1 = spv.OpLoad(Pointer: v0): f32 + v1 +} + +func F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`( + #[name = "tile_uv_wrap"] + v0: T1, + #[name = "mask_tile_start_uv_and_size"] + v1: T3, +) -> f32×2 { + v`tile_uv` = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "mask_tex_uv"] + v2 = spv.OpVariable(spv.StorageClass.Function): T1 + v3 = call F`get_mask_sample_mode(`(): f32 + v4 = f.lt(v3, 0.5f32): bool + v5: f32×2 = if v4 { + v6 = spv.OpLoad(Pointer: v0): f32×2 + v7 = vec.mul(v6, 0.5f32): f32×2 + v8 = spv.extinst."GLSL.std.450".Fract(X: v7): f32×2 + v9 = vec.mul(v8, 2.0f32): f32×2 + spv.OpStore(Pointer: v`tile_uv`, Object: v9) + v10 = spv.OpLoad(Pointer: v1): f32×4 + v11 = spv.OpVectorShuffle(Vector1: v10, Vector2: v10, 0, 1): f32×2 + v12 = spv.OpLoad(Pointer: v`tile_uv`): f32×2 + v13 = spv.OpLoad(Pointer: v1): f32×4 + v14 = spv.OpVectorShuffle(Vector1: v13, Vector2: v13, 2, 3): f32×2 + v15 = vec.distribute(f.mul)(v12, v14): f32×2 + v16 = vec.distribute(f.add)(v11, v15): f32×2 + spv.OpStore(Pointer: v2, Object: v16) + v17 = spv.OpLoad(Pointer: v2): f32×2 + v17 + } else { + v18 = spv.OpLoad(Pointer: v0): f32×2 + v18 + } + v5 +} + +func F`get_pass_input_gamma(`() -> f32 { + 1.0f32 +} + +func F`decode_input(vf4;`( + #[name = "color"] + v0: T3, +) -> f32×4 { + v1 = spv.OpLoad(Pointer: &GV`linearize_input`): bool + v2: f32×4 = if v1 { + v3 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool + v4: f32×4 = if v3 { + v5 = spv.OpLoad(Pointer: v0): f32×4 + v6 = spv.OpVectorShuffle(Vector1: v5, Vector2: v5, 0, 1, 2): f32×3 + v7 = call F`get_pass_input_gamma(`(): f32 + v8 = vec.new(v7, v7, v7): f32×3 + v9 = spv.extinst."GLSL.std.450".Pow(X: v6, Y: v8): f32×3 + v10 = vec.extract(v9, 0): f32 + v11 = vec.extract(v9, 1): f32 + v12 = vec.extract(v9, 2): f32 + v13 = vec.new(v10, v11, v12, 1.0f32): f32×4 + v13 + } else { + v14 = spv.OpLoad(Pointer: v0): f32×4 + v15 = spv.OpVectorShuffle(Vector1: v14, Vector2: v14, 0, 1, 2): f32×3 + v16 = call F`get_pass_input_gamma(`(): f32 + v17 = vec.new(v16, v16, v16): f32×3 + v18 = spv.extinst."GLSL.std.450".Pow(X: v15, Y: v17): f32×3 + v19 = spv.OpAccessChain(Base: v0, 3u32): T2 + v20 = spv.OpLoad(Pointer: v19): f32 + v21 = vec.extract(v18, 0): f32 + v22 = vec.extract(v18, 1): f32 + v23 = vec.extract(v18, 2): f32 + v24 = vec.new(v21, v22, v23, v20): f32×4 + v24 + } + v4 + } else { + v25 = spv.OpLoad(Pointer: v0): f32×4 + v25 + } + v2 +} + +func F`tex2D_linearize(s21;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + v2: T9, + #[name = "tex_coords"] + v3: T1, +) -> f32×4 { + #[name = "param"] + v4 = spv.OpVariable(spv.StorageClass.Function): T3 + v5 = spv.OpLoad(Pointer: v0): T6 + v6 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler + v7 = spv.OpSampledImage(Image: v5, Sampler: v6): T7 + v8 = spv.OpLoad(Pointer: v2): spv.OpTypeSampler + v9 = spv.OpSampledImage(Image: v7, Sampler: v8): T7 + v10 = spv.OpLoad(Pointer: v3): f32×2 + v11 = spv.OpImageSampleImplicitLod(SampledImage: v9, Coordinate: v10): f32×4 + spv.OpStore(Pointer: v4, Object: v11) + v12 = call F`decode_input(vf4;`(v4): f32×4 + v12 +} + +#[spv.Decoration.Binding(BindingPoint: 3)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_grille_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 3)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_grille_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 4)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_slot_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 4)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_slot_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 5)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`mask_shadow_texture_large`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 5)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_mask_shadow_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`tex2Dtiled_mask_linearize(s21;vf2;`( + #[name = "tex"] + v0: T8, + v1: T9, + #[name = "tex_uv"] + v2: T1, +) -> f32×4 { + #[name = "param"] + v3 = spv.OpVariable(spv.StorageClass.Function): T1 + v4 = spv.OpLoad(Pointer: v2): f32×2 + spv.OpStore(Pointer: v3, Object: v4) + v5 = call F`tex2D_linearize(s21;vf2;`(v0, v1, v3): f32×4 + v5 +} + +#[spv.Decoration.Binding(BindingPoint: 9)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`MASK_RESIZE`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 9)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_MASK_RESIZE_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +#[spv.Decoration.Binding(BindingPoint: 8)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`HALATION_BLUR`(spv.StorageClass.UniformConstant): T7 + +#[spv.Decoration.Binding(BindingPoint: 8)] +#[spv.Decoration.DescriptorSet(DescriptorSet: 0)] +global_var GV`_HALATION_BLUR_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler + +func F`get_pass_output_gamma(`() -> f32 { + 1.0f32 +} + +func F`encode_output(vf4;`( + #[name = "color"] + v0: T3, +) -> f32×4 { + v1 = spv.OpLoad(Pointer: &GV`gamma_encode_output`): bool + v2: f32×4 = if v1 { + v3 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool + v4: f32×4 = if v3 { + v5 = spv.OpLoad(Pointer: v0): f32×4 + v6 = spv.OpVectorShuffle(Vector1: v5, Vector2: v5, 0, 1, 2): f32×3 + v7 = call F`get_pass_output_gamma(`(): f32 + v8 = f.div(1.0f32, v7): f32 + v9 = vec.new(v8, v8, v8): f32×3 + v10 = spv.extinst."GLSL.std.450".Pow(X: v6, Y: v9): f32×3 + v11 = vec.extract(v10, 0): f32 + v12 = vec.extract(v10, 1): f32 + v13 = vec.extract(v10, 2): f32 + v14 = vec.new(v11, v12, v13, 1.0f32): f32×4 + v14 + } else { + v15 = spv.OpLoad(Pointer: v0): f32×4 + v16 = spv.OpVectorShuffle(Vector1: v15, Vector2: v15, 0, 1, 2): f32×3 + v17 = call F`get_pass_output_gamma(`(): f32 + v18 = f.div(1.0f32, v17): f32 + v19 = vec.new(v18, v18, v18): f32×3 + v20 = spv.extinst."GLSL.std.450".Pow(X: v16, Y: v19): f32×3 + v21 = spv.OpAccessChain(Base: v0, 3u32): T2 + v22 = spv.OpLoad(Pointer: v21): f32 + v23 = vec.extract(v20, 0): f32 + v24 = vec.extract(v20, 1): f32 + v25 = vec.extract(v20, 2): f32 + v26 = vec.new(v23, v24, v25, v22): f32×4 + v26 + } + v4 + } else { + v27 = spv.OpLoad(Pointer: v0): f32×4 + v27 + } + v2 +} + +#[spv.ExecutionMode.OriginUpperLeft] +func F`main`() { + v`scanline_color_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v0 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v1 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v2 = spv.OpVariable(spv.StorageClass.Function): T1 + v`auto_dim_factor` = spv.OpVariable(spv.StorageClass.Function): T2 + #[name = "tile_uv_wrap"] + v3 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "mask_tex_uv"] + v4 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v5 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v6 = spv.OpVariable(spv.StorageClass.Function): T3 + v`sample_orig_luts` = spv.OpVariable(spv.StorageClass.Function): spv.OpTypePointer(spv.StorageClass.Function, bool) + v`phosphor_mask_sample` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v7 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v8 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v9 = spv.OpVariable(spv.StorageClass.Function): T1 + #[name = "param"] + v10 = spv.OpVariable(spv.StorageClass.Function): T1 + v`halation_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v11 = spv.OpVariable(spv.StorageClass.Function): T1 + v`halation_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`electron_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`phosphor_emission_dim` = spv.OpVariable(spv.StorageClass.Function): T0 + v`pixel_color` = spv.OpVariable(spv.StorageClass.Function): T0 + #[name = "param"] + v12 = spv.OpVariable(spv.StorageClass.Function): T3 + v13 = spv.OpAccessChain(Base: &GV`params`, 2s32, 0u32): T4 + v14 = spv.OpLoad(Pointer: v13): f32 + v15 = spv.OpAccessChain(Base: &GV`params`, 0s32, 1u32): T4 + v16 = spv.OpLoad(Pointer: v15): f32 + v17 = f.div(v14, v16): f32 + spv.OpStore(Pointer: &GV`bloom_approx_scale_x`, Object: v17) + spv.OpStore(Pointer: &GV`crt_gamma_static`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`lcd_gamma_static`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`levels_contrast_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`levels_autodim_temp`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`halation_weight_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`diffusion_weight_static`, Object: 0.075f32) + spv.OpStore(Pointer: &GV`bloom_underestimate_levels_static`, Object: 0.8f32) + spv.OpStore(Pointer: &GV`bloom_excess_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`bloom_approx_filter_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`beam_num_scanlines`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`beam_generalized_gaussian`, Object: true) + spv.OpStore(Pointer: &GV`beam_antialias_level`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`beam_min_sigma_static`, Object: 0.02f32) + spv.OpStore(Pointer: &GV`beam_max_sigma_static`, Object: 0.3f32) + spv.OpStore(Pointer: &GV`beam_spot_shape_function`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`beam_spot_power_static`, Object: 0.33333334f32) + spv.OpStore(Pointer: &GV`beam_min_shape_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`beam_max_shape_static`, Object: 4.0f32) + spv.OpStore(Pointer: &GV`beam_shape_power_static`, Object: 0.25f32) + spv.OpStore(Pointer: &GV`beam_horiz_filter_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`beam_horiz_sigma_static`, Object: 0.35f32) + spv.OpStore(Pointer: &GV`beam_horiz_linear_rgb_weight_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`beam_misconvergence`, Object: true) + spv.OpStore(Pointer: &GV`convergence_offsets_r_static`, Object: f32×2(0.1, 0.2)) + spv.OpStore(Pointer: &GV`convergence_offsets_g_static`, Object: f32×2(0.3, 0.4)) + spv.OpStore(Pointer: &GV`convergence_offsets_b_static`, Object: f32×2(0.5, 0.6)) + spv.OpStore(Pointer: &GV`interlace_detect_static`, Object: true) + spv.OpStore(Pointer: &GV`interlace_1080i_static`, Object: false) + spv.OpStore(Pointer: &GV`interlace_bff_static`, Object: false) + spv.OpStore(Pointer: &GV`aa_level`, Object: 12.0f32) + spv.OpStore(Pointer: &GV`aa_filter`, Object: 6.0f32) + spv.OpStore(Pointer: &GV`aa_temporal`, Object: false) + spv.OpStore(Pointer: &GV`aa_subpixel_r_offset_static`, Object: f32×2(-0.33333334, 0.0)) + spv.OpStore(Pointer: &GV`aa_cubic_c_static`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`aa_gauss_sigma_static`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`mask_type_static`, Object: 1.0f32) + spv.OpStore(Pointer: &GV`mask_sample_mode_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`mask_specify_num_triads_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`mask_triad_size_desired_static`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`mask_num_triads_desired_static`, Object: 480.0f32) + spv.OpStore(Pointer: &GV`mask_sinc_lobes`, Object: 3.0f32) + spv.OpStore(Pointer: &GV`mask_min_allowed_triad_size`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_mode_static`, Object: 0.0f32) + spv.OpStore(Pointer: &GV`geom_radius_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_view_dist_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`geom_tilt_angle_static`, Object: f32×2(0.0, 0.0)) + spv.OpStore(Pointer: &GV`geom_aspect_ratio_static`, Object: 1.3130699f32) + spv.OpStore(Pointer: &GV`geom_overscan_static`, Object: f32×2(1.0, 1.0)) + spv.OpStore(Pointer: &GV`geom_force_correct_tangent_matrix`, Object: true) + spv.OpStore(Pointer: &GV`border_size_static`, Object: 0.015f32) + spv.OpStore(Pointer: &GV`border_darkness_static`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`border_compress_static`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`bloom_approx_size_x`, Object: 320.0f32) + spv.OpStore(Pointer: &GV`bloom_approx_size_x_for_fake`, Object: 400.0f32) + spv.OpStore(Pointer: &GV`mask_resize_viewport_scale`, Object: f32×2(0.0625, 0.0625)) + spv.OpStore(Pointer: &GV`geom_max_aspect_ratio`, Object: 1.3333334f32) + spv.OpStore(Pointer: &GV`mask_texture_small_size`, Object: f32×2(64.0, 64.0)) + spv.OpStore(Pointer: &GV`mask_texture_large_size`, Object: f32×2(512.0, 512.0)) + spv.OpStore(Pointer: &GV`mask_triads_per_tile`, Object: 8.0f32) + spv.OpStore(Pointer: &GV`mask_grille14_avg_color`, Object: 0.19869281f32) + spv.OpStore(Pointer: &GV`mask_grille15_avg_color`, Object: 0.20784314f32) + spv.OpStore(Pointer: &GV`mask_slot_avg_color`, Object: 0.18039216f32) + spv.OpStore(Pointer: &GV`mask_shadow_avg_color`, Object: 0.16078432f32) + v18 = spv.OpLoad(Pointer: &GV`mask_grille15_avg_color`): f32 + spv.OpStore(Pointer: &GV`mask_grille_avg_color`, Object: v18) + v19 = spv.OpLoad(Pointer: &GV`bloom_approx_filter_static`): f32 + spv.OpStore(Pointer: &GV`bloom_approx_filter`, Object: v19) + v20 = spv.OpLoad(Pointer: &GV`mask_texture_small_size`): f32×2 + spv.OpStore(Pointer: &GV`mask_resize_src_lut_size`, Object: v20) + spv.OpStore(Pointer: &GV`max_aa_base_pixel_border`, Object: 0.0f32) + v21 = spv.OpLoad(Pointer: &GV`max_aa_base_pixel_border`): f32 + v22 = f.add(v21, 0.5f32): f32 + spv.OpStore(Pointer: &GV`max_aniso_pixel_border`, Object: v22) + v23 = spv.OpLoad(Pointer: &GV`max_aniso_pixel_border`): f32 + spv.OpStore(Pointer: &GV`max_tiled_pixel_border`, Object: v23) + v24 = spv.OpLoad(Pointer: &GV`max_tiled_pixel_border`): f32 + v25 = spv.extinst."GLSL.std.450".Ceil(X: v24): f32 + spv.OpStore(Pointer: &GV`max_mask_texel_border`, Object: v25) + v26 = spv.OpLoad(Pointer: &GV`max_mask_texel_border`): f32 + v27 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32 + v28 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v29 = f.mul(v27, v28): f32 + v30 = f.div(v26, v29): f32 + spv.OpStore(Pointer: &GV`max_mask_tile_border`, Object: v30) + spv.OpStore(Pointer: &GV`mask_resize_num_tiles`, Object: 2.0f32) + spv.OpStore(Pointer: &GV`mask_start_texels`, Object: 0.0f32) + v31 = spv.OpLoad(Pointer: &GV`mask_resize_num_tiles`): f32 + v32 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v33 = f.mul(v31, v32): f32 + spv.OpStore(Pointer: &GV`mask_resize_num_triads`, Object: v33) + v34 = spv.OpLoad(Pointer: &GV`mask_resize_num_triads`): f32 + v35 = vec.new(v34, v34): f32×2 + v36 = spv.OpLoad(Pointer: &GV`mask_resize_viewport_scale`): f32×2 + v37 = vec.distribute(f.div)(v35, v36): f32×2 + spv.OpStore(Pointer: &GV`min_allowed_viewport_triads`, Object: v37) + spv.OpStore(Pointer: &GV`pi`, Object: 3.1415927f32) + spv.OpStore(Pointer: &GV`under_half`, Object: 0.4995f32) + spv.OpStore(Pointer: &GV`gba_gamma`, Object: 3.5f32) + v38 = spv.OpAccessChain(Base: &GV`global`, 46s32): T5 + v39 = spv.OpLoad(Pointer: v38): f32 + v40 = f.ne_or_unord(v39, 0.0f32): bool + spv.OpStore(Pointer: &GV`interlace_detect`, Object: v40) + spv.OpStore(Pointer: &GV`ntsc_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`pal_gamma`, Object: 2.8f32) + spv.OpStore(Pointer: &GV`crt_reference_gamma_high`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`crt_reference_gamma_low`, Object: 2.35f32) + spv.OpStore(Pointer: &GV`lcd_reference_gamma`, Object: 2.5f32) + spv.OpStore(Pointer: &GV`crt_office_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`lcd_office_gamma`, Object: 2.2f32) + spv.OpStore(Pointer: &GV`assume_opaque_alpha`, Object: false) + spv.OpStore(Pointer: &GV`linearize_input`, Object: false) + spv.OpStore(Pointer: &GV`gamma_encode_output`, Object: false) + v41 = spv.OpLoad(Pointer: &GV`linearize_input`): bool + v42 = bool.not(v41): bool + spv.OpStore(Pointer: &GV`gamma_aware_bilinear`, Object: v42) + v43 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32 + v44 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32 + v45 = f.mul(v43, v44): f32 + v46 = spv.extinst."GLSL.std.450".Ceil(X: v45): f32 + spv.OpStore(Pointer: &GV`mask_min_allowed_tile_size`, Object: v46) + v47 = spv.OpLoad(Pointer: &GV`mask_min_allowed_tile_size`): f32 + spv.OpStore(Pointer: &GV`mask_min_expected_tile_size`, Object: v47) + v48 = spv.OpLoad(Pointer: &GV`pi`): f32 + v49 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32 + v50 = f.div(v48, v49): f32 + spv.OpStore(Pointer: &GV`pi_over_lobes`, Object: v50) + v51 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32 + v52 = f.mul(2.0f32, v51): f32 + v53 = spv.OpAccessChain(Base: &GV`mask_resize_src_lut_size`, 0u32): spv.OpTypePointer(spv.StorageClass.Private, f32) + v54 = spv.OpLoad(Pointer: v53): f32 + v55 = f.mul(v52, v54): f32 + v56 = spv.OpLoad(Pointer: &GV`mask_min_expected_tile_size`): f32 + v57 = f.div(v55, v56): f32 + spv.OpStore(Pointer: &GV`max_sinc_resize_samples_float`, Object: v57) + v58 = spv.OpLoad(Pointer: &GV`max_sinc_resize_samples_float`): f32 + v59 = f.mul(v58, 0.25f32): f32 + v60 = spv.extinst."GLSL.std.450".Ceil(X: v59): f32 + v61 = f.mul(v60, 4.0f32): f32 + spv.OpStore(Pointer: &GV`max_sinc_resize_samples_m4`, Object: v61) + spv.OpStore(Pointer: &GV`blur3_std_dev`, Object: 0.62666017f32) + spv.OpStore(Pointer: &GV`blur4_std_dev`, Object: 0.6617187f32) + spv.OpStore(Pointer: &GV`blur5_std_dev`, Object: 0.9845703f32) + spv.OpStore(Pointer: &GV`blur6_std_dev`, Object: 1.0262696f32) + spv.OpStore(Pointer: &GV`blur7_std_dev`, Object: 1.3610351f32) + spv.OpStore(Pointer: &GV`blur8_std_dev`, Object: 1.4080079f32) + spv.OpStore(Pointer: &GV`blur9_std_dev`, Object: 1.7533203f32) + spv.OpStore(Pointer: &GV`blur10_std_dev`, Object: 1.8047851f32) + spv.OpStore(Pointer: &GV`blur11_std_dev`, Object: 2.1598632f32) + spv.OpStore(Pointer: &GV`blur12_std_dev`, Object: 2.2152343f32) + spv.OpStore(Pointer: &GV`blur17_std_dev`, Object: 3.455356f32) + spv.OpStore(Pointer: &GV`blur25_std_dev`, Object: 5.3409576f32) + spv.OpStore(Pointer: &GV`blur31_std_dev`, Object: 6.8648806f32) + spv.OpStore(Pointer: &GV`blur43_std_dev`, Object: 10.185205f32) + spv.OpStore(Pointer: &GV`error_blurring`, Object: 0.5f32) + spv.OpStore(Pointer: &GV`bloom_diff_thresh`, Object: 0.00390625f32) + v62 = spv.OpLoad(Pointer: &GV`scanline_tex_uv`): f32×2 + spv.OpStore(Pointer: v0, Object: v62) + v63 = spv.OpAccessChain(Base: &GV`params`, 3s32): spv.OpTypePointer(spv.StorageClass.PushConstant, f32×4) + v64 = spv.OpLoad(Pointer: v63): f32×4 + v65 = spv.OpVectorShuffle(Vector1: v64, Vector2: v64, 0, 1): f32×2 + spv.OpStore(Pointer: v1, Object: v65) + v66 = spv.OpLoad(Pointer: &GV`scanline_texture_size_inv`): f32×2 + spv.OpStore(Pointer: v2, Object: v66) + v67 = call F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(&GV`VERTICAL_SCANLINES`, &GV`_VERTICAL_SCANLINES_sampler`, v0, v1, v2): + f32×3 + spv.OpStore(Pointer: v`scanline_color_dim`, Object: v67) + v68 = spv.OpLoad(Pointer: &GV`levels_autodim_temp`): f32 + spv.OpStore(Pointer: v`auto_dim_factor`, Object: v68) + v69 = spv.OpLoad(Pointer: &GV`video_uv`): f32×2 + v70 = spv.OpLoad(Pointer: &GV`mask_tiles_per_screen`): f32×2 + v71 = vec.distribute(f.mul)(v69, v70): f32×2 + spv.OpStore(Pointer: v3, Object: v71) + v72 = spv.OpLoad(Pointer: v3): f32×2 + spv.OpStore(Pointer: v5, Object: v72) + v73 = spv.OpLoad(Pointer: &GV0): f32×4 + spv.OpStore(Pointer: v6, Object: v73) + v74 = call F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(v5, v6): f32×2 + spv.OpStore(Pointer: v4, Object: v74) + v75 = call F`get_mask_sample_mode(`(): f32 + v76 = f.gt(v75, 0.5f32): bool + spv.OpStore(Pointer: v`sample_orig_luts`, Object: v76) + v77 = spv.OpLoad(Pointer: v`sample_orig_luts`): bool + if v77 { + v103 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5 + v104 = spv.OpLoad(Pointer: v103): f32 + v105 = f.lt(v104, 0.5f32): bool + if v105 { + v106 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v7, Object: v106) + v107 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_grille_texture_large`, &GV`_mask_grille_texture_large_sampler`, v7): f32×4 + v108 = spv.OpVectorShuffle(Vector1: v107, Vector2: v107, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v108) + } else { + v109 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5 + v110 = spv.OpLoad(Pointer: v109): f32 + v111 = f.lt(v110, 1.5f32): bool + if v111 { + v112 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v8, Object: v112) + v113 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_slot_texture_large`, &GV`_mask_slot_texture_large_sampler`, v8): f32×4 + v114 = spv.OpVectorShuffle(Vector1: v113, Vector2: v113, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v114) + } else { + v115 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v9, Object: v115) + v116 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_shadow_texture_large`, &GV`_mask_shadow_texture_large_sampler`, v9): f32×4 + v117 = spv.OpVectorShuffle(Vector1: v116, Vector2: v116, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v117) + } + } + } else { + v118 = spv.OpLoad(Pointer: v4): f32×2 + spv.OpStore(Pointer: v10, Object: v118) + v119 = call F`tex2Dtiled_mask_linearize(s21;vf2;`(&GV`MASK_RESIZE`, &GV`_MASK_RESIZE_sampler`, v10): f32×4 + v120 = spv.OpVectorShuffle(Vector1: v119, Vector2: v119, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v120) + } + v78 = spv.OpLoad(Pointer: &GV`halation_tex_uv`): f32×2 + spv.OpStore(Pointer: v11, Object: v78) + v79 = call F`tex2D_linearize(s21;vf2;`(&GV`HALATION_BLUR`, &GV`_HALATION_BLUR_sampler`, v11): f32×4 + v80 = spv.OpVectorShuffle(Vector1: v79, Vector2: v79, 0, 1, 2): f32×3 + spv.OpStore(Pointer: v`halation_color`, Object: v80) + v81 = spv.OpLoad(Pointer: v`halation_color`): f32×3 + v82 = spv.OpLoad(Pointer: v`auto_dim_factor`): f32 + v83 = f.div(v82, 3.0f32): f32 + v84 = vec.new(v83, v83, v83): f32×3 + v85 = vec.dot(v81, v84): f32 + v86 = vec.new(v85, v85, v85): f32×3 + spv.OpStore(Pointer: v`halation_intensity_dim`, Object: v86) + v87 = spv.OpLoad(Pointer: v`scanline_color_dim`): f32×3 + v88 = spv.OpLoad(Pointer: v`halation_intensity_dim`): f32×3 + v89 = spv.OpAccessChain(Base: &GV`global`, 4s32): T5 + v90 = spv.OpLoad(Pointer: v89): f32 + v91 = vec.new(v90, v90, v90): f32×3 + v92 = spv.extinst."GLSL.std.450".FMix(X: v87, Y: v88, A: v91): f32×3 + spv.OpStore(Pointer: v`electron_intensity_dim`, Object: v92) + v93 = spv.OpLoad(Pointer: v`electron_intensity_dim`): f32×3 + v94 = spv.OpLoad(Pointer: v`phosphor_mask_sample`): f32×3 + v95 = vec.distribute(f.mul)(v93, v94): f32×3 + spv.OpStore(Pointer: v`phosphor_emission_dim`, Object: v95) + v96 = spv.OpLoad(Pointer: v`phosphor_emission_dim`): f32×3 + spv.OpStore(Pointer: v`pixel_color`, Object: v96) + v97 = spv.OpLoad(Pointer: v`pixel_color`): f32×3 + v98 = vec.extract(v97, 0): f32 + v99 = vec.extract(v97, 1): f32 + v100 = vec.extract(v97, 2): f32 + v101 = vec.new(v98, v99, v100, 1.0f32): f32×4 + spv.OpStore(Pointer: v12, Object: v101) + v102 = call F`encode_output(vf4;`(v12): f32×4 + spv.OpStore(Pointer: &GV`FragColor`, Object: v102) +} + +export { + spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F`main`, +} \ No newline at end of file diff --git a/librashader-reflect/out.structured.spirt.html b/librashader-reflect/out.structured.spirt.html new file mode 100644 index 0000000..a29b2eb --- /dev/null +++ b/librashader-reflect/out.structured.spirt.html @@ -0,0 +1,1536 @@ + + + + + + + + + + + + + +
+module.dialect = spv.Module(version: 1.0, spv.Capability.Shader, spv.MemoryModel.GLSL450)
+
+module.debug_info = spv.Module.DebugInfo(
+  generator: spv.Tool(id: 15),
+  source_languages: {
+    spv.SourceLanguage.GLSL(version: 450): {},
+  },
+  source_extensions: ["GL_GOOGLE_cpp_style_line_directive", "GL_GOOGLE_include_directive"],
+)
+
+type T0 = spv.OpTypePointer(spv.StorageClass.Function, f32×3)
+
+type T1 = spv.OpTypePointer(spv.StorageClass.Function, f32×2)
+
+type T2 = spv.OpTypePointer(spv.StorageClass.Function, f32)
+
+type T3 = spv.OpTypePointer(spv.StorageClass.Function, f32×4)
+
+type T4 = spv.OpTypePointer(spv.StorageClass.PushConstant, f32)
+
+#[spv.OpMemberName(Member: 0, Name: "SourceSize")]
+#[spv.OpMemberName(Member: 1, Name: "OriginalSize")]
+#[spv.OpMemberName(Member: 2, Name: "OutputSize")]
+#[spv.OpMemberName(Member: 3, Name: "VERTICAL_SCANLINESSize")]
+#[spv.OpMemberName(Member: 4, Name: "BLOOM_APPROXSize")]
+#[spv.OpMemberName(Member: 5, Name: "HALATION_BLURSize")]
+#[spv.OpMemberName(Member: 6, Name: "MASK_RESIZESize")]
+#[spv.Decoration.Block]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))]
+#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 16))]
+#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 32))]
+#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 48))]
+#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 64))]
+#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))]
+#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 96))]
+type T`Push` = spv.OpTypeStruct(f32×4, f32×4, f32×4, f32×4, f32×4, f32×4, f32×4)
+
+type T5 = spv.OpTypePointer(spv.StorageClass.Uniform, f32)
+
+#[spv.OpMemberName(Member: 0, Name: "MVP")]
+#[spv.OpMemberName(Member: 1, Name: "crt_gamma")]
+#[spv.OpMemberName(Member: 2, Name: "lcd_gamma")]
+#[spv.OpMemberName(Member: 3, Name: "levels_contrast")]
+#[spv.OpMemberName(Member: 4, Name: "halation_weight")]
+#[spv.OpMemberName(Member: 5, Name: "diffusion_weight")]
+#[spv.OpMemberName(Member: 6, Name: "bloom_underestimate_levels")]
+#[spv.OpMemberName(Member: 7, Name: "bloom_excess")]
+#[spv.OpMemberName(Member: 8, Name: "beam_min_sigma")]
+#[spv.OpMemberName(Member: 9, Name: "beam_max_sigma")]
+#[spv.OpMemberName(Member: 10, Name: "beam_spot_power")]
+#[spv.OpMemberName(Member: 11, Name: "beam_min_shape")]
+#[spv.OpMemberName(Member: 12, Name: "beam_max_shape")]
+#[spv.OpMemberName(Member: 13, Name: "beam_shape_power")]
+#[spv.OpMemberName(Member: 14, Name: "beam_horiz_filter")]
+#[spv.OpMemberName(Member: 15, Name: "beam_horiz_sigma")]
+#[spv.OpMemberName(Member: 16, Name: "beam_horiz_linear_rgb_weight")]
+#[spv.OpMemberName(Member: 17, Name: "convergence_offset_x_r")]
+#[spv.OpMemberName(Member: 18, Name: "convergence_offset_x_g")]
+#[spv.OpMemberName(Member: 19, Name: "convergence_offset_x_b")]
+#[spv.OpMemberName(Member: 20, Name: "convergence_offset_y_r")]
+#[spv.OpMemberName(Member: 21, Name: "convergence_offset_y_g")]
+#[spv.OpMemberName(Member: 22, Name: "convergence_offset_y_b")]
+#[spv.OpMemberName(Member: 23, Name: "mask_type")]
+#[spv.OpMemberName(Member: 24, Name: "mask_sample_mode_desired")]
+#[spv.OpMemberName(Member: 25, Name: "mask_num_triads_desired")]
+#[spv.OpMemberName(Member: 26, Name: "mask_triad_size_desired")]
+#[spv.OpMemberName(Member: 27, Name: "mask_specify_num_triads")]
+#[spv.OpMemberName(Member: 28, Name: "aa_subpixel_r_offset_x_runtime")]
+#[spv.OpMemberName(Member: 29, Name: "aa_subpixel_r_offset_y_runtime")]
+#[spv.OpMemberName(Member: 30, Name: "aa_cubic_c")]
+#[spv.OpMemberName(Member: 31, Name: "aa_gauss_sigma")]
+#[spv.OpMemberName(Member: 32, Name: "geom_mode_runtime")]
+#[spv.OpMemberName(Member: 33, Name: "geom_radius")]
+#[spv.OpMemberName(Member: 34, Name: "geom_view_dist")]
+#[spv.OpMemberName(Member: 35, Name: "geom_tilt_angle_x")]
+#[spv.OpMemberName(Member: 36, Name: "geom_tilt_angle_y")]
+#[spv.OpMemberName(Member: 37, Name: "geom_aspect_ratio_x")]
+#[spv.OpMemberName(Member: 38, Name: "geom_aspect_ratio_y")]
+#[spv.OpMemberName(Member: 39, Name: "geom_overscan_x")]
+#[spv.OpMemberName(Member: 40, Name: "geom_overscan_y")]
+#[spv.OpMemberName(Member: 41, Name: "border_size")]
+#[spv.OpMemberName(Member: 42, Name: "border_darkness")]
+#[spv.OpMemberName(Member: 43, Name: "border_compress")]
+#[spv.OpMemberName(Member: 44, Name: "interlace_bff")]
+#[spv.OpMemberName(Member: 45, Name: "interlace_1080i")]
+#[spv.OpMemberName(Member: 46, Name: "interlace_detect_toggle")]
+#[spv.Decoration.Block]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.ColMajor)]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.MatrixStride(MatrixStride: 16))]
+#[spv.OpMemberDecorate(Member: 0, spv.Decoration.Offset(ByteOffset: 0))]
+#[spv.OpMemberDecorate(Member: 1, spv.Decoration.Offset(ByteOffset: 64))]
+#[spv.OpMemberDecorate(Member: 2, spv.Decoration.Offset(ByteOffset: 68))]
+#[spv.OpMemberDecorate(Member: 3, spv.Decoration.Offset(ByteOffset: 72))]
+#[spv.OpMemberDecorate(Member: 4, spv.Decoration.Offset(ByteOffset: 76))]
+#[spv.OpMemberDecorate(Member: 5, spv.Decoration.Offset(ByteOffset: 80))]
+#[spv.OpMemberDecorate(Member: 6, spv.Decoration.Offset(ByteOffset: 84))]
+#[spv.OpMemberDecorate(Member: 7, spv.Decoration.Offset(ByteOffset: 88))]
+#[spv.OpMemberDecorate(Member: 8, spv.Decoration.Offset(ByteOffset: 92))]
+#[spv.OpMemberDecorate(Member: 9, spv.Decoration.Offset(ByteOffset: 96))]
+#[spv.OpMemberDecorate(Member: 10, spv.Decoration.Offset(ByteOffset: 100))]
+#[spv.OpMemberDecorate(Member: 11, spv.Decoration.Offset(ByteOffset: 104))]
+#[spv.OpMemberDecorate(Member: 12, spv.Decoration.Offset(ByteOffset: 108))]
+#[spv.OpMemberDecorate(Member: 13, spv.Decoration.Offset(ByteOffset: 112))]
+#[spv.OpMemberDecorate(Member: 14, spv.Decoration.Offset(ByteOffset: 116))]
+#[spv.OpMemberDecorate(Member: 15, spv.Decoration.Offset(ByteOffset: 120))]
+#[spv.OpMemberDecorate(Member: 16, spv.Decoration.Offset(ByteOffset: 124))]
+#[spv.OpMemberDecorate(Member: 17, spv.Decoration.Offset(ByteOffset: 128))]
+#[spv.OpMemberDecorate(Member: 18, spv.Decoration.Offset(ByteOffset: 132))]
+#[spv.OpMemberDecorate(Member: 19, spv.Decoration.Offset(ByteOffset: 136))]
+#[spv.OpMemberDecorate(Member: 20, spv.Decoration.Offset(ByteOffset: 140))]
+#[spv.OpMemberDecorate(Member: 21, spv.Decoration.Offset(ByteOffset: 144))]
+#[spv.OpMemberDecorate(Member: 22, spv.Decoration.Offset(ByteOffset: 148))]
+#[spv.OpMemberDecorate(Member: 23, spv.Decoration.Offset(ByteOffset: 152))]
+#[spv.OpMemberDecorate(Member: 24, spv.Decoration.Offset(ByteOffset: 156))]
+#[spv.OpMemberDecorate(Member: 25, spv.Decoration.Offset(ByteOffset: 160))]
+#[spv.OpMemberDecorate(Member: 26, spv.Decoration.Offset(ByteOffset: 164))]
+#[spv.OpMemberDecorate(Member: 27, spv.Decoration.Offset(ByteOffset: 168))]
+#[spv.OpMemberDecorate(Member: 28, spv.Decoration.Offset(ByteOffset: 172))]
+#[spv.OpMemberDecorate(Member: 29, spv.Decoration.Offset(ByteOffset: 176))]
+#[spv.OpMemberDecorate(Member: 30, spv.Decoration.Offset(ByteOffset: 180))]
+#[spv.OpMemberDecorate(Member: 31, spv.Decoration.Offset(ByteOffset: 184))]
+#[spv.OpMemberDecorate(Member: 32, spv.Decoration.Offset(ByteOffset: 188))]
+#[spv.OpMemberDecorate(Member: 33, spv.Decoration.Offset(ByteOffset: 192))]
+#[spv.OpMemberDecorate(Member: 34, spv.Decoration.Offset(ByteOffset: 196))]
+#[spv.OpMemberDecorate(Member: 35, spv.Decoration.Offset(ByteOffset: 200))]
+#[spv.OpMemberDecorate(Member: 36, spv.Decoration.Offset(ByteOffset: 204))]
+#[spv.OpMemberDecorate(Member: 37, spv.Decoration.Offset(ByteOffset: 208))]
+#[spv.OpMemberDecorate(Member: 38, spv.Decoration.Offset(ByteOffset: 212))]
+#[spv.OpMemberDecorate(Member: 39, spv.Decoration.Offset(ByteOffset: 216))]
+#[spv.OpMemberDecorate(Member: 40, spv.Decoration.Offset(ByteOffset: 220))]
+#[spv.OpMemberDecorate(Member: 41, spv.Decoration.Offset(ByteOffset: 224))]
+#[spv.OpMemberDecorate(Member: 42, spv.Decoration.Offset(ByteOffset: 228))]
+#[spv.OpMemberDecorate(Member: 43, spv.Decoration.Offset(ByteOffset: 232))]
+#[spv.OpMemberDecorate(Member: 44, spv.Decoration.Offset(ByteOffset: 236))]
+#[spv.OpMemberDecorate(Member: 45, spv.Decoration.Offset(ByteOffset: 240))]
+#[spv.OpMemberDecorate(Member: 46, spv.Decoration.Offset(ByteOffset: 244))]
+type T`UBO` = spv.OpTypeStruct(
+  spv.OpTypeMatrix(ColumnType: f32×4, ColumnCount: 4),
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+  f32,
+)
+
+type T6 = spv.OpTypeImage(SampledType: f32, spv.Dim.2D, Depth: 0, Arrayed: 0, MS: 0, Sampled: 1, spv.ImageFormat.Unknown)
+
+type T7 = spv.OpTypeSampledImage(ImageType: T6)
+
+type T8 = spv.OpTypePointer(spv.StorageClass.UniformConstant, T7)
+
+type T9 = spv.OpTypePointer(spv.StorageClass.UniformConstant, spv.OpTypeSampler)
+
+#[spv.Decoration.Location(Location: 1)]
+global_var GV`scanline_tex_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 4)]
+global_var GV`scanline_texture_size_inv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 0)]
+global_var GV`video_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 6)]
+global_var GV`mask_tiles_per_screen`(spv.StorageClass.Input): f32×2
+
+#[name = "mask_tile_start_uv_and_size"]
+#[spv.Decoration.Location(Location: 5)]
+global_var GV0(spv.StorageClass.Input): f32×4
+
+#[spv.Decoration.Location(Location: 3)]
+global_var GV`halation_tex_uv`(spv.StorageClass.Input): f32×2
+
+#[spv.Decoration.Location(Location: 0)]
+global_var GV`FragColor`(spv.StorageClass.Output): f32×4
+
+#[spv.Decoration.Location(Location: 2)]
+global_var GV`blur3x3_tex_uv`(spv.StorageClass.Input): f32×2
+
+global_var GV`params`(spv.StorageClass.PushConstant): T`Push`
+
+global_var GV`bloom_approx_scale_x`(spv.StorageClass.Private): f32
+
+global_var GV`crt_gamma_static`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_gamma_static`(spv.StorageClass.Private): f32
+
+global_var GV`levels_contrast_static`(spv.StorageClass.Private): f32
+
+global_var GV`levels_autodim_temp`(spv.StorageClass.Private): f32
+
+global_var GV`halation_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`diffusion_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_underestimate_levels_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_excess_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_filter_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_num_scanlines`(spv.StorageClass.Private): f32
+
+global_var GV`beam_generalized_gaussian`(spv.StorageClass.Private): bool
+
+global_var GV`beam_antialias_level`(spv.StorageClass.Private): f32
+
+global_var GV`beam_min_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_max_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_spot_shape_function`(spv.StorageClass.Private): f32
+
+global_var GV`beam_spot_power_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_min_shape_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_max_shape_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_shape_power_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_filter_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_horiz_linear_rgb_weight_static`(spv.StorageClass.Private): f32
+
+global_var GV`beam_misconvergence`(spv.StorageClass.Private): bool
+
+global_var GV`convergence_offsets_r_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`convergence_offsets_g_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`convergence_offsets_b_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`interlace_detect_static`(spv.StorageClass.Private): bool
+
+global_var GV`interlace_1080i_static`(spv.StorageClass.Private): bool
+
+global_var GV`interlace_bff_static`(spv.StorageClass.Private): bool
+
+global_var GV`aa_level`(spv.StorageClass.Private): f32
+
+global_var GV`aa_filter`(spv.StorageClass.Private): f32
+
+global_var GV`aa_temporal`(spv.StorageClass.Private): bool
+
+global_var GV`aa_subpixel_r_offset_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`aa_cubic_c_static`(spv.StorageClass.Private): f32
+
+global_var GV`aa_gauss_sigma_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_type_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_sample_mode_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_specify_num_triads_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_triad_size_desired_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_num_triads_desired_static`(spv.StorageClass.Private): f32
+
+global_var GV`mask_sinc_lobes`(spv.StorageClass.Private): f32
+
+global_var GV`mask_min_allowed_triad_size`(spv.StorageClass.Private): f32
+
+global_var GV`geom_mode_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_radius_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_view_dist_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_tilt_angle_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_aspect_ratio_static`(spv.StorageClass.Private): f32
+
+global_var GV`geom_overscan_static`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_force_correct_tangent_matrix`(spv.StorageClass.Private): bool
+
+global_var GV`border_size_static`(spv.StorageClass.Private): f32
+
+global_var GV`border_darkness_static`(spv.StorageClass.Private): f32
+
+global_var GV`border_compress_static`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_size_x`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_size_x_for_fake`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_viewport_scale`(spv.StorageClass.Private): f32×2
+
+global_var GV`geom_max_aspect_ratio`(spv.StorageClass.Private): f32
+
+global_var GV`mask_texture_small_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`mask_texture_large_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`mask_triads_per_tile`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille14_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille15_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_slot_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_shadow_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`mask_grille_avg_color`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_approx_filter`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_src_lut_size`(spv.StorageClass.Private): f32×2
+
+global_var GV`max_aa_base_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_aniso_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_tiled_pixel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_mask_texel_border`(spv.StorageClass.Private): f32
+
+global_var GV`max_mask_tile_border`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_num_tiles`(spv.StorageClass.Private): f32
+
+global_var GV`mask_start_texels`(spv.StorageClass.Private): f32
+
+global_var GV`mask_resize_num_triads`(spv.StorageClass.Private): f32
+
+global_var GV`min_allowed_viewport_triads`(spv.StorageClass.Private): f32×2
+
+global_var GV`pi`(spv.StorageClass.Private): f32
+
+global_var GV`under_half`(spv.StorageClass.Private): f32
+
+global_var GV`gba_gamma`(spv.StorageClass.Private): f32
+
+#[spv.Decoration.Binding(BindingPoint: 0)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`global`(spv.StorageClass.Uniform): T`UBO`
+
+global_var GV`interlace_detect`(spv.StorageClass.Private): bool
+
+global_var GV`ntsc_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`pal_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`crt_reference_gamma_high`(spv.StorageClass.Private): f32
+
+global_var GV`crt_reference_gamma_low`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_reference_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`crt_office_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`lcd_office_gamma`(spv.StorageClass.Private): f32
+
+global_var GV`assume_opaque_alpha`(spv.StorageClass.Private): bool
+
+global_var GV`linearize_input`(spv.StorageClass.Private): bool
+
+global_var GV`gamma_encode_output`(spv.StorageClass.Private): bool
+
+global_var GV`gamma_aware_bilinear`(spv.StorageClass.Private): bool
+
+global_var GV`mask_min_allowed_tile_size`(spv.StorageClass.Private): f32
+
+global_var GV`mask_min_expected_tile_size`(spv.StorageClass.Private): f32
+
+global_var GV`pi_over_lobes`(spv.StorageClass.Private): f32
+
+global_var GV`max_sinc_resize_samples_float`(spv.StorageClass.Private): f32
+
+global_var GV`max_sinc_resize_samples_m4`(spv.StorageClass.Private): f32
+
+global_var GV`blur3_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur4_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur5_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur6_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur7_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur8_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur9_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur10_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur11_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur12_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur17_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur25_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur31_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`blur43_std_dev`(spv.StorageClass.Private): f32
+
+global_var GV`error_blurring`(spv.StorageClass.Private): f32
+
+global_var GV`bloom_diff_thresh`(spv.StorageClass.Private): f32
+
+func F`get_convergence_offsets_x_vector(`() -> f32×3 {
+  v0 = spv.OpAccessChain(Base: &GV`global`, 17s32): T5
+  v1 = spv.OpLoad(Pointer: v0): f32
+  v2 = spv.OpAccessChain(Base: &GV`global`, 18s32): T5
+  v3 = spv.OpLoad(Pointer: v2): f32
+  v4 = spv.OpAccessChain(Base: &GV`global`, 19s32): T5
+  v5 = spv.OpLoad(Pointer: v4): f32
+  v6 = vec.new(v1, v3, v5): f32×3
+  v6
+}
+
+func F`get_intermediate_gamma(`() -> f32 {
+  v0 = spv.OpLoad(Pointer: &GV`ntsc_gamma`): f32
+  v0
+}
+
+func F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(
+  #[name = "color0"]
+  v0: T0,
+  #[name = "color1"]
+  v1: T0,
+  #[name = "color2"]
+  v2: T0,
+  #[name = "color3"]
+  v3: T0,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+  v5 = spv.OpLoad(Pointer: v0): f32×3
+  v6 = spv.OpLoad(Pointer: v1): f32×3
+  v7 = spv.OpLoad(Pointer: v2): f32×3
+  v8 = spv.OpLoad(Pointer: v3): f32×3
+  v9 = vec.extract(v5, 0): f32
+  v10 = vec.extract(v5, 1): f32
+  v11 = vec.extract(v5, 2): f32
+  v12 = vec.extract(v6, 0): f32
+  v13 = vec.extract(v6, 1): f32
+  v14 = vec.extract(v6, 2): f32
+  v15 = vec.extract(v7, 0): f32
+  v16 = vec.extract(v7, 1): f32
+  v17 = vec.extract(v7, 2): f32
+  v18 = vec.extract(v8, 0): f32
+  v19 = vec.extract(v8, 1): f32
+  v20 = vec.extract(v8, 2): f32
+  v21 = vec.new(v9, v10, v11): f32×3
+  v22 = vec.new(v12, v13, v14): f32×3
+  v23 = vec.new(v15, v16, v17): f32×3
+  v24 = vec.new(v18, v19, v20): f32×3
+  v25 = vec.new(v21, v22, v23, v24): spv.OpTypeMatrix(ColumnType: f32×3, ColumnCount: 4)
+  v26 = spv.OpLoad(Pointer: v4): f32×4
+  v27 = spv.OpMatrixTimesVector(Matrix: v25, Vector: v26): f32×3
+  v28 = vec.new(0.0f32, 0.0f32, 0.0f32): f32×3
+  v29 = spv.extinst."GLSL.std.450".FMax(X: v27, Y: v28): f32×3
+  v29
+}
+
+func F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(
+  #[name = "color0"]
+  v0: T0,
+  #[name = "color1"]
+  v1: T0,
+  #[name = "color2"]
+  v2: T0,
+  #[name = "color3"]
+  v3: T0,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+  v`intermediate_gamma` = spv.OpVariable(spv.StorageClass.Function): T2
+  v`linear_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v5 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v6 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v7 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v8 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v9 = spv.OpVariable(spv.StorageClass.Function): T3
+  v`gamma_mixed_color` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v10 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v11 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v12 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v13 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v14 = spv.OpVariable(spv.StorageClass.Function): T3
+  v15 = call F`get_intermediate_gamma(`(): f32
+  spv.OpStore(Pointer: v`intermediate_gamma`, Object: v15)
+  v16 = spv.OpLoad(Pointer: v0): f32×3
+  spv.OpStore(Pointer: v5, Object: v16)
+  v17 = spv.OpLoad(Pointer: v1): f32×3
+  spv.OpStore(Pointer: v6, Object: v17)
+  v18 = spv.OpLoad(Pointer: v2): f32×3
+  spv.OpStore(Pointer: v7, Object: v18)
+  v19 = spv.OpLoad(Pointer: v3): f32×3
+  spv.OpStore(Pointer: v8, Object: v19)
+  v20 = spv.OpLoad(Pointer: v4): f32×4
+  spv.OpStore(Pointer: v9, Object: v20)
+  v21 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v5, v6, v7, v8, v9): f32×3
+  spv.OpStore(Pointer: v`linear_mixed_color`, Object: v21)
+  v22 = spv.OpLoad(Pointer: v0): f32×3
+  v23 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+  v24 = f.div(1.0f32, v23): f32
+  v25 = vec.new(v24, v24, v24): f32×3
+  v26 = spv.extinst."GLSL.std.450".Pow(X: v22, Y: v25): f32×3
+  v27 = spv.OpLoad(Pointer: v1): f32×3
+  v28 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+  v29 = f.div(1.0f32, v28): f32
+  v30 = vec.new(v29, v29, v29): f32×3
+  v31 = spv.extinst."GLSL.std.450".Pow(X: v27, Y: v30): f32×3
+  v32 = spv.OpLoad(Pointer: v2): f32×3
+  v33 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+  v34 = f.div(1.0f32, v33): f32
+  v35 = vec.new(v34, v34, v34): f32×3
+  v36 = spv.extinst."GLSL.std.450".Pow(X: v32, Y: v35): f32×3
+  v37 = spv.OpLoad(Pointer: v3): f32×3
+  v38 = spv.OpLoad(Pointer: v`intermediate_gamma`): f32
+  v39 = f.div(1.0f32, v38): f32
+  v40 = vec.new(v39, v39, v39): f32×3
+  v41 = spv.extinst."GLSL.std.450".Pow(X: v37, Y: v40): f32×3
+  spv.OpStore(Pointer: v10, Object: v26)
+  spv.OpStore(Pointer: v11, Object: v31)
+  spv.OpStore(Pointer: v12, Object: v36)
+  spv.OpStore(Pointer: v13, Object: v41)
+  v42 = spv.OpLoad(Pointer: v4): f32×4
+  spv.OpStore(Pointer: v14, Object: v42)
+  v43 = call F`get_raw_interpolated_color(vf3;vf3;vf3;vf3;vf4;`(v10, v11, v12, v13, v14): f32×3
+  spv.OpStore(Pointer: v`gamma_mixed_color`, Object: v43)
+  v44 = spv.OpLoad(Pointer: v`gamma_mixed_color`): f32×3
+  v45 = spv.OpLoad(Pointer: v`linear_mixed_color`): f32×3
+  v46 = spv.OpAccessChain(Base: &GV`global`, 16s32): T5
+  v47 = spv.OpLoad(Pointer: v46): f32
+  v48 = vec.new(v47, v47, v47): f32×3
+  v49 = spv.extinst."GLSL.std.450".FMix(X: v44, Y: v45, A: v48): f32×3
+  v49
+}
+
+func F`get_scanline_color(s21;vf2;vf2;vf4;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "scanline_uv"]
+  v2: T1,
+  #[name = "uv_step_x"]
+  v3: T1,
+  #[name = "weights"]
+  v4: T3,
+) -> f32×3 {
+  #[name = "color1"]
+  v5 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "color2"]
+  v6 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "color0"]
+  v7 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "color3"]
+  v8 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v9 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v10 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v11 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v12 = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v13 = spv.OpVariable(spv.StorageClass.Function): T3
+  v14 = spv.OpLoad(Pointer: v0): T6
+  v15 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+  v16 = spv.OpSampledImage(Image: v14, Sampler: v15): T7
+  v17 = spv.OpLoad(Pointer: v2): f32×2
+  v18 = spv.OpImageSampleImplicitLod(SampledImage: v16, Coordinate: v17): f32×4
+  v19 = spv.OpVectorShuffle(Vector1: v18, Vector2: v18, 0, 1, 2): f32×3
+  spv.OpStore(Pointer: v5, Object: v19)
+  v20 = spv.OpLoad(Pointer: v0): T6
+  v21 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+  v22 = spv.OpSampledImage(Image: v20, Sampler: v21): T7
+  v23 = spv.OpLoad(Pointer: v2): f32×2
+  v24 = spv.OpLoad(Pointer: v3): f32×2
+  v25 = vec.distribute(f.add)(v23, v24): f32×2
+  v26 = spv.OpImageSampleImplicitLod(SampledImage: v22, Coordinate: v25): f32×4
+  v27 = spv.OpVectorShuffle(Vector1: v26, Vector2: v26, 0, 1, 2): f32×3
+  spv.OpStore(Pointer: v6, Object: v27)
+  spv.OpStore(Pointer: v7, Object: f32×3(0.0, 0.0, 0.0))
+  spv.OpStore(Pointer: v8, Object: f32×3(0.0, 0.0, 0.0))
+  v28 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+  v29 = spv.OpLoad(Pointer: v28): f32
+  v30 = f.gt(v29, 0.5f32): bool
+  if v30 {
+    v37 = spv.OpLoad(Pointer: v0): T6
+    v38 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v39 = spv.OpSampledImage(Image: v37, Sampler: v38): T7
+    v40 = spv.OpLoad(Pointer: v2): f32×2
+    v41 = spv.OpLoad(Pointer: v3): f32×2
+    v42 = vec.distribute(f.sub)(v40, v41): f32×2
+    v43 = spv.OpImageSampleImplicitLod(SampledImage: v39, Coordinate: v42): f32×4
+    v44 = spv.OpVectorShuffle(Vector1: v43, Vector2: v43, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v7, Object: v44)
+    v45 = spv.OpLoad(Pointer: v0): T6
+    v46 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+    v47 = spv.OpSampledImage(Image: v45, Sampler: v46): T7
+    v48 = spv.OpLoad(Pointer: v2): f32×2
+    v49 = spv.OpLoad(Pointer: v3): f32×2
+    v50 = vec.mul(v49, 2.0f32): f32×2
+    v51 = vec.distribute(f.add)(v48, v50): f32×2
+    v52 = spv.OpImageSampleImplicitLod(SampledImage: v47, Coordinate: v51): f32×4
+    v53 = spv.OpVectorShuffle(Vector1: v52, Vector2: v52, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v8, Object: v53)
+  } else {
+  }
+  v31 = spv.OpLoad(Pointer: v7): f32×3
+  spv.OpStore(Pointer: v9, Object: v31)
+  v32 = spv.OpLoad(Pointer: v5): f32×3
+  spv.OpStore(Pointer: v10, Object: v32)
+  v33 = spv.OpLoad(Pointer: v6): f32×3
+  spv.OpStore(Pointer: v11, Object: v33)
+  v34 = spv.OpLoad(Pointer: v8): f32×3
+  spv.OpStore(Pointer: v12, Object: v34)
+  v35 = spv.OpLoad(Pointer: v4): f32×4
+  spv.OpStore(Pointer: v13, Object: v35)
+  v36 = call F`get_interpolated_linear_color(vf3;vf3;vf3;vf3;vf4;`(v9, v10, v11, v12, v13): f32×3
+  v36
+}
+
+func F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+  #[name = "tex_size"]
+  v3: T1,
+  #[name = "texture_size_inv"]
+  v4: T1,
+) -> f32×3 {
+  v`curr_texel` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`prev_texel` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`prev_texel_hor` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`prev_texel_hor_uv` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`prev_dist` = spv.OpVariable(spv.StorageClass.Function): T2
+  v`sample_dists` = spv.OpVariable(spv.StorageClass.Function): T3
+  v`x` = spv.OpVariable(spv.StorageClass.Function): T2
+  v`w2` = spv.OpVariable(spv.StorageClass.Function): T2
+  #[name = "weights"]
+  v5 = spv.OpVariable(spv.StorageClass.Function): T3
+  v`inner_denom_inv` = spv.OpVariable(spv.StorageClass.Function): T2
+  v`pi_dists` = spv.OpVariable(spv.StorageClass.Function): T3
+  v`final_weights` = spv.OpVariable(spv.StorageClass.Function): T3
+  #[name = "uv_step_x"]
+  v6 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v7 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v8 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v9 = spv.OpVariable(spv.StorageClass.Function): T3
+  v10 = spv.OpLoad(Pointer: v2): f32×2
+  v11 = spv.OpLoad(Pointer: v3): f32×2
+  v12 = vec.distribute(f.mul)(v10, v11): f32×2
+  spv.OpStore(Pointer: v`curr_texel`, Object: v12)
+  v13 = spv.OpLoad(Pointer: v`curr_texel`): f32×2
+  v14 = spv.OpLoad(Pointer: &GV`under_half`): f32
+  v15 = vec.new(v14, v14): f32×2
+  v16 = vec.distribute(f.sub)(v13, v15): f32×2
+  v17 = spv.extinst."GLSL.std.450".Floor(X: v16): f32×2
+  v18 = vec.distribute(f.add)(v17, f32×2(0.5, 0.5)): f32×2
+  spv.OpStore(Pointer: v`prev_texel`, Object: v18)
+  v19 = spv.OpAccessChain(Base: v`prev_texel`, 0u32): T2
+  v20 = spv.OpLoad(Pointer: v19): f32
+  v21 = spv.OpAccessChain(Base: v`curr_texel`, 1u32): T2
+  v22 = spv.OpLoad(Pointer: v21): f32
+  v23 = vec.new(v20, v22): f32×2
+  spv.OpStore(Pointer: v`prev_texel_hor`, Object: v23)
+  v24 = spv.OpLoad(Pointer: v`prev_texel_hor`): f32×2
+  v25 = spv.OpLoad(Pointer: v4): f32×2
+  v26 = vec.distribute(f.mul)(v24, v25): f32×2
+  spv.OpStore(Pointer: v`prev_texel_hor_uv`, Object: v26)
+  v27 = spv.OpAccessChain(Base: v`curr_texel`, 0u32): T2
+  v28 = spv.OpLoad(Pointer: v27): f32
+  v29 = spv.OpAccessChain(Base: v`prev_texel_hor`, 0u32): T2
+  v30 = spv.OpLoad(Pointer: v29): f32
+  v31 = f.sub(v28, v30): f32
+  spv.OpStore(Pointer: v`prev_dist`, Object: v31)
+  v32 = spv.OpLoad(Pointer: v`prev_dist`): f32
+  v33 = f.add(1.0f32, v32): f32
+  v34 = spv.OpLoad(Pointer: v`prev_dist`): f32
+  v35 = spv.OpLoad(Pointer: v`prev_dist`): f32
+  v36 = f.sub(1.0f32, v35): f32
+  v37 = spv.OpLoad(Pointer: v`prev_dist`): f32
+  v38 = f.sub(2.0f32, v37): f32
+  v39 = vec.new(v33, v34, v36, v38): f32×4
+  spv.OpStore(Pointer: v`sample_dists`, Object: v39)
+  v40 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+  v41 = spv.OpLoad(Pointer: v40): f32
+  v42 = f.lt(v41, 0.5f32): bool
+  if v42 {
+    v55 = spv.OpAccessChain(Base: v`sample_dists`, 1u32): T2
+    v56 = spv.OpLoad(Pointer: v55): f32
+    spv.OpStore(Pointer: v`x`, Object: v56)
+    v57 = spv.OpLoad(Pointer: v`x`): f32
+    v58 = spv.OpLoad(Pointer: v`x`): f32
+    v59 = f.mul(v57, v58): f32
+    v60 = spv.OpLoad(Pointer: v`x`): f32
+    v61 = f.mul(v59, v60): f32
+    v62 = spv.OpLoad(Pointer: v`x`): f32
+    v63 = spv.OpLoad(Pointer: v`x`): f32
+    v64 = f.mul(v63, 6.0f32): f32
+    v65 = f.sub(v64, 15.0f32): f32
+    v66 = f.mul(v62, v65): f32
+    v67 = f.add(v66, 10.0f32): f32
+    v68 = f.mul(v61, v67): f32
+    spv.OpStore(Pointer: v`w2`, Object: v68)
+    v69 = spv.OpLoad(Pointer: v`w2`): f32
+    v70 = f.sub(1.0f32, v69): f32
+    v71 = spv.OpLoad(Pointer: v`w2`): f32
+    v72 = vec.new(0.0f32, v70, v71, 0.0f32): f32×4
+    spv.OpStore(Pointer: v5, Object: v72)
+  } else {
+    v73 = spv.OpAccessChain(Base: &GV`global`, 14s32): T5
+    v74 = spv.OpLoad(Pointer: v73): f32
+    v75 = f.lt(v74, 1.5f32): bool
+    if v75 {
+      v76 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5
+      v77 = spv.OpLoad(Pointer: v76): f32
+      v78 = f.mul(2.0f32, v77): f32
+      v79 = spv.OpAccessChain(Base: &GV`global`, 15s32): T5
+      v80 = spv.OpLoad(Pointer: v79): f32
+      v81 = f.mul(v78, v80): f32
+      v82 = f.div(1.0f32, v81): f32
+      spv.OpStore(Pointer: v`inner_denom_inv`, Object: v82)
+      v83 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+      v84 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+      v85 = vec.distribute(f.mul)(v83, v84): f32×4
+      v86 = vec.distribute(f.neg)(v85): f32×4
+      v87 = spv.OpLoad(Pointer: v`inner_denom_inv`): f32
+      v88 = vec.mul(v86, v87): f32×4
+      v89 = spv.extinst."GLSL.std.450".Exp(X: v88): f32×4
+      spv.OpStore(Pointer: v5, Object: v89)
+    } else {
+      v90 = spv.OpLoad(Pointer: v`sample_dists`): f32×4
+      v91 = spv.OpLoad(Pointer: &GV`pi`): f32
+      v92 = vec.mul(v90, v91): f32×4
+      v93 = spv.extinst."GLSL.std.450".FAbs(X: v92): f32×4
+      v94 = vec.new(1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32, 1.5258789e-5f32): f32×4
+      v95 = spv.extinst."GLSL.std.450".FMax(X: v93, Y: v94): f32×4
+      spv.OpStore(Pointer: v`pi_dists`, Object: v95)
+      v96 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+      v97 = spv.extinst."GLSL.std.450".Sin(X: v96): f32×4
+      v98 = vec.mul(v97, 2.0f32): f32×4
+      v99 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+      v100 = vec.mul(v99, 0.5f32): f32×4
+      v101 = spv.extinst."GLSL.std.450".Sin(X: v100): f32×4
+      v102 = vec.distribute(f.mul)(v98, v101): f32×4
+      v103 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+      v104 = spv.OpLoad(Pointer: v`pi_dists`): f32×4
+      v105 = vec.distribute(f.mul)(v103, v104): f32×4
+      v106 = vec.distribute(f.div)(v102, v105): f32×4
+      spv.OpStore(Pointer: v5, Object: v106)
+    }
+  }
+  v43 = spv.OpLoad(Pointer: v5): f32×4
+  v44 = spv.OpLoad(Pointer: v5): f32×4
+  v45 = vec.dot(v44, f32×4(1.0, 1.0, 1.0, 1.0)): f32
+  v46 = vec.new(v45, v45, v45, v45): f32×4
+  v47 = vec.distribute(f.div)(v43, v46): f32×4
+  spv.OpStore(Pointer: v`final_weights`, Object: v47)
+  v48 = spv.OpAccessChain(Base: v4, 0u32): T2
+  v49 = spv.OpLoad(Pointer: v48): f32
+  v50 = vec.new(v49, 0.0f32): f32×2
+  spv.OpStore(Pointer: v6, Object: v50)
+  v51 = spv.OpLoad(Pointer: v`prev_texel_hor_uv`): f32×2
+  spv.OpStore(Pointer: v7, Object: v51)
+  v52 = spv.OpLoad(Pointer: v6): f32×2
+  spv.OpStore(Pointer: v8, Object: v52)
+  v53 = spv.OpLoad(Pointer: v`final_weights`): f32×4
+  spv.OpStore(Pointer: v9, Object: v53)
+  v54 = call F`get_scanline_color(s21;vf2;vf2;vf4;`(v0, v1, v7, v8, v9): f32×3
+  v54
+}
+
+func F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+  #[name = "tex_size"]
+  v3: T1,
+  #[name = "texture_size_inv"]
+  v4: T1,
+) -> f32×3 {
+  v`convergence_offsets_rgb` = spv.OpVariable(spv.StorageClass.Function): T0
+  v`offset_u_rgb` = spv.OpVariable(spv.StorageClass.Function): T0
+  v`scanline_uv_r` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`scanline_uv_g` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`scanline_uv_b` = spv.OpVariable(spv.StorageClass.Function): T1
+  v`sample_r` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v5 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v6 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v7 = spv.OpVariable(spv.StorageClass.Function): T1
+  v`sample_g` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v8 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v9 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v10 = spv.OpVariable(spv.StorageClass.Function): T1
+  v`sample_b` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v11 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v12 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v13 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v14 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v15 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v16 = spv.OpVariable(spv.StorageClass.Function): T1
+  v17 = spv.OpLoad(Pointer: &GV`beam_misconvergence`): bool
+  v18: f32×3 = if v17 {
+    v19 = call F`get_convergence_offsets_x_vector(`(): f32×3
+    spv.OpStore(Pointer: v`convergence_offsets_rgb`, Object: v19)
+    v20 = spv.OpLoad(Pointer: v`convergence_offsets_rgb`): f32×3
+    v21 = spv.OpLoad(Pointer: v4): f32×2
+    v22 = spv.OpVectorShuffle(Vector1: v21, Vector2: v21, 0, 0, 0): f32×3
+    v23 = vec.distribute(f.mul)(v20, v22): f32×3
+    spv.OpStore(Pointer: v`offset_u_rgb`, Object: v23)
+    v24 = spv.OpLoad(Pointer: v2): f32×2
+    v25 = spv.OpAccessChain(Base: v`offset_u_rgb`, 0u32): T2
+    v26 = spv.OpLoad(Pointer: v25): f32
+    v27 = vec.new(v26, 0.0f32): f32×2
+    v28 = vec.distribute(f.sub)(v24, v27): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_r`, Object: v28)
+    v29 = spv.OpLoad(Pointer: v2): f32×2
+    v30 = spv.OpAccessChain(Base: v`offset_u_rgb`, 1u32): T2
+    v31 = spv.OpLoad(Pointer: v30): f32
+    v32 = vec.new(v31, 0.0f32): f32×2
+    v33 = vec.distribute(f.sub)(v29, v32): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_g`, Object: v33)
+    v34 = spv.OpLoad(Pointer: v2): f32×2
+    v35 = spv.OpAccessChain(Base: v`offset_u_rgb`, 2u32): T2
+    v36 = spv.OpLoad(Pointer: v35): f32
+    v37 = vec.new(v36, 0.0f32): f32×2
+    v38 = vec.distribute(f.sub)(v34, v37): f32×2
+    spv.OpStore(Pointer: v`scanline_uv_b`, Object: v38)
+    v39 = spv.OpLoad(Pointer: v`scanline_uv_r`): f32×2
+    spv.OpStore(Pointer: v5, Object: v39)
+    v40 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v6, Object: v40)
+    v41 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v7, Object: v41)
+    v42 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v5, v6, v7): f32×3
+    spv.OpStore(Pointer: v`sample_r`, Object: v42)
+    v43 = spv.OpLoad(Pointer: v`scanline_uv_g`): f32×2
+    spv.OpStore(Pointer: v8, Object: v43)
+    v44 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v9, Object: v44)
+    v45 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v10, Object: v45)
+    v46 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v8, v9, v10): f32×3
+    spv.OpStore(Pointer: v`sample_g`, Object: v46)
+    v47 = spv.OpLoad(Pointer: v`scanline_uv_b`): f32×2
+    spv.OpStore(Pointer: v11, Object: v47)
+    v48 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v12, Object: v48)
+    v49 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v13, Object: v49)
+    v50 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v11, v12, v13): f32×3
+    spv.OpStore(Pointer: v`sample_b`, Object: v50)
+    v51 = spv.OpAccessChain(Base: v`sample_r`, 0u32): T2
+    v52 = spv.OpLoad(Pointer: v51): f32
+    v53 = spv.OpAccessChain(Base: v`sample_g`, 1u32): T2
+    v54 = spv.OpLoad(Pointer: v53): f32
+    v55 = spv.OpAccessChain(Base: v`sample_b`, 2u32): T2
+    v56 = spv.OpLoad(Pointer: v55): f32
+    v57 = vec.new(v52, v54, v56): f32×3
+    v57
+  } else {
+    v58 = spv.OpLoad(Pointer: v2): f32×2
+    spv.OpStore(Pointer: v14, Object: v58)
+    v59 = spv.OpLoad(Pointer: v3): f32×2
+    spv.OpStore(Pointer: v15, Object: v59)
+    v60 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v16, Object: v60)
+    v61 = call F`sample_single_scanline_horizontal(s21;vf2;vf2;vf2;`(v0, v1, v14, v15, v16): f32×3
+    v61
+  }
+  v18
+}
+
+#[spv.Decoration.Binding(BindingPoint: 6)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`VERTICAL_SCANLINES`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 6)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_VERTICAL_SCANLINES_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`get_mask_sample_mode(`() -> f32 {
+  v0 = spv.OpAccessChain(Base: &GV`global`, 24s32): T5
+  v1 = spv.OpLoad(Pointer: v0): f32
+  v1
+}
+
+func F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(
+  #[name = "tile_uv_wrap"]
+  v0: T1,
+  #[name = "mask_tile_start_uv_and_size"]
+  v1: T3,
+) -> f32×2 {
+  v`tile_uv` = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "mask_tex_uv"]
+  v2 = spv.OpVariable(spv.StorageClass.Function): T1
+  v3 = call F`get_mask_sample_mode(`(): f32
+  v4 = f.lt(v3, 0.5f32): bool
+  v5: f32×2 = if v4 {
+    v6 = spv.OpLoad(Pointer: v0): f32×2
+    v7 = vec.mul(v6, 0.5f32): f32×2
+    v8 = spv.extinst."GLSL.std.450".Fract(X: v7): f32×2
+    v9 = vec.mul(v8, 2.0f32): f32×2
+    spv.OpStore(Pointer: v`tile_uv`, Object: v9)
+    v10 = spv.OpLoad(Pointer: v1): f32×4
+    v11 = spv.OpVectorShuffle(Vector1: v10, Vector2: v10, 0, 1): f32×2
+    v12 = spv.OpLoad(Pointer: v`tile_uv`): f32×2
+    v13 = spv.OpLoad(Pointer: v1): f32×4
+    v14 = spv.OpVectorShuffle(Vector1: v13, Vector2: v13, 2, 3): f32×2
+    v15 = vec.distribute(f.mul)(v12, v14): f32×2
+    v16 = vec.distribute(f.add)(v11, v15): f32×2
+    spv.OpStore(Pointer: v2, Object: v16)
+    v17 = spv.OpLoad(Pointer: v2): f32×2
+    v17
+  } else {
+    v18 = spv.OpLoad(Pointer: v0): f32×2
+    v18
+  }
+  v5
+}
+
+func F`get_pass_input_gamma(`() -> f32 {
+  1.0f32
+}
+
+func F`decode_input(vf4;`(
+  #[name = "color"]
+  v0: T3,
+) -> f32×4 {
+  v1 = spv.OpLoad(Pointer: &GV`linearize_input`): bool
+  v2: f32×4 = if v1 {
+    v3 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool
+    v4: f32×4 = if v3 {
+      v5 = spv.OpLoad(Pointer: v0): f32×4
+      v6 = spv.OpVectorShuffle(Vector1: v5, Vector2: v5, 0, 1, 2): f32×3
+      v7 = call F`get_pass_input_gamma(`(): f32
+      v8 = vec.new(v7, v7, v7): f32×3
+      v9 = spv.extinst."GLSL.std.450".Pow(X: v6, Y: v8): f32×3
+      v10 = vec.extract(v9, 0): f32
+      v11 = vec.extract(v9, 1): f32
+      v12 = vec.extract(v9, 2): f32
+      v13 = vec.new(v10, v11, v12, 1.0f32): f32×4
+      v13
+    } else {
+      v14 = spv.OpLoad(Pointer: v0): f32×4
+      v15 = spv.OpVectorShuffle(Vector1: v14, Vector2: v14, 0, 1, 2): f32×3
+      v16 = call F`get_pass_input_gamma(`(): f32
+      v17 = vec.new(v16, v16, v16): f32×3
+      v18 = spv.extinst."GLSL.std.450".Pow(X: v15, Y: v17): f32×3
+      v19 = spv.OpAccessChain(Base: v0, 3u32): T2
+      v20 = spv.OpLoad(Pointer: v19): f32
+      v21 = vec.extract(v18, 0): f32
+      v22 = vec.extract(v18, 1): f32
+      v23 = vec.extract(v18, 2): f32
+      v24 = vec.new(v21, v22, v23, v20): f32×4
+      v24
+    }
+    v4
+  } else {
+    v25 = spv.OpLoad(Pointer: v0): f32×4
+    v25
+  }
+  v2
+}
+
+func F`tex2D_linearize(s21;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  v2: T9,
+  #[name = "tex_coords"]
+  v3: T1,
+) -> f32×4 {
+  #[name = "param"]
+  v4 = spv.OpVariable(spv.StorageClass.Function): T3
+  v5 = spv.OpLoad(Pointer: v0): T6
+  v6 = spv.OpLoad(Pointer: v1): spv.OpTypeSampler
+  v7 = spv.OpSampledImage(Image: v5, Sampler: v6): T7
+  v8 = spv.OpLoad(Pointer: v2): spv.OpTypeSampler
+  v9 = spv.OpSampledImage(Image: v7, Sampler: v8): T7
+  v10 = spv.OpLoad(Pointer: v3): f32×2
+  v11 = spv.OpImageSampleImplicitLod(SampledImage: v9, Coordinate: v10): f32×4
+  spv.OpStore(Pointer: v4, Object: v11)
+  v12 = call F`decode_input(vf4;`(v4): f32×4
+  v12
+}
+
+#[spv.Decoration.Binding(BindingPoint: 3)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_grille_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 3)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_grille_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 4)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_slot_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 4)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_slot_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 5)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`mask_shadow_texture_large`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 5)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_mask_shadow_texture_large_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`tex2Dtiled_mask_linearize(s21;vf2;`(
+  #[name = "tex"]
+  v0: T8,
+  v1: T9,
+  #[name = "tex_uv"]
+  v2: T1,
+) -> f32×4 {
+  #[name = "param"]
+  v3 = spv.OpVariable(spv.StorageClass.Function): T1
+  v4 = spv.OpLoad(Pointer: v2): f32×2
+  spv.OpStore(Pointer: v3, Object: v4)
+  v5 = call F`tex2D_linearize(s21;vf2;`(v0, v1, v3): f32×4
+  v5
+}
+
+#[spv.Decoration.Binding(BindingPoint: 9)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`MASK_RESIZE`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 9)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_MASK_RESIZE_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+#[spv.Decoration.Binding(BindingPoint: 8)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`HALATION_BLUR`(spv.StorageClass.UniformConstant): T7
+
+#[spv.Decoration.Binding(BindingPoint: 8)]
+#[spv.Decoration.DescriptorSet(DescriptorSet: 0)]
+global_var GV`_HALATION_BLUR_sampler`(spv.StorageClass.UniformConstant): spv.OpTypeSampler
+
+func F`get_pass_output_gamma(`() -> f32 {
+  1.0f32
+}
+
+func F`encode_output(vf4;`(
+  #[name = "color"]
+  v0: T3,
+) -> f32×4 {
+  v1 = spv.OpLoad(Pointer: &GV`gamma_encode_output`): bool
+  v2: f32×4 = if v1 {
+    v3 = spv.OpLoad(Pointer: &GV`assume_opaque_alpha`): bool
+    v4: f32×4 = if v3 {
+      v5 = spv.OpLoad(Pointer: v0): f32×4
+      v6 = spv.OpVectorShuffle(Vector1: v5, Vector2: v5, 0, 1, 2): f32×3
+      v7 = call F`get_pass_output_gamma(`(): f32
+      v8 = f.div(1.0f32, v7): f32
+      v9 = vec.new(v8, v8, v8): f32×3
+      v10 = spv.extinst."GLSL.std.450".Pow(X: v6, Y: v9): f32×3
+      v11 = vec.extract(v10, 0): f32
+      v12 = vec.extract(v10, 1): f32
+      v13 = vec.extract(v10, 2): f32
+      v14 = vec.new(v11, v12, v13, 1.0f32): f32×4
+      v14
+    } else {
+      v15 = spv.OpLoad(Pointer: v0): f32×4
+      v16 = spv.OpVectorShuffle(Vector1: v15, Vector2: v15, 0, 1, 2): f32×3
+      v17 = call F`get_pass_output_gamma(`(): f32
+      v18 = f.div(1.0f32, v17): f32
+      v19 = vec.new(v18, v18, v18): f32×3
+      v20 = spv.extinst."GLSL.std.450".Pow(X: v16, Y: v19): f32×3
+      v21 = spv.OpAccessChain(Base: v0, 3u32): T2
+      v22 = spv.OpLoad(Pointer: v21): f32
+      v23 = vec.extract(v20, 0): f32
+      v24 = vec.extract(v20, 1): f32
+      v25 = vec.extract(v20, 2): f32
+      v26 = vec.new(v23, v24, v25, v22): f32×4
+      v26
+    }
+    v4
+  } else {
+    v27 = spv.OpLoad(Pointer: v0): f32×4
+    v27
+  }
+  v2
+}
+
+#[spv.ExecutionMode.OriginUpperLeft]
+func F`main`() {
+  v`scanline_color_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v0 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v1 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v2 = spv.OpVariable(spv.StorageClass.Function): T1
+  v`auto_dim_factor` = spv.OpVariable(spv.StorageClass.Function): T2
+  #[name = "tile_uv_wrap"]
+  v3 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "mask_tex_uv"]
+  v4 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v5 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v6 = spv.OpVariable(spv.StorageClass.Function): T3
+  v`sample_orig_luts` = spv.OpVariable(spv.StorageClass.Function): spv.OpTypePointer(spv.StorageClass.Function, bool)
+  v`phosphor_mask_sample` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v7 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v8 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v9 = spv.OpVariable(spv.StorageClass.Function): T1
+  #[name = "param"]
+  v10 = spv.OpVariable(spv.StorageClass.Function): T1
+  v`halation_color` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v11 = spv.OpVariable(spv.StorageClass.Function): T1
+  v`halation_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+  v`electron_intensity_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+  v`phosphor_emission_dim` = spv.OpVariable(spv.StorageClass.Function): T0
+  v`pixel_color` = spv.OpVariable(spv.StorageClass.Function): T0
+  #[name = "param"]
+  v12 = spv.OpVariable(spv.StorageClass.Function): T3
+  v13 = spv.OpAccessChain(Base: &GV`params`, 2s32, 0u32): T4
+  v14 = spv.OpLoad(Pointer: v13): f32
+  v15 = spv.OpAccessChain(Base: &GV`params`, 0s32, 1u32): T4
+  v16 = spv.OpLoad(Pointer: v15): f32
+  v17 = f.div(v14, v16): f32
+  spv.OpStore(Pointer: &GV`bloom_approx_scale_x`, Object: v17)
+  spv.OpStore(Pointer: &GV`crt_gamma_static`, Object: 2.5f32)
+  spv.OpStore(Pointer: &GV`lcd_gamma_static`, Object: 2.2f32)
+  spv.OpStore(Pointer: &GV`levels_contrast_static`, Object: 1.0f32)
+  spv.OpStore(Pointer: &GV`levels_autodim_temp`, Object: 0.5f32)
+  spv.OpStore(Pointer: &GV`halation_weight_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`diffusion_weight_static`, Object: 0.075f32)
+  spv.OpStore(Pointer: &GV`bloom_underestimate_levels_static`, Object: 0.8f32)
+  spv.OpStore(Pointer: &GV`bloom_excess_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`bloom_approx_filter_static`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`beam_num_scanlines`, Object: 3.0f32)
+  spv.OpStore(Pointer: &GV`beam_generalized_gaussian`, Object: true)
+  spv.OpStore(Pointer: &GV`beam_antialias_level`, Object: 1.0f32)
+  spv.OpStore(Pointer: &GV`beam_min_sigma_static`, Object: 0.02f32)
+  spv.OpStore(Pointer: &GV`beam_max_sigma_static`, Object: 0.3f32)
+  spv.OpStore(Pointer: &GV`beam_spot_shape_function`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`beam_spot_power_static`, Object: 0.33333334f32)
+  spv.OpStore(Pointer: &GV`beam_min_shape_static`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`beam_max_shape_static`, Object: 4.0f32)
+  spv.OpStore(Pointer: &GV`beam_shape_power_static`, Object: 0.25f32)
+  spv.OpStore(Pointer: &GV`beam_horiz_filter_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`beam_horiz_sigma_static`, Object: 0.35f32)
+  spv.OpStore(Pointer: &GV`beam_horiz_linear_rgb_weight_static`, Object: 1.0f32)
+  spv.OpStore(Pointer: &GV`beam_misconvergence`, Object: true)
+  spv.OpStore(Pointer: &GV`convergence_offsets_r_static`, Object: f32×2(0.1, 0.2))
+  spv.OpStore(Pointer: &GV`convergence_offsets_g_static`, Object: f32×2(0.3, 0.4))
+  spv.OpStore(Pointer: &GV`convergence_offsets_b_static`, Object: f32×2(0.5, 0.6))
+  spv.OpStore(Pointer: &GV`interlace_detect_static`, Object: true)
+  spv.OpStore(Pointer: &GV`interlace_1080i_static`, Object: false)
+  spv.OpStore(Pointer: &GV`interlace_bff_static`, Object: false)
+  spv.OpStore(Pointer: &GV`aa_level`, Object: 12.0f32)
+  spv.OpStore(Pointer: &GV`aa_filter`, Object: 6.0f32)
+  spv.OpStore(Pointer: &GV`aa_temporal`, Object: false)
+  spv.OpStore(Pointer: &GV`aa_subpixel_r_offset_static`, Object: f32×2(-0.33333334, 0.0))
+  spv.OpStore(Pointer: &GV`aa_cubic_c_static`, Object: 0.5f32)
+  spv.OpStore(Pointer: &GV`aa_gauss_sigma_static`, Object: 0.5f32)
+  spv.OpStore(Pointer: &GV`mask_type_static`, Object: 1.0f32)
+  spv.OpStore(Pointer: &GV`mask_sample_mode_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`mask_specify_num_triads_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`mask_triad_size_desired_static`, Object: 3.0f32)
+  spv.OpStore(Pointer: &GV`mask_num_triads_desired_static`, Object: 480.0f32)
+  spv.OpStore(Pointer: &GV`mask_sinc_lobes`, Object: 3.0f32)
+  spv.OpStore(Pointer: &GV`mask_min_allowed_triad_size`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`geom_mode_static`, Object: 0.0f32)
+  spv.OpStore(Pointer: &GV`geom_radius_static`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`geom_view_dist_static`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`geom_tilt_angle_static`, Object: f32×2(0.0, 0.0))
+  spv.OpStore(Pointer: &GV`geom_aspect_ratio_static`, Object: 1.3130699f32)
+  spv.OpStore(Pointer: &GV`geom_overscan_static`, Object: f32×2(1.0, 1.0))
+  spv.OpStore(Pointer: &GV`geom_force_correct_tangent_matrix`, Object: true)
+  spv.OpStore(Pointer: &GV`border_size_static`, Object: 0.015f32)
+  spv.OpStore(Pointer: &GV`border_darkness_static`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`border_compress_static`, Object: 2.5f32)
+  spv.OpStore(Pointer: &GV`bloom_approx_size_x`, Object: 320.0f32)
+  spv.OpStore(Pointer: &GV`bloom_approx_size_x_for_fake`, Object: 400.0f32)
+  spv.OpStore(Pointer: &GV`mask_resize_viewport_scale`, Object: f32×2(0.0625, 0.0625))
+  spv.OpStore(Pointer: &GV`geom_max_aspect_ratio`, Object: 1.3333334f32)
+  spv.OpStore(Pointer: &GV`mask_texture_small_size`, Object: f32×2(64.0, 64.0))
+  spv.OpStore(Pointer: &GV`mask_texture_large_size`, Object: f32×2(512.0, 512.0))
+  spv.OpStore(Pointer: &GV`mask_triads_per_tile`, Object: 8.0f32)
+  spv.OpStore(Pointer: &GV`mask_grille14_avg_color`, Object: 0.19869281f32)
+  spv.OpStore(Pointer: &GV`mask_grille15_avg_color`, Object: 0.20784314f32)
+  spv.OpStore(Pointer: &GV`mask_slot_avg_color`, Object: 0.18039216f32)
+  spv.OpStore(Pointer: &GV`mask_shadow_avg_color`, Object: 0.16078432f32)
+  v18 = spv.OpLoad(Pointer: &GV`mask_grille15_avg_color`): f32
+  spv.OpStore(Pointer: &GV`mask_grille_avg_color`, Object: v18)
+  v19 = spv.OpLoad(Pointer: &GV`bloom_approx_filter_static`): f32
+  spv.OpStore(Pointer: &GV`bloom_approx_filter`, Object: v19)
+  v20 = spv.OpLoad(Pointer: &GV`mask_texture_small_size`): f32×2
+  spv.OpStore(Pointer: &GV`mask_resize_src_lut_size`, Object: v20)
+  spv.OpStore(Pointer: &GV`max_aa_base_pixel_border`, Object: 0.0f32)
+  v21 = spv.OpLoad(Pointer: &GV`max_aa_base_pixel_border`): f32
+  v22 = f.add(v21, 0.5f32): f32
+  spv.OpStore(Pointer: &GV`max_aniso_pixel_border`, Object: v22)
+  v23 = spv.OpLoad(Pointer: &GV`max_aniso_pixel_border`): f32
+  spv.OpStore(Pointer: &GV`max_tiled_pixel_border`, Object: v23)
+  v24 = spv.OpLoad(Pointer: &GV`max_tiled_pixel_border`): f32
+  v25 = spv.extinst."GLSL.std.450".Ceil(X: v24): f32
+  spv.OpStore(Pointer: &GV`max_mask_texel_border`, Object: v25)
+  v26 = spv.OpLoad(Pointer: &GV`max_mask_texel_border`): f32
+  v27 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32
+  v28 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+  v29 = f.mul(v27, v28): f32
+  v30 = f.div(v26, v29): f32
+  spv.OpStore(Pointer: &GV`max_mask_tile_border`, Object: v30)
+  spv.OpStore(Pointer: &GV`mask_resize_num_tiles`, Object: 2.0f32)
+  spv.OpStore(Pointer: &GV`mask_start_texels`, Object: 0.0f32)
+  v31 = spv.OpLoad(Pointer: &GV`mask_resize_num_tiles`): f32
+  v32 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+  v33 = f.mul(v31, v32): f32
+  spv.OpStore(Pointer: &GV`mask_resize_num_triads`, Object: v33)
+  v34 = spv.OpLoad(Pointer: &GV`mask_resize_num_triads`): f32
+  v35 = vec.new(v34, v34): f32×2
+  v36 = spv.OpLoad(Pointer: &GV`mask_resize_viewport_scale`): f32×2
+  v37 = vec.distribute(f.div)(v35, v36): f32×2
+  spv.OpStore(Pointer: &GV`min_allowed_viewport_triads`, Object: v37)
+  spv.OpStore(Pointer: &GV`pi`, Object: 3.1415927f32)
+  spv.OpStore(Pointer: &GV`under_half`, Object: 0.4995f32)
+  spv.OpStore(Pointer: &GV`gba_gamma`, Object: 3.5f32)
+  v38 = spv.OpAccessChain(Base: &GV`global`, 46s32): T5
+  v39 = spv.OpLoad(Pointer: v38): f32
+  v40 = f.ne_or_unord(v39, 0.0f32): bool
+  spv.OpStore(Pointer: &GV`interlace_detect`, Object: v40)
+  spv.OpStore(Pointer: &GV`ntsc_gamma`, Object: 2.2f32)
+  spv.OpStore(Pointer: &GV`pal_gamma`, Object: 2.8f32)
+  spv.OpStore(Pointer: &GV`crt_reference_gamma_high`, Object: 2.5f32)
+  spv.OpStore(Pointer: &GV`crt_reference_gamma_low`, Object: 2.35f32)
+  spv.OpStore(Pointer: &GV`lcd_reference_gamma`, Object: 2.5f32)
+  spv.OpStore(Pointer: &GV`crt_office_gamma`, Object: 2.2f32)
+  spv.OpStore(Pointer: &GV`lcd_office_gamma`, Object: 2.2f32)
+  spv.OpStore(Pointer: &GV`assume_opaque_alpha`, Object: false)
+  spv.OpStore(Pointer: &GV`linearize_input`, Object: false)
+  spv.OpStore(Pointer: &GV`gamma_encode_output`, Object: false)
+  v41 = spv.OpLoad(Pointer: &GV`linearize_input`): bool
+  v42 = bool.not(v41): bool
+  spv.OpStore(Pointer: &GV`gamma_aware_bilinear`, Object: v42)
+  v43 = spv.OpLoad(Pointer: &GV`mask_min_allowed_triad_size`): f32
+  v44 = spv.OpLoad(Pointer: &GV`mask_triads_per_tile`): f32
+  v45 = f.mul(v43, v44): f32
+  v46 = spv.extinst."GLSL.std.450".Ceil(X: v45): f32
+  spv.OpStore(Pointer: &GV`mask_min_allowed_tile_size`, Object: v46)
+  v47 = spv.OpLoad(Pointer: &GV`mask_min_allowed_tile_size`): f32
+  spv.OpStore(Pointer: &GV`mask_min_expected_tile_size`, Object: v47)
+  v48 = spv.OpLoad(Pointer: &GV`pi`): f32
+  v49 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32
+  v50 = f.div(v48, v49): f32
+  spv.OpStore(Pointer: &GV`pi_over_lobes`, Object: v50)
+  v51 = spv.OpLoad(Pointer: &GV`mask_sinc_lobes`): f32
+  v52 = f.mul(2.0f32, v51): f32
+  v53 = spv.OpAccessChain(Base: &GV`mask_resize_src_lut_size`, 0u32): spv.OpTypePointer(spv.StorageClass.Private, f32)
+  v54 = spv.OpLoad(Pointer: v53): f32
+  v55 = f.mul(v52, v54): f32
+  v56 = spv.OpLoad(Pointer: &GV`mask_min_expected_tile_size`): f32
+  v57 = f.div(v55, v56): f32
+  spv.OpStore(Pointer: &GV`max_sinc_resize_samples_float`, Object: v57)
+  v58 = spv.OpLoad(Pointer: &GV`max_sinc_resize_samples_float`): f32
+  v59 = f.mul(v58, 0.25f32): f32
+  v60 = spv.extinst."GLSL.std.450".Ceil(X: v59): f32
+  v61 = f.mul(v60, 4.0f32): f32
+  spv.OpStore(Pointer: &GV`max_sinc_resize_samples_m4`, Object: v61)
+  spv.OpStore(Pointer: &GV`blur3_std_dev`, Object: 0.62666017f32)
+  spv.OpStore(Pointer: &GV`blur4_std_dev`, Object: 0.6617187f32)
+  spv.OpStore(Pointer: &GV`blur5_std_dev`, Object: 0.9845703f32)
+  spv.OpStore(Pointer: &GV`blur6_std_dev`, Object: 1.0262696f32)
+  spv.OpStore(Pointer: &GV`blur7_std_dev`, Object: 1.3610351f32)
+  spv.OpStore(Pointer: &GV`blur8_std_dev`, Object: 1.4080079f32)
+  spv.OpStore(Pointer: &GV`blur9_std_dev`, Object: 1.7533203f32)
+  spv.OpStore(Pointer: &GV`blur10_std_dev`, Object: 1.8047851f32)
+  spv.OpStore(Pointer: &GV`blur11_std_dev`, Object: 2.1598632f32)
+  spv.OpStore(Pointer: &GV`blur12_std_dev`, Object: 2.2152343f32)
+  spv.OpStore(Pointer: &GV`blur17_std_dev`, Object: 3.455356f32)
+  spv.OpStore(Pointer: &GV`blur25_std_dev`, Object: 5.3409576f32)
+  spv.OpStore(Pointer: &GV`blur31_std_dev`, Object: 6.8648806f32)
+  spv.OpStore(Pointer: &GV`blur43_std_dev`, Object: 10.185205f32)
+  spv.OpStore(Pointer: &GV`error_blurring`, Object: 0.5f32)
+  spv.OpStore(Pointer: &GV`bloom_diff_thresh`, Object: 0.00390625f32)
+  v62 = spv.OpLoad(Pointer: &GV`scanline_tex_uv`): f32×2
+  spv.OpStore(Pointer: v0, Object: v62)
+  v63 = spv.OpAccessChain(Base: &GV`params`, 3s32): spv.OpTypePointer(spv.StorageClass.PushConstant, f32×4)
+  v64 = spv.OpLoad(Pointer: v63): f32×4
+  v65 = spv.OpVectorShuffle(Vector1: v64, Vector2: v64, 0, 1): f32×2
+  spv.OpStore(Pointer: v1, Object: v65)
+  v66 = spv.OpLoad(Pointer: &GV`scanline_texture_size_inv`): f32×2
+  spv.OpStore(Pointer: v2, Object: v66)
+  v67 = call F`sample_rgb_scanline_horizontal(s21;vf2;vf2;vf2;`(&GV`VERTICAL_SCANLINES`, &GV`_VERTICAL_SCANLINES_sampler`, v0, v1, v2):
+    f32×3
+  spv.OpStore(Pointer: v`scanline_color_dim`, Object: v67)
+  v68 = spv.OpLoad(Pointer: &GV`levels_autodim_temp`): f32
+  spv.OpStore(Pointer: v`auto_dim_factor`, Object: v68)
+  v69 = spv.OpLoad(Pointer: &GV`video_uv`): f32×2
+  v70 = spv.OpLoad(Pointer: &GV`mask_tiles_per_screen`): f32×2
+  v71 = vec.distribute(f.mul)(v69, v70): f32×2
+  spv.OpStore(Pointer: v3, Object: v71)
+  v72 = spv.OpLoad(Pointer: v3): f32×2
+  spv.OpStore(Pointer: v5, Object: v72)
+  v73 = spv.OpLoad(Pointer: &GV0): f32×4
+  spv.OpStore(Pointer: v6, Object: v73)
+  v74 = call F`convert_phosphor_tile_uv_wrap_to_tex_uv(vf2;vf4;`(v5, v6): f32×2
+  spv.OpStore(Pointer: v4, Object: v74)
+  v75 = call F`get_mask_sample_mode(`(): f32
+  v76 = f.gt(v75, 0.5f32): bool
+  spv.OpStore(Pointer: v`sample_orig_luts`, Object: v76)
+  v77 = spv.OpLoad(Pointer: v`sample_orig_luts`): bool
+  if v77 {
+    v103 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5
+    v104 = spv.OpLoad(Pointer: v103): f32
+    v105 = f.lt(v104, 0.5f32): bool
+    if v105 {
+      v106 = spv.OpLoad(Pointer: v4): f32×2
+      spv.OpStore(Pointer: v7, Object: v106)
+      v107 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_grille_texture_large`, &GV`_mask_grille_texture_large_sampler`, v7): f32×4
+      v108 = spv.OpVectorShuffle(Vector1: v107, Vector2: v107, 0, 1, 2): f32×3
+      spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v108)
+    } else {
+      v109 = spv.OpAccessChain(Base: &GV`global`, 23s32): T5
+      v110 = spv.OpLoad(Pointer: v109): f32
+      v111 = f.lt(v110, 1.5f32): bool
+      if v111 {
+        v112 = spv.OpLoad(Pointer: v4): f32×2
+        spv.OpStore(Pointer: v8, Object: v112)
+        v113 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_slot_texture_large`, &GV`_mask_slot_texture_large_sampler`, v8): f32×4
+        v114 = spv.OpVectorShuffle(Vector1: v113, Vector2: v113, 0, 1, 2): f32×3
+        spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v114)
+      } else {
+        v115 = spv.OpLoad(Pointer: v4): f32×2
+        spv.OpStore(Pointer: v9, Object: v115)
+        v116 = call F`tex2D_linearize(s21;vf2;`(&GV`mask_shadow_texture_large`, &GV`_mask_shadow_texture_large_sampler`, v9): f32×4
+        v117 = spv.OpVectorShuffle(Vector1: v116, Vector2: v116, 0, 1, 2): f32×3
+        spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v117)
+      }
+    }
+  } else {
+    v118 = spv.OpLoad(Pointer: v4): f32×2
+    spv.OpStore(Pointer: v10, Object: v118)
+    v119 = call F`tex2Dtiled_mask_linearize(s21;vf2;`(&GV`MASK_RESIZE`, &GV`_MASK_RESIZE_sampler`, v10): f32×4
+    v120 = spv.OpVectorShuffle(Vector1: v119, Vector2: v119, 0, 1, 2): f32×3
+    spv.OpStore(Pointer: v`phosphor_mask_sample`, Object: v120)
+  }
+  v78 = spv.OpLoad(Pointer: &GV`halation_tex_uv`): f32×2
+  spv.OpStore(Pointer: v11, Object: v78)
+  v79 = call F`tex2D_linearize(s21;vf2;`(&GV`HALATION_BLUR`, &GV`_HALATION_BLUR_sampler`, v11): f32×4
+  v80 = spv.OpVectorShuffle(Vector1: v79, Vector2: v79, 0, 1, 2): f32×3
+  spv.OpStore(Pointer: v`halation_color`, Object: v80)
+  v81 = spv.OpLoad(Pointer: v`halation_color`): f32×3
+  v82 = spv.OpLoad(Pointer: v`auto_dim_factor`): f32
+  v83 = f.div(v82, 3.0f32): f32
+  v84 = vec.new(v83, v83, v83): f32×3
+  v85 = vec.dot(v81, v84): f32
+  v86 = vec.new(v85, v85, v85): f32×3
+  spv.OpStore(Pointer: v`halation_intensity_dim`, Object: v86)
+  v87 = spv.OpLoad(Pointer: v`scanline_color_dim`): f32×3
+  v88 = spv.OpLoad(Pointer: v`halation_intensity_dim`): f32×3
+  v89 = spv.OpAccessChain(Base: &GV`global`, 4s32): T5
+  v90 = spv.OpLoad(Pointer: v89): f32
+  v91 = vec.new(v90, v90, v90): f32×3
+  v92 = spv.extinst."GLSL.std.450".FMix(X: v87, Y: v88, A: v91): f32×3
+  spv.OpStore(Pointer: v`electron_intensity_dim`, Object: v92)
+  v93 = spv.OpLoad(Pointer: v`electron_intensity_dim`): f32×3
+  v94 = spv.OpLoad(Pointer: v`phosphor_mask_sample`): f32×3
+  v95 = vec.distribute(f.mul)(v93, v94): f32×3
+  spv.OpStore(Pointer: v`phosphor_emission_dim`, Object: v95)
+  v96 = spv.OpLoad(Pointer: v`phosphor_emission_dim`): f32×3
+  spv.OpStore(Pointer: v`pixel_color`, Object: v96)
+  v97 = spv.OpLoad(Pointer: v`pixel_color`): f32×3
+  v98 = vec.extract(v97, 0): f32
+  v99 = vec.extract(v97, 1): f32
+  v100 = vec.extract(v97, 2): f32
+  v101 = vec.new(v98, v99, v100, 1.0f32): f32×4
+  spv.OpStore(Pointer: v12, Object: v101)
+  v102 = call F`encode_output(vf4;`(v12): f32×4
+  spv.OpStore(Pointer: &GV`FragColor`, Object: v102)
+}
+
+export {
+  spv.OpEntryPoint(spv.ExecutionModel.Fragment, Name: "main"): F`main`,
+}
+ diff --git a/librashader-reflect/src/back/mod.rs b/librashader-reflect/src/back/mod.rs index 8022c4b..af95e9a 100644 --- a/librashader-reflect/src/back/mod.rs +++ b/librashader-reflect/src/back/mod.rs @@ -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(); + } +} diff --git a/librashader-reflect/src/back/targets.rs b/librashader-reflect/src/back/targets.rs index abc5fc1..9212f35 100644 --- a/librashader-reflect/src/back/targets.rs +++ b/librashader-reflect/src/back/targets.rs @@ -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; } +#[cfg(test)] mod test { use crate::back::targets::GLSL; use crate::back::FromCompilation; diff --git a/librashader-reflect/src/back/wgsl/lower_samplers.rs b/librashader-reflect/src/back/wgsl/lower_samplers.rs new file mode 100644 index 0000000..c3ae73d --- /dev/null +++ b/librashader-reflect/src/back/wgsl/lower_samplers.rs @@ -0,0 +1,1077 @@ +use rspirv::dr::{Builder, Instruction, Operand}; +use rustc_hash::{FxHashMap, FxHashSet}; +use spirv::{Op, StorageClass, Word}; +use std::borrow::Cow; +use std::collections::hash_map::Entry; + +pub struct LowerCombinedImageSamplerPass<'a> { + pub builder: &'a mut Builder, + pub seen_functions: FxHashSet, +} + +#[derive(Clone, Debug)] +struct CombinedImageSampler { + sampler_variable: spirv::Word, + sampler_pointer_type: spirv::Word, + original_uniform_pointer_type_id: spirv::Word, + original_uniform_type: Instruction, + + target_texture_type_id: spirv::Word, + target_texture_pointer_type_id: spirv::Word, + + // Always OpTypeImage + base_type: Instruction, +} + +#[derive(Debug)] +struct OpAccessChain<'a> { + sampled_image: &'a CombinedImageSampler, + index: Operand, + original_result_type: Word, + target_pointer_type: Word, +} + +impl<'a> LowerCombinedImageSamplerPass<'a> { + pub fn new(builder: &'a mut Builder) -> Self { + let val = Self { + builder, + seen_functions: FxHashSet::default(), + }; + + val + } + + pub(crate) fn do_pass(&mut self) { + let mut combined_image_samplers = self.collect_global_sampled_images(); + self.retype_combined_image_sampler_uniforms(&combined_image_samplers); + self.put_variables_to_end(); + + // First rewrite global loads + self.rewrite_loads(&combined_image_samplers); + + let mut op_access_chains = self.collect_op_access_chain(&combined_image_samplers); + self.rewrite_global_op_access_chain_loads(&op_access_chains); + + // Collect functions that reference combined image samplers indirectly (todo) (also rewrite the found OpFunctionCall) + + while !combined_image_samplers.is_empty() { + let op_functions = + self.rewrite_function_calls(&op_access_chains, &combined_image_samplers); + + combined_image_samplers = self.rewrite_functions_definitions(&op_functions); + self.rewrite_loads(&combined_image_samplers); + + op_access_chains = self.collect_op_access_chain(&combined_image_samplers); + + self.rewrite_global_op_access_chain_loads(&op_access_chains); + } + + // notes: OpFunctionCall %void %assign_s21_ %tex (i.e for scalar no OpLoad precedes, OpLoad and OpAccessChain is in function), this is true even when passing array of samplers + // However, if passing single sampler from array, OpAccessChain happens in outer scope. + // Rewrite functions that do so by adding sampler param + // rewrite loads + op_access_chains for functions + } + + fn put_variables_to_end(&mut self) { + // this is easier than doing proper topo sort. + let mut vars = Vec::new(); + + self.builder + .module_mut() + .types_global_values + .retain(|instr| { + if instr.class.opcode == spirv::Op::Variable { + vars.push(instr.clone()); + return false; + }; + true + }); + + self.builder + .module_mut() + .types_global_values + .append(&mut vars); + } + pub(crate) fn ensure_op_type_sampler(&mut self) { + self.builder.type_sampler(); + } + + fn find_global_instruction(&self, word: Word) -> Option<&Instruction> { + self.builder + .module_ref() + .global_inst_iter() + .find(|i| i.result_id == Some(word)) + } + + fn create_sampler_name(&mut self, word: Word) -> Option { + self.builder.module_ref().debug_names.iter().find_map(|i| { + if i.class.opcode != spirv::Op::Name { + return None; + } + + let Some(&Operand::IdRef(target)) = &i.operands.get(0) else { + return None; + }; + + if target != word { + return None; + } + + let Some(Operand::LiteralString(string)) = &i.operands.get(1) else { + return None; + }; + + return Some(format!("_{string}_sampler")); + }) + } + + fn get_base_type_for_sampled_image(&'a self, inst: &'a Instruction) -> Option<&'a Instruction> { + if inst.class.opcode != spirv::Op::TypeSampledImage { + return None; + } + + let Some(&Operand::IdRef(referand)) = inst.operands.get(0) else { + return None; + }; + + self.find_global_instruction(referand) + } + + // Create a sampler OpVariable at the selected block + fn create_sampler_uniform( + &mut self, + uniform_type: spirv::Word, + combined_image_sampler: spirv::Word, + ) -> (spirv::Word, spirv::Word) { + let sampler_pointer_type = + self.builder + .type_pointer(None, StorageClass::UniformConstant, uniform_type); + + let sampler_uniform = self.builder.variable( + sampler_pointer_type, + None, + StorageClass::UniformConstant, + None, + ); + + let decorations: Vec = self + .builder + .module_ref() + .annotations + .iter() + .filter_map(|f| { + if f.class.opcode == spirv::Op::Decorate + && f.operands[0] == Operand::IdRef(combined_image_sampler) + { + Some(f.clone()) + } else { + None + } + }) + .collect(); + + if let Some(name) = self.create_sampler_name(combined_image_sampler) { + self.builder.name(sampler_uniform, name); + } + + // Clone decorations to the created sampler + for decoration in decorations { + let Operand::Decoration(decoration_type) = decoration.operands[1] else { + continue; + }; + + self.builder.decorate( + sampler_uniform, + decoration_type, + decoration.operands[2..].iter().map(|f| f.clone()), + ) + } + + (sampler_pointer_type, sampler_uniform) + } + fn collect_global_sampled_images(&mut self) -> FxHashMap { + let mut image_sampler_cadidates = Vec::new(); + let mut image_sampler_types = FxHashMap::default(); + + for global in self.builder.module_ref().types_global_values.iter() { + if global.class.opcode == spirv::Op::Variable + && global.operands[0] == Operand::StorageClass(StorageClass::UniformConstant) + { + let pointer_type = global.result_type; + let Some(pointer_type) = pointer_type else { + continue; + }; + image_sampler_cadidates.push((pointer_type, global.result_id)) + } + } + + for (pointer_type_id, global_variable) in image_sampler_cadidates { + let Some(pointer_type) = self.find_global_instruction(pointer_type_id).cloned() else { + continue; + }; + + if pointer_type.class.opcode == spirv::Op::TypePointer + && pointer_type.operands[0] == Operand::StorageClass(StorageClass::UniformConstant) + { + let Some(&Operand::IdRef(sampled_image_type)) = pointer_type.operands.get(1) else { + continue; + }; + + let Some(uniform_type) = self.find_global_instruction(sampled_image_type).cloned() + else { + continue; + }; + + if uniform_type.class.opcode == spirv::Op::TypeSampledImage { + let Some(base_type) = + self.get_base_type_for_sampled_image(&uniform_type).cloned() + else { + continue; + }; + + let Some(combined_image_sampler) = global_variable else { + continue; + }; + + // insert the sampler + if base_type.class.opcode != spirv::Op::TypeImage { + continue; + } + + let Some(base_type_id) = base_type.result_id else { + continue; + }; + + let sampler_type = self.builder.type_sampler(); + + let (sampler_pointer_type, sampler_uniform) = + self.create_sampler_uniform(sampler_type, combined_image_sampler); + + image_sampler_types.insert( + combined_image_sampler, + CombinedImageSampler { + sampler_variable: sampler_uniform, + original_uniform_type: uniform_type, + target_texture_type_id: base_type_id, + original_uniform_pointer_type_id: pointer_type_id, + base_type, + sampler_pointer_type, + target_texture_pointer_type_id: pointer_type_id, + }, + ); + + continue; + } + + if uniform_type.class.opcode == spirv::Op::TypeArray { + let Some(&Operand::IdRef(array_base_type)) = uniform_type.operands.get(0) + else { + continue; + }; + + let Some(&Operand::IdRef(array_length)) = uniform_type.operands.get(1) else { + continue; + }; + + let Some(sampled_image_type) = + self.find_global_instruction(array_base_type).cloned() + else { + continue; + }; + + let Some(base_type) = self + .get_base_type_for_sampled_image(&sampled_image_type) + .cloned() + else { + continue; + }; + + let Some(combined_image_sampler) = global_variable else { + continue; + }; + + // insert the sampler + if base_type.class.opcode != spirv::Op::TypeImage { + continue; + } + + let sampler_type = self.builder.type_sampler(); + let sampler_array_type = self.builder.type_array(sampler_type, array_length); + + let (sampler_pointer_type, sampler_uniform) = + self.create_sampler_uniform(sampler_array_type, combined_image_sampler); + + // insert target types + let Some(base_type_id) = base_type.result_id else { + continue; + }; + + let target_texture_type_id = + self.builder.type_array(base_type_id, array_length); + + let target_texture_pointer_type_id = self.builder.type_pointer( + None, + StorageClass::UniformConstant, + target_texture_type_id, + ); + + image_sampler_types.insert( + combined_image_sampler, + CombinedImageSampler { + sampler_variable: sampler_uniform, + original_uniform_type: uniform_type, + target_texture_type_id, + original_uniform_pointer_type_id: pointer_type_id, + base_type, + sampler_pointer_type, + target_texture_pointer_type_id, + }, + ); + continue; + } + } + } + + image_sampler_types + } + + fn retype_combined_image_sampler_uniforms( + &mut self, + combined_image_samplers: &FxHashMap, + ) { + // Need to rebuild the global instructions because we need to insert new types... + let mut instructions = Vec::new(); + for instr in self.builder.module_ref().types_global_values.clone() { + let Some(result_id) = instr.result_id else { + instructions.push(instr); + continue; + }; + + let Some(sampled_image) = combined_image_samplers.get(&result_id) else { + // We need to fix.. + instructions.push(instr); + continue; + }; + + let Some(_base_type_id) = sampled_image.base_type.result_id else { + instructions.push(instr); + continue; + }; + + // If it's a OpTypeSampledImage, we want to change the variable type to &TypeImage. + if sampled_image.original_uniform_type.class.opcode == spirv::Op::TypeSampledImage { + // keep labels in sync + let mut op_variable = instr; + op_variable.result_type = Some(sampled_image.target_texture_pointer_type_id); + + instructions.push(op_variable); + continue; + } + + // Re-type array globals. + // We don't need to worry about the pointer type of the load, as + // we can instantiate that later. + if sampled_image.original_uniform_type.class.opcode == spirv::Op::TypeArray { + let mut op_variable = instr; + op_variable.result_type = Some(sampled_image.target_texture_pointer_type_id); + + instructions.push(op_variable); + } + } + + // replace + self.builder.module_mut().types_global_values = instructions; + } + + fn rewrite_loads( + &mut self, + combined_image_samplers: &FxHashMap, + ) { + let op_type_sampler = self.builder.type_sampler(); + + // need to clone + let mut functions = self.builder.module_ref().functions.clone(); + + for function in functions.iter_mut() { + for block in function.blocks.iter_mut() { + let mut instructions = Vec::new(); + for instr in block.instructions.drain(..) { + if instr.class.opcode != Op::Load { + instructions.push(instr); + continue; + } + + // This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass. + let Some(Operand::IdRef(op_variable_id)) = &instr.operands.get(0) else { + instructions.push(instr); + continue; + }; + + let Some(combined_image_sampler) = combined_image_samplers.get(op_variable_id) + else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let op_load_texture_id = self.builder.id(); + let op_load_sampler_id = self.builder.id(); + + let mut load_instr = instr.clone(); + + load_instr.result_type = combined_image_sampler.base_type.result_id; + load_instr.result_id = Some(op_load_texture_id); + instructions.push(load_instr); + + // load the sampler + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::Load), + result_type: Some(op_type_sampler), + result_id: Some(op_load_sampler_id), + operands: vec![Operand::IdRef(combined_image_sampler.sampler_variable)], + }); + + // reuse the old id for the OpSampleImage + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::SampledImage), + result_type: combined_image_sampler.original_uniform_type.result_id, + result_id: instr.result_id, + + operands: vec![ + Operand::IdRef(op_load_texture_id), + Operand::IdRef(op_load_sampler_id), + ], + }); + } + block.instructions = instructions; + } + } + + self.builder.module_mut().functions = functions; + } + + fn collect_op_access_chain<'b>( + &mut self, + combined_image_samplers: &'b FxHashMap, + ) -> FxHashMap> { + // need to clone + let mut functions = self.builder.module_ref().functions.clone(); + + let mut seen_op_access_chain = FxHashMap::default(); + + for function in functions.iter_mut() { + for block in function.blocks.iter_mut() { + let mut instructions = Vec::new(); + + // This needs to be done in two passes, first to find the OpAccessChains and + // update their type to the pointer type of the scalar value, + + // Then to update the OpLoads. + for instr in block.instructions.clone() { + if instr.class.opcode != Op::AccessChain { + instructions.push(instr); + continue; + } + + // This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass. + let Some(Operand::IdRef(op_variable)) = &instr.operands.get(0) else { + instructions.push(instr); + continue; + }; + + // Ensure that this is an OpAccessChain of our combined image sampler. + let Some(sampled_image) = combined_image_samplers.get(op_variable) else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let Some(original_result_type) = instr.result_type else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let Some(index) = instr.operands.get(1).cloned() else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let Some(base_type_id) = sampled_image.base_type.result_id else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let op_pointer_type_id = self.builder.type_pointer( + None, + StorageClass::UniformConstant, + base_type_id, + ); + + let mut op_access_chain = instr; + + let Some(result_id) = op_access_chain.result_id else { + instructions.push(op_access_chain); + continue; + }; + + op_access_chain.result_type = Some(op_pointer_type_id); + + instructions.push(op_access_chain); + + seen_op_access_chain.insert( + result_id, + OpAccessChain { + sampled_image, + index, + original_result_type, + target_pointer_type: op_pointer_type_id, + }, + ); + } + + block.instructions = instructions; + } + } + + self.builder.module_mut().functions = functions; + seen_op_access_chain + } + + fn rewrite_global_op_access_chain_loads( + &mut self, + op_access_chains: &FxHashMap, + ) { + let op_type_sampler = self.builder.type_sampler(); + let op_type_sampler_pointer = + self.builder + .type_pointer(None, StorageClass::UniformConstant, op_type_sampler); + + let mut functions = self.builder.module_ref().functions.clone(); + + for function in functions.iter_mut() { + for block in function.blocks.iter_mut() { + let mut instructions = Vec::new(); + + // This needs to be done in two passes, first to find the OpAccessChains and + // update their type to the pointer type of the scalar value, + + // Then to update the OpLoads. + for instr in block.instructions.clone() { + if instr.class.opcode != Op::Load { + instructions.push(instr); + continue; + } + + let Some(Operand::IdRef(op_variable)) = &instr.operands.get(0) else { + instructions.push(instr); + continue; + }; + + // Ensure that this is an OpLoad of the previous OpAccessChain + let Some(&OpAccessChain { + sampled_image, + ref index, + .. + }) = op_access_chains.get(op_variable) + else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let Some(base_type_id) = sampled_image.base_type.result_id else { + // Ignore what we didn't process before. + instructions.push(instr); + continue; + }; + + let op_load_texture_id = self.builder.id(); + let op_load_sampler_id = self.builder.id(); + let op_access_chain_sampler_id = self.builder.id(); + + let op_type_sampled_image = self.builder.type_sampled_image(base_type_id); + + let mut load_instr = instr.clone(); + + load_instr.result_type = sampled_image.base_type.result_id; + load_instr.result_id = Some(op_load_texture_id); + instructions.push(load_instr); + + // load the sampler + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::AccessChain), + result_type: Some(op_type_sampler_pointer), + result_id: Some(op_access_chain_sampler_id), + operands: vec![ + Operand::IdRef(sampled_image.sampler_variable), + index.clone(), + ], + }); + + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::Load), + result_type: Some(op_type_sampler), + result_id: Some(op_load_sampler_id), + operands: vec![Operand::IdRef(op_access_chain_sampler_id)], + }); + + // reuse the old id for the OpSampleImage + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::SampledImage), + result_type: Some(op_type_sampled_image), + result_id: instr.result_id, + + operands: vec![ + Operand::IdRef(op_load_texture_id), + Operand::IdRef(op_load_sampler_id), + ], + }); + } + + block.instructions = instructions; + } + } + + self.builder.module_mut().functions = functions; + } + + // Returns nested hashmap of { OpFunction: { OpType: CombinedImageSampler } }, + // indicating that the listed parameters should change + fn rewrite_function_calls<'b>( + &mut self, + op_access_chains: &'b FxHashMap, + combined_image_samplers: &'b FxHashMap, + ) -> FxHashMap>> { + let mut seen_functions: FxHashMap< + spirv::Word, + FxHashMap>, + > = FxHashMap::default(); + + // First pass, rewrite function calls involving sampled image access + for instr in self.builder.module_mut().all_inst_iter_mut() { + if instr.class.opcode != spirv::Op::FunctionCall { + continue; + } + + let Some(&Operand::IdRef(function_id)) = instr.operands.get(0) else { + continue; + }; + + if !instr.operands[1..].iter().any(|param| { + let &Operand::IdRef(function_id) = param else { + return false; + }; + + combined_image_samplers.contains_key(&function_id) + }) { + continue; + }; + + let mut function_call_operands = Vec::with_capacity(instr.operands.len()); + + for operand in instr.operands.drain(..) { + let Operand::IdRef(op_ref_id) = operand else { + function_call_operands.push(operand); + continue; + }; + + let Some(sampled_image) = combined_image_samplers.get(&op_ref_id) else { + function_call_operands.push(operand); + continue; + }; + + function_call_operands.push(operand); + function_call_operands.push(Operand::IdRef(sampled_image.sampler_variable)); + + match seen_functions.entry(function_id) { + Entry::Occupied(mut vec) => { + vec.get_mut().insert( + sampled_image.original_uniform_pointer_type_id, + Cow::Borrowed(sampled_image), + ); + } + Entry::Vacant(vec) => { + let mut map = FxHashMap::default(); + map.insert( + sampled_image.original_uniform_pointer_type_id, + Cow::Borrowed(sampled_image), + ); + vec.insert(map); + } + } + } + instr.operands = function_call_operands; + } + + // Deal with OpAccessChains. + + let op_type_sampler = self.builder.type_sampler(); + let op_type_sampler_pointer = + self.builder + .type_pointer(None, StorageClass::UniformConstant, op_type_sampler); + + let mut functions = self.builder.module_ref().functions.clone(); + + for function in functions.iter_mut() { + for block in function.blocks.iter_mut() { + let mut instructions = Vec::new(); + + // This needs to be done in two passes, first to find the OpAccessChains and + // update their type to the pointer type of the scalar value, + + // Then to update the OpLoads. + for mut instr in block.instructions.clone() { + if instr.class.opcode != Op::FunctionCall { + instructions.push(instr); + continue; + } + + let Some(&Operand::IdRef(function_id)) = instr.operands.get(0) else { + instructions.push(instr); + continue; + }; + + // Ensure that this is an OpFunctionCall involving some previous OpAccessChain + let relevant_operands = instr.operands[1..] + .iter() + .filter(|param| { + let &Operand::IdRef(op_ref_id) = param else { + return false; + }; + + op_access_chains.contains_key(&op_ref_id) + }) + .collect::>(); + + if relevant_operands.is_empty() { + instructions.push(instr); + continue; + } + + // Maps OpAccessChain of texture to OpAccessChain of sampler + let mut op_access_sampler_mapping = FxHashMap::default(); + // Insert necessary OpAccessChains + for operand in relevant_operands { + let &Operand::IdRef(op_ref_id) = operand else { + continue; + }; + + let Some(&OpAccessChain { + sampled_image, + ref index, + .. + }) = op_access_chains.get(&op_ref_id) + else { + continue; + }; + + let op_access_chain_sampler_id = self.builder.id(); + // access chain the sampler + instructions.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get( + spirv::Op::AccessChain, + ), + result_type: Some(op_type_sampler_pointer), + result_id: Some(op_access_chain_sampler_id), + operands: vec![ + Operand::IdRef(sampled_image.sampler_variable), + index.clone(), + ], + }); + + op_access_sampler_mapping.insert(op_ref_id, op_access_chain_sampler_id); + } + + let mut function_call_operands = Vec::with_capacity(instr.operands.len()); + for operand in instr.operands.drain(..) { + let Operand::IdRef(op_ref_id) = operand else { + function_call_operands.push(operand); + continue; + }; + + let Some(&OpAccessChain { + sampled_image, + index: _, + original_result_type, + target_pointer_type, + }) = op_access_chains.get(&op_ref_id) + else { + function_call_operands.push(operand); + continue; + }; + + let Some(base_type_id) = sampled_image.base_type.result_id else { + function_call_operands.push(operand); + continue; + }; + + let Some(&op_access_chain_sampler) = + op_access_sampler_mapping.get(&op_ref_id) + else { + function_call_operands.push(operand); + continue; + }; + + function_call_operands.push(operand); + function_call_operands.push(Operand::IdRef(op_access_chain_sampler)); + + let original_type = self + .find_global_instruction(original_result_type) + .cloned() + .expect("huh"); + + let sampled_image = CombinedImageSampler { + sampler_variable: op_access_chain_sampler, + sampler_pointer_type: op_type_sampler_pointer, + original_uniform_pointer_type_id: original_result_type, + original_uniform_type: original_type, + target_texture_type_id: base_type_id, + target_texture_pointer_type_id: target_pointer_type, + base_type: sampled_image.base_type.clone(), + }; + + match seen_functions.entry(function_id) { + Entry::Occupied(mut vec) => { + vec.get_mut() + .insert(original_result_type, Cow::Owned(sampled_image)); + } + Entry::Vacant(vec) => { + let mut map = FxHashMap::default(); + map.insert(original_result_type, Cow::Owned(sampled_image)); + vec.insert(map); + } + } + } + + instr.operands = function_call_operands; + + // Restore the instructions + instructions.push(instr); + } + + block.instructions = instructions; + } + } + + self.builder.module_mut().functions = functions; + seen_functions + } + + fn rewrite_functions_definitions<'b>( + &mut self, + mappings: &FxHashMap>>, + ) -> FxHashMap { + let mut sampled_refs = FxHashMap::default(); + let mut functions = self.builder.module_ref().functions.clone(); + + for function in functions.iter_mut() { + let Some(def_id) = function.def_id() else { + continue; + }; + + if self.seen_functions.contains(&def_id) { + continue; + } + + let Some(function_def) = function.def.clone() else { + continue; + }; + + let Some(param_mappings) = mappings.get(&def_id) else { + continue; + }; + + let &Some(function_return_type_id) = &function_def.result_type else { + continue; + }; + + let Some(&Operand::IdRef(_function_type_id)) = &function_def.operands.last() else { + continue; + }; + + let mut parameters = Vec::new(); + let mut param_types = Vec::new(); + for param in function.parameters.drain(..) { + let Some(param_id) = param.result_id else { + parameters.push(param); + continue; + }; + + let Some(param_type) = param.result_type else { + parameters.push(param); + continue; + }; + + let Some(sampled_image) = param_mappings.get(¶m_type) else { + parameters.push(param); + param_types.push(param_type); + continue; + }; + + let op_function_parameter_sampler_id = self.builder.id(); + + parameters.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::FunctionParameter), + result_type: Some(sampled_image.target_texture_pointer_type_id), + result_id: param.result_id, + operands: vec![], + }); + + parameters.push(Instruction { + class: rspirv::grammar::CoreInstructionTable::get(spirv::Op::FunctionParameter), + result_type: Some(sampled_image.sampler_pointer_type), + result_id: Some(op_function_parameter_sampler_id), + operands: vec![], + }); + + param_types.push(sampled_image.target_texture_pointer_type_id); + param_types.push(sampled_image.sampler_pointer_type); + + sampled_refs.insert( + param_id, + CombinedImageSampler { + sampler_variable: op_function_parameter_sampler_id, + sampler_pointer_type: sampled_image.sampler_pointer_type, + original_uniform_pointer_type_id: param_type, + original_uniform_type: sampled_image.original_uniform_type.clone(), + target_texture_type_id: sampled_image.target_texture_type_id, + target_texture_pointer_type_id: sampled_image + .target_texture_pointer_type_id, + base_type: sampled_image.base_type.clone(), + }, + ); + } + + let new_type = self + .builder + .type_function(function_return_type_id, param_types); + + if let Some(function) = &mut function.def { + if let Some(function_type) = function.operands.last_mut() { + *function_type = Operand::IdRef(new_type); + } + } + + function.parameters = parameters; + self.seen_functions.insert(def_id); + } + + self.builder.module_mut().functions = functions; + + sampled_refs + } +} + +#[cfg(test)] +mod tests { + use super::*; + use naga::back::wgsl::WriterFlags; + use naga::front::spv::Options; + use naga::valid::{Capabilities, ValidationFlags}; + use rspirv::binary::{Assemble, Disassemble}; + use std::fs::File; + use std::io::{Read, Write}; + use std::path::Path; + + fn check_wgsl(path: impl AsRef) { + let mut bin = Vec::new(); + + File::open(path).unwrap().read_to_end(&mut bin).unwrap(); + + let mut loader = rspirv::dr::Loader::new(); + rspirv::binary::parse_bytes(bin, &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(); + // find_op_type_sampled_image(&builder.builder.module_ref()); + + println!("{}", pass.builder.module_ref().disassemble()); + + let spirv = builder.module().assemble(); + + File::create("out.spv") + .unwrap() + .write_all(bytemuck::cast_slice(&spirv)) + .unwrap(); + + let mut module = naga::front::spv::parse_u8_slice( + bytemuck::cast_slice(&spirv), + &Options { + adjust_coordinate_space: false, + strict_capabilities: false, + block_ctx_dump_prefix: None, + }, + ) + .unwrap(); + + let images = module + .global_variables + .iter() + .filter(|&(_, gv)| { + let ty = &module.types[gv.ty]; + match ty.inner { + naga::TypeInner::Image { .. } => true, + naga::TypeInner::BindingArray { base, .. } => { + let ty = &module.types[base]; + matches!(ty.inner, naga::TypeInner::Image { .. }) + } + _ => false, + } + }) + .map(|(_, gv)| (gv.binding.clone(), gv.space)) + .collect::>(); + + module + .global_variables + .iter_mut() + .filter(|(_, gv)| { + let ty = &module.types[gv.ty]; + match ty.inner { + naga::TypeInner::Sampler { .. } => true, + naga::TypeInner::BindingArray { base, .. } => { + let ty = &module.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 mut valid = naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty()); + let info = valid.validate(&module).unwrap(); + + let wgsl = + naga::back::wgsl::write_string(&module, &info, WriterFlags::EXPLICIT_TYPES).unwrap(); + + println!("{}", wgsl); + } + + #[test] + fn it_works_known() { + check_wgsl("./test/combined-image-sampler.spv"); + check_wgsl("./test/combined-image-sampler-array.spv"); + check_wgsl("./test/function-call-single-scalar-sampler.spv"); + } + + #[test] + fn it_works() { + // check_wgsl("./test/combined-image-sampler.spv"); + // check_wgsl("./test/combined-image-sampler-array.spv"); + // check_wgsl("./test/function-call-single-scalar-sampler.spv"); + + check_wgsl("./test/access_out_of_call.spv"); + } +} diff --git a/librashader-reflect/src/back/wgsl/mod.rs b/librashader-reflect/src/back/wgsl/mod.rs new file mode 100644 index 0000000..9460d80 --- /dev/null +++ b/librashader-reflect/src/back/wgsl/mod.rs @@ -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 for WGSL { + type Target = WGSL; + type Options = Option<()>; + type Context = NagaWgslContext; + type Output = impl CompileShader + + ReflectShader; + + fn from_compilation( + compile: GlslangCompilation, + ) -> Result, ShaderReflectError> { + fn lower_fragment_shader(words: &[u32]) -> Vec { + 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 for NagaReflect { + type Options = Option<()>; + type Context = NagaWgslContext; + + fn compile( + mut self, + _options: Self::Options, + ) -> Result, ShaderCompileError> { + fn write_wgsl(module: &Module) -> Result { + 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::>(); + + 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:#?}"); + } +} diff --git a/librashader-reflect/src/error.rs b/librashader-reflect/src/error.rs index 1175686..9c9ead5 100644 --- a/librashader-reflect/src/error.rs +++ b/librashader-reflect/src/error.rs @@ -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), } /// 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")] diff --git a/librashader-reflect/src/front/mod.rs b/librashader-reflect/src/front/mod.rs index 0b7d7dc..0b521bc 100644 --- a/librashader-reflect/src/front/mod.rs +++ b/librashader-reflect/src/front/mod.rs @@ -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. diff --git a/librashader-reflect/src/front/naga.rs b/librashader-reflect/src/front/naga.rs deleted file mode 100644 index 32ede44..0000000 --- a/librashader-reflect/src/front/naga.rs +++ /dev/null @@ -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 { - compile_spirv(source) - } -} - -fn compile_spirv(source: &ShaderSource) -> Result { - 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::::parse(&loaded).unwrap(); - println!("{:#}", ast.compile().unwrap()); - println!("--- naga glsl---"); - println!("{glsl_out:#}"); - println!("--- naga wgsl---"); - println!("{wgsl:#}") - } -} diff --git a/librashader-reflect/src/reflect/cross.rs b/librashader-reflect/src/reflect/cross.rs index 322ade0..1ab3648 100644 --- a/librashader-reflect/src/reflect/cross.rs +++ b/librashader-reflect/src/reflect/cross.rs @@ -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 = as CompileShader>::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(); diff --git a/librashader-reflect/src/reflect/mod.rs b/librashader-reflect/src/reflect/mod.rs index 881f6f3..bd3b6c7 100644 --- a/librashader-reflect/src/reflect/mod.rs +++ b/librashader-reflect/src/reflect/mod.rs @@ -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 { diff --git a/librashader-reflect/src/reflect/naga.rs b/librashader-reflect/src/reflect/naga.rs index 5e393e0..1c26f27 100644 --- a/librashader-reflect/src/reflect/naga.rs +++ b/librashader-reflect/src/reflect/naga.rs @@ -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 for NagaReflect { - type Error = ShaderReflectError; - - fn try_from(value: NagaCompilation) -> Result { - Ok(NagaReflect { - vertex: value.vertex, - fragment: value.fragment, - }) - } -} - -impl TryFrom<&GlslangCompilation> for NagaReflect { - type Error = ShaderReflectError; - - fn try_from(value: &GlslangCompilation) -> Result { - 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, - span: u32, -} - -impl TryFrom for Ubo { - type Error = Infallible; - - fn try_from(value: Type) -> Result { - 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, +// span: u32, +// } +// +// impl TryFrom for Ubo { +// type Error = Infallible; +// +// fn try_from(value: Type) -> Result { +// 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 { - // 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 { + 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:#?}"); + // } } diff --git a/librashader-runtime-wgpu/Cargo.toml b/librashader-runtime-wgpu/Cargo.toml index 2364aeb..5195fe7 100644 --- a/librashader-runtime-wgpu/Cargo.toml +++ b/librashader-runtime-wgpu/Cargo.toml @@ -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" diff --git a/librashader-runtime-wgpu/src/graphics_pipeline.rs b/librashader-runtime-wgpu/src/graphics_pipeline.rs index f177568..d6f9e72 100644 --- a/librashader-runtime-wgpu/src/graphics_pipeline.rs +++ b/librashader-runtime-wgpu/src/graphics_pipeline.rs @@ -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, + pub bind_group_layouts: Vec +} + +pub fn add_ubo_binding(&mut self, ubo_meta: Option<&UboReflection>) { + +} + +pub fn add_texture_bindings<'a>(&mut self, textures: impl Iterator) { + 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 diff --git a/librashader-runtime-wgpu/src/lib.rs b/librashader-runtime-wgpu/src/lib.rs index 997e944..86ad583 100644 --- a/librashader-runtime-wgpu/src/lib.rs +++ b/librashader-runtime-wgpu/src/lib.rs @@ -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; \ No newline at end of file diff --git a/librashader-runtime-wgpu/src/util.rs b/librashader-runtime-wgpu/src/util.rs new file mode 100644 index 0000000..aae2164 --- /dev/null +++ b/librashader-runtime-wgpu/src/util.rs @@ -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 +} \ No newline at end of file diff --git a/test/extreme_basic.glsl b/test/extreme_basic.glsl new file mode 100644 index 0000000..52d487c --- /dev/null +++ b/test/extreme_basic.glsl @@ -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)); +} \ No newline at end of file diff --git a/test/extreme_basic.spv b/test/extreme_basic.spv new file mode 100644 index 0000000..e69de29 diff --git a/test/extreme_basic_split.frag.glsl b/test/extreme_basic_split.frag.glsl new file mode 100644 index 0000000..884ff32 --- /dev/null +++ b/test/extreme_basic_split.frag.glsl @@ -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)); +} \ No newline at end of file diff --git a/test/extreme_basic_split.spirt b/test/extreme_basic_split.spirt new file mode 100644 index 0000000..02f801a --- /dev/null +++ b/test/extreme_basic_split.spirt @@ -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, +} \ No newline at end of file diff --git a/test/extreme_basic_split.spirt.html b/test/extreme_basic_split.spirt.html new file mode 100644 index 0000000..3d62521 --- /dev/null +++ b/test/extreme_basic_split.spirt.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + +
+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,
+}
+ diff --git a/test/extreme_basic_split.spv b/test/extreme_basic_split.spv new file mode 100644 index 0000000..82d3468 Binary files /dev/null and b/test/extreme_basic_split.spv differ diff --git a/test/extreme_basic_split.structured.spirt b/test/extreme_basic_split.structured.spirt new file mode 100644 index 0000000..d22ae4c --- /dev/null +++ b/test/extreme_basic_split.structured.spirt @@ -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, +} \ No newline at end of file diff --git a/test/extreme_basic_split.structured.spirt.html b/test/extreme_basic_split.structured.spirt.html new file mode 100644 index 0000000..c26e13d --- /dev/null +++ b/test/extreme_basic_split.structured.spirt.html @@ -0,0 +1,114 @@ + + + + + + + + + + + + + +
+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,
+}
+