mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 12:42:41 +01:00
rsx: Unify UI rendering shaders
This commit is contained in:
parent
53e906d0f3
commit
64ec99be33
@ -1,6 +1,7 @@
|
||||
#include "GLOverlays.h"
|
||||
|
||||
#include "../rsx_utils.h"
|
||||
#include "../Program/RSXOverlay.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -194,132 +195,19 @@ namespace gl
|
||||
ui_overlay_renderer::ui_overlay_renderer()
|
||||
{
|
||||
vs_src =
|
||||
"#version 420\n\n"
|
||||
"layout(location=0) in vec4 in_pos;\n"
|
||||
"layout(location=0) out vec2 tc0;\n"
|
||||
"layout(location=1) flat out vec4 clip_rect;\n"
|
||||
"uniform vec4 ui_scale;\n"
|
||||
"uniform vec4 viewport;\n"
|
||||
"uniform vec4 clip_bounds;\n"
|
||||
"\n"
|
||||
"vec2 snap_to_grid(vec2 normalized)\n"
|
||||
"{\n"
|
||||
" return (floor(normalized * viewport.xy) + 0.5) / viewport.xy;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 clip_to_ndc(const in vec4 coord)\n"
|
||||
"{\n"
|
||||
" vec4 ret = (coord * ui_scale.zwzw) / ui_scale.xyxy;\n"
|
||||
" ret.yw = 1. - ret.yw;\n"
|
||||
" return ret;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 ndc_to_window(const in vec4 coord)\n"
|
||||
"{\n"
|
||||
" return fma(coord, viewport.xyxy, viewport.zwzw);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" tc0.xy = in_pos.zw;\n"
|
||||
" clip_rect = ndc_to_window(clip_to_ndc(clip_bounds)).xwzy; // Swap y1 and y2 due to flipped origin!\n"
|
||||
" vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.);\n"
|
||||
" pos.xy = snap_to_grid(pos.xy);\n"
|
||||
" gl_Position = (pos + pos) - 1.;\n"
|
||||
"}\n";
|
||||
#include "../Program/GLSLSnippets/OverlayRenderVS.glsl"
|
||||
;
|
||||
|
||||
fs_src =
|
||||
"#version 420\n\n"
|
||||
"layout(binding=31) uniform sampler2D fs0;\n"
|
||||
"layout(binding=30) uniform sampler2DArray fs1;\n"
|
||||
"layout(location=0) in vec2 tc0;\n"
|
||||
"layout(location=1) flat in vec4 clip_rect;\n"
|
||||
"layout(location=0) out vec4 ocol;\n"
|
||||
"uniform vec4 color;\n"
|
||||
"uniform float time;\n"
|
||||
"uniform int sampler_mode;\n"
|
||||
"uniform int pulse_glow;\n"
|
||||
"uniform int clip_region;\n"
|
||||
"uniform int blur_strength;\n"
|
||||
"\n"
|
||||
"vec4 blur_sample(sampler2D tex, vec2 coord, vec2 tex_offset)\n"
|
||||
"{\n"
|
||||
" vec2 coords[9];\n"
|
||||
" coords[0] = coord - tex_offset\n;"
|
||||
" coords[1] = coord + vec2(0., -tex_offset.y);\n"
|
||||
" coords[2] = coord + vec2(tex_offset.x, -tex_offset.y);\n"
|
||||
" coords[3] = coord + vec2(-tex_offset.x, 0.);\n"
|
||||
" coords[4] = coord;\n"
|
||||
" coords[5] = coord + vec2(tex_offset.x, 0.);\n"
|
||||
" coords[6] = coord + vec2(-tex_offset.x, tex_offset.y);\n"
|
||||
" coords[7] = coord + vec2(0., tex_offset.y);\n"
|
||||
" coords[8] = coord + tex_offset;\n"
|
||||
"\n"
|
||||
" float weights[9] =\n"
|
||||
" {\n"
|
||||
" 1., 2., 1.,\n"
|
||||
" 2., 4., 2.,\n"
|
||||
" 1., 2., 1.\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" vec4 blurred = vec4(0.);\n"
|
||||
" for (int n = 0; n < 9; ++n)\n"
|
||||
" {\n"
|
||||
" blurred += texture(tex, coords[n]) * weights[n];\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return blurred / 16.f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 sample_image(sampler2D tex, vec2 coord)\n"
|
||||
"{\n"
|
||||
" vec4 original = texture(tex, coord);\n"
|
||||
" if (blur_strength == 0) return original;\n"
|
||||
" \n"
|
||||
" vec2 constraints = 1.f / vec2(640, 360);\n"
|
||||
" vec2 res_offset = 1.f / textureSize(fs0, 0);\n"
|
||||
" vec2 tex_offset = max(res_offset, constraints);\n"
|
||||
"\n"
|
||||
" // Sample triangle pattern and average\n"
|
||||
" // TODO: Nicer looking gaussian blur with less sampling\n"
|
||||
" vec4 blur0 = blur_sample(tex, coord + vec2(-res_offset.x, 0.), tex_offset);\n"
|
||||
" vec4 blur1 = blur_sample(tex, coord + vec2(res_offset.x, 0.), tex_offset);\n"
|
||||
" vec4 blur2 = blur_sample(tex, coord + vec2(0., res_offset.y), tex_offset);\n"
|
||||
"\n"
|
||||
" vec4 blurred = blur0 + blur1 + blur2;\n"
|
||||
" blurred /= 3.;\n"
|
||||
" return mix(original, blurred, float(blur_strength) / 100.);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" if (clip_region != 0)\n"
|
||||
" {"
|
||||
" if (gl_FragCoord.x < clip_rect.x || gl_FragCoord.x > clip_rect.z ||\n"
|
||||
" gl_FragCoord.y < clip_rect.y || gl_FragCoord.y > clip_rect.w)\n"
|
||||
" {\n"
|
||||
" discard;\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" vec4 diff_color = color;\n"
|
||||
" if (pulse_glow != 0)\n"
|
||||
" diff_color.a *= (sin(time) + 1.f) * 0.5f;\n"
|
||||
"\n"
|
||||
" switch (sampler_mode)\n"
|
||||
" {\n"
|
||||
" case 1:\n"
|
||||
" ocol = sample_image(fs0, tc0) * diff_color;\n"
|
||||
" break;\n"
|
||||
" case 2:\n"
|
||||
" ocol = texture(fs1, vec3(tc0.x, fract(tc0.y), trunc(tc0.y))) * diff_color;\n"
|
||||
" break;\n"
|
||||
" default:\n"
|
||||
" ocol = diff_color;\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
#include "../Program/GLSLSnippets/OverlayRenderFS.glsl"
|
||||
;
|
||||
|
||||
vs_src = fmt::replace_all(vs_src,
|
||||
{
|
||||
{ "#version 450", "#version 420" },
|
||||
{ "%preprocessor", "// %preprocessor" }
|
||||
});
|
||||
fs_src = fmt::replace_all(fs_src, "%preprocessor", "// %preprocessor");
|
||||
|
||||
// Smooth filtering required for inputs
|
||||
m_input_filter = gl::filter::linear;
|
||||
@ -513,7 +401,7 @@ namespace gl
|
||||
set_primitive_type(cmd.config.primitives);
|
||||
upload_vertex_data(cmd.verts.data(), ::size32(cmd.verts));
|
||||
num_drawable_elements = ::size32(cmd.verts);
|
||||
GLint texture_read = GL_TRUE;
|
||||
auto texture_mode = rsx::overlays::texture_sampling_mode::texture2D;
|
||||
|
||||
switch (cmd.config.texture_ref)
|
||||
{
|
||||
@ -522,7 +410,7 @@ namespace gl
|
||||
// TODO
|
||||
case rsx::overlays::image_resource_id::none:
|
||||
{
|
||||
texture_read = GL_FALSE;
|
||||
texture_mode = rsx::overlays::texture_sampling_mode::none;
|
||||
cmd_->bind_texture(31, GL_TEXTURE_2D, GL_NONE);
|
||||
break;
|
||||
}
|
||||
@ -533,7 +421,7 @@ namespace gl
|
||||
}
|
||||
case rsx::overlays::image_resource_id::font_file:
|
||||
{
|
||||
texture_read = (GL_TRUE + 1);
|
||||
texture_mode = rsx::overlays::texture_sampling_mode::font3D;
|
||||
cmd_->bind_texture(30, GL_TEXTURE_2D_ARRAY, find_font(cmd.config.font_ref)->id());
|
||||
break;
|
||||
}
|
||||
@ -544,13 +432,17 @@ namespace gl
|
||||
}
|
||||
}
|
||||
|
||||
program_handle.uniforms["time"] = cmd.config.get_sinus_value();
|
||||
program_handle.uniforms["color"] = cmd.config.color;
|
||||
program_handle.uniforms["sampler_mode"] = texture_read;
|
||||
program_handle.uniforms["pulse_glow"] = static_cast<s32>(cmd.config.pulse_glow);
|
||||
program_handle.uniforms["blur_strength"] = static_cast<s32>(cmd.config.blur_strength);
|
||||
program_handle.uniforms["clip_region"] = static_cast<s32>(cmd.config.clip_region);
|
||||
rsx::overlays::fragment_options draw_opts;
|
||||
program_handle.uniforms["fragment_config"] = draw_opts
|
||||
.texture_mode(texture_mode)
|
||||
.clip_fragments(cmd.config.clip_region)
|
||||
.pulse_glow(cmd.config.pulse_glow)
|
||||
.get();
|
||||
|
||||
program_handle.uniforms["timestamp"] = cmd.config.get_sinus_value();
|
||||
program_handle.uniforms["albedo"] = cmd.config.color;
|
||||
program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect;
|
||||
program_handle.uniforms["blur_intensity"] = static_cast<s32>(cmd.config.blur_strength);
|
||||
overlay_pass::run(cmd_, viewport, target, gl::image_aspect::color, true);
|
||||
}
|
||||
|
||||
|
145
rpcs3/Emu/RSX/Program/GLSLSnippets/OverlayRenderFS.glsl
Normal file
145
rpcs3/Emu/RSX/Program/GLSLSnippets/OverlayRenderFS.glsl
Normal file
@ -0,0 +1,145 @@
|
||||
R"(
|
||||
#version 420
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
%preprocessor
|
||||
|
||||
#ifdef VULKAN
|
||||
#define USE_UBO 1
|
||||
#endif
|
||||
|
||||
#define SAMPLER_MODE_NONE 0
|
||||
#define SAMPLER_MODE_FONT2D 1
|
||||
#define SAMPLER_MODE_FONT3D 2
|
||||
#define SAMPLER_MODE_TEXTURE2D 3
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set=0, binding=1) uniform sampler2D fs0;
|
||||
layout(set=0, binding=2) uniform sampler2DArray fs1;
|
||||
#else
|
||||
layout(binding=31) uniform sampler2D fs0;
|
||||
layout(binding=30) uniform sampler2DArray fs1;
|
||||
#endif
|
||||
|
||||
layout(location=0) in vec2 tc0;
|
||||
layout(location=1) in vec4 color;
|
||||
layout(location=2) in vec4 clip_rect;
|
||||
|
||||
layout(location=0) out vec4 ocol;
|
||||
|
||||
#if USE_UBO
|
||||
layout(%push_block) uniform FragmentConfiguration
|
||||
{
|
||||
%push_block_offset
|
||||
uint fragment_config;
|
||||
float timestamp;
|
||||
float blur_intensity;
|
||||
};
|
||||
#else
|
||||
uniform uint fragment_config;
|
||||
uniform float timestamp;
|
||||
uniform float blur_intensity;
|
||||
#endif
|
||||
|
||||
struct config_t
|
||||
{
|
||||
bool clip_fragments;
|
||||
bool use_pulse_glow;
|
||||
uint sampler_mode;
|
||||
};
|
||||
|
||||
config_t unpack_fragment_options()
|
||||
{
|
||||
config_t result;
|
||||
result.clip_fragments = bitfieldExtract(fragment_config, 0, 1) != 0;
|
||||
result.use_pulse_glow = bitfieldExtract(fragment_config, 1, 1) != 0;
|
||||
result.sampler_mode = bitfieldExtract(fragment_config, 2, 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blur_sample(sampler2D tex, vec2 coord, vec2 tex_offset)
|
||||
{
|
||||
vec2 coords[9];
|
||||
coords[0] = coord - tex_offset;
|
||||
coords[1] = coord + vec2(0., -tex_offset.y);
|
||||
coords[2] = coord + vec2(tex_offset.x, -tex_offset.y);
|
||||
coords[3] = coord + vec2(-tex_offset.x, 0.);
|
||||
coords[4] = coord;
|
||||
coords[5] = coord + vec2(tex_offset.x, 0.);
|
||||
coords[6] = coord + vec2(-tex_offset.x, tex_offset.y);
|
||||
coords[7] = coord + vec2(0., tex_offset.y);
|
||||
coords[8] = coord + tex_offset;
|
||||
|
||||
float weights[9] =
|
||||
{
|
||||
1., 2., 1.,
|
||||
2., 4., 2.,
|
||||
1., 2., 1.
|
||||
};
|
||||
|
||||
vec4 blurred = vec4(0.);
|
||||
for (int n = 0; n < 9; ++n)
|
||||
{
|
||||
blurred += texture(tex, coords[n]) * weights[n];
|
||||
}
|
||||
|
||||
return blurred / 16.f;
|
||||
}
|
||||
|
||||
vec4 sample_image(sampler2D tex, vec2 coord, float blur_strength)
|
||||
{
|
||||
vec4 original = texture(tex, coord);
|
||||
if (blur_strength == 0) return original;
|
||||
|
||||
vec2 constraints = 1.f / vec2(640, 360);
|
||||
vec2 res_offset = 1.f / textureSize(fs0, 0);
|
||||
vec2 tex_offset = max(res_offset, constraints);
|
||||
|
||||
// Sample triangle pattern and average
|
||||
// TODO: Nicer looking gaussian blur with less sampling
|
||||
vec4 blur0 = blur_sample(tex, coord + vec2(-res_offset.x, 0.), tex_offset);
|
||||
vec4 blur1 = blur_sample(tex, coord + vec2(res_offset.x, 0.), tex_offset);
|
||||
vec4 blur2 = blur_sample(tex, coord + vec2(0., res_offset.y), tex_offset);
|
||||
|
||||
vec4 blurred = blur0 + blur1 + blur2;
|
||||
blurred /= 3.;
|
||||
return mix(original, blurred, blur_strength);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
config_t config = unpack_fragment_options();
|
||||
if (config.clip_fragments)
|
||||
{
|
||||
if (gl_FragCoord.x < clip_rect.x || gl_FragCoord.x > clip_rect.z ||
|
||||
gl_FragCoord.y < clip_rect.y || gl_FragCoord.y > clip_rect.w)
|
||||
{
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 diff_color = color;
|
||||
if (config.use_pulse_glow)
|
||||
{
|
||||
diff_color.a *= (sin(timestamp) + 1.f) * 0.5f;
|
||||
}
|
||||
|
||||
switch (config.sampler_mode)
|
||||
{
|
||||
default:
|
||||
case SAMPLER_MODE_NONE:
|
||||
ocol = diff_color;
|
||||
break;
|
||||
case SAMPLER_MODE_FONT2D:
|
||||
ocol = texture(fs0, tc0).rrrr * diff_color;
|
||||
break;
|
||||
case SAMPLER_MODE_FONT3D:
|
||||
ocol = texture(fs1, vec3(tc0.x, fract(tc0.y), trunc(tc0.y))).rrrr * diff_color;
|
||||
break;
|
||||
case SAMPLER_MODE_TEXTURE2D:
|
||||
ocol = sample_image(fs0, tc0, blur_intensity).bgra * diff_color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
)"
|
60
rpcs3/Emu/RSX/Program/GLSLSnippets/OverlayRenderVS.glsl
Normal file
60
rpcs3/Emu/RSX/Program/GLSLSnippets/OverlayRenderVS.glsl
Normal file
@ -0,0 +1,60 @@
|
||||
R"(
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
%preprocessor
|
||||
|
||||
#ifdef VULKAN
|
||||
#define USE_UBO 1
|
||||
#endif
|
||||
|
||||
layout(location=0) in vec4 in_pos;
|
||||
layout(location=0) out vec2 tc0;
|
||||
layout(location=1) out vec4 color;
|
||||
layout(location=2) out vec4 clip_rect;
|
||||
|
||||
#if USE_UBO
|
||||
layout(%push_block) uniform Configuration
|
||||
{
|
||||
vec4 ui_scale;
|
||||
vec4 albedo;
|
||||
vec4 viewport;
|
||||
vec4 clip_bounds;
|
||||
};
|
||||
#else
|
||||
uniform vec4 ui_scale;
|
||||
uniform vec4 albedo;
|
||||
uniform vec4 viewport;
|
||||
uniform vec4 clip_bounds;
|
||||
#endif
|
||||
|
||||
vec2 snap_to_grid(const in vec2 normalized)
|
||||
{
|
||||
return floor(fma(normalized, viewport.xy, vec2(0.5))) / viewport.xy;
|
||||
}
|
||||
|
||||
vec4 clip_to_ndc(const in vec4 coord)
|
||||
{
|
||||
vec4 ret = (coord * ui_scale.zwzw) / ui_scale.xyxy;
|
||||
#ifndef VULKAN
|
||||
// Flip Y for OpenGL
|
||||
ret.yw = 1. - ret.yw;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
vec4 ndc_to_window(const in vec4 coord)
|
||||
{
|
||||
return fma(coord, viewport.xyxy, viewport.zwzw);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
tc0.xy = in_pos.zw;
|
||||
color = albedo;
|
||||
clip_rect = ndc_to_window(clip_to_ndc(clip_bounds));
|
||||
vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.);
|
||||
pos.xy = snap_to_grid(pos.xy);
|
||||
gl_Position = (pos + pos) - 1.;
|
||||
}
|
||||
)"
|
60
rpcs3/Emu/RSX/Program/RSXOverlay.h
Normal file
60
rpcs3/Emu/RSX/Program/RSXOverlay.h
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <util/types.hpp>
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace overlays
|
||||
{
|
||||
// This is overlay common code meant only for render backends
|
||||
enum class texture_sampling_mode: s32
|
||||
{
|
||||
none = 0,
|
||||
font2D = 1,
|
||||
font3D = 2,
|
||||
texture2D = 3
|
||||
};
|
||||
|
||||
class fragment_options
|
||||
{
|
||||
u32 value = 0;
|
||||
|
||||
enum e_offsets: s32
|
||||
{
|
||||
fragment_clip_bit = 0,
|
||||
pulse_glow_bit = 1,
|
||||
sampling_mode_bit = 2
|
||||
};
|
||||
|
||||
public:
|
||||
fragment_options& texture_mode(texture_sampling_mode mode)
|
||||
{
|
||||
value |= static_cast<s32>(mode) << e_offsets::sampling_mode_bit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
fragment_options& pulse_glow(bool enable = true)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
value |= (1 << e_offsets::pulse_glow_bit);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
fragment_options& clip_fragments(bool enable = true)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
value |= (1 << e_offsets::fragment_clip_bit);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
u32 get() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
#include "vkutils/scratch.h"
|
||||
|
||||
#include "../Overlays/overlays.h"
|
||||
#include "../Program/RSXOverlay.h"
|
||||
|
||||
#include "util/fnv_hash.hpp"
|
||||
|
||||
@ -353,137 +354,25 @@ namespace vk
|
||||
ui_overlay_renderer::ui_overlay_renderer()
|
||||
{
|
||||
vs_src =
|
||||
"#version 450\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
"layout(location=0) in vec4 in_pos;\n"
|
||||
"layout(std140, set=0, binding=0) uniform static_data{ vec4 regs[8]; };\n"
|
||||
"layout(location=0) out vec2 tc0;\n"
|
||||
"layout(location=1) out vec4 color;\n"
|
||||
"layout(location=2) out vec4 parameters;\n"
|
||||
"layout(location=3) out vec4 clip_rect;\n"
|
||||
"layout(location=4) out vec4 parameters2;\n"
|
||||
"\n"
|
||||
"vec2 snap_to_grid(const in vec2 normalized)\n"
|
||||
"{\n"
|
||||
" return (floor(normalized * regs[5].xy) + 0.5) / regs[5].xy;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 clip_to_ndc(const in vec4 coord)\n"
|
||||
"{\n"
|
||||
" return (coord * regs[0].zwzw) / regs[0].xyxy;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 ndc_to_window(const in vec4 coord)\n"
|
||||
"{\n"
|
||||
" return fma(coord, regs[5].xyxy, regs[5].zwzw);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" tc0.xy = in_pos.zw;\n"
|
||||
" color = regs[1];\n"
|
||||
" parameters = regs[2];\n"
|
||||
" parameters2 = regs[4];\n"
|
||||
" clip_rect = ndc_to_window(clip_to_ndc(regs[3]));\n"
|
||||
" vec4 pos = vec4(clip_to_ndc(in_pos).xy, 0.5, 1.);\n"
|
||||
" pos.xy = snap_to_grid(pos.xy);\n"
|
||||
" gl_Position = (pos + pos) - 1.;\n"
|
||||
"}\n";
|
||||
#include "../Program/GLSLSnippets/OverlayRenderVS.glsl"
|
||||
;
|
||||
|
||||
fs_src =
|
||||
"#version 420\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
"layout(set=0, binding=1) uniform sampler2D fs0;\n"
|
||||
"layout(set=0, binding=2) uniform sampler2DArray fs1;\n"
|
||||
"layout(location=0) in vec2 tc0;\n"
|
||||
"layout(location=1) in vec4 color;\n"
|
||||
"layout(location=2) in vec4 parameters;\n"
|
||||
"layout(location=3) in vec4 clip_rect;\n"
|
||||
"layout(location=4) in vec4 parameters2;\n"
|
||||
"layout(location=0) out vec4 ocol;\n"
|
||||
"\n"
|
||||
"vec4 blur_sample(sampler2D tex, vec2 coord, vec2 tex_offset)\n"
|
||||
"{\n"
|
||||
" vec2 coords[9];\n"
|
||||
" coords[0] = coord - tex_offset\n;"
|
||||
" coords[1] = coord + vec2(0., -tex_offset.y);\n"
|
||||
" coords[2] = coord + vec2(tex_offset.x, -tex_offset.y);\n"
|
||||
" coords[3] = coord + vec2(-tex_offset.x, 0.);\n"
|
||||
" coords[4] = coord;\n"
|
||||
" coords[5] = coord + vec2(tex_offset.x, 0.);\n"
|
||||
" coords[6] = coord + vec2(-tex_offset.x, tex_offset.y);\n"
|
||||
" coords[7] = coord + vec2(0., tex_offset.y);\n"
|
||||
" coords[8] = coord + tex_offset;\n"
|
||||
"\n"
|
||||
" float weights[9] =\n"
|
||||
" {\n"
|
||||
" 1., 2., 1.,\n"
|
||||
" 2., 4., 2.,\n"
|
||||
" 1., 2., 1.\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" vec4 blurred = vec4(0.);\n"
|
||||
" for (int n = 0; n < 9; ++n)\n"
|
||||
" {\n"
|
||||
" blurred += texture(tex, coords[n]) * weights[n];\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return blurred / 16.f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 sample_image(sampler2D tex, vec2 coord, float blur_strength)\n"
|
||||
"{\n"
|
||||
" vec4 original = texture(tex, coord);\n"
|
||||
" if (blur_strength == 0) return original;\n"
|
||||
" \n"
|
||||
" vec2 constraints = 1.f / vec2(640, 360);\n"
|
||||
" vec2 res_offset = 1.f / textureSize(fs0, 0);\n"
|
||||
" vec2 tex_offset = max(res_offset, constraints);\n"
|
||||
"\n"
|
||||
" // Sample triangle pattern and average\n"
|
||||
" // TODO: Nicer looking gaussian blur with less sampling\n"
|
||||
" vec4 blur0 = blur_sample(tex, coord + vec2(-res_offset.x, 0.), tex_offset);\n"
|
||||
" vec4 blur1 = blur_sample(tex, coord + vec2(res_offset.x, 0.), tex_offset);\n"
|
||||
" vec4 blur2 = blur_sample(tex, coord + vec2(0., res_offset.y), tex_offset);\n"
|
||||
"\n"
|
||||
" vec4 blurred = blur0 + blur1 + blur2;\n"
|
||||
" blurred /= 3.;\n"
|
||||
" return mix(original, blurred, blur_strength);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" if (parameters.w != 0)\n"
|
||||
" {"
|
||||
" if (gl_FragCoord.x < clip_rect.x || gl_FragCoord.x > clip_rect.z ||\n"
|
||||
" gl_FragCoord.y < clip_rect.y || gl_FragCoord.y > clip_rect.w)\n"
|
||||
" {\n"
|
||||
" discard;\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" vec4 diff_color = color;\n"
|
||||
" if (parameters.y != 0)\n"
|
||||
" diff_color.a *= (sin(parameters.x) + 1.f) * 0.5f;\n"
|
||||
"\n"
|
||||
" if (parameters.z < 1.)\n"
|
||||
" {\n"
|
||||
" ocol = diff_color;\n"
|
||||
" }\n"
|
||||
" else if (parameters.z > 2.)\n"
|
||||
" {\n"
|
||||
" ocol = texture(fs1, vec3(tc0.x, fract(tc0.y), trunc(tc0.y))).rrrr * diff_color;\n"
|
||||
" }\n"
|
||||
" else if (parameters.z > 1.)\n"
|
||||
" {\n"
|
||||
" ocol = texture(fs0, tc0).rrrr * diff_color;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
#include "../Program/GLSLSnippets/OverlayRenderFS.glsl"
|
||||
;
|
||||
|
||||
vs_src = fmt::replace_all(vs_src,
|
||||
{
|
||||
{ "%preprocessor", "// %preprocessor" },
|
||||
{ "%push_block", "push_constant" }
|
||||
});
|
||||
|
||||
fs_src = fmt::replace_all(fs_src,
|
||||
{
|
||||
{ "%preprocessor", "// %preprocessor" },
|
||||
{ "%push_block_offset", "layout(offset=64)" },
|
||||
{ "%push_block", "push_constant" }
|
||||
});
|
||||
|
||||
// 2 input textures
|
||||
m_num_usable_samplers = 2;
|
||||
@ -646,45 +535,63 @@ namespace vk
|
||||
false, true, desc->data, owner_uid);
|
||||
}
|
||||
|
||||
void ui_overlay_renderer::update_uniforms(vk::command_buffer& /*cmd*/, vk::glsl::program* /*program*/)
|
||||
std::vector<VkPushConstantRange> ui_overlay_renderer::get_push_constants()
|
||||
{
|
||||
m_ubo_offset = static_cast<u32>(m_ubo.alloc<256>(128));
|
||||
auto dst = static_cast<f32*>(m_ubo.map(m_ubo_offset, 128));
|
||||
return
|
||||
{
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = 64
|
||||
},
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.offset = 64,
|
||||
.size = 16
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// regs[0] = scaling parameters
|
||||
dst[0] = m_scale_offset.r;
|
||||
dst[1] = m_scale_offset.g;
|
||||
dst[2] = m_scale_offset.b;
|
||||
dst[3] = m_scale_offset.a;
|
||||
void ui_overlay_renderer::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* /*program*/)
|
||||
{
|
||||
// Byte Layout
|
||||
// 00: vec4 ui_scale;
|
||||
// 16: vec4 albedo;
|
||||
// 32: vec4 viewport;
|
||||
// 48: vec4 clip_bounds;
|
||||
// 64: uint fragment_config;
|
||||
// 68: float timestamp;
|
||||
// 72: float blur_intensity;
|
||||
|
||||
// regs[1] = color
|
||||
dst[4] = m_color.r;
|
||||
dst[5] = m_color.g;
|
||||
dst[6] = m_color.b;
|
||||
dst[7] = m_color.a;
|
||||
f32 push_buf[32];
|
||||
// 1. Vertex config (00 - 63)
|
||||
std::memcpy(push_buf, m_scale_offset.rgba, 16);
|
||||
std::memcpy(push_buf + 4, m_color.rgba, 16);
|
||||
|
||||
// regs[2] = fs config parameters
|
||||
dst[8] = m_time;
|
||||
dst[9] = m_pulse_glow? 1.f : 0.f;
|
||||
dst[10] = m_skip_texture_read? 0.f : static_cast<f32>(m_texture_type);
|
||||
dst[11] = m_clip_enabled ? 1.f : 0.f;
|
||||
push_buf[8] = m_viewport.width;
|
||||
push_buf[9] = m_viewport.height;
|
||||
push_buf[10] = m_viewport.x;
|
||||
push_buf[11] = m_viewport.y;
|
||||
|
||||
// regs[3] = clip rect
|
||||
dst[12] = m_clip_region.x1;
|
||||
dst[13] = m_clip_region.y1;
|
||||
dst[14] = m_clip_region.x2;
|
||||
dst[15] = m_clip_region.y2;
|
||||
push_buf[12] = m_clip_region.x1;
|
||||
push_buf[13] = m_clip_region.y1;
|
||||
push_buf[14] = m_clip_region.x2;
|
||||
push_buf[15] = m_clip_region.y2;
|
||||
|
||||
// regs[4] = fs config parameters 2
|
||||
dst[16] = m_blur_strength;
|
||||
// 2. Fragment stuff
|
||||
rsx::overlays::fragment_options frag_opts;
|
||||
const auto frag_config = frag_opts
|
||||
.texture_mode(m_texture_type)
|
||||
.clip_fragments(m_clip_enabled)
|
||||
.pulse_glow(m_pulse_glow)
|
||||
.get();
|
||||
|
||||
// regs[5] = viewport
|
||||
dst[20] = m_viewport.width;
|
||||
dst[21] = m_viewport.height;
|
||||
dst[22] = m_viewport.x;
|
||||
dst[23] = m_viewport.y;
|
||||
std::memcpy(push_buf + 16, &frag_config, 4);
|
||||
//push_buf[16] = std::bit_cast<f32>(frag_config);
|
||||
push_buf[17] = m_time;
|
||||
push_buf[18] = m_blur_strength;
|
||||
|
||||
m_ubo.unmap();
|
||||
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 80, push_buf);
|
||||
}
|
||||
|
||||
void ui_overlay_renderer::set_primitive_type(rsx::overlays::primitive_type type)
|
||||
@ -757,13 +664,12 @@ namespace vk
|
||||
set_primitive_type(command.config.primitives);
|
||||
|
||||
m_time = command.config.get_sinus_value();
|
||||
m_skip_texture_read = false;
|
||||
m_texture_type = rsx::overlays::texture_sampling_mode::texture2D;
|
||||
m_color = command.config.color;
|
||||
m_pulse_glow = command.config.pulse_glow;
|
||||
m_blur_strength = static_cast<f32>(command.config.blur_strength) * 0.01f;
|
||||
m_clip_enabled = command.config.clip_region;
|
||||
m_clip_region = command.config.clip_rect;
|
||||
m_texture_type = 1;
|
||||
|
||||
vk::image_view* src = nullptr;
|
||||
switch (command.config.texture_ref)
|
||||
@ -772,11 +678,13 @@ namespace vk
|
||||
case rsx::overlays::image_resource_id::backbuffer:
|
||||
// TODO
|
||||
case rsx::overlays::image_resource_id::none:
|
||||
m_skip_texture_read = true;
|
||||
m_texture_type = rsx::overlays::texture_sampling_mode::none;
|
||||
break;
|
||||
case rsx::overlays::image_resource_id::font_file:
|
||||
src = find_font(command.config.font_ref, cmd, upload_heap);
|
||||
m_texture_type = src->image()->layers() == 1 ? 2 : 3;
|
||||
m_texture_type = src->image()->layers() == 1
|
||||
? rsx::overlays::texture_sampling_mode::font2D
|
||||
: rsx::overlays::texture_sampling_mode::font3D;
|
||||
break;
|
||||
case rsx::overlays::image_resource_id::raw_image:
|
||||
src = find_temp_image(static_cast<rsx::overlays::image_info*>(command.config.external_data_ref), cmd, upload_heap, ui.uid);
|
||||
|
@ -18,6 +18,7 @@ namespace rsx
|
||||
{
|
||||
namespace overlays
|
||||
{
|
||||
enum class texture_sampling_mode;
|
||||
struct overlay;
|
||||
}
|
||||
}
|
||||
@ -135,9 +136,8 @@ namespace vk
|
||||
color4f m_scale_offset;
|
||||
color4f m_color;
|
||||
bool m_pulse_glow = false;
|
||||
bool m_skip_texture_read = false;
|
||||
bool m_clip_enabled = false;
|
||||
int m_texture_type;
|
||||
rsx::overlays::texture_sampling_mode m_texture_type;
|
||||
areaf m_clip_region;
|
||||
coordf m_viewport;
|
||||
|
||||
@ -162,7 +162,9 @@ namespace vk
|
||||
vk::image_view* find_font(rsx::overlays::font* font, vk::command_buffer& cmd, vk::data_heap& upload_heap);
|
||||
vk::image_view* find_temp_image(rsx::overlays::image_info* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid);
|
||||
|
||||
void update_uniforms(vk::command_buffer& /*cmd*/, vk::glsl::program* /*program*/) override;
|
||||
std::vector<VkPushConstantRange> get_push_constants() override;
|
||||
|
||||
void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) override;
|
||||
|
||||
void set_primitive_type(rsx::overlays::primitive_type type);
|
||||
|
||||
|
@ -546,6 +546,7 @@
|
||||
<ClInclude Include="Emu\RSX\Program\GLSLTypes.h" />
|
||||
<ClInclude Include="Emu\RSX\Program\ProgramStateCache.h" />
|
||||
<ClInclude Include="Emu\RSX\Program\program_util.h" />
|
||||
<ClInclude Include="Emu\RSX\Program\RSXOverlay.h" />
|
||||
<ClInclude Include="Emu\RSX\Program\ShaderInterpreter.h" />
|
||||
<ClInclude Include="Emu\RSX\Common\texture_cache_helpers.h" />
|
||||
<ClInclude Include="Emu\RSX\Common\texture_cache_types.h" />
|
||||
@ -865,6 +866,8 @@
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\CopyRGBA8ToBuffer.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GenericVSPassthrough.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\OverlayRenderFS.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\OverlayRenderVS.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\ShuffleBytes.glsl" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
|
@ -2251,6 +2251,9 @@
|
||||
<ClInclude Include="Emu\RSX\Overlays\overlay_animated_icon.h">
|
||||
<Filter>Emu\GPU\RSX\Overlays</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\Program\RSXOverlay.h">
|
||||
<Filter>Emu\GPU\RSX\Program</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||
@ -2280,5 +2283,11 @@
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\CopyBufferToGenericImage.glsl">
|
||||
<Filter>Emu\GPU\RSX\Program\Snippets</Filter>
|
||||
</None>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\OverlayRenderVS.glsl">
|
||||
<Filter>Emu\GPU\RSX\Program\Snippets</Filter>
|
||||
</None>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\OverlayRenderFS.glsl">
|
||||
<Filter>Emu\GPU\RSX\Program\Snippets</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user