From: Giovanni Mascellani gmascellani@codeweavers.com
The format does not correspond to native, but is meant to be easily parsed so that at some point we can introduce an assembler. --- libs/vkd3d-shader/d3d_asm.c | 116 ++++++++++++++++++++--- libs/vkd3d-shader/vkd3d_shader_main.c | 4 +- libs/vkd3d-shader/vkd3d_shader_private.h | 2 + 3 files changed, 109 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 3573a6af0..bef1447e0 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -1304,31 +1304,40 @@ static void shader_dump_reg_type(struct vkd3d_d3d_asm_compiler *compiler, shader_addline(buffer, ">"); }
+static char *dump_write_mask(char buffer[5], uint32_t write_mask) +{ + unsigned int i = 0; + + if (write_mask & VKD3DSP_WRITEMASK_0) + buffer[i++] = 'x'; + if (write_mask & VKD3DSP_WRITEMASK_1) + buffer[i++] = 'y'; + if (write_mask & VKD3DSP_WRITEMASK_2) + buffer[i++] = 'z'; + if (write_mask & VKD3DSP_WRITEMASK_3) + buffer[i++] = 'w'; + + buffer[i++] = '\0'; + + return buffer; +} + static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_dst_param *param, bool is_declaration) { struct vkd3d_string_buffer *buffer = &compiler->buffer; uint32_t write_mask = param->write_mask; + char tmp[5];
shader_dump_register(compiler, ¶m->reg, is_declaration);
if (write_mask && param->reg.dimension == VSIR_DIMENSION_VEC4) { - static const char write_mask_chars[] = "xyzw"; - if (param->reg.data_type == VKD3D_DATA_DOUBLE) write_mask = vsir_write_mask_32_from_64(write_mask);
- shader_addline(buffer, ".%s", compiler->colours.write_mask); - if (write_mask & VKD3DSP_WRITEMASK_0) - shader_addline(buffer, "%c", write_mask_chars[0]); - if (write_mask & VKD3DSP_WRITEMASK_1) - shader_addline(buffer, "%c", write_mask_chars[1]); - if (write_mask & VKD3DSP_WRITEMASK_2) - shader_addline(buffer, "%c", write_mask_chars[2]); - if (write_mask & VKD3DSP_WRITEMASK_3) - shader_addline(buffer, "%c", write_mask_chars[3]); - shader_addline(buffer, "%s", compiler->colours.reset); + shader_addline(buffer, ".%s%s%s", compiler->colours.write_mask, + dump_write_mask(tmp, write_mask), compiler->colours.reset); }
shader_print_precision(compiler, ¶m->reg); @@ -2088,3 +2097,86 @@ void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instruction
vkd3d_string_buffer_cleanup(&buffer); } + +static const char *get_sysval_semantic_name(enum vkd3d_shader_sysval_semantic semantic) +{ + switch (semantic) + { + case VKD3D_SHADER_SV_NONE: return "NONE"; + 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, const char *prefix) +{ + unsigned int i; + char tmp[5]; + + for (i = 0; i < signature->element_count; ++i) + { + struct signature_element *element = &signature->elements[i]; + + vkd3d_string_buffer_printf(buffer, "// !%-6s %-30s %-2u %-4s %-2d %-10s %-6s %s\n", + prefix, element->semantic_name, element->semantic_index, dump_write_mask(tmp, element->mask), + element->register_index, get_sysval_semantic_name(element->sysval_semantic), + get_component_type_name(element->component_type), dump_write_mask(tmp, element->used_mask)); + } + + return VKD3D_OK; +} + +enum vkd3d_result vkd3d_dxbc_signature_to_text(const struct vkd3d_shader_parser *parser, + struct vkd3d_string_buffer *buffer) +{ + enum vkd3d_result ret; + + vkd3d_string_buffer_printf(buffer, "// Input signature:\n"); + ret = dump_signature(&parser->shader_desc.input_signature, buffer, "input"); + + if (ret >= 0) + { + vkd3d_string_buffer_printf(buffer, "//\n// Output signature:\n"); + ret = dump_signature(&parser->shader_desc.output_signature, buffer, "output"); + vkd3d_string_buffer_printf(buffer, "//\n"); + } + + return ret; +} diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 48430b136..651cef47e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1570,7 +1570,9 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, struct vkd3d_string_buffer buffer;
vkd3d_string_buffer_init(&buffer); - ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, &buffer, VSIR_ASM_D3D); + ret = vkd3d_dxbc_signature_to_text(parser, &buffer); + if (ret >= 0) + ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, &buffer, VSIR_ASM_D3D); vkd3d_shader_code_from_string_buffer(out, &buffer); break; } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 0a21976b9..c1ec6fecd 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1333,6 +1333,8 @@ enum vsir_asm_dialect 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_string_buffer *buffer, enum vsir_asm_dialect dialect); +enum vkd3d_result vkd3d_dxbc_signature_to_text(const struct vkd3d_shader_parser *parser, + struct vkd3d_string_buffer *buffer); 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);