In this abstraction, I almost completely rejected the previous abstraction .
Originally, the abstraction of RHI has been basically completed, and you can happily write basic lighting and shadowing functions.
However, I accidentally saw the big guys talking about bindless in the QQ group, and then went to check the information, and found that the performance of bindless is good, abstract and easy to do, so I decisively entered the pit of bindless.
In the bindless abstraction, all the used material parameters and textures are loaded into the video memory, and then an ID index is used to refer to the relevant resources.
As the refactoring progressed, I found that there were many problems with the previous design ideas, which were all caused by my unfamiliarity with GPU resource management.
When we upload textures to the GPU or update resources, Vulkan always prefers us to call the batch interface because the GPU is far from the CPU.
right! As Nvidia said, Batch! Batch! Batch!, but not limited to DrawCall, converting memory layout, uploading resources requires Batch.
Then, all the abstractions made before are basically useless.
In the previous abstraction, I did it based on the idea of synchronization. For example, when I create a new image, I need to wait for it to upload successfully before returning it. Otherwise, some data in the structure cannot be initialized.
After careful consideration, I think option 1 mentioned earlier is actually a better choice.
The problem of data redundancy is not difficult to solve, as long as we sink the data needed by the graphics API layer into the internal code of the graphics API layer, and then make a proxy function in the structure of the RHI layer to obtain the relevant attributes through gpu_handle and return. In practical applications, because attributes such as width, height, and format belong to low-frequency access, no matter how they are encapsulated, they cannot actually become performance bottlenecks.
In this way, the data structure of the new RHI layer only needs to hold the corresponding gpu_handle, and this structure has the responsibility of releasing resources.
More subtle is that due to the existence of bindless, the parameters in our shader, such as texture, material parameters are also indexed by id.
In this way, we directly make the resource management of the graphics API layer transparent, and the data structure of RHI can be directly matched with the shader, without caring about how the graphics API layer manages resources.
After the graphics API layer is transparently removed, we have greater freedom of implementation. For example, when new rhi::texture2d is used, the graphics API layer only needs to save the data required for uploading to the GPU, and then assign a gpu_handle, the function is can return immediately.
Before the business logic calls DrawCall, upload the required resources to the GPU.
In practice, since DrawCall is also executed asynchronously by writing to CommandBuffer and finally submitting it, we only need to ensure that GPU commands related to uploading resources are executed before related DrawCall commands in CommandBuffer.
Under the guiding ideology of Batch, in fact, using the encapsulation method of gpu_handle can obtain better Cache Friendly. Because the data structures of all graphics API layers are always accessed in batches during rendering.
Moreover, since gpu_handle is not a pointer, if necessary, some pool optimization techniques can be implemented, such as memory sorting, etc. (As the allocation and release progress, there may be many vacancies in the pool that cannot be used for a long time. At this time, out of memory And Cache Friendly considerations, need to sort out the distribution of elements in a pool).
Finally, this time the refactored code is here .
ps. For some reasons, the thread of this engine may need to be swapped out for a long time in the future. Save the context here so that you can continue to swap in later😀
This article is reproduced from: https://blog.gotocoding.com/archives/1760?utm_source=rss&utm_medium=rss&utm_campaign=%25e9%2587%258d%25e6%2596%25b0%25e6%258a%25bd%25e8%25b1%25a1%25e5% 259b%25be%25e5%25bd%25a2api
This site is for inclusion only, and the copyright belongs to the original author.