vkd3d-shader: Dump the converted shader too.

This commit is contained in:
Giovanni Mascellani 2024-08-12 16:27:00 +02:00 committed by Henri Verbeet
parent 1a0d6a4db4
commit 527966580e
Notes: Henri Verbeet 2024-08-29 19:26:26 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/992
2 changed files with 70 additions and 26 deletions

View File

@ -445,29 +445,46 @@ void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char
bytecode_set_bytes(buffer, offset, string, length); bytecode_set_bytes(buffer, offset, string, length);
} }
static void vkd3d_shader_dump_blob(const char *path, const char *profile, struct shader_dump_data
const char *suffix, const void *data, size_t size) {
uint8_t checksum[16];
const char *path;
const char *profile;
const char *source_suffix;
const char *target_suffix;
};
static void vkd3d_shader_dump_shader(const struct shader_dump_data *dump_data,
const void *data, size_t size, bool source)
{ {
static const char hexadecimal_digits[] = "0123456789abcdef"; static const char hexadecimal_digits[] = "0123456789abcdef";
const uint8_t *checksum = dump_data->checksum;
char str_checksum[33]; char str_checksum[33];
uint8_t checksum[16]; unsigned int pos = 0;
char filename[1024]; char filename[1024];
unsigned int i; unsigned int i;
FILE *f; FILE *f;
vkd3d_compute_md5(data, size, (uint32_t *)checksum, VKD3D_MD5_STANDARD); if (!dump_data->path)
return;
for (i = 0; i < ARRAY_SIZE(checksum); ++i) for (i = 0; i < ARRAY_SIZE(dump_data->checksum); ++i)
{ {
str_checksum[2 * i] = hexadecimal_digits[checksum[i] >> 4]; str_checksum[2 * i] = hexadecimal_digits[checksum[i] >> 4];
str_checksum[2 * i + 1] = hexadecimal_digits[checksum[i] & 0xf]; str_checksum[2 * i + 1] = hexadecimal_digits[checksum[i] & 0xf];
} }
str_checksum[32] = '\0'; str_checksum[32] = '\0';
if (profile) pos = snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s", dump_data->path, str_checksum);
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s-%s.%s", path, str_checksum, profile, suffix);
if (dump_data->profile)
pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-%s", dump_data->profile);
if (source)
pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-source.%s", dump_data->source_suffix);
else else
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s.%s", path, str_checksum, suffix); pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-target.%s", dump_data->target_suffix);
TRACE("Dumping shader to \"%s\".\n", filename); TRACE("Dumping shader to \"%s\".\n", filename);
if ((f = fopen(filename, "wb"))) if ((f = fopen(filename, "wb")))
{ {
@ -500,37 +517,59 @@ static const char *shader_get_source_type_suffix(enum vkd3d_shader_source_type t
} }
} }
void vkd3d_shader_dump_shader(const struct vkd3d_shader_compile_info *compile_info) static const char *shader_get_target_type_suffix(enum vkd3d_shader_target_type type)
{
switch (type)
{
case VKD3D_SHADER_TARGET_SPIRV_BINARY:
return "spv";
case VKD3D_SHADER_TARGET_SPIRV_TEXT:
return "spv.s";
case VKD3D_SHADER_TARGET_D3D_ASM:
return "d3d.s";
case VKD3D_SHADER_TARGET_D3D_BYTECODE:
return "d3dbc";
case VKD3D_SHADER_TARGET_DXBC_TPF:
return "dxbc";
case VKD3D_SHADER_TARGET_GLSL:
return "glsl";
case VKD3D_SHADER_TARGET_FX:
return "fx";
default:
FIXME("Unhandled target type %#x.\n", type);
return "bin";
}
}
static void fill_shader_dump_data(const struct vkd3d_shader_compile_info *compile_info,
struct shader_dump_data *data)
{ {
const struct vkd3d_shader_code *shader = &compile_info->source;
const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
const struct hlsl_profile_info *profile;
const char *profile_name = NULL;
static bool enabled = true; static bool enabled = true;
const char *path;
data->path = NULL;
if (!enabled) if (!enabled)
return; return;
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH"))) if (!(data->path = getenv("VKD3D_SHADER_DUMP_PATH")))
{ {
enabled = false; enabled = false;
return; return;
} }
data->profile = NULL;
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
{ {
if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
return;
if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) if ((hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
return; data->profile = hlsl_source_info->profile;
profile_name = profile->name;
} }
vkd3d_shader_dump_blob(path, profile_name, shader_get_source_type_suffix(compile_info->source_type), vkd3d_compute_md5(compile_info->source.code, compile_info->source.size,
shader->code, shader->size); (uint32_t *)data->checksum, VKD3D_MD5_STANDARD);
data->source_suffix = shader_get_source_type_suffix(compile_info->source_type);
data->target_suffix = shader_get_target_type_suffix(compile_info->target_type);
} }
static void init_scan_signature_info(const struct vkd3d_shader_compile_info *info) static void init_scan_signature_info(const struct vkd3d_shader_compile_info *info)
@ -1509,6 +1548,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages) int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
{ {
struct vkd3d_shader_message_context message_context; struct vkd3d_shader_message_context message_context;
struct shader_dump_data dump_data;
int ret; int ret;
TRACE("compile_info %p, messages %p.\n", compile_info, messages); TRACE("compile_info %p, messages %p.\n", compile_info, messages);
@ -1523,7 +1563,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
vkd3d_shader_message_context_init(&message_context, compile_info->log_level); vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
vkd3d_shader_dump_shader(compile_info); fill_shader_dump_data(compile_info, &dump_data);
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, true);
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
{ {
@ -1632,6 +1673,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, char **messages) struct vkd3d_shader_code *out, char **messages)
{ {
struct vkd3d_shader_message_context message_context; struct vkd3d_shader_message_context message_context;
struct shader_dump_data dump_data;
int ret; int ret;
TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages);
@ -1646,7 +1688,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_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);
vkd3d_shader_dump_shader(compile_info); fill_shader_dump_data(compile_info, &dump_data);
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, true);
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
{ {
@ -1688,6 +1731,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
} }
} }
vkd3d_shader_dump_shader(&dump_data, out->code, out->size, false);
vkd3d_shader_message_context_trace_messages(&message_context); vkd3d_shader_message_context_trace_messages(&message_context);
if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;

View File

@ -1549,7 +1549,6 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st
void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args); enum vkd3d_shader_error error, const char *format, va_list args);
void vkd3d_shader_dump_shader(const struct vkd3d_shader_compile_info *compile_info);
uint64_t vkd3d_shader_init_config_flags(void); uint64_t vkd3d_shader_init_config_flags(void);
void vkd3d_shader_trace_text_(const char *text, size_t size, const char *function); void vkd3d_shader_trace_text_(const char *text, size_t size, const char *function);
#define vkd3d_shader_trace_text(text, size) \ #define vkd3d_shader_trace_text(text, size) \