Convert the pre-rotation to just the matrix multiplication.

This commit is contained in:
Henrik Rydgård
2026-05-15 11:12:57 +02:00
parent 065a68ef4f
commit 947217d1be
4 changed files with 30 additions and 14 deletions
+4
View File
@@ -441,6 +441,10 @@ public:
return winsys_;
}
bool SupportsPreRotation() const {
return surfCapabilities_.supportedTransforms != VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
}
private:
bool ChooseQueue();
+19 -5
View File
@@ -67,7 +67,7 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo
}
// TODO: This will be removed later.
static inline void FlipProjMatrix(Matrix4x4 &in) {
static inline void FlipProjMatrix(Matrix4x4 & in) {
const bool invertedY = gstate_c.vpHeight < 0;
if (invertedY) {
in[1] = -in[1];
@@ -84,6 +84,22 @@ static inline void FlipProjMatrix(Matrix4x4 &in) {
}
}
void UpdateRotation(float rotMatrix[4], bool useBufferedRendering) {
if (useBufferedRendering) {
rotMatrix[0] = 1.0f;
rotMatrix[1] = 0.0f;
rotMatrix[2] = 0.0f;
rotMatrix[3] = 1.0f;
} else {
const DisplayRotation rotation = g_display.rotation;
// The others are ROTATE_90 and so on.
rotMatrix[0] = rotation == DisplayRotation::ROTATE_0 ? 1.0 : (rotation == DisplayRotation::ROTATE_180 ? -1.0 : 0.0);
rotMatrix[1] = rotation == DisplayRotation::ROTATE_90 ? 1.0 : (rotation == DisplayRotation::ROTATE_270 ? -1.0 : 0.0);
rotMatrix[2] = rotation == DisplayRotation::ROTATE_270 ? 1.0 : (rotation == DisplayRotation::ROTATE_90 ? -1.0 : 0.0);
rotMatrix[3] = rotation == DisplayRotation::ROTATE_0 ? 1.0 : (rotation == DisplayRotation::ROTATE_180 ? -1.0 : 0.0);
}
}
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport, bool useBufferedRendering) {
if (dirtyUniforms & DIRTY_TEXENV) {
Uint8x3ToFloat3(ub->texEnvColor, gstate.texenvcolor);
@@ -130,8 +146,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
FlipProjMatrix(flippedMatrix);
ConvertProjMatrixToZeroToOneDepth(flippedMatrix);
CopyMatrix4x4(ub->proj, flippedMatrix.getReadPtr());
ub->rotation = useBufferedRendering ? 0 : (float)g_display.rotation;
UpdateRotation(ub->rotation, useBufferedRendering); // TODO: This can be done a lot less often.
}
if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) {
@@ -145,8 +160,7 @@ 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;
UpdateRotation(ub->rotation, useBufferedRendering); // TODO: This can be done a lot less often.
}
// Transform
+5 -3
View File
@@ -25,6 +25,7 @@ struct alignas(16) UB_VS_FS_Base {
float view[12];
float world[12];
float tex[12];
float rotation[4];
float uvScaleOffset[4];
float depthRange[4];
float matAmbient[4];
@@ -39,11 +40,11 @@ struct alignas(16) UB_VS_FS_Base {
float texClamp[4];
float texClampOffset[2]; float fogCoef[2];
float blendFixA[3]; float stencilReplaceValue;
float blendFixB[3]; float rotation;
float blendFixB[3]; float padding3;
// 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_assert(sizeof(UB_VS_FS_Base) == 496, "UB_VS_FS_Base should be 496 bytes");
static const char * const ub_baseStr =
R"( mat4 u_proj;
@@ -51,6 +52,7 @@ R"( mat4 u_proj;
mat3x4 u_view;
mat3x4 u_world;
mat3x4 u_texmtx;
vec4 u_rotation;
vec4 u_uvscaleoffset;
vec4 u_depthRange;
vec4 u_matambientalpha;
@@ -66,7 +68,7 @@ R"( mat4 u_proj;
vec4 u_texclamp;
vec2 u_texclampoff; vec2 u_fogcoef;
vec3 u_blendFixA; float u_stencilReplaceValue;
vec3 u_blendFixB; float u_rotation;
vec3 u_blendFixB; float pad3;
)";
// 512 bytes. Would like to shrink more. Some colors only have 8-bit precision and we expand
+2 -6
View File
@@ -1264,12 +1264,8 @@ 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");
// NOTE: This is only needed on platforms that support pre-rotation.
WRITE(p, " outPos.xy = mul(mat2(u_rotation), outPos.xy);\n");
}
bool flipY = strlen(compat.viewportYSign) > 0;