diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index f45ef3ce57..c5dfa71e52 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -287,8 +287,7 @@ void CPUInfo::Detect() { // -- Is the RTM bit set in CPUID? (>>11) // -- No need to check HLE bit because legacy processors ignore HLE hints // -- See https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family - if (max_std_fn >= 7) - { + if (max_std_fn >= 7) { do_cpuid(cpu_id, 0x00000007); // careful; we can't enable AVX2 unless the XSAVE/XGETBV checks above passed if ((cpu_id[1] >> 5) & 1) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 96c4428939..ca1fef60ef 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -1094,17 +1094,19 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu case STENCIL_VALUE_INCR_4BIT: case STENCIL_VALUE_DECR_4BIT: // We're adding/subtracting, just by the smallest value in 4-bit. + // We have to set the blend mode to match elsewhere. snprintf(replacedAlpha, sizeof(replacedAlpha), "%f", 1.0 / 15.0); break; case STENCIL_VALUE_INCR_8BIT: case STENCIL_VALUE_DECR_8BIT: // We're adding/subtracting, just by the smallest value in 8-bit. + // We have to set the blend mode to match elsewhere. snprintf(replacedAlpha, sizeof(replacedAlpha), "%f", 1.0 / 255.0); break; case STENCIL_VALUE_KEEP: - // Do nothing. We'll mask out the alpha using color mask. + // Do nothing. We'll mask out the alpha using color mask (could also be done with a blend mode). break; } } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 735e4d7a98..d5b2ca0c62 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -429,6 +429,9 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(Framebuffer } else if (PSP_CoreParameter().compat.flags().FramebufferAllowLargeVerticalOffset && params.fb_address > v->fb_address && v->fb_stride > 0 && (params.fb_address - v->fb_address) % v->FbStrideInBytes() == 0 && params.fb_address != 0x04088000 && v->fb_address != 0x04000000) { // Heuristic to avoid merging the main framebuffers. + + // Breath of Fire III relies on this to render the second framebuffer inside the first one. + y_offset = (params.fb_address - v->fb_address) / v->FbStrideInBytes(); if (y_offset <= v->bufferHeight) { // note: v->height is misdetected as 256 instead of 272 here in tokimeki. Note that 272 is just the height of the upper part, it's supersampling vertically. large_offset_vfb = v; @@ -1037,11 +1040,11 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb) { if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { - gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_FRAMEBUFFER_DIM | DIRTY_VIEWPORTSCISSOR_STATE); } if (gstate_c.curRTRenderWidth != vfb->renderWidth || gstate_c.curRTRenderHeight != vfb->renderHeight) { gstate_c.Dirty(DIRTY_PROJMATRIX); - gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX); + gstate_c.Dirty(DIRTY_FRAMEBUFFER_DIM); } } diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index 7a93eeafd5..79dfbf724c 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -44,7 +44,7 @@ enum DebugShaderStringType { // more code than before. TODO: Can probably cut the number of these down without too much slowdown. enum : uint64_t { DIRTY_PROJMATRIX = 1ULL << 0, - DIRTY_PROJTHROUGHMATRIX = 1ULL << 1, + DIRTY_FRAMEBUFFER_DIM = 1ULL << 1, DIRTY_FOGCOLOR = 1ULL << 2, DIRTY_FOGCOEF = 1ULL << 3, DIRTY_TEXENV = 1ULL << 4, diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index ca27ff6628..27d4bf8b1f 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -76,7 +76,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool useBuffe ub->rotation = useBufferedRendering ? 0 : (float)g_display.rotation; } - if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) { + if (dirtyUniforms & DIRTY_FRAMEBUFFER_DIM) { ub->xywh[0] = (float)gstate_c.curRTOffsetX; ub->xywh[1] = (float)gstate_c.curRTOffsetY; ub->xywh[2] = (float)gstate_c.curRTWidth; @@ -96,7 +96,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool useBuffe } if (dirtyUniforms & DIRTY_VIEWPORT_UNIFORMS) { - // TODO: This should be a couple of SIMD instructions. Vec4F32 vpScale = Vec4F32::LoadF24x4(&gstate.viewportxscale); Vec4F32 vpOffset = Vec4F32::LoadF24x4(&gstate.viewportxcenter); vpScale.Store(ub->vpScale); diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index 9a4c5fa1ef..fae84d99e3 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -10,7 +10,7 @@ enum : uint64_t { DIRTY_BASE_UNIFORMS = - DIRTY_WORLDMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF | + DIRTY_WORLDMATRIX | DIRTY_FRAMEBUFFER_DIM | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF | DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEF | DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_STENCILREPLACEVALUE | DIRTY_ALPHACOLORMASK | DIRTY_SHADERBLEND | DIRTY_COLORWRITEMASK | DIRTY_UVSCALEOFFSET | DIRTY_TEXCLAMP | DIRTY_MATAMBIENTALPHA | DIRTY_DEPAL | DIRTY_VIEWPORT_UNIFORMS | DIRTY_RASTER_OFFSET, diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index 2379f9d49c..c2c3635871 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -407,7 +407,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "uniform vec4 u_xywh;\n"); WRITE(p, "uniform float u_NaN;\n"); - *uniformMask |= DIRTY_PROJTHROUGHMATRIX; + *uniformMask |= DIRTY_FRAMEBUFFER_DIM; WRITE(p, "uniform vec2 u_minZmaxZ;\n"); *uniformMask |= DIRTY_RASTER_OFFSET; // this flag is shared with raster offset. diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index ef927e5415..ce6cd5ec6d 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -406,7 +406,7 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc memcpy(&matrix, gstate.projMatrix, 16 * sizeof(float)); render_->SetUniformM4x4(&u_proj, matrix.m); } - if (dirty & DIRTY_PROJTHROUGHMATRIX) { + if (dirty & DIRTY_FRAMEBUFFER_DIM) { float xywh[4]; xywh[0] = (float)gstate_c.curRTOffsetX; xywh[1] = (float)gstate_c.curRTOffsetY; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a6bf015949..845579a69a 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -654,7 +654,7 @@ public: if (xoff != curRTOffsetX || yoff != curRTOffsetY) { curRTOffsetX = xoff; curRTOffsetY = yoff; - Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_PROJTHROUGHMATRIX); + Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAMEBUFFER_DIM); } } int curRTOffsetX; diff --git a/GPU/Math3D.h b/GPU/Math3D.h index 7cbbe796cb..d2d7c9ee12 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -1176,6 +1176,7 @@ inline void ConvertMatrix4x3To4x4Transposed(float *m4x4, const float *m4x3) { // 4567 // 89AB // Don't see a way to SIMD that. Should be pretty fast anyway. +// And on NEON it just works! inline void ConvertMatrix4x3To3x4Transposed(float *m3x4, const float *m4x3) { #if PPSSPP_ARCH(ARM_NEON) // vld3q is a perfect match here!