mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Update the uvscale uniform a bit more conservatively on framebuffer changes
Plus fixes a few minor oversights Fixes #17581 and possibly #17522
This commit is contained in:
parent
4a4cd3d977
commit
def09bf575
@ -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.
|
||||
|
@ -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);
|
||||
@ -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");
|
||||
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
@ -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.
|
||||
@ -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) {
|
||||
@ -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.
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user