wgpu: Move descriptors out into its own file

This commit is contained in:
Nathan Adams 2022-09-03 02:14:24 +02:00
parent a638b0498e
commit 70d96654d7
3 changed files with 197 additions and 152 deletions

View File

@ -6,8 +6,9 @@ use rayon::prelude::*;
use ruffle_core::tag_utils::SwfMovie; use ruffle_core::tag_utils::SwfMovie;
use ruffle_core::PlayerBuilder; use ruffle_core::PlayerBuilder;
use ruffle_render_wgpu::clap::{GraphicsBackend, PowerPreference}; use ruffle_render_wgpu::clap::{GraphicsBackend, PowerPreference};
use ruffle_render_wgpu::descriptors::Descriptors;
use ruffle_render_wgpu::target::TextureTarget; use ruffle_render_wgpu::target::TextureTarget;
use ruffle_render_wgpu::{wgpu, Descriptors, WgpuRenderBackend}; use ruffle_render_wgpu::{wgpu, WgpuRenderBackend};
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::panic::catch_unwind; use std::panic::catch_unwind;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};

View File

@ -0,0 +1,191 @@
use crate::{BitmapSamplers, Pipelines};
/// Contains data specific to a `RenderTarget`.
/// We cannot re-use this data in `with_offscreen_backend`
pub struct DescriptorsTargetData {
// These fields are specific to our `RenderTarget`, and
// cannot be re-used
pub surface_format: wgpu::TextureFormat,
pub frame_buffer_format: wgpu::TextureFormat,
pub pipelines: Pipelines,
pub msaa_sample_count: u32,
}
impl DescriptorsTargetData {
fn new(
device: &wgpu::Device,
surface_format: wgpu::TextureFormat,
bitmap_samplers: &BitmapSamplers,
msaa_sample_count: u32,
globals_layout: &wgpu::BindGroupLayout,
uniform_buffers_layout: &wgpu::BindGroupLayout,
) -> Self {
// We want to render directly onto a linear render target to avoid any gamma correction.
// If our surface is sRGB, render to a linear texture and than copy over to the surface.
// Remove Srgb from texture format.
let frame_buffer_format = match surface_format {
wgpu::TextureFormat::Rgba8UnormSrgb => wgpu::TextureFormat::Rgba8Unorm,
wgpu::TextureFormat::Bgra8UnormSrgb => wgpu::TextureFormat::Bgra8Unorm,
wgpu::TextureFormat::Bc1RgbaUnormSrgb => wgpu::TextureFormat::Bc1RgbaUnorm,
wgpu::TextureFormat::Bc2RgbaUnormSrgb => wgpu::TextureFormat::Bc2RgbaUnorm,
wgpu::TextureFormat::Bc3RgbaUnormSrgb => wgpu::TextureFormat::Bc3RgbaUnorm,
wgpu::TextureFormat::Bc7RgbaUnormSrgb => wgpu::TextureFormat::Bc7RgbaUnorm,
wgpu::TextureFormat::Etc2Rgb8UnormSrgb => wgpu::TextureFormat::Etc2Rgb8Unorm,
wgpu::TextureFormat::Etc2Rgb8A1UnormSrgb => wgpu::TextureFormat::Etc2Rgb8A1Unorm,
wgpu::TextureFormat::Etc2Rgba8UnormSrgb => wgpu::TextureFormat::Etc2Rgba8Unorm,
wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::UnormSrgb,
} => wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::Unorm,
},
_ => surface_format,
};
let pipelines = Pipelines::new(
&device,
surface_format,
frame_buffer_format,
msaa_sample_count,
bitmap_samplers.layout(),
globals_layout,
uniform_buffers_layout,
);
DescriptorsTargetData {
surface_format,
frame_buffer_format,
pipelines,
msaa_sample_count,
}
}
}
pub struct Descriptors {
pub device: wgpu::Device,
pub info: wgpu::AdapterInfo,
pub limits: wgpu::Limits,
pub surface_format: wgpu::TextureFormat,
pub frame_buffer_format: wgpu::TextureFormat,
pub queue: wgpu::Queue,
pub globals_layout: wgpu::BindGroupLayout,
pub uniform_buffers_layout: wgpu::BindGroupLayout,
pub pipelines: Pipelines,
pub bitmap_samplers: BitmapSamplers,
pub msaa_sample_count: u32,
pub onscreen: DescriptorsTargetData,
pub offscreen: DescriptorsTargetData,
}
impl Descriptors {
pub fn new(
device: wgpu::Device,
queue: wgpu::Queue,
info: wgpu::AdapterInfo,
surface_format: wgpu::TextureFormat,
msaa_sample_count: u32,
) -> Self {
let limits = device.limits();
let bitmap_samplers = BitmapSamplers::new(&device);
let uniform_buffer_layout_label = create_debug_label!("Uniform buffer bind group layout");
let uniform_buffers_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: true,
min_binding_size: None,
},
count: None,
}],
label: uniform_buffer_layout_label.as_deref(),
});
// We want to render directly onto a linear render target to avoid any gamma correction.
// If our surface is sRGB, render to a linear texture and than copy over to the surface.
// Remove Srgb from texture format.
let frame_buffer_format = match surface_format {
wgpu::TextureFormat::Rgba8UnormSrgb => wgpu::TextureFormat::Rgba8Unorm,
wgpu::TextureFormat::Bgra8UnormSrgb => wgpu::TextureFormat::Bgra8Unorm,
wgpu::TextureFormat::Bc1RgbaUnormSrgb => wgpu::TextureFormat::Bc1RgbaUnorm,
wgpu::TextureFormat::Bc2RgbaUnormSrgb => wgpu::TextureFormat::Bc2RgbaUnorm,
wgpu::TextureFormat::Bc3RgbaUnormSrgb => wgpu::TextureFormat::Bc3RgbaUnorm,
wgpu::TextureFormat::Bc7RgbaUnormSrgb => wgpu::TextureFormat::Bc7RgbaUnorm,
wgpu::TextureFormat::Etc2Rgb8UnormSrgb => wgpu::TextureFormat::Etc2Rgb8Unorm,
wgpu::TextureFormat::Etc2Rgb8A1UnormSrgb => wgpu::TextureFormat::Etc2Rgb8A1Unorm,
wgpu::TextureFormat::Etc2Rgba8UnormSrgb => wgpu::TextureFormat::Etc2Rgba8Unorm,
wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::UnormSrgb,
} => wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::Unorm,
},
_ => surface_format,
};
let globals_layout_label = create_debug_label!("Globals bind group layout");
let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: globals_layout_label.as_deref(),
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
});
let onscreen = DescriptorsTargetData::new(
&device,
surface_format,
&bitmap_samplers,
msaa_sample_count,
&globals_layout,
&uniform_buffers_layout,
);
// FIXME - get MSAA working for `TextureTarget`
let offscreen = DescriptorsTargetData::new(
&device,
wgpu::TextureFormat::Rgba8Unorm,
&bitmap_samplers,
1,
&globals_layout,
&uniform_buffers_layout,
);
let pipelines = Pipelines::new(
&device,
surface_format,
frame_buffer_format,
msaa_sample_count,
bitmap_samplers.layout(),
&globals_layout,
&uniform_buffers_layout,
);
Self {
device,
info,
limits,
surface_format,
frame_buffer_format,
queue,
globals_layout,
uniform_buffers_layout,
pipelines,
bitmap_samplers,
msaa_sample_count,
onscreen,
offscreen,
}
}
}

View File

@ -1,4 +1,5 @@
use crate::bitmaps::BitmapSamplers; use crate::bitmaps::BitmapSamplers;
use crate::descriptors::DescriptorsTargetData;
use crate::globals::Globals; use crate::globals::Globals;
use crate::pipelines::Pipelines; use crate::pipelines::Pipelines;
use crate::target::TextureTarget; use crate::target::TextureTarget;
@ -6,6 +7,7 @@ use crate::target::{RenderTarget, RenderTargetFrame, SwapChainTarget};
use crate::uniform_buffer::UniformBuffer; use crate::uniform_buffer::UniformBuffer;
use crate::utils::{create_buffer_with_data, format_list, get_backend_names, BufferDimensions}; use crate::utils::{create_buffer_with_data, format_list, get_backend_names, BufferDimensions};
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use descriptors::Descriptors;
use enum_map::Enum; use enum_map::Enum;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use ruffle_render::backend::{RenderBackend, ShapeHandle, ViewportDimensions}; use ruffle_render::backend::{RenderBackend, ShapeHandle, ViewportDimensions};
@ -37,158 +39,9 @@ mod uniform_buffer;
#[cfg(feature = "clap")] #[cfg(feature = "clap")]
pub mod clap; pub mod clap;
pub mod descriptors;
const DEFAULT_SAMPLE_COUNT: u32 = 4; pub const DEFAULT_SAMPLE_COUNT: u32 = 4;
pub struct Descriptors {
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub info: wgpu::AdapterInfo,
pub limits: wgpu::Limits,
globals_layout: wgpu::BindGroupLayout,
uniform_buffers_layout: wgpu::BindGroupLayout,
bitmap_samplers: BitmapSamplers,
onscreen: DescriptorsTargetData,
offscreen: DescriptorsTargetData,
}
/// Contains data specific to a `RenderTarget`.
/// We cannot re-use this data in `with_offscreen_backend`
pub struct DescriptorsTargetData {
// These fields are specific to our `RenderTarget`, and
// cannot be re-used
surface_format: wgpu::TextureFormat,
frame_buffer_format: wgpu::TextureFormat,
pipelines: Pipelines,
msaa_sample_count: u32,
}
impl DescriptorsTargetData {
fn new(
device: &wgpu::Device,
surface_format: wgpu::TextureFormat,
bitmap_samplers: &BitmapSamplers,
msaa_sample_count: u32,
globals_layout: &wgpu::BindGroupLayout,
uniform_buffers_layout: &wgpu::BindGroupLayout,
) -> Self {
// We want to render directly onto a linear render target to avoid any gamma correction.
// If our surface is sRGB, render to a linear texture and than copy over to the surface.
// Remove Srgb from texture format.
let frame_buffer_format = match surface_format {
wgpu::TextureFormat::Rgba8UnormSrgb => wgpu::TextureFormat::Rgba8Unorm,
wgpu::TextureFormat::Bgra8UnormSrgb => wgpu::TextureFormat::Bgra8Unorm,
wgpu::TextureFormat::Bc1RgbaUnormSrgb => wgpu::TextureFormat::Bc1RgbaUnorm,
wgpu::TextureFormat::Bc2RgbaUnormSrgb => wgpu::TextureFormat::Bc2RgbaUnorm,
wgpu::TextureFormat::Bc3RgbaUnormSrgb => wgpu::TextureFormat::Bc3RgbaUnorm,
wgpu::TextureFormat::Bc7RgbaUnormSrgb => wgpu::TextureFormat::Bc7RgbaUnorm,
wgpu::TextureFormat::Etc2Rgb8UnormSrgb => wgpu::TextureFormat::Etc2Rgb8Unorm,
wgpu::TextureFormat::Etc2Rgb8A1UnormSrgb => wgpu::TextureFormat::Etc2Rgb8A1Unorm,
wgpu::TextureFormat::Etc2Rgba8UnormSrgb => wgpu::TextureFormat::Etc2Rgba8Unorm,
wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::UnormSrgb,
} => wgpu::TextureFormat::Astc {
block,
channel: wgpu::AstcChannel::Unorm,
},
_ => surface_format,
};
let pipelines = Pipelines::new(
&device,
surface_format,
frame_buffer_format,
msaa_sample_count,
bitmap_samplers.layout(),
globals_layout,
uniform_buffers_layout,
);
DescriptorsTargetData {
surface_format,
frame_buffer_format,
pipelines,
msaa_sample_count,
}
}
}
impl Descriptors {
pub fn new(
device: wgpu::Device,
queue: wgpu::Queue,
info: wgpu::AdapterInfo,
surface_format: wgpu::TextureFormat,
msaa_sample_count: u32,
) -> Self {
let limits = device.limits();
let bitmap_samplers = BitmapSamplers::new(&device);
let globals_layout_label = create_debug_label!("Globals bind group layout");
let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: globals_layout_label.as_deref(),
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
});
let uniform_buffer_layout_label = create_debug_label!("Uniform buffer bind group layout");
let uniform_buffers_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: true,
min_binding_size: None,
},
count: None,
}],
label: uniform_buffer_layout_label.as_deref(),
});
let onscreen = DescriptorsTargetData::new(
&device,
surface_format,
&bitmap_samplers,
msaa_sample_count,
&globals_layout,
&uniform_buffers_layout,
);
// FIXME - get MSAA working for `TextureTarget`
let offscreen = DescriptorsTargetData::new(
&device,
wgpu::TextureFormat::Rgba8Unorm,
&bitmap_samplers,
1,
&globals_layout,
&uniform_buffers_layout,
);
Self {
device,
queue,
info,
limits,
bitmap_samplers,
globals_layout,
uniform_buffers_layout,
onscreen,
offscreen,
}
}
}
pub struct WgpuRenderBackend<T: RenderTarget> { pub struct WgpuRenderBackend<T: RenderTarget> {
descriptors: Arc<Descriptors>, descriptors: Arc<Descriptors>,