mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
GPU: Set projection matrix per backend.
There's a bit of variance, so this keeps the central code clean.
This commit is contained in:
parent
f35c7d04bd
commit
159eab5141
@ -151,6 +151,25 @@ static int ColorIndexOffset(int prim, GEShadeMode shadeMode, bool clearMode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SoftwareTransform::SetProjMatrix(float mtx[14], bool invertedX, bool invertedY, const Lin::Vec3 &trans, const Lin::Vec3 &scale) {
|
||||
memcpy(&projMatrix_.m, mtx, 16 * sizeof(float));
|
||||
|
||||
if (invertedY) {
|
||||
projMatrix_.xy = -projMatrix_.xy;
|
||||
projMatrix_.yy = -projMatrix_.yy;
|
||||
projMatrix_.zy = -projMatrix_.zy;
|
||||
projMatrix_.wy = -projMatrix_.wy;
|
||||
}
|
||||
if (invertedX) {
|
||||
projMatrix_.xx = -projMatrix_.xx;
|
||||
projMatrix_.yx = -projMatrix_.yx;
|
||||
projMatrix_.zx = -projMatrix_.zx;
|
||||
projMatrix_.wx = -projMatrix_.wx;
|
||||
}
|
||||
|
||||
projMatrix_.translateAndScale(trans, scale);
|
||||
}
|
||||
|
||||
void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result) {
|
||||
u8 *decoded = params_.decoded;
|
||||
TransformedVertex *transformed = params_.transformed;
|
||||
@ -560,30 +579,6 @@ void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertTy
|
||||
numTrans = vertexCount;
|
||||
result->drawIndexed = true;
|
||||
} else {
|
||||
// Pretty bad hackery where we re-do the transform (in RotateUV) to see if the vertices are flipped in screen space.
|
||||
// Since we've already got API-specific assumptions (Y direction, etc) baked into the projMatrix (which we arguably shouldn't),
|
||||
// this gets nasty and very hard to understand.
|
||||
|
||||
float flippedMatrix[16];
|
||||
if (!throughmode) {
|
||||
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
|
||||
|
||||
const bool invertedY = params_.flippedY ? (gstate_c.vpHeight < 0) : (gstate_c.vpHeight > 0);
|
||||
if (invertedY) {
|
||||
flippedMatrix[1] = -flippedMatrix[1];
|
||||
flippedMatrix[5] = -flippedMatrix[5];
|
||||
flippedMatrix[9] = -flippedMatrix[9];
|
||||
flippedMatrix[13] = -flippedMatrix[13];
|
||||
}
|
||||
const bool invertedX = gstate_c.vpWidth < 0;
|
||||
if (invertedX) {
|
||||
flippedMatrix[0] = -flippedMatrix[0];
|
||||
flippedMatrix[4] = -flippedMatrix[4];
|
||||
flippedMatrix[8] = -flippedMatrix[8];
|
||||
flippedMatrix[12] = -flippedMatrix[12];
|
||||
}
|
||||
}
|
||||
|
||||
//rectangles always need 2 vertices, disregard the last one if there's an odd number
|
||||
vertexCount = vertexCount & ~1;
|
||||
numTrans = 0;
|
||||
@ -625,9 +620,9 @@ void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertTy
|
||||
RotateUVThrough(trans);
|
||||
} else {
|
||||
Vec4f tl;
|
||||
Vec3ByMatrix44(tl.AsArray(), transVtxTL.pos, flippedMatrix);
|
||||
Vec3ByMatrix44(tl.AsArray(), transVtxTL.pos, projMatrix_.m);
|
||||
Vec4f br;
|
||||
Vec3ByMatrix44(br.AsArray(), transVtxBR.pos, flippedMatrix);
|
||||
Vec3ByMatrix44(br.AsArray(), transVtxBR.pos, projMatrix_.m);
|
||||
|
||||
// If both transformed verts are outside Z, cull this rectangle entirely.
|
||||
constexpr float outsideValue = 1.000030517578125f;
|
||||
|
@ -18,8 +18,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "VertexDecoderCommon.h"
|
||||
#include "Common/Math/lin/matrix4x4.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
|
||||
class FramebufferManagerCommon;
|
||||
class TextureCacheCommon;
|
||||
@ -64,10 +64,12 @@ public:
|
||||
SoftwareTransform(SoftwareTransformParams ¶ms) : params_(params) {
|
||||
}
|
||||
|
||||
void SetProjMatrix(float mtx[14], bool invertedX, bool invertedY, const Lin::Vec3 &trans, const Lin::Vec3 &scale);
|
||||
void Decode(int prim, u32 vertexType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result);
|
||||
void DetectOffsetTexture(int maxIndex);
|
||||
void BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *&inds, int &maxIndex, SoftwareTransformResult *result);
|
||||
|
||||
protected:
|
||||
const SoftwareTransformParams ¶ms_;
|
||||
Lin::Matrix4x4 projMatrix_;
|
||||
};
|
||||
|
@ -599,6 +599,11 @@ rotateVBO:
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform swTransform(params);
|
||||
|
||||
const Lin::Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f);
|
||||
const Lin::Vec3 scale(gstate_c.vpWidthScale, -gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
|
||||
swTransform.SetProjMatrix(gstate.projMatrix, gstate_c.vpWidth < 0, gstate_c.vpHeight < 0, trans, scale);
|
||||
|
||||
swTransform.Decode(prim, dec_->VertexType(), dec_->GetDecVtxFmt(), maxIndex, &result);
|
||||
if (result.action == SW_NOT_READY) {
|
||||
swTransform.DetectOffsetTexture(maxIndex);
|
||||
|
@ -568,6 +568,17 @@ rotateVBO:
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform swTransform(params);
|
||||
|
||||
// Half pixel offset hack.
|
||||
float xScale = gstate_c.vpWidth < 0 ? -1.0f : 1.0f;
|
||||
float xOffset = -1.0f / gstate_c.curRTRenderWidth;
|
||||
float yScale = gstate_c.vpHeight > 0 ? -1.0f : 1.0f;
|
||||
float yOffset = 1.0f / gstate_c.curRTRenderHeight;
|
||||
|
||||
const Lin::Vec3 trans(gstate_c.vpXOffset * xScale + xOffset, gstate_c.vpYOffset * yScale + yOffset, gstate_c.vpZOffset * 0.5f + 0.5f);
|
||||
const Lin::Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
|
||||
swTransform.SetProjMatrix(gstate.projMatrix, gstate_c.vpWidth < 0, gstate_c.vpHeight > 0, trans, scale);
|
||||
|
||||
swTransform.Decode(prim, dec_->VertexType(), dec_->GetDecVtxFmt(), maxIndex, &result);
|
||||
if (result.action == SW_NOT_READY) {
|
||||
swTransform.DetectOffsetTexture(maxIndex);
|
||||
|
@ -563,7 +563,7 @@ void DrawEngineGLES::DoFlush() {
|
||||
params.allowClear = true;
|
||||
params.allowSeparateAlphaClear = true;
|
||||
params.provokeFlatFirst = false;
|
||||
params.flippedY = !framebufferManager_->UseBufferedRendering();
|
||||
params.flippedY = framebufferManager_->UseBufferedRendering();
|
||||
|
||||
// We need correct viewport values in gstate_c already.
|
||||
if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {
|
||||
@ -583,6 +583,12 @@ void DrawEngineGLES::DoFlush() {
|
||||
#endif
|
||||
|
||||
SoftwareTransform swTransform(params);
|
||||
|
||||
const Lin::Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset);
|
||||
const Lin::Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale * (params.flippedY ? 1.0 : -1.0f), gstate_c.vpDepthScale);
|
||||
const bool invertedY = gstate_c.vpHeight * (params.flippedY ? 1.0 : -1.0f) < 0;
|
||||
swTransform.SetProjMatrix(gstate.projMatrix, gstate_c.vpWidth < 0, invertedY, trans, scale);
|
||||
|
||||
swTransform.Decode(prim, dec_->VertexType(), dec_->GetDecVtxFmt(), maxIndex, &result);
|
||||
if (result.action == SW_NOT_READY)
|
||||
swTransform.DetectOffsetTexture(maxIndex);
|
||||
|
@ -909,7 +909,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
params.allowClear = framebufferManager_->UseBufferedRendering();
|
||||
params.allowSeparateAlphaClear = false;
|
||||
params.provokeFlatFirst = true;
|
||||
params.flippedY = false;
|
||||
params.flippedY = true;
|
||||
|
||||
// We need to update the viewport early because it's checked for flipping in SoftwareTransform.
|
||||
// We don't have a "DrawStateEarly" in vulkan, so...
|
||||
@ -924,6 +924,11 @@ void DrawEngineVulkan::DoFlush() {
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
SoftwareTransform swTransform(params);
|
||||
|
||||
const Lin::Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f);
|
||||
const Lin::Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
|
||||
swTransform.SetProjMatrix(gstate.projMatrix, gstate_c.vpWidth < 0, gstate_c.vpHeight < 0, trans, scale);
|
||||
|
||||
swTransform.Decode(prim, dec_->VertexType(), dec_->GetDecVtxFmt(), maxIndex, &result);
|
||||
if (result.action == SW_NOT_READY) {
|
||||
swTransform.DetectOffsetTexture(maxIndex);
|
||||
|
Loading…
Reference in New Issue
Block a user