mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-21 03:36:41 +01:00
Compare commits
2 Commits
fbc86fa78d
...
c9c5cb76bd
| Author | SHA1 | Date | |
|---|---|---|---|
| c9c5cb76bd | |||
| a6d6615231 |
@@ -14,10 +14,11 @@ fn vs_main(
|
|||||||
@builtin(vertex_index) in_vertex_index: u32,
|
@builtin(vertex_index) in_vertex_index: u32,
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
let x = (1.0 - f32(in_vertex_index)) * 3.0;
|
let i = in_vertex_index / 3u + in_vertex_index % 3u;
|
||||||
let y = f32(in_vertex_index & 1u) * 3.0 - 1.0;
|
let x = -1.0 + f32(i % 2u) * 322.0;
|
||||||
out.clip_position = vec4<f32>(x, y, 0.0, 1.0);
|
let y = -1.0 + f32(i / 2u) * 242.0;
|
||||||
out.tex_coords = vec2<f32>(x, y) * uniforms.texture_scale.xy + vec2<f32>(160.0, 120.0);
|
out.clip_position = vec4<f32>((vec2<f32>(x, y) - vec2<f32>(160.0, 120.0)) / uniforms.texture_scale.xy, 0.0, 1.0);
|
||||||
|
out.tex_coords = vec2<f32>(x, y);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,10 +40,6 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
|||||||
let o = vec2<f32>(0.5) - (in.tex_coords - pixel);
|
let o = vec2<f32>(0.5) - (in.tex_coords - pixel);
|
||||||
let pixel = vec2<i32>(pixel);
|
let pixel = vec2<i32>(pixel);
|
||||||
|
|
||||||
if(pixel.x < -1 || pixel.y < -1 || pixel.x > 320 || pixel.y > 240) {
|
|
||||||
return vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let offset_x = o.xxxx + vec4<f32>(-0.125, 0.375, 0.125, -0.375) * uniforms.texture_scale.z;
|
let offset_x = o.xxxx + vec4<f32>(-0.125, 0.375, 0.125, -0.375) * uniforms.texture_scale.z;
|
||||||
let offset_y = o.yyyy + vec4<f32>(-0.375, -0.125, 0.375, 0.125) * uniforms.texture_scale.z;
|
let offset_y = o.yyyy + vec4<f32>(-0.375, -0.125, 0.375, 0.125) * uniforms.texture_scale.z;
|
||||||
|
|
||||||
|
|||||||
@@ -77,54 +77,8 @@ impl Window {
|
|||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
} = self;
|
} = self;
|
||||||
let framebuffer_texture = device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: 320,
|
|
||||||
height: 240,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: wgpu::TextureFormat::R8Uint,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let palette_texture = device.create_texture(&wgpu::TextureDescriptor {
|
let palette_screen_mode = PaletteScreenMode::new(&device);
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: 256,
|
|
||||||
height: 1,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D1,
|
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let screen_texture = device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: 320,
|
|
||||||
height: 240,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let framebuffer_texture_view =
|
|
||||||
framebuffer_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
let palette_texture_view =
|
|
||||||
palette_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
let screen_texture_view =
|
|
||||||
screen_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
|
|
||||||
let mut uniforms = Uniforms {
|
let mut uniforms = Uniforms {
|
||||||
texture_scale: texture_scale_from_resolution(window.inner_size()),
|
texture_scale: texture_scale_from_resolution(window.inner_size()),
|
||||||
@@ -136,48 +90,6 @@ impl Window {
|
|||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
let palette_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
entries: &[
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Texture {
|
|
||||||
multisampled: false,
|
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
|
||||||
sample_type: wgpu::TextureSampleType::Uint,
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 1,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Texture {
|
|
||||||
multisampled: false,
|
|
||||||
view_dimension: wgpu::TextureViewDimension::D1,
|
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: false },
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let palette_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
layout: &palette_bind_group_layout,
|
|
||||||
entries: &[
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: wgpu::BindingResource::TextureView(&framebuffer_texture_view),
|
|
||||||
},
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: wgpu::BindingResource::TextureView(&palette_texture_view),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let crt_bind_group_layout =
|
let crt_bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
entries: &[
|
entries: &[
|
||||||
@@ -210,7 +122,7 @@ impl Window {
|
|||||||
entries: &[
|
entries: &[
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::TextureView(&screen_texture_view),
|
resource: wgpu::BindingResource::TextureView(&palette_screen_mode.screen_view),
|
||||||
},
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
@@ -220,41 +132,6 @@ impl Window {
|
|||||||
label: None,
|
label: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let palette_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
|
||||||
label: None,
|
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("palette.wgsl").into()),
|
|
||||||
});
|
|
||||||
|
|
||||||
let palette_pipeline_layout =
|
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
|
||||||
label: None,
|
|
||||||
bind_group_layouts: &[&palette_bind_group_layout],
|
|
||||||
push_constant_ranges: &[],
|
|
||||||
});
|
|
||||||
|
|
||||||
let palette_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
|
||||||
label: None,
|
|
||||||
layout: Some(&palette_pipeline_layout),
|
|
||||||
vertex: wgpu::VertexState {
|
|
||||||
module: &palette_shader,
|
|
||||||
entry_point: "vs_main",
|
|
||||||
buffers: &[],
|
|
||||||
},
|
|
||||||
fragment: Some(wgpu::FragmentState {
|
|
||||||
module: &palette_shader,
|
|
||||||
entry_point: "fs_main",
|
|
||||||
targets: &[Some(wgpu::ColorTargetState {
|
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
|
||||||
blend: None,
|
|
||||||
write_mask: wgpu::ColorWrites::ALL,
|
|
||||||
})],
|
|
||||||
}),
|
|
||||||
primitive: Default::default(),
|
|
||||||
depth_stencil: None,
|
|
||||||
multisample: Default::default(),
|
|
||||||
multiview: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let crt_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let crt_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("crt.wgsl").into()),
|
source: wgpu::ShaderSource::Wgsl(include_str!("crt.wgsl").into()),
|
||||||
@@ -360,8 +237,7 @@ impl Window {
|
|||||||
let next_frame = update(
|
let next_frame = update(
|
||||||
&mut GpuFramebuffer {
|
&mut GpuFramebuffer {
|
||||||
queue: &queue,
|
queue: &queue,
|
||||||
framebuffer: &framebuffer_texture,
|
framebuffer: &palette_screen_mode,
|
||||||
palette: &palette_texture,
|
|
||||||
},
|
},
|
||||||
gamepad,
|
gamepad,
|
||||||
reset,
|
reset,
|
||||||
@@ -376,25 +252,7 @@ impl Window {
|
|||||||
let mut encoder = device
|
let mut encoder = device
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
|
|
||||||
{
|
palette_screen_mode.resolve_screen(&mut encoder);
|
||||||
let mut render_pass =
|
|
||||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
label: None,
|
|
||||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
|
||||||
view: &screen_texture_view,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: wgpu::Operations {
|
|
||||||
load: wgpu::LoadOp::Load,
|
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
})],
|
|
||||||
depth_stencil_attachment: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
render_pass.set_pipeline(&palette_pipeline);
|
|
||||||
render_pass.set_bind_group(0, &palette_bind_group, &[]);
|
|
||||||
render_pass.draw(0..3, 0..1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut render_pass =
|
let mut render_pass =
|
||||||
@@ -404,7 +262,12 @@ impl Window {
|
|||||||
view: &view,
|
view: &view,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
ops: wgpu::Operations {
|
ops: wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Load,
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
|
r: 0.0,
|
||||||
|
g: 0.0,
|
||||||
|
b: 0.0,
|
||||||
|
a: 1.0,
|
||||||
|
}),
|
||||||
store: true,
|
store: true,
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
@@ -413,7 +276,7 @@ impl Window {
|
|||||||
|
|
||||||
render_pass.set_pipeline(&render_pipeline);
|
render_pass.set_pipeline(&render_pipeline);
|
||||||
render_pass.set_bind_group(0, &crt_bind_group, &[]);
|
render_pass.set_bind_group(0, &crt_bind_group, &[]);
|
||||||
render_pass.draw(0..3, 0..1);
|
render_pass.draw(0..6, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.submit(std::iter::once(encoder.finish()));
|
queue.submit(std::iter::once(encoder.finish()));
|
||||||
@@ -426,51 +289,14 @@ impl Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct GpuFramebuffer<'a> {
|
struct GpuFramebuffer<'a> {
|
||||||
framebuffer: &'a wgpu::Texture,
|
framebuffer: &'a PaletteScreenMode,
|
||||||
palette: &'a wgpu::Texture,
|
|
||||||
queue: &'a wgpu::Queue,
|
queue: &'a wgpu::Queue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Framebuffer for GpuFramebuffer<'a> {
|
impl<'a> Framebuffer for GpuFramebuffer<'a> {
|
||||||
fn update(&mut self, pixels: &[u8], palette: &[u8]) {
|
fn update(&mut self, pixels: &[u8], palette: &[u8]) {
|
||||||
self.queue.write_texture(
|
self.framebuffer.write_framebuffer(self.queue, pixels);
|
||||||
wgpu::ImageCopyTexture {
|
self.framebuffer.write_palette(self.queue, palette);
|
||||||
texture: self.framebuffer,
|
|
||||||
mip_level: 0,
|
|
||||||
origin: wgpu::Origin3d::ZERO,
|
|
||||||
aspect: wgpu::TextureAspect::All,
|
|
||||||
},
|
|
||||||
&bytemuck::cast_slice(pixels),
|
|
||||||
wgpu::ImageDataLayout {
|
|
||||||
offset: 0,
|
|
||||||
bytes_per_row: NonZeroU32::new(320),
|
|
||||||
rows_per_image: None,
|
|
||||||
},
|
|
||||||
wgpu::Extent3d {
|
|
||||||
width: 320,
|
|
||||||
height: 240,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
self.queue.write_texture(
|
|
||||||
wgpu::ImageCopyTexture {
|
|
||||||
texture: self.palette,
|
|
||||||
mip_level: 0,
|
|
||||||
origin: wgpu::Origin3d::ZERO,
|
|
||||||
aspect: wgpu::TextureAspect::All,
|
|
||||||
},
|
|
||||||
&bytemuck::cast_slice(palette),
|
|
||||||
wgpu::ImageDataLayout {
|
|
||||||
offset: 0,
|
|
||||||
bytes_per_row: NonZeroU32::new(256 * 4),
|
|
||||||
rows_per_image: None,
|
|
||||||
},
|
|
||||||
wgpu::Extent3d {
|
|
||||||
width: 256,
|
|
||||||
height: 1,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,3 +315,211 @@ fn texture_scale_from_resolution(res: PhysicalSize<u32>) -> [f32; 4] {
|
|||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
texture_scale: [f32; 4],
|
texture_scale: [f32; 4],
|
||||||
}
|
}
|
||||||
|
struct PaletteScreenMode {
|
||||||
|
framebuffer: wgpu::Texture,
|
||||||
|
palette: wgpu::Texture,
|
||||||
|
screen_view: wgpu::TextureView,
|
||||||
|
bind_group: wgpu::BindGroup,
|
||||||
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaletteScreenMode {
|
||||||
|
fn new(device: &wgpu::Device) -> PaletteScreenMode {
|
||||||
|
let framebuffer_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
size: wgpu::Extent3d {
|
||||||
|
width: 320,
|
||||||
|
height: 240,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::R8Uint,
|
||||||
|
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let palette_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
size: wgpu::Extent3d {
|
||||||
|
width: 256,
|
||||||
|
height: 1,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D1,
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let screen_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
size: wgpu::Extent3d {
|
||||||
|
width: 320,
|
||||||
|
height: 240,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let framebuffer_texture_view =
|
||||||
|
framebuffer_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
let palette_texture_view =
|
||||||
|
palette_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
let screen_texture_view =
|
||||||
|
screen_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|
||||||
|
let palette_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
multisampled: false,
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
sample_type: wgpu::TextureSampleType::Uint,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
multisampled: false,
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D1,
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: false },
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let palette_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &palette_bind_group_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&framebuffer_texture_view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&palette_texture_view),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let palette_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: None,
|
||||||
|
source: wgpu::ShaderSource::Wgsl(include_str!("palette.wgsl").into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let palette_pipeline_layout =
|
||||||
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
bind_group_layouts: &[&palette_bind_group_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
let palette_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: Some(&palette_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &palette_shader,
|
||||||
|
entry_point: "vs_main",
|
||||||
|
buffers: &[],
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &palette_shader,
|
||||||
|
entry_point: "fs_main",
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
blend: None,
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
}),
|
||||||
|
primitive: Default::default(),
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: Default::default(),
|
||||||
|
multiview: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
PaletteScreenMode {
|
||||||
|
framebuffer: framebuffer_texture,
|
||||||
|
palette: palette_texture,
|
||||||
|
screen_view: screen_texture_view,
|
||||||
|
bind_group: palette_bind_group,
|
||||||
|
pipeline: palette_pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_framebuffer(&self, queue: &wgpu::Queue, pixels: &[u8]) {
|
||||||
|
queue.write_texture(
|
||||||
|
wgpu::ImageCopyTexture {
|
||||||
|
texture: &self.framebuffer,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d::ZERO,
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
|
},
|
||||||
|
&bytemuck::cast_slice(pixels),
|
||||||
|
wgpu::ImageDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: NonZeroU32::new(320),
|
||||||
|
rows_per_image: None,
|
||||||
|
},
|
||||||
|
wgpu::Extent3d {
|
||||||
|
width: 320,
|
||||||
|
height: 240,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_palette(&self, queue: &wgpu::Queue, palette: &[u8]) {
|
||||||
|
queue.write_texture(
|
||||||
|
wgpu::ImageCopyTexture {
|
||||||
|
texture: &self.palette,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d::ZERO,
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
|
},
|
||||||
|
&bytemuck::cast_slice(palette),
|
||||||
|
wgpu::ImageDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: NonZeroU32::new(256 * 4),
|
||||||
|
rows_per_image: None,
|
||||||
|
},
|
||||||
|
wgpu::Extent3d {
|
||||||
|
width: 256,
|
||||||
|
height: 1,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_screen(&self, encoder: &mut wgpu::CommandEncoder) {
|
||||||
|
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: None,
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: &self.screen_view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_pipeline(&self.pipeline);
|
||||||
|
render_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||||
|
render_pass.draw(0..3, 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::Instant;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||||
@@ -15,13 +15,22 @@ fn main() {
|
|||||||
palette[i as usize] = r + (g << 8) + (b << 16);
|
palette[i as usize] = r + (g << 8) + (b << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut prev_frame = Instant::now();
|
let mut fps_start = Instant::now();
|
||||||
|
let mut fps_counter = 0;
|
||||||
|
|
||||||
uw8_window::run(move |gpu_framebuffer, _gamepads, _reset| {
|
uw8_window::run(true, move |gpu_framebuffer, _gamepads, _reset| {
|
||||||
draw_frame(&mut framebuffer, start_time.elapsed().as_secs_f32());
|
for _ in 0..1 {
|
||||||
|
draw_frame(&mut framebuffer, start_time.elapsed().as_secs_f32());
|
||||||
|
}
|
||||||
gpu_framebuffer.update(&framebuffer, bytemuck::cast_slice(&palette));
|
gpu_framebuffer.update(&framebuffer, bytemuck::cast_slice(&palette));
|
||||||
prev_frame += Duration::from_secs_f32(1.0 / 60.0);
|
fps_counter += 1;
|
||||||
prev_frame
|
let elapsed = fps_start.elapsed().as_secs_f32();
|
||||||
|
if elapsed >= 1.0 {
|
||||||
|
println!("{:.1} fps", fps_counter as f32 / elapsed);
|
||||||
|
fps_start = Instant::now();
|
||||||
|
fps_counter = 0;
|
||||||
|
}
|
||||||
|
Instant::now()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user