-
Notifications
You must be signed in to change notification settings - Fork 45
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
Ownership of returned strings #143
Comments
I would probably just have them owned by the WGPUAdapter. Though, if doing that, the whole WGPUAdapterProperties could just be owned by the WGPUAdapter and you wouldn't need this writable pointer thing at all. |
Ok, right, that's an option. It's just not super convenient for us, because it's a C string, and our adapters don't like holding onto those kind. |
We discussed a proposal in today's meeting and I think we were pretty happy with it: typedef struct WGPUAdapterPropertiesImpl* WGPUAdapterProperties;
void wgpuAdapterPropertiesReference(WGPUAdapterProperties);
void wgpuAdapterPropertiesRelease(WGPUAdapterProperties);
WGPUAdapterProperties wgpuAdapterGetProperties(WGPUAdapter);
typedef struct WGPUAdapterPropertiesV1 {
// (no chained struct here)
uint32_t vendorID;
char const * vendorName;
char const * architecture;
uint32_t deviceID;
char const * name;
char const * driverDescription;
WGPUAdapterType adapterType;
WGPUBackendType backendType;
} WGPUAdapterPropertiesV1;
typedef struct WGPUAdapterPropertiesDAWN {
// example extension
} WGPUAdapterPropertiesDAWN;
// The structs are owned by AdapterProperties, returned by reference, freed when it's freed
WGPUAdapterPropertiesV1 const * wgpuAdapterPropertiesGetV1(WGPUAdapterProperties);
WGPUAdapterPropertiesDAWN const * wgpuAdapterPropertiesGetDAWN(WGPUAdapterProperties);
// Extensions can also return things other than structs
int wgpuAdapterPropertiesGetFavoriteNumber(WGPUAdapterProperties);
WGPUSurface This is a bit of a different paradigm than we use for input structs. It's a bit more like NXT's original design where input structs were all builders instead of using chained structs. But I like it a lot more than the Vulkan style where you have to call twice - once to ask for the length, and one to get the value. It was raised in the meeting that that style is especially painful when you're returning something that's generated on the fly (like some strings) and you have to generate the exact same string twice or somehow cache it. It's a little heavyweight with the refcounting, but anyway right now we only have a few cases like this (AdapterProperties, SupportedLimits/EnumerateFeatures, ?) so I think it's fine. |
I think I'm neutral about it because the extra object still feels unnecessary to me:
|
In last thursday's meeting we settled on the following proposal (IIRC - it's been a few days):
struct WGPUGetMappedRangeError {
char const * errorMessage;
}
void * wgpuBufferGetMappedRange(
WGPUBuffer buffer, size_t offset, size_t size, WGPUGetMappedRangeError * Error WGPU_NULLABLE);
void wgpuGetMappedRangeResultFreeMembers(WGPUGetMappedRangeError);
Also considered and rejected:
|
tentatively marking as "has resolution" |
This seems like it could work, it's a bunch of work to implement and makes the C++ wrapper harder to generate, but is otherwise doable. We also need to handle extensible out structures this way. |
What should the behavior be if you write to an output struct multiple times? WGPUAdapterProperties properties{};
wgpuAdapterGetProperties(adapter, &properties);
wgpuAdapterGetProperties(adapter, &properties);
wgpuAdapterGetProperties(adapter, &properties);
wgpuAdapterGetProperties(adapter, &properties); Each call will allocate strings for properties that must be freed with I see two possibilties:
(1) might be surprising for users of the C API, and would also result in invalid frees if the struct isn't zero initialized. Maybe that's fine though because it's C. High-level language bindings will zero init for you. I believe this approach also requires FreeMembers to null out fields so that we don't double-free. I think (2) would be OK so long as:
|
I definitely prefer option 2. There does need to be a valid empty state for wgpu::AdapterProperties so you can create it before passing it to GetProperties. But I'm not sure the destructor actually needs to set it to the empty state in C++, since it's about to get freed? I think I don't quite understand the problem. The chained structs make things a little messy, because even in C++ you have to make sure you don't touch the chain before freeing. Assorted thoughts:
|
Note that with #266, wgpuAdapterPropertiesFreeMembers will be replaced with wgpuAdapterInfoFreeMembers. |
Related to #82
We had a small discussion about
wgpuAdapterGetProperties
. It needs to return a name and some description. When are these going to be freed?It seems to me that we should make the storage totally owned by the user. So they'd provide a pointer and the capacity, and we'd just fill out the storage with some chars.
The text was updated successfully, but these errors were encountered: