render/wgpu: Switch to pipeline-overridable constant for bitmap saturation order toggle

Also call it `late_saturate` instead, to avoid the confusing negation
between the constant name and the (now removed) shader module name.
This commit is contained in:
TÖRÖK Attila 2024-05-17 09:38:37 +02:00
parent 45a7cbbc81
commit 9522acf61d
3 changed files with 22 additions and 22 deletions

View File

@ -10,6 +10,7 @@ struct VertexOutput {
@group(2) @binding(0) var<uniform> textureTransforms: common__TextureTransforms;
@group(2) @binding(1) var texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
override late_saturate: bool = false;
@vertex
fn main_vertex(in: common__VertexInput) -> VertexOutput {
@ -27,13 +28,11 @@ fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
if( color.a > 0.0 ) {
color = vec4<f32>(color.rgb / color.a, color.a);
color = color * transforms.mult_color + transforms.add_color;
// NOTE: `#EARLY_SATURATE#` is replaced with a boolean value at compile time.
// TODO: Switch to pipeline constants once `wgpu` is updated to `0.20`.
if (#EARLY_SATURATE# == true) {
if (!late_saturate) {
color = saturate(color);
}
color = vec4<f32>(color.rgb * color.a, color.a);
if (#EARLY_SATURATE# == false) {
if (late_saturate) {
color = saturate(color);
}
}

View File

@ -3,6 +3,7 @@ use crate::layouts::BindLayouts;
use crate::shaders::Shaders;
use crate::{MaskState, PosColorVertex, PosVertex};
use enum_map::{enum_map, Enum, EnumMap};
use std::collections::HashMap;
use wgpu::{vertex_attr_array, BlendState};
pub const VERTEX_BUFFERS_DESCRIPTION_POS: [wgpu::VertexBufferLayout; 1] =
@ -175,8 +176,8 @@ impl Pipelines {
let bitmap_opaque = device.create_render_pipeline(&create_pipeline_descriptor(
create_debug_label!("Bitmap opaque copy").as_deref(),
&shaders.bitmap_late_saturate_shader,
&shaders.bitmap_late_saturate_shader,
&shaders.bitmap_shader,
&shaders.bitmap_shader,
&bitmap_opaque_pipeline_layout,
None,
&[Some(wgpu::ColorTargetState {
@ -186,6 +187,7 @@ impl Pipelines {
})],
&VERTEX_BUFFERS_DESCRIPTION_POS,
msaa_sample_count,
&[("late_saturate".to_owned(), 1.0)].into(),
));
let bitmap_opaque_dummy_depth = device.create_render_pipeline(&create_pipeline_descriptor(
@ -212,6 +214,7 @@ impl Pipelines {
})],
&VERTEX_BUFFERS_DESCRIPTION_POS,
msaa_sample_count,
&Default::default(),
));
Self {
@ -235,6 +238,7 @@ fn create_pipeline_descriptor<'a>(
color_target_state: &'a [Option<wgpu::ColorTargetState>],
vertex_buffer_layout: &'a [wgpu::VertexBufferLayout<'a>],
msaa_sample_count: u32,
fragment_constants: &'a HashMap<String, f64>,
) -> wgpu::RenderPipelineDescriptor<'a> {
wgpu::RenderPipelineDescriptor {
label,
@ -249,7 +253,10 @@ fn create_pipeline_descriptor<'a>(
module: fragment_shader,
entry_point: "main_fragment",
targets: color_target_state,
compilation_options: Default::default(),
compilation_options: wgpu::PipelineCompilationOptions {
constants: fragment_constants,
..Default::default()
},
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
@ -314,6 +321,7 @@ fn create_shape_pipeline(
})],
vertex_buffers_layout,
msaa_sample_count,
&Default::default(),
))
};
@ -331,6 +339,7 @@ fn create_shape_pipeline(
})],
vertex_buffers_layout,
msaa_sample_count,
&Default::default(),
)),
|mask_state| match mask_state {
MaskState::NoMask => mask_render_state(

View File

@ -5,14 +5,13 @@ use ruffle_render::shader_source::SHADER_FILTER_COMMON;
#[derive(Debug)]
pub struct Shaders {
pub color_shader: wgpu::ShaderModule,
/// This has a pipeline-overridable `bool` constant, `late_saturate`,
/// with a default of `false`. It switches to performing saturation
/// after re-multiplying the alpha, rather than before. This is used
/// for the Stage3D `bitmap_opaque` pipeline, which needs to be able to
/// avoid changing initially-in-range rgb values (regadless of whether
/// dividing by the alpha value would produce an out-of-range value).
pub bitmap_shader: wgpu::ShaderModule,
/// Like `bitmap_shader` but performs saturation after we've
/// re-multiplied the alpha. This is used for the Stage3D
/// `bitmap_opaque` pipeline, which needs to able to
/// avoid changing initially-in-range rgb values (regadless
/// of whether dividing by the alpha value would produce
/// an out-of-range value).
pub bitmap_late_saturate_shader: wgpu::ShaderModule,
pub gradient_shader: wgpu::ShaderModule,
pub copy_srgb_shader: wgpu::ShaderModule,
pub copy_shader: wgpu::ShaderModule,
@ -27,16 +26,10 @@ pub struct Shaders {
impl Shaders {
pub fn new(device: &wgpu::Device) -> Self {
let color_shader = make_shader(device, "color.wgsl", include_str!("../shaders/color.wgsl"));
let bitmap = include_str!("../shaders/bitmap.wgsl");
let bitmap_shader = make_shader(
device,
"bitmap.wgsl",
&bitmap.replace("#EARLY_SATURATE#", "true"),
);
let bitmap_late_saturate_shader = make_shader(
device,
"bitmap.wgsl",
&bitmap.replace("#EARLY_SATURATE#", "false"),
include_str!("../shaders/bitmap.wgsl"),
);
let copy_srgb_shader = make_shader(
device,
@ -90,7 +83,6 @@ impl Shaders {
Self {
color_shader,
bitmap_shader,
bitmap_late_saturate_shader,
gradient_shader,
copy_srgb_shader,
copy_shader,