From dd0ac124d86d2c9f3ad8d79e7e07cbf52cfb0058 Mon Sep 17 00:00:00 2001 From: Sebastian K Date: Tue, 21 Jul 2020 19:56:47 +0300 Subject: [PATCH] Add ColorMatrix filter --- color/src/lib.rs | 2 + color/src/matrix.rs | 126 ++++++++++++ content/src/effects.rs | 8 +- renderer/src/gpu/renderer.rs | 36 +++- resources/shaders/gl3/d3d9/tile.fs.glsl | 37 +++- resources/shaders/gl3/d3d9/tile.vs.glsl | 14 +- resources/shaders/gl4/d3d11/tile.cs.glsl | 49 ++++- resources/shaders/gl4/d3d9/tile.fs.glsl | 37 +++- resources/shaders/gl4/d3d9/tile.vs.glsl | 14 +- resources/shaders/metal/d3d11/tile.cs.metal | 208 ++++++++++++-------- resources/shaders/metal/d3d9/tile.fs.metal | 160 ++++++++------- resources/shaders/metal/d3d9/tile.vs.metal | 42 ++-- shaders/d3d11/tile.cs.glsl | 6 +- shaders/d3d9/tile.fs.glsl | 4 + shaders/d3d9/tile.vs.glsl | 4 + shaders/tile_fragment.inc.glsl | 33 +++- shaders/tile_vertex.inc.glsl | 10 +- 17 files changed, 596 insertions(+), 194 deletions(-) create mode 100644 color/src/matrix.rs diff --git a/color/src/lib.rs b/color/src/lib.rs index dd3be280..a104f644 100644 --- a/color/src/lib.rs +++ b/color/src/lib.rs @@ -13,6 +13,8 @@ use std::f32::consts::PI; use std::fmt::{self, Debug, Formatter}; use std::slice; +pub mod matrix; + // TODO(pcwalton): Maybe this should be a u32? Need to be aware of endianness issues if we do that. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[repr(C)] diff --git a/color/src/matrix.rs b/color/src/matrix.rs new file mode 100644 index 00000000..ed5d197a --- /dev/null +++ b/color/src/matrix.rs @@ -0,0 +1,126 @@ +// pathfinder/color/src/lib.rs +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use pathfinder_simd::default::F32x4; +use std::ops::{Add, Mul, Deref}; + +/// ColorMatrix filter/transformation +/// +/// The entries are stored in 5 columns of F32x4, each containing a row. +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct ColorMatrix(pub [F32x4; 5]); + +impl ColorMatrix { + #[inline] + pub fn from_rows(rows: [[f32; 5]; 4]) -> ColorMatrix { + ColorMatrix([ + F32x4::new(rows[0][0], rows[1][0], rows[2][0], rows[3][0]), + F32x4::new(rows[0][1], rows[1][1], rows[2][1], rows[3][1]), + F32x4::new(rows[0][2], rows[1][2], rows[2][2], rows[3][2]), + F32x4::new(rows[0][3], rows[1][3], rows[2][3], rows[3][3]), + F32x4::new(rows[0][4], rows[1][4], rows[2][4], rows[3][4]), + ]) + } + + /// Creates a hue-rotate color matrix filter from the given angle in radians. + /// + /// See the `hueRotate` attribute of the `feColorMatrix` element in the SVG specification. + pub fn hue_rotate(angle: f32) -> ColorMatrix { + let a = ColorMatrix::from_rows([ + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 1.0, 0.0], + ]); + let b = ColorMatrix::from_rows([ + [ 0.787, -0.715, -0.072, 0.0, 0.0], + [-0.213, 0.285, -0.072, 0.0, 0.0], + [-0.213, -0.715, 0.928, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 0.0, 0.0], + ]); + let c = ColorMatrix::from_rows([ + [-0.213, -0.715, 0.928, 0.0, 0.0], + [ 0.143, 0.140, -0.283, 0.0, 0.0], + [-0.787, 0.715, 0.072, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 0.0, 0.0], + ]); + a + b * angle.cos() + c * angle.sin() + } + + /// Creates a saturate color matrix filter with the given factor between 0 and 1. + /// + /// See the `saturate` attribute of the `feColorMatrix` element in the SVG specification. + pub fn saturate(saturation: f32) -> ColorMatrix { + let a = ColorMatrix::from_rows([ + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.213, 0.715, 0.072, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 1.0, 0.0], + ]); + let b = ColorMatrix::from_rows([ + [ 0.787, -0.715, -0.072, 0.0, 0.0], + [-0.213, 0.285, -0.072, 0.0, 0.0], + [-0.213, -0.715, 0.928, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 0.0, 0.0], + ]); + a + b * saturation + } + + /// Creates a luminance-to-alpha color matrix filter. + /// + /// See the `luminanceToAlpha` attribute of the `feColorMatrix` element in the SVG + /// specification. + pub fn luminance_to_alpha() -> ColorMatrix { + ColorMatrix::from_rows([ + [ 0.0, 0.0, 0.0, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 0.0, 0.0], + [ 0.0, 0.0, 0.0, 0.0, 0.0], + [ 0.2125, 0.7154, 0.0721, 0.0, 0.0], + ]) + } +} +impl Deref for ColorMatrix { + type Target = [F32x4; 5]; + + #[inline] + fn deref(&self) -> &[F32x4; 5] { + &self.0 + } +} +impl Add for ColorMatrix { + type Output = ColorMatrix; + + #[inline] + fn add(self, rhs: ColorMatrix) -> ColorMatrix { + ColorMatrix([ + self[0] + rhs[0], + self[1] + rhs[1], + self[2] + rhs[2], + self[3] + rhs[3], + self[4] + rhs[4], + ]) + } +} + +impl Mul for ColorMatrix { + type Output = ColorMatrix; + + #[inline] + fn mul(self, rhs: f32) -> ColorMatrix { + let rhs = F32x4::splat(rhs); + ColorMatrix([ + self[0] * rhs, + self[1] * rhs, + self[2] * rhs, + self[3] * rhs, + self[4] * rhs, + ]) + } +} diff --git a/content/src/effects.rs b/content/src/effects.rs index 990b9f20..932b4a98 100644 --- a/content/src/effects.rs +++ b/content/src/effects.rs @@ -10,7 +10,7 @@ //! Special effects that can be applied to layers. -use pathfinder_color::ColorF; +use pathfinder_color::{ColorF, matrix::ColorMatrix}; use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::vector::Vector2F; use pathfinder_simd::default::F32x2; @@ -83,6 +83,12 @@ pub enum PatternFilter { direction: BlurDirection, sigma: f32, }, + + /// A color matrix multiplication. + /// + /// The matrix is stored in 5 columns of `F32x4`. See the `feColorMatrix` element in the SVG + /// specification. + ColorMatrix(ColorMatrix), } /// Blend modes that can be applied to individual paths. diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 5f29aa16..dd04505d 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -53,7 +53,7 @@ pub(crate) const MASK_TILES_DOWN: u32 = 256; const SQRT_2_PI_INV: f32 = 0.3989422804014327; const TEXTURE_METADATA_ENTRIES_PER_ROW: i32 = 128; -const TEXTURE_METADATA_TEXTURE_WIDTH: i32 = TEXTURE_METADATA_ENTRIES_PER_ROW * 8; +const TEXTURE_METADATA_TEXTURE_WIDTH: i32 = TEXTURE_METADATA_ENTRIES_PER_ROW * 10; const TEXTURE_METADATA_TEXTURE_HEIGHT: i32 = 65536 / TEXTURE_METADATA_ENTRIES_PER_ROW; // FIXME(pcwalton): Shrink this again! @@ -63,10 +63,11 @@ pub(crate) const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 / 4 * MASK_TI const COMBINER_CTRL_FILTER_RADIAL_GRADIENT: i32 = 0x1; const COMBINER_CTRL_FILTER_TEXT: i32 = 0x2; const COMBINER_CTRL_FILTER_BLUR: i32 = 0x3; +const COMBINER_CTRL_FILTER_COLOR_MATRIX: i32 = 0x4; const COMBINER_CTRL_COLOR_FILTER_SHIFT: i32 = 4; -const COMBINER_CTRL_COLOR_COMBINE_SHIFT: i32 = 6; -const COMBINER_CTRL_COMPOSITE_SHIFT: i32 = 8; +const COMBINER_CTRL_COLOR_COMBINE_SHIFT: i32 = 8; +const COMBINER_CTRL_COMPOSITE_SHIFT: i32 = 10; /// The GPU renderer that processes commands necessary to render a scene. pub struct Renderer where D: Device { @@ -693,11 +694,21 @@ impl Renderer where D: Device { f16::from_f32(filter_params.p2.z()), f16::from_f32(filter_params.p2.w()), // 6 + f16::from_f32(filter_params.p3.x()), + f16::from_f32(filter_params.p3.y()), + f16::from_f32(filter_params.p3.z()), + f16::from_f32(filter_params.p3.w()), + // 7 + f16::from_f32(filter_params.p4.x()), + f16::from_f32(filter_params.p4.y()), + f16::from_f32(filter_params.p4.z()), + f16::from_f32(filter_params.p4.w()), + // 8 f16::from_f32(filter_params.ctrl as f32), f16::default(), f16::default(), f16::default(), - // 7 + // 9 f16::default(), f16::default(), f16::default(), @@ -921,6 +932,8 @@ impl Renderer where D: Device { p0: line.from().0.concat_xy_xy(line.vector().0), p1: radii.concat_xy_xy(uv_origin.0), p2: F32x4::default(), + p3: F32x4::default(), + p4: F32x4::default(), ctrl: ctrl | (COMBINER_CTRL_FILTER_RADIAL_GRADIENT << COMBINER_CTRL_COLOR_FILTER_SHIFT) } @@ -942,6 +955,8 @@ impl Renderer where D: Device { p0: src_offset.0.concat_xy_xy(F32x2::new(support, 0.0)), p1: F32x4::new(gauss_coeff_x, gauss_coeff_y, gauss_coeff_z, 0.0), p2: F32x4::default(), + p3: F32x4::default(), + p4: F32x4::default(), ctrl: ctrl | (COMBINER_CTRL_FILTER_BLUR << COMBINER_CTRL_COLOR_FILTER_SHIFT), } } @@ -961,14 +976,25 @@ impl Renderer where D: Device { }, p1: bg_color.0, p2, + p3: F32x4::default(), + p4: F32x4::default(), ctrl: ctrl | (COMBINER_CTRL_FILTER_TEXT << COMBINER_CTRL_COLOR_FILTER_SHIFT), } } + Filter::PatternFilter(PatternFilter::ColorMatrix(matrix)) => { + let [p0, p1, p2, p3, p4] = matrix.0; + FilterParams { + p0, p1, p2, p3, p4, + ctrl: ctrl | (COMBINER_CTRL_FILTER_COLOR_MATRIX << COMBINER_CTRL_COLOR_FILTER_SHIFT), + } + } Filter::None => { FilterParams { p0: F32x4::default(), p1: F32x4::default(), p2: F32x4::default(), + p3: F32x4::default(), + p4: F32x4::default(), ctrl, } } @@ -1317,6 +1343,8 @@ struct FilterParams { p0: F32x4, p1: F32x4, p2: F32x4, + p3: F32x4, + p4: F32x4, ctrl: i32, } diff --git a/resources/shaders/gl3/d3d9/tile.fs.glsl b/resources/shaders/gl3/d3d9/tile.fs.glsl index 631fd631..ac4d8e9f 100644 --- a/resources/shaders/gl3/d3d9/tile.fs.glsl +++ b/resources/shaders/gl3/d3d9/tile.fs.glsl @@ -94,6 +94,7 @@ precision highp float; + vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ @@ -370,6 +371,18 @@ vec4 filterBlur(vec2 colorTexCoord, return color / gaussSum; } +vec4 filterColorMatrix(vec2 colorTexCoord, + sampler2D colorTexture, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4){ + vec4 srcColor = texture(colorTexture, colorTexCoord); + mat4 colorMatrix = mat4(filterParams0, filterParams1, filterParams2, filterParams3); + return colorMatrix * srcColor + filterParams4; +} + vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ return sampleColor(colorTexture, colorTexCoord); } @@ -383,6 +396,8 @@ vec4 filterColor(vec2 colorTexCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, int colorFilter){ switch(colorFilter){ case 0x1 : @@ -407,6 +422,14 @@ vec4 filterColor(vec2 colorTexCoord, filterParams0, filterParams1, filterParams2); + case 0x4 : + return filterColorMatrix(colorTexCoord, + colorTexture, + filterParams0, + filterParams1, + filterParams2, + filterParams3, + filterParams4); } return filterNone(colorTexCoord, colorTexture); } @@ -569,6 +592,8 @@ vec4 calculateColor(vec2 fragCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, vec2 framebufferSize, int ctrl, vec3 maskTexCoord0, @@ -582,10 +607,10 @@ vec4 calculateColor(vec2 fragCoord, vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& + int color0Combine =(ctrl >> 8)& 0x3; if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; + int color0Filter =(ctrl >> 4)& 0xf; vec4 color0 = filterColor(colorTexCoord0, colorTexture0, gammaLUT, @@ -595,6 +620,8 @@ vec4 calculateColor(vec2 fragCoord, filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -603,7 +630,7 @@ vec4 calculateColor(vec2 fragCoord, color . a *= maskAlpha; - int compositeOp =(ctrl >> 8)& 0xf; + int compositeOp =(ctrl >> 10)& 0xf; color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); @@ -627,6 +654,8 @@ in float vTileCtrl; in vec4 vFilterParams0; in vec4 vFilterParams1; in vec4 vFilterParams2; +in vec4 vFilterParams3; +in vec4 vFilterParams4; in float vCtrl; out vec4 oFragColor; @@ -646,6 +675,8 @@ void main(){ vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, uFramebufferSize, int(vCtrl), vMaskTexCoord0, diff --git a/resources/shaders/gl3/d3d9/tile.vs.glsl b/resources/shaders/gl3/d3d9/tile.vs.glsl index 8257d318..bb1ce9e7 100644 --- a/resources/shaders/gl3/d3d9/tile.vs.glsl +++ b/resources/shaders/gl3/d3d9/tile.vs.glsl @@ -44,21 +44,27 @@ void computeTileVaryings(vec2 position, out vec4 outFilterParams0, out vec4 outFilterParams1, out vec4 outFilterParams2, + out vec4 outFilterParams3, + out vec4 outFilterParams4, out int outCtrl){ vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize); - vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 10, colorEntry / 128); vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); - vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams3 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams4 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 7); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 8); outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra . x); } @@ -84,6 +90,8 @@ out float vTileCtrl; out vec4 vFilterParams0; out vec4 vFilterParams1; out vec4 vFilterParams2; +out vec4 vFilterParams3; +out vec4 vFilterParams4; out float vCtrl; void main(){ @@ -113,6 +121,8 @@ void main(){ vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, ctrl); vTileCtrl = float(aCtrlBackdrop . x); diff --git a/resources/shaders/gl4/d3d11/tile.cs.glsl b/resources/shaders/gl4/d3d11/tile.cs.glsl index 4bc2169f..c243eb71 100644 --- a/resources/shaders/gl4/d3d11/tile.cs.glsl +++ b/resources/shaders/gl4/d3d11/tile.cs.glsl @@ -96,6 +96,7 @@ layout(local_size_x = 16, local_size_y = 4)in; + vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ @@ -372,6 +373,18 @@ vec4 filterBlur(vec2 colorTexCoord, return color / gaussSum; } +vec4 filterColorMatrix(vec2 colorTexCoord, + sampler2D colorTexture, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4){ + vec4 srcColor = texture(colorTexture, colorTexCoord); + mat4 colorMatrix = mat4(filterParams0, filterParams1, filterParams2, filterParams3); + return colorMatrix * srcColor + filterParams4; +} + vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ return sampleColor(colorTexture, colorTexCoord); } @@ -385,6 +398,8 @@ vec4 filterColor(vec2 colorTexCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, int colorFilter){ switch(colorFilter){ case 0x1 : @@ -409,6 +424,14 @@ vec4 filterColor(vec2 colorTexCoord, filterParams0, filterParams1, filterParams2); + case 0x4 : + return filterColorMatrix(colorTexCoord, + colorTexture, + filterParams0, + filterParams1, + filterParams2, + filterParams3, + filterParams4); } return filterNone(colorTexCoord, colorTexture); } @@ -571,6 +594,8 @@ vec4 calculateColor(vec2 fragCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, vec2 framebufferSize, int ctrl, vec3 maskTexCoord0, @@ -584,10 +609,10 @@ vec4 calculateColor(vec2 fragCoord, vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& + int color0Combine =(ctrl >> 8)& 0x3; if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; + int color0Filter =(ctrl >> 4)& 0xf; vec4 color0 = filterColor(colorTexCoord0, colorTexture0, gammaLUT, @@ -597,6 +622,8 @@ vec4 calculateColor(vec2 fragCoord, filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -605,7 +632,7 @@ vec4 calculateColor(vec2 fragCoord, color . a *= maskAlpha; - int compositeOp =(ctrl >> 8)& 0xf; + int compositeOp =(ctrl >> 10)& 0xf; color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); @@ -637,21 +664,27 @@ void computeTileVaryings(vec2 position, out vec4 outFilterParams0, out vec4 outFilterParams1, out vec4 outFilterParams2, + out vec4 outFilterParams3, + out vec4 outFilterParams4, out int outCtrl){ vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize); - vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 10, colorEntry / 128); vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); - vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams3 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams4 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 7); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 8); outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra . x); } @@ -748,7 +781,7 @@ void main(){ vec3 maskTexCoord0 = vec3(vec2(ivec2(maskTileCoord)+ tileSubCoord), backdrop); vec2 colorTexCoord0; - vec4 baseColor, filterParams0, filterParams1, filterParams2; + vec4 baseColor, filterParams0, filterParams1, filterParams2, filterParams3, filterParams4; int ctrl; computeTileVaryings(fragCoord, int(colorEntry), @@ -759,6 +792,8 @@ void main(){ filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, ctrl); @@ -774,6 +809,8 @@ void main(){ filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, uFramebufferSize, ctrl, maskTexCoord0, diff --git a/resources/shaders/gl4/d3d9/tile.fs.glsl b/resources/shaders/gl4/d3d9/tile.fs.glsl index 631fd631..ac4d8e9f 100644 --- a/resources/shaders/gl4/d3d9/tile.fs.glsl +++ b/resources/shaders/gl4/d3d9/tile.fs.glsl @@ -94,6 +94,7 @@ precision highp float; + vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ @@ -370,6 +371,18 @@ vec4 filterBlur(vec2 colorTexCoord, return color / gaussSum; } +vec4 filterColorMatrix(vec2 colorTexCoord, + sampler2D colorTexture, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4){ + vec4 srcColor = texture(colorTexture, colorTexCoord); + mat4 colorMatrix = mat4(filterParams0, filterParams1, filterParams2, filterParams3); + return colorMatrix * srcColor + filterParams4; +} + vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ return sampleColor(colorTexture, colorTexCoord); } @@ -383,6 +396,8 @@ vec4 filterColor(vec2 colorTexCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, int colorFilter){ switch(colorFilter){ case 0x1 : @@ -407,6 +422,14 @@ vec4 filterColor(vec2 colorTexCoord, filterParams0, filterParams1, filterParams2); + case 0x4 : + return filterColorMatrix(colorTexCoord, + colorTexture, + filterParams0, + filterParams1, + filterParams2, + filterParams3, + filterParams4); } return filterNone(colorTexCoord, colorTexture); } @@ -569,6 +592,8 @@ vec4 calculateColor(vec2 fragCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, vec2 framebufferSize, int ctrl, vec3 maskTexCoord0, @@ -582,10 +607,10 @@ vec4 calculateColor(vec2 fragCoord, vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& + int color0Combine =(ctrl >> 8)& 0x3; if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; + int color0Filter =(ctrl >> 4)& 0xf; vec4 color0 = filterColor(colorTexCoord0, colorTexture0, gammaLUT, @@ -595,6 +620,8 @@ vec4 calculateColor(vec2 fragCoord, filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -603,7 +630,7 @@ vec4 calculateColor(vec2 fragCoord, color . a *= maskAlpha; - int compositeOp =(ctrl >> 8)& 0xf; + int compositeOp =(ctrl >> 10)& 0xf; color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); @@ -627,6 +654,8 @@ in float vTileCtrl; in vec4 vFilterParams0; in vec4 vFilterParams1; in vec4 vFilterParams2; +in vec4 vFilterParams3; +in vec4 vFilterParams4; in float vCtrl; out vec4 oFragColor; @@ -646,6 +675,8 @@ void main(){ vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, uFramebufferSize, int(vCtrl), vMaskTexCoord0, diff --git a/resources/shaders/gl4/d3d9/tile.vs.glsl b/resources/shaders/gl4/d3d9/tile.vs.glsl index 8257d318..bb1ce9e7 100644 --- a/resources/shaders/gl4/d3d9/tile.vs.glsl +++ b/resources/shaders/gl4/d3d9/tile.vs.glsl @@ -44,21 +44,27 @@ void computeTileVaryings(vec2 position, out vec4 outFilterParams0, out vec4 outFilterParams1, out vec4 outFilterParams2, + out vec4 outFilterParams3, + out vec4 outFilterParams4, out int outCtrl){ vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize); - vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 10, colorEntry / 128); vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); - vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams3 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams4 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 7); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 8); outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra . x); } @@ -84,6 +90,8 @@ out float vTileCtrl; out vec4 vFilterParams0; out vec4 vFilterParams1; out vec4 vFilterParams2; +out vec4 vFilterParams3; +out vec4 vFilterParams4; out float vCtrl; void main(){ @@ -113,6 +121,8 @@ void main(){ vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, ctrl); vTileCtrl = float(aCtrlBackdrop . x); diff --git a/resources/shaders/metal/d3d11/tile.cs.metal b/resources/shaders/metal/d3d11/tile.cs.metal index d355e756..2ea730e2 100644 --- a/resources/shaders/metal/d3d11/tile.cs.metal +++ b/resources/shaders/metal/d3d11/tile.cs.metal @@ -18,7 +18,7 @@ struct bTiles constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(16u, 4u, 1u); -constant float3 _1081 = {}; +constant float3 _1151 = {}; // Implementation of the GLSL mod() function, which is slightly different than Metal fmod() template @@ -40,10 +40,10 @@ float4 fetchUnscaled(thread const texture2d srcTexture, thread const samp } static inline __attribute__((always_inline)) -void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread int& outCtrl) +void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread float4& outFilterParams3, thread float4& outFilterParams4, thread int& outCtrl) { float2 metadataScale = float2(1.0) / float2(textureMetadataSize); - float2 metadataEntryCoord = float2(float((colorEntry % 128) * 8), float(colorEntry / 128)); + float2 metadataEntryCoord = float2(float((colorEntry % 128) * 10), float(colorEntry / 128)); float2 param = metadataScale; float2 param_1 = metadataEntryCoord; int param_2 = 0; @@ -71,12 +71,22 @@ void computeTileVaryings(thread const float2& position, thread const int& colorE float2 param_18 = metadataScale; float2 param_19 = metadataEntryCoord; int param_20 = 6; - float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20); + float4 filterParams3 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20); + float2 param_21 = metadataScale; + float2 param_22 = metadataEntryCoord; + int param_23 = 7; + float4 filterParams4 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_21, param_22, param_23); + float2 param_24 = metadataScale; + float2 param_25 = metadataEntryCoord; + int param_26 = 8; + float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_24, param_25, param_26); outColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra.x); } @@ -123,16 +133,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex { ts = ts.yx; } - float _595; + float _611; if (ts.x >= 0.0) { - _595 = ts.x; + _611 = ts.x; } else { - _595 = ts.y; + _611 = ts.y; } - float t = _595; + float t = _611; color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(t, 0.0)), level(0.0)); } return color; @@ -146,19 +156,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel) { bool wide = kernel0.x > 0.0; - float _276; + float _292; if (wide) { float param = (-4.0) * onePixel; float2 param_1 = colorTexCoord; - _276 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); + _292 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); } else { - _276 = 0.0; + _292 = 0.0; } float param_2 = (-3.0) * onePixel; float2 param_3 = colorTexCoord; @@ -190,7 +200,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_5 = colorTexCoord; float param_6 = (-1.0) * onePixel; float2 param_7 = colorTexCoord; - outAlphaLeft = float4(_276, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); + outAlphaLeft = float4(_292, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); float param_8 = 0.0; float2 param_9 = colorTexCoord; outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9); @@ -200,18 +210,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_13 = colorTexCoord; float param_14 = 3.0 * onePixel; float2 param_15 = colorTexCoord; - float _336; + float _352; if (wide) { float param_16 = 4.0 * onePixel; float2 param_17 = colorTexCoord; - _336 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); + _352 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); } else { - _336 = 0.0; + _352 = 0.0; } - outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _336); + outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _352); } static inline __attribute__((always_inline)) @@ -285,6 +295,14 @@ float4 filterText(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4) +{ + float4 srcColor = colorTexture.sample(colorTextureSmplr, colorTexCoord, level(0.0)); + float4x4 colorMatrix = float4x4(float4(filterParams0), float4(filterParams1), float4(filterParams2), float4(filterParams3)); + return (colorMatrix * srcColor) + filterParams4; +} + static inline __attribute__((always_inline)) float4 sampleColor(thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord) { @@ -299,7 +317,7 @@ float4 filterNone(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const int& colorFilter) +float4 filterColor(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4, thread const int& colorFilter) { switch (colorFilter) { @@ -330,9 +348,19 @@ float4 filterColor(thread const float2& colorTexCoord, thread const texture2d de } static inline __attribute__((always_inline)) -float4 calculateColor(thread const float2& fragCoord, thread const texture2d colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d destTexture, thread const sampler destTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl) +float4 calculateColor(thread const float2& fragCoord, thread const texture2d colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d destTexture, thread const sampler destTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl) { int maskCtrl0 = (tileCtrl >> 0) & 3; float maskAlpha = 1.0; @@ -617,10 +645,10 @@ float4 calculateColor(thread const float2& fragCoord, thread const texture2d> 6) & 3; + int color0Combine = (ctrl >> 8) & 3; if (color0Combine != 0) { - int color0Filter = (ctrl >> 4) & 3; + int color0Filter = (ctrl >> 4) & 15; float2 param_4 = colorTexCoord0; float2 param_5 = colorTextureSize0; float2 param_6 = fragCoord; @@ -628,31 +656,33 @@ float4 calculateColor(thread const float2& fragCoord, thread const texture2d> 8) & 15; - float4 param_15 = color; - float2 param_16 = framebufferSize; - float2 param_17 = fragCoord; - int param_18 = compositeOp; - color = composite(param_15, destTexture, destTextureSmplr, param_16, param_17, param_18); - float3 _1363 = color.xyz * color.w; - color = float4(_1363.x, _1363.y, _1363.z, color.w); + int compositeOp = (ctrl >> 10) & 15; + float4 param_17 = color; + float2 param_18 = framebufferSize; + float2 param_19 = fragCoord; + int param_20 = compositeOp; + color = composite(param_17, destTexture, destTextureSmplr, param_18, param_19, param_20); + float3 _1437 = color.xyz * color.w; + color = float4(_1437.x, _1437.y, _1437.z, color.w); return color; } -kernel void main0(constant int2& uFramebufferTileSize [[buffer(3)]], constant int& uLoadAction [[buffer(4)]], constant int2& uTextureMetadataSize [[buffer(7)]], constant float2& uFramebufferSize [[buffer(0)]], constant float2& uTileSize [[buffer(1)]], constant float4& uClearColor [[buffer(5)]], constant float2& uColorTextureSize0 [[buffer(8)]], constant float2& uMaskTextureSize0 [[buffer(9)]], const device bFirstTileMap& _1509 [[buffer(2)]], const device bTiles& _1602 [[buffer(6)]], texture2d uDestImage [[texture(0)]], texture2d uTextureMetadata [[texture(1)]], texture2d uColorTexture0 [[texture(2)]], texture2d uMaskTexture0 [[texture(3)]], texture2d uGammaLUT [[texture(4)]], sampler uTextureMetadataSmplr [[sampler(0)]], sampler uColorTexture0Smplr [[sampler(1)]], sampler uMaskTexture0Smplr [[sampler(2)]], sampler uGammaLUTSmplr [[sampler(3)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(constant int2& uFramebufferTileSize [[buffer(3)]], constant int& uLoadAction [[buffer(4)]], constant int2& uTextureMetadataSize [[buffer(7)]], constant float2& uFramebufferSize [[buffer(0)]], constant float2& uTileSize [[buffer(1)]], constant float4& uClearColor [[buffer(5)]], constant float2& uColorTextureSize0 [[buffer(8)]], constant float2& uMaskTextureSize0 [[buffer(9)]], const device bFirstTileMap& _1601 [[buffer(2)]], const device bTiles& _1692 [[buffer(6)]], texture2d uDestImage [[texture(0)]], texture2d uTextureMetadata [[texture(1)]], texture2d uColorTexture0 [[texture(2)]], texture2d uMaskTexture0 [[texture(3)]], texture2d uGammaLUT [[texture(4)]], sampler uTextureMetadataSmplr [[sampler(0)]], sampler uColorTexture0Smplr [[sampler(1)]], sampler uMaskTexture0Smplr [[sampler(2)]], sampler uGammaLUTSmplr [[sampler(3)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { int2 tileCoord = int2(gl_WorkGroupID.xy); int2 firstTileSubCoord = int2(gl_LocalInvocationID.xy) * int2(1, 4); int2 firstFragCoord = (tileCoord * int2(uTileSize)) + firstTileSubCoord; - int tileIndex = _1509.iFirstTileMap[tileCoord.x + (uFramebufferTileSize.x * tileCoord.y)]; + int tileIndex = _1601.iFirstTileMap[tileCoord.x + (uFramebufferTileSize.x * tileCoord.y)]; if ((tileIndex < 0) && (uLoadAction != 0)) { return; @@ -678,15 +708,17 @@ kernel void main0(constant int2& uFramebufferTileSize [[buffer(3)]], constant in float4 param_6; float4 param_7; float4 param_8; - int param_9; + float4 param_9; + float4 param_10; + int param_11; while (tileIndex >= 0) { for (int subY_1 = 0; subY_1 < 4; subY_1++) { int2 tileSubCoord = firstTileSubCoord + int2(0, subY_1); float2 fragCoord = float2(firstFragCoord + int2(0, subY_1)) + float2(0.5); - int alphaTileIndex = int(_1602.iTiles[(tileIndex * 4) + 2] << uint(8)) >> 8; - uint tileControlWord = _1602.iTiles[(tileIndex * 4) + 3]; + int alphaTileIndex = int(_1692.iTiles[(tileIndex * 4) + 2] << uint(8)) >> 8; + uint tileControlWord = _1692.iTiles[(tileIndex * 4) + 3]; uint colorEntry = tileControlWord & 65535u; int tileCtrl = int((tileControlWord >> uint(16)) & 255u); if (alphaTileIndex >= 0) @@ -704,34 +736,38 @@ kernel void main0(constant int2& uFramebufferTileSize [[buffer(3)]], constant in float2 param_1 = fragCoord; int param_2 = int(colorEntry); int2 param_3 = uTextureMetadataSize; - computeTileVaryings(param_1, param_2, uTextureMetadata, uTextureMetadataSmplr, param_3, param_4, param_5, param_6, param_7, param_8, param_9); + computeTileVaryings(param_1, param_2, uTextureMetadata, uTextureMetadataSmplr, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11); float2 colorTexCoord0 = param_4; float4 baseColor = param_5; float4 filterParams0 = param_6; float4 filterParams1 = param_7; float4 filterParams2 = param_8; - int ctrl = param_9; - float2 param_10 = fragCoord; - float2 param_11 = uColorTextureSize0; - float2 param_12 = uMaskTextureSize0; - float4 param_13 = filterParams0; - float4 param_14 = filterParams1; - float4 param_15 = filterParams2; - float2 param_16 = uFramebufferSize; - int param_17 = ctrl; - float3 param_18 = maskTexCoord0; - float2 param_19 = colorTexCoord0; - float4 param_20 = baseColor; - int param_21 = tileCtrl; - float4 srcColor = calculateColor(param_10, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, param_11, param_12, param_13, param_14, param_15, param_16, param_17, param_18, param_19, param_20, param_21); + float4 filterParams3 = param_9; + float4 filterParams4 = param_10; + int ctrl = param_11; + float2 param_12 = fragCoord; + float2 param_13 = uColorTextureSize0; + float2 param_14 = uMaskTextureSize0; + float4 param_15 = filterParams0; + float4 param_16 = filterParams1; + float4 param_17 = filterParams2; + float4 param_18 = filterParams3; + float4 param_19 = filterParams4; + float2 param_20 = uFramebufferSize; + int param_21 = ctrl; + float3 param_22 = maskTexCoord0; + float2 param_23 = colorTexCoord0; + float4 param_24 = baseColor; + int param_25 = tileCtrl; + float4 srcColor = calculateColor(param_12, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, param_13, param_14, param_15, param_16, param_17, param_18, param_19, param_20, param_21, param_22, param_23, param_24, param_25); destColors[subY_1] = (destColors[subY_1] * (1.0 - srcColor.w)) + srcColor; } - tileIndex = int(_1602.iTiles[(tileIndex * 4) + 0]); + tileIndex = int(_1692.iTiles[(tileIndex * 4) + 0]); } for (int subY_2 = 0; subY_2 < 4; subY_2++) { - int2 param_22 = firstFragCoord + int2(0, subY_2); - uDestImage.write(destColors[subY_2], uint2(toImageCoords(param_22, uFramebufferSize))); + int2 param_26 = firstFragCoord + int2(0, subY_2); + uDestImage.write(destColors[subY_2], uint2(toImageCoords(param_26, uFramebufferSize))); } } diff --git a/resources/shaders/metal/d3d9/tile.fs.metal b/resources/shaders/metal/d3d9/tile.fs.metal index 016c4194..618ddec2 100644 --- a/resources/shaders/metal/d3d9/tile.fs.metal +++ b/resources/shaders/metal/d3d9/tile.fs.metal @@ -6,7 +6,7 @@ using namespace metal; -constant float3 _1055 = {}; +constant float3 _1123 = {}; struct main0_out { @@ -22,7 +22,9 @@ struct main0_in float4 vFilterParams0 [[user(locn4)]]; float4 vFilterParams1 [[user(locn5)]]; float4 vFilterParams2 [[user(locn6)]]; - float vCtrl [[user(locn7)]]; + float4 vFilterParams3 [[user(locn7)]]; + float4 vFilterParams4 [[user(locn8)]]; + float vCtrl [[user(locn9)]]; }; // Implementation of the GLSL mod() function, which is slightly different than Metal fmod() @@ -75,16 +77,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex { ts = ts.yx; } - float _569; + float _583; if (ts.x >= 0.0) { - _569 = ts.x; + _583 = ts.x; } else { - _569 = ts.y; + _583 = ts.y; } - float t = _569; + float t = _583; color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(t, 0.0))); } return color; @@ -98,19 +100,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel) { bool wide = kernel0.x > 0.0; - float _250; + float _264; if (wide) { float param = (-4.0) * onePixel; float2 param_1 = colorTexCoord; - _250 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); + _264 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); } else { - _250 = 0.0; + _264 = 0.0; } float param_2 = (-3.0) * onePixel; float2 param_3 = colorTexCoord; @@ -142,7 +144,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_5 = colorTexCoord; float param_6 = (-1.0) * onePixel; float2 param_7 = colorTexCoord; - outAlphaLeft = float4(_250, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); + outAlphaLeft = float4(_264, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); float param_8 = 0.0; float2 param_9 = colorTexCoord; outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9); @@ -152,18 +154,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_13 = colorTexCoord; float param_14 = 3.0 * onePixel; float2 param_15 = colorTexCoord; - float _310; + float _324; if (wide) { float param_16 = 4.0 * onePixel; float2 param_17 = colorTexCoord; - _310 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); + _324 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); } else { - _310 = 0.0; + _324 = 0.0; } - outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _310); + outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _324); } static inline __attribute__((always_inline)) @@ -237,6 +239,14 @@ float4 filterText(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4) +{ + float4 srcColor = colorTexture.sample(colorTextureSmplr, colorTexCoord); + float4x4 colorMatrix = float4x4(float4(filterParams0), float4(filterParams1), float4(filterParams2), float4(filterParams3)); + return (colorMatrix * srcColor) + filterParams4; +} + static inline __attribute__((always_inline)) float4 sampleColor(thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord) { @@ -251,7 +261,7 @@ float4 filterNone(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const int& colorFilter) +float4 filterColor(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4, thread const int& colorFilter) { switch (colorFilter) { @@ -282,9 +292,19 @@ float4 filterColor(thread const float2& colorTexCoord, thread const texture2d de } static inline __attribute__((always_inline)) -float4 calculateColor(thread const float2& fragCoord, thread const texture2d colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d destTexture, thread const sampler destTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl) +float4 calculateColor(thread const float2& fragCoord, thread const texture2d colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d destTexture, thread const sampler destTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float4& filterParams3, thread const float4& filterParams4, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl) { int maskCtrl0 = (tileCtrl >> 0) & 3; float maskAlpha = 1.0; @@ -569,10 +589,10 @@ float4 calculateColor(thread const float2& fragCoord, thread const texture2d> 6) & 3; + int color0Combine = (ctrl >> 8) & 3; if (color0Combine != 0) { - int color0Filter = (ctrl >> 4) & 3; + int color0Filter = (ctrl >> 4) & 15; float2 param_4 = colorTexCoord0; float2 param_5 = colorTextureSize0; float2 param_6 = fragCoord; @@ -580,22 +600,24 @@ float4 calculateColor(thread const float2& fragCoord, thread const texture2d> 8) & 15; - float4 param_15 = color; - float2 param_16 = framebufferSize; - float2 param_17 = fragCoord; - int param_18 = compositeOp; - color = composite(param_15, destTexture, destTextureSmplr, param_16, param_17, param_18); - float3 _1339 = color.xyz * color.w; - color = float4(_1339.x, _1339.y, _1339.z, color.w); + int compositeOp = (ctrl >> 10) & 15; + float4 param_17 = color; + float2 param_18 = framebufferSize; + float2 param_19 = fragCoord; + int param_20 = compositeOp; + color = composite(param_17, destTexture, destTextureSmplr, param_18, param_19, param_20); + float3 _1411 = color.xyz * color.w; + color = float4(_1411.x, _1411.y, _1411.z, color.w); return color; } @@ -608,13 +630,15 @@ fragment main0_out main0(main0_in in [[stage_in]], constant float2& uColorTextur float4 param_3 = in.vFilterParams0; float4 param_4 = in.vFilterParams1; float4 param_5 = in.vFilterParams2; - float2 param_6 = uFramebufferSize; - int param_7 = int(in.vCtrl); - float3 param_8 = in.vMaskTexCoord0; - float2 param_9 = in.vColorTexCoord0; - float4 param_10 = in.vBaseColor; - int param_11 = int(in.vTileCtrl); - out.oFragColor = calculateColor(param, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uDestTexture, uDestTextureSmplr, uGammaLUT, uGammaLUTSmplr, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11); + float4 param_6 = in.vFilterParams3; + float4 param_7 = in.vFilterParams4; + float2 param_8 = uFramebufferSize; + int param_9 = int(in.vCtrl); + float3 param_10 = in.vMaskTexCoord0; + float2 param_11 = in.vColorTexCoord0; + float4 param_12 = in.vBaseColor; + int param_13 = int(in.vTileCtrl); + out.oFragColor = calculateColor(param, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uDestTexture, uDestTextureSmplr, uGammaLUT, uGammaLUTSmplr, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11, param_12, param_13); return out; } diff --git a/resources/shaders/metal/d3d9/tile.vs.metal b/resources/shaders/metal/d3d9/tile.vs.metal index 7e83626b..34ec0903 100644 --- a/resources/shaders/metal/d3d9/tile.vs.metal +++ b/resources/shaders/metal/d3d9/tile.vs.metal @@ -15,7 +15,9 @@ struct main0_out float4 vFilterParams0 [[user(locn4)]]; float4 vFilterParams1 [[user(locn5)]]; float4 vFilterParams2 [[user(locn6)]]; - float vCtrl [[user(locn7)]]; + float4 vFilterParams3 [[user(locn7)]]; + float4 vFilterParams4 [[user(locn8)]]; + float vCtrl [[user(locn9)]]; float4 gl_Position [[position]]; }; @@ -36,10 +38,10 @@ float4 fetchUnscaled(thread const texture2d srcTexture, thread const samp } static inline __attribute__((always_inline)) -void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread int& outCtrl) +void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread float4& outFilterParams3, thread float4& outFilterParams4, thread int& outCtrl) { float2 metadataScale = float2(1.0) / float2(textureMetadataSize); - float2 metadataEntryCoord = float2(float((colorEntry % 128) * 8), float(colorEntry / 128)); + float2 metadataEntryCoord = float2(float((colorEntry % 128) * 10), float(colorEntry / 128)); float2 param = metadataScale; float2 param_1 = metadataEntryCoord; int param_2 = 0; @@ -67,12 +69,22 @@ void computeTileVaryings(thread const float2& position, thread const int& colorE float2 param_18 = metadataScale; float2 param_19 = metadataEntryCoord; int param_20 = 6; - float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20); + float4 filterParams3 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20); + float2 param_21 = metadataScale; + float2 param_22 = metadataEntryCoord; + int param_23 = 7; + float4 filterParams4 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_21, param_22, param_23); + float2 param_24 = metadataScale; + float2 param_25 = metadataEntryCoord; + int param_26 = 8; + float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_24, param_25, param_26); outColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra.x); } @@ -90,17 +102,17 @@ vertex main0_out main0(main0_in in [[stage_in]], constant int2& uZBufferSize [[b } uint2 maskTileCoord = uint2(in.aMaskTexCoord0.x, in.aMaskTexCoord0.y + (256u * in.aMaskTexCoord0.z)); float2 maskTexCoord0 = (float2(maskTileCoord) + tileOffset) * uTileSize; - bool _244 = in.aCtrlBackdrop.y == 0; - bool _250; - if (_244) + bool _264 = in.aCtrlBackdrop.y == 0; + bool _270; + if (_264) { - _250 = in.aMaskTexCoord0.w != 0u; + _270 = in.aMaskTexCoord0.w != 0u; } else { - _250 = _244; + _270 = _264; } - if (_250) + if (_270) { out.gl_Position = float4(0.0); return out; @@ -113,14 +125,18 @@ vertex main0_out main0(main0_in in [[stage_in]], constant int2& uZBufferSize [[b float4 param_5; float4 param_6; float4 param_7; - int param_8; - computeTileVaryings(param, param_1, uTextureMetadata, uTextureMetadataSmplr, param_2, param_3, param_4, param_5, param_6, param_7, param_8); + float4 param_8; + float4 param_9; + int param_10; + computeTileVaryings(param, param_1, uTextureMetadata, uTextureMetadataSmplr, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10); out.vColorTexCoord0 = param_3; out.vBaseColor = param_4; out.vFilterParams0 = param_5; out.vFilterParams1 = param_6; out.vFilterParams2 = param_7; - int ctrl = param_8; + out.vFilterParams3 = param_8; + out.vFilterParams4 = param_9; + int ctrl = param_10; out.vTileCtrl = float(in.aCtrlBackdrop.x); out.vCtrl = float(ctrl); out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aCtrlBackdrop.y)); diff --git a/shaders/d3d11/tile.cs.glsl b/shaders/d3d11/tile.cs.glsl index f4400e8c..945b7fe8 100644 --- a/shaders/d3d11/tile.cs.glsl +++ b/shaders/d3d11/tile.cs.glsl @@ -115,7 +115,7 @@ void main() { vec3 maskTexCoord0 = vec3(vec2(ivec2(maskTileCoord) + tileSubCoord), backdrop); vec2 colorTexCoord0; - vec4 baseColor, filterParams0, filterParams1, filterParams2; + vec4 baseColor, filterParams0, filterParams1, filterParams2, filterParams3, filterParams4; int ctrl; computeTileVaryings(fragCoord, int(colorEntry), @@ -126,6 +126,8 @@ void main() { filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, ctrl); // FIXME(pcwalton): The `uColorTexture0` below is a placeholder and needs to be @@ -141,6 +143,8 @@ void main() { filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, uFramebufferSize, ctrl, maskTexCoord0, diff --git a/shaders/d3d9/tile.fs.glsl b/shaders/d3d9/tile.fs.glsl index 25afb515..7efa275d 100644 --- a/shaders/d3d9/tile.fs.glsl +++ b/shaders/d3d9/tile.fs.glsl @@ -35,6 +35,8 @@ in float vTileCtrl; in vec4 vFilterParams0; in vec4 vFilterParams1; in vec4 vFilterParams2; +in vec4 vFilterParams3; +in vec4 vFilterParams4; in float vCtrl; out vec4 oFragColor; @@ -54,6 +56,8 @@ void main() { vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, uFramebufferSize, int(vCtrl), vMaskTexCoord0, diff --git a/shaders/d3d9/tile.vs.glsl b/shaders/d3d9/tile.vs.glsl index bab4d802..9585aa0d 100644 --- a/shaders/d3d9/tile.vs.glsl +++ b/shaders/d3d9/tile.vs.glsl @@ -41,6 +41,8 @@ out float vTileCtrl; out vec4 vFilterParams0; out vec4 vFilterParams1; out vec4 vFilterParams2; +out vec4 vFilterParams3; +out vec4 vFilterParams4; out float vCtrl; void main() { @@ -70,6 +72,8 @@ void main() { vFilterParams0, vFilterParams1, vFilterParams2, + vFilterParams3, + vFilterParams4, ctrl); vTileCtrl = float(aCtrlBackdrop.x); diff --git a/shaders/tile_fragment.inc.glsl b/shaders/tile_fragment.inc.glsl index c183c78b..eac14125 100644 --- a/shaders/tile_fragment.inc.glsl +++ b/shaders/tile_fragment.inc.glsl @@ -44,10 +44,11 @@ #define COMBINER_CTRL_COLOR_COMBINE_SRC_IN 0x1 #define COMBINER_CTRL_COLOR_COMBINE_DEST_IN 0x2 -#define COMBINER_CTRL_FILTER_MASK 0x3 +#define COMBINER_CTRL_FILTER_MASK 0xf #define COMBINER_CTRL_FILTER_RADIAL_GRADIENT 0x1 #define COMBINER_CTRL_FILTER_TEXT 0x2 #define COMBINER_CTRL_FILTER_BLUR 0x3 +#define COMBINER_CTRL_FILTER_COLOR_MATRIX 0x4 #define COMBINER_CTRL_COMPOSITE_MASK 0xf #define COMBINER_CTRL_COMPOSITE_NORMAL 0x0 @@ -68,8 +69,8 @@ #define COMBINER_CTRL_COMPOSITE_LUMINOSITY 0xf #define COMBINER_CTRL_COLOR_FILTER_SHIFT 4 -#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6 -#define COMBINER_CTRL_COMPOSITE_SHIFT 8 +#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 8 +#define COMBINER_CTRL_COMPOSITE_SHIFT 10 // Color sampling @@ -347,6 +348,18 @@ vec4 filterBlur(vec2 colorTexCoord, return color / gaussSum; } +vec4 filterColorMatrix(vec2 colorTexCoord, + sampler2D colorTexture, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4) { + vec4 srcColor = texture(colorTexture, colorTexCoord); + mat4 colorMatrix = mat4(filterParams0, filterParams1, filterParams2, filterParams3); + return colorMatrix * srcColor + filterParams4; +} + vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture) { return sampleColor(colorTexture, colorTexCoord); } @@ -360,6 +373,8 @@ vec4 filterColor(vec2 colorTexCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, int colorFilter) { switch (colorFilter) { case COMBINER_CTRL_FILTER_RADIAL_GRADIENT: @@ -384,6 +399,14 @@ vec4 filterColor(vec2 colorTexCoord, filterParams0, filterParams1, filterParams2); + case COMBINER_CTRL_FILTER_COLOR_MATRIX: + return filterColorMatrix(colorTexCoord, + colorTexture, + filterParams0, + filterParams1, + filterParams2, + filterParams3, + filterParams4); } return filterNone(colorTexCoord, colorTexture); } @@ -546,6 +569,8 @@ vec4 calculateColor(vec2 fragCoord, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, + vec4 filterParams3, + vec4 filterParams4, vec2 framebufferSize, int ctrl, vec3 maskTexCoord0, @@ -572,6 +597,8 @@ vec4 calculateColor(vec2 fragCoord, filterParams0, filterParams1, filterParams2, + filterParams3, + filterParams4, color0Filter); color = combineColor0(color, color0, color0Combine); } diff --git a/shaders/tile_vertex.inc.glsl b/shaders/tile_vertex.inc.glsl index c99778a4..cd69613b 100644 --- a/shaders/tile_vertex.inc.glsl +++ b/shaders/tile_vertex.inc.glsl @@ -21,20 +21,26 @@ void computeTileVaryings(vec2 position, out vec4 outFilterParams0, out vec4 outFilterParams1, out vec4 outFilterParams2, + out vec4 outFilterParams3, + out vec4 outFilterParams4, out int outCtrl) { vec2 metadataScale = vec2(1.0) / vec2(textureMetadataSize); - vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 10, colorEntry / 128); vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); - vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams3 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + vec4 filterParams4 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 7); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 8); outColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy; outBaseColor = baseColor; outFilterParams0 = filterParams0; outFilterParams1 = filterParams1; outFilterParams2 = filterParams2; + outFilterParams3 = filterParams3; + outFilterParams4 = filterParams4; outCtrl = int(extra.x); }