forked from 1b-agent/opencadstudio-upstream
fix: no GPU allocation path maps, however small the buffer
The previous commit converted the allocations that scale with the
drawing and deliberately left the small fixed-size ones -- uniforms, the
viewcube's static geometry, per-image and per-wipeout quads -- reasoning
that an allocation failure was not a realistic outcome for a few dozen
bytes.
That reasoning was wrong, and the log says so precisely. On the
reproducer the vertex buffers degraded exactly as intended:
[gpu] uncaptured ... Out of Memory
[gpu] uncaptured ... In Queue::write_buffer
Buffer with 'block_wire.vertices' label is invalid
... errors #4 #8 #16 #32 #64 #128, session kept alive
and then the process died here:
thread 'main' panicked at wgpu_core.rs:2253:
Error in Buffer::get_mapped_range: Validation Error
Caused by: Buffer with 'block_wire.const' label is invalid
'block_wire.const' is a single uniform struct. Once the device is out of
memory every allocation fails, including a 32-byte one, and
create_buffer_init maps it and panics. Size was never the relevant
property -- whether the path maps is.
So every remaining allocation goes through gpu_upload too: block-wire
const, the viewcube's seven buffers, the blit and clip-boundary buffers,
image instances/params/vertices, mesh material params and surface and the
empty index stub, the texture-hatch uniform, and all five wipeout
buffers. `grep -r create_buffer_init src` now finds only a comment, and
no mapped_at_creation:true remains outside gpu_upload's own docs.
`queue` is threaded through the last holdouts: upload_wipeouts,
upload_clip_boundary, MeshBatchStubs::new and
create_material_bind_group_from_resources.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
1 parent
0d11421dea
commit
6747d7125e
8 files changed
+181
-129
No files matched your search
@@ -3,7 +3,6 @@
|
||||
|
||||
use crate::scene::model::hatch_model::{HatchModel, HatchPattern};
|
||||
use iced::wgpu;
|
||||
use iced::wgpu::util::DeviceExt;
|
||||
|
||||
/// Width (in texels) of the RGBA32F data texture. Height grows to fit; a hatch
|
||||
/// with N total texels uses ceil(N / WIDTH) rows.
|
||||
@@ -377,11 +376,13 @@ impl TextureHatch {
|
||||
dash_off,
|
||||
tex_width: width,
|
||||
};
|
||||
let _uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("hatch.texture.uniform"),
|
||||
contents: bytemuck::bytes_of(&uniform_data),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let _uniform_buf = crate::scene::pipeline::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"hatch.texture.uniform",
|
||||
std::slice::from_ref(&uniform_data),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("hatch.texture.bind_group1"),
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
use crate::scene::model::image_model::ImageModel;
|
||||
use iced::wgpu;
|
||||
use iced::wgpu::util::DeviceExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
// ── Vertex ────────────────────────────────────────────────────────────────
|
||||
@@ -179,24 +178,24 @@ impl ImageGpu {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let instance_buffer = Arc::new(device.create_buffer_init(
|
||||
&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("image.instances"),
|
||||
contents: bytemuck::cast_slice(&instances),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
},
|
||||
let instance_buffer = Arc::new(super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"image.instances",
|
||||
&instances,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
));
|
||||
let params = ImageParams {
|
||||
opacity: model.opacity.clamp(0.0, 1.0),
|
||||
draw_depth: 0.0,
|
||||
_pad: [0.0; 2],
|
||||
};
|
||||
let params_buf = Arc::new(device.create_buffer_init(
|
||||
&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("image.params"),
|
||||
contents: bytemuck::bytes_of(¶ms),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
},
|
||||
let params_buf = Arc::new(super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"image.params",
|
||||
std::slice::from_ref(¶ms),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
));
|
||||
|
||||
let mut output = Vec::with_capacity(x_tiles.len() * y_tiles.len());
|
||||
@@ -264,12 +263,13 @@ impl ImageGpu {
|
||||
},
|
||||
],
|
||||
});
|
||||
let vertex_buffer =
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("image.vbuf"),
|
||||
contents: bytemuck::cast_slice(&verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let vertex_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"image.vbuf",
|
||||
&verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
output.push(Self {
|
||||
vertex_buffer,
|
||||
instance_buffer: Arc::clone(&instance_buffer),
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use crate::scene::model::mesh_model::{MeshLodSet, MeshModel};
|
||||
use iced::wgpu;
|
||||
use iced::wgpu::util::DeviceExt;
|
||||
|
||||
// ── Vertex layout ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -377,13 +376,15 @@ struct MeshBatchStubs {
|
||||
}
|
||||
|
||||
impl MeshBatchStubs {
|
||||
fn new(device: &wgpu::Device) -> Self {
|
||||
fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Self {
|
||||
Self {
|
||||
index: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("mesh.batch.empty_ibuf"),
|
||||
contents: bytemuck::cast_slice(&[0u32]),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
}),
|
||||
index: super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"mesh.batch.empty_ibuf",
|
||||
&[0u32],
|
||||
wgpu::BufferUsages::INDEX,
|
||||
),
|
||||
vertex: device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("mesh.batch.empty_vbuf"),
|
||||
size: std::mem::size_of::<MeshVertex>() as u64,
|
||||
@@ -784,11 +785,13 @@ pub fn create_material_resources(
|
||||
[material.color_bleed_scale, 0.0, 0.0, 0.0]
|
||||
}),
|
||||
};
|
||||
let params_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("mesh.material.params"),
|
||||
contents: bytemuck::bytes_of(¶ms),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let params_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"mesh.material.params",
|
||||
std::slice::from_ref(¶ms),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
MeshMaterialResources {
|
||||
diffuse_view,
|
||||
specular_view,
|
||||
@@ -810,6 +813,7 @@ pub fn create_material_resources(
|
||||
|
||||
pub fn create_material_bind_group_from_resources(
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
layout: &wgpu::BindGroupLayout,
|
||||
resources: &MeshMaterialResources,
|
||||
material: Option<&crate::scene::model::material_model::MeshMaterial>,
|
||||
@@ -825,11 +829,13 @@ pub fn create_material_bind_group_from_resources(
|
||||
advanced,
|
||||
flags,
|
||||
};
|
||||
let surface_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("mesh.material.surface"),
|
||||
contents: bytemuck::bytes_of(&surface),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let surface_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"mesh.material.surface",
|
||||
std::slice::from_ref(&surface),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("mesh.material.bind_group"),
|
||||
layout,
|
||||
@@ -912,6 +918,7 @@ pub fn create_material_bind_group(
|
||||
let color = material.map_or([0.8, 0.8, 0.8, 1.0], |material| material.diffuse);
|
||||
create_material_bind_group_from_resources(
|
||||
device,
|
||||
queue,
|
||||
layout,
|
||||
&resources,
|
||||
material,
|
||||
@@ -936,6 +943,7 @@ pub fn upload_chunk_material_bind_groups(
|
||||
let resources = create_material_resources(device, queue, Some(material));
|
||||
chunk.material_bind_group = Some(create_material_bind_group_from_resources(
|
||||
device,
|
||||
queue,
|
||||
layout,
|
||||
&resources,
|
||||
chunk.material.as_ref(),
|
||||
@@ -950,6 +958,7 @@ pub fn upload_chunk_material_bind_groups(
|
||||
};
|
||||
chunk.material_bind_group = Some(create_material_bind_group_from_resources(
|
||||
device,
|
||||
queue,
|
||||
layout,
|
||||
resources,
|
||||
chunk.material.as_ref(),
|
||||
@@ -1586,7 +1595,7 @@ pub fn build_mesh_batch_filtered(
|
||||
// vertices). Bound chunks by the largest buffer produced for wire meshes.
|
||||
let max_tris =
|
||||
(budget / (6 * std::mem::size_of::<MeshEdgeVertex>())).max(1);
|
||||
let stubs = MeshBatchStubs::new(device);
|
||||
let stubs = MeshBatchStubs::new(device, queue);
|
||||
|
||||
let mut chunks = Vec::new();
|
||||
let mut verts: Vec<MeshVertex> = Vec::new();
|
||||
|
||||
+22
-15
@@ -16,7 +16,6 @@ pub mod wire_arena;
|
||||
pub mod wire_gpu;
|
||||
|
||||
use iced::wgpu;
|
||||
use iced::wgpu::util::DeviceExt;
|
||||
use iced::{Rectangle, Size};
|
||||
|
||||
pub use face3d_gpu::Face3DGpu;
|
||||
@@ -2122,11 +2121,13 @@ impl Pipeline {
|
||||
// UV crop uniform: [uv_offset_x, uv_offset_y, uv_scale_x, uv_scale_y]
|
||||
// padded to 16 bytes (std140 vec2 alignment). Defaulted to the
|
||||
// identity crop (offset 0, scale 1) for the common on-canvas case.
|
||||
let blit_uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("blit.uniform_buffer"),
|
||||
contents: bytemuck::cast_slice(&[0.0f32, 0.0, 1.0, 1.0]),
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
let blit_uniform_buffer = gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"blit.uniform_buffer",
|
||||
&[0.0f32, 0.0, 1.0, 1.0],
|
||||
wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
);
|
||||
|
||||
let blit_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("blit.pipeline_layout"),
|
||||
@@ -2969,8 +2970,7 @@ impl Pipeline {
|
||||
/// so the mask pipeline stamps it straight into the stencil with `Invert`
|
||||
/// (even-odd fill → interior marked, any convexity). Empty input clears the
|
||||
/// boundary so the viewport renders unclipped (its render rectangle clips).
|
||||
pub fn upload_clip_boundary(&mut self, device: &wgpu::Device, boundary_ndc: &[[f32; 2]]) {
|
||||
use wgpu::util::DeviceExt;
|
||||
pub fn upload_clip_boundary(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, boundary_ndc: &[[f32; 2]]) {
|
||||
if boundary_ndc.len() < 3 {
|
||||
self.clip_boundary = None;
|
||||
return;
|
||||
@@ -2986,11 +2986,13 @@ impl Pipeline {
|
||||
self.clip_boundary = None;
|
||||
return;
|
||||
}
|
||||
let vbuf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("clip_boundary.vbuf"),
|
||||
contents: bytemuck::cast_slice(&verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let vbuf = gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"clip_boundary.vbuf",
|
||||
&verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
self.clip_boundary = Some((vbuf, (verts.len() / 2) as u32));
|
||||
}
|
||||
|
||||
@@ -3378,13 +3380,18 @@ impl Pipeline {
|
||||
self.hatch_gpu.upload_preview(device, queue, hatches);
|
||||
}
|
||||
|
||||
pub fn upload_wipeouts(&mut self, device: &wgpu::Device, wipeouts: &[HatchModel]) {
|
||||
pub fn upload_wipeouts(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
wipeouts: &[HatchModel],
|
||||
) {
|
||||
let renderable: Vec<HatchModel> = wipeouts
|
||||
.iter()
|
||||
.filter(|h| h.boundary.len() >= 3)
|
||||
.cloned()
|
||||
.collect();
|
||||
self.gpu_wipeouts = WipeoutGpu::from_models(device, &renderable, &self.wipeout_bgl1);
|
||||
self.gpu_wipeouts = WipeoutGpu::from_models(device, queue, &renderable, &self.wipeout_bgl1);
|
||||
}
|
||||
|
||||
pub fn upload_images(
|
||||
|
||||
@@ -1078,43 +1078,54 @@ pub struct ViewCubePipeline {
|
||||
|
||||
impl ViewCubePipeline {
|
||||
pub fn new(device: &wgpu::Device, queue: &wgpu::Queue, format: wgpu::TextureFormat) -> Self {
|
||||
use wgpu::util::DeviceExt;
|
||||
let (verts, idxs) = build_geometry();
|
||||
let line_verts = surface_edge_lines(&verts, &idxs);
|
||||
let (ring_verts, ring_idxs) = build_ring_geometry();
|
||||
let ring_line_verts = surface_edge_lines(&ring_verts, &ring_idxs);
|
||||
let cube_px = VIEWCUBE_PX;
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.vb"),
|
||||
contents: bytemuck::cast_slice(&verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.ib"),
|
||||
contents: bytemuck::cast_slice(&idxs),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
let line_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.line_vb"),
|
||||
contents: bytemuck::cast_slice(&line_verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let ring_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.ring_vb"),
|
||||
contents: bytemuck::cast_slice(&ring_verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let ring_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.ring_ib"),
|
||||
contents: bytemuck::cast_slice(&ring_idxs),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
let vertex_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.vb",
|
||||
&verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
let index_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.ib",
|
||||
&idxs,
|
||||
wgpu::BufferUsages::INDEX,
|
||||
);
|
||||
let line_vertex_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.line_vb",
|
||||
&line_verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
let ring_vertex_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.ring_vb",
|
||||
&ring_verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
let ring_index_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.ring_ib",
|
||||
&ring_idxs,
|
||||
wgpu::BufferUsages::INDEX,
|
||||
);
|
||||
let ring_line_vertex_buffer =
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.ring_line_vb"),
|
||||
contents: bytemuck::cast_slice(&ring_line_verts),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.ring_line_vb",
|
||||
&ring_line_verts,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("vc.ub"),
|
||||
size: std::mem::size_of::<CubeUniforms>() as u64,
|
||||
@@ -1291,11 +1302,13 @@ impl ViewCubePipeline {
|
||||
],
|
||||
});
|
||||
let composite_uniform_buffer =
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("vc.composite_uniform"),
|
||||
contents: bytemuck::cast_slice(&[1.0f32, 1.0, 0.0, 0.0]),
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"vc.composite_uniform",
|
||||
&[1.0f32, 1.0, 0.0, 0.0],
|
||||
wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
);
|
||||
let composite_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||
label: Some("vc.composite_sampler"),
|
||||
mag_filter: wgpu::FilterMode::Nearest,
|
||||
|
||||
@@ -17,7 +17,6 @@ use crate::scene::model::hatch_model::{
|
||||
FillPlane, HatchModel, HatchPattern, PatFamily, MAX_HATCH_BOUNDARY_VERTS,
|
||||
};
|
||||
use iced::wgpu;
|
||||
use iced::wgpu::util::DeviceExt;
|
||||
|
||||
// ── Constants ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -157,6 +156,7 @@ pub struct WipeoutGpu {
|
||||
impl WipeoutGpu {
|
||||
pub fn from_models(
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
models: &[HatchModel],
|
||||
bgl1: &wgpu::BindGroupLayout,
|
||||
) -> Vec<Self> {
|
||||
@@ -176,11 +176,16 @@ impl WipeoutGpu {
|
||||
}
|
||||
groups
|
||||
.into_iter()
|
||||
.map(|group| Self::new(device, &group, bgl1))
|
||||
.map(|group| Self::new(device, queue, &group, bgl1))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn new(device: &wgpu::Device, models: &[&HatchModel], bgl1: &wgpu::BindGroupLayout) -> Self {
|
||||
fn new(
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
models: &[&HatchModel],
|
||||
bgl1: &wgpu::BindGroupLayout,
|
||||
) -> Self {
|
||||
let model = models[0];
|
||||
// ── Decode pattern mode ──────────────────────────────────────────
|
||||
let (mode, color2, grad_cos, grad_sin) = match &model.pattern {
|
||||
@@ -264,11 +269,13 @@ impl WipeoutGpu {
|
||||
_pad: 0.0,
|
||||
},
|
||||
];
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("hatch.vbuf"),
|
||||
contents: bytemuck::cast_slice(&quad),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let vertex_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"hatch.vbuf",
|
||||
&quad,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
|
||||
// ── Gradient: projection range (in snapped-local space) ──────────
|
||||
let (grad_min, grad_range) = if mode == 2 {
|
||||
@@ -354,21 +361,27 @@ impl WipeoutGpu {
|
||||
let family_batch = build_family_batch(&model.pattern);
|
||||
|
||||
// ── GPU buffers ───────────────────────────────────────────────────
|
||||
let _uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("hatch.uniforms"),
|
||||
contents: bytemuck::bytes_of(&uniform_data),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let _boundary_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("hatch.boundary"),
|
||||
contents: bytemuck::bytes_of(&boundary_data),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let _family_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("hatch.families"),
|
||||
contents: bytemuck::bytes_of(&family_batch),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
let _uniform_buf = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"hatch.uniforms",
|
||||
std::slice::from_ref(&uniform_data),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
let _boundary_buf = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"hatch.boundary",
|
||||
std::slice::from_ref(&boundary_data),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
let _family_buf = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"hatch.families",
|
||||
std::slice::from_ref(&family_batch),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("hatch.bind_group1"),
|
||||
@@ -419,11 +432,13 @@ impl WipeoutGpu {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("wipeout.instances"),
|
||||
contents: bytemuck::cast_slice(&placements),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let instance_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"wipeout.instances",
|
||||
&placements,
|
||||
wgpu::BufferUsages::VERTEX,
|
||||
);
|
||||
let mut world_bounds = [
|
||||
f32::INFINITY,
|
||||
f32::INFINITY,
|
||||
|
||||
@@ -676,7 +676,6 @@ impl BlockWireGpu {
|
||||
color_override: Option<[f32; 4]>,
|
||||
const_bgl: &wgpu::BindGroupLayout,
|
||||
) -> Vec<Self> {
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
let mut slots: rustc_hash::FxHashMap<(u64, bool), usize> =
|
||||
rustc_hash::FxHashMap::default();
|
||||
@@ -751,11 +750,18 @@ impl BlockWireGpu {
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let const_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("block_wire.const"),
|
||||
contents: bytemuck::bytes_of(&constant),
|
||||
usage: wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
// Tiny, but size is irrelevant here: once the device is out of
|
||||
// memory every allocation fails, including a one-struct uniform,
|
||||
// and create_buffer_init would map the invalid buffer and panic.
|
||||
// This is the allocation that killed the process after the vertex
|
||||
// buffers had already degraded gracefully.
|
||||
let const_buffer = super::gpu_upload::upload_buffer(
|
||||
device,
|
||||
queue,
|
||||
"block_wire.const",
|
||||
std::slice::from_ref(&constant),
|
||||
wgpu::BufferUsages::UNIFORM,
|
||||
);
|
||||
let const_bind_group = std::sync::Arc::new(device.create_bind_group(
|
||||
&wgpu::BindGroupDescriptor {
|
||||
label: Some("block_wire.const.bg"),
|
||||
|
||||
@@ -546,6 +546,7 @@ impl shader::Primitive for Primitive {
|
||||
if wipeout_changed || fill_changed {
|
||||
inner.upload_wipeouts(
|
||||
device,
|
||||
queue,
|
||||
if fill_mode {
|
||||
&vp.wipeout_hatches[..]
|
||||
} else {
|
||||
@@ -1117,7 +1118,7 @@ impl shader::Primitive for Primitive {
|
||||
);
|
||||
inner.silhouette_key = silhouette_key;
|
||||
}
|
||||
inner.upload_clip_boundary(device, &vp.clip_boundary_ndc);
|
||||
inner.upload_clip_boundary(device, queue, &vp.clip_boundary_ndc);
|
||||
let hatch_lod_key = (
|
||||
Arc::as_ptr(&vp.hatches) as usize,
|
||||
vp.camera_generation,
|
||||
|
||||
Reference in new issue
Block a user