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

Add support for vulkan format emulation #9

Closed
haasn opened this issue Jan 24, 2018 · 1 comment
Closed

Add support for vulkan format emulation #9

haasn opened this issue Jan 24, 2018 · 1 comment

Comments

@haasn
Copy link
Owner

haasn commented Jan 24, 2018

Some vulkan formats such as VK_FORMAT_R8G8B8_UNORM (“rgb24”) exist in theory but not in hardware. Unfortunately, this is a pretty common format for packed data to live in (basically all computer images without an alpha channel).

Being able to support uploading this somehow without requiring acrobatics from the user would be useful. There are two main methods of accomplishing this:

  1. Soft-convert using a library like zimg on the CPU, before uploading. While it sounds simple, this unfortunately has a compilcation: the data might be in a VkBuffer already (e.g. host-mapped ra_buf), so we'd have to copy from one VkBuffer to another first) and it's also a drain on RAM bandwidth (which is often more of a bottleneck than VRAM bandwidth for high res content). However, this method would be preferred in a scenario where we're already forced to copy the data around (e.g. ra_tex_upload from a source pointer instead of a ra_buf).

  2. Silently substitute a suitable “replacement” format, such as VK_FORMAT_R8G8B8A8_UNORM, and use this for all texture operations from the point of view of the GPU. The major complication here is figuring out how to upload data from a 3-component VkBuffer into a 4-component VkImage. One possibility here would be a compute shader that reads from the VkBuffer and directly writes to the VkImage. Unfortunately, this requires the VkBuffer be shader-visible as a storage buffer. It also has certain complications due to potential SSBO range limits. In the most likely scenario, we might need to copy from a host-mapped VkBuffer into an intermediate VkBuffer using the DMA engine, followed by a compute shader to write to the VkImage.

@haasn
Copy link
Owner Author

haasn commented Feb 8, 2018

I decided to go with approach #2, because I tested the compute shader / texel buffer upload path and it turned out to be very fast, certainly faster than trying to CPU-convert everything. This also is the most flexible, since it allows using buffer-based upload and all that jazz.

I had to copy via an indirect VkBuffer in either case, though, because we need it to be a storage buffer instead of a texture transfer buffer. (Note: This is actually not a hard requirement of vulkan, but a requirement of our API design. In theory, we could maybe try aliasing a TEX_TRANSFER buffer as a texel buffer at the same time.. but not today)

There's also a pretty glaring hole in that we have to use the compute shader queue for the DMA upload (instead of the transfer queue), simply because we can't deal at all with cross-queue buffer dependencies. (Maybe we could reuse the vk_signal here?)

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

No branches or pull requests

1 participant