From b025f7260467b3ffffff400f17c1caf2a23197cf Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Sun, 3 Nov 2024 13:25:20 -0500 Subject: [PATCH] Use one texture with two channels for video --- src/anaglyph.wgsl | 4 ++-- src/app.rs | 26 +++++++------------------- src/emulator.rs | 2 +- src/renderer.rs | 17 ++++++----------- src/shrooms_vb_core.rs | 18 +++++++++--------- 5 files changed, 25 insertions(+), 42 deletions(-) diff --git a/src/anaglyph.wgsl b/src/anaglyph.wgsl index 0015101..796e7b1 100644 --- a/src/anaglyph.wgsl +++ b/src/anaglyph.wgsl @@ -37,13 +37,13 @@ fn vs_main( // Fragment shader @group(0) @binding(0) -var u_textures: binding_array>; +var u_texture: texture_2d; @group(0) @binding(1) var u_sampler: sampler; @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - return textureSample(u_textures[0], u_sampler, in.tex_coords); + return textureSample(u_texture, u_sampler, in.tex_coords); // return vec4(0.3, 0.2, 0.1, 1.0); } diff --git a/src/app.rs b/src/app.rs index ef43c97..c196d8f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,7 +2,7 @@ use imgui::*; use imgui_wgpu::{Renderer, RendererConfig}; use imgui_winit_support::WinitPlatform; use pollster::block_on; -use std::{num::NonZero, sync::Arc, time::Instant}; +use std::{sync::Arc, time::Instant}; #[cfg(target_os = "windows")] use winit::platform::windows::{CornerPreference, WindowAttributesExtWindows as _}; use winit::{ @@ -69,27 +69,15 @@ impl AppWindow { })) .unwrap(); - let (device, queue) = block_on(adapter.request_device( - &wgpu::DeviceDescriptor { - required_features: wgpu::Features::TEXTURE_BINDING_ARRAY, - ..wgpu::DeviceDescriptor::default() - }, - None, - )) - .unwrap(); + let (device, queue) = + block_on(adapter.request_device(&wgpu::DeviceDescriptor::default(), None)).unwrap(); let queue = Arc::new(queue); - let eyes = [ - Arc::new(GameRenderer::create_texture(&device, "left eye")), - Arc::new(GameRenderer::create_texture(&device, "right eye")), - ]; + let eyes = Arc::new(GameRenderer::create_texture(&device, "eye")); client.send_command(EmulatorCommand::SetRenderer(GameRenderer { queue: queue.clone(), eyes: eyes.clone(), })); - let eyes = [ - eyes[0].create_view(&wgpu::TextureViewDescriptor::default()), - eyes[1].create_view(&wgpu::TextureViewDescriptor::default()), - ]; + let eyes = eyes.create_view(&wgpu::TextureViewDescriptor::default()); let sampler = device.create_sampler(&wgpu::SamplerDescriptor::default()); let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -103,7 +91,7 @@ impl AppWindow { view_dimension: wgpu::TextureViewDimension::D2, multisampled: false, }, - count: NonZero::new(2), + count: None, }, wgpu::BindGroupLayoutEntry { binding: 1, @@ -119,7 +107,7 @@ impl AppWindow { entries: &[ wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::TextureViewArray(&[&eyes[0], &eyes[1]]), + resource: wgpu::BindingResource::TextureView(&eyes), }, wgpu::BindGroupEntry { binding: 1, diff --git a/src/emulator.rs b/src/emulator.rs index 5f1e201..18100fd 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -33,7 +33,7 @@ impl Emulator { } pub fn run(&mut self) { - let mut eye_contents = [vec![0u8; 384 * 224], vec![0u8; 384 * 224]]; + let mut eye_contents = vec![0u8; 384 * 224 * 2]; loop { self.sim.emulate_frame(); if let Some(renderer) = &mut self.renderer { diff --git a/src/renderer.rs b/src/renderer.rs index 06dbe91..a97e9e7 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -8,18 +8,13 @@ use wgpu::{ #[derive(Debug)] pub struct GameRenderer { pub queue: Arc, - pub eyes: [Arc; 2], + pub eyes: Arc, } impl GameRenderer { - pub fn render(&self, buffers: &[Vec; 2]) { - for (texture, buffer) in self.eyes.iter().zip(buffers) { - self.update_texture(texture, buffer); - } - } - fn update_texture(&self, texture: &Texture, buffer: &[u8]) { + pub fn render(&self, buffer: &[u8]) { let texture = ImageCopyTexture { - texture, + texture: &self.eyes, mip_level: 0, origin: Origin3d::ZERO, aspect: wgpu::TextureAspect::All, @@ -31,7 +26,7 @@ impl GameRenderer { }; let data_layout = ImageDataLayout { offset: 0, - bytes_per_row: Some(384), + bytes_per_row: Some(384 * 2), rows_per_image: Some(224), }; self.queue.write_texture(texture, buffer, data_layout, size); @@ -47,11 +42,11 @@ impl GameRenderer { mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: TextureFormat::R8Unorm, + format: TextureFormat::Rg8Unorm, usage: TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING, - view_formats: &[TextureFormat::R8Unorm], + view_formats: &[TextureFormat::Rg8Unorm], }; device.create_texture(&desc) } diff --git a/src/shrooms_vb_core.rs b/src/shrooms_vb_core.rs index fa085ed..a28f386 100644 --- a/src/shrooms_vb_core.rs +++ b/src/shrooms_vb_core.rs @@ -113,7 +113,7 @@ impl CoreVB { unsafe { vb_emulate(self.sim, &mut cycles) }; } - pub fn read_pixels(&mut self, buffers: &mut [Vec; 2]) -> bool { + pub fn read_pixels(&mut self, buffers: &mut [u8]) -> bool { // SAFETY: the *mut VB owns its userdata. // There is no way for the userdata to be null or otherwise invalid. let data: &mut VBState = unsafe { &mut *vb_get_user_data(self.sim).cast() }; @@ -122,17 +122,17 @@ impl CoreVB { } data.frame_seen = false; - assert_eq!(buffers[0].len(), 384 * 224); - assert_eq!(buffers[1].len(), 384 * 224); + // the buffer must be big enough for our data + assert!(buffers.len() >= 384 * 224 * 2); unsafe { vb_get_pixels( self.sim, - buffers[0].as_mut_ptr().cast(), - 1, - 384, - buffers[1].as_mut_ptr().cast(), - 1, - 384, + buffers.as_mut_ptr().cast(), + 2, + 384 * 2, + buffers.as_mut_ptr().offset(1).cast(), + 2, + 384 * 2, ); }; true