So it actually doesn't depend on those patches at all. :) This series might have some minor conflicts with that series, but we should simply deal with those once they actually happen; it's entirely possible for this series to go in first.
Yes. Although, I am not sure if you mean that I should drop the first patch, that just renames VKD3D_SM4_SWIZZLE_MASK4 to VKD3D_SM4_SWIZZLE_NONE. Note that this renaming is only a subset of the first patch by Conor. I think that the new name is more appropriate.
I'm not quite as convinced it's an improvement, but the broader point is that it's an unrelated change, and should go in its own MR. It happens to touch some lines that the rest of this series also touches, but that can't be the only reason to include something in a series.
+ if (ctx->profile->major_version >= 4) + { + if (!(ctx->lookup = hlsl_new_sm4_lookup_tables())) + { + vkd3d_free((void *)ctx->source_files[0]); + vkd3d_free(ctx->source_files); + return false; + } + }
I don't hate it, but I think we can do better. In particular, I don't think we need these lookup tables before calling hlsl_sm4_write(), and that means we can just call hlsl_new_sm4_lookup_tables() there, and keep all the lookup table bits local to tpf.c.
I could imagine introducing a structure like this: ```c struct tpf_writer { struct vkd3d_bytecode_buffer buffer; struct vkd3d_sm4_lookup_tables lookup; struct hlsl_ctx *ctx; }; ``` and then passing that to e.g. write_sm4_shdr().
To put this in the broader picture, we'd ultimately like the HLSL compiler to produce a vkd3d_shader_instruction_array structure, and the TPF writer to consume that structure. Ideally the functions writing TPF then wouldn't have direct knowledge about HLSL IR, and wouldn't get passed a hlsl_ctx structure. It'll probably be a while before we get there, but I think we should at least try to avoid exposing TPF details outside tpf.c. Similarly, we probably want to avoid using hlsl_ctx in TPF writer functions that currently don't need it.
@@ -587,6 +595,8 @@ struct vkd3d_shader_sm4_parser struct sm4_index_range_array output_index_ranges; struct sm4_index_range_array patch_constant_index_ranges; + struct vkd3d_sm4_lookup_tables *lookup; + struct vkd3d_shader_parser p; };
I don't think "lookup" needs to be a pointer here, right?
+static const struct vkd3d_sm4_register_type_info register_type_table[] = +{ + {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP}, + {VKD3D_SM4_RT_INPUT, VKD3DSPR_INPUT}, ...
Now that we're no longer accessing register_type_table[] directly, we can make it local to hlsl_new_sm4_lookup_tables().
+static const struct vkd3d_sm4_register_type_info *get_info_from_sm4_register_type( + struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_register_type sm4_type) +{ + assert(sm4_type < VKD3D_SM4_REGISTER_TYPE_COUNT); + return lookup->rt_info_from_sm4[sm4_type]; +} ... @@ -1656,15 +1703,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui token = *(*ptr)++; register_type = (token & VKD3D_SM4_REGISTER_TYPE_MASK) >> VKD3D_SM4_REGISTER_TYPE_SHIFT; - if (register_type >= ARRAY_SIZE(register_type_table) - || register_type_table[register_type] == VKD3DSPR_INVALID) + register_type_info = get_info_from_sm4_register_type(priv->lookup, register_type); + if (!register_type_info) { FIXME("Unhandled register type %#x.\n", register_type); param->type = VKD3DSPR_TEMP; }
You can't do that. "register_type"/"sm4_type" is read from the bytecode, which is untrusted input. The existing code is perhaps not great in this regard either, but replacing the existing check with an assert makes it worse.