mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Split out screen rotation from the projection matrix
This commit is contained in:
1 parent
9afe66219a
commit
065a68ef4f
6 files changed
+24
-28
No files matched your search
@@ -128,11 +128,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
|
||||
|
||||
FlipProjMatrix(flippedMatrix);
|
||||
|
||||
ConvertProjMatrixToZeroToOneDepth(flippedMatrix);
|
||||
if (!useBufferedRendering && g_display.rotation != DisplayRotation::ROTATE_0) {
|
||||
flippedMatrix = flippedMatrix * g_display.rot_matrix;
|
||||
}
|
||||
CopyMatrix4x4(ub->proj, flippedMatrix.getReadPtr());
|
||||
|
||||
ub->rotation = useBufferedRendering ? 0 : (float)g_display.rotation;
|
||||
@@ -141,9 +137,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) {
|
||||
Matrix4x4 proj_through;
|
||||
proj_through.setOrthoVulkan(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
|
||||
if (!useBufferedRendering && g_display.rotation != DisplayRotation::ROTATE_0) {
|
||||
proj_through = proj_through * g_display.rot_matrix;
|
||||
}
|
||||
|
||||
// Negative RT offsets come from split framebuffers (Killzone)
|
||||
if (gstate_c.curRTOffsetX < 0 || gstate_c.curRTOffsetY < 0) {
|
||||
@@ -152,6 +145,8 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
}
|
||||
|
||||
CopyMatrix4x4(ub->proj_through, proj_through.getReadPtr());
|
||||
|
||||
ub->rotation = useBufferedRendering ? 0 : (float)g_display.rotation;
|
||||
}
|
||||
|
||||
// Transform
|
||||
|
||||
@@ -17,7 +17,7 @@ enum : uint64_t {
|
||||
DIRTY_MATDIFFUSE | DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE | DIRTY_AMBIENT,
|
||||
};
|
||||
|
||||
// Currently 496 bytes.
|
||||
// Currently 480 bytes.
|
||||
// Every line here is a 4-float.
|
||||
struct alignas(16) UB_VS_FS_Base {
|
||||
float proj[16];
|
||||
@@ -43,6 +43,7 @@ struct alignas(16) UB_VS_FS_Base {
|
||||
// VR stuff is to go here, later. For normal drawing, we can then get away
|
||||
// with just uploading the first 448 bytes of the struct (up to and including fogCoef).
|
||||
};
|
||||
static_assert(sizeof(UB_VS_FS_Base) == 480, "UB_VS_FS_Base should be 496 bytes");
|
||||
|
||||
static const char * const ub_baseStr =
|
||||
R"( mat4 u_proj;
|
||||
@@ -84,6 +85,7 @@ struct alignas(16) UB_VS_Lights {
|
||||
float lightDiffuse[4][4];
|
||||
float lightSpecular[4][4];
|
||||
};
|
||||
static_assert(sizeof(UB_VS_Lights) == 512); // it's ok to optimize this, it's just an assumption check.
|
||||
|
||||
static const char * const ub_vs_lightsStr =
|
||||
R"( vec4 u_ambient;
|
||||
@@ -105,6 +107,7 @@ R"( vec4 u_ambient;
|
||||
struct alignas(16) UB_VS_Bones {
|
||||
float bones[8][12];
|
||||
};
|
||||
static_assert(sizeof(UB_VS_Bones) == 384); // No way to optimize this further.
|
||||
|
||||
static const char * const ub_vs_bonesStr =
|
||||
R"( mat3x4 u_bone0; mat3x4 u_bone1; mat3x4 u_bone2; mat3x4 u_bone3; mat3x4 u_bone4; mat3x4 u_bone5; mat3x4 u_bone6; mat3x4 u_bone7; mat3x4 u_bone8;
|
||||
|
||||
@@ -363,6 +363,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
}
|
||||
WRITE(p, "};\n");
|
||||
} else {
|
||||
// Non-Vulkan GLSL.
|
||||
if (enableBones) {
|
||||
const char * const * boneWeightDecl = boneWeightAttrDecl;
|
||||
if (!strcmp(compat.attribute, "in")) {
|
||||
@@ -479,8 +480,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
WRITE(p, "uniform lowp vec3 u_matemissive;\n");
|
||||
*uniformMask |= DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE;
|
||||
}
|
||||
} else {
|
||||
WRITE(p, "uniform lowp float u_rotation;\n");
|
||||
}
|
||||
|
||||
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
|
||||
@@ -749,24 +748,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
// The proj_through matrix already has the rotation, if needed.
|
||||
WRITE(p, " vec4 outPos = mul(u_proj_through, vec4(position.xyz, 1.0));\n");
|
||||
} else {
|
||||
if (compat.shaderLanguage == GLSL_VULKAN) {
|
||||
// Apply rotation from the uniform.
|
||||
WRITE(p, " mat2 displayRotation = mat2(\n");
|
||||
WRITE(p, " u_rotation == 0.0 ? 1.0 : (u_rotation == 2.0 ? -1.0 : 0.0), u_rotation == 1.0 ? 1.0 : (u_rotation == 3.0 ? -1.0 : 0.0),\n");
|
||||
WRITE(p, " u_rotation == 3.0 ? 1.0 : (u_rotation == 1.0 ? -1.0 : 0.0), u_rotation == 0.0 ? 1.0 : (u_rotation == 2.0 ? -1.0 : 0.0)\n");
|
||||
WRITE(p, " );\n");
|
||||
|
||||
WRITE(p, " vec4 pos = position;\n");
|
||||
WRITE(p, " pos.xy = mul(displayRotation, pos.xy);\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 pos = position;\n");
|
||||
}
|
||||
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Use(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(pos);\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(position);\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = pos;\n");
|
||||
WRITE(p, " vec4 outPos = position;\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1276,6 +1262,16 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
}
|
||||
}
|
||||
|
||||
if (compat.shaderLanguage == GLSL_VULKAN) {
|
||||
// Apply rotation from the uniform.
|
||||
WRITE(p, " mat2 displayRotation = mat2(\n");
|
||||
WRITE(p, " u_rotation == 0.0 ? 1.0 : (u_rotation == 2.0 ? -1.0 : 0.0), u_rotation == 1.0 ? 1.0 : (u_rotation == 3.0 ? -1.0 : 0.0),\n");
|
||||
WRITE(p, " u_rotation == 3.0 ? 1.0 : (u_rotation == 1.0 ? -1.0 : 0.0), u_rotation == 0.0 ? 1.0 : (u_rotation == 2.0 ? -1.0 : 0.0)\n");
|
||||
WRITE(p, " );\n");
|
||||
|
||||
WRITE(p, " outPos.xy = mul(displayRotation, outPos.xy);\n");
|
||||
}
|
||||
|
||||
bool flipY = strlen(compat.viewportYSign) > 0;
|
||||
if (gstate_c.Use(GPU_USE_NONBUFFERED_FLIP)) {
|
||||
flipY = !flipY;
|
||||
|
||||
@@ -129,7 +129,6 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs,
|
||||
queries.push_back({ &u_depthRange, "u_depthRange" });
|
||||
queries.push_back({ &u_cullRangeMin, "u_cullRangeMin" });
|
||||
queries.push_back({ &u_cullRangeMax, "u_cullRangeMax" });
|
||||
queries.push_back({ &u_rotation, "u_rotation" });
|
||||
|
||||
// These two are only used for VR, but let's always query them for simplicity.
|
||||
queries.push_back({ &u_scaleX, "u_scaleX" });
|
||||
@@ -442,7 +441,6 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin
|
||||
ConvertProjMatrixToGL(flippedMatrix);
|
||||
|
||||
render_->SetUniformM4x4(&u_proj, flippedMatrix.m);
|
||||
render_->SetUniformF1(&u_rotation, useBufferedRendering ? 0 : (float)g_display.rotation);
|
||||
}
|
||||
if (dirty & DIRTY_PROJTHROUGHMATRIX) {
|
||||
Matrix4x4 proj_through;
|
||||
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
int u_depthRange; // x,y = viewport xscale/xcenter. z,w=clipping minz/maxz (?)
|
||||
int u_cullRangeMin;
|
||||
int u_cullRangeMax;
|
||||
int u_rotation;
|
||||
int u_mipBias;
|
||||
int u_scaleX;
|
||||
int u_scaleY;
|
||||
|
||||
@@ -504,10 +504,15 @@ void SystemInfoScreen::CreateVulkanExtsTab(UI::LinearLayout *gpuExtensions) {
|
||||
|
||||
auto si = GetI18NCategory(I18NCat::SYSINFO);
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
|
||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
||||
|
||||
CollapsibleSection *vulkanFeatures = gpuExtensions->Add(new CollapsibleSection(si->T("Vulkan Features")));
|
||||
|
||||
// TODO: This one belongs under its own header. And this is Vulkan "pre-rotation" really.
|
||||
vulkanFeatures->Add(new InfoItem(gr->T("Display rotation"), StringFromFormat("%d°", (int)g_display.rotation * 90)));
|
||||
|
||||
std::vector<std::string> features = draw->GetFeatureList();
|
||||
for (const auto &feature : features) {
|
||||
vulkanFeatures->Add(new TextView(feature, FLAG_DYNAMIC_ASCII, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
|
||||
|
||||
Reference in new issue
Block a user