Closed danielchasehooper closed 7 months ago
Yes that sounds like a good fix. If you prepare a PR I can merge that quickly.
This looks a bit concerning though in the NSString creation: initWithBytesNoCopy:label
. This looks to me like the NSString object is pointing into the original string data (which would work fine if the label is a static C string, but not otherwise).
For something as low-frequency as a pass it's ok to have the NSString copy the string data over.
I wonder though... let me check something one sec...
I think I have a better idea... sg_pass_desc
already has a label field, but that isn't used in _sg_mtl_create_pass()
(because Metal has no "pass resource objects").
Here's my suggestion:
Store the label in the _sg_mtl_pass_t
struct, e.g. change _sg_mtl_pass_t
like this:
typedef struct {
_sg_slot_t slot;
_sg_pass_common_t cmn;
struct {
_sg_mtl_attachment_t color_atts[SG_MAX_COLOR_ATTACHMENTS];
_sg_mtl_attachment_t resolve_atts[SG_MAX_COLOR_ATTACHMENTS];
_sg_mtl_attachment_t ds_att;
_sg_str_t label;
} mtl;
} _sg_mtl_pass_t
...in _sg_mtl_create_pass()
copy the label string over (sg_strcpy is "safe" in that it will make sure to not overrun the buffer in _sg_str_t
):
#if defined(SOKOL_DEBUG)
if (desc->label) {
_sg_strcpy(&pass->mtl.label, desc->label);
}
#endif
...then in _sg_mtl_begin_pass(), when it's the default pass, use a hardwired "default" label string, otherwise use the string that's stored in the pass object.
If 15 characters for the label isn't enough we can bump _SG_STRING_SIZE (the current max size is probably a bit tight also for the other places where strings are stored).
I think I have a better idea... sg_pass_desc already has a label field, but that isn't used in _sg_mtl_create_pass() (because Metal has no "pass resource objects").
The way I label my pass-as-render-target is not how I want to label my pass-as-series-of-commands (command encoder in metal parlance).
Here is an example of why you want to be able to label a command encoder differently from the texture it's rendering into. Say we have code to perform a gaussian blur that requires 2 intermediate framebuffers and 4 distinct steps:
source framebuffer -> "downscale" -> framebuffer 1 framebuffer 1 -> "blur horizontally" -> framebuffer 2 framebuffer 2 -> "blur vertically" -> framebuffer 1 framebuffer 1 -> "upscale" -> destination framebuffer
In the gpu debugger I would like to see the command encoders for this example scenario labeled as "downscale","blur horizontally", "blur vertically", and "upscale". If sg_begin_pass used the label of the destination sg_pass, then you would see "framebuffer 1"/"framebuffer 2" over and over in the debugger.
In the first image in my above comment, naming encoders based on the sg_pass label would cause all the orange boxes to be labeled as "Surface image.0" – totally unhelpful. Additionally, You can see in my second screenshot above that it is valuable for the render targets (green checkerboard icon) to have separate names from the render encoders (orange picture icons).
I think the double meaning of the word "pass" in sokol_gfx may be a source of confusion. Where you're rendering into and what you're rendering to it are different, but have the same name in sokol's types.
Yeah makes sense. In that case I would prefer to integrate the fix with https://github.com/floooh/sokol/issues/904, since sg_pass_action
also isn't quite the right place IMHO.
With those 'unified passes', the sg_begin_pass
struct would take a new wrapper struct as argument, and this would be the right place for the label.
E.g. for an offscreen-pass:
sg_begin_pass(&(sg_tbd){
.pass = ....,
.pass_action = { ... },
.label = "bla",
});
...and for a "swapchain pass" (don't know yet if I'll call it that):
sg_begin_pass(&(sg_tbd){
.swapchain = sapp_sgswapchain(...), // helper function from sokol_glue.h
.pass_action = { ... },
.label = "blub",
});
Does that make sense?
sure, however you want to package the functionality.
One thing worth considering: I suspect #904 is a long way away from shipping. I can see value in adding label
to sg_pass_action
now so that people can benefit from this straightforward non-breaking change. Since #904 is a breaking change anyway, the label
member can be moved wherever is deemed appropriate at that time.
I'm planning to tackle #904 after taking care of a couple of smaller issues and PRs. At some point I need to get back into 'feature mode' anyway ;)
This is now also fixed since https://github.com/floooh/sokol/pull/985 has been merged.
Sokol uses the word
pass
for two things:sg_make_pass
sg_pass_begin
Currently you can label the first kind of pass and that shows up in Metal GPU Debugger, but there is no way to label the second kind of pass, which would be very useful when debugging.
If you're open to it, I'd be happy to submit a PR that adds a
char *label
member tosg_pass_action
and uses that to populateMTLRenderCommandEncoder.label
and the the other APIs' equivalents, if applicable.In our project, we implemented the below function as a stopgap, and it's super useful. However, I think it'd be more elegant if integrated into
sg_pass_action
How the label appears in the GPU Debugger
and