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

Add support for ext_shader_framebuffer_fetch

This commit is contained in:
Logan McNaughton 2018-04-12 09:15:45 -06:00 committed by Sergey Lipskiy
parent 2e227cef53
commit c9cf91e8da
17 changed files with 224 additions and 76 deletions

View File

@ -317,21 +317,34 @@ void DepthBuffer::activateDepthBufferTexture(FrameBuffer * _pBuffer)
gfxContext.textureBarrier();
}
void DepthBuffer::bindDepthImageTexture()
void DepthBuffer::bindDepthImageTexture(ObjectHandle _fbo)
{
if (!Context::ImageTextures)
return;
if (Context::ImageTextures) {
Context::BindImageTextureParameters bindParams;
bindParams.imageUnit = textureImageUnits::DepthZ;
bindParams.texture = m_pDepthImageZTexture->name;
bindParams.accessMode = textureImageAccessMode::READ_WRITE;
bindParams.textureFormat = gfxContext.getFramebufferTextureFormats().depthImageInternalFormat;
gfxContext.bindImageTexture(bindParams);
Context::BindImageTextureParameters bindParams;
bindParams.imageUnit = textureImageUnits::DepthZ;
bindParams.texture = m_pDepthImageZTexture->name;
bindParams.accessMode = textureImageAccessMode::READ_WRITE;
bindParams.textureFormat = gfxContext.getFramebufferTextureFormats().depthImageInternalFormat;
gfxContext.bindImageTexture(bindParams);
bindParams.imageUnit = textureImageUnits::DepthDeltaZ;
bindParams.texture = m_pDepthImageDeltaZTexture->name;
gfxContext.bindImageTexture(bindParams);
} else if (Context::FramebufferFetch) {
Context::FrameBufferRenderTarget targetParams;
targetParams.bufferHandle = _fbo;
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
targetParams.attachment = bufferAttachment::COLOR_ATTACHMENT1;
targetParams.textureHandle = m_pDepthImageZTexture->name;
targetParams.textureTarget = textureTarget::TEXTURE_2D;
gfxContext.addFrameBufferRenderTarget(targetParams);
bindParams.imageUnit = textureImageUnits::DepthDeltaZ;
bindParams.texture = m_pDepthImageDeltaZTexture->name;
gfxContext.bindImageTexture(bindParams);
targetParams.attachment = bufferAttachment::COLOR_ATTACHMENT2;
targetParams.textureHandle = m_pDepthImageDeltaZTexture->name;
gfxContext.addFrameBufferRenderTarget(targetParams);
gfxContext.setDrawBuffers(3);
}
}
DepthBufferList::DepthBufferList() : m_pCurrent(nullptr), m_pzLUT(nullptr)

View File

@ -20,7 +20,7 @@ struct DepthBuffer
void setDepthAttachment(graphics::ObjectHandle _fbo, graphics::BufferTargetParam _target);
void activateDepthBufferTexture(FrameBuffer * _pBuffer);
void bindDepthImageTexture();
void bindDepthImageTexture(graphics::ObjectHandle _fbo);
u32 m_address, m_width;
u32 m_ulx, m_uly, m_lrx, m_lry; // Parameters of fillrect command.

View File

@ -807,7 +807,7 @@ void FrameBufferList::attachDepthBuffer()
pCurrent->m_pDepthBuffer = pDepthBuffer;
pDepthBuffer->setDepthAttachment(pCurrent->m_FBO, bufferTarget::DRAW_FRAMEBUFFER);
if (config.frameBufferEmulation.N64DepthCompare != 0)
pDepthBuffer->bindDepthImageTexture();
pDepthBuffer->bindDepthImageTexture(pCurrent->m_FBO);
} else
pCurrent->m_pDepthBuffer = nullptr;
} else

View File

@ -13,6 +13,7 @@ bool Context::ShaderProgramBinary = false;
bool Context::ImageTextures = false;
bool Context::IntegerTextures = false;
bool Context::ClipControl = false;
bool Context::FramebufferFetch = false;
Context::Context() {}
@ -34,6 +35,7 @@ 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);
}
void Context::destroy()
@ -214,6 +216,11 @@ bool Context::blitFramebuffers(const BlitFramebuffersParams & _params)
return m_impl->blitFramebuffers(_params);
}
void Context::setDrawBuffers(u32 _num)
{
m_impl->setDrawBuffers(_num);
}
PixelReadBuffer * Context::createPixelReadBuffer(size_t _sizeInBytes)
{
return m_impl->createPixelReadBuffer(_sizeInBytes);

View File

@ -23,7 +23,8 @@ namespace graphics {
ShaderProgramBinary,
ImageTextures,
IntegerTextures,
ClipControl
ClipControl,
FramebufferFetch
};
enum class ClampMode {
@ -202,6 +203,8 @@ namespace graphics {
bool blitFramebuffers(const BlitFramebuffersParams & _params);
void setDrawBuffers(u32 _num);
/*---------------Pixelbuffer-------------*/
PixelReadBuffer * createPixelReadBuffer(size_t _sizeInBytes);
@ -281,6 +284,7 @@ namespace graphics {
static bool ImageTextures;
static bool IntegerTextures;
static bool ClipControl;
static bool FramebufferFetch;
private:
std::unique_ptr<ContextImpl> m_impl;

View File

@ -46,6 +46,7 @@ namespace graphics {
virtual ObjectHandle createRenderbuffer() = 0;
virtual void initRenderbuffer(const Context::InitRenderbufferParams & _params) = 0;
virtual bool blitFramebuffers(const Context::BlitFramebuffersParams & _params) = 0;
virtual void setDrawBuffers(u32 _num) = 0;
virtual PixelReadBuffer * createPixelReadBuffer(size_t _sizeInBytes) = 0;
virtual ColorBufferReader * createColorBufferReader(CachedTexture * _pTexture) = 0;
virtual bool isCombinerProgramBuilderObsolete() = 0;

View File

@ -192,6 +192,9 @@ PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC g_glDrawRangeElementsBaseVertex;
PFNGLFLUSHMAPPEDBUFFERRANGEPROC g_glFlushMappedBufferRange;
PFNGLTEXTUREBARRIERPROC g_glTextureBarrier;
PFNGLTEXTUREBARRIERNVPROC g_glTextureBarrierNV;
PFNGLCLEARBUFFERFVPROC g_glClearBufferfv;
PFNGLENABLEIPROC g_glEnablei;
PFNGLDISABLEIPROC g_glDisablei;
void initGLFunctions()
{
@ -334,4 +337,7 @@ void initGLFunctions()
GL_GET_PROC_ADR(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, glFlushMappedBufferRange);
GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERPROC, glTextureBarrier);
GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERNVPROC, glTextureBarrierNV);
GL_GET_PROC_ADR(PFNGLCLEARBUFFERFVPROC, glClearBufferfv);
GL_GET_PROC_ADR(PFNGLENABLEIPROC, glEnablei);
GL_GET_PROC_ADR(PFNGLDISABLEIPROC, glDisablei);
}

View File

@ -216,6 +216,9 @@ extern PFNGLBLENDCOLORPROC g_glBlendColor;
#define glFlushMappedBufferRange(...) CHECKED_GL_FUNCTION(g_glFlushMappedBufferRange, __VA_ARGS__)
#define glTextureBarrier(...) CHECKED_GL_FUNCTION(g_glTextureBarrier, __VA_ARGS__)
#define glTextureBarrierNV(...) CHECKED_GL_FUNCTION(g_glTextureBarrierNV, __VA_ARGS__)
#define glClearBufferfv(...) CHECKED_GL_FUNCTION(g_glClearBufferfv, __VA_ARGS__)
#define glEnablei(...) CHECKED_GL_FUNCTION(g_glEnablei, __VA_ARGS__)
#define glDisablei(...) CHECKED_GL_FUNCTION(g_glDisablei, __VA_ARGS__)
extern PFNGLCREATESHADERPROC g_glCreateShader;
extern PFNGLCOMPILESHADERPROC g_glCompileShader;
@ -312,6 +315,9 @@ extern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC g_glDrawRangeElementsBaseVertex;
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC g_glFlushMappedBufferRange;
extern PFNGLTEXTUREBARRIERPROC g_glTextureBarrier;
extern PFNGLTEXTUREBARRIERNVPROC g_glTextureBarrierNV;
extern PFNGLCLEARBUFFERFVPROC g_glClearBufferfv;
extern PFNGLENABLEIPROC g_glEnablei;
extern PFNGLDISABLEIPROC g_glDisablei;
void initGLFunctions();

View File

@ -460,9 +460,11 @@ public:
if (_glinfo.noPerspective)
ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (_glinfo.fragment_interlockNV)
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
@ -472,18 +474,21 @@ public:
std::stringstream ss;
ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 core " << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (_glinfo.majorVersion * 10 + _glinfo.minorVersion < 42) {
ss << "#extension GL_ARB_shader_image_load_store : enable" << std::endl
<< "#extension GL_ARB_shading_language_420pack : enable" << std::endl;
}
if (_glinfo.fragment_interlock)
ss << "#extension GL_ARB_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
else if (_glinfo.fragment_interlockNV)
ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
else if (_glinfo.fragment_ordering)
ss << "#extension GL_INTEL_fragment_shader_ordering : enable" << std::endl;
if (_glinfo.imageTextures) {
if (_glinfo.majorVersion * 10 + _glinfo.minorVersion < 42) {
ss << "#extension GL_ARB_shader_image_load_store : enable" << std::endl
<< "#extension GL_ARB_shading_language_420pack : enable" << std::endl;
}
if (_glinfo.fragment_interlock)
ss << "#extension GL_ARB_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
else if (_glinfo.fragment_interlockNV)
ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
else if (_glinfo.fragment_ordering)
ss << "#extension GL_INTEL_fragment_shader_ordering : enable" << 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
@ -790,8 +795,19 @@ public:
"IN highp vec2 vTexCoord1;\n"
"IN mediump vec2 vLodTexCoord;\n"
"IN lowp float vNumLights; \n"
"OUT lowp vec4 fragColor; \n"
;
;
if (config.frameBufferEmulation.N64DepthCompare != 0 && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 2) inout highp vec4 depthDeltaZ; \n"
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
;
}
}
};
@ -855,7 +871,19 @@ public:
m_part +=
"IN lowp vec4 vShadeColor; \n"
"IN lowp float vNumLights; \n"
"OUT lowp vec4 fragColor; \n";
;
if (config.frameBufferEmulation.N64DepthCompare != 0 && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 2) inout highp vec4 depthDeltaZ; \n"
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
;
}
}
};
@ -955,13 +983,16 @@ public:
ShaderFragmentHeaderDepthCompare(const opengl::GLInfo & _glinfo)
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
m_part +=
"layout(binding = 2, r32f) highp uniform restrict image2D uDepthImageZ; \n"
"layout(binding = 3, r32f) highp uniform restrict image2D uDepthImageDeltaZ;\n"
"bool depth_compare(highp float curZ);\n"
"bool depth_render(highp float Z, highp float curZ);\n";
;
m_part =
"bool depth_compare(highp float curZ); \n"
"bool depth_render(highp float Z, highp float curZ); \n"
;
if (_glinfo.imageTextures) {
m_part +=
"layout(binding = 2, r32f) highp uniform restrict image2D uDepthImageZ; \n"
"layout(binding = 3, r32f) highp uniform restrict image2D uDepthImageDeltaZ; \n"
;
}
}
}
};
@ -1333,22 +1364,26 @@ public:
if (config.frameBufferEmulation.N64DepthCompare != 0) {
m_part = " bool should_discard = false; \n";
if (_glinfo.fragment_interlock)
m_part += " beginInvocationInterlockARB(); \n";
else if (_glinfo.fragment_interlockNV)
m_part += " beginInvocationInterlockNV(); \n";
else if (_glinfo.fragment_ordering)
m_part += " beginFragmentShaderOrderingINTEL(); \n";
if (_glinfo.imageTextures) {
if (_glinfo.fragment_interlock)
m_part += " beginInvocationInterlockARB(); \n";
else if (_glinfo.fragment_interlockNV)
m_part += " beginInvocationInterlockNV(); \n";
else if (_glinfo.fragment_ordering)
m_part += " beginFragmentShaderOrderingINTEL(); \n";
}
m_part +=
" if (uRenderTarget != 0) { if (!depth_render(fragColor.r, fragDepth)) should_discard = true; } \n"
" else if (!depth_compare(fragDepth)) should_discard = true; \n"
;
if (_glinfo.fragment_interlock)
m_part += " endInvocationInterlockARB(); \n";
else if (_glinfo.fragment_interlockNV)
m_part += " endInvocationInterlockNV(); \n";
if (_glinfo.imageTextures) {
if (_glinfo.fragment_interlock)
m_part += " endInvocationInterlockARB(); \n";
else if (_glinfo.fragment_interlockNV)
m_part += " endInvocationInterlockNV(); \n";
}
m_part += " if (should_discard) discard; \n";
@ -1918,9 +1953,15 @@ public:
"uniform mediump float uDeltaZ; \n"
"bool depth_compare(highp float curZ) \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" highp vec4 depthZ = imageLoad(uDepthImageZ,coord); \n"
" highp vec4 depthDeltaZ = imageLoad(uDepthImageDeltaZ,coord);\n"
;
if (_glinfo.imageTextures) {
m_part +=
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" highp vec4 depthZ = imageLoad(uDepthImageZ,coord); \n"
" highp vec4 depthDeltaZ = imageLoad(uDepthImageDeltaZ,coord);\n"
;
}
m_part +=
" highp float bufZ = depthZ.r; \n"
" highp float dz, dzMin; \n"
" if (uDepthSource == 1) { \n"
@ -1950,10 +1991,21 @@ public:
" break; \n"
" } \n"
" if (uEnableDepthUpdate != 0 && bRes) { \n"
" highp vec4 depthOutZ = vec4(curZ, 1.0, 1.0, 1.0); \n"
" highp vec4 depthOutDeltaZ = vec4(dz, 1.0, 1.0, 1.0); \n"
" imageStore(uDepthImageZ, coord, depthOutZ); \n"
" imageStore(uDepthImageDeltaZ, coord, depthOutDeltaZ);\n"
;
if (_glinfo.imageTextures) {
m_part +=
" highp vec4 depthOutZ = vec4(curZ, 1.0, 1.0, 1.0); \n"
" highp vec4 depthOutDeltaZ = vec4(dz, 1.0, 1.0, 1.0); \n"
" imageStore(uDepthImageZ, coord, depthOutZ); \n"
" imageStore(uDepthImageDeltaZ, coord, depthOutDeltaZ); \n"
;
} else if (_glinfo.ext_fetch) {
m_part +=
" depthZ.r = curZ; \n"
" depthDeltaZ.r = dz; \n"
;
}
m_part +=
" } \n"
" if (uEnableDepthCompare != 0) \n"
" return bRes; \n"
@ -1975,17 +2027,34 @@ public:
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" if (uEnableDepthCompare != 0) { \n"
" highp vec4 depthZ = imageLoad(uDepthImageZ,coord); \n"
;
if (_glinfo.imageTextures) {
m_part +=
" highp vec4 depthZ = imageLoad(uDepthImageZ,coord); \n"
;
}
m_part +=
" highp float bufZ = depthZ.r; \n"
" if (curZ >= bufZ) return false; \n"
" } \n"
" highp vec4 depthOutZ = vec4(Z, 1.0, 1.0, 1.0); \n"
" highp vec4 depthOutDeltaZ = vec4(0.0, 1.0, 1.0, 1.0);\n"
" imageStore(uDepthImageZ,coord, depthOutZ); \n"
" imageStore(uDepthImageDeltaZ,coord, depthOutDeltaZ); \n"
;
if (_glinfo.imageTextures) {
m_part +=
" highp vec4 depthOutZ = vec4(Z, 1.0, 1.0, 1.0); \n"
" highp vec4 depthOutDeltaZ = vec4(0.0, 1.0, 1.0, 1.0);\n"
" imageStore(uDepthImageZ,coord, depthOutZ); \n"
" imageStore(uDepthImageDeltaZ,coord, depthOutDeltaZ); \n"
;
} else if (_glinfo.ext_fetch) {
m_part +=
" depthZ.r = Z; \n"
" depthDeltaZ.r = 0.0; \n"
;
}
m_part +=
" return true; \n"
"} \n"
;
;
}
}
};

View File

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

View File

@ -1,3 +1,5 @@
#include <Graphics/Parameters.h>
#include "GLFunctions.h"
#include "opengl_GLInfo.h"
#include "opengl_CachedFunctions.h"
@ -21,9 +23,15 @@ void CachedEnable::enable(bool _enable)
return;
if (_enable) {
glEnable(GLenum(m_parameter));
if (m_parameter == enable::BLEND && IS_GL_FUNCTION_VALID(glEnablei))
glEnablei(GLenum(m_parameter), 0);
else
glEnable(GLenum(m_parameter));
} else {
glDisable(GLenum(m_parameter));
if (m_parameter == enable::BLEND && IS_GL_FUNCTION_VALID(glDisablei))
glDisablei(GLenum(m_parameter), 0);
else
glDisable(GLenum(m_parameter));
}
}

View File

@ -161,8 +161,13 @@ void ContextImpl::clearColorBuffer(f32 _red, f32 _green, f32 _blue, f32 _alpha)
CachedEnable * enableScissor = m_cachedFunctions->getCachedEnable(graphics::enable::SCISSOR_TEST);
enableScissor->enable(false);
m_cachedFunctions->getCachedClearColor()->setClearColor(_red, _green, _blue, _alpha);
glClear(GL_COLOR_BUFFER_BIT);
if (m_glInfo.isGLES2) {
m_cachedFunctions->getCachedClearColor()->setClearColor(_red, _green, _blue, _alpha);
glClear(GL_COLOR_BUFFER_BIT);
} else {
GLfloat values[4] = {_red, _green, _blue, _alpha};
glClearBufferfv(GL_COLOR, 0, values);
}
enableScissor->enable(true);
}
@ -255,8 +260,7 @@ s32 ContextImpl::getMaxTextureSize() const
void ContextImpl::bindImageTexture(const graphics::Context::BindImageTextureParameters & _params)
{
if (IS_GL_FUNCTION_VALID(glBindImageTexture))
glBindImageTexture(GLuint(_params.imageUnit), GLuint(_params.texture), 0, GL_FALSE, 0, GLenum(_params.accessMode), GLenum(_params.textureFormat));
glBindImageTexture(GLuint(_params.imageUnit), GLuint(_params.texture), 0, GL_FALSE, 0, GLenum(_params.accessMode), GLenum(_params.textureFormat));
}
u32 ContextImpl::convertInternalTextureFormat(u32 _format) const
@ -336,6 +340,12 @@ bool ContextImpl::blitFramebuffers(const graphics::Context::BlitFramebuffersPara
return m_blitFramebuffers->blitFramebuffers(_params);
}
void ContextImpl::setDrawBuffers(u32 _num)
{
GLenum targets[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(_num, targets);
}
graphics::PixelReadBuffer * ContextImpl::createPixelReadBuffer(size_t _sizeInBytes)
{
if (m_createPixelReadBuffer)
@ -479,6 +489,8 @@ bool ContextImpl::isSupported(graphics::SpecialFeatures _feature) const
return !m_glInfo.isGLES2;
case graphics::SpecialFeatures::ClipControl:
return !m_glInfo.isGLESX;
case graphics::SpecialFeatures::FramebufferFetch:
return m_glInfo.ext_fetch;
}
return false;
}

View File

@ -96,6 +96,8 @@ namespace opengl {
bool blitFramebuffers(const graphics::Context::BlitFramebuffersParams & _params) override;
void setDrawBuffers(u32 _num) override;
/*---------------Pixelbuffer-------------*/
graphics::PixelReadBuffer * createPixelReadBuffer(size_t _sizeInBytes) override;

View File

@ -47,11 +47,11 @@ void GLInfo::init() {
imageTextures = false;
msaa = false;
} else if (isGLESX) {
imageTextures = (numericVersion >= 31) && IS_GL_FUNCTION_VALID(glBindImageTexture);
imageTextures = (numericVersion >= 31);
msaa = numericVersion >= 31;
} else {
imageTextures = ((numericVersion >= 43) || (Utils::isExtensionSupported(*this, "GL_ARB_shader_image_load_store") &&
Utils::isExtensionSupported(*this, "GL_ARB_compute_shader"))) && IS_GL_FUNCTION_VALID(glBindImageTexture);
Utils::isExtensionSupported(*this, "GL_ARB_compute_shader")));
msaa = true;
}
@ -59,12 +59,7 @@ void GLInfo::init() {
fragment_interlockNV = Utils::isExtensionSupported(*this, "GL_NV_fragment_shader_interlock") && !fragment_interlock;
fragment_ordering = Utils::isExtensionSupported(*this, "GL_INTEL_fragment_shader_ordering") && !fragment_interlock && !fragment_interlockNV;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (!(imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering))) {
config.frameBufferEmulation.N64DepthCompare = 0;
LOG(LOG_WARNING, "Your GPU does not support the extensions needed for N64 Depth Compare.\n");
}
}
imageTextures = imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering);
if (isGLES2)
config.generalEmulation.enableFragmentDepthWrite = 0;
@ -87,12 +82,23 @@ void GLInfo::init() {
}
}
bool ext_draw_buffers_indexed = isGLESX && (Utils::isExtensionSupported(*this, "GL_EXT_draw_buffers_indexed") || numericVersion >= 32);
#ifdef EGL
if (isGLESX && bufferStorage)
g_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) eglGetProcAddress("glBufferStorageEXT");
if (isGLESX && numericVersion < 32) {
if (ext_draw_buffers_indexed) {
g_glEnablei = (PFNGLENABLEIPROC) eglGetProcAddress("glEnableiEXT");
g_glDisablei = (PFNGLDISABLEIPROC) eglGetProcAddress("glDisableiEXT");
} else {
g_glEnablei = nullptr;
g_glDisablei = nullptr;
}
}
if (isGLES2 && shaderStorage) {
g_glProgramBinary = (PFNGLPROGRAMBINARYPROC) eglGetProcAddress("glProgramBinaryOES");
g_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) eglGetProcAddress("glGetProgramBinaryOES");
g_glProgramParameteri = nullptr;
}
#endif
#ifndef OS_ANDROID
@ -114,4 +120,13 @@ void GLInfo::init() {
fetch_depth = Utils::isExtensionSupported(*this, "GL_ARM_shader_framebuffer_fetch_depth_stencil");
texture_barrier = (!isGLESX && numericVersion >= 45) || Utils::isExtensionSupported(*this, "GL_ARB_texture_barrier");
texture_barrierNV = Utils::isExtensionSupported(*this, "GL_NV_texture_barrier");
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTextures;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (!imageTextures && !ext_fetch) {
config.frameBufferEmulation.N64DepthCompare = 0;
LOG(LOG_WARNING, "Your GPU does not support the extensions needed for N64 Depth Compare.\n");
}
}
}

View File

@ -31,6 +31,7 @@ struct GLInfo {
bool fragment_interlock = false;
bool fragment_interlockNV = false;
bool fragment_ordering = false;
bool ext_fetch = false;
Renderer renderer = Renderer::Other;
void init();

View File

@ -50,6 +50,8 @@ namespace graphics {
namespace bufferAttachment {
BufferAttachmentParam COLOR_ATTACHMENT0(GL_COLOR_ATTACHMENT0);
BufferAttachmentParam COLOR_ATTACHMENT1(GL_COLOR_ATTACHMENT1);
BufferAttachmentParam COLOR_ATTACHMENT2(GL_COLOR_ATTACHMENT2);
BufferAttachmentParam DEPTH_ATTACHMENT(GL_DEPTH_ATTACHMENT);
}

View File

@ -50,6 +50,8 @@ namespace graphics {
namespace bufferAttachment {
extern BufferAttachmentParam COLOR_ATTACHMENT0;
extern BufferAttachmentParam COLOR_ATTACHMENT1;
extern BufferAttachmentParam COLOR_ATTACHMENT2;
extern BufferAttachmentParam DEPTH_ATTACHMENT;
}