Skip to content
Snippets Groups Projects
Unverified Commit 5d689896 authored by Giovanni Mascellani's avatar Giovanni Mascellani
Browse files

vkd3d-shader/d3d-asm: Support emitting the shader signature.

parent b5cff85e
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !553. Comments created here will be created in the context of that merge request.
......@@ -271,6 +271,17 @@ enum vkd3d_shader_compile_option_name
* \since 1.11
*/
VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,
/**
* If \a value is nonzero, emit the input and output signature
* when disassembling a shader.
*
* This option is supported by vkd3d_shader_compile() when using
* D3D_BYTECODE, DXBC_TPF or DXBC_DXIL as source and D3D_ASM as
* target; it should not be enabled otherwise.
*
* \since 1.11
*/
VKD3D_SHADER_COMPILE_OPTION_EMIT_SIGNATURE = 0x0000000b,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
......
......@@ -1960,9 +1960,107 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_addline(buffer, "\n");
}
static const char *get_sysval_semantic_name(enum vkd3d_shader_sysval_semantic semantic)
{
switch (semantic)
{
case VKD3D_SHADER_SV_NONE: return NULL;
case VKD3D_SHADER_SV_POSITION: return "POS";
case VKD3D_SHADER_SV_CLIP_DISTANCE: return "CLIPDST";
case VKD3D_SHADER_SV_CULL_DISTANCE: return "CULLDST";
case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: return "RTINDEX";
case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: return "VPINDEX";
case VKD3D_SHADER_SV_VERTEX_ID: return "VERTID";
case VKD3D_SHADER_SV_PRIMITIVE_ID: return "PRIMID";
case VKD3D_SHADER_SV_INSTANCE_ID: return "INSTID";
case VKD3D_SHADER_SV_IS_FRONT_FACE: return "FFACE";
case VKD3D_SHADER_SV_SAMPLE_INDEX: return "SAMPLE";
case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: return "QUADEDGE";
case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: return "QUADINT";
case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: return "TRIEDGE";
case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: return "TRIINT";
case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: return "LINEDET";
case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: return "LINEDEN";
case VKD3D_SHADER_SV_TARGET: return "TARGET";
case VKD3D_SHADER_SV_DEPTH: return "DEPTH";
case VKD3D_SHADER_SV_COVERAGE: return "COVERAGE";
case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "DEPTHGE";
case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "DEPTHLE";
case VKD3D_SHADER_SV_STENCIL_REF: return "STENCILREF";
default: return "??";
}
}
static const char *get_component_type_name(enum vkd3d_shader_component_type type)
{
switch (type)
{
case VKD3D_SHADER_COMPONENT_VOID: return "void";
case VKD3D_SHADER_COMPONENT_UINT: return "uint";
case VKD3D_SHADER_COMPONENT_INT: return "int";
case VKD3D_SHADER_COMPONENT_FLOAT: return "float";
case VKD3D_SHADER_COMPONENT_BOOL: return "bool";
case VKD3D_SHADER_COMPONENT_DOUBLE: return "double";
case VKD3D_SHADER_COMPONENT_UINT64: return "uint64";
default: return "??";
}
}
static enum vkd3d_result dump_signature(const struct shader_signature *signature,
struct vkd3d_string_buffer *buffer)
{
unsigned int i;
char tmp[5];
for (i = 0; i < signature->element_count; ++i)
{
struct signature_element *element = &signature->elements[i];
const char *sysval_semantic = get_sysval_semantic_name(element->sysval_semantic);
vkd3d_string_buffer_printf(buffer, ".param %s",
element->semantic_name);
if (element->semantic_index != 0)
vkd3d_string_buffer_printf(buffer, "%u", element->semantic_index);
vkd3d_string_buffer_printf(buffer, ".%s, v%d.%s, %s",
dump_write_mask(tmp, element->mask),
element->register_index, dump_write_mask(tmp, element->used_mask),
get_component_type_name(element->component_type));
if (sysval_semantic)
vkd3d_string_buffer_printf(buffer, ", %s", sysval_semantic);
vkd3d_string_buffer_printf(buffer, "\n");
}
return VKD3D_OK;
}
static enum vkd3d_result dump_signatures(const struct vkd3d_shader_desc *shader_desc,
struct vkd3d_string_buffer *buffer)
{
enum vkd3d_result ret;
vkd3d_string_buffer_printf(buffer, ".section ISGN\n");
ret = dump_signature(&shader_desc->input_signature, buffer);
if (ret >= 0)
{
vkd3d_string_buffer_printf(buffer, ".section OSGN\n");
ret = dump_signature(&shader_desc->output_signature, buffer);
}
if (ret >= 0)
vkd3d_string_buffer_printf(buffer, ".section SHEX\n");
return ret;
}
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, enum vsir_asm_flags flags)
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_desc *shader_desc,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
enum vsir_asm_flags flags)
{
enum vkd3d_shader_compile_option_formatting_flags formatting;
struct vkd3d_d3d_asm_compiler compiler =
......@@ -2024,6 +2122,15 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
buffer = &compiler.buffer;
vkd3d_string_buffer_init(buffer);
if (flags & VSIR_ASM_FLAG_EMIT_SIGNATURE)
{
if ((result = dump_signatures(shader_desc, buffer)) < 0)
{
vkd3d_string_buffer_cleanup(buffer);
return result;
}
}
compiler.shader_version = *shader_version;
shader_version = &compiler.shader_version;
vkd3d_string_buffer_printf(buffer, "%s%s_%u_%u%s\n", compiler.colours.version,
......@@ -2082,7 +2189,7 @@ void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instruction
const char *p, *q, *end;
struct vkd3d_shader_code code;
if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code, VSIR_ASM_FLAG_DUMP_TYPES) != VKD3D_OK)
if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, NULL, &code, VSIR_ASM_FLAG_DUMP_TYPES) != VKD3D_OK)
return;
end = (const char *)code.code + code.size;
......
......@@ -1552,6 +1552,21 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
return ret;
}
static enum vsir_asm_flags asm_flags_from_compile_info(const struct vkd3d_shader_compile_info *compile_info)
{
enum vsir_asm_flags ret = VSIR_ASM_FLAG_NONE;
unsigned int i;
for (i = 0; i < compile_info->option_count; ++i)
{
if (compile_info->options[i].name == VKD3D_SHADER_COMPILE_OPTION_EMIT_SIGNATURE
&& compile_info->options[i].value)
ret |= VSIR_ASM_FLAG_EMIT_SIGNATURE;
}
return ret;
}
static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
......@@ -1566,7 +1581,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_FLAG_NONE);
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version,
&parser->shader_desc, compile_info, out, asm_flags_from_compile_info(compile_info));
break;
case VKD3D_SHADER_TARGET_GLSL:
......
......@@ -1328,11 +1328,13 @@ enum vsir_asm_flags
{
VSIR_ASM_FLAG_NONE = 0,
VSIR_ASM_FLAG_DUMP_TYPES = 0x1,
VSIR_ASM_FLAG_EMIT_SIGNATURE = 0x2,
};
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, enum vsir_asm_flags flags);
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_desc *shader_desc,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
enum vsir_asm_flags flags);
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment