From 68e91ec57f3d2b87e57050960ef543ebe6f21c13 Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 19 Oct 2018 16:33:37 -0700 Subject: [PATCH 1/3] OpenGL Renderer: Fix a bug with the MSAA automatic selector where the MSAA sample size would be selected based on the PREVIOUSLY set framebuffer size, even though the selection should be based on the CURRENTLY set framebuffer size. --- desmume/src/OGLRender.cpp | 12 +++++++----- desmume/src/OGLRender_3_2.cpp | 14 ++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index eb71ef72c..76c4e6d66 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -4895,8 +4895,15 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h) glActiveTextureARB(GL_TEXTURE0_ARB); + this->_framebufferWidth = w; + this->_framebufferHeight = h; + this->_framebufferPixCount = w * h; + this->_framebufferColorSizeBytes = newFramebufferColorSizeBytes; + if (this->isMultisampledFBOSupported) { + // Call GetLimitedMultisampleSize() after _framebufferWidth and _framebufferHeight are set + // since this method depends on them. GLsizei sampleSize = this->GetLimitedMultisampleSize(); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboMSGColorID); @@ -4911,11 +4918,6 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleSize, GL_DEPTH24_STENCIL8_EXT, w, h); } - this->_framebufferWidth = w; - this->_framebufferHeight = h; - this->_framebufferPixCount = w * h; - this->_framebufferColorSizeBytes = newFramebufferColorSizeBytes; - if (this->isPBOSupported) { this->_framebufferColor = NULL; diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index a7daf15cd..2ad4fdb98 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -2035,8 +2035,16 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h) glActiveTexture(GL_TEXTURE0); + 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. + if (this->isMultisampledFBOSupported) { + // Call GetLimitedMultisampleSize() after _framebufferWidth and _framebufferHeight are set + // since this method depends on them. GLsizei sampleSize = this->GetLimitedMultisampleSize(); if (this->willUsePerSampleZeroDstPass) @@ -2063,12 +2071,6 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t 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. - if (oglrender_framebufferDidResizeCallback != NULL) { oglrender_framebufferDidResizeCallback(w, h); From a894000333a1a7dc772cf7e3252738b3d46b1dd2 Mon Sep 17 00:00:00 2001 From: rogerman Date: Sat, 20 Oct 2018 14:53:49 -0700 Subject: [PATCH 2/3] matrix.cpp Fix a bug with _Vec3_MultiplyByMatrix() returning an incorrect value on SSE4.1. --- desmume/src/matrix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desmume/src/matrix.cpp b/desmume/src/matrix.cpp index c4c2349ab..16d5fc682 100755 --- a/desmume/src/matrix.cpp +++ b/desmume/src/matrix.cpp @@ -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); From 94ddf1a467632e64e88d4d9fc0611044e07707f4 Mon Sep 17 00:00:00 2001 From: rogerman Date: Mon, 22 Oct 2018 10:32:16 -0700 Subject: [PATCH 3/3] OpenGL Renderer: The MSAA sample size is no longer automatically selected and must now be manually selected via GFX3D_Renderer_MultisampleSize. - All frontends will need to be updated to use the new GFX3D_Renderer_MultisampleSize setting. - This change obsoletes GFX3D_Renderer_Multisample, which currently does nothing at the moment. It will be removed after all frontends are updated. --- desmume/src/NDSSystem.h | 2 + desmume/src/OGLRender.cpp | 126 ++++++++++++++++++++++++---------- desmume/src/OGLRender.h | 42 ++++-------- desmume/src/OGLRender_3_2.cpp | 92 +++++++++++++++++-------- desmume/src/OGLRender_3_2.h | 1 + 5 files changed, 170 insertions(+), 93 deletions(-) diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 452794f17..5ced00d72 100755 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -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_TextureDeposterize(false) , GFX3D_Renderer_TextureSmoothing(false) @@ -591,6 +592,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} bool GFX3D_Renderer_TextureDeposterize; bool GFX3D_Renderer_TextureSmoothing; diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 76c4e6d66..d7da0061f 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1474,35 +1474,39 @@ 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) ) + if (workingMultisamples == 1) { - maxMultisamples = OGLMaxMultisamples_Tier1; - } - else if ( (this->_framebufferWidth <= GPU_FRAMEBUFFER_NATIVE_WIDTH * OGLMaxMultisamplesScaleLimit_Tier2) && - (this->_framebufferHeight <= GPU_FRAMEBUFFER_NATIVE_HEIGHT * OGLMaxMultisamplesScaleLimit_Tier2) ) - { - maxMultisamples = OGLMaxMultisamples_Tier2; - } - else if ( (this->_framebufferWidth <= GPU_FRAMEBUFFER_NATIVE_WIDTH * OGLMaxMultisamplesScaleLimit_Tier3) && - (this->_framebufferHeight <= GPU_FRAMEBUFFER_NATIVE_HEIGHT * OGLMaxMultisamplesScaleLimit_Tier3) ) - { - 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 { - 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; @@ -1945,7 +1949,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); } @@ -2169,6 +2182,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"); @@ -2178,15 +2193,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 { @@ -2207,7 +2238,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 @@ -2956,6 +2987,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 *oglExtensionSet) { OGLRenderRef &OGLRef = *this->ref; @@ -4900,23 +4963,10 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h) this->_framebufferPixCount = w * h; this->_framebufferColorSizeBytes = newFramebufferColorSizeBytes; - if (this->isMultisampledFBOSupported) - { - // Call GetLimitedMultisampleSize() after _framebufferWidth and _framebufferHeight are set - // since this method depends on them. - 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); - } + // Call ResizeMultisampledFBOs() after _framebufferWidth and _framebufferHeight are set + // since this method depends on them. + GLsizei sampleSize = this->GetLimitedMultisampleSize(); + this->ResizeMultisampledFBOs(sampleSize); if (this->isPBOSupported) { diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 9d095a581..e64d29ea3 100755 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -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, @@ -534,7 +519,7 @@ struct OGLRenderRef // Client-side Buffers GLfloat *color4fBuffer; - GLushort *vertIndexBuffer; + GLushort *vertIndexBuffer; CACHE_ALIGN GLushort workingCIColorBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN GLuint workingCIDepthStencilBuffer[2][GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN GLuint workingCIFogAttributesBuffer[2][GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; @@ -617,15 +602,15 @@ public: void SetDeposterizeBuffer(void *dstBuffer, void *workingBuffer); void SetUpscalingBuffer(void *upscaleBuffer); }; - -#if defined(ENABLE_AVX2) -class OpenGLRenderer : public Render3D_AVX2 -#elif defined(ENABLE_SSE2) -class OpenGLRenderer : public Render3D_SSE2 -#elif defined(ENABLE_ALTIVEC) -class OpenGLRenderer : public Render3D_Altivec -#else -class OpenGLRenderer : public Render3D + +#if defined(ENABLE_AVX2) +class OpenGLRenderer : public Render3D_AVX2 +#elif defined(ENABLE_SSE2) +class OpenGLRenderer : public Render3D_SSE2 +#elif defined(ENABLE_ALTIVEC) +class OpenGLRenderer : public Render3D_Altivec +#else +class OpenGLRenderer : public Render3D #endif { private: @@ -662,7 +647,8 @@ protected: size_t _currentPolyIndex; OGLTextureUnitID _lastTextureDrawTarget; - bool _enableMultisampledRendering; + 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 *oglExtensionSet); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 2ad4fdb98..5c1de9cb0 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -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; @@ -2041,32 +2099,10 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t 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. - if (this->isMultisampledFBOSupported) - { - // Call GetLimitedMultisampleSize() after _framebufferWidth and _framebufferHeight are set - // since this method depends on them. - 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); - } + // 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); diff --git a/desmume/src/OGLRender_3_2.h b/desmume/src/OGLRender_3_2.h index d556d93ff..516e2a23e 100644 --- a/desmume/src/OGLRender_3_2.h +++ b/desmume/src/OGLRender_3_2.h @@ -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();