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

Implement scaled partial texture updates #2679

Merged
merged 1 commit into from Jul 22, 2015
Merged

Conversation

Tinob
Copy link
Contributor

@Tinob Tinob commented Jun 30, 2015

No description provided.

@JMC47
Copy link
Contributor

JMC47 commented Jun 30, 2015

Works as expected with no noticeable regressions.

You'll definitely need to squash the commits after things have been reviewed.

@mimimi085181
Copy link
Contributor

This is maybe a dumb question, but could you make it so, that it uses the texture pool for the new texture? I'm not sure if this is possible, and for new super mario bros it would only be a tiny boost for 1 frame when switching worlds, but still...

Also, what if this upscaling was imlemented for all normal textures? Would that properly upscale the clothes in the Last Story?

@degasus
Copy link
Member

degasus commented Jun 30, 2015

I think this function should be splitted from DoPartialTextureUpdate(), eg

void TextureCache::TCacheEntry::ReScale(const TCacheEntryBase& entry);

// Makes a scaled copy of old_entry. 
new_entry->ReScale(old_entry);

So we can reuse the allocator and move the rescale logic into videocommon.

@Linktothepast
Copy link
Contributor

Tino could you remove the recent gameini change where scaled efb copies were disabled for nsmb with this pr? #2666
Testing wise seems fine with both backends.

@Tinob
Copy link
Contributor Author

Tinob commented Jun 30, 2015

@mimimi085181: we can use the texture pool but it will complicate the code a little, but will not bring any noticeable speed improvements. I don't have the last history but are the clothes generated by efb copy?
@degasus: the scale math can be moved to videocommon easily, what is not easy to put in common code is the scaled copy code maybe we can separate the process, one function to make a new entry with the new size and then a new function to make the copy?
@Linktothepast: will rebase and modify the files when i get home tonight.

@degasus
Copy link
Member

degasus commented Jun 30, 2015

There is already a function to create a new texture:
https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoCommon/TextureCacheBase.h#L147
So yes, I've also thought about a new virtual function for the copy.

@Tinob
Copy link
Contributor Author

Tinob commented Jun 30, 2015

:) yes i was thinking in that function to create the new texture, the only missing part then is the copy function, you think in something specific like a simple copy or something more generic with parameter so we can re use it?

@degasus
Copy link
Member

degasus commented Jun 30, 2015

Maybe also with both a source_rect and a dest_rect. So it can also be used for the partial texture update itself.

@mimimi085181
Copy link
Contributor

The clothes in the Last Story are a story of its own. Yes, they are generated via efb copies, and those efb copies are not used as textures in Dolphin. And trying the same as for new super mario bros, but with efb copies are the target/big texture didn't work either. At least i couldn't get it to work.

So if normal textures could just be upscaled as well, i think that might work for the clothes in the Last Story. And it might upscale the coins in nsmb when using efb2ram.

s_ColorCopyProgram.Bind();
glUniform4f(s_ColorCopyPositionUniform, 0.0f, 0.0f,
(float)config.width, (float)config.height);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

This comment was marked as off-topic.

@Tinob
Copy link
Contributor Author

Tinob commented Jun 30, 2015

mimimi085181: that is an interesting case, so the efb copies are used but the destination address does not belong to an active texture?

@degasus
Copy link
Member

degasus commented Jun 30, 2015

@mimimi085181 About your tiny boost with the pool: Pooling is much faster than allocating and freeing. But on NSMBW, this is only done once. So you shouldn't see any speedup ingame.

@mimimi085181
Copy link
Contributor

@Tinob: I have an heuristic for the efb copies that need to be in ram. If i do efb2ram for these efb copies, and remove all texture cache entries that overlap with those, there are still clothes that are displayed wrong. On top of doing efb2ram for the right efb copies, i also need to enable hashing for efb copies, so a change in some other random efb copy is detected. My skills are too limited to see what is going on there. Maybe there's an easy explanation.

@degasus: I know there won't be a speedup by pooling for nsmb, because the speedup would only affect 1 frame when loading a new world. But for consistency it might be nice. Or if it was done for all normal textures.

@JMC47
Copy link
Contributor

JMC47 commented Jul 1, 2015

I'd like to try and get this merged before the progress report goes up. A super high res image with coins would be cool for the progress report.

@degasus
Copy link
Member

degasus commented Jul 1, 2015

@JMC47 unlikely

@neobrain
Copy link
Member

neobrain commented Jul 1, 2015

There is a small problem with the approach taken here: It doesn't take the active texture filtering mode into account when copying the new data into a scaled EFB copy texture. When nearest-neighbor filtering is used, the image will appear blurred compared to the original version (since we currently use a linear filter for updating the texture). This could be dealt with by updating the texture with the proper filter (i.e. by replicating the source texels into a "scale_factor x scale_factor" block of pixels using the nearest-neighbor filter where necessary).

However, one issue with my proposed approach is that there is not "one" filter, but there may be different ones for magnification/minification. Maybe it's useful regardless. I figured I'd point out the issue in any case ;p

@Tinob Tinob force-pushed the master branch 3 times, most recently from 5947a35 to dcdbbe6 Compare July 1, 2015 21:27
@Tinob
Copy link
Contributor Author

Tinob commented Jul 2, 2015

@neobrain: you are right, it will be really difficult to emulate native filtering right in upscaled copies, I prefer to stay with a basic approach unless issues are detected because it could be really complicated and gpu intensive if more scaling filters need to be implemented.

@JMC47
Copy link
Contributor

JMC47 commented Jul 2, 2015

Are there any blocking issues remaining on this?

@Tinob Maybe should remove the line disabling scaled EFB Copies in the INI file?

@@ -19,14 +19,17 @@ class TextureCache : public ::TextureCache
private:
struct TCacheEntry : TCacheEntryBase
{
D3DTexture2D *const texture;
D3DTexture2D * texture;

This comment was marked as off-topic.

iter++;
continue;
}
if (entry_to_update->config.width != w || entry_to_update->config.height != h)

This comment was marked as off-topic.

This comment was marked as off-topic.

@degasus
Copy link
Member

degasus commented Jul 2, 2015

@Tinob Nice rewrite of this feature, I really like it. And sorry for so many comments ;)

@neobrain Through I agree on your comment, I fear there is no way to deal with it. Upscaling is an enhancement which isn't safe by default, especially when dealing with accurate texture sampler settings. And I don't want to spam our texture cache with one rescaled texture per possible sampler state.

@neobrain
Copy link
Member

neobrain commented Jul 2, 2015

@degasus @Tinob: A fix for the specific case where both the mag and the min filter are set to nearest-neighbor sampling is entirely possible and within reasonable scope. Just needs the linear filter in the current code conditionally replaced with point filtering, and the texture region be reloaded upon filter changes. While a generic solution probably will not work indeed, at least this path should be pursued.

srcrect.bottom = entry_to_update->config.height;
dstrect.right = w;
dstrect.bottom = h;
newentry->CopyRectangleFromTexture(entry_to_update, srcrect, dstrect);

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

@degasus
Copy link
Member

degasus commented Jul 2, 2015

LGTM

@Tinob
Copy link
Contributor Author

Tinob commented Jul 5, 2015

Sorry for get missing but i really needed a little rest, a week away from home can really drain your energy. I was looking at @neobrain proposal and i find a posible performance issue, if a game uses the same texture with small updated rectangles from efb with diferent filters in the same frames, the implementation can end redrawing the texture for every filter change. If that is not a problem the implemnation is not that hard, It adds a new field to the cache item to store the filter uses and forces regeneration on filter changes.

@degasus
Copy link
Member

degasus commented Jul 22, 2015

Filtering would still be nice, but it's more of a feature than a bug in my opinion.
@Tinob If you're still working on it, please create a new PR with filtered images.

degasus added a commit that referenced this pull request Jul 22, 2015
Implement scaled partial texture updates
@degasus degasus merged commit 6bcdae6 into dolphin-emu:master Jul 22, 2015
@Tinob
Copy link
Contributor Author

Tinob commented Jul 22, 2015

No problem, Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
6 participants