From 2d712f2ae0482d7da3b49397902551addd676107 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Wed, 8 May 2019 21:04:24 +0700 Subject: [PATCH] Rewrite textures loading and mapping: - use RiceVideo method for texture size calculation. RiceVideo uses the same method for texture dumping. - rewrite texture mapping. Texture Clamp-Wrap-Mirror implemented in shaders. Problem explanation: https://github.com/gonetz/GLideN64/issues/1885#issuecomment-485136358 Fixed various glitches with HD textures, #1885 --- src/BufferCopy/ColorBufferToRDRAM.cpp | 24 +- src/BufferCopy/DepthBufferToRDRAM.cpp | 22 +- src/BufferCopy/RDRAMtoColorBuffer.cpp | 17 +- src/Debugger.cpp | 6 +- src/DepthBuffer.cpp | 34 +- src/FrameBuffer.cpp | 68 ++-- src/Graphics/ColorBufferReader.cpp | 6 +- .../GLSL/glsl_CombinerProgramBuilder.cpp | 147 +++++++-- .../GLSL/glsl_CombinerProgramBuilder.h | 4 + .../glsl_CombinerProgramUniformFactory.cpp | 139 ++++++++- .../OpenGLContext/GLSL/glsl_ShaderStorage.h | 2 +- .../GLSL/glsl_SpecialShadersFactory.cpp | 6 +- ...ngl_ColorBufferReaderWithBufferStorage.cpp | 4 +- ...pengl_ColorBufferReaderWithPixelBuffer.cpp | 6 +- ...opengl_ColorBufferReaderWithReadPixels.cpp | 4 +- .../windows/windows_DisplayWindow.cpp | 6 +- src/NoiseTexture.cpp | 10 +- src/PaletteTexture.cpp | 14 +- src/PostProcessor.cpp | 26 +- src/TexrectDrawer.cpp | 20 +- src/TextDrawer.cpp | 6 +- src/Textures.cpp | 290 +++++++----------- src/Textures.h | 7 +- src/ZlutTexture.cpp | 10 +- src/gDP.cpp | 9 + 25 files changed, 500 insertions(+), 387 deletions(-) diff --git a/src/BufferCopy/ColorBufferToRDRAM.cpp b/src/BufferCopy/ColorBufferToRDRAM.cpp index 3bd637e6..5037b23a 100644 --- a/src/BufferCopy/ColorBufferToRDRAM.cpp +++ b/src/BufferCopy/ColorBufferToRDRAM.cpp @@ -77,15 +77,15 @@ void ColorBufferToRDRAM::_initFBTexture(void) m_pTexture->mirrorT = 0; //The actual VI width is not used for texture width because most texture widths //cause slowdowns in the glReadPixels call, at least on Android - m_pTexture->realWidth = m_lastBufferWidth; - m_pTexture->realHeight = VI_GetMaxBufferHeight(m_lastBufferWidth); - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormat.colorFormatBytes; + m_pTexture->width = m_lastBufferWidth; + m_pTexture->height = VI_GetMaxBufferHeight(m_lastBufferWidth); + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormat.colorFormatBytes; { Context::InitTextureParams params; params.handle = m_pTexture->name; - params.width = m_pTexture->realWidth; - params.height = m_pTexture->realHeight; + params.width = m_pTexture->width; + params.height = m_pTexture->height; params.internalFormat = fbTexFormat.colorInternalFormat; params.format = fbTexFormat.colorFormat; params.dataType = fbTexFormat.colorType; @@ -157,8 +157,8 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress) return false; if(m_pTexture == nullptr || - m_pTexture->realWidth != _getRealWidth(pBuffer->m_width) || - m_pTexture->realHeight != VI_GetMaxBufferHeight(_getRealWidth(pBuffer->m_width))) + m_pTexture->width != _getRealWidth(pBuffer->m_width) || + m_pTexture->height != VI_GetMaxBufferHeight(_getRealWidth(pBuffer->m_width))) { _destroyFBTexure(); @@ -193,7 +193,7 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress) x0 = (screenWidth - width) / 2; } } else { - width = m_pCurFrameBuffer->m_pTexture->realWidth; + width = m_pCurFrameBuffer->m_pTexture->width; } u32 height = (u32)(bufferHeight * m_pCurFrameBuffer->m_scale); @@ -203,14 +203,14 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress) blitParams.srcY0 = 0; blitParams.srcX1 = x0 + width; blitParams.srcY1 = height; - blitParams.srcWidth = pInputTexture->realWidth; - blitParams.srcHeight = pInputTexture->realHeight; + blitParams.srcWidth = pInputTexture->width; + blitParams.srcHeight = pInputTexture->height; blitParams.dstX0 = 0; blitParams.dstY0 = 0; blitParams.dstX1 = m_pCurFrameBuffer->m_width; blitParams.dstY1 = bufferHeight; - blitParams.dstWidth = m_pTexture->realWidth; - blitParams.dstHeight = m_pTexture->realHeight; + blitParams.dstWidth = m_pTexture->width; + blitParams.dstHeight = m_pTexture->height; blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.tex[0] = pInputTexture; blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram(); diff --git a/src/BufferCopy/DepthBufferToRDRAM.cpp b/src/BufferCopy/DepthBufferToRDRAM.cpp index 559ae6ea..d2559a70 100644 --- a/src/BufferCopy/DepthBufferToRDRAM.cpp +++ b/src/BufferCopy/DepthBufferToRDRAM.cpp @@ -59,9 +59,9 @@ void DepthBufferToRDRAM::init() m_pColorTexture->maskT = 0; m_pColorTexture->mirrorS = 0; m_pColorTexture->mirrorT = 0; - m_pColorTexture->realWidth = DEPTH_TEX_WIDTH; - m_pColorTexture->realHeight = DEPTH_TEX_HEIGHT; - m_pColorTexture->textureBytes = m_pColorTexture->realWidth * m_pColorTexture->realHeight; + m_pColorTexture->width = DEPTH_TEX_WIDTH; + m_pColorTexture->height = DEPTH_TEX_HEIGHT; + m_pColorTexture->textureBytes = m_pColorTexture->width * m_pColorTexture->height; m_pDepthTexture = textureCache().addFrameBufferTexture(false); m_pDepthTexture->format = G_IM_FMT_I; @@ -73,16 +73,16 @@ void DepthBufferToRDRAM::init() m_pDepthTexture->maskT = 0; m_pDepthTexture->mirrorS = 0; m_pDepthTexture->mirrorT = 0; - m_pDepthTexture->realWidth = DEPTH_TEX_WIDTH; - m_pDepthTexture->realHeight = DEPTH_TEX_HEIGHT; - m_pDepthTexture->textureBytes = m_pDepthTexture->realWidth * m_pDepthTexture->realHeight * sizeof(float); + m_pDepthTexture->width = DEPTH_TEX_WIDTH; + m_pDepthTexture->height = DEPTH_TEX_HEIGHT; + m_pDepthTexture->textureBytes = m_pDepthTexture->width * m_pDepthTexture->height * sizeof(float); const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); Context::InitTextureParams initParams; initParams.handle = m_pColorTexture->name; initParams.textureUnitIndex = textureIndices::Tex[0]; - initParams.width = m_pColorTexture->realWidth; - initParams.height = m_pColorTexture->realHeight; + initParams.width = m_pColorTexture->width; + initParams.height = m_pColorTexture->height; initParams.internalFormat = fbTexFormats.monochromeInternalFormat; initParams.format = fbTexFormats.monochromeFormat; initParams.dataType = fbTexFormats.monochromeType; @@ -97,8 +97,8 @@ void DepthBufferToRDRAM::init() gfxContext.setTextureParameters(setParams); initParams.handle = m_pDepthTexture->name; - initParams.width = m_pDepthTexture->realWidth; - initParams.height = m_pDepthTexture->realHeight; + initParams.width = m_pDepthTexture->width; + initParams.height = m_pDepthTexture->height; initParams.internalFormat = fbTexFormats.depthInternalFormat; initParams.format = fbTexFormats.depthFormat; initParams.dataType = fbTexFormats.depthType; @@ -189,7 +189,7 @@ bool DepthBufferToRDRAM::_prepareCopy(u32& _startAddress, bool _copyChunk) blitParams.drawBuffer = m_FBO; blitParams.srcX0 = 0; blitParams.srcY0 = 0; - blitParams.srcX1 = m_pCurFrameBuffer->m_pTexture->realWidth; + blitParams.srcX1 = m_pCurFrameBuffer->m_pTexture->width; blitParams.srcY1 = s32(m_pCurFrameBuffer->m_height * m_pCurFrameBuffer->m_scale); blitParams.dstX0 = 0; blitParams.dstY0 = 0; diff --git a/src/BufferCopy/RDRAMtoColorBuffer.cpp b/src/BufferCopy/RDRAMtoColorBuffer.cpp index 776a16bb..3e6a1265 100644 --- a/src/BufferCopy/RDRAMtoColorBuffer.cpp +++ b/src/BufferCopy/RDRAMtoColorBuffer.cpp @@ -41,14 +41,14 @@ void RDRAMtoColorBuffer::init() m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; - m_pTexture->realWidth = 640; - m_pTexture->realHeight = 580; - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.colorFormatBytes; + m_pTexture->width = 640; + m_pTexture->height = 580; + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes; Context::InitTextureParams initParams; initParams.handle = m_pTexture->name; - initParams.width = m_pTexture->realWidth; - initParams.height = m_pTexture->realHeight; + initParams.width = m_pTexture->width; + initParams.height = m_pTexture->height; initParams.internalFormat = fbTexFormats.colorInternalFormat; initParams.format = fbTexFormats.colorFormat; initParams.dataType = fbTexFormats.colorType; @@ -185,9 +185,6 @@ void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha) const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); - m_pTexture->width = width; - m_pTexture->height = height; - u32 * pDst = nullptr; std::unique_ptr dstData; @@ -254,8 +251,8 @@ void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha) updateParams.data = m_pbuf; gfxContext.update2DTexture(updateParams); - m_pTexture->scaleS = 1.0f / (float)m_pTexture->realWidth; - m_pTexture->scaleT = 1.0f / (float)m_pTexture->realHeight; + m_pTexture->scaleS = 1.0f / (float)m_pTexture->width; + m_pTexture->scaleT = 1.0f / (float)m_pTexture->height; m_pTexture->shiftScaleS = 1.0f; m_pTexture->shiftScaleT = 1.0f; m_pTexture->offsetS = 0.0f; diff --git a/src/Debugger.cpp b/src/Debugger.cpp index 6ca2d795..2908fd76 100644 --- a/src/Debugger.cpp +++ b/src/Debugger.cpp @@ -618,7 +618,7 @@ void Debugger::_drawFrameBuffer(FrameBuffer * _pBuffer) pBufferTexture = _pBuffer->m_pResolveTexture; } - s32 srcCoord[4] = { 0, 0, pBufferTexture->realWidth, (s32)(_pBuffer->m_height * _pBuffer->m_scale) }; + s32 srcCoord[4] = { 0, 0, pBufferTexture->width, (s32)(_pBuffer->m_height * _pBuffer->m_scale) }; const s32 hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2; const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2 + wnd.getHeightOffset() + wnd.getHeight()*3/8; s32 dstCoord[4] = { hOffset, vOffset, hOffset + (s32)wnd.getWidth()*5/8, vOffset + (s32)wnd.getHeight()*5/8 }; @@ -635,8 +635,8 @@ void Debugger::_drawFrameBuffer(FrameBuffer * _pBuffer) blitParams.srcY0 = srcCoord[3]; blitParams.srcX1 = srcCoord[2]; blitParams.srcY1 = srcCoord[1]; - blitParams.srcWidth = pBufferTexture->realWidth; - blitParams.srcHeight = pBufferTexture->realHeight; + blitParams.srcWidth = pBufferTexture->width; + blitParams.srcHeight = pBufferTexture->height; blitParams.dstX0 = dstCoord[0]; blitParams.dstY0 = dstCoord[1]; blitParams.dstX1 = dstCoord[2]; diff --git a/src/DepthBuffer.cpp b/src/DepthBuffer.cpp index bd1d59b6..0bb79570 100644 --- a/src/DepthBuffer.cpp +++ b/src/DepthBuffer.cpp @@ -64,15 +64,13 @@ void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture.maskT = 0; _cachedTexture.mirrorS = 0; _cachedTexture.mirrorT = 0; - _cachedTexture.realWidth = _cachedTexture.width; - _cachedTexture.realHeight = _cachedTexture.height; - _cachedTexture.textureBytes = _cachedTexture.realWidth * _cachedTexture.realHeight * fbTexFormat.depthImageFormatBytes; + _cachedTexture.textureBytes = _cachedTexture.width * _cachedTexture.height * fbTexFormat.depthImageFormatBytes; { Context::InitTextureParams params; params.handle = _cachedTexture.name; - params.width = _cachedTexture.realWidth; - params.height = _cachedTexture.realHeight; + params.width = _cachedTexture.width; + params.height = _cachedTexture.height; params.internalFormat = fbTexFormat.depthImageInternalFormat; params.format = fbTexFormat.depthImageFormat; params.dataType = fbTexFormat.depthImageType; @@ -146,15 +144,13 @@ void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture _pTexture->maskT = 0; _pTexture->mirrorS = 0; _pTexture->mirrorT = 0; - _pTexture->realWidth = _pTexture->width; - _pTexture->realHeight = _pTexture->height; - _pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight * fbTexFormat.depthFormatBytes; + _pTexture->textureBytes = _pTexture->width * _pTexture->height * fbTexFormat.depthFormatBytes; Context::InitTextureParams initParams; initParams.handle = _pTexture->name; initParams.msaaLevel = _multisample ? config.video.multisampling : 0U; - initParams.width = _pTexture->realWidth; - initParams.height = _pTexture->realHeight; + initParams.width = _pTexture->width; + initParams.height = _pTexture->height; initParams.internalFormat = fbTexFormat.depthInternalFormat; initParams.format = fbTexFormat.depthFormat; initParams.dataType = fbTexFormat.depthType; @@ -259,12 +255,12 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer) blitParams.drawBuffer = _pBuffer->m_resolveFBO; blitParams.srcX0 = 0; blitParams.srcY0 = 0; - blitParams.srcX1 = m_pDepthBufferTexture->realWidth; - blitParams.srcY1 = m_pDepthBufferTexture->realHeight; + blitParams.srcX1 = m_pDepthBufferTexture->width; + blitParams.srcY1 = m_pDepthBufferTexture->height; blitParams.dstX0 = 0; blitParams.dstY0 = 0; - blitParams.dstX1 = m_pResolveDepthBufferTexture->realWidth; - blitParams.dstY1 = m_pResolveDepthBufferTexture->realHeight; + blitParams.dstX1 = m_pResolveDepthBufferTexture->width; + blitParams.dstY1 = m_pResolveDepthBufferTexture->height; blitParams.mask = blitMask::DEPTH_BUFFER; blitParams.filter = textureParameters::FILTER_NEAREST; @@ -310,12 +306,12 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer) blitParams.drawBuffer = m_copyFBO; blitParams.srcX0 = 0; blitParams.srcY0 = 0; - blitParams.srcX1 = m_pDepthBufferTexture->realWidth; - blitParams.srcY1 = m_pDepthBufferTexture->realHeight; + blitParams.srcX1 = m_pDepthBufferTexture->width; + blitParams.srcY1 = m_pDepthBufferTexture->height; blitParams.dstX0 = 0; blitParams.dstY0 = 0; - blitParams.dstX1 = m_pDepthBufferTexture->realWidth; - blitParams.dstY1 = m_pDepthBufferTexture->realHeight; + blitParams.dstX1 = m_pDepthBufferTexture->width; + blitParams.dstY1 = m_pDepthBufferTexture->height; blitParams.mask = blitMask::DEPTH_BUFFER; blitParams.filter = textureParameters::FILTER_NEAREST; @@ -507,7 +503,7 @@ void DepthBufferList::clearBuffer() return; DepthBuffer * pDepthBuffer = pColorBuffer->m_pDepthBuffer; - //if (pColorBuffer->m_pTexture->realWidth == pDepthBuffer->m_pDepthImageZTexture->realWidth) + //if (pColorBuffer->m_pTexture->realWidth == pDepthBuffer->m_pDepthImageZTexture->realWidth) { gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_ZTextureClearFBO); gfxContext.clearColorBuffer(1.0f, 0.0f, 0.0f, 0.0f); diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index 79cb923d..2756448e 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -98,9 +98,7 @@ void _initFrameBufferTexture(u32 _address, u16 _width, u16 _height, f32 _scale, _pTexture->maskT = 0; _pTexture->mirrorS = 0; _pTexture->mirrorT = 0; - _pTexture->realWidth = _pTexture->width; - _pTexture->realHeight = _pTexture->height; - _pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight; + _pTexture->textureBytes = _pTexture->width * _pTexture->height; if (_size > G_IM_SIZ_8b) _pTexture->textureBytes *= fbTexFormats.colorFormatBytes; else @@ -121,8 +119,8 @@ void _setAndAttachBufferTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32 initParams.textureUnitIndex = textureIndices::Tex[_t]; if (_multisampling) initParams.msaaLevel = config.video.multisampling; - initParams.width = _pTexture->realWidth; - initParams.height = _pTexture->realHeight; + initParams.width = _pTexture->width; + initParams.height = _pTexture->height; if (_pTexture->size > G_IM_SIZ_8b) { initParams.internalFormat = fbTexFormat.colorInternalFormat; initParams.format = fbTexFormat.colorFormat; @@ -331,12 +329,12 @@ void FrameBuffer::resolveMultisampledTexture(bool _bForce) blitParams.drawBuffer = m_resolveFBO; blitParams.srcX0 = 0; blitParams.srcY0 = 0; - blitParams.srcX1 = m_pTexture->realWidth; - blitParams.srcY1 = m_pTexture->realHeight; + blitParams.srcX1 = m_pTexture->width; + blitParams.srcY1 = m_pTexture->height; blitParams.dstX0 = 0; blitParams.dstY0 = 0; - blitParams.dstX1 = m_pResolveTexture->realWidth; - blitParams.dstY1 = m_pResolveTexture->realHeight; + blitParams.dstX1 = m_pResolveTexture->width; + blitParams.dstY1 = m_pResolveTexture->height; blitParams.mask = blitMask::COLOR_BUFFER; blitParams.filter = textureParameters::FILTER_NEAREST; @@ -391,12 +389,12 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t) s32 x0 = (s32)(m_pTexture->offsetS * m_scale); s32 y0 = (s32)(m_pTexture->offsetT * m_scale); - s32 copyWidth = m_pSubTexture->realWidth; - if (x0 + copyWidth > m_pTexture->realWidth) - copyWidth = m_pTexture->realWidth - x0; - s32 copyHeight = m_pSubTexture->realHeight; - if (y0 + copyHeight > m_pTexture->realHeight) - copyHeight = m_pTexture->realHeight - y0; + s32 copyWidth = m_pSubTexture->width; + if (x0 + copyWidth > m_pTexture->width) + copyWidth = m_pTexture->width - x0; + s32 copyHeight = m_pSubTexture->height; + if (y0 + copyHeight > m_pTexture->height) + copyHeight = m_pTexture->height - y0; ObjectHandle readFBO = m_FBO; if (Context::WeakBlitFramebuffer && @@ -451,12 +449,12 @@ CachedTexture * FrameBuffer::_copyFrameBufferTexture() blitParams.drawBuffer = m_copyFBO; blitParams.srcX0 = 0; blitParams.srcY0 = 0; - blitParams.srcX1 = m_pTexture->realWidth; - blitParams.srcY1 = m_pTexture->realHeight; + blitParams.srcX1 = m_pTexture->width; + blitParams.srcY1 = m_pTexture->height; blitParams.dstX0 = 0; blitParams.dstY0 = 0; - blitParams.dstX1 = m_pTexture->realWidth; - blitParams.dstY1 = m_pTexture->realHeight; + blitParams.dstX1 = m_pTexture->width; + blitParams.dstY1 = m_pTexture->height; blitParams.mask = blitMask::COLOR_BUFFER; blitParams.filter = textureParameters::FILTER_NEAREST; @@ -497,8 +495,8 @@ CachedTexture * FrameBuffer::getTexture(u32 _t) if (!getDepthTexture && (gSP.textureTile[_t]->clamps == 0 || gSP.textureTile[_t]->clampt == 0)) pTexture = _getSubTexture(_t); - pTexture->scaleS = m_scale / (float)pTexture->realWidth; - pTexture->scaleT = m_scale / (float)pTexture->realHeight; + pTexture->scaleS = m_scale / (float)pTexture->width; + pTexture->scaleT = m_scale / (float)pTexture->height; if (gSP.textureTile[_t]->shifts > 10) pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[_t]->shifts)); @@ -528,8 +526,8 @@ CachedTexture * FrameBuffer::getTextureBG(u32 _t) pTexture = _copyFrameBufferTexture(); } - pTexture->scaleS = m_scale / (float)pTexture->realWidth; - pTexture->scaleT = m_scale / (float)pTexture->realHeight; + pTexture->scaleS = m_scale / (float)pTexture->width; + pTexture->scaleT = m_scale / (float)pTexture->height; pTexture->shiftScaleS = 1.0f; pTexture->shiftScaleT = 1.0f; @@ -920,12 +918,12 @@ void FrameBufferList::attachDepthBuffer() bool goodDepthBufferTexture = false; if (Context::DepthFramebufferTextures) { if (Context::WeakBlitFramebuffer) - goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->realWidth == pCurrent->m_pTexture->realWidth; + goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width == pCurrent->m_pTexture->width; else - goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->realWidth >= pCurrent->m_pTexture->realWidth || + goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width >= pCurrent->m_pTexture->width || std::abs((s32)(pCurrent->m_width - pDepthBuffer->m_width)) < 2; } else { - goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->realWidth; + goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->width; } if (goodDepthBufferTexture) { @@ -1302,8 +1300,8 @@ void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL) blitParams.srcY0 = static_cast(_fullHeight * m_scale) - bottom; blitParams.srcX1 = m_bufferWidth - right; blitParams.srcY1 = top; - blitParams.srcWidth = m_pTexture->realWidth; - blitParams.srcHeight = m_pTexture->realHeight; + blitParams.srcWidth = m_pTexture->width; + blitParams.srcHeight = m_pTexture->height; blitParams.dstX0 = m_hOffset; blitParams.dstY0 = m_vOffset + wnd.getHeightOffset(); blitParams.dstX1 = m_hOffset + wnd.getWidth(); @@ -1430,8 +1428,8 @@ void FrameBufferList::renderBuffer() s32 srcCoord[4] = { (s32)((XoffsetLeft) * srcScaleX) + cutleft, (s32)(srcY0*srcScaleY), (s32)((srcWidth + XoffsetLeft - XoffsetRight) * srcScaleX) - cutright, - min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->realHeight) }; - if (srcCoord[2] > pBufferTexture->realWidth || srcCoord[3] > pBufferTexture->realHeight) { + min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->height) }; + if (srcCoord[2] > pBufferTexture->width || srcCoord[3] > pBufferTexture->height) { removeBuffer(pBuffer->m_startAddress); return; } @@ -1462,8 +1460,8 @@ void FrameBufferList::renderBuffer() blitParams.srcY0 = srcCoord[1]; blitParams.srcX1 = srcCoord[2]; blitParams.srcY1 = srcCoord[3]; - blitParams.srcWidth = pBufferTexture->realWidth; - blitParams.srcHeight = pBufferTexture->realHeight; + blitParams.srcWidth = pBufferTexture->width; + blitParams.srcHeight = pBufferTexture->height; blitParams.dstX0 = dstCoord[0]; blitParams.dstY0 = dstCoord[1]; blitParams.dstX1 = dstCoord[2]; @@ -1498,9 +1496,9 @@ void FrameBufferList::renderBuffer() } blitParams.srcY0 = 0; - blitParams.srcY1 = min((s32)(srcY1*srcScaleY), (s32)pFilteredBuffer->m_pTexture->realHeight); - blitParams.srcWidth = pBufferTexture->realWidth; - blitParams.srcHeight = pBufferTexture->realHeight; + blitParams.srcY1 = min((s32)(srcY1*srcScaleY), (s32)pFilteredBuffer->m_pTexture->height); + blitParams.srcWidth = pBufferTexture->width; + blitParams.srcHeight = pBufferTexture->height; blitParams.dstY0 = vOffset + (s32)(dstY0*dstScaleY); blitParams.dstY1 = vOffset + (s32)(dstY1*dstScaleY); blitParams.dstWidth = m_overscan.getBufferWidth(); diff --git a/src/Graphics/ColorBufferReader.cpp b/src/Graphics/ColorBufferReader.cpp index 2b96f925..372b2428 100644 --- a/src/Graphics/ColorBufferReader.cpp +++ b/src/Graphics/ColorBufferReader.cpp @@ -18,14 +18,14 @@ namespace graphics { const u8* ColorBufferReader::_convertFloatTextureBuffer(const u8* _gpuData, u32 _width, u32 _height, u32 _heightOffset, u32 _stride) { - int bytesToCopy = m_pTexture->realWidth * _height * 16; + int bytesToCopy = m_pTexture->width * _height * 16; std::copy_n(_gpuData, bytesToCopy, m_tempPixelData.data()); u8* pixelDataAlloc = m_pixelData.data(); float* pixelData = reinterpret_cast(m_tempPixelData.data()); const u32 colorsPerPixel = 4; const u32 widthPixels = _width * colorsPerPixel; const u32 stridePixels = _stride * colorsPerPixel; - + if (_height * widthPixels > m_pixelData.size()) _height = static_cast(m_pixelData.size()) / widthPixels; @@ -47,7 +47,7 @@ namespace graphics { const u32 strideBytes = _stride * _colorsPerPixel; u8* pixelDataAlloc = m_pixelData.data(); - + if (_height * widthBytes > m_pixelData.size()) _height = static_cast(m_pixelData.size()) / widthBytes; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index 2c152aaa..f592b4ec 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -269,8 +269,8 @@ public: "uniform mediump vec2 uCacheShiftScale[2]; \n" "uniform lowp ivec2 uCacheFrameBuffer; \n" "OUT lowp vec4 vShadeColor; \n" - "OUT highp vec2 vTexCoord0; \n" - "OUT highp vec2 vTexCoord1; \n" + "OUT highp vec2 vTexCoord0; \n" + "OUT highp vec2 vTexCoord1; \n" "OUT mediump vec2 vLodTexCoord; \n" "OUT lowp float vNumLights; \n" @@ -749,7 +749,17 @@ public: "uniform lowp int uDepthSource; \n" "uniform highp float uPrimDepth; \n" "uniform mediump vec2 uScreenScale; \n" + "uniform highp vec4 uTexClamp0; \n" + "uniform highp vec4 uTexClamp1; \n" + "uniform highp vec2 uTexWrap0; \n" + "uniform highp vec2 uTexWrap1; \n" + "uniform lowp vec2 uTexMirror0; \n" + "uniform lowp vec2 uTexMirror1; \n" + "uniform highp vec2 uTexScale0; \n" + "uniform highp vec2 uTexScale1; \n" "uniform lowp int uFogUsage; \n" + "highp vec2 texCoord0; \n" + "highp vec2 texCoord1; \n" ; if (config.generalEmulation.enableLegacyBlending == 0) { @@ -938,6 +948,19 @@ public: } }; +class ShaderFragmentHeaderClampWrapMirror : public ShaderPart +{ +public: + ShaderFragmentHeaderClampWrapMirror(const opengl::GLInfo & _glinfo) + { + m_part = + "highp vec2 clampWrapMirror(in highp vec2 vTexCoord, \n" + " in highp vec4 vClamp, in highp vec2 vWrap, \n" + " in lowp vec2 vMirror, in highp vec2 vOffset); \n" + ; + } +}; + class ShaderFragmentHeaderReadMSTex : public ShaderPart { public: @@ -1297,6 +1320,28 @@ public: } }; +class ShaderFragmentClampWrapMirrorTex0 : public ShaderPart +{ +public: + ShaderFragmentClampWrapMirrorTex0(const opengl::GLInfo & _glinfo) + { + m_part = + " texCoord0 = clampWrapMirror(vTexCoord0, uTexClamp0, uTexWrap0, uTexMirror0, uTexScale0); \n" + ; + } +}; + +class ShaderFragmentClampWrapMirrorTex1 : public ShaderPart +{ +public: + ShaderFragmentClampWrapMirrorTex1(const opengl::GLInfo & _glinfo) + { + m_part = + " texCoord1 = clampWrapMirror(vTexCoord1, uTexClamp1, uTexWrap1, uTexMirror1, uTexScale1); \n" + ; + } +}; + class ShaderFragmentReadTexMipmap : public ShaderPart { public: @@ -1317,20 +1362,20 @@ public: if (_glinfo.isGLES2) { m_part = " nCurrentTile = 0; \n" - " lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n" + " lowp vec4 readtex0 = readTex(uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n" ; } else { if (config.video.multisampling > 0) { m_part = " lowp vec4 readtex0; \n" " if (uMSTexEnabled[0] == 0) { \n" - " READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" - " } else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n" + " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" + " } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n" ; } else { m_part = " lowp vec4 readtex0; \n" - " READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" + " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" ; } } @@ -1352,27 +1397,27 @@ public: shaderPart = " nCurrentTile = 0; \n"; if (g_textureConvert.getBilerp0()) { - shaderPart += " lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; + shaderPart += " lowp vec4 readtex0 = readTex(uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; } else { shaderPart += " lowp vec4 tmpTex = vec4(0.0); \n" - " lowp vec4 readtex0 = YUV_Convert(uTex0, vTexCoord0, 0, uTextureFormat[0], tmpTex); \n"; + " lowp vec4 readtex0 = YUV_Convert(uTex0, texCoord0, 0, uTextureFormat[0], tmpTex); \n"; } } else { if (!g_textureConvert.getBilerp0()) { shaderPart = " lowp vec4 readtex0; \n" - " YUVCONVERT_TEX0(readtex0, uTex0, vTexCoord0, uTextureFormat[0]) \n"; + " YUVCONVERT_TEX0(readtex0, uTex0, texCoord0, uTextureFormat[0]) \n"; } else { if (config.video.multisampling > 0) { shaderPart = " lowp vec4 readtex0; \n" " if (uMSTexEnabled[0] == 0) { \n" - " READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" - " } else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; + " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" + " } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; } else { shaderPart = " lowp vec4 readtex0; \n" - " READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"; + " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"; } } @@ -1401,9 +1446,9 @@ public: shaderPart = " nCurrentTile = 1; \n"; if (g_textureConvert.getBilerp1()) { - shaderPart += " lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; + shaderPart += " lowp vec4 readtex1 = readTex(uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; } else { - shaderPart += " lowp vec4 readtex1 = YUV_Convert(uTex1, vTexCoord1, uTextureConvert, uTextureFormat[1], readtex0); \n"; + shaderPart += " lowp vec4 readtex1 = YUV_Convert(uTex1, texCoord1, uTextureConvert, uTextureFormat[1], readtex0); \n"; } } else { @@ -1411,17 +1456,17 @@ public: if (!g_textureConvert.getBilerp1()) { shaderPart = " lowp vec4 readtex1; \n" - " YUVCONVERT_TEX1(readtex1, uTex1, vTexCoord1, uTextureFormat[1], readtex0) \n"; + " YUVCONVERT_TEX1(readtex1, uTex1, texCoord1, uTextureFormat[1], readtex0) \n"; } else { if (config.video.multisampling > 0) { shaderPart = " lowp vec4 readtex1; \n" " if (uMSTexEnabled[1] == 0) { \n" - " READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n" - " } else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; + " READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n" + " } else readtex1 = readTexMS(uMSTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; } else { shaderPart = " lowp vec4 readtex1; \n" - " READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"; + " READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"; } } @@ -1651,8 +1696,8 @@ public: "uniform mediump float uMinLod; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" - " readtex0 = texture2D(uTex0, vTexCoord0); \n" - " readtex1 = texture2D(uTex1, vTexCoord1); \n" + " readtex0 = texture2D(uTex0, texCoord0); \n" + " readtex1 = texture2D(uTex1, texCoord1); \n" " if (uMaxTile == 0) return 1.0; \n" " return uMinLod; \n" "} \n" @@ -1665,8 +1710,8 @@ public: "uniform lowp int uTextureDetail; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" - " readtex0 = texture2D(uTex0, vTexCoord0); \n" - " readtex1 = texture2DLodEXT(uTex1, vTexCoord1, 0.0); \n" + " readtex0 = texture2D(uTex0, texCoord0); \n" + " readtex1 = texture2DLodEXT(uTex1, texCoord1, 0.0); \n" " \n" " mediump float fMaxTile = float(uMaxTile); \n" " mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n" @@ -1695,9 +1740,9 @@ public: " lod_tile = min(lod_tile, fMaxTile); \n" " lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n" " lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n" - " lowp vec4 lodT = texture2DLodEXT(uTex1, vTexCoord1, lod_tile); \n" - " lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_m1); \n" - " lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_p1); \n" + " lowp vec4 lodT = texture2DLodEXT(uTex1, texCoord1, lod_tile); \n" + " lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, texCoord1, lod_tile_m1); \n" + " lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, texCoord1, lod_tile_p1); \n" " if (lod_tile < 1.0) { \n" " if (magnify) { \n" // !sharpen && !detail @@ -1731,8 +1776,8 @@ public: "uniform mediump float uMinLod; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" - " readtex0 = texture(uTex0, vTexCoord0); \n" - " readtex1 = texture(uTex1, vTexCoord1); \n" + " readtex0 = texture(uTex0, texCoord0); \n" + " readtex1 = texture(uTex1, texCoord1); \n" " if (uMaxTile == 0) return 1.0; \n" " return uMinLod; \n" "} \n" @@ -1777,8 +1822,8 @@ public: "uniform lowp int uTextureDetail; \n" " \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" - " READ_TEX_NORMAL(readtex0, uTex0, vTexCoord0, 0.0); \n" - " READ_TEX_MIPMAP(readtex1, uTex1, vTexCoord1, 0.0); \n" + " READ_TEX_NORMAL(readtex0, uTex0, texCoord0, 0.0); \n" + " READ_TEX_MIPMAP(readtex1, uTex1, texCoord1, 0.0); \n" " \n" " mediump float fMaxTile = float(uMaxTile); \n" " mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n" @@ -1808,9 +1853,9 @@ public: " lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n" " lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n" " lowp vec4 lodT, lodT_m1, lodT_p1; \n" - " READ_TEX_MIPMAP(lodT, uTex1, vTexCoord1, lod_tile); \n" - " READ_TEX_MIPMAP(lodT_m1, uTex1, vTexCoord1, lod_tile_m1); \n" - " READ_TEX_MIPMAP(lodT_p1, uTex1, vTexCoord1, lod_tile_p1); \n" + " READ_TEX_MIPMAP(lodT, uTex1, texCoord1, lod_tile); \n" + " READ_TEX_MIPMAP(lodT_m1, uTex1, texCoord1, lod_tile_m1); \n" + " READ_TEX_MIPMAP(lodT_p1, uTex1, texCoord1, lod_tile_p1); \n" " if (lod_tile < 1.0) { \n" " if (magnify) { \n" // !sharpen && !detail @@ -2174,6 +2219,33 @@ public: } }; +class ShaderClampWrapMirror : public ShaderPart +{ +public: + ShaderClampWrapMirror(const opengl::GLInfo & _glinfo) + { + m_part = + "highp vec2 clampWrapMirror(in highp vec2 vTexCoord, in highp vec4 vClamp, \n" + " in highp vec2 vWrap, in lowp vec2 vMirror, in highp vec2 vScale) \n" + "{ \n" + " highp vec2 texCoord = clamp(vTexCoord, vClamp.xy, vClamp.zw); \n" + " lowp vec2 one = vec2(1.0); \n" + " lowp vec2 clamped = step(vClamp.zw, texCoord); \n" + " lowp vec2 notClamped = one - clamped; \n" + " texCoord = clamped * texCoord + notClamped * mod(texCoord, vWrap); \n" + " highp vec2 intPart = floor(texCoord); \n" + " highp vec2 fractPart = fract(texCoord); \n" + " lowp vec2 needMirror = step(vec2(0.5), mod(intPart, vec2(2.0))) * vMirror; \n" + " texCoord = clamped * texCoord + notClamped * fractPart; \n" + " texCoord = (one - vMirror) * texCoord + vMirror * fractPart; \n" + " texCoord = (one - texCoord) * needMirror + texCoord * (one - needMirror); \n" + " texCoord *= vScale; \n" + " return texCoord; \n" + "} \n" + ; + } +}; + /*---------------ShaderPartsEnd-------------*/ static @@ -2339,6 +2411,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine m_fragmentHeaderWriteDepth->write(ssShader); m_fragmentHeaderDepthCompare->write(ssShader); m_fragmentHeaderReadMSTex->write(ssShader); + m_fragmentHeaderClampWrapMirror->write(ssShader); if (bUseLod) m_fragmentHeaderMipMap->write(ssShader); else if (g_cycleType < G_CYC_COPY) @@ -2371,6 +2444,11 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine m_fragmentBlendMux->write(ssShader); if (bUseTextures) { + if (combinerInputs.usesTile(0)) + m_fragmentClampWrapMirrorTex0->write(ssShader); + if (combinerInputs.usesTile(1)) + m_fragmentClampWrapMirrorTex1->write(ssShader); + if (bUseLod) { m_fragmentReadTexMipmap->write(ssShader); } else { @@ -2408,6 +2486,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine m_shaderCalcLight->write(ssShader); if (bUseTextures) { + m_shaderClampWrapMirror->write(ssShader); if (bUseLod) m_shaderMipmap->write(ssShader); else { @@ -2518,6 +2597,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o , m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_glinfo)) , m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_glinfo)) , m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_glinfo)) +, m_fragmentHeaderClampWrapMirror(new ShaderFragmentHeaderClampWrapMirror(_glinfo)) , m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_glinfo)) , m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_glinfo)) , m_fragmentHeaderDepthCompare(new ShaderFragmentHeaderDepthCompare(_glinfo)) @@ -2528,6 +2608,8 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o , m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo)) , m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo)) , m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo)) +, m_fragmentClampWrapMirrorTex0(new ShaderFragmentClampWrapMirrorTex0(_glinfo)) +, m_fragmentClampWrapMirrorTex1(new ShaderFragmentClampWrapMirrorTex1(_glinfo)) , m_fragmentReadTexCopyMode(new ShaderFragmentReadTexCopyMode(_glinfo)) , m_fragmentReadTexMipmap(new ShaderFragmentReadTexMipmap(_glinfo)) , m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_glinfo)) @@ -2542,6 +2624,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o , m_shaderReadtexCopyMode(new ShaderReadtexCopyMode(_glinfo)) , m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo)) , m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo)) +, m_shaderClampWrapMirror(new ShaderClampWrapMirror(_glinfo)) , m_useProgram(_useProgram) , m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits()) { diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h index ba194863..41c94e42 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h @@ -62,6 +62,7 @@ namespace glsl { ShaderPartPtr m_fragmentHeaderWriteDepth; ShaderPartPtr m_fragmentHeaderCalcLight; ShaderPartPtr m_fragmentHeaderMipMap; + ShaderPartPtr m_fragmentHeaderClampWrapMirror; ShaderPartPtr m_fragmentHeaderReadMSTex; ShaderPartPtr m_fragmentHeaderDither; ShaderPartPtr m_fragmentHeaderDepthCompare; @@ -72,6 +73,8 @@ namespace glsl { ShaderPartPtr m_fragmentBlendMux; ShaderPartPtr m_fragmentReadTex0; ShaderPartPtr m_fragmentReadTex1; + ShaderPartPtr m_fragmentClampWrapMirrorTex0; + ShaderPartPtr m_fragmentClampWrapMirrorTex1; ShaderPartPtr m_fragmentReadTexCopyMode; ShaderPartPtr m_fragmentReadTexMipmap; ShaderPartPtr m_fragmentCallN64Depth; @@ -87,6 +90,7 @@ namespace glsl { ShaderPartPtr m_shaderReadtexCopyMode; ShaderPartPtr m_shaderN64DepthCompare; ShaderPartPtr m_shaderN64DepthRender; + ShaderPartPtr m_shaderClampWrapMirror; std::unique_ptr m_uniformFactory; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp index d862030a..411c6d65 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp @@ -815,9 +815,9 @@ public: { TextureCache & cache = textureCache(); if (m_useT0 && cache.current[0] != NULL) - uTextureSize[0].set((float)cache.current[0]->realWidth, (float)cache.current[0]->realHeight, _force); + uTextureSize[0].set((float)cache.current[0]->width, (float)cache.current[0]->height, _force); if (m_useT1 && cache.current[1] != NULL) - uTextureSize[1].set((float)cache.current[1]->realWidth, (float)cache.current[1]->realHeight, _force); + uTextureSize[1].set((float)cache.current[1]->width, (float)cache.current[1]->height, _force); } private: @@ -853,35 +853,37 @@ public: if (!m_useTile[t]) continue; - if (gSP.textureTile[t] != nullptr) { - if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG) + gDPTile * pTile = gSP.textureTile[t]; + if (pTile != nullptr) { + if (pTile->textureMode == TEXTUREMODE_BGIMAGE || pTile->textureMode == TEXTUREMODE_FRAMEBUFFER_BG) uTexOffset[t].set(0.0f, 0.0f, _force); else { - float fuls = gSP.textureTile[t]->fuls; - float fult = gSP.textureTile[t]->fult; - if (gSP.textureTile[t]->frameBufferAddress > 0) { - FrameBuffer * pBuffer = frameBufferList().getBuffer(gSP.textureTile[t]->frameBufferAddress); + float fuls = pTile->fuls; + float fult = pTile->fult; + if (pTile->frameBufferAddress > 0) { + FrameBuffer * pBuffer = frameBufferList().getBuffer(pTile->frameBufferAddress); if (pBuffer != nullptr) { - if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0) - fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks)); - if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0) - fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt)); + if (pTile->masks > 0 && pTile->clamps == 0) + fuls = float(pTile->uls % (1 << pTile->masks)); + if (pTile->maskt > 0 && pTile->clampt == 0) + fult = float(pTile->ult % (1 << pTile->maskt)); } else { - gSP.textureTile[t]->frameBufferAddress = 0; + pTile->frameBufferAddress = 0; } } uTexOffset[t].set(fuls, fult, _force); } } - if (cache.current[t] != nullptr) { + CachedTexture *_pTexture = cache.current[t]; + if (_pTexture != nullptr) { f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT); uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force); - uCacheScale[t].set(cache.current[t]->scaleS, cache.current[t]->scaleT, _force); - uCacheOffset[t].set(cache.current[t]->offsetS, cache.current[t]->offsetT, _force); - nFB[t] = cache.current[t]->frameBufferTexture; + uCacheScale[t].set(_pTexture->scaleS, _pTexture->scaleT, _force); + uCacheOffset[t].set(_pTexture->offsetS, _pTexture->offsetT, _force); + nFB[t] = _pTexture->frameBufferTexture; } } @@ -899,6 +901,107 @@ private: iv2Uniform uCacheFrameBuffer; }; +class UClampWrapMirrorTex : public UniformGroup +{ +public: + UClampWrapMirrorTex(GLuint _program, bool _useT0, bool _useT1) + { + m_useTile[0] = _useT0; + m_useTile[1] = _useT1; + LocateUniform(uTexClamp0); + LocateUniform(uTexClamp1); + LocateUniform(uTexWrap0); + LocateUniform(uTexWrap1); + LocateUniform(uTexMirror0); + LocateUniform(uTexMirror1); + LocateUniform(uTexScale0); + LocateUniform(uTexScale1); + } + + void update(bool _force) override + { + std::array aTexClamp[2] = { { -10000.0f, -10000.0f, 10000.0f, 10000.0f }, + { -10000.0f, -10000.0f, 10000.0f, 10000.0f } }; + std::array aTexWrap[2] = { { 10000.0f, 10000.0f }, { 10000.0f, 10000.0f } }; + std::array aTexMirror[2] = { { 0.0f, 0.0f}, { 0.0f, 0.0f } }; + std::array aTexScale[2] = { { 1.0f, 1.0f },{ 1.0f, 1.0f } }; + TextureCache & cache = textureCache(); + for (u32 t = 0; t < 2; ++t) { + if (!m_useTile[t]) + continue; + + const gDPTile * pTile = gSP.textureTile[t]; + CachedTexture * pTexture = cache.current[t]; + if (pTile == nullptr || pTexture == nullptr) + continue; + + if (gDP.otherMode.cycleType != G_CYC_COPY) { + if (pTexture->clampS) { + aTexClamp[t][0] = 0.0f; // S lower bound + if (pTexture->frameBufferTexture != CachedTexture::fbNone) + aTexClamp[t][2] = 1.0f; + else { + u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; + if (pTile->size > pTexture->size) + tileWidth <<= pTile->size - pTexture->size; + // aTexClamp[t][2] = f32(tileWidth) / (pTexture->mirrorS ? f32(pTexture->width) : f32(pTexture->clampWidth)); // S upper bound + aTexClamp[t][2] = f32(tileWidth) / f32(pTexture->width); // S upper bound + } + } + if (pTexture->clampT) { + aTexClamp[t][1] = 0.0f; // T lower bound + if (pTexture->frameBufferTexture != CachedTexture::fbNone) + aTexClamp[t][3] = 1.0f; + else { + const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; + // aTexClamp[t][3] = f32(tileHeight) / (pTexture->mirrorT ? f32(pTexture->height) : f32(pTexture->clampHeight)); // T upper bound + aTexClamp[t][3] = f32(tileHeight) / f32(pTexture->height); // T upper bound + } + } + } + if (pTexture->maskS) { + u32 wrapWidth = 1 << pTile->originalMaskS; + u32 pow2Width = pow2(pTexture->width); + aTexWrap[t][0] = f32(wrapWidth) / f32(pow2Width); + aTexScale[t][0] = 1.0f / (1.0f - f32(pow2Width - pTexture->width) / f32(pow2Width)); + } + if (pTexture->maskT) { + u32 wrapHeight = 1 << pTile->originalMaskT; + u32 pow2Height = pow2(pTexture->height); + aTexWrap[t][1] = f32(wrapHeight) / f32(pow2Height); + aTexScale[t][1] = 1.0f / (1.0f - f32(pow2Height - pTexture->height) / f32(pow2Height)); + } + if (pTexture->mirrorS) { + aTexMirror[t][0] = 1.0f; + aTexWrap[t][0] *= 2.0f; + } + if (pTexture->mirrorT) { + aTexMirror[t][1] = 1.0f; + aTexWrap[t][1] *= 2.0f; + } + } + + uTexClamp0.set(aTexClamp[0].data(), _force); + uTexClamp1.set(aTexClamp[1].data(), _force); + uTexWrap0.set(aTexWrap[0][0], aTexWrap[0][1], _force); + uTexWrap1.set(aTexWrap[1][0], aTexWrap[1][1], _force); + uTexMirror0.set(aTexMirror[0][0], aTexMirror[0][1], _force); + uTexMirror1.set(aTexMirror[1][0], aTexMirror[1][1], _force); + uTexScale0.set(aTexScale[0][0], aTexScale[0][1], _force); + uTexScale1.set(aTexScale[1][0], aTexScale[1][1], _force); + } + +private: + bool m_useTile[2]; + fv4Uniform uTexClamp0; + fv4Uniform uTexClamp1; + fv2Uniform uTexWrap0; + fv2Uniform uTexWrap1; + fv2Uniform uTexMirror0; + fv2Uniform uTexMirror1; + fv2Uniform uTexScale0; + fv2Uniform uTexScale1; +}; class ULights : public UniformGroup { @@ -966,6 +1069,8 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program, if (!_key.isRectKey()) _uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1))); + + _uniforms.emplace_back(new UClampWrapMirrorTex(_program, _inputs.usesTile(0), _inputs.usesTile(1))); } _uniforms.emplace_back(new UFog(_program)); diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h index c64812ae..ee79f772 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h +++ b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h @@ -20,7 +20,7 @@ namespace glsl { bool _saveCombinerKeys(const graphics::Combiners & _combiners) const; bool _loadFromCombinerKeys(graphics::Combiners & _combiners); - const u32 m_formatVersion = 0x26U; + const u32 m_formatVersion = 0x28U; const u32 m_keysFormatVersion = 0x04; const opengl::GLInfo & m_glinfo; opengl::CachedUseProgram * m_useProgram; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp index 91a10184..f94cafe7 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp @@ -539,9 +539,9 @@ namespace glsl { FXAAShaderBase::activate(); FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN); if (pBuffer != nullptr && pBuffer->m_pTexture != nullptr && - (m_width != pBuffer->m_pTexture->realWidth || m_height != pBuffer->m_pTexture->realHeight)) { - m_width = pBuffer->m_pTexture->realWidth; - m_height = pBuffer->m_pTexture->realHeight; + (m_width != pBuffer->m_pTexture->width || m_height != pBuffer->m_pTexture->height)) { + m_width = pBuffer->m_pTexture->width; + m_height = pBuffer->m_pTexture->height; glUniform2f(m_textureSizeLoc, GLfloat(m_width), GLfloat(m_height)); } } diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp index d82d5135..cb0ccd47 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp @@ -54,7 +54,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); - glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, nullptr); + glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, nullptr); if (!_params.sync) { m_curIndex = (m_curIndex + 1) % m_numPBO; @@ -63,7 +63,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer } _heightOffset = 0; - _stride = m_pTexture->realWidth; + _stride = m_pTexture->width; return reinterpret_cast(m_PBOData[m_curIndex]); } diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp index 72e4d26d..b80cd78b 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp @@ -51,7 +51,7 @@ const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferPa GLenum type = GLenum(_params.colorType); m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); - glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0); + glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, 0); // If Sync, read pixels from the buffer, copy them to RDRAM. // If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM. if (!_params.sync) { @@ -60,10 +60,10 @@ const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferPa } _heightOffset = 0; - _stride = m_pTexture->realWidth; + _stride = m_pTexture->width; return reinterpret_cast(glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, - m_pTexture->realWidth * _params.height * _params.colorFormatBytes, GL_MAP_READ_BIT)); + m_pTexture->width * _params.height * _params.colorFormatBytes, GL_MAP_READ_BIT)); } void ColorBufferReaderWithPixelBuffer::cleanUp() diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithReadPixels.cpp b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithReadPixels.cpp index 8aace1f3..aedda5df 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithReadPixels.cpp +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithReadPixels.cpp @@ -19,10 +19,10 @@ const u8 * ColorBufferReaderWithReadPixels::_readPixels(const ReadColorBufferPar // No async pixel buffer copies are supported in this class, this is a last resort fallback u8* gpuData = m_pixelData.data(); - glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, gpuData); + glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, gpuData); _heightOffset = 0; - _stride = m_pTexture->realWidth; + _stride = m_pTexture->width; return gpuData; } diff --git a/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp b/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp index 767d7c83..3070ed00 100644 --- a/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp +++ b/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp @@ -82,15 +82,15 @@ void DisplayWindowWindows::_saveBufferContent(graphics::ObjectHandle _fbo, Cache GLint oldMode; glGetIntegerv(GL_READ_BUFFER, &oldMode); gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, _fbo); - pixelData = (unsigned char*)malloc(_pTexture->realWidth * _pTexture->realHeight * 3); - glReadPixels(0, 0, _pTexture->realWidth, _pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData); + pixelData = (unsigned char*)malloc(_pTexture->width * _pTexture->height * 3); + glReadPixels(0, 0, _pTexture->width, _pTexture->height, GL_RGB, GL_UNSIGNED_BYTE, pixelData); if (graphics::BufferAttachmentParam(oldMode) == graphics::bufferAttachment::COLOR_ATTACHMENT0) { FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); if (pCurrentBuffer != nullptr) gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, pCurrentBuffer->m_FBO); } glReadBuffer(oldMode); - SaveScreenshot(m_strScreenDirectory, RSP.romname, _pTexture->realWidth, _pTexture->realHeight, pixelData); + SaveScreenshot(m_strScreenDirectory, RSP.romname, _pTexture->width, _pTexture->height, pixelData); free(pixelData); } diff --git a/src/NoiseTexture.cpp b/src/NoiseTexture.cpp index d4ea3594..50839638 100644 --- a/src/NoiseTexture.cpp +++ b/src/NoiseTexture.cpp @@ -122,17 +122,17 @@ void NoiseTexture::init() m_pTexture[i]->maskT = 0; m_pTexture[i]->mirrorS = 0; m_pTexture[i]->mirrorT = 0; - m_pTexture[i]->realWidth = NOISE_TEX_WIDTH; - m_pTexture[i]->realHeight = NOISE_TEX_HEIGHT; - m_pTexture[i]->textureBytes = m_pTexture[i]->realWidth * m_pTexture[i]->realHeight; + m_pTexture[i]->width = NOISE_TEX_WIDTH; + m_pTexture[i]->height = NOISE_TEX_HEIGHT; + m_pTexture[i]->textureBytes = m_pTexture[i]->width * m_pTexture[i]->height; const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); { Context::InitTextureParams params; params.handle = m_pTexture[i]->name; params.textureUnitIndex = textureIndices::NoiseTex; - params.width = m_pTexture[i]->realWidth; - params.height = m_pTexture[i]->realHeight; + params.width = m_pTexture[i]->width; + params.height = m_pTexture[i]->height; params.internalFormat = fbTexFormats.noiseInternalFormat; params.format = fbTexFormats.noiseFormat; params.dataType = fbTexFormats.noiseType; diff --git a/src/PaletteTexture.cpp b/src/PaletteTexture.cpp index 23d7d175..84bdcf3a 100644 --- a/src/PaletteTexture.cpp +++ b/src/PaletteTexture.cpp @@ -35,14 +35,14 @@ void PaletteTexture::init() m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; - m_pTexture->realWidth = 256; - m_pTexture->realHeight = 1; - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.lutFormatBytes; + m_pTexture->width = 256; + m_pTexture->height = 1; + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.lutFormatBytes; Context::InitTextureParams initParams; initParams.handle = m_pTexture->name; - initParams.width = m_pTexture->realWidth; - initParams.height = m_pTexture->realHeight; + initParams.width = m_pTexture->width; + initParams.height = m_pTexture->height; initParams.internalFormat = fbTexFormats.lutInternalFormat; initParams.format = fbTexFormats.lutFormat; initParams.dataType = fbTexFormats.lutType; @@ -93,8 +93,8 @@ void PaletteTexture::update() Context::UpdateTextureDataParams params; params.handle = m_pTexture->name; params.textureUnitIndex = textureIndices::PaletteTex; - params.width = m_pTexture->realWidth; - params.height = m_pTexture->realHeight; + params.width = m_pTexture->width; + params.height = m_pTexture->height; params.format = fbTexFormats.lutFormat; params.internalFormat = fbTexFormats.lutInternalFormat; params.dataType = fbTexFormats.lutType; diff --git a/src/PostProcessor.cpp b/src/PostProcessor.cpp index 993e3742..d48a72b0 100644 --- a/src/PostProcessor.cpp +++ b/src/PostProcessor.cpp @@ -33,14 +33,14 @@ void PostProcessor::_createResultBuffer(const FrameBuffer * _pMainBuffer) pTexture->maskT = 0; pTexture->mirrorS = 0; pTexture->mirrorT = 0; - pTexture->realWidth = pMainTexture->realWidth; - pTexture->realHeight = pMainTexture->realHeight; - pTexture->textureBytes = pTexture->realWidth * pTexture->realHeight * 4; + pTexture->width = pMainTexture->width; + pTexture->height = pMainTexture->height; + pTexture->textureBytes = pTexture->width * pTexture->height * 4; Context::InitTextureParams initParams; initParams.handle = pTexture->name; - initParams.width = pTexture->realWidth; - initParams.height = pTexture->realHeight; + initParams.width = pTexture->width; + initParams.height = pTexture->height; initParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); initParams.format = colorFormat::RGBA; initParams.dataType = datatype::UNSIGNED_BYTE; @@ -131,16 +131,16 @@ FrameBuffer * PostProcessor::_doPostProcessing(FrameBuffer * _pBuffer, graphics: GraphicsDrawer::CopyRectParams copyParams; copyParams.srcX0 = 0; copyParams.srcY0 = 0; - copyParams.srcX1 = m_pTextureOriginal->realWidth; - copyParams.srcY1 = m_pTextureOriginal->realHeight; - copyParams.srcWidth = m_pTextureOriginal->realWidth; - copyParams.srcHeight = m_pTextureOriginal->realHeight; + copyParams.srcX1 = m_pTextureOriginal->width; + copyParams.srcY1 = m_pTextureOriginal->height; + copyParams.srcWidth = m_pTextureOriginal->width; + copyParams.srcHeight = m_pTextureOriginal->height; copyParams.dstX0 = 0; copyParams.dstY0 = 0; - copyParams.dstX1 = pDstTex->realWidth; - copyParams.dstY1 = pDstTex->realHeight; - copyParams.dstWidth = pDstTex->realWidth; - copyParams.dstHeight = pDstTex->realHeight; + copyParams.dstX1 = pDstTex->width; + copyParams.dstY1 = pDstTex->height; + copyParams.dstWidth = pDstTex->width; + copyParams.dstHeight = pDstTex->height; copyParams.tex[0] = m_pTextureOriginal; copyParams.filter = textureParameters::FILTER_NEAREST; copyParams.combiner = _pShader; diff --git a/src/TexrectDrawer.cpp b/src/TexrectDrawer.cpp index 62c51f6d..da837d94 100644 --- a/src/TexrectDrawer.cpp +++ b/src/TexrectDrawer.cpp @@ -50,17 +50,17 @@ void TexrectDrawer::init() m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; - m_pTexture->realWidth = 640; - m_pTexture->realHeight = 580; - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.colorFormatBytes; + m_pTexture->width = 640; + m_pTexture->height = 580; + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes; m_stepX = 2.0f / 640.0f; m_stepY = 2.0f / 580.0f; Context::InitTextureParams initParams; initParams.handle = m_pTexture->name; initParams.textureUnitIndex = textureIndices::Tex[0]; - initParams.width = m_pTexture->realWidth; - initParams.height = m_pTexture->realHeight; + initParams.width = m_pTexture->width; + initParams.height = m_pTexture->height; initParams.internalFormat = fbTexFormats.colorInternalFormat; initParams.format = fbTexFormats.colorFormat; initParams.dataType = fbTexFormats.colorType; @@ -89,7 +89,7 @@ void TexrectDrawer::init() m_programTex.reset(gfxContext.createTexrectDrawerDrawShader()); m_programClear.reset(gfxContext.createTexrectDrawerClearShader()); - m_programTex->setTextureSize(m_pTexture->realWidth, m_pTexture->realHeight); + m_programTex->setTextureSize(m_pTexture->width, m_pTexture->height); m_vecRectCoords.reserve(256); } @@ -378,10 +378,10 @@ bool TexrectDrawer::draw() scaleX *= 2.0f; scaleY *= 2.0f; - const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->realWidth + 0.5f / (float)m_pTexture->realWidth; - const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->realHeight;// +0.5f / (float)m_pTexture->realHeight; - const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->realWidth; - const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->realHeight; + const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->width + 0.5f / (float)m_pTexture->width; + const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->height;// +0.5f / (float)m_pTexture->height; + const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->width; + const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->height; const float W = 1.0f; drawer._updateScreenCoordsViewport(m_pBuffer); diff --git a/src/TextDrawer.cpp b/src/TextDrawer.cpp index 57e017a4..4d134e32 100644 --- a/src/TextDrawer.cpp +++ b/src/TextDrawer.cpp @@ -108,9 +108,9 @@ struct Atlas { m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; - m_pTexture->realWidth = w; - m_pTexture->realHeight = h; - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.noiseFormatBytes; + m_pTexture->width = w; + m_pTexture->height = h; + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.noiseFormatBytes; Context::InitTextureParams initParams; initParams.handle = m_pTexture->name; diff --git a/src/Textures.cpp b/src/Textures.cpp index dcde9896..0051d95a 100644 --- a/src/Textures.cpp +++ b/src/Textures.cpp @@ -214,28 +214,10 @@ inline u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette ) return RGBA8888_RGBA4444(((u32*)src)[x^i]); } -#if 0 -u32 YUV_RGBA8888(u8 y, u8 u, u8 v) -{ - s32 r = (s32)(y + (1.370705f * (v - 128))); - s32 g = (s32)((y - (0.698001f * (v - 128)) - (0.337633f * (u - 128)))); - s32 b = (s32)(y + (1.732446f * (u - 128))); - //clipping the result - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - - return (0xff << 24) | (b << 16) | (g << 8) | r; -} -#else inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v) { return (0xff << 24) | (y << 16) | (v << 8) | u; } -#endif inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x) { @@ -460,8 +442,6 @@ void TextureCache::_initDummyTexture(CachedTexture * _pDummy) _pDummy->frameBufferTexture = CachedTexture::fbNone; _pDummy->width = 2; _pDummy->height = 2; - _pDummy->realWidth = 2; - _pDummy->realHeight = 2; _pDummy->maskS = 0; _pDummy->maskT = 0; _pDummy->scaleS = 0.5f; @@ -485,8 +465,8 @@ void TextureCache::init() params.handle = m_pDummy->name; params.mipMapLevel = 0; params.msaaLevel = 0; - params.width = m_pDummy->realWidth; - params.height = m_pDummy->realHeight; + params.width = m_pDummy->width; + params.height = m_pDummy->height; params.format = colorFormat::RGBA; params.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); params.dataType = datatype::UNSIGNED_BYTE; @@ -507,8 +487,8 @@ void TextureCache::init() msParams.handle = m_pMSDummy->name; msParams.mipMapLevel = 0; msParams.msaaLevel = config.video.multisampling; - msParams.width = m_pMSDummy->realWidth; - msParams.height = m_pMSDummy->realHeight; + msParams.width = m_pMSDummy->width; + msParams.height = m_pMSDummy->height; msParams.format = colorFormat::RGBA; msParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); msParams.dataType = datatype::UNSIGNED_BYTE; @@ -577,9 +557,11 @@ CachedTexture * TextureCache::addFrameBufferTexture(bool _multisample) struct TileSizes { - u32 maskWidth, clampWidth, width, realWidth; - u32 maskHeight, clampHeight, height, realHeight; - u32 bytes; + u32 clampWidth = 0U; + u32 width = 0U; + u32 clampHeight = 0U; + u32 height = 0U; + u32 bytes = 0U; }; static @@ -589,11 +571,9 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile) pTile->masks = pTile->originalMaskS; pTile->maskt = pTile->originalMaskT; - const TextureLoadParameters & loadParams = - ImageFormat::get().tlp[gDP.otherMode.textureLUT][pTile->size][pTile->format]; - const u32 maxTexels = loadParams.maxTexels; u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; + if (tileWidth == 1 && tileHeight == 1 && gDP.otherMode.cycleType == G_CYC_COPY && _pLoadTile != nullptr && @@ -606,22 +586,6 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile) tileHeight = lry - uly + 1; } - const bool bUseLoadSizes = _pLoadTile != nullptr && _pLoadTile->loadType == LOADTYPE_TILE && - (pTile->tmem == _pLoadTile->tmem); - - u32 loadWidth = 0, loadHeight = 0; - if (bUseLoadSizes) { - loadWidth = ((_pLoadTile->lrs - _pLoadTile->uls) & 0x03FF) + 1; - loadHeight = ((_pLoadTile->lrt - _pLoadTile->ult) & 0x03FF) + 1; - } - - const u32 lineWidth = pTile->line << loadParams.lineShift; - const u32 lineHeight = lineWidth != 0 ? min(maxTexels / lineWidth, tileHeight) : 0; - - u32 maskWidth = 1 << pTile->masks; - u32 maskHeight = 1 << pTile->maskt; - u32 width, height; - const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF; gDPLoadTileInfo &info = gDP.loadInfo[pTile->tmem & tMemMask]; if (pTile->tmem == gDP.loadTile->tmem) { @@ -637,75 +601,44 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile) gDP.loadTile->loadWidth = gDP.loadTile->loadHeight = 0; } _sizes.bytes = info.bytes; + + u32 width = 0, height = 0; if (info.loadType == LOADTYPE_TILE) { - if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) - width = maskWidth; // Use mask width if set and valid - else { - width = info.width; - if (info.size > pTile->size) - width <<= info.size - pTile->size; - } - if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) - height = maskHeight; - else - height = info.height; + width = min(info.width, info.texWidth); + if (info.size > pTile->size) + width <<= info.size - pTile->size; + + height = info.height; + if ((config.generalEmulation.hacks & hack_MK64) != 0 && (height % 2) != 0) + height--; } else { - if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) - width = maskWidth; // Use mask width if set and valid - else if ((tileWidth * tileHeight) <= maxTexels) - width = tileWidth; // else use tile width if valid + int tile_width = pTile->lrs - pTile->uls + 1; + int tile_height = pTile->lrt - pTile->ult + 1; + + int mask_width = (pTile->masks == 0) ? (tile_width) : (1 << pTile->masks); + int mask_height = (pTile->maskt == 0) ? (tile_height) : (1 << pTile->maskt); + + if ((pTile->clamps && tile_width <= 256)) + width = min(mask_width, tile_width); else - width = lineWidth; // else use line-based width + width = mask_width; - if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) - height = maskHeight; - else if ((tileWidth * tileHeight) <= maxTexels) - height = tileHeight; + if ((pTile->clampt && tile_height <= 256) || (mask_height > 256)) + height = min(mask_height, tile_height); else - height = lineHeight; + height = mask_height; } - _sizes.clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width; - _sizes.clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height; - - // Make sure masking is valid - if (maskWidth > width) { - pTile->masks = powof(width); - maskWidth = 1 << pTile->masks; - } - - if (maskHeight > height) { - pTile->maskt = powof(height); - maskHeight = 1 << pTile->maskt; - } - - _sizes.maskWidth = maskWidth; - _sizes.maskHeight = maskHeight; _sizes.width = width; _sizes.height = height; - if (pTile->clamps != 0) - _sizes.realWidth = _sizes.clampWidth; - else if (pTile->masks != 0) - _sizes.realWidth = _sizes.maskWidth; - else - _sizes.realWidth = _sizes.width; - - if (pTile->clampt != 0) - _sizes.realHeight = _sizes.clampHeight; - else if (pTile->maskt != 0) - _sizes.realHeight = _sizes.maskHeight; - else - _sizes.realHeight = _sizes.height; - - if (gSP.texture.level > 0) { - _sizes.realWidth = pow2(_sizes.realWidth); - _sizes.realHeight = pow2(_sizes.realHeight); - } + _sizes.clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width; + _sizes.clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height; } + inline -void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, f32 _scale) +void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, u16 widthOrg, u16 heightOrg) { _pTexture->textureBytes = _info.width * _info.height; @@ -714,20 +647,12 @@ void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, f3 format == internalcolorFormat::RGBA4 || format == internalcolorFormat::RGB5_A1) { _pTexture->textureBytes <<= 1; - } - else { + } else { _pTexture->textureBytes <<= 2; } - if (_pTexture->realWidth == _pTexture->width * 2) - _pTexture->clampS = 0; // force wrap or mirror s - if (_pTexture->realHeight == _pTexture->height * 2) - _pTexture->clampT = 0; // force wrap or mirror t - - _pTexture->realWidth = _info.width; - _pTexture->realHeight = _info.height; - _pTexture->scaleS = _scale / f32(_info.width); - _pTexture->scaleT = _scale / f32(_info.height); + _pTexture->scaleS = 1.0f / (_pTexture->maskS ? f32(pow2(widthOrg)) : f32(widthOrg)); + _pTexture->scaleT = 1.0f / (_pTexture->maskT ? f32(pow2(heightOrg)) : f32(heightOrg)); _pTexture->bHDTexture = true; } @@ -776,7 +701,7 @@ bool TextureCache::_loadHiresBackground(CachedTexture *_pTexture, u64 & _ricecrc gfxContext.init2DTexture(params); assert(!gfxContext.isError()); - _updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(tile_width)); + _updateCachedTexture(ghqTexInfo, _pTexture, tile_width, tile_height); return true; } return false; @@ -803,12 +728,12 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) const TextureLoadParameters & loadParams = ImageFormat::get().tlp[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format]; if (loadParams.autoFormat == internalcolorFormat::RGBA8) { - pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 2; + pTexture->textureBytes = (pTexture->width * pTexture->height) << 2; GetTexel = loadParams.Get32; glInternalFormat = loadParams.glInternalFormat32; glType = loadParams.glType32; } else { - pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 1; + pTexture->textureBytes = (pTexture->width * pTexture->height) << 1; GetTexel = loadParams.Get16; glInternalFormat = loadParams.glInternalFormat16; glType = loadParams.glType16; @@ -831,12 +756,12 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) clampTClamp = pTexture->height - 1; j = 0; - for (y = 0; y < pTexture->realHeight; y++) { + for (y = 0; y < pTexture->height; y++) { ty = min(y, (u32)clampTClamp); pSrc = &pSwapped[bpl * ty]; - for (x = 0; x < pTexture->realWidth; x++) { + for (x = 0; x < pTexture->width; x++) { tx = min(x, (u32)clampSClamp); if (glInternalFormat == internalcolorFormat::RGBA8) @@ -856,8 +781,8 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) if (m_toggleDumpTex && config.textureFilter.txHiresEnable != 0 && config.textureFilter.txDump != 0) { - txfilter_dmptx((u8*)pDest, pTexture->realWidth, pTexture->realHeight, - pTexture->realWidth, (u16)u32(glInternalFormat), + txfilter_dmptx((u8*)pDest, pTexture->width, pTexture->height, + pTexture->width, (u16)u32(glInternalFormat), (unsigned short)(pTexture->format << 8 | pTexture->size), ricecrc); } @@ -867,7 +792,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) config.textureFilter.txFilterIgnoreBG == 0 && TFH.isInited()) { GHQTexInfo ghqTexInfo; - if (txfilter_filter((u8*)pDest, pTexture->realWidth, pTexture->realHeight, + if (txfilter_filter((u8*)pDest, pTexture->width, pTexture->height, (u16)u32(glInternalFormat), (uint64)pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) { @@ -888,19 +813,19 @@ void TextureCache::_loadBackground(CachedTexture *pTexture) params.dataType = DatatypeParam(ghqTexInfo.pixel_type); params.data = ghqTexInfo.data; gfxContext.init2DTexture(params); - _updateCachedTexture(ghqTexInfo, pTexture, f32(ghqTexInfo.width) / f32(pTexture->realWidth)); + _updateCachedTexture(ghqTexInfo, pTexture, pTexture->width, pTexture->height); bLoaded = true; } } if (!bLoaded) { - if (pTexture->realWidth % 2 != 0 && glInternalFormat != internalcolorFormat::RGBA8) + if (pTexture->width % 2 != 0 && glInternalFormat != internalcolorFormat::RGBA8) gfxContext.setTextureUnpackAlignment(2); Context::InitTextureParams params; params.handle = pTexture->name; params.mipMapLevel = 0; params.msaaLevel = 0; - params.width = pTexture->realWidth; - params.height = pTexture->realHeight; + params.width = pTexture->width; + params.height = pTexture->height; params.format = colorFormat::RGBA; params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat)); params.dataType = glType; @@ -995,7 +920,7 @@ bool TextureCache::_loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 & params.textureUnitIndex = textureIndices::Tex[_tile]; gfxContext.init2DTexture(params); assert(!gfxContext.isError()); - _updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(width)); + _updateCachedTexture(ghqTexInfo, _pTexture, width, height); return true; } @@ -1007,7 +932,7 @@ void TextureCache::_loadDepthTexture(CachedTexture * _pTexture, u16* _pDest) if (!config.generalEmulation.enableFragmentDepthWrite) return; - u32 size = _pTexture->realWidth * _pTexture->realHeight; + u32 size = _pTexture->width * _pTexture->height; std::vector pDestFloat(size); for (u32 i = 0; i < size; ++i) pDestFloat[i] = _pDest[i] / 65535.0f; @@ -1016,8 +941,8 @@ void TextureCache::_loadDepthTexture(CachedTexture * _pTexture, u16* _pDest) params.handle = _pTexture->name; params.mipMapLevel = 0; params.msaaLevel = 0; - params.width = _pTexture->realWidth; - params.height = _pTexture->realHeight; + params.width = _pTexture->width; + params.height = _pTexture->height; params.internalFormat = internalcolorFormat::R16F; params.format = colorFormat::RED; params.dataType = datatype::FLOAT; @@ -1034,29 +959,26 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex, GetTexelFunc GetTexel, u16* pLine) { - u16 mirrorSBit, maskSMask, clampSClamp; - u16 mirrorTBit, maskTMask, clampTClamp; + u16 maskSMask, clampSClamp; + u16 maskTMask, clampTClamp; u16 x, y, tx, ty; u32 i, j; u64 *pSrc; + if (tmptex.maskS > 0) { clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1); maskSMask = (1 << tmptex.maskS) - 1; - mirrorSBit = tmptex.mirrorS != 0 ? 1 << tmptex.maskS : 0; } else { clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : tmptex.width - 1; maskSMask = 0xFFFF; - mirrorSBit = 0x0000; } if (tmptex.maskT > 0) { clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : (tmptex.mirrorT ? (tmptex.height << 1) - 1 : tmptex.height - 1); maskTMask = (1 << tmptex.maskT) - 1; - mirrorTBit = tmptex.mirrorT != 0 ? 1 << tmptex.maskT : 0; } else { clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : tmptex.height - 1; maskTMask = 0xFFFF; - mirrorTBit = 0x0000; } if (tmptex.size == G_IM_SIZ_32b) { @@ -1080,20 +1002,14 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex, u16 gr, ab; j = 0; - for (y = 0; y < tmptex.realHeight; ++y) { + for (y = 0; y < tmptex.height; ++y) { ty = min(y, clampTClamp) & maskTMask; - if (y & mirrorTBit) { - ty ^= maskTMask; - } u32 tline = tbase + line32 * ty; u32 xorval = (ty & 1) ? 3 : 1; - for (x = 0; x < tmptex.realWidth; ++x) { + for (x = 0; x < tmptex.width; ++x) { tx = min(x, clampSClamp) & maskSMask; - if (x & mirrorSBit) { - tx ^= maskSMask; - } u32 taddr = ((tline + tx) ^ xorval) & 0x3ff; gr = swapword(tmem16[taddr]); @@ -1104,9 +1020,9 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex, } else if (tmptex.format == G_IM_FMT_YUV) { j = 0; *pLine <<= 1; - for (y = 0; y < tmptex.realHeight; ++y) { + for (y = 0; y < tmptex.height; ++y) { pSrc = &TMEM[tmptex.tMem] + *pLine * y; - for (x = 0; x < tmptex.realWidth / 2; x++) { + for (x = 0; x < tmptex.width / 2; x++) { GetYUV_RGBA8888(pSrc, pDest + j, x); j += 2; } @@ -1114,22 +1030,15 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex, } else { j = 0; const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF; - for (y = 0; y < tmptex.realHeight; ++y) { + for (y = 0; y < tmptex.height; ++y) { ty = min(y, clampTClamp) & maskTMask; - if (y & mirrorTBit) - ty ^= maskTMask; - pSrc = &TMEM[(tmptex.tMem + *pLine * ty) & tMemMask]; i = (ty & 1) << 1; - for (x = 0; x < tmptex.realWidth; ++x) { + for (x = 0; x < tmptex.width; ++x) { tx = min(x, clampSClamp) & maskSMask; - if (x & mirrorSBit) { - tx ^= maskSMask; - } - if (glInternalFormat == internalcolorFormat::RGBA8) { pDest[j++] = GetTexel(pSrc, tx, i, tmptex.palette); } else { @@ -1158,13 +1067,13 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format]; if (loadParams.autoFormat == internalcolorFormat::RGBA8) { sizeShift = 2; - _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; + _pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift; GetTexel = loadParams.Get32; glInternalFormat = loadParams.glInternalFormat32; glType = loadParams.glType32; } else { sizeShift = 1; - _pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; + _pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift; GetTexel = loadParams.Get16; glInternalFormat = loadParams.glInternalFormat16; glType = loadParams.glType16; @@ -1205,8 +1114,8 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) if (m_toggleDumpTex && config.textureFilter.txHiresEnable != 0 && config.textureFilter.txDump != 0) { - txfilter_dmptx((u8*)pDest, tmptex.realWidth, tmptex.realHeight, - tmptex.realWidth, (u16)u32(glInternalFormat), + txfilter_dmptx((u8*)pDest, tmptex.width, tmptex.height, + tmptex.width, (u16)u32(glInternalFormat), (unsigned short)(_pTexture->format << 8 | _pTexture->size), ricecrc); } @@ -1232,7 +1141,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) if (needEnhance) { GHQTexInfo ghqTexInfo; - if (txfilter_filter((u8*)pDest, tmptex.realWidth, tmptex.realHeight, + if (txfilter_filter((u8*)pDest, tmptex.width, tmptex.height, (u16)u32(glInternalFormat), (uint64)_pTexture->crc, &ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) { if (ghqTexInfo.width % 2 != 0 && @@ -1252,12 +1161,12 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) params.dataType = DatatypeParam(ghqTexInfo.pixel_type); params.data = ghqTexInfo.data; gfxContext.init2DTexture(params); - _updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(tmptex.realWidth)); + _updateCachedTexture(ghqTexInfo, _pTexture, tmptex.width, tmptex.height); bLoaded = true; } } if (!bLoaded) { - if (tmptex.realWidth % 2 != 0 && + if (tmptex.width % 2 != 0 && glInternalFormat != internalcolorFormat::RGBA8 && m_curUnpackAlignment > 1) gfxContext.setTextureUnpackAlignment(2); @@ -1267,8 +1176,8 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) params.mipMapLevel = mipLevel; params.mipMapLevels = _pTexture->max_level + 1; params.msaaLevel = 0; - params.width = tmptex.realWidth; - params.height = tmptex.realHeight; + params.width = tmptex.width; + params.height = tmptex.height; params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat)); params.format = colorFormat::RGBA; params.dataType = glType; @@ -1287,16 +1196,14 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture) tmptex.maskT = mipTile.maskt; TileSizes sizes; _calcTileSizes(tileMipLevel, sizes, nullptr); - tmptex.width = sizes.width; tmptex.clampWidth = sizes.clampWidth; - tmptex.height = sizes.height; tmptex.clampHeight = sizes.clampHeight; // Insure mip-map levels size consistency. - if (tmptex.realWidth > 1) - tmptex.realWidth >>= 1; - if (tmptex.realHeight > 1) - tmptex.realHeight >>= 1; - _pTexture->textureBytes += (tmptex.realWidth * tmptex.realHeight) << sizeShift; + if (tmptex.width > 1) + tmptex.width >>= 1; + if (tmptex.height > 1) + tmptex.height >>= 1; + _pTexture->textureBytes += (tmptex.width * tmptex.height) << sizeShift; } if (m_curUnpackAlignment > 1) gfxContext.setTextureUnpackAlignment(m_curUnpackAlignment); @@ -1384,11 +1291,9 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture) // Set clamping modes params.wrapS = _pTexture->clampS ? textureParameters::WRAP_CLAMP_TO_EDGE : - _pTexture->mirrorS ? textureParameters::WRAP_MIRRORED_REPEAT - : textureParameters::WRAP_REPEAT; + _pTexture->mirrorS ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT; params.wrapT = _pTexture->clampT ? textureParameters::WRAP_CLAMP_TO_EDGE : - _pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT - : textureParameters::WRAP_REPEAT; + _pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT; if (dwnd().getDrawer().getDrawingState() == DrawingState::Triangle && config.texture.maxAnisotropyF > 0.0f) params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF); @@ -1479,11 +1384,8 @@ void TextureCache::_updateBackground() pCurrent->tMem = 0; pCurrent->frameBufferTexture = CachedTexture::fbNone; - pCurrent->realWidth = gSP.bgImage.width; - pCurrent->realHeight = gSP.bgImage.height; - - pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); - pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); + pCurrent->scaleS = 1.0f / (f32)(pCurrent->width); + pCurrent->scaleT = 1.0f / (f32)(pCurrent->height); pCurrent->shiftScaleS = 1.0f; pCurrent->shiftScaleT = 1.0f; @@ -1574,8 +1476,8 @@ void TextureCache::update(u32 _t) (pTile->size << 12) | (pTile->format << 14) | (gDP.otherMode.textureLUT << 17); - params.width = sizes.realWidth; - params.height = sizes.realHeight; + params.width = sizes.width; + params.height = sizes.height; const u32 crc = _calculateCRC(_t, params, sizes.bytes); @@ -1637,11 +1539,8 @@ void TextureCache::update(u32 _t) pCurrent->tMem = pTile->tmem; pCurrent->frameBufferTexture = CachedTexture::fbNone; - pCurrent->realWidth = sizes.realWidth; - pCurrent->realHeight = sizes.realHeight; - - pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth); - pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight); + pCurrent->scaleS = 1.0f / (pCurrent->maskS ? f32(pow2(pCurrent->width)) : f32(pCurrent->width)); + pCurrent->scaleT = 1.0f / (pCurrent->maskT ? f32(pow2(pCurrent->height)) : f32(pCurrent->height)); pCurrent->offsetS = 0.5f; pCurrent->offsetT = 0.5f; @@ -1673,3 +1572,22 @@ void getTextureShiftScale(u32 t, const TextureCache & cache, f32 & shiftScaleS, else if (gSP.textureTile[t]->shiftt > 0) shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt); } + +void getMirrorClamp(u32 _tile, const CachedTexture * _pTexture, MirrorClamp& aMirrorClamp) +{ + const gDPTile * pTile = gSP.textureTile[_tile]; + const u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; + const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; + const bool mirrorClampS = _pTexture->mirrorS && _pTexture->clampS && + tileWidth > _pTexture->width && tileWidth % _pTexture->width == 0; + const bool mirrorClampT = _pTexture->mirrorT && _pTexture->clampT && + tileHeight > _pTexture->height && tileHeight % _pTexture->height == 0; + if (mirrorClampS) { + aMirrorClamp[0] = 0.0f; + aMirrorClamp[2] = f32(tileWidth / _pTexture->width); + } + if (mirrorClampT) { + aMirrorClamp[1] = 0.0f; + aMirrorClamp[3] = f32(tileHeight / _pTexture->height); + } +} diff --git a/src/Textures.h b/src/Textures.h index 2738e7bb..cb6c933b 100644 --- a/src/Textures.h +++ b/src/Textures.h @@ -1,9 +1,10 @@ #ifndef TEXTURES_H #define TEXTURES_H +#include +#include #include #include -#include #include "CRC.h" #include "convert.h" @@ -31,7 +32,6 @@ struct CachedTexture u32 palette; u16 width, height; // N64 width and height u16 clampWidth, clampHeight; // Size to clamp to - u16 realWidth, realHeight; // Actual texture size f32 scaleS, scaleT; // Scale to map to 0.0-1.0 f32 shiftScaleS, shiftScaleT; // Scale to shift u32 textureBytes; @@ -109,6 +109,9 @@ private: void getTextureShiftScale(u32 tile, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT); +using MirrorClamp = std::array; +void getMirrorClamp(u32 _tile, const CachedTexture * _pTexture, MirrorClamp& aMirrorClamp); + inline TextureCache & textureCache() { return TextureCache::get(); diff --git a/src/ZlutTexture.cpp b/src/ZlutTexture.cpp index 34689d53..2563e287 100644 --- a/src/ZlutTexture.cpp +++ b/src/ZlutTexture.cpp @@ -35,14 +35,14 @@ void ZlutTexture::init() m_pTexture->maskT = 0; m_pTexture->mirrorS = 0; m_pTexture->mirrorT = 0; - m_pTexture->realWidth = 512; - m_pTexture->realHeight = 512; - m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.lutFormatBytes; + m_pTexture->width = 512; + m_pTexture->height = 512; + m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.lutFormatBytes; Context::InitTextureParams initParams; initParams.handle = m_pTexture->name; - initParams.width = m_pTexture->realWidth; - initParams.height = m_pTexture->realHeight; + initParams.width = m_pTexture->width; + initParams.height = m_pTexture->height; initParams.internalFormat = fbTexFormats.lutInternalFormat; initParams.format = fbTexFormats.lutFormat; initParams.dataType = fbTexFormats.lutType; diff --git a/src/gDP.cpp b/src/gDP.cpp index 0aeaa2fc..f28d03bc 100644 --- a/src/gDP.cpp +++ b/src/gDP.cpp @@ -637,6 +637,15 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt) gDP.loadTile->frameBufferAddress = 0; CheckForFrameBufferTexture(address, info.width, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy + const u32 texLowerBound = gDP.loadTile->tmem; + const u32 texUpperBound = gDP.loadTile->tmem + (bytes >> 3); + for (u32 i = 0; i < tile; ++i) { + if (gDP.tiles[i].tmem >= texLowerBound && gDP.tiles[i].tmem < texUpperBound) { + gDPLoadTileInfo &info = gDP.loadInfo[gDP.tiles[i].tmem]; + info.loadType = LOADTYPE_BLOCK; + } + } + if (gDP.loadTile->size == G_IM_SIZ_32b) gDPLoadBlock32(gDP.loadTile->uls, gDP.loadTile->lrs, dxt); else if (gDP.loadTile->format == G_IM_FMT_YUV)