Skip to content

Commit

Permalink
Support texture compression
Browse files Browse the repository at this point in the history
This uses the block_compression crate that I wrote.

It is using WGPU compute shader to compress the textures using BC7 on the fly when loading the map.

Textures using BC7 are 1/4 of the uncompressed texture size. Quality is defined by "speed" like video encoders do: the slower, the better the quality.
  • Loading branch information
hasenbanck committed Jan 22, 2025
1 parent 3392323 commit 8af55cb
Show file tree
Hide file tree
Showing 19 changed files with 576 additions and 207 deletions.
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Steam Hardware survey: https://store.steampowered.com/hwsurvey/Steam-Hardware-Software-Survey-Welcome-to-Steam
[target.'cfg(target_arch="x86_64")']
rustflags = ["-C", "target-feature=+aes,+avx,+avx2,+cmpxchg16b,+fma,+sse3,+ssse3,+sse4.1,+sse4.2"]
64 changes: 36 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = ["korangar", "ragnarok_*", "korangar_*"]
[workspace.dependencies]
arrayvec = "0.7"
bitflags = "2.6"
block_compression = { version = "0.2", default-features = false }
bumpalo = "3.16"
bytemuck = "1.21"
cgmath = "0.18"
Expand Down Expand Up @@ -52,6 +53,9 @@ walkdir = "2.5"
wgpu = "24"
winit = "0.30"

[profile.release]
lto = "thin"

[profile.dev.build-override]
opt-level = 3

Expand Down
1 change: 1 addition & 0 deletions korangar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"

[dependencies]
arrayvec = { workspace = true }
block_compression = { workspace = true, features = ["bc7", "wgpu"] }
bumpalo = { workspace = true, features = ["allocator_api"] }
bytemuck = { workspace = true, features = ["derive", "extern_crate_std", "min_const_generics"] }
cgmath = { workspace = true, features = ["mint", "serde"] }
Expand Down
13 changes: 13 additions & 0 deletions korangar/src/graphics/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct Capabilities {
bindless: bool,
multidraw_indirect: bool,
clamp_to_border: bool,
texture_compression: bool,
#[cfg(feature = "debug")]
polygon_mode_line: bool,
required_features: Features,
Expand All @@ -37,6 +38,7 @@ impl Capabilities {
bindless: false,
multidraw_indirect: false,
clamp_to_border: false,
texture_compression: false,
#[cfg(feature = "debug")]
polygon_mode_line: false,
required_features: Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
Expand All @@ -58,6 +60,7 @@ impl Capabilities {
adapter_features,
Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
);
Self::check_feature(adapter_features, Features::TEXTURE_COMPRESSION_BC);
Self::check_feature(adapter_features, Features::TEXTURE_BINDING_ARRAY);
Self::check_feature(adapter_features, Features::POLYGON_MODE_LINE);
}
Expand Down Expand Up @@ -85,6 +88,11 @@ impl Capabilities {
capabilities.required_features |= Features::ADDRESS_MODE_CLAMP_TO_BORDER | Features::ADDRESS_MODE_CLAMP_TO_ZERO;
}

if adapter_features.contains(Features::TEXTURE_COMPRESSION_BC) {
capabilities.texture_compression = true;
capabilities.required_features |= Features::TEXTURE_COMPRESSION_BC;
}

#[cfg(feature = "debug")]
if adapter_features.contains(Features::POLYGON_MODE_LINE) {
capabilities.polygon_mode_line = true;
Expand Down Expand Up @@ -135,6 +143,11 @@ impl Capabilities {
self.clamp_to_border
}

/// Returns `true` if the backend supports BC texture compression.
pub fn supports_texture_compression(&self) -> bool {
self.texture_compression
}

/// Returns `true` if the backend allows drawing triangles as lines
/// (wireframe) instead of filled.
#[cfg(feature = "debug")]
Expand Down
11 changes: 10 additions & 1 deletion korangar/src/graphics/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use winit::window::Window;

use super::{
AntiAliasingResource, Capabilities, EntityInstruction, FramePacer, FrameStage, GlobalContext, LimitFramerate, ModelInstruction, Msaa,
Prepare, PresentModeInfo, ScreenSpaceAntiAliasing, ShadowDetail, Ssaa, Surface, TextureSamplerType, RENDER_TO_TEXTURE_FORMAT,
Prepare, PresentModeInfo, ScreenSpaceAntiAliasing, ShadowDetail, Ssaa, Surface, TextureCompression, TextureSamplerType,
RENDER_TO_TEXTURE_FORMAT,
};
use crate::graphics::instruction::RenderInstruction;
use crate::graphics::passes::*;
Expand Down Expand Up @@ -428,6 +429,14 @@ impl GraphicsEngine {
ssaa
}

pub fn check_texture_compression_requirements(&self, texture_compression: TextureCompression) -> TextureCompression {
if self.capabilities.supports_texture_compression() {
texture_compression
} else {
TextureCompression::Off
}
}

pub fn on_suspended(&mut self) {
// Android devices are expected to drop their surface view.
if cfg!(target_os = "android") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn vs_main(
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
var diffuse_color = textureSampleLevel(texture, texture_sampler, input.texture_coordinates, 0.0);

if (diffuse_color.a < 1.0) {
if (diffuse_color.a == 0.0) {
discard;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn fs_main(input: VertexOutput) -> @builtin(frag_depth) f32 {

let light_distance = length(input.world_position.xyz - pass_uniforms.light_position.xyz);

if (diffuse_color.a != 1.0) {
if (diffuse_color.a == 0.0) {
discard;
}

Expand Down
42 changes: 42 additions & 0 deletions korangar/src/graphics/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ use std::fmt::{Display, Formatter};
#[cfg(feature = "debug")]
use std::num::NonZeroU32;

use block_compression::{BC7Settings, CompressionVariant};
#[cfg(feature = "debug")]
use derive_new::new;
use serde::{Deserialize, Serialize};
use wgpu::TextureFormat;

use crate::interface::layout::ScreenSize;

Expand Down Expand Up @@ -160,6 +162,46 @@ impl Display for ScreenSpaceAntiAliasing {
}
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum TextureCompression {
Off,
UltraFast,
VeryFast,
Fast,
Normal,
}

impl TextureCompression {
pub fn is_uncompressed(&self) -> bool {
*self == TextureCompression::Off
}
}

impl From<TextureCompression> for TextureFormat {
fn from(value: TextureCompression) -> Self {
match value {
TextureCompression::Off => TextureFormat::Rgba8UnormSrgb,
TextureCompression::UltraFast | TextureCompression::VeryFast | TextureCompression::Fast | TextureCompression::Normal => {
TextureFormat::Bc7RgbaUnormSrgb
}
}
}
}

impl TryFrom<TextureCompression> for CompressionVariant {
type Error = ();

fn try_from(value: TextureCompression) -> Result<Self, Self::Error> {
match value {
TextureCompression::Off => Err(()),
TextureCompression::UltraFast => Ok(CompressionVariant::BC7(BC7Settings::alpha_ultrafast())),
TextureCompression::VeryFast => Ok(CompressionVariant::BC7(BC7Settings::alpha_very_fast())),
TextureCompression::Fast => Ok(CompressionVariant::BC7(BC7Settings::alpha_fast())),
TextureCompression::Normal => Ok(CompressionVariant::BC7(BC7Settings::alpha_basic())),
}
}
}

#[cfg(feature = "debug")]
#[derive(Copy, Clone, Default, new)]
pub struct RenderSettings {
Expand Down
Loading

0 comments on commit 8af55cb

Please sign in to comment.