vkd3d-shader/dxbc: Parse the SFI0 ROV requirement.

This commit is contained in:
Francisco Casas 2024-12-05 21:19:04 -03:00 committed by Henri Verbeet
parent b484288a82
commit d9c4a257c2
Notes: Henri Verbeet 2024-12-09 16:18:05 +01:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1287
4 changed files with 62 additions and 16 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;