mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader: Introduce an API to retrieve all signatures from DXBC shaders.
This commit is contained in:
parent
7b9eb8d189
commit
20190a1388
Notes:
Alexandre Julliard
2023-06-27 23:33:23 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/200
@ -85,6 +85,11 @@ enum vkd3d_shader_structure_type
|
|||||||
* \since 1.3
|
* \since 1.3
|
||||||
*/
|
*/
|
||||||
VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO,
|
VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO,
|
||||||
|
/**
|
||||||
|
* The structure is a vkd3d_shader_scan_signature_info structure.
|
||||||
|
* \since 1.9
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO,
|
||||||
|
|
||||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
||||||
};
|
};
|
||||||
@ -1551,6 +1556,44 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com
|
|||||||
| ((w & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(3));
|
| ((w & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chained structure containing descriptions of shader inputs and outputs.
|
||||||
|
*
|
||||||
|
* This structure is currently implemented only for DXBC source types. For DXBC
|
||||||
|
* shaders, the returned information is parsed directly from the signatures
|
||||||
|
* embedded in the DXBC shader. For all other shader types, the structure is
|
||||||
|
* zeroed.
|
||||||
|
*
|
||||||
|
* All members (except for \ref type and \ref next) are output-only.
|
||||||
|
*
|
||||||
|
* This structure is passed to vkd3d_shader_scan() and extends
|
||||||
|
* vkd3d_shader_compile_info.
|
||||||
|
*
|
||||||
|
* Members of this structure are allocated by vkd3d-shader and should be freed
|
||||||
|
* with vkd3d_shader_free_scan_signature_info() when no longer needed.
|
||||||
|
*
|
||||||
|
* All signatures may contain pointers into the input shader, and should only
|
||||||
|
* be accessed while the input shader remains valid.
|
||||||
|
*
|
||||||
|
* \since 1.9
|
||||||
|
*/
|
||||||
|
struct vkd3d_shader_scan_signature_info
|
||||||
|
{
|
||||||
|
/** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO. */
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
/** Optional pointer to a structure containing further parameters. */
|
||||||
|
const void *next;
|
||||||
|
|
||||||
|
/** The shader input varyings. */
|
||||||
|
struct vkd3d_shader_signature input;
|
||||||
|
|
||||||
|
/** The shader output varyings. */
|
||||||
|
struct vkd3d_shader_signature output;
|
||||||
|
|
||||||
|
/** The shader patch constant varyings. */
|
||||||
|
struct vkd3d_shader_signature patch_constant;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef LIBVKD3D_SHADER_SOURCE
|
#ifdef LIBVKD3D_SHADER_SOURCE
|
||||||
# define VKD3D_SHADER_API VKD3D_EXPORT
|
# define VKD3D_SHADER_API VKD3D_EXPORT
|
||||||
#else
|
#else
|
||||||
@ -1625,6 +1668,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
|
|||||||
* following chained structures:
|
* following chained structures:
|
||||||
* - vkd3d_shader_interface_info
|
* - vkd3d_shader_interface_info
|
||||||
* - vkd3d_shader_scan_descriptor_info
|
* - vkd3d_shader_scan_descriptor_info
|
||||||
|
* - vkd3d_shader_scan_signature_info
|
||||||
* - vkd3d_shader_spirv_domain_shader_target_info
|
* - vkd3d_shader_spirv_domain_shader_target_info
|
||||||
* - vkd3d_shader_spirv_target_info
|
* - vkd3d_shader_spirv_target_info
|
||||||
* - vkd3d_shader_transform_feedback_info
|
* - vkd3d_shader_transform_feedback_info
|
||||||
@ -1811,6 +1855,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver
|
|||||||
* \n
|
* \n
|
||||||
* The DXBC_TPF scanner supports the following chained structures:
|
* The DXBC_TPF scanner supports the following chained structures:
|
||||||
* - vkd3d_shader_scan_descriptor_info
|
* - vkd3d_shader_scan_descriptor_info
|
||||||
|
* - vkd3d_shader_scan_signature_info
|
||||||
* \n
|
* \n
|
||||||
* Although the \a compile_info parameter is read-only, chained structures
|
* Although the \a compile_info parameter is read-only, chained structures
|
||||||
* passed to this function need not be, and may serve as output parameters,
|
* passed to this function need not be, and may serve as output parameters,
|
||||||
@ -1847,12 +1892,18 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info(
|
|||||||
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
|
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the input signature of a compiled shader, returning a structural
|
* Read the input signature of a compiled DXBC shader, returning a structural
|
||||||
* description which can be easily parsed by C code.
|
* description which can be easily parsed by C code.
|
||||||
*
|
*
|
||||||
* This function parses a compiled shader. To parse a standalone root signature,
|
* This function parses a compiled shader. To parse a standalone root signature,
|
||||||
* use vkd3d_shader_parse_root_signature().
|
* use vkd3d_shader_parse_root_signature().
|
||||||
*
|
*
|
||||||
|
* This function only parses DXBC shaders, and only retrieves the input
|
||||||
|
* signature. To retrieve signatures from other shader types, or other signature
|
||||||
|
* types, use vkd3d_shader_scan() and struct vkd3d_shader_scan_signature_info.
|
||||||
|
* This function returns the same input signature that is returned in
|
||||||
|
* struct vkd3d_shader_scan_signature_info.
|
||||||
|
*
|
||||||
* \param dxbc Compiled byte code, in DXBC format.
|
* \param dxbc Compiled byte code, in DXBC format.
|
||||||
*
|
*
|
||||||
* \param signature Output location in which the parsed root signature will be
|
* \param signature Output location in which the parsed root signature will be
|
||||||
@ -2042,6 +2093,19 @@ VKD3D_SHADER_API int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxb
|
|||||||
VKD3D_SHADER_API int vkd3d_shader_serialize_dxbc(size_t section_count,
|
VKD3D_SHADER_API int vkd3d_shader_serialize_dxbc(size_t section_count,
|
||||||
const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages);
|
const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free members of struct vkd3d_shader_scan_signature_info allocated by
|
||||||
|
* vkd3d_shader_scan().
|
||||||
|
*
|
||||||
|
* This function may free members of vkd3d_shader_scan_signature_info, but
|
||||||
|
* does not free the structure itself.
|
||||||
|
*
|
||||||
|
* \param info Scan information to free.
|
||||||
|
*
|
||||||
|
* \since 1.9
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_API void vkd3d_shader_free_scan_signature_info(struct vkd3d_shader_scan_signature_info *info);
|
||||||
|
|
||||||
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
|
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
|
||||||
|
|
||||||
/** Type of vkd3d_shader_get_version(). */
|
/** Type of vkd3d_shader_get_version(). */
|
||||||
@ -2107,6 +2171,9 @@ typedef int (*PFN_vkd3d_shader_parse_dxbc)(const struct vkd3d_shader_code *dxbc,
|
|||||||
typedef int (*PFN_vkd3d_shader_serialize_dxbc)(size_t section_count,
|
typedef int (*PFN_vkd3d_shader_serialize_dxbc)(size_t section_count,
|
||||||
const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages);
|
const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages);
|
||||||
|
|
||||||
|
/** Type of vkd3d_shader_free_scan_signature_info(). \since 1.9 */
|
||||||
|
typedef void (*PFN_vkd3d_shader_free_scan_signature_info)(struct vkd3d_shader_scan_signature_info *info);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -8,6 +8,7 @@ global:
|
|||||||
vkd3d_shader_free_messages;
|
vkd3d_shader_free_messages;
|
||||||
vkd3d_shader_free_root_signature;
|
vkd3d_shader_free_root_signature;
|
||||||
vkd3d_shader_free_scan_descriptor_info;
|
vkd3d_shader_free_scan_descriptor_info;
|
||||||
|
vkd3d_shader_free_scan_signature_info;
|
||||||
vkd3d_shader_free_shader_code;
|
vkd3d_shader_free_shader_code;
|
||||||
vkd3d_shader_free_shader_signature;
|
vkd3d_shader_free_shader_signature;
|
||||||
vkd3d_shader_get_supported_source_types;
|
vkd3d_shader_get_supported_source_types;
|
||||||
|
@ -440,6 +440,18 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
|
|||||||
shader_get_source_type_suffix(source_type), shader->code, shader->size);
|
shader_get_source_type_suffix(source_type), shader->code, shader->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_scan_signature_info(const struct vkd3d_shader_compile_info *info)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_scan_signature_info *signature_info;
|
||||||
|
|
||||||
|
if ((signature_info = vkd3d_find_struct(info->next, SCAN_SIGNATURE_INFO)))
|
||||||
|
{
|
||||||
|
memset(&signature_info->input, 0, sizeof(signature_info->input));
|
||||||
|
memset(&signature_info->output, 0, sizeof(signature_info->output));
|
||||||
|
memset(&signature_info->patch_constant, 0, sizeof(signature_info->patch_constant));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
||||||
struct vkd3d_shader_message_context *message_context, const char *source_name,
|
struct vkd3d_shader_message_context *message_context, const char *source_name,
|
||||||
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
|
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
|
||||||
@ -526,6 +538,43 @@ void vkd3d_shader_free_messages(char *messages)
|
|||||||
vkd3d_free(messages);
|
vkd3d_free(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_signature *signature,
|
||||||
|
const struct shader_signature *src)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
signature->element_count = src->element_count;
|
||||||
|
if (!src->elements)
|
||||||
|
{
|
||||||
|
assert(!signature->element_count);
|
||||||
|
signature->elements = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(signature->elements = vkd3d_calloc(signature->element_count, sizeof(*signature->elements))))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = 0; i < signature->element_count; ++i)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_signature_element *d = &signature->elements[i];
|
||||||
|
struct signature_element *e = &src->elements[i];
|
||||||
|
|
||||||
|
d->semantic_name = e->semantic_name;
|
||||||
|
d->semantic_index = e->semantic_index;
|
||||||
|
d->stream_index = e->stream_index;
|
||||||
|
d->sysval_semantic = e->sysval_semantic;
|
||||||
|
d->component_type = e->component_type;
|
||||||
|
d->register_index = e->register_index;
|
||||||
|
if (e->register_count > 1)
|
||||||
|
FIXME("Arrayed elements are not supported yet.\n");
|
||||||
|
d->mask = e->mask;
|
||||||
|
d->used_mask = e->used_mask;
|
||||||
|
d->min_precision = e->min_precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct vkd3d_shader_scan_context
|
struct vkd3d_shader_scan_context
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
|
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
|
||||||
@ -1070,6 +1119,7 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
|
|||||||
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser)
|
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
|
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
|
||||||
|
struct vkd3d_shader_scan_signature_info *signature_info;
|
||||||
struct vkd3d_shader_instruction *instruction;
|
struct vkd3d_shader_instruction *instruction;
|
||||||
struct vkd3d_shader_scan_context context;
|
struct vkd3d_shader_scan_context context;
|
||||||
int ret = VKD3D_OK;
|
int ret = VKD3D_OK;
|
||||||
@ -1080,6 +1130,7 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
|
|||||||
scan_descriptor_info->descriptors = NULL;
|
scan_descriptor_info->descriptors = NULL;
|
||||||
scan_descriptor_info->descriptor_count = 0;
|
scan_descriptor_info->descriptor_count = 0;
|
||||||
}
|
}
|
||||||
|
signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO);
|
||||||
|
|
||||||
vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
|
vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
|
||||||
|
|
||||||
@ -1099,6 +1150,21 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ret && signature_info)
|
||||||
|
{
|
||||||
|
if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &parser->shader_desc.input_signature)
|
||||||
|
|| !vkd3d_shader_signature_from_shader_signature(&signature_info->output,
|
||||||
|
&parser->shader_desc.output_signature)
|
||||||
|
|| !vkd3d_shader_signature_from_shader_signature(&signature_info->patch_constant,
|
||||||
|
&parser->shader_desc.patch_constant_signature))
|
||||||
|
{
|
||||||
|
vkd3d_shader_free_scan_signature_info(signature_info);
|
||||||
|
if (scan_descriptor_info)
|
||||||
|
vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
|
||||||
|
ret = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vkd3d_shader_scan_context_cleanup(&context);
|
vkd3d_shader_scan_context_cleanup(&context);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1152,6 +1218,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
|
|||||||
if ((ret = vkd3d_shader_validate_compile_info(compile_info, false)) < 0)
|
if ((ret = vkd3d_shader_validate_compile_info(compile_info, false)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
init_scan_signature_info(compile_info);
|
||||||
|
|
||||||
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
|
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
|
||||||
|
|
||||||
switch (compile_info->source_type)
|
switch (compile_info->source_type)
|
||||||
@ -1305,6 +1373,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|||||||
if ((ret = vkd3d_shader_validate_compile_info(compile_info, true)) < 0)
|
if ((ret = vkd3d_shader_validate_compile_info(compile_info, true)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
init_scan_signature_info(compile_info);
|
||||||
|
|
||||||
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
|
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
|
||||||
|
|
||||||
switch (compile_info->source_type)
|
switch (compile_info->source_type)
|
||||||
@ -1339,6 +1409,15 @@ void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_
|
|||||||
vkd3d_free(scan_descriptor_info->descriptors);
|
vkd3d_free(scan_descriptor_info->descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vkd3d_shader_free_scan_signature_info(struct vkd3d_shader_scan_signature_info *info)
|
||||||
|
{
|
||||||
|
TRACE("info %p.\n", info);
|
||||||
|
|
||||||
|
vkd3d_shader_free_shader_signature(&info->input);
|
||||||
|
vkd3d_shader_free_shader_signature(&info->output);
|
||||||
|
vkd3d_shader_free_shader_signature(&info->patch_constant);
|
||||||
|
}
|
||||||
|
|
||||||
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
|
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
|
||||||
{
|
{
|
||||||
TRACE("shader_code %p.\n", shader_code);
|
TRACE("shader_code %p.\n", shader_code);
|
||||||
@ -1401,43 +1480,6 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu
|
|||||||
desc->version = 0;
|
desc->version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_signature *signature,
|
|
||||||
const struct shader_signature *src)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
signature->element_count = src->element_count;
|
|
||||||
if (!src->elements)
|
|
||||||
{
|
|
||||||
assert(!signature->element_count);
|
|
||||||
signature->elements = NULL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(signature->elements = vkd3d_calloc(signature->element_count, sizeof(*signature->elements))))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (i = 0; i < signature->element_count; ++i)
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_signature_element *d = &signature->elements[i];
|
|
||||||
struct signature_element *e = &src->elements[i];
|
|
||||||
|
|
||||||
d->semantic_name = e->semantic_name;
|
|
||||||
d->semantic_index = e->semantic_index;
|
|
||||||
d->stream_index = e->stream_index;
|
|
||||||
d->sysval_semantic = e->sysval_semantic;
|
|
||||||
d->component_type = e->component_type;
|
|
||||||
d->register_index = e->register_index;
|
|
||||||
if (e->register_count > 1)
|
|
||||||
FIXME("Arrayed elements are not supported yet.\n");
|
|
||||||
d->mask = e->mask;
|
|
||||||
d->used_mask = e->used_mask;
|
|
||||||
d->min_precision = e->min_precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_signature_cleanup(struct shader_signature *signature)
|
void shader_signature_cleanup(struct shader_signature *signature)
|
||||||
{
|
{
|
||||||
vkd3d_free(signature->elements);
|
vkd3d_free(signature->elements);
|
||||||
|
@ -401,6 +401,192 @@ static void test_dxbc(void)
|
|||||||
vkd3d_shader_free_shader_code(&dxbc);
|
vkd3d_shader_free_shader_code(&dxbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_signature_element(const struct vkd3d_shader_signature_element *element,
|
||||||
|
const struct vkd3d_shader_signature_element *expect)
|
||||||
|
{
|
||||||
|
ok(!strcmp(element->semantic_name, expect->semantic_name), "Got semantic name %s.\n", element->semantic_name);
|
||||||
|
ok(element->semantic_index == expect->semantic_index, "Got semantic index %u.\n", element->semantic_index);
|
||||||
|
ok(element->stream_index == expect->stream_index, "Got stream index %u.\n", element->stream_index);
|
||||||
|
ok(element->sysval_semantic == expect->sysval_semantic, "Got sysval semantic %#x.\n", element->sysval_semantic);
|
||||||
|
ok(element->component_type == expect->component_type, "Got component type %#x.\n", element->component_type);
|
||||||
|
ok(element->register_index == expect->register_index, "Got register index %u.\n", element->register_index);
|
||||||
|
ok(element->mask == expect->mask, "Got mask %#x.\n", element->mask);
|
||||||
|
todo_if (expect->used_mask != expect->mask)
|
||||||
|
ok(element->used_mask == expect->used_mask, "Got used mask %#x.\n", element->used_mask);
|
||||||
|
ok(element->min_precision == expect->min_precision, "Got minimum precision %#x.\n", element->min_precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_scan_signatures(void)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_scan_signature_info signature_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO};
|
||||||
|
struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
|
||||||
|
struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
||||||
|
struct vkd3d_shader_code dxbc;
|
||||||
|
size_t i, j;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
static const char vs1_source[] =
|
||||||
|
"void main(\n"
|
||||||
|
" in float4 a : apple,\n"
|
||||||
|
" out float4 b : banana2,\n"
|
||||||
|
" inout float4 c : color,\n"
|
||||||
|
" inout float4 d : depth,\n"
|
||||||
|
" inout float4 e : sv_position,\n"
|
||||||
|
" in uint3 f : fruit,\n"
|
||||||
|
" inout bool2 g : grape,\n"
|
||||||
|
" in int h : honeydew,\n"
|
||||||
|
" in uint i : sv_vertexid)\n"
|
||||||
|
"{\n"
|
||||||
|
" b.yw = a.xz;\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element vs1_inputs[] =
|
||||||
|
{
|
||||||
|
{"apple", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0x5},
|
||||||
|
{"color", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||||
|
{"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||||
|
{"sv_position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||||
|
{"fruit", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 4, 0x7},
|
||||||
|
{"grape", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 5, 0x3, 0x3},
|
||||||
|
{"honeydew", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_INT, 6, 0x1},
|
||||||
|
{"sv_vertexid", 0, 0, VKD3D_SHADER_SV_VERTEX_ID, VKD3D_SHADER_COMPONENT_UINT, 7, 0x1},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element vs1_outputs[] =
|
||||||
|
{
|
||||||
|
{"banana", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xa},
|
||||||
|
{"color", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||||
|
{"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||||
|
{"sv_position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||||
|
{"grape", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 4, 0x3, 0x3},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char vs2_source[] =
|
||||||
|
"void main(inout float4 pos : position)\n"
|
||||||
|
"{\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element vs2_inputs[] =
|
||||||
|
{
|
||||||
|
{"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element vs2_outputs[] =
|
||||||
|
{
|
||||||
|
{"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char ps1_source[] =
|
||||||
|
"void main(\n"
|
||||||
|
" in float2 a : apple,\n"
|
||||||
|
" out float4 b : sv_target2,\n"
|
||||||
|
" out float c : sv_depth,\n"
|
||||||
|
" in float4 d : position,\n"
|
||||||
|
" in float4 e : sv_position)\n"
|
||||||
|
"{\n"
|
||||||
|
" b = d;\n"
|
||||||
|
" c = 0;\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element ps1_inputs[] =
|
||||||
|
{
|
||||||
|
{"apple", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0x3},
|
||||||
|
{"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||||
|
{"sv_position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_signature_element ps1_outputs[] =
|
||||||
|
{
|
||||||
|
{"sv_target", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||||
|
{"sv_depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, ~0u, 0x1, 0x1},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char cs1_source[] =
|
||||||
|
"[numthreads(1, 1, 1)]\n"
|
||||||
|
"void main(\n"
|
||||||
|
" in uint a : sv_dispatchthreadid,\n"
|
||||||
|
" in uint b : sv_groupid,\n"
|
||||||
|
" in uint c : sv_groupthreadid)\n"
|
||||||
|
"{\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const char *source;
|
||||||
|
const char *profile;
|
||||||
|
const struct vkd3d_shader_signature_element *inputs;
|
||||||
|
size_t input_count;
|
||||||
|
const struct vkd3d_shader_signature_element *outputs;
|
||||||
|
size_t output_count;
|
||||||
|
const struct vkd3d_shader_signature_element *patch_constants;
|
||||||
|
size_t patch_constant_count;
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
{vs1_source, "vs_4_0", vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
|
||||||
|
{vs2_source, "vs_4_0", vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)},
|
||||||
|
{ps1_source, "ps_4_0", ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)},
|
||||||
|
{cs1_source, "cs_5_0", NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tests); ++i)
|
||||||
|
{
|
||||||
|
vkd3d_test_push_context("test %u", i);
|
||||||
|
|
||||||
|
compile_info.source.code = tests[i].source;
|
||||||
|
compile_info.source.size = strlen(tests[i].source);
|
||||||
|
compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
|
||||||
|
compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
|
||||||
|
compile_info.log_level = VKD3D_SHADER_LOG_INFO;
|
||||||
|
|
||||||
|
compile_info.next = &hlsl_info;
|
||||||
|
hlsl_info.profile = tests[i].profile;
|
||||||
|
|
||||||
|
rc = vkd3d_shader_compile(&compile_info, &dxbc, NULL);
|
||||||
|
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
|
||||||
|
|
||||||
|
compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||||
|
compile_info.source = dxbc;
|
||||||
|
|
||||||
|
compile_info.next = &signature_info;
|
||||||
|
|
||||||
|
rc = vkd3d_shader_scan(&compile_info, NULL);
|
||||||
|
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
|
||||||
|
|
||||||
|
ok(signature_info.input.element_count == tests[i].input_count,
|
||||||
|
"Got input count %u.\n", signature_info.input.element_count);
|
||||||
|
for (j = 0; j < signature_info.input.element_count; ++j)
|
||||||
|
{
|
||||||
|
vkd3d_test_push_context("input %u", j);
|
||||||
|
check_signature_element(&signature_info.input.elements[j], &tests[i].inputs[j]);
|
||||||
|
vkd3d_test_pop_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(signature_info.output.element_count == tests[i].output_count,
|
||||||
|
"Got output count %u.\n", signature_info.output.element_count);
|
||||||
|
for (j = 0; j < signature_info.output.element_count; ++j)
|
||||||
|
{
|
||||||
|
vkd3d_test_push_context("output %u", j);
|
||||||
|
check_signature_element(&signature_info.output.elements[j], &tests[i].outputs[j]);
|
||||||
|
vkd3d_test_pop_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(signature_info.patch_constant.element_count == tests[i].patch_constant_count,
|
||||||
|
"Got patch constant count %u.\n", signature_info.patch_constant.element_count);
|
||||||
|
for (j = 0; j < signature_info.patch_constant.element_count; ++j)
|
||||||
|
{
|
||||||
|
vkd3d_test_push_context("patch constant %u", j);
|
||||||
|
check_signature_element(&signature_info.patch_constant.elements[j], &tests[i].patch_constants[j]);
|
||||||
|
vkd3d_test_pop_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
vkd3d_shader_free_scan_signature_info(&signature_info);
|
||||||
|
vkd3d_shader_free_shader_code(&dxbc);
|
||||||
|
|
||||||
|
vkd3d_test_pop_context();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(vkd3d_shader_api)
|
START_TEST(vkd3d_shader_api)
|
||||||
{
|
{
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
@ -410,4 +596,5 @@ START_TEST(vkd3d_shader_api)
|
|||||||
run_test(test_version);
|
run_test(test_version);
|
||||||
run_test(test_d3dbc);
|
run_test(test_d3dbc);
|
||||||
run_test(test_dxbc);
|
run_test(test_dxbc);
|
||||||
|
run_test(test_scan_signatures);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user