mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-utils: Implement D3DDisassemble().
Very loosely based on Wine's d3dcompiler_43.
This commit is contained in:
parent
4fd4ecc020
commit
8c6f5b847b
Notes:
Alexandre Julliard
2024-01-29 22:53:26 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/610
@ -89,6 +89,10 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
|
||||
#define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE)
|
||||
#endif
|
||||
|
||||
#ifndef WARN_ON
|
||||
#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN)
|
||||
#endif
|
||||
|
||||
#define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN)
|
||||
|
||||
#define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name
|
||||
|
@ -79,6 +79,7 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
||||
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
|
||||
ID3DBlob **error_messages);
|
||||
HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
||||
@ -89,5 +90,8 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename
|
||||
HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
|
||||
HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
|
||||
|
||||
typedef HRESULT (WINAPI *pD3DDisassemble)(const void *data, SIZE_T data_size,
|
||||
UINT flags, const char *comments, ID3DBlob **blob);
|
||||
|
||||
#endif /* __D3DCOMPILER_H__ */
|
||||
#endif /* __VKD3D_D3DCOMPILER_H */
|
||||
|
@ -117,6 +117,8 @@ VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_
|
||||
VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
|
||||
|
||||
/** \since 1.11 */
|
||||
VKD3D_UTILS_API HRESULT WINAPI D3DDisassemble(const void *data,
|
||||
SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob);
|
||||
VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -11,6 +11,7 @@ global:
|
||||
D3DCompile;
|
||||
D3DCompile2;
|
||||
D3DCreateBlob;
|
||||
D3DDisassemble;
|
||||
D3DGetBlobPart;
|
||||
D3DGetDebugInfo;
|
||||
D3DGetInputAndOutputSignatureBlob;
|
||||
|
@ -928,3 +928,75 @@ void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback)
|
||||
vkd3d_set_log_callback(callback);
|
||||
vkd3d_dbg_set_log_callback(callback);
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size,
|
||||
UINT flags, const char *comments, ID3DBlob **blob)
|
||||
{
|
||||
enum vkd3d_shader_source_type source_type;
|
||||
struct vkd3d_shader_compile_info info;
|
||||
struct vkd3d_shader_code output;
|
||||
const char *p, *q, *end;
|
||||
char *messages;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
static const struct vkd3d_shader_compile_option options[] =
|
||||
{
|
||||
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
|
||||
};
|
||||
|
||||
TRACE("data %p, data_size %lu, flags %#x, comments %p, blob %p.\n",
|
||||
data, data_size, flags, comments, blob);
|
||||
|
||||
if (flags)
|
||||
FIXME("Ignoring flags %#x.\n", flags);
|
||||
|
||||
if (comments)
|
||||
FIXME("Ignoring comments %s.\n", debugstr_a(comments));
|
||||
|
||||
if (!data_size)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (data_size >= sizeof(uint32_t) && *(uint32_t *)data == TAG_DXBC)
|
||||
source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||
else
|
||||
source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
||||
|
||||
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
|
||||
info.next = NULL;
|
||||
info.source.code = data;
|
||||
info.source.size = data_size;
|
||||
info.source_type = source_type;
|
||||
info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
|
||||
info.options = options;
|
||||
info.option_count = ARRAY_SIZE(options);
|
||||
info.log_level = VKD3D_SHADER_LOG_INFO;
|
||||
info.source_name = NULL;
|
||||
|
||||
ret = vkd3d_shader_compile(&info, &output, &messages);
|
||||
if (messages && *messages && WARN_ON())
|
||||
{
|
||||
WARN("Compiler log:\n");
|
||||
for (p = messages, end = p + strlen(p); p < end; p = q)
|
||||
{
|
||||
if (!(q = memchr(p, '\n', end - p)))
|
||||
q = end;
|
||||
else
|
||||
++q;
|
||||
WARN(" %.*s", (int)(q - p), p);
|
||||
}
|
||||
WARN("\n");
|
||||
}
|
||||
vkd3d_shader_free_messages(messages);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
WARN("Failed to disassemble shader, ret %d.\n", ret);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
}
|
||||
|
||||
if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size, blob)))
|
||||
vkd3d_shader_free_shader_code(&output);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -1514,6 +1514,98 @@ static void test_signature_reflection(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_disassemble_shader(void)
|
||||
{
|
||||
ID3DBlob *blob;
|
||||
int hr;
|
||||
|
||||
/* A Direct3D 8 vertex shader without dcl_ instructions. */
|
||||
static const uint32_t vs_1_1[] =
|
||||
{
|
||||
0xfffe0101, /* vs_1_1 */
|
||||
0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
|
||||
0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
|
||||
0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
|
||||
0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
|
||||
0x0000ffff, /* end */
|
||||
};
|
||||
|
||||
static const uint32_t vs_2_0[] =
|
||||
{
|
||||
0xfffe0200, /* vs_2_0 */
|
||||
0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
|
||||
0x0200001f, 0x80000003, 0x900f0001, /* dcl_normal v1 */
|
||||
0x0200001f, 0x8001000a, 0x900f0002, /* dcl_color1 v2 */
|
||||
0x0200001f, 0x80000005, 0x900f0003, /* dcl_texcoord0 v3 */
|
||||
0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
|
||||
0x02000001, 0xd00f0001, 0x90e40002, /* mov oD1, v2 */
|
||||
0x02000001, 0xe0070000, 0x90e40003, /* mov oT0.xyz, v3 */
|
||||
0x02000001, 0xc00f0001, 0x90ff0002, /* mov oFog, v2.w */
|
||||
0x02000001, 0xc00f0002, 0x90ff0001, /* mov oPts, v1.w */
|
||||
0x0000ffff, /* end */
|
||||
};
|
||||
|
||||
/* A shader model 3 vertex shader without dcl_ instructions. */
|
||||
static const uint32_t vs_3_0[] =
|
||||
{
|
||||
0xfffe0300, /* vs_3_0 */
|
||||
0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
|
||||
0x0000ffff, /* end */
|
||||
};
|
||||
|
||||
/* A "shader model 4" d3dbc vertex shader. */
|
||||
static const uint32_t vs_4_0[] =
|
||||
{
|
||||
0xfffe0400, /* vs_4_0 */
|
||||
0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
|
||||
0x0000ffff, /* end */
|
||||
};
|
||||
|
||||
/* An actual shader model 4 dxbc-tpf vertex shader. */
|
||||
static const uint32_t vs_4_0_dxbc[] =
|
||||
{
|
||||
#if 0
|
||||
float4 main(float4 position : POSITION) : SV_POSITION
|
||||
{
|
||||
return position;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
|
||||
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
|
||||
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
|
||||
0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
|
||||
0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
|
||||
0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
|
||||
};
|
||||
|
||||
hr = D3DDisassemble(vs_1_1, 0, 0, NULL, &blob);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = D3DDisassemble(vs_1_1, sizeof(vs_1_1), 0, NULL, &blob);
|
||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
hr = D3DDisassemble(vs_2_0, sizeof(vs_2_0), 0, NULL, &blob);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
hr = D3DDisassemble(vs_3_0, sizeof(vs_3_0), 0, NULL, &blob);
|
||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
hr = D3DDisassemble(vs_4_0, sizeof(vs_4_0), 0, NULL, &blob);
|
||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
hr = D3DDisassemble(vs_4_0_dxbc, sizeof(vs_4_0_dxbc), 0, NULL, &blob);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ID3D10Blob_Release(blob);
|
||||
}
|
||||
|
||||
START_TEST(hlsl_d3d12)
|
||||
{
|
||||
parse_args(argc, argv);
|
||||
@ -1525,4 +1617,5 @@ START_TEST(hlsl_d3d12)
|
||||
run_test(test_create_blob);
|
||||
run_test(test_get_blob_part);
|
||||
run_test(test_signature_reflection);
|
||||
run_test(test_disassemble_shader);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user