Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the uvscale uniform a bit more conservatively on framebuffer-texture changes #17582

Merged
merged 1 commit into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions GPU/Common/ShaderUniforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,16 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView

// Texturing
if (dirtyUniforms & DIRTY_UVSCALEOFFSET) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
float widthFactor = 1.0f;
float heightFactor = 1.0f;
if (gstate_c.textureIsFramebuffer) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
widthFactor = (float)w * invW;
heightFactor = (float)h * invH;
}
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
// However, this is missing a check that we're not getting our UV:s supplied for us in the vertices.
Expand Down
19 changes: 12 additions & 7 deletions GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1141,23 +1141,26 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate)
bool needsDepthXSwizzle = depthUpperBits == 2;

// We need to force it, since we may have set it on a texture before attaching.
gstate_c.curTextureWidth = framebuffer->bufferWidth;
gstate_c.curTextureHeight = framebuffer->bufferHeight;

int texWidth = framebuffer->bufferWidth;
int texHeight = framebuffer->bufferHeight;
if (candidate.channel == RASTER_COLOR && gstate.getTextureFormat() == GE_TFMT_CLUT8 && framebuffer->fb_format == GE_FORMAT_5551 && PSP_CoreParameter().compat.flags().SOCOMClut8Replacement) {
// See #16210. UV must be adjusted as if the texture was twice the width.
gstate_c.curTextureWidth *= 2.0f;
texWidth *= 2.0f;
}

if (needsDepthXSwizzle) {
gstate_c.curTextureWidth = RoundUpToPowerOf2(gstate_c.curTextureWidth);
texWidth = RoundUpToPowerOf2(texWidth);
}

gstate_c.curTextureWidth = texWidth;
gstate_c.curTextureHeight = texHeight;
gstate_c.SetTextureIsFramebuffer(true);
gstate_c.SetTextureIsBGRA(false);

if ((gstate_c.curTextureXOffset == 0) != (fbInfo.xOffset == 0) || (gstate_c.curTextureYOffset == 0) != (fbInfo.yOffset == 0)) {
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
gstate_c.SetTextureIsBGRA(false);
gstate_c.SetTextureIsFramebuffer(true);

gstate_c.curTextureXOffset = fbInfo.xOffset;
gstate_c.curTextureYOffset = fbInfo.yOffset;
u32 texW = (u32)gstate.getTextureWidth(0);
Expand Down Expand Up @@ -2364,6 +2367,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
gpuStats.numDepal++;

gstate_c.curTextureWidth = texWidth;
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);

draw_->BindTexture(0, nullptr);
framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer");
Expand Down Expand Up @@ -2465,6 +2469,7 @@ void TextureCacheCommon::ApplyTextureDepal(TexCacheEntry *entry) {
gpuStats.numDepal++;

gstate_c.curTextureWidth = texWidth;
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);

draw_->BindTexture(0, nullptr);
framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer");
Expand Down
16 changes: 10 additions & 6 deletions GPU/Directx9/ShaderManagerDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,16 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {

// Texturing
if (dirtyUniforms & DIRTY_UVSCALEOFFSET) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
float widthFactor = 1.0f;
float heightFactor = 1.0f;
if (gstate_c.textureIsFramebuffer) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
widthFactor = (float)w * invW;
heightFactor = (float)h * invH;
}
float uvscaleoff[4];
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
Expand Down
16 changes: 10 additions & 6 deletions GPU/GLES/ShaderManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,16 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin
render_->SetUniformF(&u_fogcoef, 2, fogcoef);
}
if (dirty & DIRTY_UVSCALEOFFSET) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
float widthFactor = 1.0f;
float heightFactor = 1.0f;
if (gstate_c.textureIsFramebuffer) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
widthFactor = (float)w * invW;
heightFactor = (float)h * invH;
}
float uvscaleoff[4];
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
Expand Down
10 changes: 6 additions & 4 deletions GPU/GPUCommonHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@ void GPUCommonHW::Execute_Bezier(u32 op, u32 diff) {

SetDrawType(DRAW_BEZIER, PatchPrimToPrim(surface.primType));

gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);
// We need to dirty UVSCALEOFFSET here because we look at the submit type when setting that uniform.
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_UVSCALEOFFSET);
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
gstate_c.submitType = SubmitType::HW_BEZIER;
if (gstate_c.spline_num_points_u != surface.num_points_u) {
Expand All @@ -1207,7 +1208,7 @@ void GPUCommonHW::Execute_Bezier(u32 op, u32 diff) {
UpdateUVScaleOffset();
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "bezier");

gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_UVSCALEOFFSET);
gstate_c.submitType = SubmitType::DRAW;

// After drawing, we advance pointers - see SubmitPrim which does the same.
Expand Down Expand Up @@ -1265,7 +1266,8 @@ void GPUCommonHW::Execute_Spline(u32 op, u32 diff) {

SetDrawType(DRAW_SPLINE, PatchPrimToPrim(surface.primType));

gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);
// We need to dirty UVSCALEOFFSET here because we look at the submit type when setting that uniform.
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_UVSCALEOFFSET);
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
gstate_c.submitType = SubmitType::HW_SPLINE;
if (gstate_c.spline_num_points_u != surface.num_points_u) {
Expand All @@ -1280,7 +1282,7 @@ void GPUCommonHW::Execute_Spline(u32 op, u32 diff) {
UpdateUVScaleOffset();
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "spline");

gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE);
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_UVSCALEOFFSET);
gstate_c.submitType = SubmitType::DRAW;

// After drawing, we advance pointers - see SubmitPrim which does the same.
Expand Down
5 changes: 5 additions & 0 deletions GPU/GPUState.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,11 @@ struct GPUStateCache {
if (textureIsFramebuffer != isFramebuffer) {
textureIsFramebuffer = isFramebuffer;
Dirty(DIRTY_UVSCALEOFFSET);
} else if (isFramebuffer) {
// Always dirty if it's a framebuffer, since the uniform value depends both
// on the specified texture size and the bound texture size. Makes things easier.
// TODO: Look at this again later.
Dirty(DIRTY_UVSCALEOFFSET);
}
}
void SetUseFlags(u32 newFlags) {
Expand Down