wgpu: Store quality, not sample_count, and calculate the correct sample count per format
This commit is contained in:
parent
b95983b492
commit
1cb3ea7bf9
|
@ -4241,6 +4241,7 @@ dependencies = [
|
|||
"regex",
|
||||
"ruffle_core",
|
||||
"ruffle_input_format",
|
||||
"ruffle_render",
|
||||
"ruffle_render_wgpu",
|
||||
"serde",
|
||||
"toml",
|
||||
|
|
|
@ -114,7 +114,7 @@ fn take_screenshot(
|
|||
.map_err(|e| anyhow!(e.to_string()))?;
|
||||
let player = PlayerBuilder::new()
|
||||
.with_renderer(
|
||||
WgpuRenderBackend::new(descriptors, target, 4).map_err(|e| anyhow!(e.to_string()))?,
|
||||
WgpuRenderBackend::new(descriptors, target).map_err(|e| anyhow!(e.to_string()))?,
|
||||
)
|
||||
.with_movie(movie)
|
||||
.with_viewport_dimensions(width, height, size.scale)
|
||||
|
|
|
@ -47,10 +47,7 @@ pub struct WgpuRenderBackend<T: RenderTarget> {
|
|||
|
||||
impl WgpuRenderBackend<SwapChainTarget> {
|
||||
#[cfg(target_family = "wasm")]
|
||||
pub async fn for_canvas(
|
||||
canvas: &web_sys::HtmlCanvasElement,
|
||||
sample_count: u32,
|
||||
) -> Result<Self, Error> {
|
||||
pub async fn for_canvas(canvas: &web_sys::HtmlCanvasElement) -> Result<Self, Error> {
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||
backends: wgpu::Backends::BROWSER_WEBGPU | wgpu::Backends::GL,
|
||||
dx12_shader_compiler: wgpu::Dx12Compiler::default(),
|
||||
|
@ -67,7 +64,7 @@ impl WgpuRenderBackend<SwapChainTarget> {
|
|||
let descriptors = Descriptors::new(adapter, device, queue);
|
||||
let target =
|
||||
SwapChainTarget::new(surface, &descriptors.adapter, (1, 1), &descriptors.device);
|
||||
Self::new(Arc::new(descriptors), target, sample_count)
|
||||
Self::new(Arc::new(descriptors), target)
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
|
@ -100,7 +97,7 @@ impl WgpuRenderBackend<SwapChainTarget> {
|
|||
))?;
|
||||
let descriptors = Descriptors::new(adapter, device, queue);
|
||||
let target = SwapChainTarget::new(surface, &descriptors.adapter, size, &descriptors.device);
|
||||
Self::new(Arc::new(descriptors), target, 4)
|
||||
Self::new(Arc::new(descriptors), target)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +128,7 @@ impl WgpuRenderBackend<crate::target::TextureTarget> {
|
|||
))?;
|
||||
let descriptors = Descriptors::new(adapter, device, queue);
|
||||
let target = crate::target::TextureTarget::new(&descriptors.device, size)?;
|
||||
Self::new(Arc::new(descriptors), target, 4)
|
||||
Self::new(Arc::new(descriptors), target)
|
||||
}
|
||||
|
||||
pub fn capture_frame(&self, premultiplied_alpha: bool) -> Option<image::RgbaImage> {
|
||||
|
@ -152,11 +149,7 @@ impl WgpuRenderBackend<crate::target::TextureTarget> {
|
|||
}
|
||||
|
||||
impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||
pub fn new(
|
||||
descriptors: Arc<Descriptors>,
|
||||
target: T,
|
||||
preferred_sample_count: u32,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn new(descriptors: Arc<Descriptors>, target: T) -> Result<Self, Error> {
|
||||
if target.width() > descriptors.limits.max_texture_dimension_2d
|
||||
|| target.height() > descriptors.limits.max_texture_dimension_2d
|
||||
{
|
||||
|
@ -171,7 +164,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
|||
|
||||
let surface = Surface::new(
|
||||
&descriptors,
|
||||
preferred_sample_count,
|
||||
StageQuality::Low,
|
||||
target.width(),
|
||||
target.height(),
|
||||
target.format(),
|
||||
|
@ -319,7 +312,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
self.surface = Surface::new(
|
||||
&self.descriptors,
|
||||
self.surface.sample_count(),
|
||||
self.surface.quality(),
|
||||
width,
|
||||
height,
|
||||
self.target.format(),
|
||||
|
@ -400,6 +393,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
result.push(format!("Enabled features: {enabled_features:?}"));
|
||||
result.push(format!("Available features: {available_features:?}"));
|
||||
result.push(format!("Current limits: {current_limits:?}"));
|
||||
result.push(format!("Surface quality: {}", self.surface.quality()));
|
||||
result.push(format!("Surface samples: {}", self.surface.sample_count()));
|
||||
result.push(format!("Surface size: {:?}", self.surface.size()));
|
||||
|
||||
|
@ -409,7 +403,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
fn set_quality(&mut self, quality: StageQuality) {
|
||||
self.surface = Surface::new(
|
||||
&self.descriptors,
|
||||
quality.sample_count(),
|
||||
quality,
|
||||
self.surface.size().width,
|
||||
self.surface.size().height,
|
||||
self.target.format(),
|
||||
|
@ -630,7 +624,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
let mut surface = Surface::new(
|
||||
&self.descriptors,
|
||||
self.surface.sample_count(),
|
||||
self.surface.quality(),
|
||||
width,
|
||||
height,
|
||||
wgpu::TextureFormat::Rgba8Unorm,
|
||||
|
@ -701,7 +695,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
.expect("TextureTargetFrame.get_next_texture is infallible");
|
||||
let surface = Surface::new(
|
||||
&self.descriptors,
|
||||
self.preferred_sample_count,
|
||||
self.surface.quality(),
|
||||
dest_texture.width,
|
||||
dest_texture.height,
|
||||
wgpu::TextureFormat::Rgba8Unorm,
|
||||
|
|
|
@ -6,13 +6,14 @@ use crate::buffer_pool::TexturePool;
|
|||
use crate::mesh::Mesh;
|
||||
use crate::surface::commands::{chunk_blends, Chunk, CommandRenderer};
|
||||
use crate::uniform_buffer::BufferStorage;
|
||||
use crate::utils::remove_srgb;
|
||||
use crate::utils::{remove_srgb, supported_sample_count};
|
||||
use crate::{
|
||||
ColorAdjustments, Descriptors, MaskState, Pipelines, PushConstants, Texture, TextureTransforms,
|
||||
Transforms, UniformBuffer, DEFAULT_COLOR_ADJUSTMENTS,
|
||||
};
|
||||
use ruffle_render::commands::CommandList;
|
||||
use ruffle_render::filters::{BlurFilter, ColorMatrixFilter, Filter};
|
||||
use ruffle_render::quality::StageQuality;
|
||||
use std::sync::Arc;
|
||||
use target::CommandTarget;
|
||||
use tracing::instrument;
|
||||
|
@ -21,6 +22,7 @@ use wgpu::util::DeviceExt;
|
|||
#[derive(Debug)]
|
||||
pub struct Surface {
|
||||
size: wgpu::Extent3d,
|
||||
quality: StageQuality,
|
||||
sample_count: u32,
|
||||
pipelines: Arc<Pipelines>,
|
||||
format: wgpu::TextureFormat,
|
||||
|
@ -30,7 +32,7 @@ pub struct Surface {
|
|||
impl Surface {
|
||||
pub fn new(
|
||||
descriptors: &Descriptors,
|
||||
sample_count: u32,
|
||||
quality: StageQuality,
|
||||
width: u32,
|
||||
height: u32,
|
||||
surface_format: wgpu::TextureFormat,
|
||||
|
@ -42,9 +44,11 @@ impl Surface {
|
|||
};
|
||||
let frame_buffer_format = remove_srgb(surface_format);
|
||||
|
||||
let sample_count = supported_sample_count(quality, frame_buffer_format);
|
||||
let pipelines = descriptors.pipelines(sample_count, frame_buffer_format);
|
||||
Self {
|
||||
size,
|
||||
quality,
|
||||
sample_count,
|
||||
pipelines,
|
||||
format: frame_buffer_format,
|
||||
|
@ -219,7 +223,7 @@ impl Surface {
|
|||
uniform_encoder,
|
||||
draw_encoder,
|
||||
meshes,
|
||||
target.sample_count(),
|
||||
self.quality,
|
||||
target.width(),
|
||||
target.height(),
|
||||
nearest_layer.unwrap_or(&target),
|
||||
|
@ -395,6 +399,10 @@ impl Surface {
|
|||
target
|
||||
}
|
||||
|
||||
pub fn quality(&self) -> StageQuality {
|
||||
self.quality
|
||||
}
|
||||
|
||||
pub fn sample_count(&self) -> u32 {
|
||||
self.sample_count
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ use ruffle_render::bitmap::BitmapHandle;
|
|||
use ruffle_render::color_transform::ColorTransform;
|
||||
use ruffle_render::commands::Command;
|
||||
use ruffle_render::matrix::Matrix;
|
||||
use ruffle_render::quality::StageQuality;
|
||||
use ruffle_render::tessellator::GradientType;
|
||||
use ruffle_render::transform::Transform;
|
||||
use swf::{BlendMode, Color, Fixed8, GradientSpread};
|
||||
|
@ -449,7 +450,7 @@ pub fn chunk_blends<'a>(
|
|||
uniform_encoder: &mut wgpu::CommandEncoder,
|
||||
draw_encoder: &mut wgpu::CommandEncoder,
|
||||
meshes: &'a Vec<Mesh>,
|
||||
sample_count: u32,
|
||||
quality: StageQuality,
|
||||
width: u32,
|
||||
height: u32,
|
||||
nearest_layer: &CommandTarget,
|
||||
|
@ -465,7 +466,7 @@ pub fn chunk_blends<'a>(
|
|||
Command::Blend(commands, blend_mode) => {
|
||||
let mut surface = Surface::new(
|
||||
&descriptors,
|
||||
sample_count,
|
||||
quality,
|
||||
width,
|
||||
height,
|
||||
wgpu::TextureFormat::Rgba8Unorm,
|
||||
|
|
|
@ -206,10 +206,6 @@ impl CommandTarget {
|
|||
self.size.height
|
||||
}
|
||||
|
||||
pub fn sample_count(&self) -> u32 {
|
||||
self.sample_count
|
||||
}
|
||||
|
||||
pub fn ensure_cleared(&self, encoder: &mut wgpu::CommandEncoder) {
|
||||
if self.color_needs_clear.get().is_some() {
|
||||
return;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use ruffle_render::quality::StageQuality;
|
||||
use ruffle_render::utils::unmultiply_alpha_rgba;
|
||||
use std::borrow::Cow;
|
||||
use std::mem::size_of;
|
||||
|
@ -155,3 +156,16 @@ pub fn buffer_to_image(
|
|||
buffer.unmap();
|
||||
image
|
||||
}
|
||||
|
||||
pub fn supported_sample_count(quality: StageQuality, format: wgpu::TextureFormat) -> u32 {
|
||||
let mut sample_count = quality.sample_count();
|
||||
let features = format.describe().guaranteed_format_features.flags;
|
||||
|
||||
// Keep halving the sample count until we get one that's supported - or 1 (no multisampling)
|
||||
// It's not guaranteed that supporting 4x means supporting 2x, so there's no "max" option
|
||||
// And it's probably safer to round down than up, given it's a performance setting.
|
||||
while sample_count > 1 && !features.sample_count_supported(sample_count) {
|
||||
sample_count /= 2;
|
||||
}
|
||||
sample_count
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ version.workspace = true
|
|||
futures = "0.3.25"
|
||||
ruffle_core = { path = "../core", features = ["deterministic", "timeline_debug", "avm_debug"] }
|
||||
ruffle_render_wgpu = { path = "../render/wgpu" }
|
||||
ruffle_render = { path = "../render" }
|
||||
ruffle_input_format = { path = "input-format" }
|
||||
image = { version = "0.24.5", default-features = false, features = ["png"] }
|
||||
regex = "1.7.1"
|
||||
|
|
|
@ -4,6 +4,8 @@ use approx::assert_relative_eq;
|
|||
use regex::Regex;
|
||||
use ruffle_core::tag_utils::SwfMovie;
|
||||
use ruffle_core::{PlayerBuilder, ViewportDimensions};
|
||||
use ruffle_render::backend::RenderBackend;
|
||||
use ruffle_render::quality::StageQuality;
|
||||
use serde::Deserialize;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -118,10 +120,15 @@ impl PlayerOptions {
|
|||
let target = TextureTarget::new(&descriptors.device, (width, height))
|
||||
.map_err(|e| anyhow!(e.to_string()))?;
|
||||
|
||||
player_builder = player_builder.with_renderer(
|
||||
WgpuRenderBackend::new(descriptors, target, render_options.sample_count)
|
||||
.map_err(|e| anyhow!(e.to_string()))?,
|
||||
);
|
||||
let mut backend = WgpuRenderBackend::new(descriptors, target)
|
||||
.map_err(|e| anyhow!(e.to_string()))?;
|
||||
backend.set_quality(match render_options.sample_count {
|
||||
8 => StageQuality::High,
|
||||
4 => StageQuality::High,
|
||||
2 => StageQuality::Medium,
|
||||
_ => StageQuality::Low,
|
||||
});
|
||||
player_builder = player_builder.with_renderer(backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue