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:
parent
d509758b6f
commit
f01405bc75
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -81,6 +81,7 @@ namespace glsl {
|
|||
ShaderPartPtr m_fragmentCallN64Depth;
|
||||
ShaderPartPtr m_fragmentRenderTarget;
|
||||
ShaderPartPtr m_shaderFragmentMainEnd;
|
||||
ShaderPartPtr m_shaderFragmentMainEndSpecial;
|
||||
|
||||
ShaderPartPtr m_shaderNoise;
|
||||
ShaderPartPtr m_shaderDither;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user