Merge branch 'master' into antialiasing_settings

This commit is contained in:
Roger Manuel 2018-10-22 11:08:49 -07:00 committed by GitHub
commit acf49dfa01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 176 additions and 96 deletions

View File

@ -532,6 +532,7 @@ extern struct TCommonSettings
, GFX3D_Texture(true)
, GFX3D_LineHack(true)
, GFX3D_Renderer_Multisample(false)
, GFX3D_Renderer_MultisampleSize(0)
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
, GFX3D_Renderer_AntiAliasingSamples(8) // Possible values: 2, 4, 8
, GFX3D_Renderer_AntiAliasingLimit(false)
@ -593,6 +594,7 @@ extern struct TCommonSettings
bool GFX3D_Texture;
bool GFX3D_LineHack;
bool GFX3D_Renderer_Multisample;
int GFX3D_Renderer_MultisampleSize;
int GFX3D_Renderer_TextureScalingFactor; //must be one of {1,2,4}
int GFX3D_Renderer_AntiAliasingSamples; //must be one of {2,4,8}
bool GFX3D_Renderer_AntiAliasingLimit;

View File

@ -1474,27 +1474,20 @@ FragmentColor* OpenGLRenderer::GetFramebuffer()
return (this->willFlipAndConvertFramebufferOnGPU && this->isPBOSupported) ? this->_mappedFramebuffer : GPU->GetEngineMain()->Get3DFramebufferMain();
}
GLsizei OpenGLRenderer::GetLimitedMultisampleSize() const
{
GLsizei deviceMultisamples = this->_deviceInfo.maxSamples;
GLsizei maxMultisamples = OGLMaxMultisamples_Tier1;
u32 workingMultisamples = (u32)this->_selectedMultisampleSize;
if ( (this->_framebufferWidth <= GPU_FRAMEBUFFER_NATIVE_WIDTH * OGLMaxMultisamplesScaleLimit_Tier1) &&
(this->_framebufferHeight <= GPU_FRAMEBUFFER_NATIVE_HEIGHT * OGLMaxMultisamplesScaleLimit_Tier1) && CommonSettings.GFX3D_Renderer_AntiAliasingLimit == false )
if (workingMultisamples == 1)
{
maxMultisamples = OGLMaxMultisamples_Tier1;
}
else if ( (this->_framebufferWidth <= GPU_FRAMEBUFFER_NATIVE_WIDTH * OGLMaxMultisamplesScaleLimit_Tier2) &&
(this->_framebufferHeight <= GPU_FRAMEBUFFER_NATIVE_HEIGHT * OGLMaxMultisamplesScaleLimit_Tier2) && CommonSettings.GFX3D_Renderer_AntiAliasingLimit == false )
{
maxMultisamples = OGLMaxMultisamples_Tier2;
}
else if ( (this->_framebufferWidth <= GPU_FRAMEBUFFER_NATIVE_WIDTH * OGLMaxMultisamplesScaleLimit_Tier3) &&
(this->_framebufferHeight <= GPU_FRAMEBUFFER_NATIVE_HEIGHT * OGLMaxMultisamplesScaleLimit_Tier3) &&
((CommonSettings.GFX3D_Renderer_AntiAliasingSamples == 8) || CommonSettings.GFX3D_Renderer_AntiAliasingLimit == false) )
{
maxMultisamples = OGLMaxMultisamples_Tier3;
// If this->_selectedMultisampleSize is 1, then just set workingMultisamples to 2
// by default. This is done to prevent the multisampled FBOs from being resized to
// a meaningless sample size of 1.
//
// As an side, if someone wants to bring back automatic MSAA sample size selection
// in the future, then this would be the place to reimplement it.
workingMultisamples = 2;
}
else if (CommonSettings.GFX3D_Renderer_AntiAliasingLimit && CommonSettings.GFX3D_Renderer_AntiAliasingSamples == 2)
{
@ -1502,12 +1495,22 @@ GLsizei OpenGLRenderer::GetLimitedMultisampleSize() const
}
else
{
maxMultisamples = OGLMaxMultisamples_Tier4;
// Ensure that workingMultisamples is a power-of-two, which is what OpenGL likes.
//
// If workingMultisamples is not a power-of-two, then workingMultisamples is
// increased to the next largest power-of-two.
workingMultisamples--;
workingMultisamples |= workingMultisamples >> 1;
workingMultisamples |= workingMultisamples >> 2;
workingMultisamples |= workingMultisamples >> 4;
workingMultisamples |= workingMultisamples >> 8;
workingMultisamples |= workingMultisamples >> 16;
workingMultisamples++;
}
if (deviceMultisamples > maxMultisamples)
if (deviceMultisamples > workingMultisamples)
{
deviceMultisamples = maxMultisamples;
deviceMultisamples = workingMultisamples;
}
return deviceMultisamples;
@ -1950,7 +1953,16 @@ Render3DError OpenGLRenderer::DrawOtherPolygon(const GLenum polyPrimitive, const
Render3DError OpenGLRenderer::ApplyRenderingSettings(const GFX3D_State &renderState)
{
this->_enableMultisampledRendering = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported);
int oldSelectedMultisampleSize = this->_selectedMultisampleSize;
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
if (this->_selectedMultisampleSize != oldSelectedMultisampleSize)
{
GLsizei sampleSize = this->GetLimitedMultisampleSize();
this->ResizeMultisampledFBOs(sampleSize);
}
return Render3D::ApplyRenderingSettings(renderState);
}
@ -2174,6 +2186,8 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
INFO("OpenGL: FBOs are unsupported. Some emulation features will be disabled.\n");
}
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
// Don't use ARB versions since we're using the EXT versions for backwards compatibility.
this->isMultisampledFBOSupported = this->isFBOSupported &&
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_framebuffer_multisample");
@ -2183,15 +2197,31 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamplesOGL);
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
if (maxSamplesOGL >= 2)
if (this->_deviceInfo.maxSamples >= 2)
{
// Try and initialize the multisampled FBOs with the GFX3D_Renderer_MultisampleSize.
// However, if the client has this set to 0, then set sampleSize to 2 in order to
// force the generation and the attachments of the buffers at a meaningful sample
// size. If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffer
// memory afterwards.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
if (sampleSize == 0)
{
sampleSize = 2;
}
error = this->CreateMultisampledFBO(sampleSize);
if (error != OGLERROR_NOERR)
{
this->isMultisampledFBOSupported = false;
}
// If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffers now
// in order to save some memory.
if (this->_selectedMultisampleSize == 0)
{
this->ResizeMultisampledFBOs(0);
}
}
else
{
@ -2212,7 +2242,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
this->_deviceInfo.isFogSupported = (this->isShaderSupported && this->isVBOSupported && this->isFBOSupported);
this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported;
this->_enableMultisampledRendering = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported);
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
@ -2961,6 +2991,38 @@ void OpenGLRenderer_1_2::DestroyMultisampledFBO()
this->isMultisampledFBOSupported = false;
}
void OpenGLRenderer_1_2::ResizeMultisampledFBOs(GLsizei numSamples)
{
OGLRenderRef &OGLRef = *this->ref;
GLsizei w = this->_framebufferWidth;
GLsizei h = this->_framebufferHeight;
if ( !this->isMultisampledFBOSupported ||
(numSamples == 1) ||
(w < GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) )
{
return;
}
if (numSamples == 0)
{
w = 0;
h = 0;
numSamples = 2;
}
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_DEPTH24_STENCIL8_EXT, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilAlphaID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_DEPTH24_STENCIL8_EXT, w, h);
}
Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::string> *oglExtensionSet)
{
OGLRenderRef &OGLRef = *this->ref;
@ -4900,27 +4962,16 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
glActiveTextureARB(GL_TEXTURE0_ARB);
if (this->isMultisampledFBOSupported)
{
GLsizei sampleSize = this->GetLimitedMultisampleSize();
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_RGBA, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_DEPTH24_STENCIL8_EXT, w, h);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGDepthStencilAlphaID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_DEPTH24_STENCIL8_EXT, w, h);
}
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferPixCount = w * h;
this->_framebufferColorSizeBytes = newFramebufferColorSizeBytes;
// Call ResizeMultisampledFBOs() after _framebufferWidth and _framebufferHeight are set
// since this method depends on them.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
this->ResizeMultisampledFBOs(sampleSize);
if (this->isPBOSupported)
{
this->_framebufferColor = NULL;

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
Copyright (C) 2008-2017 DeSmuME team
Copyright (C) 2008-2018 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -282,21 +282,6 @@ EXTERNOGLEXT(PFNGLTEXBUFFERPROC, glTexBuffer) // Core in v3.1
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT (POLYLIST_SIZE * 6)
enum OGLMaxMultisamples
{
OGLMaxMultisamples_Tier1 = 32,
OGLMaxMultisamples_Tier2 = 16,
OGLMaxMultisamples_Tier3 = 8,
OGLMaxMultisamples_Tier4 = 4
};
enum OGLMaxMultisamplesScaleLimit
{
OGLMaxMultisamplesScaleLimit_Tier1 = 1,
OGLMaxMultisamplesScaleLimit_Tier2 = 4,
OGLMaxMultisamplesScaleLimit_Tier3 = 8
};
enum OGLVertexAttributeID
{
OGLVertexAttributeID_Position = 0,
@ -663,6 +648,7 @@ protected:
OGLTextureUnitID _lastTextureDrawTarget;
bool _enableMultisampledRendering;
int _selectedMultisampleSize;
size_t _clearImageIndex;
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
@ -680,6 +666,7 @@ protected:
virtual void DestroyFBOs() = 0;
virtual Render3DError CreateMultisampledFBO(GLsizei numSamples) = 0;
virtual void DestroyMultisampledFBO() = 0;
virtual void ResizeMultisampledFBOs(GLsizei numSamples) = 0;
virtual Render3DError InitGeometryProgram(const char *geometryVtxShaderCString, const char *geometryFragShaderCString,
const char *geometryAlphaVtxShaderCString, const char *geometryAlphaFragShaderCString,
const char *geometryMSAlphaVtxShaderCString, const char *geometryMSAlphaFragShaderCString) = 0;
@ -751,6 +738,7 @@ protected:
virtual void DestroyFBOs();
virtual Render3DError CreateMultisampledFBO(GLsizei numSamples);
virtual void DestroyMultisampledFBO();
virtual void ResizeMultisampledFBOs(GLsizei numSamples);
virtual Render3DError CreateVAOs();
virtual void DestroyVAOs();
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);

View File

@ -699,20 +699,37 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
}
this->isMultisampledFBOSupported = true;
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
GLint maxSamplesOGL = 0;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamplesOGL);
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
if (maxSamplesOGL >= 2)
if (this->_deviceInfo.maxSamples >= 2)
{
// Try and initialize the multisampled FBOs with the GFX3D_Renderer_MultisampleSize.
// However, if the client has this set to 0, then set sampleSize to 2 in order to
// force the generation and the attachments of the buffers at a meaningful sample
// size. If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffer
// memory afterwards.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
if (sampleSize == 0)
{
sampleSize = 2;
}
error = this->CreateMultisampledFBO(sampleSize);
if (error != OGLERROR_NOERR)
{
this->isMultisampledFBOSupported = false;
}
// If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffers now
// in order to save some memory.
if (this->_selectedMultisampleSize == 0)
{
this->ResizeMultisampledFBOs(0);
}
}
else
{
@ -720,7 +737,7 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
INFO("OpenGL: Driver does not support at least 2x multisampled FBOs.\n");
}
this->_enableMultisampledRendering = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported);
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
@ -1140,6 +1157,47 @@ void OpenGLRenderer_3_2::DestroyMultisampledFBO()
this->isMultisampledFBOSupported = false;
}
void OpenGLRenderer_3_2::ResizeMultisampledFBOs(GLsizei numSamples)
{
OGLRenderRef &OGLRef = *this->ref;
GLsizei w = this->_framebufferWidth;
GLsizei h = this->_framebufferHeight;
if ( !this->isMultisampledFBOSupported ||
(numSamples == 1) ||
(w < GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) )
{
return;
}
if (numSamples == 0)
{
w = 0;
h = 0;
numSamples = 2;
}
if (this->willUsePerSampleZeroDstPass)
{
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, OGLRef.texMSGColorID);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, GL_RGBA, w, h, GL_TRUE);
}
else
{
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_RGBA, w, h);
}
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_DEPTH24_STENCIL8, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilAlphaID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_DEPTH24_STENCIL8, w, h);
}
Render3DError OpenGLRenderer_3_2::CreateVAOs()
{
OGLRenderRef &OGLRef = *this->ref;
@ -2035,40 +2093,20 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
glActiveTexture(GL_TEXTURE0);
if (this->isMultisampledFBOSupported)
{
GLsizei sampleSize = this->GetLimitedMultisampleSize();
if (this->willUsePerSampleZeroDstPass)
{
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, OGLRef.texMSGColorID);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleSize, GL_RGBA, w, h, GL_TRUE);
}
else
{
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGColorID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleSize, GL_RGBA, w, h);
}
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGPolyID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleSize, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGFogAttrID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleSize, GL_RGBA, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleSize, GL_DEPTH24_STENCIL8, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMSGDepthStencilAlphaID);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleSize, GL_DEPTH24_STENCIL8, w, h);
}
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilAlphaID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferPixCount = w * h;
this->_framebufferColorSizeBytes = newFramebufferColorSizeBytes;
this->_framebufferColor = NULL; // Don't need to make a client-side buffer since we will be reading directly from the PBO.
// Call ResizeMultisampledFBOs() after _framebufferWidth and _framebufferHeight are set
// since this method depends on them.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
this->ResizeMultisampledFBOs(sampleSize);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilAlphaID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
if (oglrender_framebufferDidResizeCallback != NULL)
{
oglrender_framebufferDidResizeCallback(w, h);

View File

@ -73,6 +73,7 @@ protected:
virtual void DestroyFBOs();
virtual Render3DError CreateMultisampledFBO(GLsizei numSamples);
virtual void DestroyMultisampledFBO();
virtual void ResizeMultisampledFBOs(GLsizei numSamples);
virtual Render3DError CreateVAOs();
virtual void DestroyVAOs();

View File

@ -694,7 +694,7 @@ FORCEINLINE void _Vec3_MultiplyByMatrix(__m128i &outVec,
outVecLo = _mm_srli_epi64(outVecLo, 12);
outVecLo = _mm_shuffle_epi32(outVecLo, 0xD8);
__m128i outVecHi = _mm_add_epi64( _mm_mul_epi32(rowHi0, c0), _mm_add_epi64(_mm_mul_epi32(rowLo1, c1), _mm_mul_epi32(rowHi2, c2)) );
__m128i outVecHi = _mm_add_epi64( _mm_mul_epi32(rowHi0, c0), _mm_add_epi64(_mm_mul_epi32(rowHi1, c1), _mm_mul_epi32(rowHi2, c2)) );
outVecHi = _mm_srli_epi64(outVecHi, 12);
outVecHi = _mm_shuffle_epi32(outVecHi, 0x8D);