GS/OpenGL: Move some uniform buffers to program uniforms

This commit is contained in:
Connor McLaughlin 2021-10-20 17:52:05 +10:00 committed by refractionpcsx2
parent 55695bb5bc
commit 4e1b2792c9
11 changed files with 43 additions and 137 deletions

View File

@ -31,11 +31,6 @@ layout(std140, binding = 14) uniform cb14
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
SamplerState TextureSampler : register(s0); SamplerState TextureSampler : register(s0);
cbuffer cb0
{
float4 _rcpFrame : register(c0);
};
struct VS_INPUT struct VS_INPUT
{ {
float4 p : POSITION; float4 p : POSITION;
@ -131,11 +126,6 @@ float RGBLuminance(float3 color)
return dot(color.rgb, lumCoeff); return dot(color.rgb, lumCoeff);
} }
#if (FXAA_GLSL_130 == 0)
#define PixelSize float2(_rcpFrame.x, _rcpFrame.y)
#endif
float3 RGBGammaToLinear(float3 color, float gamma) float3 RGBGammaToLinear(float3 color, float gamma)
{ {
color = FxaaSat(color); color = FxaaSat(color);
@ -502,6 +492,7 @@ float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
tex.tex = Texture; tex.tex = Texture;
tex.smpl = TextureSampler; tex.smpl = TextureSampler;
float2 PixelSize;
Texture.GetDimensions(PixelSize.x, PixelSize.y); Texture.GetDimensions(PixelSize.x, PixelSize.y);
FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin); FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);

View File

@ -44,15 +44,6 @@ out gl_PerVertex {
// Performance note, some drivers (nouveau) will validate all Constant Buffers // Performance note, some drivers (nouveau) will validate all Constant Buffers
// even if only one was updated. // even if only one was updated.
#ifdef FRAGMENT_SHADER
layout(std140, binding = 6) uniform cb15
{
int EMODA;
int EMODC;
ivec2 pad_cb15;
};
#endif
#if defined(VERTEX_SHADER) || defined(GEOMETRY_SHADER) #if defined(VERTEX_SHADER) || defined(GEOMETRY_SHADER)
layout(std140, binding = 1) uniform cb20 layout(std140, binding = 1) uniform cb20
{ {
@ -69,7 +60,7 @@ layout(std140, binding = 1) uniform cb20
#endif #endif
#if defined(VERTEX_SHADER) || defined(FRAGMENT_SHADER) #if defined(VERTEX_SHADER) || defined(FRAGMENT_SHADER)
layout(std140, binding = 2) uniform cb21 layout(std140, binding = 0) uniform cb21
{ {
vec3 FogColor; vec3 FogColor;
float AREF; float AREF;

View File

@ -388,6 +388,8 @@ void ps_mod256()
#endif #endif
#ifdef ps_yuv #ifdef ps_yuv
uniform ivec2 EMOD;
void ps_yuv() void ps_yuv()
{ {
vec4 i = sample_c(); vec4 i = sample_c();
@ -404,7 +406,7 @@ void ps_yuv()
float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f; float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f;
float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f; float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f;
switch(EMODA) { switch(EMOD.x) {
case 0: case 0:
o.a = i.a; o.a = i.a;
break; break;
@ -419,7 +421,7 @@ void ps_yuv()
break; break;
} }
switch(EMODC) { switch(EMOD.y) {
case 0: case 0:
o.rgb = i.rgb; o.rgb = i.rgb;
break; break;

View File

@ -9,11 +9,8 @@ in SHADER
#ifdef FRAGMENT_SHADER #ifdef FRAGMENT_SHADER
layout(std140, binding = 4) uniform cb11 uniform vec2 ZrH;
{ uniform float hH;
vec2 ZrH;
float hH;
};
layout(location = 0) out vec4 SV_Target0; layout(location = 0) out vec4 SV_Target0;

View File

@ -9,10 +9,7 @@ in SHADER
#ifdef FRAGMENT_SHADER #ifdef FRAGMENT_SHADER
layout(std140, binding = 3) uniform cb10 uniform vec4 BGColor;
{
vec4 BGColor;
};
layout(location = 0) out vec4 SV_Target0; layout(location = 0) out vec4 SV_Target0;

View File

@ -49,11 +49,8 @@ in SHADER
layout(location = 0) out vec4 SV_Target0; layout(location = 0) out vec4 SV_Target0;
layout(std140, binding = 14) uniform cb14 uniform vec2 _xyFrame;
{ uniform vec4 _rcpFrame;
vec2 _xyFrame;
vec4 _rcpFrame;
};
#else #else

View File

@ -97,15 +97,6 @@ public:
ExternalFXConstantBuffer() { memset(this, 0, sizeof(*this)); } ExternalFXConstantBuffer() { memset(this, 0, sizeof(*this)); }
}; };
class FXAAConstantBuffer
{
public:
GSVector4 rcpFrame;
GSVector4 rcpFrameOpt;
FXAAConstantBuffer() { memset(this, 0, sizeof(*this)); }
};
class ShadeBoostConstantBuffer class ShadeBoostConstantBuffer
{ {
public: public:

View File

@ -351,16 +351,6 @@ bool GSDevice11::Create(const WindowInfo& wi)
m_dev->CreateBuffer(&bd, nullptr, m_shaderfx.cb.put()); m_dev->CreateBuffer(&bd, nullptr, m_shaderfx.cb.put());
// Fxaa
memset(&bd, 0, sizeof(bd));
bd.ByteWidth = sizeof(FXAAConstantBuffer);
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
m_dev->CreateBuffer(&bd, nullptr, m_fxaa.cb.put());
// //
memset(&rd, 0, sizeof(rd)); memset(&rd, 0, sizeof(rd));
@ -954,9 +944,7 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
const GSVector4 sRect(0, 0, 1, 1); const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y); const GSVector4 dRect(0, 0, s.x, s.y);
FXAAConstantBuffer cb; if (!m_fxaa_ps)
if (m_fxaa.ps == nullptr)
{ {
try try
{ {
@ -964,7 +952,7 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
if (shader.has_value()) if (shader.has_value())
{ {
ShaderMacro sm(m_shader.model); ShaderMacro sm(m_shader.model);
CreateShader(*shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa.ps.put()); CreateShader(*shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa_ps.put());
} }
} }
catch (GSRecoverableError) catch (GSRecoverableError)
@ -973,12 +961,7 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
} }
} }
cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); StretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
cb.rcpFrameOpt = GSVector4::zero();
m_ctx->UpdateSubresource(m_fxaa.cb.get(), 0, nullptr, &cb, 0, 0);
StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps.get(), m_fxaa.cb.get(), true);
//sTex->Save("c:\\temp1\\1.bmp"); //sTex->Save("c:\\temp1\\1.bmp");
//dTex->Save("c:\\temp1\\2.bmp"); //dTex->Save("c:\\temp1\\2.bmp");

View File

@ -193,11 +193,7 @@ private:
wil::com_ptr_nothrow<ID3D11Buffer> cb; wil::com_ptr_nothrow<ID3D11Buffer> cb;
} m_shaderfx; } m_shaderfx;
struct wil::com_ptr_nothrow<ID3D11PixelShader> m_fxaa_ps;
{
wil::com_ptr_nothrow<ID3D11PixelShader> ps;
wil::com_ptr_nothrow<ID3D11Buffer> cb;
} m_fxaa;
struct struct
{ {

View File

@ -32,12 +32,8 @@ u64 g_vertex_upload_byte = 0;
u64 g_uniform_upload_byte = 0; u64 g_uniform_upload_byte = 0;
#endif #endif
static constexpr u32 g_merge_cb_index = 3;
static constexpr u32 g_interlace_cb_index = 4;
static constexpr u32 g_fx_cb_index = 14;
static constexpr u32 g_convert_index = 5;
static constexpr u32 g_vs_cb_index = 1; static constexpr u32 g_vs_cb_index = 1;
static constexpr u32 g_ps_cb_index = 2; static constexpr u32 g_ps_cb_index = 0;
static constexpr u32 VERTEX_BUFFER_SIZE = 32 * 1024 * 1024; static constexpr u32 VERTEX_BUFFER_SIZE = 32 * 1024 * 1024;
static constexpr u32 INDEX_BUFFER_SIZE = 16 * 1024 * 1024; static constexpr u32 INDEX_BUFFER_SIZE = 16 * 1024 * 1024;
@ -110,24 +106,9 @@ GSDeviceOGL::~GSDeviceOGL()
m_vertex_stream_buffer.reset(); m_vertex_stream_buffer.reset();
m_index_stream_buffer.reset(); m_index_stream_buffer.reset();
// Clean m_merge_obj
delete m_merge_obj.cb;
// Clean m_interlace
delete m_interlace.cb;
// Clean m_convert // Clean m_convert
delete m_convert.dss; delete m_convert.dss;
delete m_convert.dss_write; delete m_convert.dss_write;
delete m_convert.cb;
// Clean m_fxaa
delete m_fxaa.cb;
#ifndef PCSX2_CORE
// Clean m_shaderfx
delete m_shaderfx.cb;
#endif
// Clean m_date // Clean m_date
delete m_date.dss; delete m_date.dss;
@ -375,8 +356,6 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
{ {
GL_PUSH("GSDeviceOGL::Convert"); GL_PUSH("GSDeviceOGL::Convert");
m_convert.cb = new GSUniformBufferOGL("Misc UBO", g_convert_index, sizeof(MiscConstantBuffer));
// these all share the same vertex shader // these all share the same vertex shader
const auto shader = Host::ReadResourceFileToString("shaders/opengl/convert.glsl"); const auto shader = Host::ReadResourceFileToString("shaders/opengl/convert.glsl");
if (!shader.has_value()) if (!shader.has_value())
@ -394,6 +373,9 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
if (!m_shader_cache.GetProgram(&m_convert.ps[i], m_convert.vs, {}, ps)) if (!m_shader_cache.GetProgram(&m_convert.ps[i], m_convert.vs, {}, ps))
return false; return false;
m_convert.ps[i].SetFormattedName("Convert pipe %s", name); m_convert.ps[i].SetFormattedName("Convert pipe %s", name);
if (static_cast<ShaderConvert>(i) == ShaderConvert::YUV)
m_convert.ps[i].RegisterUniform("EMOD");
} }
PSSamplerSelector point; PSSamplerSelector point;
@ -415,10 +397,6 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
{ {
GL_PUSH("GSDeviceOGL::Merge"); GL_PUSH("GSDeviceOGL::Merge");
static const float default_merge_cb[4] = {};
m_merge_obj.cb = new GSUniformBufferOGL("Merge UBO", g_merge_cb_index, sizeof(MergeConstantBuffer));
m_merge_obj.cb->upload(default_merge_cb);
const auto shader = Host::ReadResourceFileToString("shaders/opengl/merge.glsl"); const auto shader = Host::ReadResourceFileToString("shaders/opengl/merge.glsl");
if (!shader.has_value()) if (!shader.has_value())
return false; return false;
@ -429,6 +407,7 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
if (!m_shader_cache.GetProgram(&m_merge_obj.ps[i], m_convert.vs, {}, ps)) if (!m_shader_cache.GetProgram(&m_merge_obj.ps[i], m_convert.vs, {}, ps))
return false; return false;
m_merge_obj.ps[i].SetFormattedName("Merge pipe %zu", i); m_merge_obj.ps[i].SetFormattedName("Merge pipe %zu", i);
m_merge_obj.ps[i].RegisterUniform("BGColor");
} }
} }
@ -438,10 +417,6 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
{ {
GL_PUSH("GSDeviceOGL::Interlace"); GL_PUSH("GSDeviceOGL::Interlace");
m_interlace.cb = new GSUniformBufferOGL("Interlace UBO", g_interlace_cb_index, sizeof(InterlaceConstantBuffer));
InterlaceConstantBuffer interlace_cb;
m_interlace.cb->upload(&interlace_cb);
const auto shader = Host::ReadResourceFileToString("shaders/opengl/interlace.glsl"); const auto shader = Host::ReadResourceFileToString("shaders/opengl/interlace.glsl");
if (!shader.has_value()) if (!shader.has_value())
return false; return false;
@ -452,6 +427,8 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
if (!m_shader_cache.GetProgram(&m_interlace.ps[i], m_convert.vs, {}, ps)) if (!m_shader_cache.GetProgram(&m_interlace.ps[i], m_convert.vs, {}, ps))
return false; return false;
m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i); m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i);
m_interlace.ps[i].RegisterUniform("ZrH");
m_interlace.ps[i].RegisterUniform("hH");
} }
} }
@ -1323,15 +1300,6 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
OMSetColorMaskState(); OMSetColorMaskState();
ClearRenderTarget(dTex, c); ClearRenderTarget(dTex, c);
// Upload constant to select YUV algo
if (feedback_write_2 || feedback_write_1)
{
// Write result to feedback loop
m_misc_cb_cache.EMOD_AC.x = EXTBUF.EMODA;
m_misc_cb_cache.EMOD_AC.y = EXTBUF.EMODC;
m_convert.cb->cache_upload(&m_misc_cb_cache);
}
if (sTex[1] && (PMODE.SLBG == 0 || feedback_write_2_but_blend_bg)) if (sTex[1] && (PMODE.SLBG == 0 || feedback_write_2_but_blend_bg))
{ {
// 2nd output is enabled and selected. Copy it to destination so we can blend it with 1st output // 2nd output is enabled and selected. Copy it to destination so we can blend it with 1st output
@ -1339,6 +1307,14 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
StretchRect(sTex[1], sRect[1], dTex, dRect[1], ShaderConvert::COPY); StretchRect(sTex[1], sRect[1], dTex, dRect[1], ShaderConvert::COPY);
} }
// Upload constant to select YUV algo
if (feedback_write_2 || feedback_write_1)
{
// Write result to feedback loop
m_convert.ps[static_cast<int>(ShaderConvert::YUV)].Bind();
m_convert.ps[static_cast<int>(ShaderConvert::YUV)].Uniform2i(0, EXTBUF.EMODA, EXTBUF.EMODC);
}
// Save 2nd output // Save 2nd output
if (feedback_write_2) // FIXME I'm not sure dRect[1] is always correct if (feedback_write_2) // FIXME I'm not sure dRect[1] is always correct
StretchRect(dTex, full_r, sTex[2], dRect[1], ShaderConvert::YUV); StretchRect(dTex, full_r, sTex[2], dRect[1], ShaderConvert::YUV);
@ -1356,7 +1332,8 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
if (PMODE.MMOD == 1) if (PMODE.MMOD == 1)
{ {
// Blend with a constant alpha // Blend with a constant alpha
m_merge_obj.cb->cache_upload(&c.v); m_merge_obj.ps[1].Bind();
m_merge_obj.ps[1].Uniform4fv(0, c.v);
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], m_MERGE_BLEND, OMColorMaskSelector()); StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], m_MERGE_BLEND, OMColorMaskSelector());
} }
else else
@ -1381,12 +1358,9 @@ void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
const GSVector4 sRect(0, 0, 1, 1); const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0.0f, yoffset, s.x, s.y + yoffset); const GSVector4 dRect(0.0f, yoffset, s.x, s.y + yoffset);
InterlaceConstantBuffer cb; m_interlace.ps[shader].Bind();
m_interlace.ps[shader].Uniform2f(0, 0, 1.0f / s.y);
cb.ZrH = GSVector2(0, 1.0f / s.y); m_interlace.ps[shader].Uniform1f(1, s.y / 2);
cb.hH = s.y / 2;
m_interlace.cb->cache_upload(&cb);
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear); StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear);
} }
@ -1456,10 +1430,13 @@ void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
shader << fshader.rdbuf(); shader << fshader.rdbuf();
m_shaderfx.cb = new GSUniformBufferOGL("eFX UBO", g_fx_cb_index, sizeof(ExternalFXConstantBuffer));
const std::string ps(GetShaderSource("ps_main", GL_FRAGMENT_SHADER, m_shader_common_header, shader.str(), config.str())); const std::string ps(GetShaderSource("ps_main", GL_FRAGMENT_SHADER, m_shader_common_header, shader.str(), config.str()));
if (!m_shaderfx.ps.Compile(m_convert.vs, {}, ps) || !m_shaderfx.ps.Link()) if (!m_shaderfx.ps.Compile(m_convert.vs, {}, ps) || !m_shaderfx.ps.Link())
return; return;
m_shaderfx.ps.RegisterUniform("_xyFrame");
m_shaderfx.ps.RegisterUniform("_rcpFrame");
m_shaderfx.ps.RegisterUniform("_rcpFrameOpt");
} }
GL_PUSH("DoExternalFX"); GL_PUSH("DoExternalFX");
@ -1471,13 +1448,10 @@ void GSDeviceOGL::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
const GSVector4 sRect(0, 0, 1, 1); const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0, 0, s.x, s.y); const GSVector4 dRect(0, 0, s.x, s.y);
ExternalFXConstantBuffer cb; m_shaderfx.ps.Bind();
m_shaderfx.ps.Uniform2f(0, (float)s.x, (float)s.y);
cb.xyFrame = GSVector2((float)s.x, (float)s.y); m_shaderfx.ps.Uniform4f(1, 1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f);
cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); m_shaderfx.ps.Uniform4f(2, 0.0f, 0.0f, 0.0f, 0.0f);
cb.rcpFrameOpt = GSVector4::zero();
m_shaderfx.cb->cache_upload(&cb);
StretchRect(sTex, sRect, dTex, dRect, m_shaderfx.ps, true); StretchRect(sTex, sRect, dTex, dRect, m_shaderfx.ps, true);
#endif #endif

View File

@ -183,13 +183,6 @@ public:
using OMDepthStencilSelector = GSHWDrawConfig::DepthStencilSelector; using OMDepthStencilSelector = GSHWDrawConfig::DepthStencilSelector;
using OMColorMaskSelector = GSHWDrawConfig::ColorMaskSelector; using OMColorMaskSelector = GSHWDrawConfig::ColorMaskSelector;
struct alignas(32) MiscConstantBuffer
{
GSVector4i EMOD_AC;
MiscConstantBuffer() { memset(this, 0, sizeof(*this)); }
};
struct ProgramSelector struct ProgramSelector
{ {
VSSelector vs; VSSelector vs;
@ -247,13 +240,11 @@ private:
struct struct
{ {
GL::Program ps[2]; // program object GL::Program ps[2]; // program object
GSUniformBufferOGL* cb; // uniform buffer object
} m_merge_obj; } m_merge_obj;
struct struct
{ {
GL::Program ps[4]; // program object GL::Program ps[4]; // program object
GSUniformBufferOGL* cb; // uniform buffer object
} m_interlace; } m_interlace;
struct struct
@ -264,20 +255,17 @@ private:
GLuint pt; // sampler object GLuint pt; // sampler object
GSDepthStencilOGL* dss; GSDepthStencilOGL* dss;
GSDepthStencilOGL* dss_write; GSDepthStencilOGL* dss_write;
GSUniformBufferOGL* cb;
} m_convert; } m_convert;
struct struct
{ {
GL::Program ps; GL::Program ps;
GSUniformBufferOGL* cb;
} m_fxaa; } m_fxaa;
#ifndef PCSX2_CORE #ifndef PCSX2_CORE
struct struct
{ {
GL::Program ps; GL::Program ps;
GSUniformBufferOGL* cb;
} m_shaderfx; } m_shaderfx;
#endif #endif
@ -309,7 +297,6 @@ private:
GSHWDrawConfig::VSConstantBuffer m_vs_cb_cache; GSHWDrawConfig::VSConstantBuffer m_vs_cb_cache;
GSHWDrawConfig::PSConstantBuffer m_ps_cb_cache; GSHWDrawConfig::PSConstantBuffer m_ps_cb_cache;
MiscConstantBuffer m_misc_cb_cache;
std::unique_ptr<GSTexture> m_font; std::unique_ptr<GSTexture> m_font;
AlignedBuffer<u8, 32> m_download_buffer; AlignedBuffer<u8, 32> m_download_buffer;