graphics: dynamic wgpu Limits

This commit is contained in:
2026-03-19 07:35:04 -07:00
parent 87853d3de8
commit 78d89ed3d9
5 changed files with 22 additions and 13 deletions

View File

@@ -49,8 +49,6 @@ struct ModelInstance{
//my fancy idea is to create a megatexture for each model that includes all the textures each intance will need
//the texture transform then maps the texture coordinates to the location of the specific texture
//group 1 is the model
// This is equal to the CHUNK_SIZE constant from graphics.rs
const MAX_MODEL_INSTANCES=113;
@group(2)
@binding(0)
var<uniform> model_instances: array<ModelInstance, MAX_MODEL_INSTANCES>;

View File

@@ -129,6 +129,7 @@ pub struct GraphicsState{
models:Vec<GraphicsModel>,
depth_view:wgpu::TextureView,
staging_belt:wgpu::util::StagingBelt,
model_instances_uniform_len:usize,
}
impl GraphicsState{
@@ -478,15 +479,14 @@ impl GraphicsState{
//.into_iter() the modeldata vec so entities can be /moved/ to models.entities
let mut model_count=0;
let mut instance_count=0;
const CHUNK_SIZE:usize=crate::setup::required_limits().max_uniform_buffer_binding_size as usize/MODEL_BUFFER_SIZE_BYTES;
self.models.reserve(models.len());
for model in models.into_iter(){
instance_count+=model.instances.len();
for instances_chunk in model.instances.rchunks(CHUNK_SIZE){
for instances_chunk in model.instances.rchunks(self.model_instances_uniform_len){
model_count+=1;
let mut model_uniforms=get_instances_buffer_data(instances_chunk);
//TEMP: fill with zeroes to pass validation
model_uniforms.resize(MODEL_BUFFER_SIZE*CHUNK_SIZE,0.0f32);
model_uniforms.resize(MODEL_BUFFER_SIZE*self.model_instances_uniform_len,0.0f32);
let model_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
label:Some(format!("Model{} Buf",model_count).as_str()),
contents:bytemuck::cast_slice(&model_uniforms),
@@ -544,6 +544,7 @@ impl GraphicsState{
queue:&wgpu::Queue,
size:glam::UVec2,
view_format:wgpu::TextureFormat,
limits:wgpu::Limits,
)->Self{
let camera_bind_group_layout=device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor{
label:None,
@@ -635,10 +636,18 @@ impl GraphicsState{
..Default::default()
});
let model_instances_uniform_len=limits.max_uniform_buffer_binding_size as usize/MODEL_BUFFER_SIZE_BYTES;
// write dynamic value into shader
let shader=format!("
// This is equal to the CHUNK_SIZE constant from graphics.rs
const MAX_MODEL_INSTANCES={model_instances_uniform_len};
")+include_str!("../shaders/shader.wgsl");
// Create the render pipeline
let shader=device.create_shader_module(wgpu::ShaderModuleDescriptor{
label:None,
source:wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("../shaders/shader.wgsl"))),
source:wgpu::ShaderSource::Wgsl(Cow::Owned(shader)),
});
//load textures
@@ -888,6 +897,7 @@ impl GraphicsState{
bind_group_layouts:GraphicsBindGroupLayouts{model:model_bind_group_layout},
samplers:GraphicsSamplers{repeat:repeat_sampler},
temp_squid_texture_view:squid_texture_view,
model_instances_uniform_len,
}
}
pub fn resize(

View File

@@ -5,9 +5,6 @@ fn optional_features()->wgpu::Features{
fn required_features()->wgpu::Features{
wgpu::Features::TEXTURE_COMPRESSION_BC
}
pub const fn required_limits()->wgpu::Limits{
wgpu::Limits::downlevel_webgl2_defaults()
}
fn required_downlevel_capabilities()->wgpu::DownlevelCapabilities{
wgpu::DownlevelCapabilities{
flags:wgpu::DownlevelFlags::empty(),
@@ -64,12 +61,12 @@ pub mod step3{
}
pub mod step4{
pub async fn request_device(adapter:&wgpu::Adapter)->Result<(wgpu::Device,wgpu::Queue),wgpu::RequestDeviceError>{
pub async fn request_device(adapter:&wgpu::Adapter,limits:wgpu::Limits)->Result<(wgpu::Device,wgpu::Queue),wgpu::RequestDeviceError>{
let optional_features=super::optional_features();
let required_features=super::required_features();
// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the surface.
let needed_limits=super::required_limits().using_resolution(adapter.limits());
let needed_limits=limits.using_resolution(adapter.limits());
let (device, queue)=adapter
.request_device(

View File

@@ -1,5 +1,7 @@
use strafesnet_graphics::setup;
const LIMITS:wgpu::Limits=wgpu::Limits::defaults();
fn create_window(title:&str,event_loop:&winit::event_loop::EventLoop<()>)->Result<winit::window::Window,winit::error::OsError>{
let mut attr=winit::window::WindowAttributes::default();
attr=attr.with_title(title);
@@ -22,7 +24,7 @@ pub async fn setup_and_start(title:&str){
let adapter_info=adapter.get_info();
println!("Using {} ({:?})",adapter_info.name,adapter_info.backend);
let (device,queue)=setup::step4::request_device(&adapter).await.unwrap();
let (device,queue)=setup::step4::request_device(&adapter,LIMITS).await.unwrap();
let size=window.inner_size();
let surface=setup::step5::configure_surface(&adapter,&device,surface,(size.width,size.height)).unwrap();
@@ -35,6 +37,7 @@ pub async fn setup_and_start(title:&str){
device,
queue,
surface,
LIMITS,
);
for arg in std::env::args().skip(1){

View File

@@ -242,6 +242,7 @@ pub fn worker<'a>(
device:wgpu::Device,
queue:wgpu::Queue,
surface:strafesnet_graphics::surface::Surface<'a>,
limits:wgpu::Limits,
)->crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTime>>{
// WindowContextSetup::new
#[cfg(feature="user-install")]
@@ -252,7 +253,7 @@ pub fn worker<'a>(
let user_settings=directories.settings();
let screen_size=surface.size();
let mut graphics=strafesnet_graphics::graphics::GraphicsState::new(&device,&queue,screen_size,surface.view_format());
let mut graphics=strafesnet_graphics::graphics::GraphicsState::new(&device,&queue,screen_size,surface.view_format(),limits);
//WindowContextSetup::into_context
let fov=user_settings.calculate_fov(1.0,&screen_size).as_vec2();