-
Notifications
You must be signed in to change notification settings - Fork 7
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
Dedicated frame buffers. #125
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…for on swap chain presents.
- Move render pass dependency to rendering base library and simplify it (finally remove render pass dependency source). - Move secondary command buffers to render pass. - Allow adding frame buffer images directly from render targets. - Implement frame buffer resize and release events. - Implement render pass and pipeline frame buffer caches. - Adjust builder interfaces to above changes.
crud89
added
DX12 ❎
The issue involves the DX12 backend.
Build 🛠
Issues that involve the build process.
labels
Feb 19, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Describe the pull request
This PR decouples frame buffers from render passes, which allows to have multiple frame buffers (for example of different resolutions and/or sampling rates) that pass through the same render pass during a single frame, ultimately making it easier to implement features like render textures or viewports with differing properties. It is an extension of the concepts introduced in PR #124.
Frame buffers have now a slightly different semantic compared to their low-level counterparts (most importantly Vulkan). A frame buffer in the engine now is merely more than is a set of images that can be mapped to render targets. A frame buffer itself can store images of different resolutions and samples and only if a render pass uses the images for rendering, their restrictions are enforced. At this point, the render target sampling rate and format must match the image sampling rate and format. Additionally all images that are used as render targets in one render pass must have equal sampling rates.
Frame buffer images are mapped to render targets. This can be done in different ways. Conceptually a frame buffer image is addressed by an index, whilst a render target can now be identified via an identifier. A mapping must be explicitly set up when creating the render pass. To simplify this process, render target identifiers can be deduced from their name's hash. Similarly, a frame buffer image can be mapped using its name's hash. If a render target uses the same name as a frame buffer image, it is sufficient to pass the render target to
IFrameBuffer::mapRenderTarget
to establish a mapping. Render targets from different render passes can use the same name (or identifier) to map to the same image this way (alternatively, they can use different names, but have manual mappings defined).When a render pass begins, the mappings are resolved for the render targets and they are implicitly transitioned into compatible render target states. Similarly, if a render pass ends, the render targets are transitioned back into compatbile shader resource states. Note that by default render targets are expected to be in read-only shader resource states outside of render passes. If a resource should be written to (for example from a compute shader), it needs manual barriers to ensure the layouts transition from and back into shader resource state. The compute sample demonstrates how to do this.
Whenever a render pipeline gets used on a render pass, the input attachments it is using are resolved and bound through the render pass in a similar fashion to how render targets are resolved described above. This means that an input attachment must resolve to a resource from the same frame buffer. Mapping render targets to different frame buffers or sharing images between multiple frame buffers is not supported. In other words: a frame buffer stores all target images for a single frame that is rendered.
The Vulkan backend now uses the dynamic rendering to model render passes, which has two major advantages: first, it allows to specify sampling rates at pipeline level. This makes it possible to have multiple pipelines at different sampling rates that use the same render pass instead of having to create a new one for different sampling rates. The natural limitation being the frame buffer requirements mentioned above. The second avantage is that it is now possible to use the same shader code base for render pass inputs between the DirectX 12 and Vulkan backends. Subpass attachments and dependencies are no longer supported.
Finally, the render pass example has been extended significantly. It now uses three render passes to demonstrate how to share frame buffer images between them. Previously one had to fetch contents from an earlier render pass to write them into it's own local resource, which not only increased memory consumption (every render pass had it's own local frame buffer images), but also is more expensive in some situations, for example when using a depth buffer from an earlier pass to do an early depth test. In the example, the first render pass draws to a color and depth texture. A second render pass reads the color buffer and copies the result into a new one (purely for demonstration purposes). The last render pass binds the second color buffer as well as the depth buffer and draws more geometry with proper depth testing enabled, but without writing it's own depth values.
Note that the changes in this PR require changes to the code base, as frame buffers now must be managed by the application. To aid with this, they can be put into the device state, though. All examples have been updated to demonstrate how to use the new frame buffers.