Example #1
0
// 32 bit frames have additional constraints to frame
// maxpos was maximum length of frame at normal constraints
inline void VB::CheckFrame32bitRes(int maxpos)
{
    int fbh = frame.fbh;

    if (frame.fbh >= 512)
    {
        // neopets hack
        maxmin = min(maxmin, frame.fbh);
        frame.fbh = maxmin;
        ConstraintReason = 8;
    }

    // ffxii hack to stop resolving
    if (frame.fbp >= 0x3000 && fbh >= 0x1a0)
    {
        int endfbp = frame.fbp + frame.fbw * fbh / (PSMT_ISHALF(gsfb.psm) ? 128 : 64);

        // see if there is a previous render target in the way, reduce

        for (CRenderTargetMngr::MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew)
        {
            if (itnew->second->fbp > frame.fbp && endfbp > itnew->second->fbp)
            {
                endfbp = itnew->second->fbp;
            }
        }

        frame.fbh = (endfbp - frame.fbp) * (PSMT_ISHALF(gsfb.psm) ? 128 :  64) / frame.fbw;

        if (frame.fbh < fbh) ConstraintReason = 9;
    }

}
Example #2
0
inline bool CheckWidthIsSame(const frameInfo& frame, CRenderTarget* ptarg)
{
	if (PSMT_ISHALF(frame.psm) == PSMT_ISHALF(ptarg->psm))
		return (frame.fbw == ptarg->fbw);

	if (PSMT_ISHALF(frame.psm))
		return (frame.fbw == 2 * ptarg->fbw);
	else
		return (2 * frame.fbw == ptarg->fbw);
}
Example #3
0
// Check if after resizing, a new render target is needed to be used. Also perform deptarget check.
// Returns 1 if only 1 render target is changed and 3 -- if both.
inline int VB::CheckFrameResolveRender(int tbp)
{
    int result = 0;

    CRenderTarget* pprevrndr = prndr;
    prndr = NULL;
    CDepthTarget* pprevdepth = pdepth;
    pdepth = NULL;
    // Set renderes to NULL to prevent Flushing.

    CRenderTarget* pnewtarg = s_RTs.GetTarg(frame, 0, maxmin);
    assert(pnewtarg != NULL);

    // pnewtarg->fbh >= 0x1c0 needed for ffx

    if ((pnewtarg->fbh >= 0x1c0) && pnewtarg->fbh > frame.fbh && zbuf.zbp < tbp && !zbuf.zmsk)
    {
        // check if zbuf is in the way of the texture (suikoden5)
        int maxallowedfbh = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 128 : 64) / gsfb.fbw;

        if (PSMT_ISHALF(gsfb.psm)) maxallowedfbh *= 2;

        if (pnewtarg->fbh > maxallowedfbh + 32)   // +32 needed for ffx2
        {
            // destroy and recreate
            s_RTs.DestroyAllTargs(0, 0x100, pnewtarg->fbw);
            pnewtarg = s_RTs.GetTarg(frame, 0, maxmin);
            assert(pnewtarg != NULL);
        }
    }

    ZZLog::Prim_Log("frame_%d: fbp=0x%x fbw=%d fbh=%d(%d) psm=0x%x fbm=0x%x\n", ictx, gsfb.fbp, gsfb.fbw, gsfb.fbh, pnewtarg->fbh, gsfb.psm, gsfb.fbm);

    if ((pprevrndr != pnewtarg) || (pprevrndr != NULL && (pprevrndr->status & CRenderTarget::TS_NeedUpdate)))
        result = 1;

    prndr = pnewtarg;

    pdepth = pprevdepth;

    result |= CheckFrameResolveDepth(tbp);

    return result;
}
Example #4
0
// Return number of 64-pixels block, that guaranted could be hold in memory
// from gsfb.fbp and tbp (textrure pase), zbuf.zbp (Z-buffer), frame.fbp
// (previous frame).
inline int VB::FindMinimalMemoryConstrain(int tbp, int maxpos)
{
    int MinConstraint = maxpos;

    // make sure texture is far away from tbp
    {
        int Constraint = tbp - gsfb.fbp;

        if ((0 < Constraint) && (Constraint < MinConstraint))
        {
            MinConstraint = Constraint;
            ConstraintReason = 1;
        }
    }

    // offroad uses 0x80 fbp which messes up targets
    // special case when double buffering (hamsterball)
    // Suikoden 3 require e00 have this issue too. P3 - 0x1000.

    if (prndr != NULL)
    {
        int Constraint = frame.fbp - gsfb.fbp;

        if ((0x0 < Constraint) && (Constraint < MinConstraint))
        {
            MinConstraint = Constraint;
            ConstraintReason = 2;
        }
    }

    // old caching method
    // zmsk necessary for KH movie
    if (!zbuf.zmsk)
    {
        int Constraint = zbuf.zbp - gsfb.fbp;

        if ((0 < Constraint) && (Constraint < MinConstraint))
        {
            MinConstraint = Constraint;
            ConstraintReason = 3;
        }
    }

    // In 16Bit mode in one Word frame stored 2 pixels
    if (PSMT_ISHALF(gsfb.psm)) MinConstraint *= 2;

    return MinConstraint ;
}
Example #5
0
// This is the main code for frame resizing.
// It checks for several reasons to resize and resizes if it needs to.
// 4Mb memory in 64 bit (4 bytes) words.
// |------------------------|---------------------|----------|----------|---------------------|
// 0                     gsfb.fbp               zbuff.zpb   tbp    frame.fbp              2^20/64
inline int VB::CheckFrameAddConstraints(int tbp)
{
    if (gsfb.fbw <= 0)
    {
        ERROR_LOG_SPAM("render target null, no constraints. Ignoring\n");
        return -1;
    }

    // Memory region after fbp
    int maxmemorypos = 0x4000 - gsfb.fbp;

    ConstraintReason = 0;

    maxmemorypos = FindMinimalMemoryConstrain(tbp, maxmemorypos);
    maxmemorypos = FindZbufferMemoryConstrain(tbp, maxmemorypos);

    int maxpos = 64 * maxmemorypos ;

    maxpos /= gsfb.fbw;

    //? atelier iris crashes without it
    if (maxpos > 256) maxpos &= ~0x1f;

#ifdef DEVBUILD
    int noscissorpos = maxpos;
    int ConstrainR1 = ConstraintReason;
#endif

    maxpos = FindMinimalHeightConstrain(maxpos);

    frame = gsfb;
    frame.fbh = maxpos;

    if (!PSMT_ISHALF(frame.psm) || !(conf.settings().full_16_bit_res)) CheckFrame32bitRes(maxpos);

#ifdef DEVBUILD
    if (frame.fbh == 0xe2)
        ZZLog::Debug_Log("Const: %x %x %d| %x %d %x %x", frame.fbh, frame.fbw, ConstraintReason, noscissorpos, ConstrainR1, tbp, frame.fbp);
#endif

// 	Fixme: Reserved psm for framebuffers
//	gsfb.psm &= 0xf; // shadow tower

    return 0;
}
Example #6
0
// Return number of 64 pizel words that could be placed in Z-Buffer
// If no Z-buffer present return old constraint
inline int VB::FindZbufferMemoryConstrain(int tbp, int maxpos)
{
    int MinConstraint = maxpos;

    // Check tbp / zbuffer constraint
    if (!zbuf.zmsk)
    {
        int Constraint = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 2 : 1);

        if ((0 < Constraint) && (Constraint < MinConstraint))
        {
            MinConstraint = Constraint;
            ConstraintReason = 4;
        }
    }

    return MinConstraint;
}
void CRenderTarget::SetTarget(int fbplocal, const Rect2& scissor, int context)
{
	FUNCLOG
	int dy = 0;

	if (fbplocal != fbp)
	{
		float4 v;

		// will be rendering to a subregion
		u32 bpp = PSMT_ISHALF(psm) ? 2 : 4;
		assert(((256 / bpp)*(fbplocal - fbp)) % fbw == 0);
		assert(fbplocal >= fbp);

		dy = ((256 / bpp) * (fbplocal - fbp)) / fbw;

		v.x = vposxy.x;
		v.y = vposxy.y;
		v.z = vposxy.z;
		v.w = vposxy.w - dy * 2.0f / (float)fbh;
		ZZshSetParameter4fv(g_vparamPosXY[context], v, "g_fPosXY");
	}
	else
	{
		ZZshSetParameter4fv(g_vparamPosXY[context], vposxy, "g_fPosXY");
	}

	// set render states
	// Bleh. I *really* need to fix this. << 3 when setting the scissors, then >> 3 when using them... --Arcum42
	scissorrect.x = scissor.x0 >> 3;
	scissorrect.y = (scissor.y0 >> 3) + dy;
	scissorrect.w = (scissor.x1 >> 3) + 1;
	scissorrect.h = (scissor.y1 >> 3) + 1 + dy;

	scissorrect.w = min(scissorrect.w, fbw) - scissorrect.x;
	scissorrect.h = min(scissorrect.h, fbh) - scissorrect.y;

	scissorrect.x = RW(scissorrect.x);
	scissorrect.y = RH(scissorrect.y);
	scissorrect.w = RW(scissorrect.w);
	scissorrect.h = RH(scissorrect.h);
}