Do we need the macros?
Instead of using a fixed header size, it depends upon packing of each struct, so the only truly reliable way to get the data is declare a struct. Without the macro the first case becomes:
`case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE:` ` {` ` struct` ` {` ` D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type;` ` ID3D12RootSignature *root_signature;` ` } *subobject = (void *)stream_ptr;` ` desc->root_signature = subobject->root_signature;` ` break;` ` }`
It can be done that way if you prefer.
I think that's a fair bit more readable, yes, thanks.
We may be able to do slightly better though, if we build a table like this: ```c static const struct { size_t alignment; size_t size; size_t dst_offset; } subobject_info[] = { [D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE] = {__alignof__(ID3D12RootSignature *), sizeof(ID3D12RootSignature *), offsetof(struct d3d12_pipeline_state_desc, root_signature)}, [D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS] = {__alignof__(ID3D12RootSignature *), sizeof(D3D12_SHADER_BYTECODE), offsetof(struct d3d12_pipeline_state_desc, vs)}, ... }; ``` and then use that information to copy the data to the right location. We could even use macros to build that table if we're so inclined; I don't think it would be terribly necessary, but the macro in question would be simple enough and save some typing/reading.