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

Implement Buffer Device Address for Rendering Device Vulkan and DirectX12 #100062

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

thimenesup
Copy link
Contributor

This is an extremely useful feature that is supported on many GPUs which may be worthwhile to have it since the changes are minimally invasive, and allows for a lot of flexibility, specially for compute shaders and a requirement for ray tracing.

Tested to work on Windows 10 with Vulkan driver.
On DirectX12 the SPIR-V to NIR shader compiler doesn't have implemented this extension (yet?), so remains untested.
Test project used available here

Do note that it only has been implemented for storage buffers, to not change function signatures, but it could be implemented for the other buffer types, either by adding another default parameter, or breaking compatibility and using bitwise flags.

@thimenesup thimenesup requested a review from a team as a code owner December 5, 2024 17:49
@DarioSamo
Copy link
Contributor

DarioSamo commented Dec 5, 2024

Both you and #99119 are trying to implement this as buffer device address is required for RT as well. You might want to coordinate how to support this particular feature as both implementations seem to be a bit different. CC @Fahien

@thimenesup
Copy link
Contributor Author

From what I have seen the implementations are fairly similar, albeit with some small differences, mine loads the extension either from core 1.2 or the KHR version which has a wider support compared to the EXT used in the other branch (sourced from the gpuinfo database), and also flags index and vertex buffers by default, which likely won't play nicely on devices where its not supported.

I think the buffer device address feature its worthwhile on its own and should be merged beforehand, then the other ray tracing branch could be rebased from it.

Went ahead an added it as optional functionality to index, vertex and uniform buffers while preserving compatibility, and updated the documentation.
Also implemented it for Metal to ensure compilation, but its an API I haven't really used, so I don't know for sure if its 100% correct.

@Fahien
Copy link
Contributor

Fahien commented Dec 6, 2024

@thimenesup: I think the buffer device address feature its worthwhile on its own and should be merged beforehand, then the other ray tracing branch could be rebased from it.

I agree.

@DarioSamo
Copy link
Contributor

I think the buffer device address feature its worthwhile on its own and should be merged beforehand, then the other ray tracing branch could be rebased from it.

I believe so as well, it's easier to integrate it piece-meal like this. I just wanted to make sure you were both in agreement as it'll break the RT branch as soon as it's merged. I have no qualms with integrating the feature as I know how necessary it is for advanced rendering.

@thimenesup thimenesup force-pushed the rd_buffer_address branch 2 times, most recently from e8b36c3 to 0326684 Compare December 9, 2024 19:09
@RandomShaper
Copy link
Member

Looks good, but there are compatibility breakages.

@thimenesup
Copy link
Contributor Author

Added the GDExtension compatiblity methods and rebased with the current master again to fix merge conflicts.

@Fahien
Copy link
Contributor

Fahien commented Dec 20, 2024

Do we need something like this in _initialize_device()?

	VkPhysicalDeviceBufferDeviceAddressFeaturesKHR device_address_features = {};
	if (buffer_device_address_support) {
		device_address_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
		device_address_features.pNext = create_info_next;
		device_address_features.bufferDeviceAddress = buffer_device_address_support;
		create_info_next = &device_address_features;
	}

@thimenesup
Copy link
Contributor Author

I think it might be needed for the devices that aren't initializing core Vulkan 1.2 but a prior version instead.

Copy link
Contributor

@stuartcarnie stuartcarnie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left a couple of notes for Metal. Your implementation is correct, so I suggest you add a property to the MetalFeatures structure, that is set on initialisation, so you can return the correct value for the SUPPORTS_BUFFER_ADDRESS feature.

Comment on lines +3959 to +3960
case SUPPORTS_BUFFER_ADDRESS:
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be true, but I would like to implement it by adding a new boolean property on the MetalFeatures struct:

struct API_AVAILABLE(macos(11.0), ios(14.0)) MetalFeatures {

Comment on lines +161 to +169
uint64_t RenderingDeviceDriverMetal::buffer_get_device_address(BufferID p_buffer) {
if (@available(iOS 16.0, macOS 13.0, *)) {
id<MTLBuffer> obj = rid::get(p_buffer);
return obj.gpuAddress;
} else {
return 0;
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct for Metal 👍🏻

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

Successfully merging this pull request may close these issues.

8 participants