├── .clang-format ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── OVERVIEW.md ├── README.md ├── application ├── CMakeLists.txt ├── application.cpp ├── application.hpp ├── application_entry.cpp ├── application_glue.hpp ├── application_interface_query.cpp ├── events │ ├── CMakeLists.txt │ ├── application_events.hpp │ ├── application_wsi.cpp │ ├── application_wsi.hpp │ └── application_wsi_events.hpp ├── global │ ├── CMakeLists.txt │ ├── global_managers.cpp │ ├── global_managers.hpp │ ├── global_managers_init.cpp │ ├── global_managers_init.hpp │ └── global_managers_interface.hpp ├── input │ ├── CMakeLists.txt │ ├── input.cpp │ ├── input.hpp │ ├── input_sdl.cpp │ └── input_sdl.hpp ├── platforms │ ├── .dummy.cpp │ ├── CMakeLists.txt │ ├── android │ │ ├── build.gradle │ │ ├── external_layers │ │ │ └── README.txt │ │ ├── gradle │ │ │ ├── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle.properties │ │ │ ├── res │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ └── icon.png │ │ │ │ └── drawable-xxxhdpi │ │ │ │ │ └── icon.png │ │ │ ├── settings.gradle │ │ │ ├── settings_custom.gradle │ │ │ └── toplevel.build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── net │ │ │ │ └── themaister │ │ │ │ └── granite │ │ │ │ └── GraniteActivity.java │ │ │ └── res │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── themes.xml │ ├── application_android.cpp │ ├── application_headless.cpp │ ├── application_headless_wrapper.cpp │ ├── application_libretro.cpp │ ├── application_libretro_utils.cpp │ ├── application_libretro_utils.hpp │ ├── application_null.cpp │ ├── application_sdl3.cpp │ └── libretro │ │ ├── libretro.h │ │ └── libretro_vulkan.h ├── scene_viewer_application.cpp └── scene_viewer_application.hpp ├── assets ├── fonts │ └── font.ttf ├── shaders │ ├── blit.frag │ ├── blur.frag │ ├── debug_mesh.frag │ ├── debug_mesh.vert │ ├── debug_probe.frag │ ├── debug_probe.vert │ ├── decode │ │ ├── astc.comp │ │ ├── bc6.comp │ │ ├── bc7.comp │ │ ├── bitextract.h │ │ ├── eac.comp │ │ ├── etc2.comp │ │ ├── meshlet_decode.comp │ │ ├── rgtc.comp │ │ ├── rgtc.h │ │ └── s3tc.comp │ ├── dummy.frag │ ├── dummy_depth.frag │ ├── fft │ │ ├── fft.comp │ │ ├── fft_butterflies.h │ │ ├── fft_c2r.comp │ │ ├── fft_common.h │ │ ├── fft_data_type_extensions.h │ │ └── fft_r2c.comp │ ├── ground.frag │ ├── ground.vert │ ├── inc │ │ ├── bandlimited_pixel_filter.h │ │ ├── cube_coordinates.h │ │ ├── debug_channel.h │ │ ├── global_bindings.h │ │ ├── helper_invocation.h │ │ ├── meshlet_attribute_decode.h │ │ ├── meshlet_payload_constants.h │ │ ├── meshlet_payload_decode.h │ │ ├── meshlet_primitive_cull.h │ │ ├── meshlet_render.h │ │ ├── meshlet_render_types.h │ │ ├── prerotate.h │ │ ├── project_direction.h │ │ ├── render_parameters.h │ │ ├── render_target.h │ │ ├── srgb.h │ │ ├── subgroup_discard.h │ │ ├── subgroup_extensions.h │ │ └── two_component_normal.h │ ├── lights │ │ ├── atmospheric_scatter.h │ │ ├── clusterer.h │ │ ├── clusterer_bindless.h │ │ ├── clusterer_bindless_binning.comp │ │ ├── clusterer_bindless_binning_decal.comp │ │ ├── clusterer_bindless_buffers.h │ │ ├── clusterer_bindless_setup.comp │ │ ├── clusterer_bindless_spot_transform.comp │ │ ├── clusterer_bindless_z_range.comp │ │ ├── clusterer_bindless_z_range_opt.comp │ │ ├── clusterer_data.h │ │ ├── clusterer_legacy.h │ │ ├── clustering.comp │ │ ├── clustering.frag │ │ ├── clustering.vert │ │ ├── directional.frag │ │ ├── directional.vert │ │ ├── fog.frag │ │ ├── fog.h │ │ ├── fog.vert │ │ ├── fog_accumulate.comp │ │ ├── fog_light_density.comp │ │ ├── lighting.h │ │ ├── lighting_data.h │ │ ├── lighting_irradiance.h │ │ ├── lighting_resources.h │ │ ├── lighting_scatter.h │ │ ├── linear_clamp_sampler.h │ │ ├── linear_geometry_sampler.h │ │ ├── linear_shadow_sampler.h │ │ ├── pbr.h │ │ ├── pcf.h │ │ ├── point.frag │ │ ├── point.h │ │ ├── point.vert │ │ ├── resolve_esm.frag │ │ ├── resolve_vsm.frag │ │ ├── spot.frag │ │ ├── spot.h │ │ ├── spot.vert │ │ ├── volumetric_decal.h │ │ ├── volumetric_diffuse.h │ │ ├── volumetric_fog.frag │ │ ├── volumetric_fog.h │ │ ├── volumetric_fog.vert │ │ ├── volumetric_gbuffer_copy.comp │ │ ├── volumetric_hemisphere_integral.comp │ │ ├── volumetric_light_average.comp │ │ ├── volumetric_light_clear_atomic.comp │ │ ├── volumetric_light_compute_fallback.comp │ │ ├── volumetric_light_cull_texels.comp │ │ ├── volumetric_light_setup_sky.comp │ │ ├── volumetric_probe_hash.h │ │ └── vsm.h │ ├── line_ui.vert │ ├── ocean │ │ ├── bake_maps.comp │ │ ├── cull_blocks.comp │ │ ├── generate_fft.comp │ │ ├── init_counter_buffer.comp │ │ ├── mipmap.comp │ │ ├── ocean.frag │ │ ├── ocean.inc │ │ ├── ocean.vert │ │ ├── ocean_heightmap.vert │ │ ├── ocean_plane.vert │ │ └── update_lod.comp │ ├── post │ │ ├── SMAA.hlsl │ │ ├── aa_sharpen_resolve.frag │ │ ├── bloom_downsample.comp │ │ ├── bloom_downsample.frag │ │ ├── bloom_threshold.comp │ │ ├── bloom_threshold.frag │ │ ├── bloom_upsample.comp │ │ ├── bloom_upsample.frag │ │ ├── ffx-a │ │ │ └── ffx_a.h │ │ ├── ffx-cacao │ │ │ ├── CACAOApply_32.spv │ │ │ ├── CACAOClearLoadCounter_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur1_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur2_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur3_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur4_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur5_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur6_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur7_32.spv │ │ │ ├── CACAOEdgeSensitiveBlur8_32.spv │ │ │ ├── CACAOGenerateImportanceMap_32.spv │ │ │ ├── CACAOGenerateQ0_32.spv │ │ │ ├── CACAOGenerateQ1_32.spv │ │ │ ├── CACAOGenerateQ2_32.spv │ │ │ ├── CACAOGenerateQ3Base_32.spv │ │ │ ├── CACAOGenerateQ3_32.spv │ │ │ ├── CACAONonSmartApply_32.spv │ │ │ ├── CACAONonSmartHalfApply_32.spv │ │ │ ├── CACAOPostprocessImportanceMapA_32.spv │ │ │ ├── CACAOPostprocessImportanceMapB_32.spv │ │ │ ├── CACAOPrepareDownsampledDepthsAndMips_32.spv │ │ │ ├── CACAOPrepareDownsampledDepthsHalf_32.spv │ │ │ ├── CACAOPrepareDownsampledDepths_32.spv │ │ │ ├── CACAOPrepareDownsampledNormalsFromInputNormals_32.spv │ │ │ ├── CACAOPrepareDownsampledNormals_32.spv │ │ │ ├── CACAOPrepareNativeDepthsAndMips_32.spv │ │ │ ├── CACAOPrepareNativeDepthsHalf_32.spv │ │ │ ├── CACAOPrepareNativeDepths_32.spv │ │ │ ├── CACAOPrepareNativeNormalsFromInputNormals_32.spv │ │ │ ├── CACAOPrepareNativeNormals_32.spv │ │ │ ├── CACAOUpscaleBilateral5x5Half_32.spv │ │ │ ├── CACAOUpscaleBilateral5x5NonSmart_32.spv │ │ │ └── CACAOUpscaleBilateral5x5Smart_32.spv │ │ ├── ffx-fsr │ │ │ ├── ffx_fsr1.h │ │ │ ├── sharpen.frag │ │ │ ├── sharpen.vert │ │ │ ├── upscale.frag │ │ │ └── upscale.vert │ │ ├── ffx-spd │ │ │ ├── ffx_spd.h │ │ │ └── spd.comp │ │ ├── ffx-sssr │ │ │ ├── apply.frag │ │ │ ├── apply.vert │ │ │ ├── build_indirect.comp │ │ │ ├── classify.comp │ │ │ ├── sssr_util.h │ │ │ ├── trace_fallback.comp │ │ │ └── trace_primary.comp │ │ ├── fxaa.frag │ │ ├── hiz.comp │ │ ├── lanczos2.frag │ │ ├── lanczos2.h │ │ ├── luminance.comp │ │ ├── pq10_encode.frag │ │ ├── reprojection.h │ │ ├── reprojection_color_space.h │ │ ├── smaa_blend_weight.frag │ │ ├── smaa_blend_weight.vert │ │ ├── smaa_common.h │ │ ├── smaa_edge_detection.frag │ │ ├── smaa_edge_detection.vert │ │ ├── smaa_neighbor_blend.frag │ │ ├── smaa_neighbor_blend.vert │ │ ├── smaa_t2x_resolve.frag │ │ ├── taa_resolve.frag │ │ ├── tonemap.frag │ │ ├── vsm_down_blur.frag │ │ └── vsm_up_blur.frag │ ├── quad.vert │ ├── reconstruct_mv.frag │ ├── scaled_readback.frag │ ├── skybox.frag │ ├── skybox.vert │ ├── skybox_latlon.frag │ ├── skycylinder.frag │ ├── skycylinder.vert │ ├── sprite.frag │ ├── sprite.vert │ ├── static_mesh.frag │ ├── static_mesh.vert │ ├── static_mesh_depth.frag │ ├── static_mesh_mv.frag │ ├── texture_plane.frag │ ├── texture_plane.vert │ ├── util │ │ ├── chroma_downsample.comp │ │ ├── copy_buffer_to_image_3d.comp │ │ ├── ibl_diffuse.frag │ │ ├── ibl_specular.frag │ │ ├── rgb_scale.comp │ │ ├── rgb_to_yuv.comp │ │ └── yuv_to_rgb.comp │ ├── water_tint.frag │ └── water_tint.vert └── textures │ ├── background.png │ ├── checkerboard.png │ ├── ibl_brdf_lut.gtx │ └── smaa │ ├── area.gtx │ └── search.gtx ├── audio ├── CMakeLists.txt ├── audio_events.hpp ├── audio_interface.cpp ├── audio_interface.hpp ├── audio_mixer.cpp ├── audio_mixer.hpp ├── audio_oboe.cpp ├── audio_oboe.hpp ├── audio_pulse.cpp ├── audio_pulse.hpp ├── audio_resampler.cpp ├── audio_resampler.hpp ├── audio_wasapi.cpp ├── audio_wasapi.hpp ├── dsp │ ├── audio_fft_eq.cpp │ ├── audio_fft_eq.hpp │ ├── dsp.cpp │ ├── dsp.hpp │ ├── pole_zero_filter_design.cpp │ ├── pole_zero_filter_design.hpp │ ├── sinc_resampler.cpp │ ├── sinc_resampler.hpp │ ├── tone_filter.cpp │ ├── tone_filter.hpp │ ├── tone_filter_stream.cpp │ └── tone_filter_stream.hpp ├── vorbis_stream.cpp └── vorbis_stream.hpp ├── compiler ├── CMakeLists.txt ├── compiler.cpp └── compiler.hpp ├── ecs ├── CMakeLists.txt ├── ecs.cpp └── ecs.hpp ├── event ├── CMakeLists.txt ├── event.cpp └── event.hpp ├── filesystem ├── CMakeLists.txt ├── android │ ├── android.cpp │ └── android.hpp ├── asset_manager.cpp ├── asset_manager.hpp ├── filesystem.cpp ├── filesystem.hpp ├── linux │ ├── os_filesystem.cpp │ └── os_filesystem.hpp ├── netfs │ ├── fs-netfs.cpp │ └── fs-netfs.hpp ├── volatile_source.hpp └── windows │ ├── os_filesystem.cpp │ └── os_filesystem.hpp ├── math ├── CMakeLists.txt ├── aabb.cpp ├── aabb.hpp ├── docs │ └── squad.md ├── frustum.cpp ├── frustum.hpp ├── interpolation.cpp ├── interpolation.hpp ├── math.cpp ├── math.hpp ├── muglm │ ├── matrix_helper.hpp │ ├── muglm.cpp │ ├── muglm.hpp │ ├── muglm_impl.hpp │ └── muglm_test.cpp ├── render_parameters.hpp ├── simd.hpp ├── simd_headers.hpp ├── transforms.cpp └── transforms.hpp ├── network ├── looper.cpp ├── netfs.hpp ├── netfs_server.cpp ├── network.hpp ├── socket.cpp └── tcp_listener.cpp ├── path ├── CMakeLists.txt ├── path_utils.cpp └── path_utils.hpp ├── physics ├── CMakeLists.txt ├── physics_system.cpp └── physics_system.hpp ├── renderer ├── CMakeLists.txt ├── abstract_renderable.hpp ├── animation_system.cpp ├── animation_system.hpp ├── camera.cpp ├── camera.hpp ├── common_renderer_data.cpp ├── common_renderer_data.hpp ├── fft │ ├── fft.cpp │ ├── fft.hpp │ └── test │ │ ├── CMakeLists.txt │ │ ├── fft_bench.cpp │ │ └── fft_test.cpp ├── flat_renderer.cpp ├── flat_renderer.hpp ├── font.cpp ├── font.hpp ├── formats │ ├── gltf.cpp │ ├── gltf.hpp │ ├── scene_formats.cpp │ └── scene_formats.hpp ├── ground.cpp ├── ground.hpp ├── lights │ ├── clusterer.cpp │ ├── clusterer.hpp │ ├── decal_volume.cpp │ ├── decal_volume.hpp │ ├── deferred_lights.cpp │ ├── deferred_lights.hpp │ ├── light_info.hpp │ ├── lights.cpp │ ├── lights.hpp │ ├── volumetric_diffuse.cpp │ ├── volumetric_diffuse.hpp │ ├── volumetric_fog.cpp │ ├── volumetric_fog.hpp │ └── volumetric_fog_region.hpp ├── material.hpp ├── material_manager.cpp ├── material_manager.hpp ├── material_util.cpp ├── material_util.hpp ├── mesh.cpp ├── mesh.hpp ├── mesh_util.cpp ├── mesh_util.hpp ├── node.cpp ├── node.hpp ├── ocean.cpp ├── ocean.hpp ├── post │ ├── aa.cpp │ ├── aa.hpp │ ├── ffx-cacao │ │ ├── inc │ │ │ ├── ffx_cacao.h │ │ │ └── ffx_cacao_impl.h │ │ └── src │ │ │ ├── build_shaders_spirv.sh │ │ │ ├── cauldron-dxc-wrapper.sh │ │ │ ├── ffx_cacao.cpp │ │ │ ├── ffx_cacao.hlsl │ │ │ ├── ffx_cacao_bindings.hlsl │ │ │ ├── ffx_cacao_defines.h │ │ │ └── ffx_cacao_impl.cpp │ ├── fxaa.cpp │ ├── fxaa.hpp │ ├── hdr.cpp │ ├── hdr.hpp │ ├── smaa.cpp │ ├── smaa.hpp │ ├── spd.cpp │ ├── spd.hpp │ ├── ssao.cpp │ ├── ssao.hpp │ ├── ssr.cpp │ ├── ssr.hpp │ ├── temporal.cpp │ └── temporal.hpp ├── render_components.cpp ├── render_components.hpp ├── render_context.cpp ├── render_context.hpp ├── render_graph.cpp ├── render_graph.hpp ├── render_queue.cpp ├── render_queue.hpp ├── renderer.cpp ├── renderer.hpp ├── renderer_enums.hpp ├── scene.cpp ├── scene.hpp ├── scene_loader.cpp ├── scene_loader.hpp ├── scene_renderer.cpp ├── scene_renderer.hpp ├── shader_suite.cpp ├── shader_suite.hpp ├── simple_renderer.cpp ├── simple_renderer.hpp ├── sprite.cpp ├── sprite.hpp ├── threaded_scene.cpp ├── threaded_scene.hpp └── utils │ ├── blue │ └── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.hpp │ ├── image_utils.cpp │ └── image_utils.hpp ├── scene-export ├── CMakeLists.txt ├── camera_export.cpp ├── camera_export.hpp ├── gltf_export.cpp ├── gltf_export.hpp ├── light_export.cpp ├── light_export.hpp ├── meshlet_export.cpp ├── meshlet_export.hpp ├── obj.cpp ├── obj.hpp ├── rgtc_compressor.cpp ├── rgtc_compressor.hpp ├── texture_compression.cpp ├── texture_compression.hpp ├── texture_utils.cpp ├── texture_utils.hpp ├── tmx_parser.cpp └── tmx_parser.hpp ├── self-test ├── CMakeLists.txt └── link_test.cpp ├── slangmosh ├── CMakeLists.txt └── slangmosh.cpp ├── tests ├── CMakeLists.txt ├── animation_rail_test.cpp ├── asset_manager_test.cpp ├── assets │ ├── shaders │ │ ├── additive.frag │ │ ├── bandlimited_quad.vert │ │ ├── bindless.frag │ │ ├── bitmap_mesh.frag │ │ ├── bitmap_mesh.vert │ │ ├── burn.frag │ │ ├── clustering_viz.frag │ │ ├── clustering_viz.vert │ │ ├── compute_add.comp │ │ ├── compute_bucket_allocate.comp │ │ ├── copy_image.comp │ │ ├── debug_channel.comp │ │ ├── dgc.frag │ │ ├── dgc.vert │ │ ├── dgc_compute.comp │ │ ├── divergent_lod.frag │ │ ├── fill_color_spec_constant.frag │ │ ├── fill_depth.frag │ │ ├── fill_depth_checkerboard.frag │ │ ├── fill_flat.frag │ │ ├── fill_image.comp │ │ ├── hdrtest.frag │ │ ├── hdrtest.vert │ │ ├── hdrtest_srgb_gradient.frag │ │ ├── hdrtest_srgb_gradient.vert │ │ ├── image_write.comp │ │ ├── meshlet_cull.comp │ │ ├── meshlet_cull_aabb.comp │ │ ├── meshlet_debug.frag │ │ ├── meshlet_debug.mesh │ │ ├── meshlet_debug.mesh.frag │ │ ├── meshlet_debug.task │ │ ├── meshlet_debug.vert │ │ ├── meshlet_debug_plain.mesh │ │ ├── mrt_debug.frag │ │ ├── mrt_quad.frag │ │ ├── multi_draw_indirect.frag │ │ ├── multi_draw_indirect.vert │ │ ├── multiview_debug.frag │ │ ├── multiview_quad.frag │ │ ├── multiview_quad.vert │ │ ├── music_viz.frag │ │ ├── music_viz.vert │ │ ├── query_lod.frag │ │ ├── query_lod_debug.frag │ │ ├── robustness2.comp │ │ ├── sample_cube_array.frag │ │ ├── sample_pcf.frag │ │ ├── sampler_precision.comp │ │ ├── subgroup.comp │ │ ├── test_quad.frag │ │ ├── test_quad.vert │ │ ├── triangle.frag │ │ ├── triangle.mesh │ │ ├── triangle.task │ │ ├── triangle.vert │ │ ├── triangle_mesh.frag │ │ ├── video.frag │ │ ├── video.vert │ │ ├── write_swapchain.comp │ │ └── yuv420p-sample.frag │ └── textures │ │ └── sprite.png ├── async_compute_present.cpp ├── async_spec_constant.cpp ├── atomic_append_buffer_test.cpp ├── audio_application.cpp ├── audio_test.cpp ├── bandlimited_pixel_test.cpp ├── basic_compute.cpp ├── bindless_test.cpp ├── clustering_visualizer.cpp ├── coherency.cpp ├── conservative_raster_test.cpp ├── controller_test.cpp ├── cube_array_test.cpp ├── d3d11_interop_test.cpp ├── d3d12_interop_test.cpp ├── debug_channel.cpp ├── dgc-test-compute.sh ├── dgc-test-graphics.sh ├── dgc_test_compute.cpp ├── dgc_test_graphics.cpp ├── divergent_lod_test.cpp ├── ecs_test.cpp ├── external_objects.cpp ├── fragment_output_components.cpp ├── gl_interop_test.cpp ├── glad │ ├── include │ │ ├── KHR │ │ │ └── khrplatform.h │ │ └── glad │ │ │ └── glad.h │ └── src │ │ └── glad.c ├── gltf_viewer_simple.cpp ├── hdr_test.cpp ├── hemisphere_integration.cpp ├── hiz.cpp ├── image_query_lod.cpp ├── imported_host.cpp ├── imported_host_concurrent.cpp ├── intrusive_ptr_test.cpp ├── latency_test.cpp ├── linear_image_test.cpp ├── linkage_test.cpp ├── lru_cache_test.cpp ├── meshlet_viewer.cpp ├── meshopt_sandbox.cpp ├── mrt_color_mask.cpp ├── multi_draw_indirect.cpp ├── multiview_test.cpp ├── pcf_test.cpp ├── performance_query.cpp ├── render_graph_sandbox.cpp ├── resampler_test.cpp ├── robustness2.cpp ├── sampler_precision.cpp ├── setup_android_test.sh ├── simd_test.cpp ├── subgroup.cpp ├── texture_decoder_test.cpp ├── thread_group_test.cpp ├── tone_filter_bench.cpp ├── triangle.cpp ├── triangle_mesh.cpp ├── ui_sandbox.cpp ├── unordered_array_test.cpp ├── video_encode_test.cpp ├── video_player.cpp ├── ycbcr_sampling.cpp └── z_binning_test.cpp ├── third_party ├── CMakeLists.txt ├── dirent │ └── dirent.h ├── mikktspace │ ├── CMakeLists.txt │ ├── mikktspace.c │ └── mikktspace.h ├── rapidjson_wrapper.hpp ├── renderdoc │ ├── CMakeLists.txt │ └── renderdoc_app.h └── stb │ ├── CMakeLists.txt │ ├── stb_image.c │ ├── stb_truetype.c │ └── stb_vorbis.h ├── threading ├── CMakeLists.txt ├── task_composer.cpp ├── task_composer.hpp ├── thread_group.cpp ├── thread_group.hpp ├── thread_latch.cpp └── thread_latch.hpp ├── toolchains ├── aarch64.cmake └── armhf.cmake ├── tools ├── CMakeLists.txt ├── aa_bench.cpp ├── aa_bench_to_csv.py ├── android-cmake-wrapper.sh ├── bench_aa.py ├── bin_to_text.py ├── bitmap_mesh.cpp ├── bitmap_to_mesh.cpp ├── bitmap_to_mesh.hpp ├── blobify.py ├── brdf_lut_generate.cpp ├── build-steamrt-inside.sh ├── build-steamrt.sh ├── build_smaa_luts.cpp ├── convert_cube_to_environment.cpp ├── convert_equirect_to_environment.cpp ├── create_android_build.py ├── gltf_repacker.cpp ├── gtx_cat.cpp ├── gtx_convert.cpp ├── image_compare.cpp ├── image_packer.cpp ├── obj_to_gltf.cpp ├── setup_android_toolchain.sh ├── smaa │ ├── AreaTex.h │ └── SearchTex.h ├── sweep_scene.py ├── sweep_stat_analysis.py ├── sweep_stat_diff.py ├── sweep_to_csv.py └── texture_viewer.cpp ├── ui ├── CMakeLists.txt ├── click_button.cpp ├── click_button.hpp ├── horizontal_packing.cpp ├── horizontal_packing.hpp ├── image_widget.cpp ├── image_widget.hpp ├── label.cpp ├── label.hpp ├── slider.cpp ├── slider.hpp ├── toggle_button.cpp ├── toggle_button.hpp ├── ui_manager.cpp ├── ui_manager.hpp ├── vertical_packing.cpp ├── vertical_packing.hpp ├── widget.cpp ├── widget.hpp ├── window.cpp └── window.hpp ├── util ├── CMakeLists.txt ├── aligned_alloc.cpp ├── aligned_alloc.hpp ├── arena_allocator.cpp ├── arena_allocator.hpp ├── array_view.hpp ├── async_object_sink.hpp ├── atomic_append_buffer.hpp ├── bitops.hpp ├── cli_parser.cpp ├── cli_parser.hpp ├── compile_time_hash.hpp ├── dynamic_array.hpp ├── dynamic_library.cpp ├── dynamic_library.hpp ├── enum_cast.hpp ├── environment.cpp ├── environment.hpp ├── generational_handle.hpp ├── hash.hpp ├── hashmap.hpp ├── intrusive.hpp ├── intrusive_hash_map.hpp ├── intrusive_list.hpp ├── logging.cpp ├── logging.hpp ├── lru_cache.hpp ├── message_queue.cpp ├── message_queue.hpp ├── no_init_pod.hpp ├── object_pool.hpp ├── radix_sorter.hpp ├── read_write_lock.hpp ├── small_callable.hpp ├── small_vector.hpp ├── stack_allocator.hpp ├── string_helpers.cpp ├── string_helpers.hpp ├── temporary_hashmap.hpp ├── thread_id.cpp ├── thread_id.hpp ├── thread_name.cpp ├── thread_name.hpp ├── thread_priority.cpp ├── thread_priority.hpp ├── timeline_trace_file.cpp ├── timeline_trace_file.hpp ├── timer.cpp ├── timer.hpp ├── unordered_array.hpp ├── unstable_remove_if.hpp └── variant.hpp ├── video ├── CMakeLists.txt ├── ffmpeg_decode.cpp ├── ffmpeg_decode.hpp ├── ffmpeg_encode.cpp ├── ffmpeg_encode.hpp ├── ffmpeg_hw_device.cpp ├── ffmpeg_hw_device.hpp ├── pyro_protocol.h ├── slangmosh_decode.json ├── slangmosh_decode_iface.hpp ├── slangmosh_encode.json └── slangmosh_encode_iface.hpp ├── viewer ├── CMakeLists.txt ├── physics_sandbox.cpp ├── quirks.json ├── setup_android_build.sh ├── viewer.cpp └── viewer_config.json └── vulkan ├── CMakeLists.txt ├── buffer.cpp ├── buffer.hpp ├── buffer_pool.cpp ├── buffer_pool.hpp ├── command_buffer.cpp ├── command_buffer.hpp ├── command_pool.cpp ├── command_pool.hpp ├── context.cpp ├── context.hpp ├── cookie.cpp ├── cookie.hpp ├── descriptor_set.cpp ├── descriptor_set.hpp ├── device.cpp ├── device.hpp ├── device_fossilize.cpp ├── device_fossilize.hpp ├── event_manager.cpp ├── event_manager.hpp ├── fence.cpp ├── fence.hpp ├── fence_manager.cpp ├── fence_manager.hpp ├── format.hpp ├── image.cpp ├── image.hpp ├── indirect_layout.cpp ├── indirect_layout.hpp ├── limits.hpp ├── managers ├── resource_manager.cpp ├── resource_manager.hpp ├── shader_manager.cpp └── shader_manager.hpp ├── memory_allocator.cpp ├── memory_allocator.hpp ├── mesh ├── meshlet.cpp └── meshlet.hpp ├── pipeline_cache.cpp ├── pipeline_cache.hpp ├── pipeline_event.cpp ├── pipeline_event.hpp ├── post-mortem ├── CMakeLists.txt ├── NsightAftermathGpuCrashTracker.cpp ├── NsightAftermathGpuCrashTracker.h ├── NsightAftermathHelpers.h ├── post_mortem.cpp └── post_mortem.hpp ├── query_pool.cpp ├── query_pool.hpp ├── quirks.hpp ├── render_pass.cpp ├── render_pass.hpp ├── renderdoc_capture.cpp ├── sampler.cpp ├── sampler.hpp ├── semaphore.cpp ├── semaphore.hpp ├── semaphore_manager.cpp ├── semaphore_manager.hpp ├── shader.cpp ├── shader.hpp ├── texture ├── memory_mapped_texture.cpp ├── memory_mapped_texture.hpp ├── texture_decoder.cpp ├── texture_decoder.hpp ├── texture_files.cpp ├── texture_files.hpp ├── texture_format.cpp └── texture_format.hpp ├── type_to_string.hpp ├── vulkan_common.hpp ├── vulkan_headers.hpp ├── vulkan_prerotate.hpp ├── wsi.cpp ├── wsi.hpp ├── wsi_dxgi.cpp └── wsi_dxgi.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | /build 3 | /.idea 4 | *.o 5 | CMakeFiles 6 | CMakeCache 7 | /viewer/.gradle 8 | /viewer/gradlew* 9 | /viewer/gradle 10 | /viewer/local.properties 11 | *.iml 12 | /viewer/app/build 13 | /viewer/app/.externalNativeBuild 14 | __pycache__ 15 | perf.data 16 | /viewer/app/assets 17 | /viewer/app/build 18 | /application/platforms/android/build 19 | /cmake-build-debug 20 | /cmake-build-release 21 | /cmake-build-relwithdebinfo 22 | /application/platforms/android/renderdoc 23 | /viewer/settings.gradle 24 | /viewer/build.gradle 25 | /viewer/android 26 | /viewer/assets 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /application/application_interface_query.cpp: -------------------------------------------------------------------------------- 1 | #include "application_glue.hpp" 2 | GRANITE_APPLICATION_DECL_DEFAULT_QUERY() -------------------------------------------------------------------------------- /application/events/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-application-events 2 | application_wsi.hpp 3 | application_wsi.cpp application_wsi_events.hpp 4 | application_events.hpp) 5 | target_include_directories(granite-application-events PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 6 | target_link_libraries(granite-application-events 7 | PRIVATE granite-vulkan granite-event granite-input granite-application-global) 8 | -------------------------------------------------------------------------------- /application/global/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-application-global 2 | global_managers.hpp global_managers.cpp) 3 | target_include_directories(granite-application-global PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 4 | target_link_libraries(granite-application-global PUBLIC granite-util) 5 | 6 | add_granite_internal_lib(granite-application-global-init 7 | global_managers_init.hpp global_managers_init.cpp) 8 | target_include_directories(granite-application-global-init PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 9 | target_link_libraries(granite-application-global-init 10 | PUBLIC granite-application-global 11 | PRIVATE granite-threading granite-event granite-filesystem) 12 | 13 | if (TARGET granite-renderer) 14 | target_link_libraries(granite-application-global-init PRIVATE granite-renderer granite-ui) 15 | target_compile_definitions(granite-application-global-init PRIVATE HAVE_GRANITE_RENDERER) 16 | endif() 17 | 18 | if (GRANITE_AUDIO) 19 | target_link_libraries(granite-application-global-init PRIVATE granite-audio) 20 | endif() 21 | 22 | if (GRANITE_BULLET) 23 | target_link_libraries(granite-application-global-init PRIVATE granite-physics) 24 | endif() 25 | 26 | add_library(granite-application-global-interface INTERFACE) 27 | target_include_directories(granite-application-global-interface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -------------------------------------------------------------------------------- /application/global/global_managers_init.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "global_managers.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace Global 30 | { 31 | void init(ManagerFeatureFlags flags = MANAGER_FEATURE_DEFAULT_BITS, 32 | unsigned max_threads = UINT_MAX, float audio_sample_rate = -1.0f); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /application/input/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-input input.hpp input.cpp) 2 | target_include_directories(granite-input PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(granite-input PUBLIC granite-util granite-event granite-math) 4 | 5 | if (${GRANITE_PLATFORM} MATCHES "SDL") 6 | add_granite_internal_static_lib(granite-input-sdl input_sdl.cpp input_sdl.hpp) 7 | target_link_libraries(granite-input-sdl PUBLIC granite-input) 8 | if (GRANITE_SYSTEM_SDL) 9 | find_package(SDL3 REQUIRED) 10 | target_link_libraries(granite-input-sdl PUBLIC SDL3::SDL3-shared) 11 | else() 12 | target_link_libraries(granite-input-sdl PUBLIC SDL3-static) 13 | endif() 14 | endif() -------------------------------------------------------------------------------- /application/platforms/.dummy.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/.dummy.cpp -------------------------------------------------------------------------------- /application/platforms/android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | namespace "net.themaister.granite" 5 | compileSdkVersion 34 6 | buildFeatures.prefab true 7 | 8 | defaultConfig { 9 | minSdkVersion 26 10 | targetSdkVersion 34 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation 'androidx.appcompat:appcompat:1.5.1' 16 | implementation 'com.google.android.material:material:1.7.0' 17 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 18 | implementation 'androidx.core:core:1.9.0' 19 | implementation 'androidx.games:games-activity:2.0.2' 20 | } 21 | -------------------------------------------------------------------------------- /application/platforms/android/external_layers/README.txt: -------------------------------------------------------------------------------- 1 | Place {arm64-v8a,armeabi-v7a}/libVkLayer_*.so here to have it bundled in the APK. 2 | -------------------------------------------------------------------------------- /application/platforms/android/gradle/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /application/platforms/android/gradle/gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX=true 2 | -------------------------------------------------------------------------------- /application/platforms/android/gradle/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/android/gradle/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /application/platforms/android/gradle/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/android/gradle/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /application/platforms/android/gradle/res/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/android/gradle/res/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /application/platforms/android/gradle/res/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/android/gradle/res/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /application/platforms/android/gradle/res/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/application/platforms/android/gradle/res/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /application/platforms/android/gradle/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'granite:android' 2 | project(':granite:android').projectDir = file('$$GRANITE_ANDROID_ACTIVITY_PATH$$') 3 | include '$$APP$$' 4 | -------------------------------------------------------------------------------- /application/platforms/android/gradle/settings_custom.gradle: -------------------------------------------------------------------------------- 1 | include 'granite:android' 2 | project(':granite:android').projectDir = file('$$GRANITE_ANDROID_ACTIVITY_PATH$$') 3 | include 'custom:android' 4 | project(':custom:android').projectDir = file('$$ANDROID_ACTIVITY_PATH$$') 5 | include '$$APP$$' 6 | -------------------------------------------------------------------------------- /application/platforms/android/gradle/toplevel.build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:8.3.0' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | task clean(type: Delete) { 25 | delete rootProject.buildDir 26 | } 27 | -------------------------------------------------------------------------------- /application/platforms/android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /application/platforms/android/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /application/platforms/application_headless_wrapper.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "application_glue.hpp" 24 | 25 | namespace Granite 26 | { 27 | int application_main( 28 | bool (*query_application_interface)(ApplicationQuery, void *, size_t), 29 | Application *(*create_application)(int, char **), int argc, char *argv[]) 30 | { 31 | return application_main_headless(query_application_interface, create_application, argc, argv); 32 | } 33 | } -------------------------------------------------------------------------------- /application/platforms/application_null.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "../application_glue.hpp" 24 | #include 25 | 26 | namespace Granite 27 | { 28 | int application_main( 29 | bool (*query_application_interface)(ApplicationQuery, void *, size_t), 30 | Application *(*create_application)(int, char **), int argc, char *argv[]) 31 | { 32 | (void)query_application_interface; 33 | (void)create_application; 34 | return 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assets/fonts/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/fonts/font.ttf -------------------------------------------------------------------------------- /assets/shaders/blit.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 vUV; 3 | layout(location = 0) out vec4 FragColor; 4 | layout(set = 0, binding = 0) uniform sampler2D uImage; 5 | 6 | layout(constant_id = 0) const float Scale = 1.0; 7 | 8 | void main() 9 | { 10 | FragColor = Scale * textureLod(uImage, vUV, 0.0); 11 | } -------------------------------------------------------------------------------- /assets/shaders/debug_mesh.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision mediump float; 3 | 4 | #if HAVE_VERTEX_COLOR 5 | layout(location = 0) in mediump vec4 vColor; 6 | #endif 7 | 8 | layout(location = 0) out vec4 FragColor; 9 | 10 | void main() 11 | { 12 | #if HAVE_VERTEX_COLOR 13 | FragColor = vColor; 14 | #else 15 | FragColor = vec4(1.0); 16 | #endif 17 | } -------------------------------------------------------------------------------- /assets/shaders/debug_mesh.vert: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | 3 | #include "inc/render_parameters.h" 4 | 5 | layout(location = 0) in highp vec3 Position; 6 | 7 | #if HAVE_VERTEX_COLOR 8 | layout(location = 1) in mediump vec4 Color; 9 | layout(location = 0) out mediump vec4 vColor; 10 | #endif 11 | 12 | layout(std430, push_constant) uniform Model 13 | { 14 | mat4 MVP; 15 | } registers; 16 | 17 | #include "inc/prerotate.h" 18 | 19 | void main() 20 | { 21 | gl_Position = registers.MVP * vec4(Position, 1.0); 22 | #if HAVE_VERTEX_COLOR 23 | vColor = Color; 24 | #endif 25 | prerotate_fixup_clip_xy(); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /assets/shaders/debug_probe.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #if defined(RENDERER_FORWARD) 4 | #include "inc/subgroup_extensions.h" 5 | #endif 6 | 7 | #include "inc/render_target.h" 8 | 9 | layout(set = 2, binding = 0) uniform sampler3D uProbe; 10 | layout(set = 3, binding = 0) uniform UBO 11 | { 12 | vec3 pos; 13 | float radius; 14 | vec3 tex_coord; 15 | }; 16 | 17 | layout(location = 0) in vec3 vNormal; 18 | 19 | void main() 20 | { 21 | vec3 normal = normalize(vNormal); 22 | vec3 normal2 = normal * normal; 23 | vec3 normal_offsets = mix(vec3(0.0), vec3(1.0 / 6.0), lessThan(normal, vec3(0.0))); 24 | 25 | float base_x = tex_coord.x / 6.0; 26 | float x_offset = base_x + (0.0 / 3.0) + normal_offsets.x; 27 | float y_offset = base_x + (1.0 / 3.0) + normal_offsets.y; 28 | float z_offset = base_x + (2.0 / 3.0) + normal_offsets.z; 29 | 30 | vec3 result = 31 | normal2.x * textureLod(uProbe, vec3(x_offset, tex_coord.yz), 0.0).rgb + 32 | normal2.y * textureLod(uProbe, vec3(y_offset, tex_coord.yz), 0.0).rgb + 33 | normal2.z * textureLod(uProbe, vec3(z_offset, tex_coord.yz), 0.0).rgb; 34 | 35 | emit_render_target(result, vec4(0.0), normal, 0.0, 1.0, 0.0, vec3(0.0)); 36 | } 37 | -------------------------------------------------------------------------------- /assets/shaders/debug_probe.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "inc/render_parameters.h" 4 | 5 | layout(location = 0) in vec3 Position; 6 | layout(location = 0) out vec3 vNormal; 7 | 8 | layout(set = 3, binding = 0) uniform UBO 9 | { 10 | vec3 pos; 11 | float radius; 12 | vec3 tex_coord; 13 | }; 14 | 15 | void main() 16 | { 17 | vec3 World = Position * radius + pos; 18 | gl_Position = global.view_projection * vec4(World, 1.0); 19 | vNormal = Position; 20 | } 21 | -------------------------------------------------------------------------------- /assets/shaders/dummy.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision mediump float; 3 | 4 | void main() 5 | { 6 | } -------------------------------------------------------------------------------- /assets/shaders/dummy_depth.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #ifdef SHADOW_RESOLVE_VSM 4 | #include "inc/render_parameters.h" 5 | layout(location = 0) out vec2 VSM; 6 | #endif 7 | 8 | void main() 9 | { 10 | #ifdef SHADOW_RESOLVE_VSM 11 | #ifdef DIRECTIONAL_SHADOW_VSM 12 | float z = gl_FragCoord.z; 13 | #else 14 | float z = clip_z_to_linear(gl_FragCoord.z); 15 | #endif 16 | VSM = vec2(z, z * z); 17 | #endif 18 | } -------------------------------------------------------------------------------- /assets/shaders/inc/cube_coordinates.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_COORDINATES_H_ 2 | #define CUBE_COORDINATES_H_ 3 | 4 | const vec3 base_dirs[6] = vec3[]( 5 | vec3(1.0, 0.0, 0.0), 6 | vec3(-1.0, 0.0, 0.0), 7 | vec3(0.0, 1.0, 0.0), 8 | vec3(0.0, -1.0, 0.0), 9 | vec3(0.0, 0.0, 1.0), 10 | vec3(0.0, 0.0, -1.0)); 11 | 12 | const vec3 pos_du[6] = vec3[]( 13 | vec3(0.0, 0.0, -1.0), 14 | vec3(0.0, 0.0, +1.0), 15 | vec3(1.0, 0.0, 0.0), 16 | vec3(1.0, 0.0, 0.0), 17 | vec3(1.0, 0.0, 0.0), 18 | vec3(-1.0, 0.0, 0.0)); 19 | 20 | const vec3 pos_dv[6] = vec3[]( 21 | vec3(0.0, -1.0, 0.0), 22 | vec3(0.0, -1.0, 0.0), 23 | vec3(0.0, 0.0, +1.0), 24 | vec3(0.0, 0.0, -1.0), 25 | vec3(0.0, -1.0, 0.0), 26 | vec3(0.0, -1.0, 0.0)); 27 | 28 | #endif -------------------------------------------------------------------------------- /assets/shaders/inc/global_bindings.h: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_BINDINGS_H_ 2 | #define GLOBAL_BINDINGS_H_ 3 | 4 | #define BINDING_GLOBAL_TRANSFORM 0 5 | #define BINDING_GLOBAL_RENDER_PARAMETERS 1 6 | 7 | #define BINDING_GLOBAL_VOLUMETRIC_DIFFUSE_PARAMETERS 2 8 | #define BINDING_GLOBAL_VOLUMETRIC_FOG_PARAMETERS 3 9 | 10 | #define BINDING_GLOBAL_BRDF_TABLE 4 11 | #define BINDING_GLOBAL_DIRECTIONAL_SHADOW 5 12 | #define BINDING_GLOBAL_AMBIENT_OCCLUSION 6 13 | #define BINDING_GLOBAL_VOLUMETRIC_FOG 7 14 | 15 | #define BINDING_GLOBAL_CLUSTERER_PARAMETERS 8 16 | #define BINDING_GLOBAL_CLUSTER_IMAGE_LEGACY 9 17 | #define BINDING_GLOBAL_CLUSTER_SPOT_LEGACY 10 18 | #define BINDING_GLOBAL_CLUSTER_POINT_LEGACY 11 19 | 20 | #define BINDING_GLOBAL_CLUSTER_TRANSFORM 9 21 | #define BINDING_GLOBAL_CLUSTER_BITMASK 10 22 | #define BINDING_GLOBAL_CLUSTER_RANGE 11 23 | #define BINDING_GLOBAL_CLUSTER_BITMASK_DECAL 12 24 | #define BINDING_GLOBAL_CLUSTER_RANGE_DECAL 13 25 | 26 | #define BINDING_GLOBAL_LINEAR_SAMPLER 14 27 | #define BINDING_GLOBAL_SHADOW_SAMPLER 15 28 | #define BINDING_GLOBAL_GEOMETRY_SAMPLER 16 29 | 30 | #define BINDING_GLOBAL_VOLUMETRIC_DIFFUSE_FALLBACK_VOLUME 17 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /assets/shaders/inc/helper_invocation.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPER_INVOCATION_H_ 2 | #define HELPER_INVOCATION_H_ 3 | 4 | #ifdef DEMOTE 5 | #extension GL_EXT_demote_to_helper_invocation : require 6 | #endif 7 | 8 | bool is_helper_invocation() 9 | { 10 | #if defined(DEMOTE) 11 | return helperInvocationEXT(); 12 | #else 13 | return gl_HelperInvocation; 14 | #endif 15 | } 16 | 17 | #define HAS_IS_HELPER_INVOCATION 18 | 19 | #endif -------------------------------------------------------------------------------- /assets/shaders/inc/meshlet_attribute_decode.h: -------------------------------------------------------------------------------- 1 | #ifndef MESHLET_ATTRIBUTE_DECODE_H_ 2 | #define MESHLET_ATTRIBUTE_DECODE_H_ 3 | 4 | vec3 attribute_decode_snorm_exp_position(i16vec3 payload, int exponent) 5 | { 6 | vec3 fp_pos = ldexp(vec3(payload), ivec3(exponent)); 7 | return fp_pos; 8 | } 9 | 10 | vec2 attribute_decode_snorm_exp_uv(i16vec2 payload, int exponent) 11 | { 12 | return 0.5 * ldexp(vec2(payload), ivec2(exponent)) + 0.5; 13 | } 14 | 15 | mediump vec3 attribute_decode_oct_normal(mediump vec2 f) 16 | { 17 | mediump vec3 n = vec3(f.x, f.y, 1.0 - abs(f.x) - abs(f.y)); 18 | mediump float t = max(-n.z, 0.0); 19 | n.xy += mix(vec2(t), vec2(-t), greaterThanEqual(n.xy, vec2(0.0))); 20 | return normalize(n); 21 | } 22 | 23 | // Adapted from: https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/ 24 | // https://twitter.com/Stubbesaurus/status/9379947905532272640 25 | mediump mat2x4 attribute_decode_oct8_normal_tangent(u8vec4 payload, bool t_sign) 26 | { 27 | mediump vec4 f = vec4(i8vec4(payload)) / 127.0; 28 | mediump vec3 N = attribute_decode_oct_normal(f.xy); 29 | mediump vec3 T = attribute_decode_oct_normal(f.zw); 30 | return mat2x4(vec4(N, 0.0), vec4(T, t_sign ? -1.0 : 1.0)); 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /assets/shaders/inc/meshlet_payload_constants.h: -------------------------------------------------------------------------------- 1 | #ifndef MESHLET_PAYLOAD_CONSTANTS_H_ 2 | #define MESHLET_PAYLOAD_CONSTANTS_H_ 3 | 4 | #define MESHLET_PAYLOAD_MAX_ELEMENTS 256 5 | #define MESHLET_PAYLOAD_NUM_CHUNKS 8 6 | #define MESHLET_PAYLOAD_MAX_STREAMS 16 7 | 8 | const int MESHLET_STREAM_TYPE_PRIMITIVE = 0; 9 | const int MESHLET_STREAM_TYPE_POSITION = 1; 10 | const int MESHLET_STREAM_TYPE_NORMAL_TANGENT_OCT8 = 2; 11 | const int MESHLET_STREAM_TYPE_UV = 3; 12 | const int MESHLET_STREAM_TYPE_BONE_INDICES = 4; 13 | const int MESHLET_STREAM_TYPE_BONE_WEIGHTS = 5; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /assets/shaders/inc/meshlet_render_types.h: -------------------------------------------------------------------------------- 1 | #ifndef MESHLET_RENDER_TYPES_H_ 2 | #define MESHLET_RENDER_TYPES_H_ 3 | 4 | struct AABB 5 | { 6 | vec3 lo; float pad0; vec3 hi; float pad; 7 | }; 8 | 9 | struct Bound 10 | { 11 | vec4 center_radius; 12 | vec4 cone; 13 | }; 14 | 15 | struct TaskInfo 16 | { 17 | uint aabb_instance; 18 | uint node_instance; 19 | uint material_index; 20 | uint mesh_index_count; 21 | uint occluder_state_offset; 22 | }; 23 | 24 | struct CompactedDrawInfo 25 | { 26 | uint meshlet_index; 27 | uint node_offset; 28 | uint material_offset; 29 | }; 30 | 31 | #ifdef MESHLET_RENDER_TASK_HIERARCHICAL 32 | #if MESHLET_RENDER_TASK_HIERARCHICAL 33 | struct CompactedDrawInfoPayload 34 | { 35 | CompactedDrawInfo infos[32 * 32]; 36 | }; 37 | #else 38 | struct CompactedDrawInfoPayload 39 | { 40 | CompactedDrawInfo info; 41 | uint8_t offsets[32]; 42 | }; 43 | #endif 44 | #endif 45 | 46 | struct IndirectDrawMesh 47 | { 48 | uint primitive_offset; 49 | uint vertex_offset; 50 | uint primitive_count; 51 | uint vertex_count; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /assets/shaders/inc/prerotate.h: -------------------------------------------------------------------------------- 1 | #ifndef PREROTATE_H_ 2 | #define PREROTATE_H_ 3 | 4 | layout(constant_id = 8) const float PREROTATE_MATRIX_0 = 1.0; 5 | layout(constant_id = 9) const float PREROTATE_MATRIX_1 = 0.0; 6 | layout(constant_id = 10) const float PREROTATE_MATRIX_2 = 0.0; 7 | layout(constant_id = 11) const float PREROTATE_MATRIX_3 = 1.0; 8 | 9 | void prerotate_fixup_clip_xy() 10 | { 11 | gl_Position.xy = 12 | mat2(PREROTATE_MATRIX_0, PREROTATE_MATRIX_1, 13 | PREROTATE_MATRIX_2, PREROTATE_MATRIX_3) * 14 | gl_Position.xy; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /assets/shaders/inc/render_parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef RENDER_PARAMETERS_H 2 | #define RENDER_PARAMETERS_H 3 | 4 | #include "../inc/global_bindings.h" 5 | 6 | layout(set = 0, binding = BINDING_GLOBAL_TRANSFORM, std140) uniform RenderParameters 7 | { 8 | mat4 projection; 9 | mat4 view; 10 | mat4 view_projection; 11 | mat4 inv_projection; 12 | mat4 inv_view; 13 | mat4 inv_view_projection; 14 | mat4 local_view_projection; 15 | mat4 inv_local_view_projection; 16 | 17 | mat4 unjittered_view_projection; 18 | mat4 unjittered_inv_view_projection; 19 | mat4 unjittered_prev_view_projection; 20 | 21 | mat4 multiview_view_projection[4]; 22 | 23 | vec3 camera_position; 24 | vec3 camera_front; 25 | vec3 camera_right; 26 | vec3 camera_up; 27 | 28 | float z_near; 29 | float z_far; 30 | } global; 31 | 32 | float clip_z_to_linear(float clip_z) 33 | { 34 | vec2 z = global.inv_projection[2].zw * clip_z + global.inv_projection[3].zw; 35 | return -z.x / z.y; 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /assets/shaders/inc/srgb.h: -------------------------------------------------------------------------------- 1 | #ifndef SRGB_H_ 2 | #define SRGB_H_ 3 | 4 | mediump vec3 decode_srgb(mediump vec3 c) 5 | { 6 | bvec3 small = lessThanEqual(c, vec3(0.0404482362771082)); 7 | mediump vec3 small_side = c / 12.92; 8 | mediump vec3 pow_side = pow(((c + 0.055) / 1.055), vec3(2.4)); 9 | return clamp(mix(pow_side, small_side, small), vec3(0.0), vec3(1.0)); 10 | } 11 | 12 | mediump vec3 encode_srgb(mediump vec3 c) 13 | { 14 | bvec3 small = lessThanEqual(c, vec3(0.0031308)); 15 | mediump vec3 small_side = c * 12.92; 16 | mediump vec3 pow_side = 1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055; 17 | return clamp(mix(pow_side, small_side, small), vec3(0.0), vec3(1.0)); 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /assets/shaders/inc/subgroup_discard.h: -------------------------------------------------------------------------------- 1 | #ifndef SUBGROUP_DISCARD_H_ 2 | #define SUBGROUP_DISCARD_H_ 3 | 4 | #include "helper_invocation.h" 5 | #include "subgroup_extensions.h" 6 | 7 | void quad_discard_late(bool to_discard) 8 | { 9 | #if !defined(DEMOTE) 10 | if (to_discard) 11 | discard; 12 | #endif 13 | } 14 | 15 | void quad_discard_early(bool to_discard) 16 | { 17 | #if defined(DEMOTE) 18 | if (to_discard) 19 | demote; 20 | #elif defined(SUBGROUP_OPS) 21 | // Next best solution. Broadcast all lanes in the quad and decide. 22 | bvec4 lanes = bvec4( 23 | subgroupQuadBroadcast(to_discard, 0), 24 | subgroupQuadBroadcast(to_discard, 1), 25 | subgroupQuadBroadcast(to_discard, 2), 26 | subgroupQuadBroadcast(to_discard, 3)); 27 | if (all(lanes)) 28 | discard; 29 | #endif 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /assets/shaders/inc/subgroup_extensions.h: -------------------------------------------------------------------------------- 1 | #ifndef SUBGROUP_EXTENSIONS_H_ 2 | #define SUBGROUP_EXTENSIONS_H_ 3 | 4 | #ifdef SUBGROUP_OPS 5 | #extension GL_KHR_shader_subgroup_basic : require 6 | #extension GL_KHR_shader_subgroup_vote : require 7 | #extension GL_KHR_shader_subgroup_clustered : require 8 | #extension GL_KHR_shader_subgroup_ballot : require 9 | #extension GL_KHR_shader_subgroup_quad : require 10 | #extension GL_KHR_shader_subgroup_arithmetic : require 11 | #endif 12 | 13 | #ifdef SUBGROUP_SHUFFLE 14 | #extension GL_KHR_shader_subgroup_shuffle : require 15 | #endif 16 | 17 | #endif -------------------------------------------------------------------------------- /assets/shaders/inc/two_component_normal.h: -------------------------------------------------------------------------------- 1 | #ifndef TWO_COMPONENT_NORMAL_H_ 2 | #define TWO_COMPONENT_NORMAL_H_ 3 | 4 | mediump vec3 two_component_normal(mediump vec2 N) 5 | { 6 | return vec3(N, sqrt(max(1.0 - dot(N, N), 0.0))); 7 | } 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /assets/shaders/lights/clusterer.h: -------------------------------------------------------------------------------- 1 | #ifndef CLUSTERER_H_ 2 | #define CLUSTERER_H_ 3 | 4 | #ifdef CLUSTERER_BINDLESS 5 | #extension GL_EXT_nonuniform_qualifier : require 6 | #extension GL_EXT_samplerless_texture_functions : require 7 | #endif 8 | 9 | #include "../inc/subgroup_extensions.h" 10 | #include "clusterer_data.h" 11 | 12 | #ifdef CLUSTERER_BINDLESS 13 | #include "clusterer_bindless.h" 14 | #else 15 | #include "clusterer_legacy.h" 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /assets/shaders/lights/clusterer_bindless_buffers.h: -------------------------------------------------------------------------------- 1 | #ifndef CLUSTERER_BINDLESS_BUFFERS_H_ 2 | #define CLUSTERER_BINDLESS_BUFFERS_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | #include "clusterer_data.h" 6 | 7 | layout(std140, set = 0, binding = BINDING_GLOBAL_CLUSTERER_PARAMETERS) uniform ClusterParameters 8 | { 9 | ClustererParametersBindless cluster; 10 | }; 11 | 12 | layout(std430, set = 0, binding = BINDING_GLOBAL_CLUSTER_TRANSFORM) readonly buffer ClustererData 13 | { 14 | ClustererBindlessTransforms cluster_transforms; 15 | }; 16 | 17 | uint cluster_mask_range(uint mask, uvec2 range, uint start_index) 18 | { 19 | range.x = clamp(range.x, start_index, start_index + 32u); 20 | range.y = clamp(range.y + 1u, range.x, start_index + 32u); 21 | 22 | uint num_bits = range.y - range.x; 23 | uint range_mask = num_bits == 32 ? 24 | 0xffffffffu : 25 | ((1u << num_bits) - 1u) << (range.x - start_index); 26 | return mask & uint(range_mask); 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/clusterer_bindless_z_range.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(local_size_x = 64) in; 4 | 5 | layout(push_constant, std430) uniform Registers 6 | { 7 | uint num_lights; 8 | } registers; 9 | 10 | layout(set = 0, binding = 0, std430) readonly buffer ZRangesPerLight 11 | { 12 | uvec2 z_ranges[]; 13 | }; 14 | 15 | layout(set = 0, binding = 1, std430) writeonly buffer LightRange 16 | { 17 | uvec2 light_ranges[]; 18 | }; 19 | 20 | void main() 21 | { 22 | uint z_lo = 0xffffffffu; 23 | uint z_hi = 0u; 24 | uint z = gl_GlobalInvocationID.x; 25 | 26 | // Kinda brute force. A faster algorithm seems non-trivial. 27 | 28 | for (uint i = 0; i < registers.num_lights; i++) 29 | { 30 | uvec2 range = z_ranges[i]; 31 | if (z >= range.x && z <= range.y) 32 | { 33 | z_lo = i; 34 | break; 35 | } 36 | } 37 | 38 | int z_lo_int = max(int(z_lo), 0); 39 | 40 | for (int i = int(registers.num_lights) - 1; i >= z_lo_int; i--) 41 | { 42 | uvec2 range = z_ranges[i]; 43 | if (z >= range.x && z <= range.y) 44 | { 45 | z_hi = i; 46 | break; 47 | } 48 | } 49 | 50 | light_ranges[z] = uvec2(z_lo, z_hi); 51 | } -------------------------------------------------------------------------------- /assets/shaders/lights/clustering.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out vec4 vClip; 4 | 5 | layout(std140, set = 0, binding = 0) uniform Transforms 6 | { 7 | mat4 inverse_view_projection; 8 | }; 9 | 10 | void main() 11 | { 12 | gl_Position = vec4(Position, 1.0, 1.0); 13 | vClip = inverse_view_projection * vec4(Position, 0.0, 1.0); 14 | } -------------------------------------------------------------------------------- /assets/shaders/lights/directional.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out highp vec4 vClip; 4 | 5 | #define SHADOW_NUM_CASCADES 4 6 | 7 | layout(std140, set = 0, binding = 0) uniform Transforms 8 | { 9 | mat4 inverse_view_projection; 10 | mat4 transforms[SHADOW_NUM_CASCADES]; 11 | }; 12 | 13 | void main() 14 | { 15 | gl_Position = vec4(Position, 1.0, 1.0); 16 | vClip = inverse_view_projection * vec4(Position, 0.0, 1.0); 17 | } -------------------------------------------------------------------------------- /assets/shaders/lights/fog.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | precision highp int; 4 | 5 | #include "fog.h" 6 | 7 | layout(std430, push_constant) uniform Registers 8 | { 9 | mat4 inverse_view_projection; 10 | vec3 camera_pos; 11 | vec3 color; 12 | float falloff; 13 | } registers; 14 | 15 | layout(input_attachment_index = 3, set = 3, binding = 3) uniform highp subpassInput Depth; 16 | layout(location = 0) in highp vec4 vClip; 17 | layout(location = 0) out mediump vec4 FragColor; 18 | 19 | void main() 20 | { 21 | float depth = subpassLoad(Depth).x; 22 | vec4 clip = vClip + depth * registers.inverse_view_projection[2]; 23 | vec3 pos = clip.xyz / clip.w; 24 | vec3 eye_vec = pos - registers.camera_pos; 25 | FragColor = vec4(registers.color, fog_factor(eye_vec, registers.falloff)); 26 | } 27 | -------------------------------------------------------------------------------- /assets/shaders/lights/fog.h: -------------------------------------------------------------------------------- 1 | #ifndef FOG_H_ 2 | #define FOG_H_ 3 | 4 | highp float fog_factor(highp vec3 eye_vec, highp float falloff) 5 | { 6 | highp float distance = dot(eye_vec, eye_vec); 7 | return exp2(-distance * falloff); 8 | } 9 | 10 | mediump vec3 apply_fog(mediump vec3 color, highp vec3 eye_vec, mediump vec3 fog_color, highp float fog_falloff) 11 | { 12 | highp float lerp = fog_factor(eye_vec, fog_falloff); 13 | return mix(fog_color, color, lerp); 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/fog.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out vec4 vClip; 4 | 5 | layout(std430, push_constant) uniform Registers 6 | { 7 | mat4 inverse_view_projection; 8 | vec3 camera_pos; 9 | vec3 color; 10 | float falloff; 11 | } registers; 12 | 13 | void main() 14 | { 15 | gl_Position = vec4(Position, 1.0, 1.0); 16 | vClip = registers.inverse_view_projection * vec4(Position, 0.0, 1.0); 17 | } -------------------------------------------------------------------------------- /assets/shaders/lights/lighting_data.h: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTING_DATA_H_ 2 | #define LIGHTING_DATA_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | 6 | struct FogParameters 7 | { 8 | vec3 color; 9 | float falloff; 10 | }; 11 | 12 | struct VolumetricFogParameters 13 | { 14 | float slice_z_log2_scale; 15 | }; 16 | 17 | #define SHADOW_NUM_CASCADES 4 18 | #define SHADOW_TRANSFORMS shadow.transforms 19 | #define SHADOW_CASCADE_LOG_BIAS shadow.cascade_log_bias 20 | 21 | struct ShadowParameters 22 | { 23 | mat4 transforms[SHADOW_NUM_CASCADES]; 24 | float cascade_log_bias; 25 | }; 26 | 27 | struct DirectionalParameters 28 | { 29 | vec3 color; 30 | vec3 direction; 31 | }; 32 | 33 | struct RefractionParameters 34 | { 35 | vec3 falloff; 36 | }; 37 | 38 | struct ResolutionParameters 39 | { 40 | vec2 resolution; 41 | vec2 inv_resolution; 42 | }; 43 | 44 | layout(set = 0, binding = BINDING_GLOBAL_RENDER_PARAMETERS, std140) uniform LightingParameters 45 | { 46 | FogParameters fog; 47 | ShadowParameters shadow; 48 | VolumetricFogParameters volumetric_fog; 49 | DirectionalParameters directional; 50 | RefractionParameters refraction; 51 | ResolutionParameters resolution; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /assets/shaders/lights/lighting_irradiance.h: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTING_IRRADIANCE_H_ 2 | #define LIGHTING_IRRADIANCE_H_ 3 | 4 | #include "lighting_resources.h" 5 | 6 | #ifndef PI 7 | #define PI 3.1415628 8 | #endif 9 | 10 | mediump vec3 compute_irradiance_lighting( 11 | vec3 light_world_pos, 12 | mediump vec3 light_normal, 13 | mediump vec3 light_direction, 14 | mediump vec3 light_color, bool active_lane) 15 | { 16 | #ifdef SHADOWS 17 | mediump float shadow_term = get_directional_shadow_term( 18 | light_world_pos, vec3(0.0), vec3(0.0), light_direction); 19 | #else 20 | mediump const float shadow_term = 1.0; 21 | #endif 22 | 23 | // Don't consider specular or PBR here. It's too directional in nature 24 | // to be meaningful for hemisphere integrals. Instead, assume dielectric, fully diffuse, max rough materials. 25 | mediump float NoL = clamp(dot(light_normal, light_direction), 0.0, 1.0); 26 | mediump vec3 in_light = light_color * shadow_term * NoL * (1.0 / PI); 27 | 28 | #ifdef POSITIONAL_LIGHTS 29 | in_light += compute_cluster_irradiance_light(light_world_pos, light_normal); 30 | #endif 31 | 32 | #ifdef VOLUMETRIC_DIFFUSE 33 | in_light += compute_volumetric_diffuse(light_world_pos, light_normal, active_lane); 34 | #endif 35 | 36 | return in_light; 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /assets/shaders/lights/lighting_scatter.h: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTING_SCATTER_H_ 2 | #define LIGHTING_SCATTER_H_ 3 | 4 | #include "lighting_resources.h" 5 | 6 | mediump float directional_scatter_phase_function(mediump float VoL) 7 | { 8 | // Very crude :) 9 | return 0.55 - 0.45 * VoL; 10 | } 11 | 12 | mediump vec3 compute_scatter_lighting( 13 | vec3 light_world_pos, 14 | mediump vec3 light_camera_pos, 15 | mediump vec3 light_camera_front, 16 | mediump vec3 light_direction, 17 | mediump vec3 light_color) 18 | { 19 | #ifdef SHADOWS 20 | mediump float shadow_term = get_directional_shadow_term( 21 | light_world_pos, light_camera_pos, 22 | light_camera_front, light_direction); 23 | #else 24 | mediump const float shadow_term = 1.0; 25 | #endif 26 | 27 | float VoL = dot(normalize(light_camera_pos - light_world_pos), light_direction); 28 | mediump vec3 in_scatter = light_color * (directional_scatter_phase_function(VoL) * shadow_term); 29 | 30 | #ifdef VOLUMETRIC_DIFFUSE 31 | in_scatter += compute_volumetric_diffuse(light_world_pos, normalize(light_world_pos - light_camera_pos), true); 32 | #endif 33 | 34 | #ifdef POSITIONAL_LIGHTS 35 | in_scatter += compute_cluster_scatter_light(light_world_pos, light_camera_pos); 36 | #endif 37 | 38 | return in_scatter; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /assets/shaders/lights/linear_clamp_sampler.h: -------------------------------------------------------------------------------- 1 | #ifndef LINEAR_CLAMP_SAMPLER_H_ 2 | #define LINEAR_CLAMP_SAMPLER_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | layout(set = 0, binding = BINDING_GLOBAL_LINEAR_SAMPLER) uniform sampler LinearClampSampler; 6 | 7 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/linear_geometry_sampler.h: -------------------------------------------------------------------------------- 1 | #ifndef LINEAR_GEOMETRY_SAMPLER_H_ 2 | #define LINEAR_GEOMETRY_SAMPLER_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | layout(set = 0, binding = BINDING_GLOBAL_GEOMETRY_SAMPLER) uniform sampler LinearGeometrySampler; 6 | 7 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/linear_shadow_sampler.h: -------------------------------------------------------------------------------- 1 | #ifndef LINEAR_SHADOW_SAMPLER_H_ 2 | #define LINEAR_SHADOW_SAMPLER_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | layout(set = 0, binding = BINDING_GLOBAL_SHADOW_SAMPLER) uniform sampler LinearShadowSampler; 6 | 7 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/point.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "../inc/render_parameters.h" 4 | 5 | layout(std140, set = 2, binding = 1) uniform Parameters 6 | { 7 | #if defined(VARIANT_BIT_2) 8 | mat4 transforms[128]; 9 | #else 10 | mat4 transform; 11 | #endif 12 | }; 13 | 14 | layout(location = 0) in vec4 Position; 15 | 16 | #if defined(VARIANT_BIT_2) && !defined(RENDERER_DEPTH) 17 | layout(location = 0) flat out int vIndex; 18 | #endif 19 | 20 | void main() 21 | { 22 | #if defined(VARIANT_BIT_0) 23 | gl_Position = vec4(Position.xy, 1.0, 1.0); 24 | #else 25 | const float fudge_factor = 1.15; // Make sure cover the entire volume. 26 | #if defined(VARIANT_BIT_2) 27 | vec4 world = transforms[gl_InstanceIndex] * (vec4(fudge_factor, fudge_factor, fudge_factor, 1.0) * vec4(Position)); 28 | #else 29 | vec4 world = transform * (vec4(fudge_factor, fudge_factor, fudge_factor, 1.0) * vec4(Position)); 30 | #endif 31 | vec4 clip = global.view_projection * world; 32 | gl_Position = clip; 33 | #endif 34 | 35 | #if defined(VARIANT_BIT_2) && !defined(RENDERER_DEPTH) 36 | vIndex = gl_InstanceIndex; 37 | #endif 38 | } 39 | -------------------------------------------------------------------------------- /assets/shaders/lights/resolve_esm.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput uDepth; 4 | layout(location = 0) out float FragColor; 5 | 6 | void main() 7 | { 8 | float value = 2.0 * subpassLoad(uDepth).x - 1.0; 9 | FragColor = exp2(100.0 * value); 10 | } 11 | -------------------------------------------------------------------------------- /assets/shaders/lights/resolve_vsm.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput uDepth; 4 | layout(location = 0) out vec2 FragColor; 5 | 6 | void main() 7 | { 8 | float value = subpassLoad(uDepth).x; 9 | FragColor = vec2(value, value * value); 10 | } 11 | -------------------------------------------------------------------------------- /assets/shaders/lights/spot.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "../inc/render_parameters.h" 4 | 5 | layout(std140, set = 2, binding = 1) uniform Parameters 6 | { 7 | #if defined(VARIANT_BIT_2) 8 | mat4 transforms[128]; 9 | #else 10 | mat4 transform; 11 | #endif 12 | }; 13 | 14 | layout(location = 0) in vec4 Position; 15 | 16 | #if defined(VARIANT_BIT_2) && !defined(RENDERER_DEPTH) 17 | layout(location = 0) flat out int vIndex; 18 | #endif 19 | 20 | void main() 21 | { 22 | #if defined(VARIANT_BIT_0) 23 | gl_Position = vec4(Position.xy, 1.0, 1.0); 24 | #else 25 | #if defined(VARIANT_BIT_2) 26 | vec4 world = transforms[gl_InstanceIndex] * vec4(Position); 27 | #else 28 | vec4 world = transform * vec4(Position); 29 | #endif 30 | vec4 clip = global.view_projection * world; 31 | gl_Position = clip; 32 | #endif 33 | 34 | #if defined(VARIANT_BIT_2) && !defined(RENDERER_DEPTH) 35 | vIndex = gl_InstanceIndex; 36 | #endif 37 | } 38 | -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_fog.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | precision highp int; 4 | 5 | #define VOLUMETRIC_FOG_SET 2 6 | #define VOLUMETRIC_FOG_BINDING 0 7 | #include "volumetric_fog.h" 8 | 9 | layout(std430, push_constant) uniform Registers 10 | { 11 | vec4 inverse_z; 12 | float slice_z_log2_scale; 13 | } registers; 14 | 15 | layout(input_attachment_index = 3, set = 3, binding = 3) uniform highp subpassInput Depth; 16 | layout(location = 0) out mediump vec4 FragColor; 17 | layout(location = 0) in vec2 vUV; 18 | layout(set = 2, binding = 0) uniform mediump sampler3D uFogVolume; 19 | 20 | float to_world_depth(float z) 21 | { 22 | vec2 zw = z * registers.inverse_z.xy + registers.inverse_z.zw; 23 | return -zw.x / zw.y; 24 | } 25 | 26 | void main() 27 | { 28 | float depth = subpassLoad(Depth).x; 29 | float world_depth = to_world_depth(depth); 30 | mediump vec4 fog = sample_volumetric_fog(uFogVolume, vUV, world_depth, registers.slice_z_log2_scale); 31 | FragColor = fog; // RGB additive fog (in-scatter), A (out-scatter for scene). Use blending. 32 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_fog.h: -------------------------------------------------------------------------------- 1 | #ifndef VOLUMETRIC_FOG_H_ 2 | #define VOLUMETRIC_FOG_H_ 3 | 4 | #include "../inc/global_bindings.h" 5 | 6 | float volumetric_fog_texture_z_to_world(float texture_z, float slice_z_log2_scale) 7 | { 8 | float world_z = exp2(texture_z / slice_z_log2_scale) - 1.0; 9 | return world_z; 10 | } 11 | 12 | float volumetric_fog_world_to_texture_z(float world_z, float slice_z_log2_scale) 13 | { 14 | mediump float texture_z = log2(1.0 + world_z) * slice_z_log2_scale; 15 | return texture_z; 16 | } 17 | 18 | mediump vec4 sample_volumetric_fog(sampler3D FogVolume, mediump vec2 uv, mediump float world_z, mediump float slice_z_log2_scale) 19 | { 20 | mediump float texture_z = volumetric_fog_world_to_texture_z(world_z, slice_z_log2_scale); 21 | return textureLod(FogVolume, vec3(uv, texture_z), 0.0); 22 | } 23 | 24 | #if defined(RENDERER_FORWARD) && defined(VOLUMETRIC_FOG) 25 | layout(set = 0, binding = BINDING_GLOBAL_VOLUMETRIC_FOG) uniform mediump sampler3D uFogVolume; 26 | #endif 27 | 28 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_fog.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out vec2 vUV; 4 | 5 | void main() 6 | { 7 | gl_Position = vec4(Position, 1.0, 1.0); 8 | vUV = Position * 0.5 + 0.5; 9 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_gbuffer_copy.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_samplerless_texture_functions : require 3 | layout(local_size_x = 8, local_size_y = 8) in; 4 | 5 | layout(set = 0, binding = 0) writeonly uniform image2DArray uOutput; 6 | layout(set = 0, binding = 1) uniform texture2DArray uInput; 7 | 8 | layout(push_constant) uniform Registers 9 | { 10 | uvec2 position_yz; 11 | uint probe_resolution; 12 | uint probe_downsampling_factor; 13 | }; 14 | 15 | layout(set = 0, binding = 2) uniform UBO 16 | { 17 | vec4 inv_projection_zw; 18 | }; 19 | 20 | #include "volumetric_probe_hash.h" 21 | 22 | layout(constant_id = 0) const bool DepthTransform = false; 23 | 24 | void main() 25 | { 26 | uvec3 position = uvec3(gl_WorkGroupID.z, position_yz); 27 | 28 | uvec2 probe_resolution_2 = uvec2(probe_resolution * 6, probe_resolution); 29 | uvec2 xy = position.xy * probe_resolution_2 + gl_GlobalInvocationID.xy; 30 | ivec3 probe_coord = ivec3(xy, position.z); 31 | vec4 v = texelFetch(uInput, ivec3( 32 | gl_GlobalInvocationID.xy * probe_downsampling_factor + 33 | volumetric_probe_hash(probe_coord, probe_downsampling_factor), 34 | position.x), 0); 35 | 36 | if (DepthTransform) 37 | { 38 | if (v.x < 1.0) 39 | { 40 | vec2 linear_depth2 = mat2(inv_projection_zw.xy, inv_projection_zw.zw) * vec2(v.x, 1.0); 41 | float linear_depth = -linear_depth2.x / linear_depth2.y; 42 | v.x = linear_depth; 43 | } 44 | else 45 | v.x = 0.0; 46 | } 47 | 48 | imageStore(uOutput, probe_coord, v); 49 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_light_average.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_samplerless_texture_functions : require 3 | layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; 4 | 5 | layout(rgba16f, set = 0, binding = 0) writeonly uniform image3D uOutput; 6 | 7 | const int NumProbeLayers = 4; 8 | layout(set = 0, binding = 1) uniform texture3D uInputs[NumProbeLayers]; 9 | 10 | layout(push_constant) uniform Registers 11 | { 12 | ivec3 resolution; 13 | }; 14 | 15 | void main() 16 | { 17 | ivec3 coord = ivec3(gl_GlobalInvocationID); 18 | if (all(lessThan(coord, resolution))) 19 | { 20 | vec3 res = vec3(0.0); 21 | for (int i = 0; i < NumProbeLayers; i++) 22 | res += texelFetch(uInputs[i], coord, 0).rgb; 23 | 24 | res *= 1.0 / float(NumProbeLayers); 25 | imageStore(uOutput, coord, vec4(res, 1.0)); 26 | } 27 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_light_clear_atomic.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 1) in; 3 | 4 | layout(set = 0, binding = 0) writeonly buffer SSBO 5 | { 6 | uvec4 c; 7 | }; 8 | 9 | void main() 10 | { 11 | c = uvec4(0, 1, 1, 0); 12 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_light_setup_sky.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | layout(set = 0, binding = 0, rgba16f) writeonly uniform image2DArray uSkydome; 4 | layout(set = 1, binding = 0) uniform UBO 5 | { 6 | vec3 sun_color; 7 | float camera_y; 8 | vec3 sun_direction; 9 | float inv_resolution; 10 | }; 11 | 12 | #include "../inc/cube_coordinates.h" 13 | #include "atmospheric_scatter.h" 14 | 15 | void main() 16 | { 17 | ivec3 coord = ivec3(gl_GlobalInvocationID); 18 | vec2 uv = (vec2(coord.xy) + 0.5) * inv_resolution; 19 | uv = 2.0 * uv - 1.0; 20 | 21 | vec3 N = base_dirs[coord.z] + pos_du[coord.z] * uv.x + pos_dv[coord.z] * uv.y; 22 | 23 | vec3 result = sun_color * rayleigh_mie_scatter(normalize(N), 24 | sun_direction, camera_y, 32, 16); 25 | 26 | imageStore(uSkydome, coord, vec4(result, 1.0)); 27 | } -------------------------------------------------------------------------------- /assets/shaders/lights/volumetric_probe_hash.h: -------------------------------------------------------------------------------- 1 | #ifndef VOLUMETRIC_PROBE_HASH_H_ 2 | #define VOLUMETRIC_PROBE_HASH_H_ 3 | 4 | uvec2 volumetric_probe_hash(ivec3 coord, uint range) 5 | { 6 | // From: https://www.shadertoy.com/view/XlXcW4 with slight modifications. 7 | const uint NOISE_PRIME = 1103515245u; 8 | uvec3 seed = uvec3(coord); 9 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 10 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 11 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 12 | return (seed.xy >> 16u) & (range - 1u); 13 | } 14 | 15 | #endif -------------------------------------------------------------------------------- /assets/shaders/lights/vsm.h: -------------------------------------------------------------------------------- 1 | #ifndef VSM_H_ 2 | #define VSM_H_ 3 | 4 | #ifdef CLUSTERER_BINDLESS 5 | #include "linear_clamp_sampler.h" 6 | #endif 7 | 8 | mediump float vsm(float depth, vec2 moments) 9 | { 10 | mediump float shadow_term = 1.0; 11 | if (depth > moments.x) 12 | { 13 | float variance = max(moments.y - moments.x * moments.x, 0.00001); 14 | float d = depth - moments.x; 15 | shadow_term = variance / (variance + d * d); 16 | shadow_term = clamp((shadow_term - 0.25) / 0.75, 0.0, 1.0); // Avoid some lighting leaking. 17 | } 18 | return shadow_term; 19 | } 20 | 21 | #endif -------------------------------------------------------------------------------- /assets/shaders/line_ui.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in highp vec3 Position; 4 | 5 | #if HAVE_VERTEX_COLOR 6 | layout(location = 1) in mediump vec4 Color; 7 | layout(location = 0) out mediump vec4 vColor; 8 | #endif 9 | 10 | layout(std140, set = 0, binding = 0) uniform Scene 11 | { 12 | vec3 inv_resolution; 13 | vec3 pos_offset_pixels; 14 | }; 15 | 16 | #include "inc/prerotate.h" 17 | 18 | void main() 19 | { 20 | vec2 pos_ndc = (Position.xy + pos_offset_pixels.xy) * inv_resolution.xy; 21 | gl_Position = vec4(2.0 * pos_ndc - 1.0, (Position.z + pos_offset_pixels.z) * inv_resolution.z, 1.0); 22 | #if HAVE_VERTEX_COLOR 23 | vColor = Color; 24 | #endif 25 | prerotate_fixup_clip_xy(); 26 | } 27 | -------------------------------------------------------------------------------- /assets/shaders/ocean/init_counter_buffer.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = NUM_COUNTERS) in; 3 | #include "ocean.inc" 4 | 5 | layout(set = 0, binding = 0, std430) writeonly buffer LODCounter 6 | { 7 | IndirectDraw draws[]; 8 | }; 9 | 10 | layout(set = 0, binding = 1, std140) uniform DrawCounters 11 | { 12 | uvec4 counts[4]; 13 | }; 14 | 15 | void main() 16 | { 17 | uint index = gl_GlobalInvocationID.x >> 2u; 18 | uint elem = gl_GlobalInvocationID.x & 3u; 19 | 20 | IndirectDraw draw = IndirectDraw( 21 | counts[index][elem], 0, 0, 0, 22 | 0, 0, 0, 0); 23 | 24 | draws[gl_GlobalInvocationID.x] = draw; 25 | } -------------------------------------------------------------------------------- /assets/shaders/ocean/mipmap.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | 4 | #if defined(MIPMAP_R16F) 5 | #define IMAGE_FORMAT r16f 6 | #elif defined(MIPMAP_RG16F) 7 | #define IMAGE_FORMAT rg16f 8 | #elif defined(MIPMAP_RGBA16F) 9 | #define IMAGE_FORMAT rgba16f 10 | #else 11 | #error "Unknown format" 12 | #endif 13 | 14 | layout(IMAGE_FORMAT, set = 0, binding = 0) writeonly uniform mediump image2D uImageOutput; 15 | layout(set = 0, binding = 1) uniform mediump sampler2D uInput; 16 | 17 | layout(std430, push_constant) uniform Registers 18 | { 19 | vec4 result_mod; 20 | vec2 inv_resolution; 21 | uvec2 count; 22 | float lod; 23 | } registers; 24 | 25 | void main() 26 | { 27 | if (all(lessThan(gl_GlobalInvocationID.xy, registers.count))) 28 | { 29 | vec2 uv = (2.0 * vec2(gl_GlobalInvocationID.xy) + 1.0) * registers.inv_resolution; 30 | mediump vec4 filtered = textureLod(uInput, uv, registers.lod); 31 | imageStore(uImageOutput, ivec2(gl_GlobalInvocationID.xy), registers.result_mod * filtered); 32 | } 33 | } -------------------------------------------------------------------------------- /assets/shaders/ocean/ocean.inc: -------------------------------------------------------------------------------- 1 | #ifndef OCEAN_INC_H_ 2 | #define OCEAN_INC_H_ 3 | 4 | struct PatchData 5 | { 6 | vec2 Offsets; 7 | float InnerLOD; 8 | float Padding; 9 | vec4 LODs; 10 | }; 11 | 12 | struct IndirectDraw 13 | { 14 | uint index_count; 15 | uint instance_count; 16 | uint first_index; 17 | int vertex_offset; 18 | uint first_instance; 19 | uint padding0; 20 | uint padding1; 21 | uint padding2; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /assets/shaders/ocean/ocean.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #include "../inc/render_parameters.h" 3 | #include "ocean.inc" 4 | 5 | invariant gl_Position; 6 | 7 | #if defined(VARIANT_BIT_0) 8 | #define OCEAN_BORDER 9 | #endif 10 | 11 | #if defined(VARIANT_BIT_3) 12 | #define NO_HEIGHTMAP 13 | #endif 14 | 15 | layout(location = 0) out vec3 vPos; 16 | layout(location = 1) out vec4 vGradNormalUV; 17 | 18 | layout(std140, set = 2, binding = 6) uniform Registers 19 | { 20 | vec3 world_offset; 21 | vec2 coord_offset; 22 | 23 | vec2 inv_heightmap_size; 24 | vec2 inv_ocean_grid_count; 25 | vec2 normal_uv_scale; 26 | vec2 integer_to_world_mod; 27 | vec2 heightmap_range; 28 | } registers; 29 | 30 | #ifdef NO_HEIGHTMAP 31 | #include "ocean_plane.vert" 32 | #else 33 | #include "ocean_heightmap.vert" 34 | #endif 35 | -------------------------------------------------------------------------------- /assets/shaders/ocean/ocean_plane.vert: -------------------------------------------------------------------------------- 1 | layout(location = 0) in vec2 aPosition; 2 | 3 | void main() 4 | { 5 | vec2 integer_pos = aPosition + registers.coord_offset; 6 | vec2 uv = integer_pos * registers.inv_heightmap_size; 7 | vec2 centered_uv = uv + 0.5 * registers.inv_heightmap_size; 8 | vGradNormalUV = vec4(centered_uv, centered_uv * registers.normal_uv_scale); 9 | 10 | vec2 world_pos = integer_pos * registers.integer_to_world_mod; 11 | vec3 world = vec3(world_pos.x, 0.0, world_pos.y) + registers.world_offset; 12 | vPos = world; 13 | gl_Position = global.view_projection * vec4(world, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /assets/shaders/post/SMAA.hlsl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/SMAA.hlsl -------------------------------------------------------------------------------- /assets/shaders/post/bloom_downsample.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | precision mediump float; 3 | 4 | layout(set = 0, binding = 0) uniform mediump sampler2D uSampler; 5 | #ifdef FEEDBACK 6 | layout(set = 0, binding = 1) uniform mediump sampler2D uSamplerHistory; 7 | #endif 8 | layout(location = 0) in highp vec2 vUV; 9 | layout(location = 0) out mediump vec4 FragColor; 10 | 11 | layout(push_constant, std430) uniform Registers 12 | { 13 | vec2 inv_texel_size; 14 | #ifdef FEEDBACK 15 | float lerp; 16 | #endif 17 | } registers; 18 | 19 | void main() 20 | { 21 | mediump vec4 value = 0.25 * textureLod(uSampler, vUV, 0.0); 22 | value += 0.0625 * textureLod(uSampler, vUV + vec2(-1.75, +1.75) * registers.inv_texel_size, 0.0); 23 | value += 0.125 * textureLod(uSampler, vUV + vec2(+0.00, +1.75) * registers.inv_texel_size, 0.0); 24 | value += 0.0625 * textureLod(uSampler, vUV + vec2(+1.75, +1.75) * registers.inv_texel_size, 0.0); 25 | value += 0.125 * textureLod(uSampler, vUV + vec2(-1.75, +0.00) * registers.inv_texel_size, 0.0); 26 | value += 0.125 * textureLod(uSampler, vUV + vec2(+1.75, +0.00) * registers.inv_texel_size, 0.0); 27 | value += 0.0625 * textureLod(uSampler, vUV + vec2(-1.75, -1.75) * registers.inv_texel_size, 0.0); 28 | value += 0.125 * textureLod(uSampler, vUV + vec2(+0.00, -1.75) * registers.inv_texel_size, 0.0); 29 | value += 0.0625 * textureLod(uSampler, vUV + vec2(+1.75, -1.75) * registers.inv_texel_size, 0.0); 30 | #ifdef FEEDBACK 31 | value = mix(textureLod(uSamplerHistory, vUV, 0.0), value, vec4(vec3(registers.lerp), 1.0)); 32 | #endif 33 | 34 | FragColor = value; 35 | } -------------------------------------------------------------------------------- /assets/shaders/post/bloom_threshold.comp: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | precision mediump float; 4 | 5 | #if DYNAMIC_EXPOSURE 6 | layout(std140, set = 0, binding = 1) uniform LuminanceData 7 | { 8 | float average_log_luminance; 9 | float average_linear_luminance; 10 | float average_inv_linear_luminance; 11 | }; 12 | #endif 13 | 14 | layout(push_constant, std430) uniform Registers 15 | { 16 | uvec2 num_threads; 17 | vec2 inv_output_size; 18 | } registers; 19 | 20 | layout(set = 0, binding = 0) uniform mediump sampler2D uHDR; 21 | layout(set = 0, binding = 2, rgba16f) writeonly uniform mediump image2D uOutput; 22 | 23 | void main() 24 | { 25 | if (any(greaterThanEqual(gl_GlobalInvocationID.xy, registers.num_threads))) 26 | return; 27 | 28 | vec2 vUV = (vec2(gl_GlobalInvocationID.xy) + 0.5) * registers.inv_output_size; 29 | 30 | mediump vec3 color = textureLod(uHDR, vUV, 0.0).rgb; 31 | highp float luminance = max(max(color.x, color.y), color.z) + 0.0001; 32 | highp float loglum = log2(luminance); 33 | 34 | color /= luminance; 35 | 36 | #if DYNAMIC_EXPOSURE 37 | luminance -= 8.0 * average_linear_luminance; 38 | #else 39 | luminance -= 8.0; 40 | #endif 41 | 42 | mediump vec3 thres_color = max(color * luminance, vec3(0.0)); 43 | 44 | imageStore(uOutput, ivec2(gl_GlobalInvocationID.xy), vec4(thres_color, loglum)); 45 | } -------------------------------------------------------------------------------- /assets/shaders/post/bloom_threshold.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | precision mediump float; 3 | 4 | #if DYNAMIC_EXPOSURE 5 | layout(std140, set = 0, binding = 1) uniform LuminanceData 6 | { 7 | float average_log_luminance; 8 | float average_linear_luminance; 9 | float average_inv_linear_luminance; 10 | }; 11 | #endif 12 | 13 | layout(set = 0, binding = 0) uniform mediump sampler2D uHDR; 14 | layout(location = 0) out mediump vec4 FragColor; 15 | layout(location = 0) in highp vec2 vUV; 16 | 17 | void main() 18 | { 19 | mediump vec3 color = textureLod(uHDR, vUV, 0.0).rgb; 20 | highp float luminance = max(max(color.x, color.y), color.z) + 0.0001; 21 | highp float loglum = log2(luminance); 22 | 23 | color /= luminance; 24 | 25 | #if DYNAMIC_EXPOSURE 26 | luminance -= 8.0 * average_linear_luminance; 27 | #else 28 | luminance -= 8.0; 29 | #endif 30 | 31 | mediump vec3 thres_color = max(color * luminance, vec3(0.0)); 32 | FragColor = vec4(thres_color, loglum); 33 | } 34 | -------------------------------------------------------------------------------- /assets/shaders/post/bloom_upsample.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | precision mediump float; 3 | 4 | layout(set = 0, binding = 0) uniform mediump sampler2D uSampler; 5 | layout(location = 0) in highp vec2 vUV; 6 | layout(location = 0) out mediump vec4 FragColor; 7 | 8 | layout(push_constant, std430) uniform Registers 9 | { 10 | vec2 inv_texel_size; 11 | } registers; 12 | 13 | void main() 14 | { 15 | mediump vec4 value = 0.25 * textureLod(uSampler, vUV, 0.0); 16 | value += 0.0625 * textureLod(uSampler, vUV + vec2(-0.875, +0.875) * registers.inv_texel_size, 0.0); 17 | value += 0.125 * textureLod(uSampler, vUV + vec2(+0.00, +0.875) * registers.inv_texel_size, 0.0); 18 | value += 0.0625 * textureLod(uSampler, vUV + vec2(+0.875, +0.875) * registers.inv_texel_size, 0.0); 19 | value += 0.125 * textureLod(uSampler, vUV + vec2(-0.875, +0.00) * registers.inv_texel_size, 0.0); 20 | value += 0.125 * textureLod(uSampler, vUV + vec2(+0.875, +0.00) * registers.inv_texel_size, 0.0); 21 | value += 0.0625 * textureLod(uSampler, vUV + vec2(-0.875, -0.875) * registers.inv_texel_size, 0.0); 22 | value += 0.125 * textureLod(uSampler, vUV + vec2(+0.00, -0.875) * registers.inv_texel_size, 0.0); 23 | value += 0.0625 * textureLod(uSampler, vUV + vec2(+0.875, -0.875) * registers.inv_texel_size, 0.0); 24 | 25 | FragColor = value; 26 | } -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOApply_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOApply_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOClearLoadCounter_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOClearLoadCounter_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur1_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur1_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur2_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur2_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur3_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur3_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur4_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur4_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur5_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur5_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur6_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur6_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur7_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur7_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur8_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOEdgeSensitiveBlur8_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateImportanceMap_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateImportanceMap_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateQ0_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateQ0_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateQ1_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateQ1_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateQ2_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateQ2_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateQ3Base_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateQ3Base_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOGenerateQ3_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOGenerateQ3_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAONonSmartApply_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAONonSmartApply_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAONonSmartHalfApply_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAONonSmartHalfApply_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPostprocessImportanceMapA_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPostprocessImportanceMapA_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPostprocessImportanceMapB_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPostprocessImportanceMapB_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepthsAndMips_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepthsAndMips_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepthsHalf_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepthsHalf_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepths_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledDepths_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledNormalsFromInputNormals_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledNormalsFromInputNormals_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledNormals_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareDownsampledNormals_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepthsAndMips_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepthsAndMips_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepthsHalf_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepthsHalf_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepths_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareNativeDepths_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareNativeNormalsFromInputNormals_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareNativeNormalsFromInputNormals_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOPrepareNativeNormals_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOPrepareNativeNormals_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5Half_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5Half_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5NonSmart_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5NonSmart_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5Smart_32.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/shaders/post/ffx-cacao/CACAOUpscaleBilateral5x5Smart_32.spv -------------------------------------------------------------------------------- /assets/shaders/post/ffx-fsr/sharpen.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #define A_GLSL 1 4 | #define A_GPU 1 5 | #define FSR_RCAS_F 1 6 | 7 | layout(set = 0, binding = 0) uniform sampler2D uTex; 8 | 9 | layout(set = 1, binding = 0) uniform UBO 10 | { 11 | uvec4 param0; 12 | ivec4 range; 13 | }; 14 | 15 | vec4 FsrRcasLoadF(ivec2 p) { return texelFetch(uTex, clamp(p, range.xy, range.zw), 0); } 16 | void FsrRcasInputF(inout float r, inout float g, inout float b) {} 17 | 18 | #include "../ffx-a/ffx_a.h" 19 | #include "ffx_fsr1.h" 20 | 21 | layout(location = 0) out vec4 FragColor; 22 | layout(location = 0) in vec2 vUV; 23 | 24 | void main() 25 | { 26 | vec3 color; 27 | FsrRcasF(color.r, color.g, color.b, uvec2(vUV), param0); 28 | FragColor = vec4(color, 1.0); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /assets/shaders/post/ffx-fsr/sharpen.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out highp vec2 vUV; 4 | 5 | #define A_GLSL 1 6 | #define A_GPU 1 7 | #include "../ffx-a/ffx_a.h" 8 | #include "ffx_fsr1.h" 9 | 10 | #include "../../inc/prerotate.h" 11 | 12 | layout(push_constant) uniform Registers 13 | { 14 | vec2 out_resolution; 15 | }; 16 | 17 | void main() 18 | { 19 | gl_Position = vec4(Position, 0.0, 1.0); 20 | vUV = (0.5 * Position + 0.5) * out_resolution; 21 | prerotate_fixup_clip_xy(); 22 | } 23 | -------------------------------------------------------------------------------- /assets/shaders/post/ffx-fsr/upscale.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #define A_GLSL 1 4 | #define A_GPU 1 5 | 6 | layout(set = 0, binding = 0) uniform sampler2D uTex; 7 | 8 | #if FP16 9 | #define FSR_EASU_H 1 10 | #define A_HALF 1 11 | #extension GL_EXT_shader_explicit_arithmetic_types_float16 : require 12 | f16vec4 FsrEasuRH(vec2 p) { return f16vec4(textureGather(uTex, p, 0)); } 13 | f16vec4 FsrEasuGH(vec2 p) { return f16vec4(textureGather(uTex, p, 1)); } 14 | f16vec4 FsrEasuBH(vec2 p) { return f16vec4(textureGather(uTex, p, 2)); } 15 | #else 16 | #define FSR_EASU_F 1 17 | vec4 FsrEasuRF(vec2 p) { return textureGather(uTex, p, 0); } 18 | vec4 FsrEasuGF(vec2 p) { return textureGather(uTex, p, 1); } 19 | vec4 FsrEasuBF(vec2 p) { return textureGather(uTex, p, 2); } 20 | #endif 21 | 22 | #include "../ffx-a/ffx_a.h" 23 | #include "ffx_fsr1.h" 24 | #include "../../inc/srgb.h" 25 | 26 | layout(location = 0) out vec4 FragColor; 27 | layout(location = 0) in vec2 vUV; 28 | 29 | layout(set = 1, binding = 0) uniform Params 30 | { 31 | uvec4 param0; 32 | uvec4 param1; 33 | uvec4 param2; 34 | uvec4 param3; 35 | }; 36 | 37 | void main() 38 | { 39 | vec3 color; 40 | #if FP16 41 | FsrEasuH(color, uvec2(vUV), param0, param1, param2, param3); 42 | #else 43 | FsrEasuF(color, uvec2(vUV), param0, param1, param2, param3); 44 | #endif 45 | 46 | #if TARGET_SRGB 47 | color = decode_srgb(color); 48 | #endif 49 | 50 | FragColor = vec4(color, 1.0); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /assets/shaders/post/ffx-fsr/upscale.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out highp vec2 vUV; 4 | 5 | #define A_GLSL 1 6 | #define A_GPU 1 7 | #include "../ffx-a/ffx_a.h" 8 | #include "ffx_fsr1.h" 9 | #include "../../inc/prerotate.h" 10 | 11 | layout(push_constant) uniform Push 12 | { 13 | vec2 out_resolution; 14 | }; 15 | 16 | void main() 17 | { 18 | gl_Position = vec4(Position, 0.0, 1.0); 19 | vUV = (0.5 * Position + 0.5) * out_resolution; 20 | prerotate_fixup_clip_xy(); 21 | } 22 | -------------------------------------------------------------------------------- /assets/shaders/post/ffx-sssr/apply.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "sssr_util.h" 4 | #include "../../lights/pbr.h" 5 | 6 | layout(location = 0) out vec3 FragColor; 7 | layout(location = 0) in vec2 vUV; 8 | 9 | layout(input_attachment_index = 0, set = 0, binding = 1) uniform mediump subpassInput uBaseColor; 10 | layout(input_attachment_index = 1, set = 0, binding = 2) uniform mediump subpassInput uNormal; 11 | layout(input_attachment_index = 2, set = 0, binding = 3) uniform mediump subpassInput uPBR; 12 | layout(input_attachment_index = 3, set = 0, binding = 4) uniform subpassInput uDepth; 13 | layout(set = 0, binding = 0) uniform sampler2D uReflected; 14 | layout(set = 0, binding = 5) uniform sampler2D uBRDFLut; 15 | 16 | void main() 17 | { 18 | mediump vec2 mr = subpassLoad(uPBR).xy; 19 | mediump float metallic = mr.x; 20 | mediump float roughness = mr.y; 21 | float clip_depth = subpassLoad(uDepth).x; 22 | 23 | vec2 clip_uv = vUV * 2.0 - 1.0; 24 | vec3 world_pos = FFX_SSSR_ScreenSpaceToWorldSpace(vec3(clip_uv, clip_depth)); 25 | mediump vec3 V = normalize(sssr.camera_position - world_pos); 26 | mediump vec3 N = normalize(subpassLoad(uNormal).xyz * 2.0 - 1.0); 27 | 28 | // Modulate by IBL parameters. 29 | mediump float NoV = clamp(dot(N, V), 0.0, 1.0); 30 | mediump vec3 F0 = compute_F0(subpassLoad(uBaseColor).rgb, metallic); 31 | mediump vec3 F = fresnel_ibl(F0, NoV, roughness); 32 | mediump vec2 brdf = textureLod(uBRDFLut, vec2(NoV, roughness), 0.0).xy; 33 | FragColor = textureLod(uReflected, vUV, 0.0).rgb * (F * brdf.x + brdf.y); 34 | } -------------------------------------------------------------------------------- /assets/shaders/post/ffx-sssr/apply.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 Attr; 4 | layout(location = 0) out vec2 vUV; 5 | 6 | void main() 7 | { 8 | gl_Position = vec4(Attr, 1.0, 1.0); 9 | vUV = Attr * 0.5 + 0.5; 10 | } -------------------------------------------------------------------------------- /assets/shaders/post/ffx-sssr/build_indirect.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 1) in; 3 | 4 | layout(set = 2, binding = 9) buffer RayCounter 5 | { 6 | uvec4 indirect; 7 | uint atomic_count; 8 | uint copied_count; 9 | } ray_counter; 10 | 11 | void main() 12 | { 13 | uint count = ray_counter.atomic_count; 14 | ray_counter.indirect = uvec4((count + 63) / 64, 1, 1, 0); 15 | ray_counter.copied_count = count; 16 | ray_counter.atomic_count = 0; 17 | } 18 | -------------------------------------------------------------------------------- /assets/shaders/post/lanczos2.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "../inc/srgb.h" 4 | #include "lanczos2.h" 5 | 6 | layout(location = 0) out vec4 FragColor; 7 | layout(location = 0) in vec2 vUV; 8 | layout(set = 0, binding = 0) uniform sampler2D uTex; 9 | 10 | layout(set = 1, binding = 0) uniform Registers 11 | { 12 | vec2 resolution; 13 | vec2 inv_resolution; 14 | vec2 out_resolution; 15 | vec2 inv_out_resolution; 16 | } registers; 17 | 18 | void main() 19 | { 20 | vec2 coord = vUV * registers.resolution; 21 | vec3 color = lanczos2(uTex, coord, registers.inv_resolution); 22 | 23 | #if TARGET_SRGB 24 | color = decode_srgb(color); 25 | #endif 26 | 27 | FragColor = vec4(color, 1.0); 28 | } -------------------------------------------------------------------------------- /assets/shaders/post/lanczos2.h: -------------------------------------------------------------------------------- 1 | #ifndef LANCZOS2_H_ 2 | #define LANCZOS2_H_ 3 | 4 | #ifndef PI 5 | #define PI 3.1415628 6 | #endif 7 | 8 | // Simple and naive sinc scaler, slow impl. 9 | // Placeholder implementation. 10 | 11 | mediump float sinc(mediump float v) 12 | { 13 | if (abs(v) < 0.0001) 14 | { 15 | return 1.0; 16 | } 17 | else 18 | { 19 | v *= PI; 20 | return sin(v) / v; 21 | } 22 | } 23 | 24 | mediump float kernel(mediump float v) 25 | { 26 | return sinc(v) * sinc(v * 0.5); 27 | } 28 | 29 | mediump float weight(mediump float x, mediump float y) 30 | { 31 | return kernel(x) * kernel(y); 32 | } 33 | 34 | mediump vec3 lanczos2(mediump sampler2D tex, vec2 unnormalized_coord, vec2 inv_resolution) 35 | { 36 | unnormalized_coord -= 0.5; 37 | vec2 i_coord = floor(unnormalized_coord); 38 | vec2 f_coord = unnormalized_coord - i_coord; 39 | vec2 uv = (i_coord + 0.5) * inv_resolution; 40 | 41 | mediump vec3 color = vec3(0.0); 42 | 43 | float total_w = 0.0; 44 | 45 | #define TAP(X, Y) { \ 46 | mediump float w = weight(f_coord.x - float(X), f_coord.y - float(Y)); \ 47 | mediump vec3 col = textureLodOffset(tex, uv, 0.0, ivec2(X, Y)).rgb; \ 48 | color += col * w; \ 49 | total_w += w; \ 50 | } 51 | 52 | #define TAPS(l) TAP(-1, l); TAP(+0, l); TAP(+1, l); TAP(+2, l) 53 | TAPS(-1); 54 | TAPS(+0); 55 | TAPS(+1); 56 | TAPS(+2); 57 | 58 | color /= total_w; 59 | return color; 60 | } 61 | 62 | #endif -------------------------------------------------------------------------------- /assets/shaders/post/pq10_encode.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_samplerless_texture_functions : require 3 | 4 | layout(location = 0) out vec4 FragColor; 5 | 6 | layout(set = 1, binding = 0) uniform Config 7 | { 8 | mat4 primary_conversion; 9 | float hdr_pre_exposure; 10 | float ui_pre_exposure; 11 | float max_light_level; 12 | float inv_max_light_level; 13 | } config; 14 | 15 | layout(set = 0, binding = 0) uniform texture2D uHDR; 16 | layout(set = 0, binding = 1) uniform texture2D uUI; 17 | 18 | vec3 encode_pq(vec3 nits) 19 | { 20 | // PQ 21 | vec3 y = nits / 10000.0; 22 | const float c1 = 0.8359375; 23 | const float c2 = 18.8515625; 24 | const float c3 = 18.6875; 25 | const float m1 = 0.1593017578125; 26 | const float m2 = 78.84375; 27 | vec3 num = c1 + c2 * pow(y, vec3(m1)); 28 | vec3 den = 1.0 + c3 * pow(y, vec3(m1)); 29 | vec3 n = pow(num / den, vec3(m2)); 30 | return n; 31 | } 32 | 33 | void main() 34 | { 35 | ivec2 coord = ivec2(gl_FragCoord.xy); 36 | vec3 hdr = texelFetch(uHDR, coord, 0).rgb; 37 | vec4 ui = texelFetch(uUI, coord, 0); 38 | vec3 col = hdr * (config.hdr_pre_exposure * ui.a) + ui.rgb * config.ui_pre_exposure; 39 | 40 | // Convert to ST.2020 primaries. 41 | col = mat3(config.primary_conversion) * col; 42 | 43 | col *= config.inv_max_light_level; 44 | 45 | const float K = 4.0; 46 | vec3 col_k = col * K; 47 | vec3 saturated = col_k / (1.0 + col_k); 48 | 49 | col = mix(col, saturated, greaterThan(col, vec3(0.75))); 50 | vec3 pq = encode_pq(col * config.max_light_level); 51 | FragColor = vec4(pq, 1.0); 52 | } 53 | -------------------------------------------------------------------------------- /assets/shaders/post/smaa_blend_weight.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | precision highp int; 4 | 5 | #define SMAA_INCLUDE_VS 0 6 | #define SMAA_INCLUDE_PS 1 7 | #include "smaa_common.h" 8 | 9 | layout(set = 0, binding = 0) uniform sampler2D EdgesTex; 10 | layout(set = 0, binding = 1) uniform sampler2D AreaTex; 11 | layout(set = 0, binding = 2) uniform sampler2D SearchTex; 12 | 13 | layout(location = 0) in vec2 vTex; 14 | layout(location = 1) in vec2 vPixCoord; 15 | layout(location = 2) in vec4 vOffset0; 16 | layout(location = 3) in vec4 vOffset1; 17 | layout(location = 4) in vec4 vOffset2; 18 | layout(location = 0) out vec4 Weights; 19 | 20 | void main() 21 | { 22 | Weights = SMAABlendingWeightCalculationPS(vTex, vPixCoord, vec4[](vOffset0, vOffset1, vOffset2), 23 | EdgesTex, AreaTex, SearchTex, 24 | #if SMAA_SUBPIXEL_MODE == 0 25 | vec4(0.0) 26 | #elif SMAA_SUBPIXEL_MODE == 1 27 | vec4(1.0, 1.0, 1.0, 0.0) 28 | #elif SMAA_SUBPIXEL_MODE == 2 29 | vec4(2.0, 2.0, 2.0, 0.0) 30 | #endif 31 | ); 32 | } -------------------------------------------------------------------------------- /assets/shaders/post/smaa_blend_weight.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #define SMAA_INCLUDE_VS 1 3 | #define SMAA_INCLUDE_PS 0 4 | #include "smaa_common.h" 5 | 6 | layout(location = 0) in vec2 Position; 7 | layout(location = 0) out vec2 vTex; 8 | layout(location = 1) out vec2 vPixCoord; 9 | layout(location = 2) out vec4 vOffset0; 10 | layout(location = 3) out vec4 vOffset1; 11 | layout(location = 4) out vec4 vOffset2; 12 | 13 | #include "../inc/prerotate.h" 14 | 15 | void main() 16 | { 17 | vec2 TexCoord = Position * 0.5 + 0.5; 18 | gl_Position = vec4(Position, 0.0, 1.0); 19 | 20 | vec4 out_coord[3]; 21 | SMAABlendingWeightCalculationVS(TexCoord, vPixCoord, out_coord); 22 | vTex = TexCoord; 23 | vOffset0 = out_coord[0]; 24 | vOffset1 = out_coord[1]; 25 | vOffset2 = out_coord[2]; 26 | prerotate_fixup_clip_xy(); 27 | } -------------------------------------------------------------------------------- /assets/shaders/post/smaa_common.h: -------------------------------------------------------------------------------- 1 | #ifndef SMAA_COMMON_H_ 2 | #define SMAA_COMMON_H_ 3 | 4 | layout(std430, push_constant) uniform Registers 5 | { 6 | vec4 rt_metrics; 7 | } registers; 8 | 9 | #define SMAA_RT_METRICS registers.rt_metrics 10 | #define SMAA_GLSL_4 11 | 12 | #if SMAA_QUALITY == 0 13 | #define SMAA_PRESET_LOW 14 | #elif SMAA_QUALITY == 1 15 | #define SMAA_PRESET_MEDIUM 16 | #elif SMAA_QUALITY == 2 17 | #define SMAA_PRESET_HIGH 18 | #elif SMAA_QUALITY == 3 19 | #define SMAA_PRESET_ULTRA 20 | #endif 21 | 22 | #include "SMAA.hlsl" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /assets/shaders/post/smaa_edge_detection.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | precision highp int; 4 | 5 | #define SMAA_INCLUDE_VS 0 6 | #define SMAA_INCLUDE_PS 1 7 | #include "smaa_common.h" 8 | 9 | layout(set = 0, binding = 0) uniform sampler2D ColorTex; 10 | layout(location = 0) in vec2 vTex; 11 | layout(location = 1) in vec4 vOffset0; 12 | layout(location = 2) in vec4 vOffset1; 13 | layout(location = 3) in vec4 vOffset2; 14 | layout(location = 0) out vec2 Edges; 15 | 16 | void main() 17 | { 18 | Edges = SMAALumaEdgeDetectionPS(vTex, vec4[](vOffset0, vOffset1, vOffset2), ColorTex); 19 | } 20 | -------------------------------------------------------------------------------- /assets/shaders/post/smaa_edge_detection.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #define SMAA_INCLUDE_VS 1 3 | #define SMAA_INCLUDE_PS 0 4 | #include "smaa_common.h" 5 | 6 | layout(location = 0) in vec2 Position; 7 | layout(location = 0) out vec2 vTex; 8 | layout(location = 1) out vec4 vOffset0; 9 | layout(location = 2) out vec4 vOffset1; 10 | layout(location = 3) out vec4 vOffset2; 11 | 12 | #include "../inc/prerotate.h" 13 | 14 | void main() 15 | { 16 | vec2 TexCoord = Position * 0.5 + 0.5; 17 | gl_Position = vec4(Position, 0.0, 1.0); 18 | 19 | vec4 out_coord[3]; 20 | SMAAEdgeDetectionVS(TexCoord, out_coord); 21 | vTex = TexCoord; 22 | vOffset0 = out_coord[0]; 23 | vOffset1 = out_coord[1]; 24 | vOffset2 = out_coord[2]; 25 | prerotate_fixup_clip_xy(); 26 | } -------------------------------------------------------------------------------- /assets/shaders/post/smaa_neighbor_blend.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | precision highp int; 4 | #define SMAA_INCLUDE_VS 0 5 | #define SMAA_INCLUDE_PS 1 6 | #include "smaa_common.h" 7 | #include "../inc/srgb.h" 8 | 9 | layout(set = 0, binding = 0) uniform sampler2D ColorTex; 10 | layout(set = 0, binding = 1) uniform sampler2D BlendTex; 11 | 12 | layout(location = 0) in vec2 vTex; 13 | layout(location = 1) in vec4 vOffset; 14 | layout(location = 0) out vec4 Color; 15 | 16 | void main() 17 | { 18 | Color = SMAANeighborhoodBlendingPS(vTex, vOffset, ColorTex, BlendTex); 19 | #if SMAA_TARGET_SRGB 20 | Color.rgb = decode_srgb(Color.rgb); 21 | #endif 22 | } 23 | -------------------------------------------------------------------------------- /assets/shaders/post/smaa_neighbor_blend.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #define SMAA_INCLUDE_VS 1 3 | #define SMAA_INCLUDE_PS 0 4 | #include "smaa_common.h" 5 | 6 | layout(location = 0) in vec2 Position; 7 | layout(location = 0) out vec2 vTex; 8 | layout(location = 1) out vec4 vOffset; 9 | 10 | #include "../inc/prerotate.h" 11 | 12 | void main() 13 | { 14 | vec2 TexCoord = Position * 0.5 + 0.5; 15 | gl_Position = vec4(Position, 0.0, 1.0); 16 | SMAANeighborhoodBlendingVS(TexCoord, vOffset); 17 | vTex = TexCoord; 18 | prerotate_fixup_clip_xy(); 19 | } -------------------------------------------------------------------------------- /assets/shaders/post/vsm_down_blur.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | 3 | #if defined(LAYERED) && LAYERED 4 | #extension GL_EXT_multiview : require 5 | #endif 6 | 7 | precision highp float; 8 | 9 | #if defined(LAYERED) && LAYERED 10 | layout(set = 0, binding = 0) uniform highp sampler2DArray uSampler; 11 | #else 12 | layout(set = 0, binding = 0) uniform sampler2D uSampler; 13 | #endif 14 | layout(location = 0) in highp vec2 vUV; 15 | layout(location = 0) out vec2 FragColor; 16 | 17 | layout(push_constant, std430) uniform Registers 18 | { 19 | vec2 inv_texel_size; 20 | } registers; 21 | 22 | void main() 23 | { 24 | #if defined(LAYERED) && LAYERED 25 | float layer = float(gl_ViewIndex); 26 | #define SAMPLE_OFFSET(x, y) textureLod(uSampler, vec3(vUV + vec2(x, y) * registers.inv_texel_size, layer), 0.0).xy 27 | #else 28 | #define SAMPLE_OFFSET(x, y) textureLod(uSampler, vUV + vec2(x, y) * registers.inv_texel_size, 0.0).xy 29 | #endif 30 | 31 | vec2 value = 0.25 * SAMPLE_OFFSET(0.0, 0.0); 32 | value += 0.0625 * SAMPLE_OFFSET(-1.75, +1.75); 33 | value += 0.125 * SAMPLE_OFFSET(+0.00, +1.75); 34 | value += 0.0625 * SAMPLE_OFFSET(+1.75, +1.75); 35 | value += 0.125 * SAMPLE_OFFSET(-1.75, +0.00); 36 | value += 0.125 * SAMPLE_OFFSET(+1.75, +0.00); 37 | value += 0.0625 * SAMPLE_OFFSET(-1.75, -1.75); 38 | value += 0.125 * SAMPLE_OFFSET(+0.00, -1.75); 39 | value += 0.0625 * SAMPLE_OFFSET(+1.75, -1.75); 40 | 41 | FragColor = value; 42 | } -------------------------------------------------------------------------------- /assets/shaders/post/vsm_up_blur.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | 3 | #if defined(LAYERED) && LAYERED 4 | #extension GL_EXT_multiview : require 5 | #endif 6 | 7 | precision highp float; 8 | 9 | #if defined(LAYERED) && LAYERED 10 | layout(set = 0, binding = 0) uniform highp sampler2DArray uSampler; 11 | #else 12 | layout(set = 0, binding = 0) uniform sampler2D uSampler; 13 | #endif 14 | layout(location = 0) in highp vec2 vUV; 15 | layout(location = 0) out vec2 FragColor; 16 | 17 | layout(push_constant, std430) uniform Registers 18 | { 19 | vec2 inv_texel_size; 20 | } registers; 21 | 22 | void main() 23 | { 24 | #if defined(LAYERED) && LAYERED 25 | float layer = float(gl_ViewIndex); 26 | #define SAMPLE_OFFSET(x, y) textureLod(uSampler, vec3(vUV + vec2(x, y) * registers.inv_texel_size, layer), 0.0).xy 27 | #else 28 | #define SAMPLE_OFFSET(x, y) textureLod(uSampler, vUV + vec2(x, y) * registers.inv_texel_size, 0.0).xy 29 | #endif 30 | 31 | vec2 value = 0.25 * SAMPLE_OFFSET(0.0, 0.0); 32 | value += 0.0625 * SAMPLE_OFFSET(-0.875, +0.875); 33 | value += 0.125 * SAMPLE_OFFSET(+0.00, +0.875); 34 | value += 0.0625 * SAMPLE_OFFSET(+0.875, +0.875); 35 | value += 0.125 * SAMPLE_OFFSET(-0.875, +0.00); 36 | value += 0.125 * SAMPLE_OFFSET(+0.875, +0.00); 37 | value += 0.0625 * SAMPLE_OFFSET(-0.875, -0.875); 38 | value += 0.125 * SAMPLE_OFFSET(+0.00, -0.875); 39 | value += 0.0625 * SAMPLE_OFFSET(+0.875, -0.875); 40 | 41 | FragColor = value; 42 | } -------------------------------------------------------------------------------- /assets/shaders/quad.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out highp vec2 vUV; 4 | 5 | #include "inc/prerotate.h" 6 | 7 | void main() 8 | { 9 | gl_Position = vec4(Position, 0.0, 1.0); 10 | vUV = 0.5 * Position + 0.5; 11 | prerotate_fixup_clip_xy(); 12 | } -------------------------------------------------------------------------------- /assets/shaders/reconstruct_mv.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput uDepth; 4 | 5 | layout(set = 1, binding = 0, std140) uniform UBO 6 | { 7 | mat4 reprojection; 8 | vec2 inv_resolution; 9 | }; 10 | 11 | layout(location = 0) out vec2 MV; 12 | 13 | void main() 14 | { 15 | vec4 clip = vec4(2.0 * gl_FragCoord.xy * inv_resolution - 1.0, subpassLoad(uDepth).x, 1.0); 16 | vec4 reclip = reprojection * clip; 17 | 18 | if (reclip.w <= 0.0) 19 | { 20 | MV = vec2(0.0); 21 | } 22 | else 23 | { 24 | vec2 oldUV = reclip.xy / reclip.w; 25 | vec2 UV = clip.xy; 26 | MV = 0.5 * (UV - oldUV); 27 | } 28 | } -------------------------------------------------------------------------------- /assets/shaders/scaled_readback.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | 4 | layout(location = 0) in highp vec2 vUV; 5 | 6 | #ifdef HAVE_TARGET_0 7 | layout(location = 0) out vec4 FragColor0; 8 | layout(set = 0, binding = 0) uniform sampler2D uSampler0; 9 | #endif 10 | 11 | #ifdef HAVE_TARGET_1 12 | layout(location = 1) out vec4 FragColor1; 13 | layout(set = 0, binding = 1) uniform sampler2D uSampler1; 14 | #endif 15 | 16 | #ifdef HAVE_TARGET_2 17 | layout(location = 2) out vec4 FragColor2; 18 | layout(set = 0, binding = 2) uniform sampler2D uSampler2; 19 | #endif 20 | 21 | #ifdef HAVE_TARGET_3 22 | layout(location = 3) out vec4 FragColor3; 23 | layout(set = 0, binding = 3) uniform sampler2D uSampler3; 24 | #endif 25 | 26 | void main() 27 | { 28 | #ifdef HAVE_TARGET_0 29 | FragColor0 = textureLod(uSampler0, vUV, 0.0); 30 | #endif 31 | #ifdef HAVE_TARGET_1 32 | FragColor1 = textureLod(uSampler1, vUV, 0.0); 33 | #endif 34 | #ifdef HAVE_TARGET_2 35 | FragColor2 = textureLod(uSampler2, vUV, 0.0); 36 | #endif 37 | #ifdef HAVE_TARGET_3 38 | FragColor3 = textureLod(uSampler3, vUV, 0.0); 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /assets/shaders/skybox.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #ifdef VOLUMETRIC_FOG 4 | #include "lights/lighting_data.h" 5 | #include "inc/render_parameters.h" 6 | #include "lights/volumetric_fog.h" 7 | #endif 8 | 9 | #if defined(HAVE_EMISSIVE) && HAVE_EMISSIVE 10 | layout(set = 2, binding = 0) uniform mediump samplerCube uSkybox; 11 | #endif 12 | layout(location = 0) in highp vec3 vDirection; 13 | 14 | layout(location = 0) out mediump vec3 Emissive; 15 | 16 | layout(std430, push_constant) uniform Registers 17 | { 18 | vec3 color; 19 | float camera_height; 20 | vec3 sun_direction; 21 | } registers; 22 | 23 | #if !defined(HAVE_EMISSIVE) || !HAVE_EMISSIVE 24 | #include "lights/atmospheric_scatter.h" 25 | #endif 26 | 27 | void main() 28 | { 29 | #if defined(HAVE_EMISSIVE) && HAVE_EMISSIVE 30 | Emissive = texture(uSkybox, vDirection).rgb * registers.color; 31 | #else 32 | Emissive = registers.color * rayleigh_mie_scatter(normalize(vDirection), 33 | registers.sun_direction, registers.camera_height, 34 | 16, 8); 35 | #endif 36 | #ifdef VOLUMETRIC_FOG 37 | mediump vec4 fog = sample_volumetric_fog(uFogVolume, 38 | gl_FragCoord.xy * resolution.inv_resolution, 39 | 10.0 * global.z_far, 40 | volumetric_fog.slice_z_log2_scale); 41 | Emissive = fog.rgb + Emissive * fog.a; 42 | #endif 43 | } 44 | -------------------------------------------------------------------------------- /assets/shaders/skybox.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "inc/render_parameters.h" 4 | 5 | layout(location = 0) in vec2 Position; 6 | layout(location = 0) out highp vec3 vDirection; 7 | 8 | void main() 9 | { 10 | gl_Position = vec4(Position, 1.0, 1.0); 11 | vDirection = (global.inv_local_view_projection * vec4(Position, 0.0, 1.0)).xyz; 12 | } -------------------------------------------------------------------------------- /assets/shaders/skybox_latlon.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #ifdef VOLUMETRIC_FOG 4 | #include "lights/lighting_data.h" 5 | #include "inc/render_parameters.h" 6 | #include "lights/volumetric_fog.h" 7 | #endif 8 | 9 | #if defined(HAVE_EMISSIVE) && HAVE_EMISSIVE 10 | layout(set = 2, binding = 0) uniform mediump sampler2D uSkybox; 11 | #endif 12 | layout(location = 0) in highp vec3 vDirection; 13 | 14 | layout(location = 0) out mediump vec3 Emissive; 15 | 16 | layout(std430, push_constant) uniform Registers 17 | { 18 | vec3 color; 19 | } registers; 20 | 21 | void main() 22 | { 23 | #if defined(HAVE_EMISSIVE) && HAVE_EMISSIVE 24 | vec3 v = normalize(vDirection); 25 | if (abs(v.x) < 0.00001) 26 | v.x = 0.00001; 27 | 28 | vec2 uv = vec2(atan(v.z, v.x), asin(-v.y)); 29 | uv *= vec2(0.1591, 0.3183); 30 | uv += 0.5; 31 | Emissive = textureLod(uSkybox, uv, 0.0).rgb * registers.color; 32 | #else 33 | Emissive = registers.color; 34 | #endif 35 | 36 | #ifdef VOLUMETRIC_FOG 37 | mediump vec4 fog = sample_volumetric_fog(uFogVolume, 38 | gl_FragCoord.xy * resolution.inv_resolution, 39 | 10.0 * global.z_far, 40 | volumetric_fog.slice_z_log2_scale); 41 | Emissive = fog.rgb + Emissive * fog.a; 42 | #endif 43 | } 44 | -------------------------------------------------------------------------------- /assets/shaders/skycylinder.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #ifdef VOLUMETRIC_FOG 4 | #include "lights/lighting_data.h" 5 | #include "inc/render_parameters.h" 6 | #include "lights/volumetric_fog.h" 7 | #endif 8 | 9 | layout(location = 0) out mediump vec3 Emissive; 10 | layout(location = 0) in highp vec2 vUV; 11 | layout(set = 2, binding = 0) uniform mediump sampler2D uCylinder; 12 | 13 | layout(push_constant, std430) uniform Registers 14 | { 15 | vec3 color; 16 | float xz_scale; 17 | } registers; 18 | 19 | void main() 20 | { 21 | Emissive = texture(uCylinder, vUV).rgb * registers.color; 22 | #ifdef VOLUMETRIC_FOG 23 | mediump vec4 fog = sample_volumetric_fog(uFogVolume, 24 | gl_FragCoord.xy * resolution.inv_resolution, 25 | 10.0 * global.z_far, 26 | volumetric_fog.slice_z_log2_scale); 27 | Emissive = fog.rgb + Emissive * fog.a; 28 | #endif 29 | } -------------------------------------------------------------------------------- /assets/shaders/skycylinder.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "inc/render_parameters.h" 4 | 5 | layout(location = 0) in vec3 Position; 6 | layout(location = 1) in vec2 UV; 7 | layout(location = 0) out highp vec2 vUV; 8 | 9 | layout(push_constant, std430) uniform Registers 10 | { 11 | vec3 color; 12 | float xz_scale; 13 | } registers; 14 | 15 | void main() 16 | { 17 | vec3 pos = Position; 18 | pos.xz *= registers.xz_scale; 19 | 20 | gl_Position = global.view_projection * vec4(pos, 0.0); 21 | // Work around case where zw = 0.0, which freaks out any clipper. 22 | gl_Position.w = (gl_Position.w >= 0.0 ? 1.0 : -1.0) * max(abs(gl_Position.w), 0.00001); 23 | gl_Position.z = 0.99999 * gl_Position.w; 24 | vUV = UV; 25 | } 26 | -------------------------------------------------------------------------------- /assets/shaders/static_mesh_mv.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec2 MV; 4 | layout(location = 0) in vec3 vOldClip; 5 | layout(location = 1) in vec3 vNewClip; 6 | 7 | void main() 8 | { 9 | if (vOldClip.z <= 0.00001) 10 | { 11 | MV = vec2(0.0); 12 | } 13 | else 14 | { 15 | vec2 UV = vNewClip.xy / vNewClip.z; 16 | vec2 oldUV = vOldClip.xy / vOldClip.z; 17 | MV = 0.5 * (UV - oldUV); 18 | } 19 | } -------------------------------------------------------------------------------- /assets/shaders/texture_plane.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #include "inc/render_parameters.h" 3 | 4 | layout(location = 0) in vec2 Position; 5 | 6 | #ifndef RENDERER_DEPTH 7 | layout(location = 0) out highp vec2 vUV; 8 | layout(location = 1) out highp vec3 vPos; 9 | #endif 10 | 11 | layout(std430, push_constant) uniform Registers 12 | { 13 | vec3 normal; 14 | vec3 tangent; 15 | vec3 bitangent; 16 | 17 | vec3 position; 18 | vec3 dPdx; 19 | vec3 dPdy; 20 | vec4 offset; 21 | vec3 base_emissive; 22 | } registers; 23 | 24 | void main() 25 | { 26 | vec3 plane = registers.position + Position.x * registers.dPdx + Position.y * registers.dPdy; 27 | gl_Position = global.view_projection * vec4(plane, 1.0); 28 | #ifndef RENDERER_DEPTH 29 | vUV = Position * 0.5 + 0.5; 30 | vPos = plane; 31 | #endif 32 | } 33 | -------------------------------------------------------------------------------- /assets/shaders/util/copy_buffer_to_image_3d.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | 4 | layout(set = 0, binding = 0, rgba32ui) uniform writeonly uimage3D uImage; 5 | 6 | layout(set = 0, binding = 1, std430) readonly buffer SSBO 7 | { 8 | uvec4 data[]; 9 | } source_buffer; 10 | 11 | layout(push_constant, std430) uniform Registers 12 | { 13 | ivec2 dimension_xy; 14 | int row_stride; 15 | int height_stride; 16 | } registers; 17 | 18 | void main() 19 | { 20 | ivec3 ident = ivec3(gl_GlobalInvocationID); 21 | if (all(lessThan(ident.xy, registers.dimension_xy))) 22 | { 23 | int offset = ident.x + ident.y * registers.row_stride + ident.z * registers.height_stride; 24 | uvec4 idata = source_buffer.data[offset]; 25 | imageStore(uImage, ident, idata); 26 | } 27 | } -------------------------------------------------------------------------------- /assets/shaders/util/ibl_diffuse.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp int; 3 | precision highp float; 4 | 5 | layout(set = 2, binding = 0) uniform samplerCube uCube; 6 | layout(location = 0) out vec4 FragColor; 7 | layout(location = 0) in highp vec3 vDirection; 8 | 9 | layout(push_constant, std430) uniform Registers 10 | { 11 | float lod; 12 | } registers; 13 | 14 | #define PI 3.1415628 15 | 16 | // Shamelessly copypasted from learnopengl.com 17 | 18 | void main() 19 | { 20 | vec3 irradiance = vec3(0.0); 21 | vec3 dir = normalize(vDirection); 22 | vec3 up = vec3(0.0, 1.0, 0.0); 23 | vec3 right = cross(up, dir); 24 | up = cross(dir, right); 25 | 26 | float sample_delta = 0.025; 27 | float nr_samples = 0.0; 28 | 29 | for (float phi = 0.0; phi < 2.0 * PI; phi += sample_delta) 30 | { 31 | for (float theta = 0.0; theta < 0.5 * PI; theta += sample_delta) 32 | { 33 | // spherical to cartesian (in tangent space) 34 | vec3 tangent_sample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); 35 | // tangent space to world 36 | vec3 sample_vec = tangent_sample.x * right + tangent_sample.y * up + tangent_sample.z * dir; 37 | 38 | irradiance += textureLod(uCube, sample_vec, registers.lod).rgb * cos(theta) * sin(theta); 39 | nr_samples++; 40 | } 41 | } 42 | 43 | irradiance = PI * irradiance * (1.0 / float(nr_samples)); 44 | FragColor = vec4(irradiance, 1.0); 45 | } -------------------------------------------------------------------------------- /assets/shaders/util/rgb_scale.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | 4 | layout(set = 0, binding = 0) uniform mediump sampler2D uImage; 5 | layout(set = 0, binding = 1) writeonly uniform mediump image2D uOutput; 6 | 7 | layout(constant_id = 0) const bool ENCODE_SRGB = false; 8 | 9 | #include "../post/lanczos2.h" 10 | #include "../inc/srgb.h" 11 | 12 | layout(push_constant) uniform Registers 13 | { 14 | uvec2 resolution; 15 | vec2 inv_resolution; 16 | vec2 input_resolution; 17 | vec2 inv_input_resolution; 18 | float dither_strength; 19 | } registers; 20 | 21 | #define D(x) ((x) - 0.5) 22 | const mediump float dither[] = float[]( 23 | D(0.0625), D(0.5625), D(0.1875), D(0.6875), 24 | D(0.8125), D(0.3125), D(0.9375), D(0.4375), 25 | D(0.25), D(0.75), D(0.125), D(0.625), 26 | D(1.00), D(0.5), D(0.875), D(0.375)); 27 | 28 | void main() 29 | { 30 | uvec2 coord = gl_GlobalInvocationID.xy; 31 | if (all(lessThan(coord, registers.resolution))) 32 | { 33 | vec2 uv = (vec2(coord) + 0.5) * registers.inv_resolution; 34 | mediump vec3 rgb = lanczos2(uImage, uv * registers.input_resolution, registers.inv_input_resolution); 35 | 36 | if (ENCODE_SRGB) 37 | rgb = encode_srgb(rgb); 38 | 39 | rgb += dither[(coord.y & 3u) * 4 + (coord.x & 3u)] * registers.dither_strength; 40 | imageStore(uOutput, ivec2(coord), vec4(rgb, 1.0)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /assets/shaders/water_tint.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | precision highp float; 3 | 4 | layout(std430, push_constant) uniform Registers 5 | { 6 | mat4 inverse_view_projection; 7 | vec3 falloff; 8 | } registers; 9 | 10 | layout(input_attachment_index = 3, set = 3, binding = 3) uniform highp subpassInput Depth; 11 | layout(location = 0) in highp vec4 vClip; 12 | layout(location = 0) out mediump vec3 FragColor; 13 | 14 | void main() 15 | { 16 | float depth = subpassLoad(Depth).x; 17 | vec4 clip = vClip + depth * registers.inverse_view_projection[2]; 18 | vec3 pos = clip.xyz / clip.w; 19 | vec3 pos_near = vClip.xyz / vClip.w; 20 | float distance = distance(pos, pos_near); 21 | FragColor = exp2(-registers.falloff * distance); 22 | } 23 | -------------------------------------------------------------------------------- /assets/shaders/water_tint.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out highp vec4 vClip; 4 | 5 | layout(std430, push_constant) uniform Registers 6 | { 7 | mat4 inverse_view_projection; 8 | vec3 falloff; 9 | } registers; 10 | 11 | void main() 12 | { 13 | gl_Position = vec4(Position, 1.0, 1.0); 14 | vClip = registers.inverse_view_projection * vec4(Position, 0.0, 1.0); 15 | } -------------------------------------------------------------------------------- /assets/textures/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/textures/background.png -------------------------------------------------------------------------------- /assets/textures/checkerboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/textures/checkerboard.png -------------------------------------------------------------------------------- /assets/textures/ibl_brdf_lut.gtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/textures/ibl_brdf_lut.gtx -------------------------------------------------------------------------------- /assets/textures/smaa/area.gtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/textures/smaa/area.gtx -------------------------------------------------------------------------------- /assets/textures/smaa/search.gtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/assets/textures/smaa/search.gtx -------------------------------------------------------------------------------- /audio/audio_oboe.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "audio_interface.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace Audio 30 | { 31 | Backend *create_oboe_backend(BackendCallback *callback, float sample_rate, unsigned channels); 32 | void set_oboe_low_latency_parameters(unsigned sample_rate, unsigned block_frames); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /audio/audio_pulse.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "audio_interface.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace Audio 30 | { 31 | Backend *create_pulse_backend(BackendCallback *callback, float sample_rate, unsigned channels); 32 | RecordStream *create_pulse_record_backend(const char *ident, float sample_rate, unsigned channels); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /audio/audio_wasapi.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "audio_interface.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace Audio 30 | { 31 | Backend *create_wasapi_backend(BackendCallback *callback, float sample_rate, unsigned channels); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /audio/dsp/audio_fft_eq.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | #include "audio_mixer.hpp" 25 | 26 | namespace Granite 27 | { 28 | namespace Audio 29 | { 30 | namespace DSP 31 | { 32 | MixerStream *create_fft_eq_stream(MixerStream *source, 33 | const float *filter_coeffs, unsigned coeff_count); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /audio/dsp/tone_filter_stream.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "audio_mixer.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace Audio 30 | { 31 | namespace DSP 32 | { 33 | MixerStream *create_tone_filter_stream(MixerStream *source, float tuning_rate = 440.0f); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /audio/vorbis_stream.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "audio_mixer.hpp" 26 | #include 27 | 28 | namespace Granite 29 | { 30 | namespace Audio 31 | { 32 | MixerStream *create_vorbis_stream(const std::string &path, bool looping = false); 33 | MixerStream *create_decoded_vorbis_stream(const std::string &path, bool looping = false); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /compiler/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-compiler compiler.cpp compiler.hpp) 2 | target_include_directories(granite-compiler PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(granite-compiler 4 | PUBLIC granite-application-global 5 | PRIVATE SPIRV-Tools shaderc granite-path granite-util) 6 | 7 | if (GRANITE_SHADER_COMPILER_OPTIMIZE) 8 | target_compile_definitions(granite-compiler PRIVATE GRANITE_COMPILER_OPTIMIZE=1) 9 | else() 10 | target_compile_definitions(granite-compiler PRIVATE GRANITE_COMPILER_OPTIMIZE=0) 11 | endif() 12 | 13 | -------------------------------------------------------------------------------- /ecs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-ecs ecs.hpp ecs.cpp) 2 | target_include_directories(granite-ecs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(granite-ecs PUBLIC granite-util) -------------------------------------------------------------------------------- /event/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-event event.hpp event.cpp) 2 | target_include_directories(granite-event PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(granite-event PUBLIC granite-util granite-application-global) -------------------------------------------------------------------------------- /filesystem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-filesystem 2 | volatile_source.hpp 3 | filesystem.hpp filesystem.cpp 4 | asset_manager.cpp asset_manager.hpp) 5 | 6 | if (WIN32) 7 | target_sources(granite-filesystem PRIVATE windows/os_filesystem.cpp windows/os_filesystem.hpp) 8 | target_include_directories(granite-filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/windows) 9 | elseif (ANDROID) 10 | target_sources(granite-filesystem PRIVATE linux/os_filesystem.cpp linux/os_filesystem.hpp) 11 | target_sources(granite-filesystem PRIVATE android/android.cpp android/android.hpp) 12 | target_include_directories(granite-filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux) 13 | target_include_directories(granite-filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/android) 14 | else() 15 | target_sources(granite-filesystem PRIVATE linux/os_filesystem.cpp linux/os_filesystem.hpp) 16 | target_include_directories(granite-filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux) 17 | endif() 18 | 19 | target_include_directories(granite-filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 20 | target_link_libraries(granite-filesystem PUBLIC granite-util granite-path granite-application-global PRIVATE granite-threading) 21 | 22 | if (GRANITE_SHIPPING) 23 | target_compile_definitions(granite-filesystem PRIVATE GRANITE_SHIPPING) 24 | else() 25 | target_compile_definitions(granite-filesystem PRIVATE GRANITE_DEFAULT_BUILTIN_DIRECTORY=\"${CMAKE_CURRENT_SOURCE_DIR}/../assets\") 26 | target_compile_definitions(granite-filesystem PRIVATE GRANITE_DEFAULT_CACHE_DIRECTORY=\"${CMAKE_BINARY_DIR}/cache\") 27 | endif() 28 | -------------------------------------------------------------------------------- /math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-math 2 | math.hpp math.cpp 3 | frustum.hpp frustum.cpp 4 | aabb.cpp aabb.hpp 5 | render_parameters.hpp 6 | interpolation.cpp interpolation.hpp 7 | muglm/muglm.cpp muglm/muglm.hpp 8 | muglm/muglm_impl.hpp muglm/matrix_helper.hpp 9 | transforms.cpp transforms.hpp 10 | simd.hpp simd_headers.hpp) 11 | 12 | target_include_directories(granite-math PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -------------------------------------------------------------------------------- /math/interpolation.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Granite 26 | { 27 | float catmull_rom_spline(float c0, float c1, float c2, float c3, float phase); 28 | float catmull_rom_spline_gradient(float c0, float c1, float c2, float c3, float phase); 29 | } -------------------------------------------------------------------------------- /math/math.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "math.hpp" 24 | #include "muglm/muglm_impl.hpp" 25 | 26 | namespace Granite 27 | { 28 | void quantize_color(uint8_t *v, const vec4 &color) 29 | { 30 | for (unsigned i = 0; i < 4; i++) 31 | v[i] = uint8_t(muglm::round(muglm::clamp(color[i] * 255.0f, 0.0f, 255.0f))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /math/math.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "muglm/muglm.hpp" 26 | 27 | namespace Granite 28 | { 29 | using namespace muglm; 30 | void quantize_color(uint8_t *v, const vec4 &color); 31 | } -------------------------------------------------------------------------------- /path/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-path path_utils.hpp path_utils.cpp) 2 | target_include_directories(granite-path PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(granite-path PRIVATE granite-util) -------------------------------------------------------------------------------- /physics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(USE_GLUT OFF CACHE BOOL "" FORCE) 2 | set(BUILD_EGL OFF CACHE BOOL "" FORCE) 3 | set(BUILD_BULLET3 OFF CACHE BOOL "" FORCE) 4 | set(BUILD_PYBULLET OFF CACHE BOOL "" FORCE) 5 | set(USE_GRAPHICAL_BENCHMARK OFF CACHE BOOL "" FORCE) 6 | set(USE_DOUBLE_PRECISION OFF CACHE BOOL "" FORCE) 7 | set(BUILD_CPU_DEMOS OFF CACHE BOOL "" FORCE) 8 | set(INSTALL_LIBS ON CACHE BOOL "" FORCE) 9 | option(GRANITE_BULLET_ROOT "" "Path to a Bullet library checkout.") 10 | if (NOT GRANITE_BULLET_ROOT) 11 | set(GRANITE_BULLET_ROOT $ENV{BULLET_ROOT}) 12 | message("GRANITE_BULLET_ROOT not set, overriding with environment variable BULLET_ROOT.") 13 | endif() 14 | message("Including bullet3 from GRANITE_BULLET_ROOT: ${GRANITE_BULLET_ROOT}") 15 | add_subdirectory(${GRANITE_BULLET_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/third_party/bullet3 EXCLUDE_FROM_ALL) 16 | 17 | add_granite_internal_lib(granite-physics physics_system.cpp physics_system.hpp) 18 | target_include_directories(granite-physics PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${GRANITE_BULLET_ROOT}/src) 19 | target_compile_definitions(granite-physics PUBLIC HAVE_GRANITE_PHYSICS=1) 20 | target_link_libraries(granite-physics PRIVATE 21 | BulletDynamics BulletCollision LinearMath 22 | granite-renderer granite-application-global granite-application-global-interface) -------------------------------------------------------------------------------- /renderer/fft/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_offline_tool(fft-test fft_test.cpp) 2 | target_link_libraries(fft-test PRIVATE muFFT) 3 | add_granite_offline_tool(fft-bench fft_bench.cpp) 4 | -------------------------------------------------------------------------------- /renderer/material_util.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "material.hpp" 26 | 27 | namespace Granite 28 | { 29 | class StockMaterials 30 | { 31 | public: 32 | static Material create_checkerboard(); 33 | }; 34 | } -------------------------------------------------------------------------------- /renderer/post/ffx-cacao/src/cauldron-dxc-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $FFX_CACAO ]; then 4 | FFX_CACAO=$HOME/git/FidelityFX-CACAO 5 | echo "FFX_CACAO not set, assuming checkout is in $FFX_CACAO." 6 | fi 7 | 8 | # Upstream DXC fails to compile to SPIR-V due to invalid use of texture offsets. 9 | 10 | wine $FFX_CACAO/sample/libs/cauldron/libs/DXC/bin/dxc.exe "$@" 11 | -------------------------------------------------------------------------------- /renderer/post/fxaa.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | #include "render_graph.hpp" 25 | 26 | namespace Granite 27 | { 28 | void setup_fxaa_postprocess(RenderGraph &graph, const std::string &input, const std::string &output, 29 | VkFormat output_format = VK_FORMAT_UNDEFINED); 30 | } -------------------------------------------------------------------------------- /renderer/post/ssao.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | #include "render_graph.hpp" 25 | #include "render_context.hpp" 26 | 27 | namespace Granite 28 | { 29 | void setup_ffx_cacao(RenderGraph &graph, const RenderContext &context, 30 | const std::string &output, const std::string &input_depth, const std::string &input_normal); 31 | } -------------------------------------------------------------------------------- /scene-export/camera_export.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "scene_formats.hpp" 26 | 27 | namespace Granite 28 | { 29 | struct RecordedCamera 30 | { 31 | vec3 position; 32 | vec3 direction; 33 | vec3 up; 34 | float fovy; 35 | float aspect; 36 | float znear; 37 | float zfar; 38 | }; 39 | std::string export_cameras_to_json(const std::vector &cameras); 40 | } -------------------------------------------------------------------------------- /scene-export/light_export.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Granite 28 | { 29 | struct DirectionalParameters; 30 | class Scene; 31 | std::string export_lights_to_json(const DirectionalParameters &directional, Scene &scene); 32 | } -------------------------------------------------------------------------------- /scene-export/meshlet_export.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include "scene_formats.hpp" 28 | #include "meshlet.hpp" 29 | 30 | namespace Granite 31 | { 32 | namespace Meshlet 33 | { 34 | bool export_mesh_to_meshlet(const std::string &path, SceneFormats::Mesh mesh, Vulkan::Meshlet::MeshStyle style); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /scene-export/rgtc_compressor.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Granite 28 | { 29 | void compress_rgtc_red_block(uint8_t *output_r, const uint8_t *input_r); 30 | void compress_rgtc_red_green_block(uint8_t *output_rg, const uint8_t *input_r, const uint8_t *input_g); 31 | void decompress_rgtc_red_block(uint8_t *output_r, const uint8_t *block); 32 | } -------------------------------------------------------------------------------- /self-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | set(CMAKE_CXX_STANDARD 14) 3 | set(CMAKE_C_STANDARD 99) 4 | project(Granite-Self-Test LANGUAGES CXX C) 5 | 6 | add_subdirectory(.. granite) 7 | add_granite_offline_tool(link-test link_test.cpp) 8 | granite_install_executable(link-test) 9 | -------------------------------------------------------------------------------- /self-test/link_test.cpp: -------------------------------------------------------------------------------- 1 | #include "global_managers_init.hpp" 2 | 3 | int main() 4 | { 5 | Granite::Global::init(); 6 | LOGI("Hello there! :)\n"); 7 | Granite::Global::deinit(); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /slangmosh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_offline_tool(slangmosh slangmosh.cpp) 2 | target_link_libraries(slangmosh PRIVATE granite-filesystem granite-compiler granite-rapidjson granite-vulkan) 3 | 4 | -------------------------------------------------------------------------------- /tests/assets/shaders/additive.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(0.5, 0.4, 0.3, 0.1); 7 | } -------------------------------------------------------------------------------- /tests/assets/shaders/bandlimited_quad.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec4 Position; 3 | layout(location = 0) out mediump vec4 vColor; 4 | layout(location = 1) out vec2 vUV; 5 | 6 | layout(std430, push_constant) uniform UBO 7 | { 8 | mat4 MVP; 9 | }; 10 | 11 | void main() 12 | { 13 | gl_Position = MVP * Position; 14 | vUV = Position.xy * 7.5 + 0.5; 15 | vColor = vec4(1.0); 16 | } -------------------------------------------------------------------------------- /tests/assets/shaders/bindless.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_nonuniform_qualifier : require 3 | #extension GL_EXT_samplerless_texture_functions : require 4 | 5 | layout(set = 0, binding = 0) uniform texture2D uImages[]; 6 | layout(set = 2, binding = 0) uniform texture2D uImages2[]; 7 | layout(set = 1, binding = 2) uniform sampler uSampler; 8 | layout(location = 0) out vec4 FragColor; 9 | 10 | void main() 11 | { 12 | int x = int(gl_FragCoord.x / 16.0) & 1023; 13 | int y = int(gl_FragCoord.y / 16.0) & 1023; 14 | int index = x ^ y; 15 | 16 | FragColor = 17 | textureLod(nonuniformEXT(sampler2D(uImages[index], uSampler)), vec2(0.5), 0.0) * 18 | textureLod(nonuniformEXT(sampler2D(uImages2[index], uSampler)), vec2(0.5), 0.0); 19 | } 20 | -------------------------------------------------------------------------------- /tests/assets/shaders/bitmap_mesh.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | void main() 5 | { 6 | FragColor = vec4(1.0); 7 | } -------------------------------------------------------------------------------- /tests/assets/shaders/bitmap_mesh.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(push_constant) uniform Registers 4 | { 5 | mat4 vp; 6 | } registers; 7 | 8 | layout(location = 0) in vec4 Position; 9 | 10 | void main() 11 | { 12 | gl_Position = registers.vp * Position; 13 | } -------------------------------------------------------------------------------- /tests/assets/shaders/burn.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(push_constant) uniform Regs { uint burn_count; }; 4 | layout(location = 0) out vec4 FragColor; 5 | 6 | void main() 7 | { 8 | FragColor = vec4(1, 2, 3, 4); 9 | for (uint i = 0; i < burn_count; i++) 10 | FragColor = sin(FragColor); 11 | } -------------------------------------------------------------------------------- /tests/assets/shaders/clustering_viz.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) flat in vec3 vColor; 3 | layout(location = 1) in vec3 vPos; 4 | layout(location = 0) out vec4 FragColor; 5 | 6 | void main() 7 | { 8 | vec3 abs_pos = fract(abs(vPos) + 0.05); 9 | float max_pos = max(max(abs_pos.x, abs_pos.y), abs_pos.z); 10 | float min_pos = min(min(abs_pos.x, abs_pos.y), abs_pos.z); 11 | max_pos = max(max_pos, 1.0 - min_pos); 12 | FragColor = vec4(vColor.xyz * pow(max_pos, 20.0), 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /tests/assets/shaders/clustering_viz.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec4 Position; 3 | layout(location = 1) in vec4 OffsetScale; 4 | layout(location = 2) in vec4 ColorLevel; 5 | 6 | layout(location = 0) flat out vec3 vColor; 7 | layout(location = 1) out vec3 vPos; 8 | 9 | layout(push_constant, std430) uniform Registers 10 | { 11 | mat4 VP; 12 | } registers; 13 | 14 | void main() 15 | { 16 | uint level = uint(ColorLevel.w); 17 | gl_Position = registers.VP * vec4(((Position.xyz * vec3(1.0, 1.0, 1.0) * OffsetScale.w) + vec3(1.0, 1.0, 2.0) * OffsetScale.xyz), 1.0); 18 | vColor = ColorLevel.xyz; 19 | vPos = Position.xyz; 20 | } 21 | -------------------------------------------------------------------------------- /tests/assets/shaders/compute_add.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_shader_explicit_arithmetic_types_float16 : require 3 | layout(local_size_x = 1, local_size_y = 1) in; 4 | 5 | layout(std430, binding = 0, set = 0) buffer SSBO 6 | { 7 | f16vec4 a; 8 | f16vec4 b; 9 | float16_t dot_result; 10 | float16_t length_a_result; 11 | float16_t length_b_result; 12 | float16_t distance_result; 13 | }; 14 | 15 | void main() 16 | { 17 | dot_result = dot(a, b); 18 | length_a_result = length(a); 19 | length_b_result = length(b); 20 | distance_result = distance(a, b); 21 | } -------------------------------------------------------------------------------- /tests/assets/shaders/compute_bucket_allocate.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #pragma optimize off 4 | 5 | #extension GL_KHR_shader_subgroup_ballot : require 6 | layout(local_size_x = 64) in; 7 | 8 | layout(std430, set = 0, binding = 0) readonly buffer VariantBuffer 9 | { 10 | uint variants[]; 11 | }; 12 | 13 | layout(std430, set = 0, binding = 1) writeonly buffer WorkList 14 | { 15 | uint work_list[]; 16 | }; 17 | 18 | layout(std430, set = 0, binding = 2) buffer ItemCounts 19 | { 20 | uint item_counts_per_variant[]; 21 | }; 22 | 23 | uint allocate_work_offset(uint variant_index) 24 | { 25 | #if 0 26 | return atomicAdd(item_counts_per_variant[variant_index], 1u); 27 | #else 28 | // Merge atomic operations. 29 | for (;;) 30 | { 31 | if (subgroupBroadcastFirst(variant_index) == variant_index) 32 | { 33 | uvec4 active_mask = subgroupBallot(true); 34 | uint count = subgroupBallotBitCount(active_mask); 35 | uint work_offset = 0u; 36 | if (subgroupElect()) 37 | work_offset = atomicAdd(item_counts_per_variant[variant_index], count); 38 | 39 | work_offset = subgroupBroadcastFirst(work_offset); 40 | work_offset += subgroupBallotExclusiveBitCount(active_mask); 41 | return work_offset; 42 | } 43 | } 44 | #endif 45 | } 46 | 47 | void main() 48 | { 49 | uint variant_index = variants[gl_GlobalInvocationID.x]; 50 | uint work_offset = allocate_work_offset(variant_index); 51 | work_list[work_offset + 64u * variant_index] = gl_GlobalInvocationID.x; 52 | } 53 | -------------------------------------------------------------------------------- /tests/assets/shaders/copy_image.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = WORKGROUP_X, local_size_y = WORKGROUP_Y) in; 3 | 4 | layout(rgba8, set = 0, binding = 0) writeonly uniform image2D uOutput; 5 | #if IMAGE_INPUT 6 | layout(rgba8, set = 0, binding = 1) readonly uniform image2D uInput; 7 | #else 8 | layout(set = 0, binding = 2) uniform sampler2D uInput; 9 | #endif 10 | 11 | void main() 12 | { 13 | #if IMAGE_INPUT 14 | vec4 in_value = imageLoad(uInput, ivec2(gl_GlobalInvocationID.xy)); 15 | #else 16 | vec4 in_value = texelFetch(uInput, ivec2(gl_GlobalInvocationID.xy), 0); 17 | #endif 18 | 19 | imageStore(uOutput, ivec2(gl_GlobalInvocationID.xy), in_value); 20 | } 21 | -------------------------------------------------------------------------------- /tests/assets/shaders/debug_channel.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 64) in; 3 | 4 | #include "inc/debug_channel.h" 5 | 6 | void main() 7 | { 8 | add_debug_message(0, gl_GlobalInvocationID, vec3(gl_GlobalInvocationID)); 9 | } -------------------------------------------------------------------------------- /tests/assets/shaders/dgc.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | 5 | void main() 6 | { 7 | #if DGC == 0 8 | FragColor = vec4(1.0, 0.0, 0.0, 1.0); 9 | #elif DGC == 1 10 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 11 | #else 12 | FragColor = vec4(0.0, 0.0, 1.0, 1.0); 13 | #endif 14 | } -------------------------------------------------------------------------------- /tests/assets/shaders/dgc.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #if MDI 4 | #extension GL_ARB_shader_draw_parameters : require 5 | #define index gl_DrawIDARB 6 | #else 7 | layout(push_constant) uniform Registers { uint index; }; 8 | #endif 9 | layout(set = 0, binding = 0) buffer SSBO { uint data[]; }; 10 | 11 | void main() 12 | { 13 | atomicAdd(data[index], 1u); 14 | gl_Position = vec4(-1.0); 15 | } -------------------------------------------------------------------------------- /tests/assets/shaders/dgc_compute.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(local_size_x = 32) in; 4 | 5 | layout(set = 0, binding = 0) buffer SSBO 6 | { 7 | uint data[]; 8 | }; 9 | 10 | layout(push_constant) uniform Registers 11 | { 12 | uint index; 13 | uint sequence; 14 | }; 15 | 16 | layout(constant_id = 0) const uint C = 1; 17 | 18 | void main() 19 | { 20 | atomicAdd(data[index], C + sequence); 21 | } -------------------------------------------------------------------------------- /tests/assets/shaders/divergent_lod.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 vUV; 4 | layout(location = 0) out vec4 FragColor; 5 | layout(set = 0, binding = 1) uniform sampler2D uSampler; 6 | layout(set = 0, binding = 0, std140) uniform Weights 7 | { 8 | vec4 weights[4]; 9 | }; 10 | 11 | void main() 12 | { 13 | vec3 tex = vec3(0.0); 14 | float lod = -10.0; 15 | vec2 uv = vUV; 16 | if (weights[int(gl_FragCoord.x) + 2 * int(gl_FragCoord.y)].x > 0.0) 17 | { 18 | tex = texture(uSampler, uv).rgb; 19 | lod = textureQueryLod(uSampler, uv).y; 20 | } 21 | 22 | FragColor = vec4(tex, lod); 23 | } -------------------------------------------------------------------------------- /tests/assets/shaders/fill_color_spec_constant.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | 5 | layout(push_constant, std430) uniform Registers 6 | { 7 | uint value; 8 | } registers; 9 | 10 | layout(constant_id = 1) const uint USE_SPEC_CONSTANT = 0u; 11 | layout(constant_id = 2) const uint VALUE = 0u; 12 | 13 | void main() 14 | { 15 | uint value = registers.value; 16 | if (USE_SPEC_CONSTANT != 0u) 17 | value = VALUE; 18 | 19 | switch (value & 3u) 20 | { 21 | case 0: FragColor = vec4(1.0, 0.0, 0.0, 1.0); break; 22 | case 1: FragColor = vec4(0.0, 1.0, 0.0, 1.0); break; 23 | case 2: FragColor = vec4(0.0, 0.0, 1.0, 1.0); break; 24 | case 3: FragColor = vec4(1.0, 0.0, 1.0, 1.0); break; 25 | default: FragColor = vec4(0.0); break; 26 | } 27 | } -------------------------------------------------------------------------------- /tests/assets/shaders/fill_depth.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | 5 | layout(push_constant, std430) uniform Registers 6 | { 7 | vec3 color; 8 | float depth; 9 | } registers; 10 | 11 | void main() 12 | { 13 | FragColor = vec4(registers.color, 1.0); 14 | gl_FragDepth = registers.depth; 15 | } -------------------------------------------------------------------------------- /tests/assets/shaders/fill_depth_checkerboard.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | void main() 3 | { 4 | int x = int(gl_FragCoord.x); 5 | int y = int(gl_FragCoord.y); 6 | gl_FragDepth = 0.45 + 0.1 * float((x ^ y) & 1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/assets/shaders/fill_flat.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #pragma optimize off 4 | 5 | layout(std140, set = 0, binding = 0) uniform UBO 6 | { 7 | vec4 color; 8 | } ubos[4]; 9 | 10 | layout(push_constant, std430) uniform Registers 11 | { 12 | int index; 13 | } registers; 14 | 15 | #if OUTPUT_COMPONENTS == 1 16 | layout(location = 0) out float FragColor; 17 | void main() { FragColor = ubos[registers.index].color.x * 0.2; } 18 | #elif OUTPUT_COMPONENTS == 2 19 | layout(location = 0) out vec2 FragColor; 20 | void main() { FragColor = ubos[registers.index].color.xy * vec2(0.2); } 21 | #elif OUTPUT_COMPONENTS == 3 22 | layout(location = 0) out vec3 FragColor; 23 | void main() { FragColor = ubos[registers.index].color.xyz * vec3(0.2); } 24 | #elif OUTPUT_COMPONENTS == 4 25 | layout(location = 0) out vec4 FragColor; 26 | void main() { FragColor = ubos[registers.index].color * vec4(0.2); } 27 | #else 28 | #error "Invalid number of components." 29 | #endif 30 | -------------------------------------------------------------------------------- /tests/assets/shaders/fill_image.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 2, local_size_y = 2) in; 3 | 4 | layout(rgba8, set = 0, binding = 0) writeonly uniform image2D uImage; 5 | 6 | float foo[4]; 7 | 8 | void main() 9 | { 10 | ivec2 coord = ivec2(gl_GlobalInvocationID.xy); 11 | 12 | float x_sin = sin(coord.x * 0.2); 13 | float y_sin = sin(coord.y * 0.5 + 0.8); 14 | for (int i = 0; i < 20; i++) 15 | x_sin = exp(x_sin + 0.1); 16 | foo[gl_LocalInvocationIndex] = x_sin; 17 | 18 | memoryBarrierShared(); 19 | barrier(); 20 | 21 | imageStore(uImage, coord, vec4(foo[gl_LocalInvocationIndex ^ 1u], y_sin, 0.0, 0.0)); 22 | } -------------------------------------------------------------------------------- /tests/assets/shaders/hdrtest.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec3 vColor; 4 | layout(location = 0) out vec3 FragColor; 5 | 6 | layout(set = 0, binding = 0) uniform UBO 7 | { 8 | mat4 primary_convert; 9 | }; 10 | 11 | layout(constant_id = 0) const bool hdr10 = false; 12 | 13 | vec3 linear_to_srgb(vec3 col) 14 | { 15 | return mix(1.055 * pow(col, vec3(1.0 / 2.4)) - 0.055, col * 12.92, lessThanEqual(col, vec3(0.0031308))); 16 | } 17 | 18 | vec3 encode_transfer_function(vec3 nits) 19 | { 20 | if (hdr10) 21 | { 22 | // PQ 23 | vec3 y = clamp(nits / 10000.0, vec3(0.0), vec3(1.0)); 24 | const float c1 = 0.8359375; 25 | const float c2 = 18.8515625; 26 | const float c3 = 18.6875; 27 | const float m1 = 0.1593017578125; 28 | const float m2 = 78.84375; 29 | vec3 num = c1 + c2 * pow(y, vec3(m1)); 30 | vec3 den = 1.0 + c3 * pow(y, vec3(m1)); 31 | vec3 n = pow(num / den, vec3(m2)); 32 | return n; 33 | } 34 | else 35 | { 36 | vec3 n = clamp(nits / 100.0, vec3(0.0), vec3(1.0)); 37 | return linear_to_srgb(n); 38 | } 39 | } 40 | 41 | void main() 42 | { 43 | // Convert primaries into target color space. 44 | // For HDR10 -> ST.2020 45 | // For sRGB -> BT.709 46 | // CPU side prepares the matrix. 47 | vec3 color = mat3(primary_convert) * vColor; 48 | 49 | FragColor = encode_transfer_function(color); 50 | } 51 | -------------------------------------------------------------------------------- /tests/assets/shaders/hdrtest.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 aPos; 4 | layout(location = 0) out vec3 vColor; 5 | 6 | layout(set = 0, binding = 1) uniform Lum 7 | { 8 | float lum; 9 | }; 10 | 11 | void main() 12 | { 13 | gl_Position = vec4(aPos, 0.0, 1.0); 14 | vColor = mix(vec3(0.0), vec3(lum), equal(ivec3(gl_VertexIndex), ivec3(0, 1, 2))); 15 | } 16 | -------------------------------------------------------------------------------- /tests/assets/shaders/hdrtest_srgb_gradient.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec3 vColor; 4 | layout(location = 0) out vec3 FragColor; 5 | 6 | layout(constant_id = 0) const bool hdr10 = false; 7 | 8 | layout(set = 0, binding = 1) uniform Lum 9 | { 10 | float lum; 11 | }; 12 | 13 | vec3 srgb_to_linear(vec3 color) 14 | { 15 | bvec3 isLo = lessThanEqual(color, vec3(0.04045f)); 16 | 17 | vec3 loPart = color / 12.92f; 18 | vec3 hiPart = pow((color + 0.055f) / 1.055f, vec3(12.0f / 5.0f)); 19 | return mix(hiPart, loPart, isLo); 20 | } 21 | 22 | 23 | vec3 linear_to_srgb(vec3 col) 24 | { 25 | return mix(1.055 * pow(col, vec3(1.0 / 2.4)) - 0.055, col * 12.92, lessThanEqual(col, vec3(0.0031308))); 26 | } 27 | 28 | vec3 encode_transfer_function(vec3 nits) 29 | { 30 | if (hdr10) 31 | { 32 | // PQ 33 | vec3 y = clamp(nits / 10000.0, vec3(0.0), vec3(1.0)); 34 | const float c1 = 0.8359375; 35 | const float c2 = 18.8515625; 36 | const float c3 = 18.6875; 37 | const float m1 = 0.1593017578125; 38 | const float m2 = 78.84375; 39 | vec3 num = c1 + c2 * pow(y, vec3(m1)); 40 | vec3 den = 1.0 + c3 * pow(y, vec3(m1)); 41 | vec3 n = pow(num / den, vec3(m2)); 42 | return n; 43 | } 44 | else 45 | { 46 | vec3 n = clamp(nits / 100.0, vec3(0.0), vec3(1.0)); 47 | return linear_to_srgb(n); 48 | } 49 | } 50 | 51 | void main() 52 | { 53 | vec3 color = srgb_to_linear(vColor) * lum; 54 | FragColor = encode_transfer_function(color); 55 | } 56 | -------------------------------------------------------------------------------- /tests/assets/shaders/hdrtest_srgb_gradient.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 aPos; 4 | layout(location = 0) out vec3 vColor; 5 | 6 | void main() 7 | { 8 | gl_Position = vec4(aPos, 0.0, 1.0); 9 | vColor = mix(vec3(1.0), vec3(0.0), bvec3((gl_VertexIndex & 1) == 1)); 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/shaders/image_write.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | 4 | layout(set = 0, binding = 0, rgba8) writeonly uniform image2D uImage; 5 | layout(set = 0, binding = 1) uniform sampler2D uTexture; 6 | 7 | void main() 8 | { 9 | imageStore(uImage, ivec2(gl_GlobalInvocationID.xy), texelFetch(uTexture, ivec2(gl_GlobalInvocationID.xy), 0)); 10 | } -------------------------------------------------------------------------------- /tests/assets/shaders/meshlet_cull_aabb.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(local_size_x = 64) in; 4 | 5 | #define MESHLET_RENDER_DESCRIPTOR_SET 0 6 | #define MESHLET_RENDER_AABB_BINDING 0 7 | #define MESHLET_RENDER_BOUND_BINDING 1 8 | #define MESHLET_RENDER_TRANSFORM_BINDING 2 9 | #define MESHLET_RENDER_FRUSTUM_BINDING 3 10 | #define MESHLET_RENDER_TASKS_BINDING 5 11 | #if MESHLET_RENDER_PHASE == 2 12 | #extension GL_EXT_samplerless_texture_functions : require 13 | #define MESHLET_RENDER_HIZ_BINDING 6 14 | #endif 15 | #include "meshlet_render.h" 16 | 17 | layout(set = 0, binding = 4) writeonly buffer AABBOut 18 | { 19 | uint data[]; 20 | } visibility; 21 | 22 | layout(push_constant) uniform Registers 23 | { 24 | uint count; 25 | } registers; 26 | 27 | shared uint shared_bits[2]; 28 | 29 | void main() 30 | { 31 | uint index = gl_GlobalInvocationID.x; 32 | 33 | if (gl_LocalInvocationIndex < 2) 34 | shared_bits[gl_LocalInvocationIndex] = 0; 35 | barrier(); 36 | 37 | bool active_aabb = false; 38 | if (index < registers.count) 39 | { 40 | AABB aabb = aabb.data[index]; 41 | active_aabb = frustum_cull(aabb.lo, aabb.hi); 42 | #ifdef MESHLET_RENDER_HIZ_BINDING 43 | if (active_aabb) 44 | active_aabb = aabb_hiz_cull(aabb.lo, aabb.hi); 45 | #endif 46 | } 47 | 48 | if (active_aabb) 49 | atomicOr(shared_bits[gl_LocalInvocationIndex / 32], 1u << (gl_LocalInvocationIndex & 31u)); 50 | 51 | barrier(); 52 | 53 | if (gl_LocalInvocationIndex < 2) 54 | visibility.data[2 * gl_WorkGroupID.x + gl_LocalInvocationIndex] = shared_bits[gl_LocalInvocationIndex]; 55 | } 56 | -------------------------------------------------------------------------------- /tests/assets/shaders/meshlet_debug.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_ARB_shader_draw_parameters : require 3 | 4 | invariant gl_Position; 5 | 6 | #include "meshlet_render_types.h" 7 | 8 | layout(location = 0) in vec3 POS; 9 | layout(location = 1) in mediump vec3 NORMAL; 10 | layout(location = 2) in mediump vec4 TANGENT; 11 | layout(location = 3) in vec2 UV; 12 | 13 | layout(location = 0) out mediump vec3 vNormal; 14 | layout(location = 1) out mediump vec4 vTangent; 15 | layout(location = 2) out vec2 vUV; 16 | 17 | #if !SINGLE_INSTANCE_RENDER 18 | layout(location = 3) flat out uint vDrawID; 19 | #endif 20 | 21 | layout(set = 1, binding = 0) uniform UBO 22 | { 23 | mat4 VP; 24 | }; 25 | 26 | #if SINGLE_INSTANCE_RENDER 27 | layout(set = 1, binding = 1) uniform DrawParameters 28 | { 29 | mat4 M; 30 | }; 31 | #else 32 | layout(set = 0, binding = 0) readonly buffer DrawParameters 33 | { 34 | CompactedDrawInfo data[]; 35 | } draw_info; 36 | 37 | layout(set = 0, binding = 1) readonly buffer Transforms 38 | { 39 | mat4 data[]; 40 | } transforms; 41 | #endif 42 | 43 | void main() 44 | { 45 | #if !SINGLE_INSTANCE_RENDER 46 | mat4 M = transforms.data[draw_info.data[gl_DrawIDARB].node_offset]; 47 | #endif 48 | vec3 world_pos = (M * vec4(POS, 1.0)).xyz; 49 | vNormal = mat3(M) * NORMAL; 50 | vTangent = vec4(mat3(M) * TANGENT.xyz, TANGENT.w); 51 | vUV = UV; 52 | #if !SINGLE_INSTANCE_RENDER 53 | vDrawID = draw_info.data[gl_DrawIDARB].meshlet_index; 54 | #endif 55 | 56 | gl_Position = VP * vec4(world_pos, 1.0); 57 | } 58 | -------------------------------------------------------------------------------- /tests/assets/shaders/mrt_debug.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 vUV; 3 | layout(set = 0, binding = 0) uniform sampler2D uMRT0; 4 | layout(set = 0, binding = 1) uniform sampler2D uMRT1; 5 | layout(set = 0, binding = 2) uniform sampler2D uMRT2; 6 | layout(set = 0, binding = 3) uniform sampler2D uMRT3; 7 | layout(location = 0) out vec4 FragColor; 8 | 9 | void main() 10 | { 11 | if (vUV.x < 0.5) 12 | { 13 | if (vUV.y < 0.5) 14 | FragColor = textureLod(uMRT0, vUV, 0.0); 15 | else 16 | FragColor = textureLod(uMRT2, vUV, 0.0); 17 | } 18 | else 19 | { 20 | if (vUV.y < 0.5) 21 | FragColor = textureLod(uMRT1, vUV, 0.0); 22 | else 23 | FragColor = textureLod(uMRT3, vUV, 0.0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/assets/shaders/mrt_quad.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 1) out vec4 MRT1; 3 | layout(location = 2) out vec4 MRT2; 4 | layout(location = 3) out vec4 MRT3; 5 | 6 | void main() 7 | { 8 | MRT1 = vec4(0.0, 1.0, 0.0, 1.0); 9 | MRT2 = vec4(0.0, 1.0, 1.0, 1.0); 10 | MRT3 = vec4(1.0, 0.0, 1.0, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /tests/assets/shaders/multi_draw_indirect.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | layout(location = 0) in vec4 vColor; 5 | 6 | void main() 7 | { 8 | FragColor = vColor; 9 | } -------------------------------------------------------------------------------- /tests/assets/shaders/multi_draw_indirect.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec4 Position; 4 | layout(location = 1) in vec4 Color; 5 | layout(location = 0) out vec4 vColor; 6 | 7 | void main() 8 | { 9 | vColor = Color; 10 | gl_Position = Position; 11 | } 12 | -------------------------------------------------------------------------------- /tests/assets/shaders/multiview_debug.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 vUV; 3 | layout(set = 0, binding = 0) uniform sampler2DArray uMultiview; 4 | layout(location = 0) out vec4 FragColor; 5 | 6 | void main() 7 | { 8 | if (vUV.x < 0.5) 9 | { 10 | if (vUV.y < 0.5) 11 | FragColor = textureLod(uMultiview, vec3(vUV, 0.0), 0.0); 12 | else 13 | FragColor = textureLod(uMultiview, vec3(vUV, 1.0), 0.0); 14 | } 15 | else 16 | { 17 | if (vUV.y < 0.5) 18 | FragColor = textureLod(uMultiview, vec3(vUV, 2.0), 0.0); 19 | else 20 | FragColor = textureLod(uMultiview, vec3(vUV, 3.0), 0.0); 21 | } 22 | } -------------------------------------------------------------------------------- /tests/assets/shaders/multiview_quad.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_multiview : require 3 | layout(location = 0) out vec4 FragColor; 4 | 5 | const vec4 colors[4] = vec4[](vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0)); 6 | 7 | void main() 8 | { 9 | FragColor = colors[gl_ViewIndex]; 10 | } -------------------------------------------------------------------------------- /tests/assets/shaders/multiview_quad.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_multiview : require 3 | 4 | layout(std140, binding = 0) uniform UBO 5 | { 6 | vec4 BasePositions[4]; 7 | }; 8 | 9 | layout(location = 0) in vec2 Quad; 10 | 11 | void main() 12 | { 13 | vec2 pos = BasePositions[gl_ViewIndex].xy; 14 | pos.x += float(gl_InstanceIndex) * 0.03; 15 | pos += Quad; 16 | gl_Position = vec4(pos, 0.0, 1.0); 17 | } 18 | -------------------------------------------------------------------------------- /tests/assets/shaders/music_viz.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) out vec4 FragColor; 3 | 4 | layout(push_constant, std430) uniform Registers 5 | { 6 | vec3 color; 7 | float inv_count; 8 | } registers; 9 | 10 | void main() 11 | { 12 | FragColor = vec4(registers.color, 1.0); 13 | } -------------------------------------------------------------------------------- /tests/assets/shaders/music_viz.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #include "prerotate.h" 4 | 5 | layout(location = 0) in float vMusic; 6 | layout(push_constant, std430) uniform Registers 7 | { 8 | vec3 color; 9 | float inv_count; 10 | } registers; 11 | 12 | void main() 13 | { 14 | float x = float(gl_VertexIndex) * registers.inv_count; 15 | float y = -vMusic; 16 | x = 2.0 * x - 1.0; 17 | gl_Position = vec4(x, 16.0 * y, 0.0, 1.0); 18 | prerotate_fixup_clip_xy(); 19 | } 20 | -------------------------------------------------------------------------------- /tests/assets/shaders/query_lod.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec2 FragColor; 4 | layout(set = 0, binding = 0) uniform sampler2D uSampler; 5 | layout(location = 0) in vec2 vUV; 6 | 7 | void main() 8 | { 9 | FragColor = textureQueryLod(uSampler, vUV * 0.0); 10 | } 11 | -------------------------------------------------------------------------------- /tests/assets/shaders/query_lod_debug.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) uniform sampler2D uSampler; 4 | layout(location = 0) in vec2 vUV; 5 | layout(location = 0) out vec4 FragColor; 6 | 7 | vec2 remap_range(vec2 v) 8 | { 9 | return v * 0.1 + 0.5; 10 | } 11 | 12 | void main() 13 | { 14 | FragColor = vec4(remap_range(textureLod(uSampler, vUV, 0.0).xy), 0.0, 1.0); 15 | } -------------------------------------------------------------------------------- /tests/assets/shaders/robustness2.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_scalar_block_layout : require 3 | 4 | layout(local_size_x = 1) in; 5 | 6 | layout(set = 0, binding = 0, scalar) readonly buffer Buf0 7 | { 8 | layout(offset = 16) vec4 m; 9 | }; 10 | 11 | layout(set = 0, binding = 1) writeonly buffer Output 12 | { 13 | mat2x4 data; 14 | }; 15 | 16 | void main() 17 | { 18 | vec4 loaded = m; 19 | data = mat2x4(loaded, loaded); 20 | } -------------------------------------------------------------------------------- /tests/assets/shaders/sample_cube_array.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #if 0 4 | layout(set = 0, binding = 0) uniform sampler2DArray uCube; 5 | #elif 0 6 | layout(set = 0, binding = 0) uniform samplerCube uCube; 7 | #else 8 | layout(set = 0, binding = 0) uniform samplerCubeArray uCube; 9 | #endif 10 | 11 | layout(location = 0) out vec4 FragColor; 12 | 13 | const vec3 directions[] = vec3[]( 14 | vec3(1.0, 0.0, 0.0), 15 | vec3(-1.0, 0.0, 0.0), 16 | vec3(0.0, 1.0, 0.0), 17 | vec3(0.0, -1.0, 0.0), 18 | vec3(0.0, 0.0, 1.0), 19 | vec3(0.0, 0.0, -1.0)); 20 | 21 | void main() 22 | { 23 | int face = int(gl_FragCoord.x); 24 | float slice = floor(gl_FragCoord.y); 25 | #if 0 26 | FragColor = textureLod(uCube, vec3(0.5, 0.5, float(face) + 6.0 * slice), 0.0); 27 | #elif 0 28 | FragColor = textureLod(uCube, directions[face], 0.0); 29 | #else 30 | FragColor = textureLod(uCube, vec4(directions[face], slice), 0.0); 31 | #endif 32 | } -------------------------------------------------------------------------------- /tests/assets/shaders/sample_pcf.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) out vec4 FragColor; 3 | layout(location = 0) in vec2 vUV; 4 | layout(set = 0, binding = 0) uniform sampler2D uPlain; 5 | layout(set = 1, binding = 1) uniform sampler2DShadow uPCF; 6 | 7 | void main() 8 | { 9 | vec4 clip = vec4(vUV, 1.0, 2.0); 10 | FragColor = mix(texture(uPlain, vUV).xxxx, vec4(textureProjLod(uPCF, clip, 0.0)), 0.9); 11 | } -------------------------------------------------------------------------------- /tests/assets/shaders/sampler_precision.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 64) in; 3 | 4 | layout(set = 0, binding = 0) uniform sampler2D uTexture; 5 | 6 | layout(set = 0, binding = 1) writeonly buffer uBuffer 7 | { 8 | uvec2 samples[]; 9 | }; 10 | 11 | void main() 12 | { 13 | float u = float(gl_GlobalInvocationID.x) / (4.0 * 2048.0); 14 | 15 | float gather_result = textureGather(uTexture, vec2(u, 0.5), 0).x; 16 | float point_result = textureLod(uTexture, vec2(u, 0.5), 0.0).x; 17 | samples[gl_GlobalInvocationID.x] = uvec2(round(255.0 * vec2(point_result, gather_result))); 18 | } -------------------------------------------------------------------------------- /tests/assets/shaders/test_quad.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) out vec4 FragColor; 3 | layout(location = 0) in vec2 vQuad; 4 | 5 | layout(push_constant, std430) uniform Registers 6 | { 7 | vec4 color; 8 | float phase; 9 | } registers; 10 | 11 | void main() 12 | { 13 | vec2 absquad = abs(vQuad); 14 | vec2 feather = smoothstep(vec2(0.9), vec2(1.0), absquad); 15 | float f = (1.0 - feather.x) * (1.0 - feather.y); 16 | FragColor = registers.color * vec4(vec3(1.0), f); 17 | } -------------------------------------------------------------------------------- /tests/assets/shaders/test_quad.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(location = 0) in vec2 Position; 3 | layout(location = 0) out vec2 vQuad; 4 | 5 | layout(push_constant, std430) uniform Registers 6 | { 7 | vec4 color; 8 | float phase; 9 | } registers; 10 | 11 | void main() 12 | { 13 | vec2 p = Position * vec2(0.2, 0.8); 14 | p.x += registers.phase; 15 | gl_Position = vec4(p, 0.0, 1.0); 16 | vQuad = Position; 17 | } -------------------------------------------------------------------------------- /tests/assets/shaders/triangle.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 FragColor; 4 | layout(location = 0) in vec4 vColor; 5 | 6 | void main() 7 | { 8 | FragColor = vColor; 9 | } -------------------------------------------------------------------------------- /tests/assets/shaders/triangle.task: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_mesh_shader : require 3 | #extension GL_KHR_shader_subgroup_basic : require 4 | #extension GL_KHR_shader_subgroup_ballot : require 5 | layout(local_size_x = 64) in; 6 | 7 | taskPayloadSharedEXT vec2 offsets[4]; 8 | 9 | void main() 10 | { 11 | if (gl_LocalInvocationIndex == 0) 12 | { 13 | offsets[0] = vec2(-0.1, -0.1); 14 | offsets[1] = vec2(+0.1, -0.1); 15 | offsets[2] = vec2(-0.1, +0.1); 16 | offsets[3] = vec2(+0.1, +0.1); 17 | } 18 | 19 | uint num_invocations = subgroupBallotBitCount(subgroupBallot(true)); 20 | uint expected_groups = gl_WorkGroupSize.x / gl_SubgroupSize; 21 | 22 | bool valid_invocations = num_invocations == gl_SubgroupSize; 23 | bool valid_groups = gl_NumSubgroups == expected_groups; 24 | 25 | EmitMeshTasksEXT(gl_SubgroupSize == 32 ? 2 : 4, uint(valid_invocations && valid_groups), 1); 26 | } -------------------------------------------------------------------------------- /tests/assets/shaders/triangle.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 Position; 4 | layout(location = 1) in vec4 Color; 5 | layout(location = 0) out vec4 vColor; 6 | 7 | void main() 8 | { 9 | gl_Position = vec4(Position, 0.0, 1.0); 10 | vColor = Color; 11 | } 12 | -------------------------------------------------------------------------------- /tests/assets/shaders/triangle_mesh.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_EXT_mesh_shader : require 3 | 4 | layout(location = 0) out vec4 FragColor; 5 | layout(location = 0) perprimitiveEXT in vec4 vColor; 6 | 7 | void main() 8 | { 9 | FragColor = vColor; 10 | } -------------------------------------------------------------------------------- /tests/assets/shaders/video.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 2, binding = 0) uniform sampler2D uTex; 4 | layout(location = 0) in vec2 vUV; 5 | layout(location = 0) out vec4 FragColor; 6 | 7 | void main() 8 | { 9 | FragColor = texture(uTex, vUV); 10 | } -------------------------------------------------------------------------------- /tests/assets/shaders/video.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 3, binding = 0) uniform UBO 4 | { 5 | mat4 MVP; 6 | }; 7 | 8 | layout(location = 0) out vec2 vUV; 9 | 10 | void main() 11 | { 12 | float x = float(gl_VertexIndex & 1) * 2.0 - 1.0; 13 | float z = float(gl_VertexIndex & 2) - 1.0; 14 | vUV = vec2(x, z) * 0.5 + 0.5; 15 | gl_Position = MVP * vec4(x, 0.0, z, 1.0); 16 | } -------------------------------------------------------------------------------- /tests/assets/shaders/write_swapchain.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | layout(local_size_x = 8, local_size_y = 8) in; 3 | 4 | layout(set = 0, binding = 0) writeonly uniform image2D SwapImage; 5 | 6 | layout(push_constant) uniform Registers 7 | { 8 | uvec2 resolution; 9 | } registers; 10 | 11 | void main() 12 | { 13 | if (all(lessThan(gl_GlobalInvocationID.xy, registers.resolution))) 14 | { 15 | uint checker = (gl_GlobalInvocationID.x ^ gl_GlobalInvocationID.y) >> 6u; 16 | imageStore(SwapImage, ivec2(gl_GlobalInvocationID.xy), (checker & 1u) != 0u ? vec4(0.6, 0.1, 0.1, 1.0) : vec4(0.1, 0.6, 0.1, 1.0)); 17 | } 18 | } -------------------------------------------------------------------------------- /tests/assets/shaders/yuv420p-sample.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) uniform sampler2D uSamplerLinearYUV420P; 4 | layout(location = 0) in vec2 vUV; 5 | layout(location = 0) out vec4 FragColor; 6 | 7 | void main() 8 | { 9 | FragColor = textureLod(uSamplerLinearYUV420P, vUV, 0.0); 10 | } -------------------------------------------------------------------------------- /tests/assets/textures/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Themaister/Granite/e1dde101e1f17664687c019d8592073eb4a122cb/tests/assets/textures/sprite.png -------------------------------------------------------------------------------- /tests/atomic_append_buffer_test.cpp: -------------------------------------------------------------------------------- 1 | #include "atomic_append_buffer.hpp" 2 | #include "logging.hpp" 3 | #include "thread_group.hpp" 4 | #include 5 | #include 6 | 7 | using namespace Util; 8 | using namespace Granite; 9 | 10 | static void test_iterations(ThreadGroup &group, unsigned iterations) 11 | { 12 | AtomicAppendBuffer Buf; 13 | 14 | for (unsigned i = 0; i < iterations; i++) 15 | group.create_task([i, &Buf]() { Buf.push(i); }); 16 | group.wait_idle(); 17 | 18 | std::vector output; 19 | 20 | Buf.for_each_ranged([&](const unsigned *values, size_t count) { 21 | output.insert(output.end(), values, values + count); 22 | }); 23 | 24 | std::sort(output.begin(), output.end()); 25 | 26 | if (output.size() != iterations) 27 | exit(EXIT_FAILURE); 28 | 29 | for (unsigned i = 0; i < iterations; i++) 30 | if (output[i] != i) 31 | exit(EXIT_FAILURE); 32 | } 33 | 34 | int main() 35 | { 36 | ThreadGroup group; 37 | group.start(4, 0, {}); 38 | test_iterations(group, 0); 39 | test_iterations(group, 3); 40 | test_iterations(group, 9); 41 | test_iterations(group, 8); 42 | test_iterations(group, 16); 43 | test_iterations(group, 32); 44 | test_iterations(group, 34); 45 | test_iterations(group, 63); 46 | test_iterations(group, 94); 47 | test_iterations(group, 195); 48 | } -------------------------------------------------------------------------------- /tests/ecs_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ecs.hpp" 2 | #include "logging.hpp" 3 | 4 | using namespace Granite; 5 | 6 | struct AComponent : ComponentBase 7 | { 8 | GRANITE_COMPONENT_TYPE_DECL(AComponent) 9 | AComponent(int v_) 10 | : v(v_) 11 | { 12 | } 13 | int v; 14 | }; 15 | 16 | struct BComponent : ComponentBase 17 | { 18 | GRANITE_COMPONENT_TYPE_DECL(BComponent) 19 | BComponent(int v_) 20 | : v(v_) 21 | { 22 | } 23 | int v; 24 | }; 25 | 26 | struct CComponent : ComponentBase 27 | { 28 | GRANITE_COMPONENT_TYPE_DECL(CComponent) 29 | CComponent(int v_) 30 | : v(v_) 31 | { 32 | } 33 | int v; 34 | }; 35 | 36 | int main() 37 | { 38 | EntityPool pool; 39 | auto a = pool.create_entity(); 40 | a->allocate_component(10); 41 | a->allocate_component(20); 42 | 43 | auto &group_ab = pool.get_component_group(); 44 | auto &group_ba = pool.get_component_group(); 45 | auto &group_bc = pool.get_component_group(); 46 | 47 | a->allocate_component(40); 48 | 49 | for (auto &e : group_ab) 50 | LOGI("AB: %d, %d\n", get<0>(e)->v, get<1>(e)->v); 51 | for (auto &e : group_ba) 52 | LOGI("BA: %d, %d\n", get<0>(e)->v, get<1>(e)->v); 53 | for (auto &e : group_bc) 54 | LOGI("BC: %d\n", get<0>(e)->v); 55 | } -------------------------------------------------------------------------------- /tests/linkage_test.cpp: -------------------------------------------------------------------------------- 1 | #include "global_managers_init.hpp" 2 | 3 | int main() 4 | { 5 | Granite::Global::init(); 6 | LOGI("Hello there! :)\n"); 7 | Granite::Global::deinit(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/lru_cache_test.cpp: -------------------------------------------------------------------------------- 1 | #include "lru_cache.hpp" 2 | #include "logging.hpp" 3 | 4 | using namespace Util; 5 | 6 | static int active_foos; 7 | 8 | struct Foo 9 | { 10 | Foo() 11 | { 12 | active_foos++; 13 | LOGI("Construct (%d alive)!\n", active_foos); 14 | } 15 | 16 | ~Foo() 17 | { 18 | active_foos--; 19 | LOGI("Destruct (%d alive)!\n", active_foos); 20 | } 21 | unsigned value = 0; 22 | }; 23 | 24 | int main() 25 | { 26 | LRUCache cache; 27 | cache.set_total_cost(20); 28 | 29 | cache.allocate(1, 10)->value = 1; 30 | cache.allocate(2, 10)->value = 2; 31 | cache.allocate(3, 10)->value = 3; 32 | cache.allocate(4, 10)->value = 4; 33 | cache.allocate(3, 10); 34 | cache.evict(2); 35 | cache.erase(1); 36 | 37 | LOGI("=== Values ===\n"); 38 | for (auto &entry : cache) 39 | LOGI("Value: %u\n", entry.t.value); 40 | 41 | cache.prune(); 42 | 43 | LOGI("=== Pruned ===\n"); 44 | for (auto &entry : cache) 45 | LOGI("Value: %u\n", entry.t.value); 46 | } -------------------------------------------------------------------------------- /tests/setup_android_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TARGET="$1" 3 | shift 4 | ../tools/create_android_build.py \ 5 | --output-gradle android \ 6 | --application-id net.themaister.granite.test \ 7 | --granite-dir .. \ 8 | --native-target "$TARGET" \ 9 | --app-name "Granite Test" \ 10 | --abis arm64-v8a \ 11 | --cmake-lists-toplevel ../CMakeLists.txt \ 12 | --assets assets $@ 13 | -------------------------------------------------------------------------------- /tests/tone_filter_bench.cpp: -------------------------------------------------------------------------------- 1 | #include "dsp/tone_filter.hpp" 2 | #include "timer.hpp" 3 | #include "logging.hpp" 4 | #include 5 | #include 6 | 7 | using namespace Granite::Audio; 8 | 9 | #if 0 10 | #include "simd_headers.hpp" 11 | 12 | static float recp(float v) 13 | { 14 | float32x2_t vs = vdup_n_f32(v); 15 | vs = vrecpe_f32(vs); 16 | return vget_lane_f32(vs, 0); 17 | } 18 | 19 | static float rsqrt(float v) 20 | { 21 | float32x2_t vs = vdup_n_f32(v); 22 | vs = vmul_f32(vs, vrsqrte_f32(vmax_f32(vs, vdup_n_f32(1e-30f)))); 23 | return vget_lane_f32(vs, 0); 24 | } 25 | 26 | static void test_div_sqrt() 27 | { 28 | float inputs[41]; 29 | for (int i = 0; i <= 40; i++) 30 | inputs[i] = 3.0f * std::pow(10.0f, float(i) - 20.0f); 31 | 32 | for (auto i : inputs) 33 | LOGI("recp(%g) = %g\n", i, recp(i)); 34 | for (auto i : inputs) 35 | LOGI("sqrt(%g) = %g\n", i, rsqrt(i)); 36 | } 37 | #endif 38 | 39 | int main() 40 | { 41 | #if 0 42 | test_div_sqrt(); 43 | #endif 44 | 45 | DSP::ToneFilter filter; 46 | filter.init(44100.0f); 47 | 48 | float buffer[1000] = {}; 49 | float out_buffer[1000] = {}; 50 | 51 | std::mt19937 rnd; 52 | std::uniform_real_distribution range(-1.0f, 1.0f); 53 | for (auto &b : buffer) 54 | b = range(rnd); 55 | 56 | auto start = Util::get_current_time_nsecs(); 57 | for (unsigned i = 0; i < 20000; i++) 58 | filter.filter(out_buffer, buffer, 1000); 59 | auto end = Util::get_current_time_nsecs(); 60 | LOGI("Perf: %.6f M samples / s\n", 20.0 / (1e-9 * double(end - start))); 61 | } 62 | -------------------------------------------------------------------------------- /third_party/mikktspace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_third_party_lib(granite-mikktspace mikktspace.c mikktspace.h) 2 | target_include_directories(granite-mikktspace PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | -------------------------------------------------------------------------------- /third_party/renderdoc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(granite-renderdoc-app INTERFACE) 2 | target_include_directories(granite-renderdoc-app INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_compile_definitions(granite-renderdoc-app INTERFACE GRANITE_RENDERDOC_CAPTURE) 4 | -------------------------------------------------------------------------------- /third_party/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_third_party_lib(granite-stb stb_image.c stb_truetype.c) 2 | target_include_directories(granite-stb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/stb) 3 | if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 4 | target_compile_options(granite-stb PRIVATE -Wno-backslash-newline-escape) 5 | endif() 6 | 7 | add_granite_third_party_lib(granite-stb-vorbis stb_vorbis.h stb/stb_vorbis.c) 8 | target_include_directories(granite-stb-vorbis PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 9 | if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 10 | target_compile_options(granite-stb-vorbis PRIVATE -Wno-backslash-newline-escape) 11 | endif() 12 | 13 | -------------------------------------------------------------------------------- /third_party/stb/stb_image.c: -------------------------------------------------------------------------------- 1 | #define STB_IMAGE_IMPLEMENTATION 2 | #define STB_IMAGE_WRITE_IMPLEMENTATION 3 | #include "stb_image.h" 4 | #include "stb_image_write.h" 5 | 6 | -------------------------------------------------------------------------------- /third_party/stb/stb_truetype.c: -------------------------------------------------------------------------------- 1 | #define STB_TRUETYPE_IMPLEMENTATION 2 | #include "stb_truetype.h" 3 | 4 | -------------------------------------------------------------------------------- /third_party/stb/stb_vorbis.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define STB_VORBIS_HEADER_ONLY 4 | #include "stb/stb_vorbis.c" -------------------------------------------------------------------------------- /threading/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-threading 2 | thread_group.cpp thread_group.hpp 3 | thread_latch.cpp thread_latch.hpp 4 | task_composer.cpp task_composer.hpp) 5 | 6 | target_include_directories(granite-threading PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 7 | target_link_libraries(granite-threading PUBLIC granite-util granite-application-global) -------------------------------------------------------------------------------- /toolchains/aarch64.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_PROCESSOR arm64) 3 | set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) 4 | set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) 5 | -------------------------------------------------------------------------------- /toolchains/armhf.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_PROCESSOR arm) 3 | set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) 4 | set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) 5 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_executable(gltf-image-packer image_packer.cpp) 2 | target_link_libraries(gltf-image-packer PRIVATE granite-stb) 3 | 4 | add_granite_executable(ibl-brdf-lut-generate brdf_lut_generate.cpp) 5 | 6 | add_granite_offline_tool(convert-equirect-to-environment convert_equirect_to_environment.cpp) 7 | 8 | add_granite_offline_tool(convert-cube-to-environment convert_cube_to_environment.cpp) 9 | 10 | add_granite_offline_tool(gtx-convert gtx_convert.cpp) 11 | target_link_libraries(gtx-convert PRIVATE granite-scene-export) 12 | 13 | add_granite_offline_tool(gtx-cat gtx_cat.cpp) 14 | 15 | add_granite_offline_tool(gltf-repacker gltf_repacker.cpp) 16 | target_link_libraries(gltf-repacker PRIVATE granite-scene-export granite-rapidjson) 17 | 18 | add_granite_offline_tool(obj-to-gltf obj_to_gltf.cpp) 19 | target_link_libraries(obj-to-gltf PRIVATE granite-scene-export) 20 | 21 | add_granite_offline_tool(image-compare image_compare.cpp) 22 | target_link_libraries(image-compare PRIVATE granite-stb granite-rapidjson) 23 | 24 | add_granite_offline_tool(build-smaa-luts build_smaa_luts.cpp smaa/AreaTex.h smaa/SearchTex.h) 25 | 26 | add_granite_offline_tool(bitmap-to-mesh bitmap_mesh.cpp bitmap_to_mesh.cpp bitmap_to_mesh.hpp) 27 | target_link_libraries(bitmap-to-mesh PRIVATE meshoptimizer granite-scene-export) 28 | 29 | add_granite_application(aa-bench aa_bench.cpp) 30 | 31 | add_granite_headless_application(aa-bench-headless aa_bench.cpp) 32 | 33 | add_granite_application(texture-viewer texture_viewer.cpp) 34 | -------------------------------------------------------------------------------- /tools/android-cmake-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $ANDROID_HOME ]; then 4 | echo "ANDROID_HOME is not set!" 5 | exit 1 6 | fi 7 | 8 | cmake $@ \ 9 | -DCMAKE_TOOLCHAIN_FILE="$ANDROID_HOME/ndk-bundle/build/cmake/android.toolchain.cmake" \ 10 | -DANDROID_TOOLCHAIN=clang \ 11 | -DANDROID_ARM_MODE=arm \ 12 | -DANDROID_CPP_FEATURES=exceptions \ 13 | -DANDROID_PLATFORM=android-26 \ 14 | -DANDROID_ARM_NEON=ON \ 15 | -DANDROID_ABI=arm64-v8a 16 | -------------------------------------------------------------------------------- /tools/build-steamrt-inside.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This is run from inside the container. 4 | # Useful as an initial template. 5 | 6 | mkdir -p build-steamrt 7 | cd build-steamrt 8 | cmake .. \ 9 | -DCMAKE_BUILD_TYPE=Release \ 10 | -DCMAKE_INSTALL_PREFIX=output \ 11 | -DGRANITE_VIEWER_INSTALL=ON \ 12 | -DGRANITE_AUDIO=ON \ 13 | -DGRANITE_ASTC_ENCODER_COMPRESSION=OFF \ 14 | -DPYTHON_EXECUTABLE=$(which python3) \ 15 | -G Ninja 16 | 17 | ninja install/strip -v 18 | 19 | -------------------------------------------------------------------------------- /tools/build-steamrt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Useful as an initial template. 4 | 5 | docker run -it --init --rm -u $UID -w /granite -v $(pwd):/granite registry.gitlab.steamos.cloud/steamrt/sniper/sdk ./tools/build-steamrt-inside.sh 6 | 7 | -------------------------------------------------------------------------------- /tools/build_smaa_luts.cpp: -------------------------------------------------------------------------------- 1 | #include "smaa/AreaTex.h" 2 | #include "smaa/SearchTex.h" 3 | #include "logging.hpp" 4 | #include "memory_mapped_texture.hpp" 5 | #include "global_managers_init.hpp" 6 | #include 7 | 8 | using namespace Granite; 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | if (argc != 3) 13 | { 14 | LOGE("Usage: %s \n", argv[0]); 15 | return 1; 16 | } 17 | 18 | Granite::Global::init(); 19 | 20 | Vulkan::MemoryMappedTexture area; 21 | area.set_2d(VK_FORMAT_R8G8_UNORM, AREATEX_WIDTH, AREATEX_HEIGHT); 22 | if (!area.map_write(*GRANITE_FILESYSTEM(), argv[1])) 23 | { 24 | LOGE("Failed to save area tex.\n"); 25 | return 1; 26 | } 27 | 28 | Vulkan::MemoryMappedTexture search; 29 | search.set_2d(VK_FORMAT_R8_UNORM, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT); 30 | if (!search.map_write(*GRANITE_FILESYSTEM(), argv[2])) 31 | { 32 | LOGE("Failed to save search tex.\n"); 33 | return 1; 34 | } 35 | 36 | memcpy(area.get_layout().data(), areaTexBytes, AREATEX_SIZE); 37 | memcpy(search.get_layout().data(), searchTexBytes, SEARCHTEX_SIZE); 38 | } 39 | -------------------------------------------------------------------------------- /tools/setup_android_toolchain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $ANDROID_HOME ]; then 4 | echo "ANDROID_HOME is not defined. Set this to \$HOME/Android for example." 5 | exit 1 6 | fi 7 | 8 | echo "=== Using \$ANDROID_HOME = $ANDROID_HOME ===" 9 | 10 | if [ -d $ANDROID_HOME ]; then 11 | echo "$ANDROID_HOME is already populated. This script will install from scratch." 12 | exit 1 13 | fi 14 | 15 | # Grab from https://developer.android.com/studio 16 | # Adjust as necessary. Not sure if there's a generic way to do this ... 17 | echo "=== Downloading command line tools for Linux ===" 18 | VERSION=linux-11076708 19 | FILENAME=commandlinetools-${VERSION}_latest.zip 20 | wget https://dl.google.com/android/repository/$FILENAME || exit 1 21 | 22 | mkdir "$ANDROID_HOME" 23 | mv "$FILENAME" "$ANDROID_HOME/" 24 | cd "$ANDROID_HOME" 25 | echo "=== Unzipping command line tools ===" 26 | unzip "$FILENAME" >/dev/null 2>&1 || exit 1 27 | rm "$FILENAME" 28 | mkdir cmdline-tools/tools 29 | mv cmdline-tools/{NOTICE.txt,bin,lib,source.properties} cmdline-tools/tools 30 | 31 | export PATH="$PATH:$ANDROID_HOME/cmdline-tools/tools/bin:$ANDROID_HOME/platform-tools" 32 | 33 | echo "=== Make sure JDK 17 is enabled (e.g. for Arch) ===" 34 | echo " pacman -S jre17-openjdk" 35 | echo " archlinux-java set java-17-openjdk" 36 | 37 | echo "=== Automatically accepting all relevant licenses ===" 38 | yes | sdkmanager --licenses >/dev/null 2>&1 || exit 1 39 | 40 | echo "=== Done! Now update PATH in shell ===" 41 | echo " export PATH=\"\$PATH:\$ANDROID_HOME/cmdline-tools/tools/bin:\$ANDROID_HOME/platform-tools\"" 42 | -------------------------------------------------------------------------------- /ui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-ui 2 | widget.hpp widget.cpp 3 | window.hpp window.cpp 4 | vertical_packing.cpp vertical_packing.hpp 5 | horizontal_packing.cpp horizontal_packing.hpp 6 | image_widget.cpp image_widget.hpp 7 | label.cpp label.hpp 8 | slider.cpp slider.hpp 9 | click_button.cpp click_button.hpp 10 | toggle_button.cpp toggle_button.hpp 11 | ui_manager.hpp ui_manager.cpp) 12 | target_include_directories(granite-ui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 13 | target_link_libraries(granite-ui PUBLIC granite-util granite-renderer PRIVATE granite-stb) -------------------------------------------------------------------------------- /ui/horizontal_packing.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "widget.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace UI 30 | { 31 | class HorizontalPacking : public Widget 32 | { 33 | public: 34 | protected: 35 | float render(FlatRenderer &renderer, float layer, vec2 offset, vec2 size) override; 36 | void reconfigure() override; 37 | void reconfigure_to_canvas(vec2 offset, vec2 size) override; 38 | }; 39 | } 40 | } -------------------------------------------------------------------------------- /ui/vertical_packing.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "widget.hpp" 26 | 27 | namespace Granite 28 | { 29 | namespace UI 30 | { 31 | class VerticalPacking : public Widget 32 | { 33 | public: 34 | protected: 35 | float render(FlatRenderer &renderer, float layer, vec2 offset, vec2 size) override; 36 | void reconfigure() override; 37 | void reconfigure_to_canvas(vec2 offset, vec2 size) override; 38 | }; 39 | } 40 | } -------------------------------------------------------------------------------- /util/enum_cast.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Util 28 | { 29 | template 30 | constexpr typename std::underlying_type::type ecast(T x) 31 | { 32 | return static_cast::type>(x); 33 | } 34 | } -------------------------------------------------------------------------------- /util/hashmap.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "hash.hpp" 27 | 28 | namespace Util 29 | { 30 | struct UnityHasher 31 | { 32 | inline size_t operator()(uint64_t hash) const 33 | { 34 | return hash; 35 | } 36 | }; 37 | 38 | template 39 | using HashMap = std::unordered_map; 40 | } -------------------------------------------------------------------------------- /util/no_init_pod.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Util 28 | { 29 | template 30 | struct NoInitPOD 31 | { 32 | T value; 33 | 34 | NoInitPOD() 35 | { 36 | static_assert(sizeof(NoInitPOD) == sizeof(T), "Sizes do not match."); 37 | static_assert(alignof(NoInitPOD) == alignof(T), "Alignments do not match."); 38 | } 39 | 40 | static_assert(std::is_pod::value, "Type is not POD."); 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /util/thread_id.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Util 26 | { 27 | unsigned get_current_thread_index(); 28 | void register_thread_index(unsigned thread_index); 29 | } -------------------------------------------------------------------------------- /util/thread_name.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Util 26 | { 27 | void set_current_thread_name(const char *name); 28 | } 29 | -------------------------------------------------------------------------------- /util/thread_priority.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Util 26 | { 27 | enum class ThreadPriority 28 | { 29 | High, 30 | Default, 31 | Low 32 | }; 33 | 34 | void set_current_thread_priority(ThreadPriority priority); 35 | } 36 | -------------------------------------------------------------------------------- /video/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(FindPkgConfig) 2 | pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET 3 | libavdevice libavformat libavcodec libavutil) 4 | 5 | add_granite_internal_lib(granite-video 6 | ffmpeg_encode.cpp ffmpeg_encode.hpp 7 | slangmosh_encode_iface.hpp 8 | ffmpeg_decode.cpp ffmpeg_decode.hpp slangmosh_decode_iface.hpp 9 | ffmpeg_hw_device.cpp ffmpeg_hw_device.hpp) 10 | 11 | target_link_libraries(granite-video 12 | PUBLIC granite-vulkan 13 | PRIVATE PkgConfig::LIBAV granite-threading granite-math) 14 | if (GRANITE_AUDIO) 15 | target_link_libraries(granite-video PRIVATE granite-audio) 16 | endif() 17 | if (GRANITE_FFMPEG_VULKAN) 18 | target_compile_definitions(granite-video PRIVATE HAVE_FFMPEG_VULKAN) 19 | endif() 20 | target_link_libraries(granite-video PRIVATE pyroenc pyrowave) 21 | target_include_directories(granite-video PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 22 | target_compile_definitions(granite-video PUBLIC HAVE_GRANITE_FFMPEG) -------------------------------------------------------------------------------- /video/slangmosh_decode.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ "../assets/shaders/inc" ], 3 | "shaders": [ 4 | { 5 | "name": "yuv_to_rgb", 6 | "compute": true, 7 | "path": "../assets/shaders/util/yuv_to_rgb.comp" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /video/slangmosh_decode_iface.hpp: -------------------------------------------------------------------------------- 1 | // Autogenerated from slangmosh, do not edit. 2 | #ifndef SLANGMOSH_GENERATED_FFmpegDecodeiface_H 3 | #define SLANGMOSH_GENERATED_FFmpegDecodeiface_H 4 | #include 5 | namespace Vulkan 6 | { 7 | class Program; 8 | class Shader; 9 | } 10 | 11 | namespace FFmpegDecode 12 | { 13 | template 14 | struct Shaders 15 | { 16 | Program yuv_to_rgb = {}; 17 | Shaders() = default; 18 | 19 | template 20 | Shaders(Device &device, Layout &layout, const Resolver &resolver); 21 | }; 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /video/slangmosh_encode.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ "../assets/shaders/inc" ], 3 | "shaders": [ 4 | { 5 | "name": "rgb_to_yuv", 6 | "compute": true, 7 | "path": "../assets/shaders/util/rgb_to_yuv.comp" 8 | }, 9 | { 10 | "name": "rgb_scale", 11 | "compute": true, 12 | "path": "../assets/shaders/util/rgb_scale.comp" 13 | }, 14 | { 15 | "name": "chroma_downsample", 16 | "compute": true, 17 | "path": "../assets/shaders/util/chroma_downsample.comp" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /video/slangmosh_encode_iface.hpp: -------------------------------------------------------------------------------- 1 | // Autogenerated from slangmosh, do not edit. 2 | #ifndef SLANGMOSH_GENERATED_FFmpegEncodeiface_H 3 | #define SLANGMOSH_GENERATED_FFmpegEncodeiface_H 4 | #include 5 | namespace Vulkan 6 | { 7 | class Program; 8 | class Shader; 9 | } 10 | 11 | namespace FFmpegEncode 12 | { 13 | template 14 | struct Shaders 15 | { 16 | Program rgb_to_yuv = {}; 17 | Program rgb_scale = {}; 18 | Program chroma_downsample = {}; 19 | Shaders() = default; 20 | 21 | template 22 | Shaders(Device &device, Layout &layout, const Resolver &resolver); 23 | }; 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /viewer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_application(gltf-viewer viewer.cpp) 2 | add_granite_headless_application(gltf-viewer-headless viewer.cpp) 3 | 4 | target_link_libraries(gltf-viewer PRIVATE granite-scene-viewer) 5 | target_link_libraries(gltf-viewer-headless PRIVATE granite-scene-viewer) 6 | 7 | if (NOT ANDROID) 8 | if (NOT GRANITE_SHIPPING) 9 | target_compile_definitions(gltf-viewer PRIVATE ASSET_DIRECTORY=\"${CMAKE_CURRENT_SOURCE_DIR}/assets\") 10 | target_compile_definitions(gltf-viewer-headless PRIVATE ASSET_DIRECTORY=\"${CMAKE_CURRENT_SOURCE_DIR}/assets\") 11 | endif() 12 | if (GRANITE_INSTALL_EXE_TARGETS) 13 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/assets DESTINATION bin) 14 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../assets DESTINATION bin/builtin) 15 | endif() 16 | endif() 17 | 18 | if (GRANITE_BULLET) 19 | add_granite_application(physics-sandbox physics_sandbox.cpp) 20 | target_link_libraries(physics-sandbox PRIVATE granite-physics) 21 | if (NOT ANDROID) 22 | target_compile_definitions(physics-sandbox PRIVATE ASSET_DIRECTORY=\"${CMAKE_CURRENT_SOURCE_DIR}/assets\") 23 | endif() 24 | endif() 25 | 26 | option(GRANITE_VIEWER_INSTALL "Install Granite viewer and assets." OFF) 27 | 28 | if (GRANITE_VIEWER_INSTALL) 29 | granite_install_executable(gltf-viewer) 30 | granite_install_executable(gltf-viewer-headless) 31 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/assets DESTINATION ${CMAKE_INSTALL_BINDIR}) 32 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../assets DESTINATION ${CMAKE_INSTALL_BINDIR}/builtin) 33 | endif() 34 | -------------------------------------------------------------------------------- /viewer/quirks.json: -------------------------------------------------------------------------------- 1 | { 2 | "instanceDeferredLights": true, 3 | "mergeSubpasses" : true, 4 | "useTransientColor": true, 5 | "useTransientDepthStencil": true, 6 | "queueWaitOnSubmission": false, 7 | "stagingNeedDeviceLocal" : false, 8 | "useAsyncComputePost": true, 9 | "renderGraphForceSingleQueue" : false, 10 | "forceNoSubgroups" : false, 11 | "forceNoSubgroupShuffle" : false, 12 | "forceNoSubgroupSizeControl" : false 13 | } 14 | -------------------------------------------------------------------------------- /viewer/setup_android_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ../tools/create_android_build.py \ 3 | --output-gradle android \ 4 | --application-id net.themaister.gltf_viewer \ 5 | --granite-dir .. \ 6 | --native-target gltf-viewer \ 7 | --app-name "Granite glTF Viewer" \ 8 | --abis arm64-v8a \ 9 | --cmake-lists-toplevel ../CMakeLists.txt \ 10 | --fossilize \ 11 | --swappy \ 12 | --assets assets 13 | -------------------------------------------------------------------------------- /viewer/viewer_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "renderer": "deferred", 3 | "msaa": 1, 4 | "directionalLightShadows": true, 5 | "directionalLightShadowsVSM": false, 6 | "PCFKernelWide": true, 7 | "directionalLightShadowsCascaded": true, 8 | "clusteredLights": true, 9 | "clusteredLightsBindless": true, 10 | "clusteredLightsShadows": true, 11 | "clusteredLightsShadowsVSM": false, 12 | "clusteredLightsShadowsResolution": 512, 13 | "hdrBloom": true, 14 | "hdrBloomDynamicExposure": true, 15 | "forwardDepthPrepass" : true, 16 | "shadowMapResolution": 2048, 17 | "renderTargetFp16": false, 18 | "rescaleScene": false, 19 | "deferredClusteredStencilCulling": true, 20 | "postAA": "none", 21 | "showUi": true, 22 | "volumetricFog": false, 23 | "volumetricDiffuse": false, 24 | "ssao": true, 25 | "ssr": false, 26 | "debugProbes": false, 27 | "resolutionScale": 1.0, 28 | "resolutionScaleSharpen": true, 29 | "lodBias": 0.0 30 | } 31 | -------------------------------------------------------------------------------- /vulkan/cookie.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "cookie.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | Cookie::Cookie(Device *device) 29 | : cookie(device->allocate_cookie()) 30 | { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vulkan/pipeline_event.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "pipeline_event.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | EventHolder::~EventHolder() 29 | { 30 | if (event) 31 | { 32 | if (internal_sync) 33 | device->destroy_event_nolock(event); 34 | else 35 | device->destroy_event(event); 36 | } 37 | } 38 | 39 | void EventHolderDeleter::operator()(Vulkan::EventHolder *event) 40 | { 41 | event->device->handle_pool.events.free(event); 42 | } 43 | } -------------------------------------------------------------------------------- /vulkan/post-mortem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_granite_internal_lib(granite-vulkan-post-mortem 2 | post_mortem.cpp post_mortem.hpp) 3 | 4 | target_include_directories(granite-vulkan-post-mortem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 5 | target_link_libraries(granite-vulkan-post-mortem PRIVATE granite-util) 6 | 7 | if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") 8 | set(AFTERMATH_ARCH x64) 9 | else() 10 | set(AFTERMATH_ARCH x86) 11 | endif() 12 | 13 | find_library(GFSDK_LIBRARY GFSDK_Aftermath_Lib.x64 HINTS ${AFTERMATH_SDK_PATH}/lib/${AFTERMATH_ARCH}) 14 | 15 | if (GFSDK_LIBRARY) 16 | target_sources(granite-vulkan-post-mortem PRIVATE 17 | NsightAftermathGpuCrashTracker.cpp NsightAftermathGpuCrashTracker.h 18 | NsightAftermathHelpers.h) 19 | target_compile_definitions(granite-vulkan-post-mortem PRIVATE HAVE_AFTERMATH_SDK) 20 | target_link_libraries(granite-vulkan-post-mortem PRIVATE ${GFSDK_LIBRARY} granite-volk-headers) 21 | target_include_directories(granite-vulkan-post-mortem PRIVATE ${AFTERMATH_SDK_PATH}/include) 22 | message("Found Aftermath SDK.") 23 | else() 24 | message("Did not find Aftermath SDK in AFTERMATH_SDK_PATH=${AFTERMATH_SDK_PATH}.") 25 | endif() 26 | -------------------------------------------------------------------------------- /vulkan/post-mortem/post_mortem.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2024 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Vulkan 28 | { 29 | namespace PostMortem 30 | { 31 | void init_nv_aftermath(); 32 | void deinit(); 33 | void register_shader(const void *code, size_t size); 34 | } 35 | } 36 | --------------------------------------------------------------------------------