/ src / Ryujinx.Graphics.OpenGL / Effects / Shaders / fsr_scaling.glsl
fsr_scaling.glsl
 1  #version 430 core
 2  precision mediump float;
 3  layout (local_size_x = 64) in;
 4  layout(rgba8, binding = 0, location=0) uniform image2D imgOutput;
 5  layout( location=1 ) uniform sampler2D Source;
 6  layout( location=2 ) uniform float srcX0;
 7  layout( location=3 ) uniform float srcX1;
 8  layout( location=4 ) uniform float srcY0;
 9  layout( location=5 ) uniform float srcY1;
10  layout( location=6 ) uniform float dstX0;
11  layout( location=7 ) uniform float dstX1;
12  layout( location=8 ) uniform float dstY0;
13  layout( location=9 ) uniform float dstY1;
14  layout( location=10 ) uniform float scaleX;
15  layout( location=11 ) uniform float scaleY;
16  
17  #define A_GPU 1
18  #define A_GLSL 1
19  #include "ffx_a.h"
20  
21  #define FSR_EASU_F 1
22  AU4 con0, con1, con2, con3;
23  float srcW, srcH, dstW, dstH;
24  vec2 bLeft, tRight;
25  
26  AF2 translate(AF2 pos) {
27      return AF2(pos.x * scaleX, pos.y * scaleY);
28  }
29  
30  void setBounds(vec2 bottomLeft, vec2 topRight) {
31      bLeft = bottomLeft;
32      tRight = topRight;
33  }
34  
35  AF2 translateDest(AF2 pos) {
36      AF2 translatedPos = AF2(pos.x, pos.y);
37      translatedPos.x = dstX1 < dstX0 ? dstX1 - translatedPos.x : translatedPos.x;
38      translatedPos.y = dstY0 > dstY1 ? dstY0 + dstY1 - translatedPos.y - 1: translatedPos.y;
39      return translatedPos;
40  }
41  
42  AF4 FsrEasuRF(AF2 p) { AF4 res = textureGather(Source, translate(p), 0); return res; }
43  AF4 FsrEasuGF(AF2 p) { AF4 res = textureGather(Source, translate(p), 1); return res; }
44  AF4 FsrEasuBF(AF2 p) { AF4 res = textureGather(Source, translate(p), 2); return res; }
45  
46  #include "ffx_fsr1.h"
47  
48  float insideBox(vec2 v) {
49      vec2 s = step(bLeft, v) - step(tRight, v);
50      return s.x * s.y;   
51  }
52  
53  void CurrFilter(AU2 pos)
54  {
55      if((insideBox(vec2(pos.x, pos.y))) == 0) {
56          imageStore(imgOutput, ASU2(pos.x, pos.y), AF4(0,0,0,1));
57         return;
58      }
59      AF3 c;
60      FsrEasuF(c, AU2(pos.x - bLeft.x, pos.y - bLeft.y), con0, con1, con2, con3);
61      imageStore(imgOutput, ASU2(translateDest(pos)), AF4(c, 1));
62  }
63  
64  void main() {
65      srcW = abs(srcX1 - srcX0);
66      srcH = abs(srcY1 - srcY0);
67      dstW = abs(dstX1 - dstX0);
68      dstH = abs(dstY1 - dstY0);
69  
70      AU2 gxy = ARmp8x8(gl_LocalInvocationID.x) + AU2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u);
71  
72      setBounds(vec2(dstX0 < dstX1 ? dstX0 : dstX1, dstY0 < dstY1 ? dstY0 : dstY1),
73          vec2(dstX1 > dstX0 ? dstX1 : dstX0, dstY1 > dstY0 ? dstY1 : dstY0));
74  
75      // Upscaling
76      FsrEasuCon(con0, con1, con2, con3,
77          srcW, srcH,  // Viewport size (top left aligned) in the input image which is to be scaled.
78          srcW, srcH,  // The size of the input image.
79          dstW, dstH); // The output resolution.
80  
81      CurrFilter(gxy);
82      gxy.x += 8u;
83      CurrFilter(gxy);
84      gxy.y += 8u;
85      CurrFilter(gxy);
86      gxy.x -= 8u;
87      CurrFilter(gxy);
88  }