diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 0cdec23ab..f918e36ee 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_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; diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 249714deb..29f09f629 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -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 *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; diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 9fde221b4..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 a7daf15cd..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; @@ -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); 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(); 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);