forked from StrafesNET/roblox-bot-player
refactor setup
This commit is contained in:
@@ -7,12 +7,15 @@ mod setup;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Setup{
|
||||
setup:setup::SetupContext<'static>,
|
||||
device:wgpu::Device,
|
||||
queue:wgpu::Queue,
|
||||
surface:wgpu::Surface<'static>,
|
||||
config:wgpu::SurfaceConfiguration,
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub async fn setup(canvas:web_sys::HtmlCanvasElement)->Setup{
|
||||
let setup=setup::setup_and_start(canvas).await;
|
||||
Setup{setup}
|
||||
let (device,queue,surface,config)=setup::setup_and_start(canvas).await;
|
||||
Setup{device,queue,surface,config}
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub struct Graphics{
|
||||
@@ -27,8 +30,8 @@ impl Graphics{
|
||||
data:&[u8],
|
||||
)->Result<Self,JsValue>{
|
||||
Ok(Self{
|
||||
graphics:graphics::Graphics::new(data,setup.setup.device,setup.setup.queue,setup.setup.config).map_err(|e|JsValue::from_str(&e.to_string()))?,
|
||||
surface:setup.setup.surface,
|
||||
graphics:graphics::Graphics::new(data,setup.device,setup.queue,setup.config).map_err(|e|JsValue::from_str(&e.to_string()))?,
|
||||
surface:setup.surface,
|
||||
})
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
|
||||
@@ -13,97 +13,69 @@ fn required_downlevel_capabilities()->wgpu::DownlevelCapabilities{
|
||||
}
|
||||
}
|
||||
|
||||
struct SetupContextPartial1{
|
||||
backends:wgpu::Backends,
|
||||
instance:wgpu::Instance,
|
||||
}
|
||||
fn create_instance()->SetupContextPartial1{
|
||||
let backends=wgpu::Backends::from_env().unwrap_or_default();
|
||||
SetupContextPartial1{
|
||||
backends,
|
||||
instance:Default::default(),
|
||||
mod step1{
|
||||
pub fn create_instance()->wgpu::Instance{
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
impl SetupContextPartial1{
|
||||
fn create_surface<'a>(self,canvas:web_sys::HtmlCanvasElement)->Result<SetupContextPartial2<'a>,wgpu::CreateSurfaceError>{
|
||||
Ok(SetupContextPartial2{
|
||||
backends:self.backends,
|
||||
surface:self.instance.create_surface(wgpu::SurfaceTarget::Canvas(canvas))?,
|
||||
instance:self.instance,
|
||||
})
|
||||
|
||||
mod step2{
|
||||
pub fn create_surface<'window>(instance:&wgpu::Instance,target:impl Into<wgpu::SurfaceTarget<'window>>)->Result<wgpu::Surface<'window>,wgpu::CreateSurfaceError>{
|
||||
instance.create_surface(target)
|
||||
}
|
||||
}
|
||||
struct SetupContextPartial2<'a>{
|
||||
backends:wgpu::Backends,
|
||||
instance:wgpu::Instance,
|
||||
surface:wgpu::Surface<'a>,
|
||||
}
|
||||
impl<'a> SetupContextPartial2<'a>{
|
||||
async fn pick_adapter(self)->SetupContextPartial3<'a>{
|
||||
|
||||
mod step3{
|
||||
pub async fn pick_adapter(instance:&wgpu::Instance,surface:&wgpu::Surface<'_>)->Option<wgpu::Adapter>{
|
||||
let backends=wgpu::Backends::from_env().unwrap_or_default();
|
||||
//TODO: prefer adapter that implements optional features
|
||||
//let optional_features=optional_features();
|
||||
let required_features=required_features();
|
||||
let required_features=super::required_features();
|
||||
let required_downlevel_capabilities=super::required_downlevel_capabilities();
|
||||
|
||||
//no helper function smh gotta write it myself
|
||||
let adapters=self.instance.enumerate_adapters(self.backends).await;
|
||||
let adapters=instance.enumerate_adapters(backends).await;
|
||||
|
||||
let chosen_adapter=adapters.into_iter()
|
||||
let adapter=adapters.into_iter()
|
||||
// reverse because we want to select adapters that appear first in ties,
|
||||
// and max_by_key selects the last equal element in the iterator.
|
||||
.rev()
|
||||
.filter(|adapter|
|
||||
adapter.is_surface_supported(&self.surface)
|
||||
adapter.is_surface_supported(surface)
|
||||
&&adapter.features().contains(required_features)
|
||||
&&{
|
||||
let downlevel_capabilities=adapter.get_downlevel_capabilities();
|
||||
downlevel_capabilities.shader_model>=required_downlevel_capabilities.shader_model
|
||||
&&downlevel_capabilities.flags.contains(required_downlevel_capabilities.flags)
|
||||
}
|
||||
)
|
||||
.max_by_key(|adapter|match adapter.get_info().device_type{
|
||||
wgpu::DeviceType::IntegratedGpu=>3,
|
||||
wgpu::DeviceType::DiscreteGpu=>4,
|
||||
wgpu::DeviceType::VirtualGpu=>2,
|
||||
wgpu::DeviceType::Other|wgpu::DeviceType::Cpu=>1,
|
||||
});
|
||||
|
||||
let adapter=chosen_adapter.expect("No suitable GPU adapters found on the system!");
|
||||
})?;
|
||||
|
||||
let adapter_info=adapter.get_info();
|
||||
println!("Using {} ({:?})", adapter_info.name, adapter_info.backend);
|
||||
|
||||
let required_downlevel_capabilities=required_downlevel_capabilities();
|
||||
let downlevel_capabilities=adapter.get_downlevel_capabilities();
|
||||
assert!(
|
||||
downlevel_capabilities.shader_model >= required_downlevel_capabilities.shader_model,
|
||||
"Adapter does not support the minimum shader model required to run this example: {:?}",
|
||||
required_downlevel_capabilities.shader_model
|
||||
);
|
||||
assert!(
|
||||
downlevel_capabilities
|
||||
.flags
|
||||
.contains(required_downlevel_capabilities.flags),
|
||||
"Adapter does not support the downlevel capabilities required to run this example: {:?}",
|
||||
required_downlevel_capabilities.flags - downlevel_capabilities.flags
|
||||
);
|
||||
SetupContextPartial3{
|
||||
surface:self.surface,
|
||||
adapter,
|
||||
}
|
||||
Some(adapter)
|
||||
}
|
||||
}
|
||||
struct SetupContextPartial3<'a>{
|
||||
surface:wgpu::Surface<'a>,
|
||||
adapter:wgpu::Adapter,
|
||||
}
|
||||
impl<'a> SetupContextPartial3<'a>{
|
||||
async fn request_device(self)->SetupContextPartial4<'a>{
|
||||
let optional_features=optional_features();
|
||||
let required_features=required_features();
|
||||
|
||||
mod step4{
|
||||
pub async fn request_device(adapter:&wgpu::Adapter)->(wgpu::Device,wgpu::Queue){
|
||||
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=strafesnet_graphics::graphics::required_limits().using_resolution(self.adapter.limits());
|
||||
let needed_limits=strafesnet_graphics::graphics::required_limits().using_resolution(adapter.limits());
|
||||
|
||||
let (device, queue)=self.adapter
|
||||
let (device, queue)=adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor{
|
||||
label:None,
|
||||
required_features:(optional_features&self.adapter.features())|required_features,
|
||||
required_features:(optional_features&adapter.features())|required_features,
|
||||
required_limits:needed_limits,
|
||||
memory_hints:wgpu::MemoryHints::Performance,
|
||||
trace:wgpu::Trace::Off,
|
||||
@@ -112,59 +84,66 @@ impl<'a> SetupContextPartial3<'a>{
|
||||
).await
|
||||
.expect("Unable to find a suitable GPU adapter!");
|
||||
|
||||
SetupContextPartial4{
|
||||
surface:self.surface,
|
||||
adapter:self.adapter,
|
||||
(
|
||||
device,
|
||||
queue,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
struct SetupContextPartial4<'a>{
|
||||
surface:wgpu::Surface<'a>,
|
||||
adapter:wgpu::Adapter,
|
||||
device:wgpu::Device,
|
||||
queue:wgpu::Queue,
|
||||
}
|
||||
impl<'a> SetupContextPartial4<'a>{
|
||||
fn configure_surface(self,(width,height):(u32,u32))->SetupContext<'a>{
|
||||
let mut config=self.surface
|
||||
.get_default_config(&self.adapter, width, height)
|
||||
mod step5{
|
||||
pub fn configure_surface(
|
||||
adapter:&wgpu::Adapter,
|
||||
device:&wgpu::Device,
|
||||
surface:&wgpu::Surface<'_>,
|
||||
(width,height):(u32,u32),
|
||||
)->wgpu::SurfaceConfiguration{
|
||||
let mut config=surface
|
||||
.get_default_config(adapter, width, height)
|
||||
.expect("Surface isn't supported by the adapter.");
|
||||
|
||||
let surface_view_format=config.format.add_srgb_suffix();
|
||||
config.view_formats.push(surface_view_format);
|
||||
config.present_mode=wgpu::PresentMode::AutoNoVsync;
|
||||
self.surface.configure(&self.device, &config);
|
||||
surface.configure(device, &config);
|
||||
|
||||
SetupContext{
|
||||
surface:self.surface,
|
||||
device:self.device,
|
||||
queue:self.queue,
|
||||
config,
|
||||
}
|
||||
config
|
||||
}
|
||||
}
|
||||
pub struct SetupContext<'a>{
|
||||
pub surface:wgpu::Surface<'a>,
|
||||
pub device:wgpu::Device,
|
||||
pub queue:wgpu::Queue,
|
||||
pub config:wgpu::SurfaceConfiguration,
|
||||
|
||||
struct ToSurfaceTarget{
|
||||
canvas:web_sys::HtmlCanvasElement,
|
||||
}
|
||||
impl From<ToSurfaceTarget> for wgpu::SurfaceTarget<'static>{
|
||||
fn from(ToSurfaceTarget{canvas}:ToSurfaceTarget)->Self{
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let target=wgpu::SurfaceTarget::Canvas(canvas);
|
||||
#[expect(unused)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let target=panic!("{canvas:?}");
|
||||
#[allow(unused)]
|
||||
target
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn setup_and_start(canvas:web_sys::HtmlCanvasElement)->SetupContext<'static>{
|
||||
pub async fn setup_and_start(canvas:web_sys::HtmlCanvasElement)->(wgpu::Device,wgpu::Queue,wgpu::Surface<'static>,wgpu::SurfaceConfiguration){
|
||||
let size=(canvas.width(),canvas.height());
|
||||
|
||||
println!("Initializing the surface...");
|
||||
|
||||
let partial_1=create_instance();
|
||||
let instance=step1::create_instance();
|
||||
|
||||
let partial_2=partial_1.create_surface(canvas).unwrap();
|
||||
let surface=step2::create_surface(&instance,ToSurfaceTarget{canvas}).unwrap();
|
||||
|
||||
let partial_3=partial_2.pick_adapter().await;
|
||||
let adapter=step3::pick_adapter(&instance,&surface).await.expect("No suitable GPU adapters found on the system!");
|
||||
|
||||
let partial_4=partial_3.request_device().await;
|
||||
let (device,queue)=step4::request_device(&adapter).await;
|
||||
|
||||
let setup_context=partial_4.configure_surface(size);
|
||||
let config=step5::configure_surface(&adapter,&device,&surface,size);
|
||||
|
||||
setup_context
|
||||
(
|
||||
device,
|
||||
queue,
|
||||
surface,
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user