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 //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 //the texture transform then maps the texture coordinates to the location of the specific texture
//group 1 is the model //group 1 is the model
// This is equal to the CHUNK_SIZE constant from graphics.rs
const MAX_MODEL_INSTANCES=113;
@group(2) @group(2)
@binding(0) @binding(0)
var<uniform> model_instances: array<ModelInstance, MAX_MODEL_INSTANCES>; var<uniform> model_instances: array<ModelInstance, MAX_MODEL_INSTANCES>;

View File

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

View File

@@ -5,9 +5,6 @@ fn optional_features()->wgpu::Features{
fn required_features()->wgpu::Features{ fn required_features()->wgpu::Features{
wgpu::Features::TEXTURE_COMPRESSION_BC wgpu::Features::TEXTURE_COMPRESSION_BC
} }
pub const fn required_limits()->wgpu::Limits{
wgpu::Limits::downlevel_webgl2_defaults()
}
fn required_downlevel_capabilities()->wgpu::DownlevelCapabilities{ fn required_downlevel_capabilities()->wgpu::DownlevelCapabilities{
wgpu::DownlevelCapabilities{ wgpu::DownlevelCapabilities{
flags:wgpu::DownlevelFlags::empty(), flags:wgpu::DownlevelFlags::empty(),
@@ -64,12 +61,12 @@ pub mod step3{
} }
pub mod step4{ 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 optional_features=super::optional_features();
let required_features=super::required_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. // 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 let (device, queue)=adapter
.request_device( .request_device(

View File

@@ -1,5 +1,7 @@
use strafesnet_graphics::setup; 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>{ 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(); let mut attr=winit::window::WindowAttributes::default();
attr=attr.with_title(title); attr=attr.with_title(title);
@@ -22,7 +24,7 @@ pub async fn setup_and_start(title:&str){
let adapter_info=adapter.get_info(); let adapter_info=adapter.get_info();
println!("Using {} ({:?})",adapter_info.name,adapter_info.backend); 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 size=window.inner_size();
let surface=setup::step5::configure_surface(&adapter,&device,surface,(size.width,size.height)).unwrap(); 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, device,
queue, queue,
surface, surface,
LIMITS,
); );
for arg in std::env::args().skip(1){ for arg in std::env::args().skip(1){

View File

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