diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 0c6fdc81b..53c6813b7 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -1716,6 +1716,8 @@ public: virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) = 0; virtual void DidRender3DBegin() = 0; virtual void DidRender3DEnd() = 0; + virtual void DidApplyRender3DSettingsBegin() = 0; + virtual void DidApplyRender3DSettingsEnd() = 0; }; // All of the default event handler methods should do nothing. @@ -1728,6 +1730,8 @@ public: virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) {}; virtual void DidRender3DBegin() {}; virtual void DidRender3DEnd() {}; + virtual void DidApplyRender3DSettingsBegin() {}; + virtual void DidApplyRender3DSettingsEnd() {}; }; class GPUSubsystem diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 5099c5674..8d71c8fcc 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1515,7 +1515,7 @@ OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly, theTexture->SetDeposterizeBuffer(this->_workingTextureUnpackBuffer, this->_textureDeposterizeDstSurface.workingSurface[0]); theTexture->SetUpscalingBuffer(this->_textureUpscaleBuffer); - theTexture->SetUseDeposterize(this->_textureDeposterize); + theTexture->SetUseDeposterize(this->_enableTextureDeposterize); theTexture->SetScalingFactor(this->_textureScalingFactor); theTexture->Load(isNewTexture || (previousScalingFactor != this->_textureScalingFactor)); @@ -1925,6 +1925,13 @@ Render3DError OpenGLRenderer::DrawOtherPolygon(const GLenum polyPrimitive, const return OGLERROR_NOERR; } +Render3DError OpenGLRenderer::ApplyRenderingSettings(const GFX3D_State &renderState) +{ + this->_enableMultisampledRendering = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported); + + return Render3D::ApplyRenderingSettings(renderState); +} + OpenGLRenderer_1_2::~OpenGLRenderer_1_2() { glFinish(); @@ -2161,6 +2168,8 @@ 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->InitFinalRenderStates(&oglExtensionSet); // This must be done last return OGLERROR_NOERR; @@ -3773,7 +3782,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading); glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformStateEnableAntialiasing, (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE); - glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE); + glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (this->_enableEdgeMark) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE); glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE); @@ -3878,7 +3887,7 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine) } } - this->_textureList[i] = this->GetLoadedTextureFromPolygon(*thePoly, engine.renderState.enableTexturing); + this->_textureList[i] = this->GetLoadedTextureFromPolygon(*thePoly, this->_enableTextureSampling); } if (this->isVBOSupported) @@ -4227,7 +4236,7 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf if (this->isMultisampledFBOSupported) { - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, OGLRef.fboRenderID); @@ -4276,7 +4285,7 @@ Render3DError OpenGLRenderer_1_2::ClearUsingValues(const FragmentColor &clearCol if (this->isFBOSupported) { - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); } @@ -4465,7 +4474,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, size_t polyR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (this->_textureSmooth) + if (this->_enableTextureSmoothing) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -4928,7 +4937,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading); glUniform1i(OGLRef.uniformStateEnableAlphaTest, (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformStateEnableAntialiasing, (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE); - glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE); + glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (this->_enableEdgeMark) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformStateUseWDepth, (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE); glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[engine.renderState.alphaTestRef]); glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE); @@ -4967,7 +4976,7 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine) } } - this->_textureList[i] = this->GetLoadedTextureFromPolygon(*thePoly, engine.renderState.enableTexturing); + this->_textureList[i] = this->GetLoadedTextureFromPolygon(*thePoly, this->_enableTextureSampling); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); @@ -5004,7 +5013,7 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, size_t polyR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (this->_textureSmooth) + if (this->_enableTextureSmoothing) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 48ee1aaf7..e27c2fe7f 100755 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -656,6 +656,8 @@ protected: size_t _currentPolyIndex; OGLTextureUnitID _lastTextureDrawTarget; + bool _enableMultisampledRendering; + Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16); OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing); template size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, POLYGON_ATTR &lastPolyAttr); @@ -726,6 +728,8 @@ public: virtual FragmentColor* GetFramebuffer(); virtual GLsizei GetLimitedMultisampleSize() const; + + Render3DError ApplyRenderingSettings(const GFX3D_State &renderState); }; class OpenGLRenderer_1_2 : public OpenGLRenderer diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 918626275..335aec200 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -719,6 +719,8 @@ 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->InitFinalRenderStates(&oglExtensionSet); // This must be done last return OGLERROR_NOERR; @@ -1565,7 +1567,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) state->toonShadingMode = engine.renderState.shading; state->enableAlphaTest = (engine.renderState.enableAlphaTest) ? GL_TRUE : GL_FALSE; state->enableAntialiasing = (engine.renderState.enableAntialiasing) ? GL_TRUE : GL_FALSE; - state->enableEdgeMarking = (engine.renderState.enableEdgeMarking) ? GL_TRUE : GL_FALSE; + state->enableEdgeMarking = (this->_enableEdgeMark) ? GL_TRUE : GL_FALSE; state->enableFogAlphaOnly = (engine.renderState.enableFogAlphaOnly) ? GL_TRUE : GL_FALSE; state->useWDepth = (engine.renderState.wbuffer) ? GL_TRUE : GL_FALSE; state->alphaTestRef = divide5bitBy31_LUT[engine.renderState.alphaTestRef]; @@ -1640,7 +1642,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine) } } - this->_textureList[i] = this->GetLoadedTextureFromPolygon(thePoly, engine.renderState.enableTexturing); + this->_textureList[i] = this->GetLoadedTextureFromPolygon(thePoly, this->_enableTextureSampling); const NDSTextureFormat packFormat = this->_textureList[i]->GetPackFormat(); @@ -1803,7 +1805,7 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID); glDrawBuffers(3, RenderDrawList); - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; if (OGLRef.selectedRenderingFBO == OGLRef.fboMSIntermediateRenderID) { glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboRenderID); @@ -1834,7 +1836,7 @@ Render3DError OpenGLRenderer_3_2::ClearUsingImage(const u16 *__restrict colorBuf Render3DError OpenGLRenderer_3_2::ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) { OGLRenderRef &OGLRef = *this->ref; - OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample && this->isMultisampledFBOSupported) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; + OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID; glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); glReadBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffers(3, RenderDrawList); @@ -1958,7 +1960,7 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, size_t polyR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ((thePoly.texParam.RepeatS_Enable) ? ((thePoly.texParam.MirroredRepeatS_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ((thePoly.texParam.RepeatT_Enable) ? ((thePoly.texParam.MirroredRepeatT_Enable) ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (this->_textureSmooth) + if (this->_enableTextureSmoothing) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.mm b/desmume/src/frontend/cocoa/cocoa_GPU.mm index 59252b191..4ed857a94 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.mm +++ b/desmume/src/frontend/cocoa/cocoa_GPU.mm @@ -54,6 +54,7 @@ private: pthread_rwlock_t _rwlockFrame; pthread_mutex_t _mutex3DRender; + pthread_mutex_t _mutexApplyRender3DSettings; bool _render3DNeedsFinish; public: @@ -68,6 +69,8 @@ public: void FramebufferUnlock(); void Render3DLock(); void Render3DUnlock(); + void ApplyRender3DSettingsLock(); + void ApplyRender3DSettingsUnlock(); pthread_rwlock_t* GetFrameRWLock(); bool GetRender3DNeedsFinish(); @@ -76,6 +79,8 @@ public: virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo); virtual void DidRender3DBegin(); virtual void DidRender3DEnd(); + virtual void DidApplyRender3DSettingsBegin(); + virtual void DidApplyRender3DSettingsEnd(); }; @implementation CocoaDSGPU @@ -336,64 +341,64 @@ public: - (void) setRender3DHighPrecisionColorInterpolation:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_HighResolutionInterpolateColor = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DHighPrecisionColorInterpolation { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_HighResolutionInterpolateColor ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DEdgeMarking:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_EdgeMark = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DEdgeMarking { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_EdgeMark ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DFog:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_Fog = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DFog { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_Fog ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DTextures:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_Texture = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DTextures { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_Texture ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } @@ -453,64 +458,64 @@ public: - (void) setRender3DLineHack:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_LineHack = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DLineHack { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_LineHack ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DMultisample:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_Renderer_Multisample = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DMultisample { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_Renderer_Multisample ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DTextureDeposterize:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_Renderer_TextureDeposterize = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DTextureDeposterize { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_Renderer_TextureDeposterize ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } - (void) setRender3DTextureSmoothing:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_Renderer_TextureSmoothing = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DTextureSmoothing { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_Renderer_TextureSmoothing ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } @@ -528,7 +533,7 @@ public: newScalingFactor = 4; } - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); if (newScalingFactor == 3) { @@ -536,30 +541,30 @@ public: } CommonSettings.GFX3D_Renderer_TextureScalingFactor = newScalingFactor; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (NSUInteger) render3DTextureScalingFactor { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const NSUInteger scalingFactor = (NSUInteger)CommonSettings.GFX3D_Renderer_TextureScalingFactor; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return scalingFactor; } - (void) setRender3DFragmentSamplingHack:(BOOL)state { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); CommonSettings.GFX3D_TXTHack = state ? true : false; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); } - (BOOL) render3DFragmentSamplingHack { - gpuEvent->Render3DLock(); + gpuEvent->ApplyRender3DSettingsLock(); const BOOL state = CommonSettings.GFX3D_TXTHack ? YES : NO; - gpuEvent->Render3DUnlock(); + gpuEvent->ApplyRender3DSettingsUnlock(); return state; } @@ -1212,6 +1217,7 @@ GPUEventHandlerOSX::GPUEventHandlerOSX() _render3DNeedsFinish = false; pthread_rwlock_init(&_rwlockFrame, NULL); pthread_mutex_init(&_mutex3DRender, NULL); + pthread_mutex_init(&_mutexApplyRender3DSettings, NULL); } GPUEventHandlerOSX::~GPUEventHandlerOSX() @@ -1223,6 +1229,7 @@ GPUEventHandlerOSX::~GPUEventHandlerOSX() pthread_rwlock_destroy(&this->_rwlockFrame); pthread_mutex_destroy(&this->_mutex3DRender); + pthread_mutex_destroy(&this->_mutexApplyRender3DSettings); } GPUClientFetchObject* GPUEventHandlerOSX::GetFetchObject() const @@ -1281,6 +1288,16 @@ void GPUEventHandlerOSX::DidRender3DEnd() this->Render3DUnlock(); } +void GPUEventHandlerOSX::DidApplyRender3DSettingsBegin() +{ + this->ApplyRender3DSettingsLock(); +} + +void GPUEventHandlerOSX::DidApplyRender3DSettingsEnd() +{ + this->ApplyRender3DSettingsUnlock(); +} + void GPUEventHandlerOSX::FramebufferLockWrite() { pthread_rwlock_wrlock(&this->_rwlockFrame); @@ -1306,6 +1323,16 @@ void GPUEventHandlerOSX::Render3DUnlock() pthread_mutex_unlock(&this->_mutex3DRender); } +void GPUEventHandlerOSX::ApplyRender3DSettingsLock() +{ + pthread_mutex_lock(&this->_mutexApplyRender3DSettings); +} + +void GPUEventHandlerOSX::ApplyRender3DSettingsUnlock() +{ + pthread_mutex_unlock(&this->_mutexApplyRender3DSettings); +} + bool GPUEventHandlerOSX::GetRender3DNeedsFinish() { return this->_render3DNeedsFinish; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 91e93cfed..204d8ac8c 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -2243,16 +2243,6 @@ static void gfx3d_doFlush() //that's pretty annoying. gfx3d.renderState = gfx3d.state; - // Override render states per user settings - if (!CommonSettings.GFX3D_Texture) - gfx3d.renderState.enableTexturing = false; - - if (!CommonSettings.GFX3D_EdgeMark) - gfx3d.renderState.enableEdgeMarking = false; - - if (!CommonSettings.GFX3D_Fog) - gfx3d.renderState.enableFog = false; - gfx3d.state.activeFlushCommand = gfx3d.state.pendingFlushCommand; const size_t polycount = polylist->count; @@ -2403,16 +2393,18 @@ void gfx3d_VBlankEndSignal(bool skipFrame) if (skipFrame) return; drawPending = FALSE; - + + GPU->GetEventHandler()->DidApplyRender3DSettingsBegin(); + CurrentRenderer->ApplyRenderingSettings(gfx3d.renderState); + GPU->GetEventHandler()->DidApplyRender3DSettingsEnd(); + GPU->GetEventHandler()->DidRender3DBegin(); CurrentRenderer->SetRenderNeedsFinish(true); //the timing of powering on rendering may not be exactly right here. if (CommonSettings.showGpu.main && nds.power_render) { - CurrentRenderer->SetTextureProcessingProperties(CommonSettings.GFX3D_Renderer_TextureScalingFactor, - CommonSettings.GFX3D_Renderer_TextureDeposterize, - CommonSettings.GFX3D_Renderer_TextureSmoothing); + CurrentRenderer->SetTextureProcessingProperties(); CurrentRenderer->Render(gfx3d); } else diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index c4e9b2aa2..8ad4fa712 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -397,7 +397,7 @@ public: s32 iu = 0; s32 iv = 0; - if (!CommonSettings.GFX3D_TXTHack) + if (!this->_softRender->_enableFragmentSamplingHack) { iu = s32floor(fu); iv = s32floor(fv); @@ -1058,12 +1058,13 @@ static RasterizerUnit rasterizerUnit[_MAX_CORES]; static RasterizerUnit _HACK_viewer_rasterizerUnit; static size_t rasterizerCores = 0; static bool rasterizerUnitTasksInited = false; +static bool gEnableLineHack = true; static void* execRasterizerUnit(void *arg) { intptr_t which = (intptr_t)arg; - if (CommonSettings.GFX3D_LineHack) + if (gEnableLineHack) { rasterizerUnit[which].mainLoop(); } @@ -1121,7 +1122,7 @@ static void* SoftRasterizer_RunRenderEdgeMarkAndFog(void *arg) void _HACK_Viewer_ExecUnit() { - if (CommonSettings.GFX3D_LineHack) + if (gEnableLineHack) { _HACK_viewer_rasterizerUnit.mainLoop(); } @@ -1436,6 +1437,11 @@ SoftRasterizerRenderer::SoftRasterizerRenderer() _renderGeometryNeedsFinish = false; _framebufferAttributes = NULL; + _enableHighPrecisionColorInterpolation = CommonSettings.GFX3D_HighResolutionInterpolateColor; + _enableLineHack = CommonSettings.GFX3D_LineHack; + gEnableLineHack = _enableLineHack; + _enableFragmentSamplingHack = CommonSettings.GFX3D_TXTHack; + if (!rasterizerUnitTasksInited) { _HACK_viewer_rasterizerUnit._debug_thisPoly = false; @@ -1649,7 +1655,7 @@ void SoftRasterizerRenderer::GetAndLoadAllTextures() //(otherwise on a multithreaded system there will be multiple writers-- //this SHOULD be read-only, although some day the texcache may collect statistics or something //and then it won't be safe. - this->_textureList[i] = this->GetLoadedTextureFromPolygon(thePoly, gfx3d.renderState.enableTexturing); + this->_textureList[i] = this->GetLoadedTextureFromPolygon(thePoly, this->_enableTextureSampling); } } @@ -1695,6 +1701,16 @@ void SoftRasterizerRenderer::performBackfaceTests() } } +Render3DError SoftRasterizerRenderer::ApplyRenderingSettings(const GFX3D_State &renderState) +{ + this->_enableHighPrecisionColorInterpolation = CommonSettings.GFX3D_HighResolutionInterpolateColor; + this->_enableLineHack = CommonSettings.GFX3D_LineHack; + gEnableLineHack = this->_enableLineHack; + this->_enableFragmentSamplingHack = CommonSettings.GFX3D_TXTHack; + + return Render3D::ApplyRenderingSettings(renderState); +} + Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine) { if (rasterizerCores > 1) @@ -1709,7 +1725,7 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine) // Keep the current render states for later use this->currentRenderState = (GFX3D_State *)&engine.renderState; - if (CommonSettings.GFX3D_HighResolutionInterpolateColor) + if (this->_enableHighPrecisionColorInterpolation) { this->_clippedPolyCount = this->performClipping(engine.vertList, engine.polylist, &engine.indexlist); } @@ -1734,12 +1750,12 @@ Render3DError SoftRasterizerRenderer::BeginRender(const GFX3D &engine) this->GetAndLoadAllTextures(); this->UpdateToonTable(engine.renderState.u16ToonTable); - if (this->currentRenderState->enableEdgeMarking) + if (this->_enableEdgeMark) { this->UpdateEdgeMarkColorTable(this->currentRenderState->edgeMarkColorTable); } - if (this->currentRenderState->enableFog) + if (this->_enableFog) { this->UpdateFogTable(this->currentRenderState->fogDensityTable); } @@ -1776,7 +1792,7 @@ Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderSt } else { - if (CommonSettings.GFX3D_LineHack) + if (this->_enableLineHack) { rasterizerUnit[0].mainLoop(); } @@ -2082,7 +2098,7 @@ SoftRasterizerTexture* SoftRasterizerRenderer::GetLoadedTextureFromPolygon(const if (theTexture->IsLoadNeeded() && isTextureEnabled) { - theTexture->SetUseDeposterize(this->_textureDeposterize); + theTexture->SetUseDeposterize(this->_enableTextureDeposterize); theTexture->SetScalingFactor(this->_textureScalingFactor); theTexture->Load(); } @@ -2187,10 +2203,10 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount) // If we're not multithreaded, then just do the post-processing steps now. if (!this->_renderGeometryNeedsFinish) { - if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog) + if (this->_enableEdgeMark || this->_enableFog) { - this->postprocessParam[0].enableEdgeMarking = this->currentRenderState->enableEdgeMarking; - this->postprocessParam[0].enableFog = this->currentRenderState->enableFog; + this->postprocessParam[0].enableEdgeMarking = this->_enableEdgeMark; + this->postprocessParam[0].enableFog = this->_enableFog; this->postprocessParam[0].fogColor = this->currentRenderState->fogColor; this->postprocessParam[0].fogAlphaOnly = this->currentRenderState->enableFogAlphaOnly; @@ -2219,12 +2235,12 @@ Render3DError SoftRasterizerRenderer::RenderFinish() texCache.Evict(); // Do multithreaded post-processing. - if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog) + if (this->_enableEdgeMark || this->_enableFog) { for (size_t i = 0; i < rasterizerCores; i++) { - this->postprocessParam[i].enableEdgeMarking = this->currentRenderState->enableEdgeMarking; - this->postprocessParam[i].enableFog = this->currentRenderState->enableFog; + this->postprocessParam[i].enableEdgeMarking = this->_enableEdgeMark; + this->postprocessParam[i].enableFog = this->_enableFog; this->postprocessParam[i].fogColor = this->currentRenderState->fogColor; this->postprocessParam[i].fogAlphaOnly = this->currentRenderState->enableFogAlphaOnly; diff --git a/desmume/src/rasterize.h b/desmume/src/rasterize.h index 52862de5e..9a4c62134 100644 --- a/desmume/src/rasterize.h +++ b/desmume/src/rasterize.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2016 DeSmuME team + Copyright (C) 2009-2017 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 @@ -98,6 +98,9 @@ protected: bool _stateSetupNeedsFinish; bool _renderGeometryNeedsFinish; + bool _enableHighPrecisionColorInterpolation; + bool _enableLineHack; + // SoftRasterizer-specific methods virtual Render3DError InitTables(); @@ -124,6 +127,8 @@ public: GFX3D_State *currentRenderState; SoftRasterizerPostProcessParams *postprocessParam; + bool _enableFragmentSamplingHack; + SoftRasterizerRenderer(); virtual ~SoftRasterizerRenderer(); @@ -140,6 +145,7 @@ public: // Base rendering methods virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer); virtual Render3DError Reset(); + virtual Render3DError ApplyRenderingSettings(const GFX3D_State &renderState); virtual Render3DError Render(const GFX3D &engine); virtual Render3DError RenderFinish(); virtual Render3DError RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16); diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 62fe429d0..4077a8ddf 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006-2007 shash - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2017 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 @@ -26,6 +26,7 @@ #include "utils/bits.h" #include "MMU.h" +#include "NDSSystem.h" #include "./filter/filter.h" #include "./filter/xbrz.h" @@ -296,11 +297,21 @@ Render3D::Render3D() _renderNeedsFlushMain = false; _renderNeedsFlush16 = false; - _textureScalingFactor = 1; - _textureDeposterize = false; - _textureSmooth = false; _textureUpscaleBuffer = NULL; + _enableEdgeMark = CommonSettings.GFX3D_EdgeMark; + _enableFog = CommonSettings.GFX3D_Fog; + _enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing; + + _enableTextureSampling = CommonSettings.GFX3D_Texture; + _prevEnableTextureSampling = _enableTextureSampling; + + _enableTextureDeposterize = CommonSettings.GFX3D_Renderer_TextureDeposterize; + _prevEnableTextureDeposterize = _enableTextureDeposterize; + + _textureScalingFactor = 1; + _prevTextureScalingFactor = _textureScalingFactor; + memset(&_textureDeposterizeSrcSurface, 0, sizeof(_textureDeposterizeSrcSurface)); memset(&_textureDeposterizeDstSurface, 0, sizeof(_textureDeposterizeDstSurface)); @@ -402,13 +413,16 @@ bool Render3D::GetRenderNeedsFlush16() const return this->_renderNeedsFlush16; } -void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth) +void Render3D::SetTextureProcessingProperties() { - const bool isScaleValid = ( (scalingFactor == 2) || (scalingFactor == 4) ); - const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1; bool needTextureReload = false; - if ( willDeposterize && !this->_textureDeposterize) + if (this->_enableTextureSampling && !this->_prevEnableTextureSampling) + { + needTextureReload = true; + } + + if (this->_enableTextureDeposterize && !this->_prevEnableTextureDeposterize) { // 1024x1024 texels is the largest possible texture size. // We need two buffers, one for each deposterize stage. @@ -416,35 +430,29 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep this->_textureDeposterizeDstSurface.Surface = (unsigned char *)malloc_alignedCacheLine(bufferSize); this->_textureDeposterizeDstSurface.workingSurface[0] = (unsigned char *)((u32 *)this->_textureDeposterizeDstSurface.Surface + (1024 * 1024)); - memset(this->_textureDeposterizeDstSurface.Surface, 0, bufferSize); - this->_textureDeposterize = true; needTextureReload = true; } - else if (!willDeposterize && this->_textureDeposterize) + else if (!this->_enableTextureDeposterize && this->_prevEnableTextureDeposterize) { free_aligned(this->_textureDeposterizeDstSurface.Surface); this->_textureDeposterizeDstSurface.Surface = NULL; this->_textureDeposterizeDstSurface.workingSurface[0] = NULL; - this->_textureDeposterize = false; needTextureReload = true; } - if (newScalingFactor != this->_textureScalingFactor) + if (this->_textureScalingFactor != this->_prevTextureScalingFactor) { u32 *oldTextureBuffer = this->_textureUpscaleBuffer; - u32 *newTextureBuffer = (u32 *)malloc_alignedCacheLine( (1024 * newScalingFactor) * (1024 * newScalingFactor) * sizeof(u32) ); - this->_textureScalingFactor = newScalingFactor; + u32 *newTextureBuffer = (u32 *)malloc_alignedCacheLine( (1024 * this->_textureScalingFactor) * (1024 * this->_textureScalingFactor) * sizeof(u32) ); this->_textureUpscaleBuffer = newTextureBuffer; free_aligned(oldTextureBuffer); needTextureReload = true; } - this->_textureSmooth = willSmooth; - if (needTextureReload) { texCache.ForceReloadAllTextures(); @@ -456,6 +464,32 @@ Render3DTexture* Render3D::GetTextureByPolygonRenderIndex(size_t polyRenderIndex return this->_textureList[polyRenderIndex]; } +Render3DError Render3D::ApplyRenderingSettings(const GFX3D_State &renderState) +{ + this->_enableEdgeMark = (CommonSettings.GFX3D_EdgeMark) ? renderState.enableEdgeMarking : false; + this->_enableFog = (CommonSettings.GFX3D_Fog) ? renderState.enableFog : false; + this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing; + + this->_prevEnableTextureSampling = this->_enableTextureSampling; + this->_enableTextureSampling = (CommonSettings.GFX3D_Texture) ? renderState.enableTexturing : false; + + this->_prevEnableTextureDeposterize = this->_enableTextureDeposterize; + this->_enableTextureDeposterize = CommonSettings.GFX3D_Renderer_TextureDeposterize; + + this->_prevTextureScalingFactor = this->_textureScalingFactor; + size_t newScalingFactor = (size_t)CommonSettings.GFX3D_Renderer_TextureScalingFactor; + + const bool isScaleValid = ( (newScalingFactor == 2) || (newScalingFactor == 4) ); + if (!isScaleValid) + { + newScalingFactor = 1; + } + + this->_textureScalingFactor = newScalingFactor; + + return RENDER3DERROR_NOERR; +} + Render3DError Render3D::BeginRender(const GFX3D &engine) { return RENDER3DERROR_NOERR; @@ -666,12 +700,12 @@ Render3DError Render3D::Render(const GFX3D &engine) this->RenderGeometry(engine.renderState, engine.polylist, &engine.indexlist); - if (engine.renderState.enableEdgeMarking) + if (this->_enableEdgeMark) { this->RenderEdgeMarking(engine.renderState.edgeMarkColorTable, engine.renderState.enableAntialiasing); } - if (engine.renderState.enableFog) + if (this->_enableFog) { this->RenderFog(engine.renderState.fogDensityTable, engine.renderState.fogColor, engine.renderState.fogOffset, engine.renderState.fogShift, engine.renderState.enableFogAlphaOnly); } diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index 75096d97a..7912acd4e 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006-2007 shash - Copyright (C) 2007-2016 DeSmuME team + Copyright (C) 2007-2017 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 @@ -154,9 +154,16 @@ protected: bool _renderNeedsFlushMain; bool _renderNeedsFlush16; + bool _enableEdgeMark; + bool _enableFog; + bool _enableTextureSampling; + bool _enableTextureDeposterize; + bool _enableTextureSmoothing; size_t _textureScalingFactor; - bool _textureDeposterize; - bool _textureSmooth; + + bool _prevEnableTextureSampling; + bool _prevEnableTextureDeposterize; + size_t _prevTextureScalingFactor; SSurface _textureDeposterizeSrcSurface; SSurface _textureDeposterizeDstSurface; @@ -168,7 +175,7 @@ protected: CACHE_ALIGN u32 clearImageDepthBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u8 clearImageFogBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u8 clearImagePolyIDBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; - + virtual Render3DError BeginRender(const GFX3D &engine); virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList); virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias); @@ -199,6 +206,8 @@ public: virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer); virtual Render3DError ClearFramebuffer(const GFX3D_State &renderState); + virtual Render3DError ApplyRenderingSettings(const GFX3D_State &renderState); + virtual Render3DError Reset(); // Called when the emulator resets. virtual Render3DError Render(const GFX3D &engine); // Called when the renderer should do its job and render the current display lists. @@ -234,7 +243,7 @@ public: bool GetRenderNeedsFlushMain() const; bool GetRenderNeedsFlush16() const; - void SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth); + void SetTextureProcessingProperties(); Render3DTexture* GetTextureByPolygonRenderIndex(size_t polyRenderIndex) const; };