mirror of
https://github.com/libretro/ppsspp.git
synced 2024-12-05 15:37:51 +00:00
Merge pull request #7196 from unknownbrackets/gpu-minor
dx9: Compensate for viewport w/h adjustments
This commit is contained in:
commit
4b053efe8a
@ -853,7 +853,7 @@ namespace DX9 {
|
||||
// We maintain a separate vector of framebuffer objects for blitting.
|
||||
for (size_t i = 0; i < bvfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *v = bvfbs_[i];
|
||||
if (MaskedEqual(v->fb_address, vfb->fb_address) && v->format == vfb->format) {
|
||||
if (v->fb_address == vfb->fb_address && v->format == vfb->format) {
|
||||
if (v->bufferWidth == vfb->bufferWidth && v->bufferHeight == vfb->bufferHeight) {
|
||||
nvfb = v;
|
||||
v->fb_stride = vfb->fb_stride;
|
||||
@ -874,8 +874,8 @@ namespace DX9 {
|
||||
nvfb->z_stride = vfb->z_stride;
|
||||
nvfb->width = vfb->width;
|
||||
nvfb->height = vfb->height;
|
||||
nvfb->renderWidth = vfb->width;
|
||||
nvfb->renderHeight = vfb->height;
|
||||
nvfb->renderWidth = vfb->bufferWidth;
|
||||
nvfb->renderHeight = vfb->bufferHeight;
|
||||
nvfb->bufferWidth = vfb->bufferWidth;
|
||||
nvfb->bufferHeight = vfb->bufferHeight;
|
||||
nvfb->format = vfb->format;
|
||||
|
@ -222,13 +222,27 @@ void ShaderManagerDX9::VSSetMatrix(int creg, const float* pMatrix) {
|
||||
}
|
||||
|
||||
// Depth in ogl is between -1;1 we need between 0;1 and optionally reverse it
|
||||
static void ConvertProjMatrixToD3D(Matrix4x4 & in, bool invertedX, bool invertedY, bool invertedZ) {
|
||||
static void ConvertProjMatrixToD3D(Matrix4x4 &in, bool invertedX, bool invertedY, bool invertedZ) {
|
||||
Matrix4x4 s;
|
||||
Matrix4x4 t;
|
||||
s.setScaling(Vec3(1, 1, invertedZ ? -0.5 : 0.5f));
|
||||
|
||||
s.setScaling(Vec3(gstate_c.vpWidthScale, gstate_c.vpHeightScale, invertedZ ? -0.5 : 0.5f));
|
||||
float xoff = 0.5f / gstate_c.curRTRenderWidth;
|
||||
xoff = gstate_c.vpXOffset + (invertedX ? xoff : -xoff);
|
||||
float yoff = 0.5f / gstate_c.curRTRenderHeight;
|
||||
t.setTranslation(Vec3(invertedX ? xoff : -xoff, invertedY ? -yoff : yoff, 0.5f));
|
||||
yoff = gstate_c.vpYOffset + (invertedY ? yoff : -yoff);
|
||||
t.setTranslation(Vec3(xoff, yoff, 0.5f));
|
||||
in = in * s * t;
|
||||
}
|
||||
|
||||
static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) {
|
||||
Matrix4x4 s;
|
||||
Matrix4x4 t;
|
||||
|
||||
s.setScaling(Vec3(1.0f, 1.0f, 0.5f));
|
||||
float xoff = -0.5f / gstate_c.curRTRenderWidth;
|
||||
float yoff = -0.5f / gstate_c.curRTRenderHeight;
|
||||
t.setTranslation(Vec3(xoff, yoff, 0.5f));
|
||||
in = in * s * t;
|
||||
}
|
||||
|
||||
@ -310,7 +324,7 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
|
||||
Matrix4x4 proj_through;
|
||||
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
|
||||
|
||||
ConvertProjMatrixToD3D(proj_through, false, false, false);
|
||||
ConvertProjMatrixToD3DThrough(proj_through);
|
||||
|
||||
VSSetMatrix(CONST_VS_PROJ_THROUGH, proj_through.getReadPtr());
|
||||
}
|
||||
|
@ -713,7 +713,6 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
||||
(regionY2 - regionY1) * renderHeightFactor,
|
||||
0.f, 1.f);
|
||||
} else {
|
||||
// These we can turn into a glViewport call, offset by offsetX and offsetY. Math after.
|
||||
float vpXScale = getFloat24(gstate.viewportx1);
|
||||
float vpXCenter = getFloat24(gstate.viewportx2);
|
||||
float vpYScale = getFloat24(gstate.viewporty1);
|
||||
@ -737,8 +736,6 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
||||
vpY0 *= renderHeightFactor;
|
||||
vpWidth *= renderWidthFactor;
|
||||
vpHeight *= renderHeightFactor;
|
||||
|
||||
// shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
|
||||
|
||||
float zScale = getFloat24(gstate.viewportz1) / 65535.0f;
|
||||
float zOff = getFloat24(gstate.viewportz2) / 65535.0f;
|
||||
@ -748,15 +745,59 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
||||
|
||||
gstate_c.vpDepth = zScale * 2;
|
||||
|
||||
// D3D doesn't like viewports partially outside the target. Clamp the viewport for now. Should also adjust
|
||||
// the projection matrix to compensate, really.
|
||||
float left = std::max(0.0f, vpX0 + renderX);
|
||||
float top = std::max(0.0f, vpY0 + renderY);
|
||||
float right = std::min(left + vpWidth, renderWidth);
|
||||
float bottom = std::min(top + vpHeight, renderHeight);
|
||||
// D3D doesn't like viewports partially outside the target, so we
|
||||
// apply the viewport partially in the shader.
|
||||
float left = renderX + vpX0;
|
||||
float top = renderY + vpY0;
|
||||
float right = left + vpWidth;
|
||||
float bottom = top + vpHeight;
|
||||
|
||||
float wScale = 1.0f;
|
||||
float xOffset = 0.0f;
|
||||
float hScale = 1.0f;
|
||||
float yOffset = 0.0f;
|
||||
|
||||
// If we're within the bounds, we want clipping the viewport way. So leave it be.
|
||||
if (left < 0.0f || right > renderWidth) {
|
||||
float overageLeft = std::max(-left, 0.0f);
|
||||
float overageRight = std::max(right - renderWidth, 0.0f);
|
||||
// Our center drifted by the difference in overages.
|
||||
float drift = overageRight - overageLeft;
|
||||
|
||||
left += overageLeft;
|
||||
right -= overageRight;
|
||||
|
||||
wScale = vpWidth / (right - left);
|
||||
xOffset = drift / (right - left);
|
||||
}
|
||||
|
||||
if (top < 0.0f || bottom > renderHeight) {
|
||||
float overageTop = std::max(-top, 0.0f);
|
||||
float overageBottom = std::max(bottom - renderHeight, 0.0f);
|
||||
// Our center drifted by the difference in overages.
|
||||
float drift = overageBottom - overageTop;
|
||||
|
||||
top += overageTop;
|
||||
bottom -= overageBottom;
|
||||
|
||||
hScale = vpHeight / (bottom - top);
|
||||
yOffset = -drift / (bottom - top);
|
||||
}
|
||||
|
||||
depthRangeMin = std::max(0.0f, depthRangeMin);
|
||||
depthRangeMax = std::min(1.0f, depthRangeMax);
|
||||
|
||||
bool scaleChanged = gstate_c.vpWidthScale != wScale || gstate_c.vpHeightScale != hScale;
|
||||
bool offsetChanged = gstate_c.vpXOffset != xOffset || gstate_c.vpYOffset != yOffset;
|
||||
if (scaleChanged || offsetChanged)
|
||||
{
|
||||
gstate_c.vpWidthScale = wScale;
|
||||
gstate_c.vpHeightScale = hScale;
|
||||
gstate_c.vpXOffset = xOffset;
|
||||
gstate_c.vpYOffset = yOffset;
|
||||
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
dxstate.viewport.set(left, top, right - left, bottom - top, depthRangeMin, depthRangeMax);
|
||||
}
|
||||
}
|
||||
|
@ -1652,7 +1652,7 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, int maxL
|
||||
entry.SetAlphaStatus(TexCacheEntry::STATUS_ALPHA_UNKNOWN);
|
||||
}
|
||||
|
||||
if (level == 0 && !replaceImages) {
|
||||
if (level == 0 && (!replaceImages || entry.texture == nullptr)) {
|
||||
// Create texture
|
||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||
int usage = 0;
|
||||
|
@ -476,6 +476,11 @@ struct GPUStateCache
|
||||
float vpWidth;
|
||||
float vpHeight;
|
||||
float vpDepth;
|
||||
// Only used by Direct3D, not saved.
|
||||
float vpXOffset;
|
||||
float vpYOffset;
|
||||
float vpWidthScale;
|
||||
float vpHeightScale;
|
||||
|
||||
u32 curRTWidth;
|
||||
u32 curRTHeight;
|
||||
|
Loading…
Reference in New Issue
Block a user