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

RenderingServer.texture_2d_update_partial() missing #65762

Open
Griefchief opened this issue Sep 13, 2022 · 9 comments · May be fixed by #80164
Open

RenderingServer.texture_2d_update_partial() missing #65762

Griefchief opened this issue Sep 13, 2022 · 9 comments · May be fixed by #80164

Comments

@Griefchief
Copy link
Contributor

Godot version

4.0.alpha17.official

System information

Windows 10, Vulkan.

Issue description

VisualServer in Godot3 has texture_set_data_partial() function for performance reasons instead of texture_set_data. It is used prominently in Zyllan Terrain. Godot 4 is missing such a function, exposing only the original full image override via RenderingServer.texture_2d_update().

I suspect Godot 4 still needs a function similar to RenderingServer.texture_2d_update_partial()

original implementation in Godot 3.06 and above:
● void texture_set_data_partial(texture: RID, image: Image, src_x: int, src_y: int, src_w: int, src_h: int, dst_x: int, dst_y: int, dst_mip: int, layer: int = 0)

Sets a part of the data for a texture. Warning: this function calls the underlying graphics API directly and may corrupt your texture if used improperly.

@Zylann

Steps to reproduce

Not needed.

Minimal reproduction project

Not needed.

@alazifk
Copy link

alazifk commented Sep 21, 2022

Does that mean we could do texture.update_partial()? That would be great, because texture.update() is a bottleneck for bigger textures.

@Oshroth
Copy link

Oshroth commented Nov 8, 2022

I've been looking at the source code to see what happens and if there is an equivalent for Godot 4. In Godot 3, it looks like the call to VisualServer.texture_set_data_partial() goes to the rasterizer storage class for the graphics API (i.e. GLES2, GLES3) (though apparently its not implemented for GLES2) and calls glTexSubImage2D() or respective functions to update the texture. And that code hasn't been implemented/exposed in Godot 4 for Vulkan.

It looks like the equivalent function for Vulkan is vkCmdCopyBufferToImage() but that is only currently being used internally in Godot 4's RenderingDeviceVulkan::_texture_update() function

@kleonc
Copy link
Member

kleonc commented Nov 8, 2022

cc @clayjohn

@kayomn
Copy link
Contributor

kayomn commented Jan 23, 2023

I've been looking at the source code to see what happens and if there is an equivalent for Godot 4. In Godot 3, it looks like the call to VisualServer.texture_set_data_partial() goes to the rasterizer storage class for the graphics API (i.e. GLES2, GLES3) (though apparently its not implemented for GLES2) and calls glTexSubImage2D() or respective functions to update the texture. And that code hasn't been implemented/exposed in Godot 4 for Vulkan.

It looks like the equivalent function for Vulkan is vkCmdCopyBufferToImage() but that is only currently being used internally in Godot 4's RenderingDeviceVulkan::_texture_update() function

Unless I'm misreading the code, it looks like a fix to this would be exposing an area rect as a new argument to the function, using that in the x y dimension loop, renaming the function, then wrapping that in a new _update_texture function that follows the original function signature.

Then it would just be a case of exposing this to the higher level interfaces in a similar way to how it already is through RenderingDevice::texture_update as a new virtual function specifically for partial updates.

The only thing that makes me doubt this solution is the logic that deals with compressed images.

@Zylann
Copy link
Contributor

Zylann commented Jan 23, 2023

The only thing that makes me doubt this solution is the logic that deals with compressed images.

I think the Godot 3 version did not support compressed images either. Although compressed images are usually not present in use cases for this function. Or if that was actually needed, I think VRAM compressed formats use blocks of pixels, so perhaps it would work if the specified sub-rectangle is a multiple of block size.

@kayomn
Copy link
Contributor

kayomn commented Jan 23, 2023

I think the Godot 3 version did not support compressed images either. Although compressed images are usually not present in use cases for this function. Or if that was actually needed, I think VRAM compressed formats use blocks of pixels, so perhaps it would work if the specified sub-rectangle is a multiple of block size.

I've had a look through rasterizer_storage_gles3.cpp in 3.5 and it looks like it does handle compressed images, but the interface for doing so is supplied by OpenGL itself via glCompressedTexSubImage2D.

@ozzr
Copy link

ozzr commented Feb 8, 2023

Is there any progress on this?
I porting my terrain to Godot 4 and I would like to use this feature for heightmap editing and runtime updates

@SlashScreen

This comment was marked as off-topic.

@Calinou
Copy link
Member

Calinou commented Apr 5, 2023

@SlashScreen Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In progress / Assigned
10 participants