-
Notifications
You must be signed in to change notification settings - Fork 405
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 KHR_buffer_device_address #1619
Add support for KHR_buffer_device_address #1619
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the submission!
Have you tested this? I'm asking, because coincidentally, I started working on this extension a couple of weeks ago, before WWDC introduced gpuAddress
(I had been curious if contents
would work on shared memory), and one thing I found when trying to run the buffer_device_address
sample from Vulkan-Samples
was that the MSL generated by SPIRV-Cross did not generate the right address space for the GPU pointers.
I do have a SPIRV-Cross change for that, which I will publish now that we can actually definitely do this.
Also because the gpuAddress getter obviously doesn't exist on older versions of macOS or Xcode, should I wrap the function definition with MVK_XCODE_14?
Yes...add an MVK_XCODE_14
exactly like MVK_XCODE_13
, and wrap the call to gpuAddress
in that...and I guess return either 0
or MVKBuffer::getHostMemoryAddress()
in the #else
part. I recommend adding a MVKBuffer::gpuAddress()
function and handle all this messiness there...so we can use it more generally (for example as part of eventually supporting capture replay)
Also...add...
ADD_DVC_EXT_ENTRY_POINT(vkGetBufferDeviceAddressKHR, KHR_BUFFER_DEVICE_ADDRESS);
in the appropriate place in MVKInstance.mm
(line 629 I think).
Also...even though we indicate that capture replay is disabled, we should add the functions anyway, so that app build linkages won't break from app code that checks for that flag any maybe calls those functions. For now you can just stub them out (plus add the corresponding MVKInstance.mm
entry points).
Finally...there are some other housekeeping items that normally get added regarding formal extension enablement. But rather than explain them here, I'll add them from my version of this after we pull yours in.
e39e2f3
to
8ae9ed4
Compare
I will test how |
8ae9ed4
to
a87aa62
Compare
Just a note, I can't remember what page it was but I think |
@mbarriault macOS 13 release notes mention that MTLResource.gpuHandle is deprecated and should use gpuResourceID instead. Maybe that's what you're thinking of? |
Yep that's what I was thinking of, and got confused not realizing |
I also just finished upgrading to macOS 13 and tested the selectors. id<MTLBuffer> buffer = [device newBufferWithLength:64
options:MTLResourceStorageModeShared];
std::cout << [buffer contents] << std::endl;
std::cout << [buffer gpuAddress] << std::endl; For some reason I get the following output in the console:
But running with Xcode 14 in the debugger:
Here it shows that they're two different values... Though why and how I'll see tomorrow, it's getting late. |
a87aa62
to
c52eebe
Compare
I'm not sure it matters. macOS 13 drops support for practically everything that doesn't support Metal 3. |
macOS13 will support AMD Bronze GPUs like Radeon560, which is the default GPU for 2019 MacPro, but Bronze does not support Metal3. I would say - having a support check still matters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested cleanups for getMTLBufferAddress()
.
c52eebe
to
60b06e0
Compare
I agree with this. Once we pull this in, I'll add a check for Metal3 when I add the code to track enablement of this extension in the |
@billhollings So I'm testing a simple application atm. And I did post a small message yesterday here. However, I'll just recap what I wrote there. So, it seems as if Quite frankly, I don't think the About your issue with address spaces I found the following on the Metal language specification. Essentially, using
|
Are you even allowed to use gpuAddress outside of argument buffers? Every mention of it from Apple mentions it as a means to fill an argument buffer. |
With Metal 3 argument buffers, the usage I just showed is the same as what you would "normally" do. Metal 3 argument buffers are essentially just a struct where you assign each member with a |
Yup...I saw that. It didn't talk about shaders and SPIRV-Cross...which is my main concern in my question. Is your
Okay. I've marked this PR as WIP for now...and it can evolve as the Beta, and other testing, progresses. |
@billhollings I did some testing in my own renderer and in a simple test application, which simply tries writing to a buffer by using its uint64_t address as a pointer. Xcode shows "Invalid buffer" in the debug viewer, however the code still runs fine. I tested this by using the shader to multiply a value and the output buffer did indeed have the correct value in it. Another person, as well as myself, also noticed that when running the same code inside of an AppKit application makes Xcode correctly pick up the buffer. So, ultimately, it seems it's currently just a bug with Xcode that it falsely displays the buffer as being invalid. Therefore, I would think that it does actually work as expected and that SPIRV-Cross would only need to change to use
It is hand-written, although I did try and compile a GLSL shader separately and got a similar result to it and I think it would still be valid (given that your patch to fix the address space is applied).
I have a feeling the CPU and GPU access memory differently. The contents pointer is at a different address than the gpuAddress. Accessing the address from gpuAddress on the CPU results in EXC_BAD_ACCESS, similar to when trying to access contents from the GPU. Also quoting the documentation for the gpuAddress property, it explicitly says "virtual":
I cannot reproduce this exact case, but the gpuAddress has not been 0x0 ever since... So perhaps this was just invalid testing by me. So, in conclusion, I think this is actually perfectly valid and good-to-go. The gpuAddress is in fact a pointer to the memory that the GPU can access and works perfectly fine currently. |
Does it help if you link explicitly to |
No, linking CoreGraphics.framework does nothing. Also, |
@billhollings I received an answer from Apple regarding gpuAddress being shown as invalid in the Xcode debugger window:
So my concerns came from a bug within Xcode; the code itself actually works perfectly. Without the shader validation layer the gpuAddress shows as expected and Xcode also shows the pointers in argument buffers properly: So yeah, there's definitely nothing wrong with this PR anymore :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my concerns came from a bug within Xcode; the code itself actually works perfectly.
Thanks for the update. I have also confirmed that gpuAddress()
works correctly in my testing with the Vulkan-Samples
sample app.
Just one last change needed to fix an issue I encountered in my testing.
60b06e0
to
83c0ca6
Compare
SPIRV-Cross PR #1965 adds the shader pointer behavior needed for this functionality. Once that is pulled in, I'll pull this in, and add the additional functionality described above on a second PR here. |
I've created issue #1644 to track the update required for this.
|
Quick patch to add support for KHR_buffer_device_address for devices with iOS 16 or macOS 13.
Though also, was a small concern I had about #1600, this never checks if the MTLDevice actually supports Metal 3. Perhaps there are some changes to be made to
MVKExtensions.def
andMVKExtensions.mm
. Somewhere, it should be checkingsupportsMTLGPUFamily(MTLGPUFamilyMetal3)
and only then return the extension. And forVK_KHR_fragment_shader_barycentric
, this:Also because the
gpuAddress
getter obviously doesn't exist on older versions of macOS or Xcode, should I wrap the function definition withMVK_XCODE_14
?