Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use an integer texture instead of a storage buffer #238

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions bin/boilerplate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ impl Harness {
Terrain::RayTraced { .. } | Terrain::Sliced { .. } | Terrain::Painted { .. } => {
wgpu::Limits {
max_texture_dimension_2d: adapter_limits.max_texture_dimension_2d,
max_storage_buffers_per_shader_stage: 1,
max_storage_buffer_binding_size: terrain_buffer_size,
..wgpu::Limits::downlevel_webgl2_defaults()
}
}
Expand Down
2 changes: 0 additions & 2 deletions lib/ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ pub extern "C" fn rv_init(desc: InitDescriptor) -> Option<ptr::NonNull<Context>>

let limits = wgpu::Limits {
max_texture_dimension_2d: adapter_limits.max_texture_dimension_2d,
max_storage_buffers_per_shader_stage: 1,
max_storage_buffer_binding_size: 1 << 28,
..wgpu::Limits::downlevel_webgl2_defaults()
};

Expand Down
11 changes: 3 additions & 8 deletions res/shader/surface.inc.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ struct SurfaceConstants {
terrain_bits: u32, // low 4 bits = shift, high 4 bits = mask
delta_mode: u32, // low 8 bits = power, higher 16 bits = mask
};
struct TerrainData {
inner: array<u32>,
};

@group(1) @binding(0) var<uniform> u_Surface: SurfaceConstants;
@group(1) @binding(2) var<storage, read> b_Terrain: TerrainData;
@group(1) @binding(2) var t_Terrain: texture_2d<u32>;

const c_DoubleLevelMask: u32 = 64u;
const c_ShadowMask: u32 = 128u;
Expand Down Expand Up @@ -50,9 +47,7 @@ fn get_map_coordinates(pos: vec2<f32>) -> vec2<i32> {
fn get_surface_impl(tci: vec2<i32>) -> Surface {
var suf: Surface;

let tc_index = tci.y * i32(u_Surface.texture_scale.x) + tci.x;
let data_raw = b_Terrain.inner[tc_index / 2];
let data = (vec4<u32>(data_raw) >> vec4<u32>(0u, 8u, 16u, 24u)) & vec4<u32>(0xFFu);
let data = textureLoad(t_Terrain, vec2<i32>(tci.x/2, tci.y), 0);
suf.is_shadowed = (data.y & c_ShadowMask) != 0u;
let scale = u_Surface.texture_scale.z / 256.0;

Expand All @@ -74,7 +69,7 @@ fn get_surface_impl(tci: vec2<i32>) -> Surface {
}
suf.mid_alt = f32(mid) * scale;
} else {
let subdata = select(data.xy, data.zw, (tc_index & 1) != 0);
let subdata = select(data.xy, data.zw, (tci.x & 1) != 0);
let altitude = f32(subdata.x) * scale;
let ty = get_terrain_type(subdata.y);
suf.low_type = ty;
Expand Down
72 changes: 49 additions & 23 deletions src/render/terrain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ pub struct Context {
raytrace_geo: Geometry,
kind: Kind,
shadow_kind: ShadowKind,
terrain_buf: wgpu::Buffer,
terrain_texture: wgpu::Texture,
palette_texture: wgpu::Texture,
pub flood: Flood,
pub dirty_rects: Vec<super::DirtyRect>,
Expand Down Expand Up @@ -698,11 +698,18 @@ impl Context {
})
.collect::<Vec<_>>();

let terrain_buf = gfx.device.create_buffer(&wgpu::BufferDescriptor {
let terrain_texture = gfx.device.create_texture(&wgpu::TextureDescriptor {
label: Some("Terrain data"),
size: (extent.width * extent.height) as wgpu::BufferAddress * 2,
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::STORAGE,
mapped_at_creation: false,
size: wgpu::Extent3d {
width: extent.width / 2,
..extent
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Uint,
view_formats: &[],
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
});

let flood_texture = gfx.device.create_texture(&wgpu::TextureDescriptor {
Expand Down Expand Up @@ -792,15 +799,11 @@ impl Context {
// terrain data
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: if supports_vertex_storage {
wgpu::ShaderStages::all()
} else {
wgpu::ShaderStages::FRAGMENT | wgpu::ShaderStages::COMPUTE
},
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
min_binding_size: None,
visibility: wgpu::ShaderStages::all(),
ty: wgpu::BindingType::Texture {
view_dimension: wgpu::TextureViewDimension::D2,
sample_type: wgpu::TextureSampleType::Uint,
multisampled: false,
},
count: None,
},
Expand Down Expand Up @@ -881,7 +884,9 @@ impl Context {
},
wgpu::BindGroupEntry {
binding: 2,
resource: terrain_buf.as_entire_binding(),
resource: wgpu::BindingResource::TextureView(
&terrain_texture.create_view(&wgpu::TextureViewDescriptor::default()),
),
},
wgpu::BindGroupEntry {
binding: 4,
Expand Down Expand Up @@ -1365,7 +1370,7 @@ impl Context {
raytrace_geo,
kind,
shadow_kind,
terrain_buf,
terrain_texture,
palette_texture: palette.texture,
flood: Flood {
texture: flood_texture,
Expand Down Expand Up @@ -1569,6 +1574,8 @@ impl Context {
if !dr.need_upload {
continue;
}
//Note: we are uploading the whole rows currently. We could instead upload
// only the relevant sub-rectangle, but managing `bytes_per_row` becomes annoying.

let total_size =
dr.rect.h as wgpu::BufferAddress * level.size.0 as wgpu::BufferAddress * 2;
Expand All @@ -1588,15 +1595,34 @@ impl Context {
}
}
}
staging_buf.unmap();
encoder.copy_buffer_to_buffer(
&staging_buf,
0,
&self.terrain_buf,
dr.rect.y as wgpu::BufferAddress * level.size.0 as wgpu::BufferAddress * 2,
total_size,

encoder.copy_buffer_to_texture(
wgpu::ImageCopyBuffer {
buffer: &staging_buf,
layout: wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: Some(level.size.0 as u32 * 2),
rows_per_image: None,
},
},
wgpu::ImageCopyTexture {
texture: &self.terrain_texture,
mip_level: 0,
origin: wgpu::Origin3d {
x: 0,
y: dr.rect.y as u32,
z: 0,
},
aspect: wgpu::TextureAspect::All,
},
wgpu::Extent3d {
width: level.size.0 as u32 / 2,
height: dr.rect.h as u32,
depth_or_array_layers: 1,
},
);

staging_buf.unmap();
dr.need_upload = false;
}

Expand Down
Loading