From 465fe54a9bf1b96ca54e13e3599d8c6ed3447ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Mon, 19 Jun 2017 18:05:53 +0200 Subject: [PATCH] libs/vkd3d-shader: Implement vkd3d_shader_compile_dxbc(). --- libs/vkd3d-shader/vkd3d_shader_main.c | 59 ++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 52defccd..5edd5c81 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -21,9 +21,64 @@ HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_code *spirv, uint32_t compiler_options) { - FIXME("Not implemented!\n"); + struct vkd3d_dxbc_compiler *spirv_compiler; + struct vkd3d_shader_version shader_version; + struct vkd3d_shader_desc shader_desc; + struct vkd3d_shader_instruction ins; + void *parser_data; + const DWORD *ptr; + HRESULT hr; + bool ret; - return E_NOTIMPL; + TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x.\n", + dxbc->code, dxbc->size, spirv, compiler_options); + + if (FAILED(hr = shader_extract_from_dxbc(dxbc->code, dxbc->size, &shader_desc))) + { + WARN("Failed to extract shader, hr %#x.\n", hr); + return hr; + } + + if (!(parser_data = shader_sm4_init(shader_desc.byte_code, shader_desc.byte_code_size, + &shader_desc.output_signature))) + { + WARN("Failed to initialize shader parser, hr %#x.\n", hr); + free_shader_desc(&shader_desc); + return hr; + } + + shader_sm4_read_header(parser_data, &ptr, &shader_version); + + if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&shader_version, compiler_options))) + { + ERR("Failed to create DXBC compiler.\n"); + shader_sm4_free(parser_data); + free_shader_desc(&shader_desc); + return hr; + } + + while (!shader_sm4_is_end(parser_data, &ptr)) + { + shader_sm4_read_instruction(parser_data, &ptr, &ins); + + if (ins.handler_idx == VKD3DSIH_TABLE_SIZE) + { + WARN("Encountered unrecognized or invalid instruction.\n"); + shader_sm4_free(parser_data); + free_shader_desc(&shader_desc); + vkd3d_dxbc_compiler_destroy(spirv_compiler); + return E_FAIL; + } + + vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &ins); + } + + ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, spirv); + vkd3d_dxbc_compiler_destroy(spirv_compiler); + shader_sm4_free(parser_data); + free_shader_desc(&shader_desc); + + return ret ? S_OK : E_FAIL; } void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)