I think it's close, but not entirely what I had in mind. You can avoid both the callback and some of the data copies if you just let parse_dxbc() create a list / array of sections. So you'd have something like this:
struct dxbc_section { DWORD tag; const char *data; SIZE_T data_size; };
struct dxbc { UINT section_size; UINT section_count; struct dxbc_section *sections; };
with parse_dxbc() just calling something like dxbc_add_section() instead of chunk_handler(). The sections can just refer to the original data in the dxbc blob, it's then the responsibility of the caller to either make sure that data stays around for as long as the sections are needed or make a copy of the data.
d3dcompiler_get_blob_part() would then just iterate over all the sections and add the relevant ones to a second dxbc struct, which it would pass to dxbc_write_blob() afterwards. I don't think dxbc_remove_section() is very useful in general, you'll pretty much always just want to add sections to a new section list. It's also simply unused in your current patch. dxbc_release() should be called dxbc_destroy(), you're not doing any reference counting, and the naming would be more consistent if you renamed parse_dxbc() to dxbc_parse().
Am 20.09.2010 13:09, schrieb Henri Verbeet:
I think it's close, but not entirely what I had in mind. You can avoid both the callback and some of the data copies if you just let parse_dxbc() create a list / array of sections. So you'd have something like this:
struct dxbc_section { DWORD tag; const char *data; SIZE_T data_size; };
struct dxbc { UINT section_size; UINT section_count; struct dxbc_section *sections; };
with parse_dxbc() just calling something like dxbc_add_section() instead of chunk_handler(). The sections can just refer to the original data in the dxbc blob, it's then the responsibility of the caller to either make sure that data stays around for as long as the sections are needed or make a copy of the data.
d3dcompiler_get_blob_part() would then just iterate over all the sections and add the relevant ones to a second dxbc struct, which it would pass to dxbc_write_blob() afterwards. I don't think dxbc_remove_section() is very useful in general, you'll pretty much always just want to add sections to a new section list. It's also simply unused in your current patch. dxbc_release() should be called dxbc_destroy(), you're not doing any reference counting, and the naming would be more consistent if you renamed parse_dxbc() to dxbc_parse().
Sure that abroach works pretty well for the D3DGetBlobPart() function, but you it is a bit ugly to use it for the D3DStripShader(). There you have to add some quirks. You would have to parse the dxbc twice to get the correct count (could be != count in dxbc original) and then parse only the needed blob parts. Therefore I added the dxbc_remove_section() function. I've attached all patches so that you could see what D3DStripShader() does.
2010/9/20 Rico Schüller kgbricola@web.de:
Sure that abroach works pretty well for the D3DGetBlobPart() function, but you it is a bit ugly to use it for the D3DStripShader(). There you have to add some quirks. You would have to parse the dxbc twice to get the correct count (could be != count in dxbc original) and then parse only the needed blob parts. Therefore I added the dxbc_remove_section() function. I've attached all patches so that you could see what D3DStripShader() does.
Well, you'd do something like the following:
struct dxbc src_dxbc, dst_dxbc; unsigned int i;
dxbc_init(&src_dxbc); dxbc_init(&dst_dxbc);
dxbc_parse(&src_dxbc, data, data_size);
for (i = 0; i < src_dxbc.section_count; ++i) { struct dxbc_section *s = &src_dxbc.sections[i]; switch (s->tag) { case TAG_SDBG: if (!(flags & D3DCOMPILER_STRIP_DEBUG_INFO)) dxbc_add_section(&dst_dxbc, s->tag, s->data, s->data_size); break;
case TAG_RDEF: case TAG_STAT: if (!(flags & D3DCOMPILER_STRIP_REFLECTION_DATA)) dxbc_add_section(&dst_dxbc, s->tag, s->data, s->data_size); break;
default: dxbc_add_section(&dst_dxbc, s->tag, s->data, s->data_size); break; } }
dxbc_write(&dst_dxbc, blob);
dxbc_destroy(&dst_dxbc); dxbc_destroy(&src_dxbc);
But if it turns out to really be much nicer you could certainly introduce a dxbc_remove_section() function, but I doubt it. In the current patch it's simply dead code though. Somewhat related, do you happen to know if section tags need to be unique within a DXBC? I'd imagine the DXBC format doesn't restrict that, though specific functions may have additional constraints on what is considered a valid input DXBC.
Am 20.09.2010 20:05, schrieb Henri Verbeet:
But if it turns out to really be much nicer you could certainly introduce a dxbc_remove_section() function, but I doubt it. In the current patch it's simply dead code though. Somewhat related, do you happen to know if section tags need to be unique within a DXBC? I'd imagine the DXBC format doesn't restrict that, though specific functions may have additional constraints on what is considered a valid input DXBC.
I have no idea if section codes need to be unique, but I couldn't get a DXBC with not unique items (beside the ones in the effect but which use several shaders as part DXBCs - I wouldn't count that as a DXBC it is more the FX10). I have to admit I haven't tried that specifically.