1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Implement N64 blending using framebuffer fetch extensions

This commit is contained in:
fzurita 2020-11-08 14:38:42 -05:00 committed by Sergey Lipskiy
parent d509758b6f
commit f01405bc75
10 changed files with 124 additions and 32 deletions

View File

@ -342,7 +342,7 @@ void DepthBuffer::bindDepthImageTexture(ObjectHandle _fbo)
bindParams.imageUnit = textureImageUnits::DepthDeltaZ;
bindParams.texture = m_pDepthImageDeltaZTexture->name;
gfxContext.bindImageTexture(bindParams);
} else if (Context::FramebufferFetch) {
} else if (Context::FramebufferFetchDepth) {
Context::FrameBufferRenderTarget targetParams;
targetParams.bufferHandle = _fbo;
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;

View File

@ -13,7 +13,8 @@ bool Context::ShaderProgramBinary = false;
bool Context::ImageTextures = false;
bool Context::IntegerTextures = false;
bool Context::ClipControl = false;
bool Context::FramebufferFetch = false;
bool Context::FramebufferFetchDepth = false;
bool Context::FramebufferFetchColor = false;
bool Context::TextureBarrier = false;
bool Context::EglImage = false;
bool Context::EglImageFramebuffer = false;
@ -39,7 +40,8 @@ void Context::init()
ImageTextures = m_impl->isSupported(SpecialFeatures::ImageTextures);
IntegerTextures = m_impl->isSupported(SpecialFeatures::IntegerTextures);
ClipControl = m_impl->isSupported(SpecialFeatures::ClipControl);
FramebufferFetch = m_impl->isSupported(SpecialFeatures::FramebufferFetch);
FramebufferFetchDepth = m_impl->isSupported(SpecialFeatures::FramebufferFetchDepth);
FramebufferFetchColor = m_impl->isSupported(SpecialFeatures::FramebufferFetchColor);
TextureBarrier = m_impl->isSupported(SpecialFeatures::TextureBarrier);
EglImage = m_impl->isSupported(SpecialFeatures::EglImage);
EglImageFramebuffer = m_impl->isSupported(SpecialFeatures::EglImageFramebuffer);

View File

@ -24,7 +24,8 @@ namespace graphics {
ImageTextures,
IntegerTextures,
ClipControl,
FramebufferFetch,
FramebufferFetchDepth,
FramebufferFetchColor,
TextureBarrier,
EglImage,
EglImageFramebuffer,
@ -299,7 +300,8 @@ namespace graphics {
static bool ImageTextures;
static bool IntegerTextures;
static bool ClipControl;
static bool FramebufferFetch;
static bool FramebufferFetchDepth;
static bool FramebufferFetchColor;
static bool TextureBarrier;
static bool EglImage;
static bool EglImageFramebuffer;

View File

@ -516,12 +516,16 @@ public:
ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl;
if (_glinfo.dual_source_blending)
ss << "#extension GL_EXT_blend_func_extended : enable" << std::endl;
if (_glinfo.ext_fetch)
ss << "#extension GL_EXT_shader_framebuffer_fetch : enable" << std::endl;
if (_glinfo.ext_fetch_arm)
ss << "#extension GL_ARM_shader_framebuffer_fetch : enable" << std::endl;
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast) {
if (_glinfo.imageTextures && _glinfo.fragment_interlockNV) {
ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
} else if (_glinfo.ext_fetch)
ss << "#extension GL_EXT_shader_framebuffer_fetch : enable" << std::endl;
}
}
ss << "# define IN in" << std::endl
<< "# define OUT out" << std::endl
@ -670,18 +674,29 @@ class ShaderBlenderAlpha : public ShaderPart
public:
ShaderBlenderAlpha(const opengl::GLInfo & _glinfo)
{
if (_glinfo.dual_source_blending)
m_part +=
"if (uBlendAlphaMode != 2) { \n"
" lowp float cvg = clampedColor.a; \n"
" lowp vec4 srcAlpha = vec4(cvg, cvg, 1.0, 0.0); \n"
" lowp vec4 dstFactorAlpha = vec4(1.0, 1.0, 0.0, 1.0); \n"
" if (uBlendAlphaMode == 0) \n"
" dstFactorAlpha[0] = 0.0; \n"
" fragColor.a = srcAlpha[uCvgDest]; \n"
" fragColor1.a = dstFactorAlpha[uCvgDest]; \n"
"} else fragColor.a = clampedColor.a; \n"
;
if (_glinfo.dual_source_blending) {
m_part +=
"if (uBlendAlphaMode != 2) { \n"
" lowp float cvg = clampedColor.a; \n"
" lowp vec4 srcAlpha = vec4(cvg, cvg, 1.0, 0.0); \n"
" lowp vec4 dstFactorAlpha = vec4(1.0, 1.0, 0.0, 1.0); \n"
" if (uBlendAlphaMode == 0) \n"
" dstFactorAlpha[0] = 0.0; \n"
" fragColor.a = srcAlpha[uCvgDest]; \n"
" fragColor1.a = dstFactorAlpha[uCvgDest]; \n"
"} else fragColor.a = clampedColor.a; \n";
} else if (_glinfo.ext_fetch || _glinfo.ext_fetch_arm) {
m_part +=
"if (uBlendAlphaMode != 2) { \n"
" lowp float cvg = clampedColor.a; \n"
" lowp vec4 srcAlpha = vec4(cvg, cvg, 1.0, 0.0); \n"
" lowp vec4 dstFactorAlpha = vec4(1.0, 1.0, 0.0, 1.0); \n"
" if (uBlendAlphaMode == 0) \n"
" dstFactorAlpha[0] = 0.0; \n"
" fragColor.a = srcAlpha[uCvgDest] + LAST_FRAG_COLOR_ALPHA * dstFactorAlpha[uCvgDest]; \n"
"} else fragColor.a = clampedColor.a; \n"
;
}
}
};
@ -993,11 +1008,28 @@ public:
m_part +=
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n"
;
"#define LAST_FRAG_COLOR vec4(0.0) \n"
"#define LAST_FRAG_COLOR_ALPHA 1.0 \n"
;
} else if (_glinfo.ext_fetch) {
m_part +=
"layout(location = 0) inout lowp vec4 realFragColor; \n"
"lowp vec4 fragColor; \n"
"#define LAST_FRAG_COLOR realFragColor \n"
"#define LAST_FRAG_COLOR_ALPHA realFragColor.a \n"
;
} else if (_glinfo.ext_fetch_arm) {
m_part +=
"OUT lowp vec4 fragColor; \n"
"#define LAST_FRAG_COLOR gl_LastFragColorARM \n"
"#define LAST_FRAG_COLOR_ALPHA gl_LastFragColorARM.a \n"
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
;
"#define LAST_FRAG_COLOR vec4(0.0) \n"
"#define LAST_FRAG_COLOR_ALPHA 1.0 \n"
;
}
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
@ -1082,12 +1114,31 @@ public:
if (_glinfo.dual_source_blending) {
m_part +=
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n"
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n"
"#define LAST_FRAG_COLOR vec4(0.0) \n"
"#define LAST_FRAG_COLOR_ALPHA 1.0 \n"
;
;
} else if (_glinfo.ext_fetch) {
m_part +=
"layout(location = 0) inout lowp vec4 realFragColor; \n"
"lowp vec4 fragColor; \n"
"#define LAST_FRAG_COLOR realFragColor \n"
"#define LAST_FRAG_COLOR_ALPHA realFragColor.a \n"
;
} else if (_glinfo.ext_fetch_arm) {
m_part +=
"OUT lowp vec4 fragColor; \n"
"#define LAST_FRAG_COLOR gl_LastFragColorARM \n"
"#define LAST_FRAG_COLOR_ALPHA gl_LastFragColorARM.a \n"
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
"OUT lowp vec4 fragColor; \n"
"#define LAST_FRAG_COLOR vec4(0.0) \n"
"#define LAST_FRAG_COLOR_ALPHA 1.0 \n"
;
;
}
@ -1502,13 +1553,17 @@ public:
" #define MUXB(pos) dot(muxB, STVEC(pos)) \n"
" #define MUXPM(pos) muxPM*(STVEC(pos)) \n"
" #define MUXF(pos) dot(muxF, STVEC(pos)) \n"
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n"
;
m_part +=
" lowp mat4 muxPM = mat4(vec4(0.0), LAST_FRAG_COLOR, uBlendColor, uFogColor); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, shadeColor.a, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, LAST_FRAG_COLOR_ALPHA, 1.0, 0.0); \n"
;
m_part +=
" lowp vec4 muxF = vec4(0.0, 1.0, 0.0, 0.0); \n"
" lowp vec4 muxp, muxm, srcColor1, srcColor2; \n"
" lowp float muxa, muxb, dstFactor1, dstFactor2, muxaf, muxbf; \n"
;
;
}
}
};
@ -1706,10 +1761,10 @@ public:
}
};
class ShaderFragmentMainEnd : public ShaderPart
class ShaderFragmentMainEndSpecial : public ShaderPart
{
public:
ShaderFragmentMainEnd(const opengl::GLInfo & _glinfo)
ShaderFragmentMainEndSpecial(const opengl::GLInfo & _glinfo)
{
if (_glinfo.isGLES2) {
m_part =
@ -1724,6 +1779,27 @@ public:
}
};
class ShaderFragmentMainEnd : public ShaderPart
{
public:
ShaderFragmentMainEnd(const opengl::GLInfo & _glinfo)
{
if (_glinfo.isGLES2) {
m_part =
" gl_FragColor = fragColor; \n"
"} \n\n";
} else if (!_glinfo.dual_source_blending && _glinfo.ext_fetch) {
m_part =
" realFragColor = fragColor; \n"
"} \n\n";
} else {
m_part =
"} \n\n"
;
}
}
};
class ShaderNoise : public ShaderPart
{
public:
@ -2859,7 +2935,7 @@ const ShaderPart * CombinerProgramBuilder::getFragmentShaderHeader() const
const ShaderPart * CombinerProgramBuilder::getFragmentShaderEnd() const
{
return m_shaderFragmentMainEnd.get();
return m_shaderFragmentMainEndSpecial.get();
}
static
@ -2923,6 +2999,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_glinfo))
, m_fragmentRenderTarget(new ShaderFragmentRenderTarget(_glinfo))
, m_shaderFragmentMainEnd(new ShaderFragmentMainEnd(_glinfo))
, m_shaderFragmentMainEndSpecial(new ShaderFragmentMainEndSpecial(_glinfo))
, m_shaderNoise(new ShaderNoise(_glinfo))
, m_shaderDither(new ShaderDither(_glinfo))
, m_shaderWriteDepth(new ShaderWriteDepth(_glinfo))

View File

@ -81,6 +81,7 @@ namespace glsl {
ShaderPartPtr m_fragmentCallN64Depth;
ShaderPartPtr m_fragmentRenderTarget;
ShaderPartPtr m_shaderFragmentMainEnd;
ShaderPartPtr m_shaderFragmentMainEndSpecial;
ShaderPartPtr m_shaderNoise;
ShaderPartPtr m_shaderDither;

View File

@ -20,7 +20,7 @@ namespace glsl {
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
const u32 m_formatVersion = 0x2EU;
const u32 m_formatVersion = 0x2FU;
const u32 m_keysFormatVersion = 0x04;
const opengl::GLInfo & m_glinfo;
opengl::CachedUseProgram * m_useProgram;

View File

@ -512,8 +512,10 @@ bool ContextImpl::isSupported(graphics::SpecialFeatures _feature) const
return !m_glInfo.isGLES2;
case graphics::SpecialFeatures::ClipControl:
return !m_glInfo.isGLESX;
case graphics::SpecialFeatures::FramebufferFetch:
case graphics::SpecialFeatures::FramebufferFetchDepth:
return m_glInfo.ext_fetch;
case graphics::SpecialFeatures::FramebufferFetchColor:
return m_glInfo.ext_fetch || m_glInfo.ext_fetch_arm;
case graphics::SpecialFeatures::TextureBarrier:
return m_glInfo.texture_barrier || m_glInfo.texture_barrierNV;
case graphics::SpecialFeatures::EglImage:

View File

@ -163,6 +163,7 @@ void GLInfo::init() {
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTexturesInterlock;
eglImage = (Utils::isEGLExtensionSupported("EGL_KHR_image_base") || Utils::isEGLExtensionSupported("EGL_KHR_image"));
ext_fetch_arm = Utils::isExtensionSupported(*this, "GL_ARM_shader_framebuffer_fetch") && !ext_fetch;
dual_source_blending = !isGLESX || (Utils::isExtensionSupported(*this, "GL_EXT_blend_func_extended") && !isAnyAdreno);

View File

@ -33,6 +33,7 @@ struct GLInfo {
bool fragment_interlockNV = false;
bool fragment_ordering = false;
bool ext_fetch = false;
bool ext_fetch_arm = false;
bool eglImage = false;
bool eglImageFramebuffer = false;
bool dual_source_blending = false;

View File

@ -23,6 +23,7 @@
#include "RSP.h"
#include "RDP.h"
#include "VI.h"
#include "Log.h"
using namespace graphics;
@ -675,6 +676,11 @@ void GraphicsDrawer::setBlendMode(bool _forceLegacyBlending) const
return;
}
if (Context::FramebufferFetchColor && !isTexrectDrawerMode()) {
gfxContext.enable(enable::BLEND, false);
return;
}
_ordinaryBlending();
}