Create window using the graphen-cli

This commit is contained in:
Dennis Kobert
2023-06-17 12:38:32 +02:00
committed by Keavon Chambers
parent dccb5235c0
commit 5d1581dd70
9 changed files with 141 additions and 40 deletions

View File

@@ -1136,7 +1136,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
category: "Gpu",
identifier: NodeImplementation::DocumentNode(NodeNetwork {
inputs: vec![1, 1, 0],
outputs: vec![NodeOutput::new(2, 0)],
outputs: vec![NodeOutput::new(1, 0)],
nodes: [
DocumentNode {
name: "Extract Executor".to_string(),
@@ -1154,12 +1154,6 @@ fn static_nodes() -> Vec<DocumentNodeType> {
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::RenderTextureNode<_, _>")),
..Default::default()
},
DocumentNode {
name: "Cache".to_string(),
inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")),
..Default::default()
},
]
.into_iter()
.enumerate()

View File

@@ -520,6 +520,7 @@ where
#[node_macro::node_fn(RenderTextureNode)]
async fn render_texture_node<'a: 'input, E: 'a + GpuExecutor>(image: ShaderInputFrame<E>, surface: Arc<SurfaceHandle<E::Surface>>, executor: &'a E) -> SurfaceFrame {
let surface_id = surface.surface_id;
log::trace!("rendering to surface {:?}", surface_id);
executor.create_render_pass(image.shader_input, surface).unwrap();

View File

@@ -6,7 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
gpu = ["interpreted-executor/gpu", "graphene-std/gpu", "graphene-core/gpu", "wgpu-executor", "gpu-executor"]
gpu = [
"interpreted-executor/gpu",
"graphene-std/gpu",
"graphene-core/gpu",
"wgpu-executor",
"gpu-executor",
]
default = ["wgpu"]
wgpu = ["wgpu-executor", "gpu"]
@@ -30,7 +36,7 @@ gpu-executor = { path = "../gpu-executor", optional = true }
interpreted-executor = { path = "../interpreted-executor" }
dyn-any = { path = "../../libraries/dyn-any" }
graphene-core = { path = "../gcore" }
graphene-std = { path = "../gstd" }
graphene-std = { path = "../gstd", features = [] }
future-executor = { path = "../future-executor", optional = true }
wasm-bindgen = { version = "0.2.86", optional = true }

View File

@@ -26,12 +26,37 @@ impl NodeGraphUpdateSender for UpdateLogger {
}
fn main() -> Result<(), Box<dyn Error>> {
init_logging();
let document_path = std::env::args().nth(1).expect("No document path provided");
let document_string = std::fs::read_to_string(&document_path).expect("Failed to read document");
let executor = create_executor(document_string)?;
println!("creating gpu context",);
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
for i in 0..10 {
//println!("executing");
let result = block_on((&executor).execute(editor_api.clone()))?;
//println!("result: {:?}", result);
std::thread::sleep(std::time::Duration::from_secs(1));
}
Ok(())
}
fn init_logging() {
let colors = ColoredLevelConfig::new().debug(Color::Magenta).info(Color::Green).error(Color::Red);
fern::Dispatch::new()
.chain(std::io::stdout())
.level_for("foodcalc", log::LevelFilter::Trace)
.level_for("sqlx", log::LevelFilter::Trace)
.level_for("iced", log::LevelFilter::Trace)
.level_for("wgpu", log::LevelFilter::Debug)
.level(log::LevelFilter::Trace)
.format(move |out, message, record| {
out.finish(format_args!(
@@ -44,37 +69,38 @@ fn main() -> Result<(), Box<dyn Error>> {
})
.apply()
.unwrap();
}
let document_path = std::env::args().nth(1).expect("No document path provided");
let document_string = std::fs::read_to_string(&document_path).expect("Failed to read document");
fn create_executor(document_string: String) -> Result<DynamicExecutor, Box<dyn Error>> {
let document: serde_json::Value = serde_json::from_str(&document_string).expect("Failed to parse document");
let document = serde_json::from_value::<Document>(document["document_legacy"].clone()).expect("Failed to parse document");
let Some(LayerDataType::Layer(ref node_graph)) = document.root.iter().find(|layer| matches!(layer.data, LayerDataType::Layer(_))).map(|x|&x.data) else { panic!("failed to extract node graph from docmuent") };
let network = &node_graph.network;
let wrapped_network = wrap_network_in_scope(network.clone());
let compiler = Compiler {};
let protograph = compiler.compile_single(wrapped_network, true)?;
let mut executor = block_on(DynamicExecutor::new(protograph))?;
Ok(executor)
}
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
loop {
let result = block_on((&executor).execute(editor_api.clone()))?;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn gpu_surface() {
let document_string = include_str!("../test_files/gpu_surface.graphite");
let executor = create_executor(document_string.to_string()).unwrap();
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
let result = block_on((&executor).execute(editor_api.clone())).unwrap();
println!("result: {:?}", result);
}
Ok(())
}
pub fn wrap_network_in_scope(mut network: NodeNetwork) -> NodeNetwork {

File diff suppressed because one or more lines are too long

View File

@@ -10,12 +10,18 @@ license = "MIT OR Apache-2.0"
[features]
default = ["wasm", "imaginate"]
gpu = ["graphene-core/gpu", "gpu-compiler-bin-wrapper", "compilation-client", "gpu-executor"]
gpu = [
"graphene-core/gpu",
"gpu-compiler-bin-wrapper",
"compilation-client",
"gpu-executor",
]
vulkan = ["gpu", "vulkan-executor"]
wgpu = ["gpu", "wgpu-executor"]
quantization = ["autoquant"]
wasm = ["wasm-bindgen", "web-sys", "js-sys"]
imaginate = ["image/png", "base64", "js-sys", "web-sys", "wasm-bindgen-futures"]
wayland = []
[dependencies]

View File

@@ -20,6 +20,8 @@ pub struct WasmApplicationIo {
ids: RefCell<u64>,
#[cfg(feature = "wgpu")]
pub(crate) gpu_executor: Option<WgpuExecutor>,
#[cfg(not(target_arch = "wasm32"))]
windows: RefCell<Vec<Arc<winit::window::Window>>>,
}
impl WasmApplicationIo {
@@ -28,6 +30,8 @@ impl WasmApplicationIo {
ids: RefCell::new(0),
#[cfg(feature = "wgpu")]
gpu_executor: WgpuExecutor::new().await,
#[cfg(not(target_arch = "wasm32"))]
windows: RefCell::new(Vec::new()),
}
}
}
@@ -54,7 +58,7 @@ impl ApplicationIo for WasmApplicationIo {
#[cfg(target_arch = "wasm32")]
type Surface = HtmlCanvasElement;
#[cfg(not(target_arch = "wasm32"))]
type Surface = winit::window::Window;
type Surface = Arc<winit::window::Window>;
#[cfg(feature = "wgpu")]
type Executor = WgpuExecutor;
#[cfg(not(feature = "wgpu"))]
@@ -96,12 +100,20 @@ impl ApplicationIo for WasmApplicationIo {
}
#[cfg(not(target_arch = "wasm32"))]
fn create_surface(&self) -> SurfaceHandle<Self::Surface> {
#[cfg(feature = "wayland")]
use winit::platform::wayland::EventLoopBuilderExtWayland;
#[cfg(feature = "wayland")]
let event_loop = winit::event_loop::EventLoopBuilder::new().with_any_thread(true).build();
#[cfg(not(feature = "wayland"))]
let event_loop = winit::event_loop::EventLoop::new();
let window = winit::window::WindowBuilder::new()
.with_title("Graphite")
.with_inner_size(winit::dpi::PhysicalSize::new(1920, 1080))
.build(&event_loop)
.unwrap();
let window = Arc::new(window);
self.windows.borrow_mut().push(window.clone());
SurfaceHandle {
surface_id: SurfaceId(window.id().into()),
surface: window,

View File

@@ -12,7 +12,9 @@ pub struct Context {
impl Context {
pub async fn new() -> Option<Self> {
// Instantiates instance of WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
let mut instance_descriptor = wgpu::InstanceDescriptor::default();
instance_descriptor.backends = wgpu::Backends::VULKAN | wgpu::Backends::BROWSER_WEBGPU;
let instance = wgpu::Instance::new(instance_descriptor);
// `request_adapter` instantiates the general connection to the GPU
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await?;

View File

@@ -15,7 +15,7 @@ use std::pin::Pin;
use std::sync::Arc;
use wgpu::util::DeviceExt;
use wgpu::{Buffer, BufferDescriptor, CommandBuffer, ShaderModule, Texture, TextureView};
use wgpu::{Buffer, BufferDescriptor, CommandBuffer, ShaderModule, SurfaceError, Texture, TextureView};
#[cfg(target_arch = "wasm32")]
use web_sys::HtmlCanvasElement;
@@ -104,7 +104,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
#[cfg(target_arch = "wasm32")]
type Window = HtmlCanvasElement;
#[cfg(not(target_arch = "wasm32"))]
type Window = winit::window::Window;
type Window = Arc<winit::window::Window>;
fn load_shader(&self, shader: Shader) -> Result<Self::ShaderHandle> {
let shader_module = self.context.device.create_shader_module(wgpu::ShaderModuleDescriptor {
@@ -265,7 +265,59 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
fn create_render_pass(&self, texture: Arc<ShaderInput<Self>>, canvas: Arc<SurfaceHandle<wgpu::Surface>>) -> Result<()> {
let texture = texture.texture().expect("Expected texture input");
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let output = canvas.as_ref().surface.get_current_texture()?;
let result = canvas.as_ref().surface.get_current_texture();
let output = match result {
Err(SurfaceError::Timeout) => {
log::warn!("Timeout when getting current texture");
return Ok(());
}
Err(SurfaceError::Lost) => {
log::warn!("Surface lost");
let surface = &canvas.as_ref().surface;
let surface_caps = surface.get_capabilities(&self.context.adapter);
println!("{:?}", surface_caps);
if surface_caps.formats.is_empty() {
log::warn!("No surface formats available");
//return Ok(());
}
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
width: 1920,
height: 1080,
present_mode: wgpu::PresentMode::Fifo,
alpha_mode: wgpu::CompositeAlphaMode::Opaque,
view_formats: vec![],
};
surface.configure(&self.context.device, &config);
return Ok(());
}
Err(SurfaceError::OutOfMemory) => {
log::warn!("Out of memory");
return Ok(());
}
Err(SurfaceError::Outdated) => {
log::warn!("Surface outdated");
let surface = &canvas.as_ref().surface;
let surface_caps = surface.get_capabilities(&self.context.adapter);
println!("{:?}", surface_caps);
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
width: 1920,
height: 1080,
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
};
surface.configure(&self.context.device, &config);
return Ok(());
}
Ok(surface) => surface,
};
let view = output.texture.create_view(&wgpu::TextureViewDescriptor {
format: Some(wgpu::TextureFormat::Bgra8Unorm),
..Default::default()
@@ -310,6 +362,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
let encoder = encoder.finish();
self.context.queue.submit(Some(encoder));
log::trace!("Submitted render pass");
output.present();
Ok(())
@@ -394,10 +447,11 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
})
}
#[cfg(not(target_arch = "wasm32"))]
fn create_surface(&self, window: SurfaceHandle<winit::window::Window>) -> Result<SurfaceHandle<wgpu::Surface>> {
let surface = unsafe { self.context.instance.create_surface(&window.surface) }?;
fn create_surface(&self, window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<wgpu::Surface>> {
let surface = unsafe { self.context.instance.create_surface(window.surface.as_ref()) }?;
let surface_caps = surface.get_capabilities(&self.context.adapter);
println!("{:?}", surface_caps);
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
@@ -406,7 +460,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
height: 1080,
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![wgpu::TextureFormat::Bgra8UnormSrgb],
view_formats: vec![],
};
surface.configure(&self.context.device, &config);