diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index f6ac8e08..81af62f7 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -115,6 +115,14 @@ static uint32_t read_u32(const char **ptr) return ret; } +static uint64_t read_u64(const char **ptr) +{ + uint64_t ret; + memcpy(&ret, *ptr, sizeof(ret)); + *ptr += sizeof(ret); + return ret; +} + static float read_float(const char **ptr) { union @@ -502,6 +510,28 @@ int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, return ret; } +static int shdr_parse_features(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, struct vsir_features *f) +{ + const char *data = section->data.code; + const char *ptr = data; + uint64_t flags; + + if (!require_space(0, 1, sizeof(uint64_t), section->data.size)) + { + WARN("Invalid data size %#zx.\n", section->data.size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE, + "SFI0 section size %zu is too small to contain flags.\n", section->data.size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + flags = read_u64(&ptr); + + if (flags & DXBC_SFI0_REQUIRES_ROVS) + f->rovs = true; + + return VKD3D_OK; +} + static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, struct vkd3d_shader_message_context *message_context, void *context) { @@ -558,6 +588,11 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, desc->byte_code_size = section->data.size; break; + case TAG_SFI0: + if ((ret = shdr_parse_features(section, message_context, &desc->features)) < 0) + return ret; + break; + case TAG_AON9: TRACE("Skipping AON9 shader code chunk.\n"); break; diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 71f3c7f1..fed0a3bd 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -10379,6 +10379,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro *input_signature = dxbc_desc->input_signature; *output_signature = dxbc_desc->output_signature; *patch_constant_signature = dxbc_desc->patch_constant_signature; + program->features = dxbc_desc->features; memset(dxbc_desc, 0, sizeof(*dxbc_desc)); block = &sm6->root_block; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index c689f376..c491c17c 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -166,21 +166,6 @@ STATIC_ASSERT(SM4_MAX_SRC_COUNT <= SPIRV_MAX_SRC_COUNT); /* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */ #define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2 -#define VKD3D_SM4_REQUIRES_DOUBLES 0x00000001 -#define VKD3D_SM4_REQUIRES_EARLY_DEPTH_STENCIL 0x00000002 -#define VKD3D_SM4_REQUIRES_UAVS_AT_EVERY_STAGE 0x00000004 -#define VKD3D_SM4_REQUIRES_64_UAVS 0x00000008 -#define VKD3D_SM4_REQUIRES_MINIMUM_PRECISION 0x00000010 -#define VKD3D_SM4_REQUIRES_11_1_DOUBLE_EXTENSIONS 0x00000020 -#define VKD3D_SM4_REQUIRES_11_1_SHADER_EXTENSIONS 0x00000040 -#define VKD3D_SM4_REQUIRES_LEVEL_9_COMPARISON_FILTERING 0x00000080 -#define VKD3D_SM4_REQUIRES_TILED_RESOURCES 0x00000100 -#define VKD3D_SM4_REQUIRES_STENCIL_REF 0x00000200 -#define VKD3D_SM4_REQUIRES_INNER_COVERAGE 0x00000400 -#define VKD3D_SM4_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00000800 -#define VKD3D_SM4_REQUIRES_ROVS 0x00001000 -#define VKD3D_SM4_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x00002000 - enum vkd3d_sm4_opcode { VKD3D_SM4_OP_ADD = 0x00, @@ -2917,6 +2902,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con program->input_signature = dxbc_desc.input_signature; program->output_signature = dxbc_desc.output_signature; program->patch_constant_signature = dxbc_desc.patch_constant_signature; + program->features = dxbc_desc.features; memset(&dxbc_desc, 0, sizeof(dxbc_desc)); /* DXBC stores used masks inverted for output signatures, for some reason. @@ -5006,7 +4992,7 @@ static void tpf_write_sfi0(struct tpf_compiler *tpf) for (unsigned int i = 0; i < extern_resources_count; ++i) { if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) - *flags |= VKD3D_SM4_REQUIRES_ROVS; + *flags |= DXBC_SFI0_REQUIRES_ROVS; } sm4_free_extern_resources(extern_resources, extern_resources_count); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index c4c52476..c25c0041 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1125,6 +1125,12 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, enum vkd3d_shader_sysval_semantic sysval, unsigned int semantic_index, unsigned int *element_index); void shader_signature_cleanup(struct shader_signature *signature); +struct vsir_features +{ + /* The shader requires rasteriser-ordered views. */ + bool rovs; +}; + struct dxbc_shader_desc { const uint32_t *byte_code; @@ -1133,6 +1139,7 @@ struct dxbc_shader_desc struct shader_signature input_signature; struct shader_signature output_signature; struct shader_signature patch_constant_signature; + struct vsir_features features; }; struct vkd3d_shader_register_semantic @@ -1437,6 +1444,8 @@ struct vsir_program enum vkd3d_tessellator_domain tess_domain; uint32_t io_dcls[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]; + struct vsir_features features; + const char **block_names; size_t block_name_count; }; @@ -1947,6 +1956,21 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, #define DXBC_MAX_SECTION_COUNT 7 +#define DXBC_SFI0_REQUIRES_DOUBLES 0x00000001u +#define DXBC_SFI0_REQUIRES_EARLY_DEPTH_STENCIL 0x00000002u +#define DXBC_SFI0_REQUIRES_UAVS_AT_EVERY_STAGE 0x00000004u +#define DXBC_SFI0_REQUIRES_64_UAVS 0x00000008u +#define DXBC_SFI0_REQUIRES_MINIMUM_PRECISION 0x00000010u +#define DXBC_SFI0_REQUIRES_11_1_DOUBLE_EXTENSIONS 0x00000020u +#define DXBC_SFI0_REQUIRES_11_1_SHADER_EXTENSIONS 0x00000040u +#define DXBC_SFI0_REQUIRES_LEVEL_9_COMPARISON_FILTERING 0x00000080u +#define DXBC_SFI0_REQUIRES_TILED_RESOURCES 0x00000100u +#define DXBC_SFI0_REQUIRES_STENCIL_REF 0x00000200u +#define DXBC_SFI0_REQUIRES_INNER_COVERAGE 0x00000400u +#define DXBC_SFI0_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00000800u +#define DXBC_SFI0_REQUIRES_ROVS 0x00001000u +#define DXBC_SFI0_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x00002000u + struct dxbc_writer { unsigned int section_count;