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
Conversation
Works as expected with no noticeable regressions. You'll definitely need to squash the commits after things have been reviewed. |
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? |
I think this function should be splitted from DoPartialTextureUpdate(), eg
So we can reuse the allocator and move the rescale logic into videocommon. |
Tino could you remove the recent gameini change where scaled efb copies were disabled for nsmb with this pr? #2666 |
@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? |
There is already a function to create a new texture: |
:) 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? |
Maybe also with both a source_rect and a dest_rect. So it can also be used for the partial texture update itself. |
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.
This comment was marked as off-topic.
Sorry, something went wrong.
mimimi085181: that is an interesting case, so the efb copies are used but the destination address does not belong to an active texture? |
@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. |
@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. |
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. |
@JMC47 unlikely |
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 |
5947a35
to
dcdbbe6
Compare
@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. |
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.
This comment was marked as off-topic.
Sorry, something went wrong.
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.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
@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. |
@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.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
LGTM |
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. |
Filtering would still be nice, but it's more of a feature than a bug in my opinion. |
Implement scaled partial texture updates
No problem, Thanks |
No description provided.