vkd3d-shader/hlsl: Use a block in hlsl_normalize_binary_exprs().
[vkd3d.git] / tests / vkd3d_shader_api.c
blob8849f7179614ec780c2850226042b5c6b1a3541a
1 /*
2 * Copyright 2018 Józef Kucia for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "vkd3d_test.h"
20 #include "utils.h"
21 #include <vkd3d_shader.h>
22 #ifdef HAVE_OPENGL
23 #define GL_GLEXT_PROTOTYPES
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26 #include <GL/gl.h>
27 #endif
29 #include <locale.h>
31 static void test_invalid_shaders(void)
33 struct vkd3d_shader_compile_info info;
34 struct vkd3d_shader_code spirv;
35 int rc;
37 static const DWORD ps_break_code[] =
39 #if 0
40 ps_4_0
41 dcl_constantbuffer cb0[1], immediateIndexed
42 dcl_output o0.xyzw
43 if_z cb0[0].x
44 mov o0.xyzw, l(1.000000,1.000000,1.000000,1.000000)
45 break
46 endif
47 mov o0.xyzw, l(0,0,0,0)
48 ret
49 #endif
50 0x43425844, 0x1316702a, 0xb1a7ebfc, 0xf477753e, 0x72605647, 0x00000001, 0x000000f8, 0x00000003,
51 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
52 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
53 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000080, 0x00000040, 0x00000020,
54 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x0400001f,
55 0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000,
56 0x3f800000, 0x3f800000, 0x3f800000, 0x01000002, 0x01000015, 0x08000036, 0x001020f2, 0x00000000,
57 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
59 static const struct vkd3d_shader_compile_option option =
61 .name = VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG,
62 .value = 1,
65 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
66 info.next = NULL;
67 info.source.code = ps_break_code;
68 info.source.size = sizeof(ps_break_code);
69 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
70 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
71 info.options = &option;
72 info.option_count = 1;
73 info.log_level = VKD3D_SHADER_LOG_NONE;
74 info.source_name = NULL;
76 rc = vkd3d_shader_compile(&info, &spirv, NULL);
77 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
79 rc = vkd3d_shader_scan(&info, NULL);
80 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
83 static void test_vkd3d_shader_pfns(void)
85 PFN_vkd3d_shader_get_supported_source_types pfn_vkd3d_shader_get_supported_source_types;
86 PFN_vkd3d_shader_get_supported_target_types pfn_vkd3d_shader_get_supported_target_types;
87 PFN_vkd3d_shader_free_scan_descriptor_info pfn_vkd3d_shader_free_scan_descriptor_info;
88 PFN_vkd3d_shader_serialize_root_signature pfn_vkd3d_shader_serialize_root_signature;
89 PFN_vkd3d_shader_find_signature_element pfn_vkd3d_shader_find_signature_element;
90 PFN_vkd3d_shader_free_shader_signature pfn_vkd3d_shader_free_shader_signature;
91 PFN_vkd3d_shader_parse_input_signature pfn_vkd3d_shader_parse_input_signature;
92 PFN_vkd3d_shader_parse_root_signature pfn_vkd3d_shader_parse_root_signature;
93 PFN_vkd3d_shader_free_root_signature pfn_vkd3d_shader_free_root_signature;
94 PFN_vkd3d_shader_free_shader_code pfn_vkd3d_shader_free_shader_code;
95 PFN_vkd3d_shader_get_version pfn_vkd3d_shader_get_version;
96 PFN_vkd3d_shader_compile pfn_vkd3d_shader_compile;
97 PFN_vkd3d_shader_scan pfn_vkd3d_shader_scan;
99 struct vkd3d_shader_versioned_root_signature_desc root_signature_desc;
100 unsigned int major, minor, expected_major, expected_minor;
101 struct vkd3d_shader_scan_descriptor_info descriptor_info;
102 const enum vkd3d_shader_source_type *source_types;
103 const enum vkd3d_shader_target_type *target_types;
104 struct vkd3d_shader_signature_element *element;
105 struct vkd3d_shader_compile_info compile_info;
106 unsigned int i, j, source_count, target_count;
107 struct vkd3d_shader_signature signature;
108 struct vkd3d_shader_code dxbc, spirv;
109 const char *version, *p;
110 bool b;
111 int rc;
113 static const struct vkd3d_shader_versioned_root_signature_desc empty_rs_desc =
115 .version = VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0,
117 static const DWORD vs_code[] =
119 #if 0
120 float4 main(int4 p : POSITION) : SV_Position
122 return p;
124 #endif
125 0x43425844, 0x3fd50ab1, 0x580a1d14, 0x28f5f602, 0xd1083e3a, 0x00000001, 0x000000d8, 0x00000003,
126 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
127 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
128 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
129 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52444853, 0x0000003c, 0x00010040,
130 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
131 0x0500002b, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
133 static const struct vkd3d_shader_code vs = {vs_code, sizeof(vs_code)};
135 pfn_vkd3d_shader_get_supported_source_types = vkd3d_shader_get_supported_source_types;
136 pfn_vkd3d_shader_get_supported_target_types = vkd3d_shader_get_supported_target_types;
137 pfn_vkd3d_shader_free_scan_descriptor_info = vkd3d_shader_free_scan_descriptor_info;
138 pfn_vkd3d_shader_serialize_root_signature = vkd3d_shader_serialize_root_signature;
139 pfn_vkd3d_shader_find_signature_element = vkd3d_shader_find_signature_element;
140 pfn_vkd3d_shader_free_shader_signature = vkd3d_shader_free_shader_signature;
141 pfn_vkd3d_shader_parse_input_signature = vkd3d_shader_parse_input_signature;
142 pfn_vkd3d_shader_parse_root_signature = vkd3d_shader_parse_root_signature;
143 pfn_vkd3d_shader_free_root_signature = vkd3d_shader_free_root_signature;
144 pfn_vkd3d_shader_free_shader_code = vkd3d_shader_free_shader_code;
145 pfn_vkd3d_shader_get_version = vkd3d_shader_get_version;
146 pfn_vkd3d_shader_compile = vkd3d_shader_compile;
147 pfn_vkd3d_shader_scan = vkd3d_shader_scan;
149 sscanf(PACKAGE_VERSION, "%d.%d", &expected_major, &expected_minor);
150 version = pfn_vkd3d_shader_get_version(&major, &minor);
151 p = strstr(version, "vkd3d-shader " PACKAGE_VERSION);
152 ok(p == version, "Got unexpected version string \"%s\"\n", version);
153 ok(major == expected_major, "Got unexpected major version %u.\n", major);
154 ok(minor == expected_minor, "Got unexpected minor version %u.\n", minor);
156 source_types = pfn_vkd3d_shader_get_supported_source_types(&source_count);
157 ok(source_types, "Got unexpected source types array %p.\n", source_types);
158 ok(source_count, "Got unexpected source type count %u.\n", source_count);
160 b = false;
161 for (i = 0; i < source_count; ++i)
163 target_types = pfn_vkd3d_shader_get_supported_target_types(source_types[i], &target_count);
164 ok(target_types, "Got unexpected target types array %p.\n", target_types);
165 ok(target_count, "Got unexpected target type count %u.\n", target_count);
167 for (j = 0; j < target_count; ++j)
169 if (source_types[i] == VKD3D_SHADER_SOURCE_DXBC_TPF
170 && target_types[j] == VKD3D_SHADER_TARGET_SPIRV_BINARY)
171 b = true;
174 ok(b, "The dxbc-tpf source type with spirv-binary target type is not supported.\n");
176 rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc, NULL);
177 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
178 rc = pfn_vkd3d_shader_parse_root_signature(&dxbc, &root_signature_desc, NULL);
179 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
180 pfn_vkd3d_shader_free_root_signature(&root_signature_desc);
181 pfn_vkd3d_shader_free_shader_code(&dxbc);
183 rc = pfn_vkd3d_shader_parse_input_signature(&vs, &signature, NULL);
184 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
185 element = pfn_vkd3d_shader_find_signature_element(&signature, "position", 0, 0);
186 ok(element, "Could not find shader signature element.\n");
187 pfn_vkd3d_shader_free_shader_signature(&signature);
189 compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
190 compile_info.next = NULL;
191 compile_info.source = vs;
192 compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
193 compile_info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
194 compile_info.options = NULL;
195 compile_info.option_count = 0;
196 compile_info.log_level = VKD3D_SHADER_LOG_NONE;
197 compile_info.source_name = NULL;
199 rc = pfn_vkd3d_shader_compile(&compile_info, &spirv, NULL);
200 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
201 pfn_vkd3d_shader_free_shader_code(&spirv);
203 memset(&descriptor_info, 0, sizeof(descriptor_info));
204 descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
205 compile_info.next = &descriptor_info;
207 rc = pfn_vkd3d_shader_scan(&compile_info, NULL);
208 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
209 pfn_vkd3d_shader_free_scan_descriptor_info(&descriptor_info);
212 static void test_version(void)
214 unsigned int major, minor, expected_major, expected_minor;
215 const char *version, *p;
217 sscanf(PACKAGE_VERSION, "%d.%d", &expected_major, &expected_minor);
219 version = vkd3d_shader_get_version(NULL, NULL);
220 p = strstr(version, "vkd3d-shader " PACKAGE_VERSION);
221 ok(p == version, "Got unexpected version string \"%s\"\n", version);
223 major = ~0u;
224 vkd3d_shader_get_version(&major, NULL);
225 ok(major == expected_major, "Got unexpected major version %u.\n", major);
227 minor = ~0u;
228 vkd3d_shader_get_version(NULL, &minor);
229 ok(minor == expected_minor, "Got unexpected minor version %u.\n", minor);
231 major = minor = ~0u;
232 vkd3d_shader_get_version(&major, &minor);
233 ok(major == expected_major, "Got unexpected major version %u.\n", major);
234 ok(minor == expected_minor, "Got unexpected minor version %u.\n", minor);
237 static void test_d3dbc(void)
239 struct vkd3d_shader_compile_info info;
240 struct vkd3d_shader_code d3d_asm;
241 int rc;
243 static const uint32_t vs_minimal[] =
245 0xfffe0100, /* vs_1_0 */
246 0x0000ffff, /* end */
248 static const uint32_t vs_dcl_def[] =
250 0xfffe0101, /* vs_1_1 */
251 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
252 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
253 0x0000ffff, /* end */
255 static const uint32_t invalid_type[] =
257 0x00010100, /* <invalid>_1_0 */
258 0x0000ffff, /* end */
260 static const uint32_t invalid_version[] =
262 0xfffe0400, /* vs_4_0 */
263 0x0000ffff, /* end */
265 static const uint32_t ps[] =
267 0xffff0101, /* ps_1_1 */
268 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
269 0x0000ffff, /* end */
271 static const char expected[] = "vs_1_0\n";
272 static const char expected_dcl_def[] =
273 "vs_1_1\n"
274 "dcl_position0 v0\n"
275 "def c0 = 1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00\n";
277 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
278 info.next = NULL;
279 info.source.code = vs_minimal;
280 info.source.size = sizeof(vs_minimal);
281 info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
282 info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
283 info.options = NULL;
284 info.option_count = 0;
285 info.log_level = VKD3D_SHADER_LOG_NONE;
286 info.source_name = NULL;
288 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
289 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
290 ok(d3d_asm.size == strlen(expected), "Got unexpected size %zu.\n", d3d_asm.size);
291 ok(!memcmp(d3d_asm.code, expected, d3d_asm.size), "Got unexpected code \"%.*s\"\n",
292 (int)d3d_asm.size, (char *)d3d_asm.code);
293 vkd3d_shader_free_shader_code(&d3d_asm);
295 rc = vkd3d_shader_scan(&info, NULL);
296 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
298 info.source.size = sizeof(vs_minimal) + 1;
299 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
300 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
301 vkd3d_shader_free_shader_code(&d3d_asm);
303 info.source.size = ~(size_t)0;
304 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
305 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
306 vkd3d_shader_free_shader_code(&d3d_asm);
308 info.source.size = sizeof(vs_minimal) - 1;
309 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
310 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
312 info.source.code = vs_dcl_def;
313 info.source.size = sizeof(vs_dcl_def);
314 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
315 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
316 ok(d3d_asm.size == strlen(expected_dcl_def), "Got unexpected size %zu.\n", d3d_asm.size);
317 ok(!memcmp(d3d_asm.code, expected_dcl_def, d3d_asm.size), "Got unexpected code \"%.*s\"\n",
318 (int)d3d_asm.size, (char *)d3d_asm.code);
319 vkd3d_shader_free_shader_code(&d3d_asm);
321 info.source.code = invalid_type;
322 info.source.size = sizeof(invalid_type);
323 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
324 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
326 info.source.code = invalid_version;
327 info.source.size = sizeof(invalid_version);
328 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
329 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
331 info.source.code = ps;
332 info.source.size = sizeof(ps);
333 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
334 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
335 vkd3d_shader_free_shader_code(&d3d_asm);
337 /* Truncated before the destination parameter. */
338 info.source.size = sizeof(ps) - 3 * sizeof(*ps);
339 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
340 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
342 /* Truncated before the source parameter. */
343 info.source.size = sizeof(ps) - 2 * sizeof(*ps);
344 rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
345 ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
348 static void test_dxbc(void)
350 PFN_vkd3d_shader_serialize_dxbc pfn_vkd3d_shader_serialize_dxbc;
351 PFN_vkd3d_shader_parse_dxbc pfn_vkd3d_shader_parse_dxbc;
352 PFN_vkd3d_shader_free_dxbc pfn_vkd3d_shader_free_dxbc;
353 struct vkd3d_shader_dxbc_desc dxbc_desc;
354 const uint8_t *dxbc_start, *dxbc_end;
355 struct vkd3d_shader_code dxbc;
356 size_t expected_size;
357 unsigned int i;
358 int ret;
360 static const uint32_t section_0[] =
362 0x00000000, 0x00000001, 0x00000001, 0x00000002,
363 0x00000003, 0x00000005, 0x00000008, 0x0000000d,
364 0x00000015, 0x00000022, 0x00000037, 0x00000059,
365 0x00000090, 0x000000e9, 0x00000179, 0x00000262,
367 static const uint8_t section_1[] =
369 0x1, 0x4, 0x1, 0x5, 0x9, 0x2, 0x6, 0x5, 0x3, 0x5, 0x8, 0x9, 0x7, 0x9, 0x3, 0x2,
370 0x3, 0x8, 0x4, 0x6, 0x2, 0x6, 0x4, 0x3, 0x3, 0x8, 0x3, 0x2, 0x7, 0x9, 0x5, 0x0,
371 0x2, 0x8, 0x8, 0x4, 0x1, 0x9, 0x7, 0x1, 0x6, 0x9, 0x3, 0x9, 0x9, 0x3, 0x7, 0x5,
372 0x1, 0x0, 0x5, 0x8, 0x2, 0x0, 0x9, 0x7, 0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x2, 0x3,
374 static const struct vkd3d_shader_dxbc_section_desc sections[] =
376 {.tag = 0x00424946, .data = {.code = section_0, .size = sizeof(section_0)}},
377 {.tag = 0x49504950, .data = {.code = section_1, .size = sizeof(section_1)}},
379 static const uint32_t checksum[] = {0x7cfc687d, 0x7e8f4cff, 0x72a4739a, 0xd75c3703};
381 pfn_vkd3d_shader_serialize_dxbc = vkd3d_shader_serialize_dxbc;
382 pfn_vkd3d_shader_parse_dxbc = vkd3d_shader_parse_dxbc;
383 pfn_vkd3d_shader_free_dxbc = vkd3d_shader_free_dxbc;
385 /* 8 * u32 for the DXBC header */
386 expected_size = 8 * sizeof(uint32_t);
387 for (i = 0; i < ARRAY_SIZE(sections); ++i)
389 /* 1 u32 for the section offset + 2 u32 for the section header. */
390 expected_size += 3 * sizeof(uint32_t) + sections[i].data.size;
393 ret = pfn_vkd3d_shader_serialize_dxbc(ARRAY_SIZE(sections), sections, &dxbc, NULL);
394 ok(ret == VKD3D_OK, "Got unexpected ret %d.\n", ret);
395 ok(dxbc.size == expected_size, "Got unexpected size %zu, expected %zu.\n", dxbc_desc.size, expected_size);
397 ret = pfn_vkd3d_shader_parse_dxbc(&dxbc, 0, &dxbc_desc, NULL);
398 ok(ret == VKD3D_OK, "Got unexpected ret %d.\n", ret);
399 ok(dxbc_desc.tag == 0x43425844, "Got unexpected tag 0x%08x.\n", dxbc_desc.tag);
400 ok(!memcmp(dxbc_desc.checksum, checksum, sizeof(dxbc_desc.checksum)),
401 "Got unexpected checksum 0x%08x 0x%08x 0x%08x 0x%08x.\n",
402 dxbc_desc.checksum[0], dxbc_desc.checksum[1], dxbc_desc.checksum[2], dxbc_desc.checksum[3]);
403 ok(dxbc_desc.version == 1, "Got unexpected version %#x.\n", dxbc_desc.version);
404 ok(dxbc_desc.size == expected_size, "Got unexpected size %zu, expected %zu.\n", dxbc_desc.size, expected_size);
405 ok(dxbc_desc.section_count == ARRAY_SIZE(sections), "Got unexpected section count %zu, expected %zu.\n",
406 dxbc_desc.section_count, ARRAY_SIZE(sections));
408 dxbc_start = dxbc.code;
409 dxbc_end = dxbc_start + dxbc.size;
410 for (i = 0; i < dxbc_desc.section_count; ++i)
412 const struct vkd3d_shader_dxbc_section_desc *section = &dxbc_desc.sections[i];
413 const uint8_t *data = section->data.code;
415 vkd3d_test_push_context("Section %u", i);
416 ok(section->tag == sections[i].tag, "Got unexpected tag 0x%08x, expected 0x%08x.\n",
417 section->tag, sections[i].tag);
418 ok(section->data.size == sections[i].data.size, "Got unexpected size %zu, expected %zu.\n",
419 section->data.size, sections[i].data.size);
420 ok(!memcmp(data, sections[i].data.code, section->data.size), "Got unexpected section data.\n");
421 ok(data > dxbc_start && data <= dxbc_end - section->data.size,
422 "Data {%p, %zu} is not contained within blob {%p, %zu}.\n",
423 data, section->data.size, dxbc_start, dxbc_end - dxbc_start);
424 vkd3d_test_pop_context();
427 pfn_vkd3d_shader_free_dxbc(&dxbc_desc);
428 vkd3d_shader_free_shader_code(&dxbc);
431 static void check_signature_element(const struct vkd3d_shader_signature_element *element,
432 const struct vkd3d_shader_signature_element *expect)
434 ok(!strcmp(element->semantic_name, expect->semantic_name), "Got semantic name %s.\n", element->semantic_name);
435 ok(element->semantic_index == expect->semantic_index, "Got semantic index %u.\n", element->semantic_index);
436 ok(element->stream_index == expect->stream_index, "Got stream index %u.\n", element->stream_index);
437 ok(element->sysval_semantic == expect->sysval_semantic, "Got sysval semantic %#x.\n", element->sysval_semantic);
438 ok(element->component_type == expect->component_type, "Got component type %#x.\n", element->component_type);
439 ok(element->register_index == expect->register_index, "Got register index %u.\n", element->register_index);
440 ok(element->mask == expect->mask, "Got mask %#x.\n", element->mask);
441 todo_if (expect->used_mask != expect->mask && strcmp(expect->semantic_name, "PSIZE"))
442 ok(element->used_mask == expect->used_mask, "Got used mask %#x.\n", element->used_mask);
443 ok(element->min_precision == expect->min_precision, "Got minimum precision %#x.\n", element->min_precision);
446 static void test_scan_signatures(void)
448 struct vkd3d_shader_scan_signature_info signature_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO};
449 struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
450 struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
451 struct vkd3d_shader_compile_option options[1];
452 struct vkd3d_shader_code dxbc;
453 size_t i, j;
454 int rc;
456 static const char vs1_source[] =
457 "void main(\n"
458 " in float4 a : apple,\n"
459 " out float4 b : banana2,\n"
460 " inout float4 c : color,\n"
461 " inout float4 d : depth,\n"
462 " inout float4 e : sv_position,\n"
463 " in uint3 f : fruit,\n"
464 " inout bool2 g : grape,\n"
465 " in int h : honeydew,\n"
466 " in uint i : sv_vertexid)\n"
467 "{\n"
468 " b.yw = a.xz;\n"
469 "}";
471 static const struct vkd3d_shader_signature_element vs1_inputs[] =
473 {"apple", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0x5},
474 {"color", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
475 {"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
476 {"sv_position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
477 {"fruit", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 4, 0x7},
478 {"grape", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 5, 0x3, 0x3},
479 {"honeydew", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_INT, 6, 0x1},
480 {"sv_vertexid", 0, 0, VKD3D_SHADER_SV_VERTEX_ID, VKD3D_SHADER_COMPONENT_UINT, 7, 0x1},
483 static const struct vkd3d_shader_signature_element vs1_outputs[] =
485 {"banana", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xa},
486 {"color", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
487 {"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
488 {"sv_position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
489 {"grape", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_UINT, 4, 0x3, 0x3},
492 static const char vs2_source[] =
493 "void main(inout float4 pos : position)\n"
494 "{\n"
495 "}";
497 static const struct vkd3d_shader_signature_element vs2_inputs[] =
499 {"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
502 static const struct vkd3d_shader_signature_element vs2_outputs[] =
504 {"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
507 static const struct vkd3d_shader_signature_element vs2_legacy_outputs[] =
509 {"SV_Position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
512 static const char vs3_source[] =
513 "void main(\n"
514 " in float4 c : position,\n"
515 " out float4 b : position,\n"
516 " in float4 a : binormal,\n"
517 " in float4 d : blendindices,\n"
518 " inout float4 e : texcoord2,\n"
519 " inout float4 f : color,\n"
520 " inout float g : fog,\n"
521 " inout float h : psize)\n"
522 "{\n"
523 " b = a + c + d;\n"
524 "}";
526 static const struct vkd3d_shader_signature_element vs3_inputs[] =
528 {"POSITION", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
529 {"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
530 {"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
531 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
532 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
533 {"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
534 {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0xf},
537 static const struct vkd3d_shader_signature_element vs3_outputs[] =
539 {"POSITION", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 10, 0xf, 0xf},
540 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
541 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 8, 0xf, 0xf},
542 {"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 11, 0x1, 0x1},
543 {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 12, 0x1, 0x1},
546 static const char vs4_source[] =
547 "void main(\n"
548 " inout float4 c : position,\n"
549 " inout float4 a : binormal,\n"
550 " inout float4 d : blendindices,\n"
551 " inout float4 e : texcoord2,\n"
552 " inout float4 f : color,\n"
553 " inout float4 g : fog,\n"
554 " inout float h : psize)\n"
555 "{\n"
556 "}";
558 static const struct vkd3d_shader_signature_element vs4_inputs[] =
560 {"POSITION", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
561 {"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
562 {"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
563 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
564 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
565 {"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
566 {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0xf},
569 static const struct vkd3d_shader_signature_element vs4_outputs[] =
571 {"POSITION", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
572 {"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
573 {"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
574 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
575 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
576 {"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
577 {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0x1},
580 static const char ps1_source[] =
581 "void main(\n"
582 " in float2 a : apple,\n"
583 " out float4 b : sv_target2,\n"
584 " out float c : sv_depth,\n"
585 " in float4 d : position,\n"
586 " in float4 e : sv_position)\n"
587 "{\n"
588 " b = d;\n"
589 " c = 0;\n"
590 "}";
592 static const struct vkd3d_shader_signature_element ps1_inputs[] =
594 {"apple", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0x3},
595 {"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
596 {"sv_position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf},
599 static const struct vkd3d_shader_signature_element ps1_outputs[] =
601 {"sv_target", 2, 0, VKD3D_SHADER_SV_TARGET, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
602 {"sv_depth", 0, 0, VKD3D_SHADER_SV_DEPTH, VKD3D_SHADER_COMPONENT_FLOAT, ~0u, 0x1, 0x1},
605 static const char ps2_source[] =
606 "void main(\n"
607 "in float4 c : color,\n"
608 "in float4 a : texcoord2,\n"
609 "out float4 b : color)\n"
610 "{\n"
611 "b = a.x + c;\n"
612 "}";
614 static const struct vkd3d_shader_signature_element ps2_inputs[] =
616 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
617 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 8, 0xf, 0xf},
620 static const struct vkd3d_shader_signature_element ps2_outputs[] =
622 {"COLOR", 0, 0, VKD3D_SHADER_SV_TARGET, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
625 static const char ps3_source[] =
626 "void main(\n"
627 "in float4 c : color,\n"
628 "in float4 a : texcoord2,\n"
629 "out float4 b : color,\n"
630 "out float d : depth)\n"
631 "{\n"
632 "b = c;\n"
633 "d = a;\n"
634 "}";
636 static const struct vkd3d_shader_signature_element ps3_inputs[] =
638 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 8, 0xf, 0xf},
639 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
642 static const struct vkd3d_shader_signature_element ps3_outputs[] =
644 {"COLOR", 0, 0, VKD3D_SHADER_SV_TARGET, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
645 {"DEPTH", 0, 0, VKD3D_SHADER_SV_DEPTH, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0x1, 0x1},
648 static const char ps4_source[] =
649 "void main(\n"
650 " in float4 c : color,\n"
651 " in float4 a : texcoord2,\n"
652 " out float4 b : color,\n"
653 " inout float d : depth,\n"
654 " in float4 e : blendindices,\n"
655 " in float4 f : vpos,\n"
656 " in float g : vface)\n"
657 "{\n"
658 " b = c + a + e + f + g;\n"
659 "}";
661 static const struct vkd3d_shader_signature_element ps4_inputs[] =
663 {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
664 {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
665 {"DEPTH", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0x1, 0x1},
666 {"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
667 {"VPOS", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
668 {"VFACE", 0, 0, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1},
671 static const char ps5_source[] =
672 "void main(\n"
673 " inout float4 a : color2,\n"
674 " inout float b : depth,\n"
675 " in float4 c : position)\n"
676 "{\n"
677 "}";
679 static const struct vkd3d_shader_signature_element ps5_inputs[] =
681 {"color", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
682 {"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1},
683 {"SV_Position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf},
686 static const struct vkd3d_shader_signature_element ps5_outputs[] =
688 {"SV_Target", 2, 0, VKD3D_SHADER_SV_TARGET, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
689 {"SV_Depth", 0, 0, VKD3D_SHADER_SV_DEPTH, VKD3D_SHADER_COMPONENT_FLOAT, ~0u, 0x1, 0x1},
692 static const char cs1_source[] =
693 "[numthreads(1, 1, 1)]\n"
694 "void main(\n"
695 " in uint a : sv_dispatchthreadid,\n"
696 " in uint b : sv_groupid,\n"
697 " in uint c : sv_groupthreadid)\n"
698 "{\n"
699 "}";
701 static const struct
703 const char *source;
704 bool sm4;
705 const char *profile;
706 bool compat;
707 const struct vkd3d_shader_signature_element *inputs;
708 size_t input_count;
709 const struct vkd3d_shader_signature_element *outputs;
710 size_t output_count;
711 const struct vkd3d_shader_signature_element *patch_constants;
712 size_t patch_constant_count;
714 tests[] =
716 {vs1_source, true, "vs_4_0", false, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
717 {vs1_source, true, "vs_4_0", true, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
718 {vs2_source, true, "vs_4_0", false, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)},
719 {vs2_source, true, "vs_4_0", true, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_legacy_outputs, ARRAY_SIZE(vs2_legacy_outputs)},
720 {ps1_source, true, "ps_4_0", false, ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)},
721 {ps5_source, true, "ps_4_0", true, ps5_inputs, ARRAY_SIZE(ps5_inputs), ps5_outputs, ARRAY_SIZE(ps5_outputs)},
722 {cs1_source, true, "cs_5_0", false, NULL, 0, NULL, 0},
724 {vs3_source, false, "vs_1_1", false, vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)},
725 {vs3_source, false, "vs_2_0", false, vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)},
726 {vs4_source, false, "vs_3_0", false, vs4_inputs, ARRAY_SIZE(vs4_inputs), vs4_outputs, ARRAY_SIZE(vs4_outputs)},
727 {ps2_source, false, "ps_1_1", false, ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)},
728 {ps3_source, false, "ps_2_0", false, ps3_inputs, ARRAY_SIZE(ps3_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)},
729 {ps4_source, false, "ps_3_0", false, ps4_inputs, ARRAY_SIZE(ps4_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)},
732 for (i = 0; i < ARRAY_SIZE(tests); ++i)
734 vkd3d_test_push_context("test %u", i);
736 compile_info.source.code = tests[i].source;
737 compile_info.source.size = strlen(tests[i].source);
738 compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
739 compile_info.target_type = tests[i].sm4 ? VKD3D_SHADER_TARGET_DXBC_TPF : VKD3D_SHADER_TARGET_D3D_BYTECODE;
740 compile_info.log_level = VKD3D_SHADER_LOG_INFO;
741 compile_info.options = options;
742 compile_info.option_count = 1;
744 options[0].name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY;
745 options[0].value = 0;
746 if (tests[i].compat)
747 options[0].value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
749 compile_info.next = &hlsl_info;
750 hlsl_info.profile = tests[i].profile;
752 rc = vkd3d_shader_compile(&compile_info, &dxbc, NULL);
753 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
755 compile_info.source_type = tests[i].sm4 ? VKD3D_SHADER_SOURCE_DXBC_TPF : VKD3D_SHADER_SOURCE_D3D_BYTECODE;
756 compile_info.source = dxbc;
758 compile_info.next = &signature_info;
760 rc = vkd3d_shader_scan(&compile_info, NULL);
761 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
763 ok(signature_info.input.element_count == tests[i].input_count,
764 "Got input count %u.\n", signature_info.input.element_count);
765 for (j = 0; j < signature_info.input.element_count; ++j)
767 vkd3d_test_push_context("input %u", j);
768 check_signature_element(&signature_info.input.elements[j], &tests[i].inputs[j]);
769 vkd3d_test_pop_context();
772 ok(signature_info.output.element_count == tests[i].output_count,
773 "Got output count %u.\n", signature_info.output.element_count);
774 for (j = 0; j < signature_info.output.element_count; ++j)
776 vkd3d_test_push_context("output %u", j);
777 check_signature_element(&signature_info.output.elements[j], &tests[i].outputs[j]);
778 vkd3d_test_pop_context();
781 ok(signature_info.patch_constant.element_count == tests[i].patch_constant_count,
782 "Got patch constant count %u.\n", signature_info.patch_constant.element_count);
783 for (j = 0; j < signature_info.patch_constant.element_count; ++j)
785 vkd3d_test_push_context("patch constant %u", j);
786 check_signature_element(&signature_info.patch_constant.elements[j], &tests[i].patch_constants[j]);
787 vkd3d_test_pop_context();
790 vkd3d_shader_free_scan_signature_info(&signature_info);
791 vkd3d_shader_free_shader_code(&dxbc);
793 vkd3d_test_pop_context();
797 static void test_scan_descriptors(void)
799 struct vkd3d_shader_scan_descriptor_info descriptor_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO};
800 struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
801 struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
802 struct vkd3d_shader_code dxbc;
803 size_t i, j;
804 int rc;
806 static const char ps1_source[] =
807 "float4 main(uniform float4 u, uniform float4 v) : sv_target\n"
808 "{\n"
809 " return u * v + 1.0;\n"
810 "}";
812 static const char ps2_source[] =
813 "float4 main() : sv_target\n"
814 "{\n"
815 " return 1.0;\n"
816 "}";
818 static const struct vkd3d_shader_descriptor_info ps1_descriptors[] =
820 {VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, 0, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER,
821 VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 1},
824 static const struct
826 const char *source;
827 bool sm4;
828 const char *profile;
829 const struct vkd3d_shader_descriptor_info *descriptors;
830 size_t descriptor_count;
832 tests[] =
834 {ps1_source, false, "ps_2_0", ps1_descriptors, ARRAY_SIZE(ps1_descriptors)},
835 {ps2_source, false, "ps_2_0", NULL, 0},
838 for (i = 0; i < ARRAY_SIZE(tests); ++i)
840 vkd3d_test_push_context("test %u", i);
842 compile_info.source.code = tests[i].source;
843 compile_info.source.size = strlen(tests[i].source);
844 compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
845 compile_info.target_type = tests[i].sm4 ? VKD3D_SHADER_TARGET_DXBC_TPF : VKD3D_SHADER_TARGET_D3D_BYTECODE;
846 compile_info.log_level = VKD3D_SHADER_LOG_INFO;
848 compile_info.next = &hlsl_info;
849 hlsl_info.profile = tests[i].profile;
851 rc = vkd3d_shader_compile(&compile_info, &dxbc, NULL);
852 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
854 compile_info.source_type = tests[i].sm4 ? VKD3D_SHADER_SOURCE_DXBC_TPF : VKD3D_SHADER_SOURCE_D3D_BYTECODE;
855 compile_info.source = dxbc;
857 compile_info.next = &descriptor_info;
859 rc = vkd3d_shader_scan(&compile_info, NULL);
860 ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
862 ok(descriptor_info.descriptor_count == tests[i].descriptor_count,
863 "Got descriptor count %u.\n", descriptor_info.descriptor_count);
864 for (j = 0; j < descriptor_info.descriptor_count; ++j)
866 const struct vkd3d_shader_descriptor_info *descriptor = &descriptor_info.descriptors[j];
867 const struct vkd3d_shader_descriptor_info *expect = &tests[i].descriptors[j];
869 vkd3d_test_push_context("descriptor %u", j);
871 ok(descriptor->type == expect->type, "Got type %#x.\n", descriptor->type);
872 ok(descriptor->register_space == expect->register_space, "Got space %u.\n", descriptor->register_space);
873 ok(descriptor->register_index == expect->register_index, "Got index %u.\n", descriptor->register_index);
874 ok(descriptor->resource_type == expect->resource_type,
875 "Got resource type %#x.\n", descriptor->resource_type);
876 ok(descriptor->resource_data_type == expect->resource_data_type,
877 "Got data type %#x.\n", descriptor->resource_data_type);
878 ok(descriptor->flags == expect->flags, "Got flags %#x.\n", descriptor->flags);
879 ok(descriptor->count == expect->count, "Got count %u.\n", descriptor->count);
881 vkd3d_test_pop_context();
884 vkd3d_shader_free_scan_descriptor_info(&descriptor_info);
885 vkd3d_shader_free_shader_code(&dxbc);
887 vkd3d_test_pop_context();
891 static void test_build_varying_map(void)
893 struct vkd3d_shader_signature_element output_elements[] =
895 {"position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
896 {"texcoord", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
897 {"colour", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
899 struct vkd3d_shader_signature_element input_elements[] =
901 {"colour", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
902 {"texcoord", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0x3, 0x3},
904 struct vkd3d_shader_signature output = {output_elements, ARRAY_SIZE(output_elements)};
905 struct vkd3d_shader_signature input = {input_elements, ARRAY_SIZE(input_elements)};
906 PFN_vkd3d_shader_build_varying_map pfn_vkd3d_shader_build_varying_map;
907 struct vkd3d_shader_varying_map map[ARRAY_SIZE(input_elements)];
908 unsigned int count;
910 pfn_vkd3d_shader_build_varying_map = vkd3d_shader_build_varying_map;
911 pfn_vkd3d_shader_build_varying_map(&output, &input, &count, map);
912 ok(count == ARRAY_SIZE(input_elements), "Got count %u.\n", count);
913 ok(map[0].output_signature_index == 2, "Got map[0].output_signature_index %u.\n", map[0].output_signature_index);
914 ok(map[0].input_register_index == 3, "Got map[0].input_register_index %u.\n", map[0].input_register_index);
915 ok(map[0].input_mask == 0xf, "Got map[0].input_mask %#x.\n", map[0].input_mask);
916 ok(map[1].output_signature_index == 1, "Got map[1].output_signature_index %u.\n", map[1].output_signature_index);
917 ok(map[1].input_register_index == 4, "Got map[1].input_register_index %u.\n", map[1].input_register_index);
918 ok(map[1].input_mask == 0x3, "Got map[1].input_mask %#x.\n", map[1].input_mask);
921 static void test_scan_combined_resource_samplers(void)
923 struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
924 struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
925 PFN_vkd3d_shader_free_scan_combined_resource_sampler_info pfn_free_combined_sampler_info;
926 struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info;
927 struct vkd3d_shader_combined_resource_sampler_info *s;
928 struct vkd3d_shader_code d3dbc;
929 int rc;
931 static const char ps_3_0_source[] =
932 "sampler s[3];\n"
933 "\n"
934 "float4 main(float4 coord : TEXCOORD) : COLOR\n"
935 "{\n"
936 " float4 r;\n"
937 "\n"
938 " r = tex2D(s[0], coord.xy);\n"
939 " r += tex2D(s[2], coord.xy);\n"
940 "\n"
941 " return r;\n"
942 "}\n";
944 static const uint32_t ps_5_1[] =
946 #if 0
947 Texture2D<float4> t0[8] : register(t8, space4);
948 Texture2D<float4> t1[4] : register(t9, space5);
949 SamplerState s2[4] : register(s10, space6);
950 SamplerState s3[8] : register(s11, space7);
952 float4 main(float4 coord : TEXCOORD) : SV_TARGET
954 float4 r;
956 r = t0[7].Sample(s2[3], coord.xy);
957 r += t1[2].Sample(s3[6], coord.xy);
958 r += t0[4].Load(coord.xyz);
960 return r;
962 #endif
963 0x43425844, 0x743f5994, 0x0c6d43cf, 0xde114c10, 0xc1adc69a, 0x00000001, 0x000001f8, 0x00000003,
964 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
965 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000070f, 0x43584554, 0x44524f4f, 0xababab00,
966 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
967 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x0000015c, 0x00000051,
968 0x00000057, 0x0100086a, 0x0600005a, 0x00306e46, 0x00000000, 0x0000000a, 0x0000000d, 0x00000006,
969 0x0600005a, 0x00306e46, 0x00000001, 0x0000000b, 0x00000012, 0x00000007, 0x07001858, 0x00307e46,
970 0x00000000, 0x00000008, 0x0000000f, 0x00005555, 0x00000004, 0x07001858, 0x00307e46, 0x00000001,
971 0x00000009, 0x0000000c, 0x00005555, 0x00000005, 0x03001062, 0x00101072, 0x00000000, 0x03000065,
972 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0b000045, 0x001000f2, 0x00000000, 0x00101046,
973 0x00000000, 0x00207e46, 0x00000000, 0x0000000f, 0x00206000, 0x00000000, 0x0000000d, 0x0b000045,
974 0x001000f2, 0x00000001, 0x00101046, 0x00000000, 0x00207e46, 0x00000001, 0x0000000b, 0x00206000,
975 0x00000001, 0x00000011, 0x07000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46,
976 0x00000001, 0x0500001b, 0x001000f2, 0x00000001, 0x00101a46, 0x00000000, 0x0800002d, 0x001000f2,
977 0x00000001, 0x00100e46, 0x00000001, 0x00207e46, 0x00000000, 0x0000000c, 0x07000000, 0x001020f2,
978 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e,
981 pfn_free_combined_sampler_info = vkd3d_shader_free_scan_combined_resource_sampler_info;
983 hlsl_info.profile = "ps_3_0";
985 info.next = &hlsl_info;
986 info.source.code = ps_3_0_source;
987 info.source.size = ARRAY_SIZE(ps_3_0_source);
988 info.source_type = VKD3D_SHADER_SOURCE_HLSL;
989 info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
990 info.log_level = VKD3D_SHADER_LOG_INFO;
992 rc = vkd3d_shader_compile(&info, &d3dbc, NULL);
993 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
995 combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO;
996 combined_sampler_info.next = NULL;
998 info.next = &combined_sampler_info;
999 info.source = d3dbc;
1000 info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
1001 info.target_type = VKD3D_SHADER_TARGET_NONE;
1003 rc = vkd3d_shader_scan(&info, NULL);
1004 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
1005 ok(combined_sampler_info.combined_sampler_count == 2, "Got combined_sampler_count %u.\n",
1006 combined_sampler_info.combined_sampler_count);
1007 s = &combined_sampler_info.combined_samplers[0];
1008 ok(s->resource_space == 0, "Got resource space %u.\n", s->resource_space);
1009 ok(s->resource_index == 0, "Got resource index %u.\n", s->resource_index);
1010 ok(s->sampler_space == 0, "Got sampler space %u.\n", s->sampler_space);
1011 ok(s->sampler_index == 0, "Got sampler index %u.\n", s->sampler_index);
1012 s = &combined_sampler_info.combined_samplers[1];
1013 ok(s->resource_space == 0, "Got resource space %u.\n", s->resource_space);
1014 ok(s->resource_index == 2, "Got resource index %u.\n", s->resource_index);
1015 ok(s->sampler_space == 0, "Got sampler space %u.\n", s->sampler_space);
1016 ok(s->sampler_index == 2, "Got sampler index %u.\n", s->sampler_index);
1017 pfn_free_combined_sampler_info(&combined_sampler_info);
1019 vkd3d_shader_free_shader_code(&d3dbc);
1021 info.source.code = ps_5_1;
1022 info.source.size = sizeof(ps_5_1);
1023 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
1025 rc = vkd3d_shader_scan(&info, NULL);
1026 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
1027 ok(combined_sampler_info.combined_sampler_count == 3, "Got combined_sampler_count %u.\n",
1028 combined_sampler_info.combined_sampler_count);
1029 s = &combined_sampler_info.combined_samplers[0];
1030 ok(s->resource_space == 4, "Got resource space %u.\n", s->resource_space);
1031 ok(s->resource_index == 15, "Got resource index %u.\n", s->resource_index);
1032 ok(s->sampler_space == 6, "Got sampler space %u.\n", s->sampler_space);
1033 ok(s->sampler_index == 13, "Got sampler index %u.\n", s->sampler_index);
1034 s = &combined_sampler_info.combined_samplers[1];
1035 ok(s->resource_space == 5, "Got resource space %u.\n", s->resource_space);
1036 ok(s->resource_index == 11, "Got resource index %u.\n", s->resource_index);
1037 ok(s->sampler_space == 7, "Got sampler space %u.\n", s->sampler_space);
1038 ok(s->sampler_index == 17, "Got sampler index %u.\n", s->sampler_index);
1039 s = &combined_sampler_info.combined_samplers[2];
1040 ok(s->resource_space == 4, "Got resource space %u.\n", s->resource_space);
1041 ok(s->resource_index == 12, "Got resource index %u.\n", s->resource_index);
1042 ok(s->sampler_space == 0, "Got sampler space %u.\n", s->sampler_space);
1043 ok(s->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX, "Got sampler index %u.\n", s->sampler_index);
1044 pfn_free_combined_sampler_info(&combined_sampler_info);
1047 static void test_emit_signature(void)
1049 static const uint32_t dxbc_minprec[] =
1051 0x43425844, 0xec41e0af, 0x4d0f3dea, 0x33b9c460, 0x178f7734, 0x00000001, 0x00000310, 0x00000006,
1052 0x00000038, 0x000000b0, 0x00000124, 0x00000160, 0x00000264, 0x00000274, 0x46454452, 0x00000070,
1053 0x00000000, 0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452,
1054 0x0000003c, 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d,
1055 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265,
1056 0x2e302e30, 0x31303031, 0x36312e31, 0x00343833, 0x31475349, 0x0000006c, 0x00000003, 0x00000008,
1057 0x00000000, 0x00000068, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000002,
1058 0x00000000, 0x00000068, 0x00000001, 0x00000000, 0x00000002, 0x00000001, 0x00000f0f, 0x00000004,
1059 0x00000000, 0x00000068, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000f0f, 0x00000005,
1060 0x006d6573, 0x3147534f, 0x00000034, 0x00000001, 0x00000008, 0x00000000, 0x00000028, 0x00000000,
1061 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000001, 0x745f7673, 0x65677261, 0xabab0074,
1062 0x58454853, 0x000000fc, 0x00000050, 0x0000003f, 0x0101086a, 0x04001062, 0x801010f2, 0x00008001,
1063 0x00000000, 0x04000862, 0x801010f2, 0x00010001, 0x00000001, 0x04000862, 0x801010f2, 0x00014001,
1064 0x00000002, 0x04000065, 0x801020f2, 0x00004001, 0x00000000, 0x02000068, 0x00000002, 0x0700002b,
1065 0x801000f2, 0x00008001, 0x00000000, 0x80101e46, 0x00010001, 0x00000001, 0x0a000000, 0x801000f2,
1066 0x00008001, 0x00000000, 0x80100e46, 0x00008001, 0x00000000, 0x80101e46, 0x00008001, 0x00000000,
1067 0x07000056, 0x801000f2, 0x00008001, 0x00000001, 0x80101e46, 0x00014001, 0x00000002, 0x0a000000,
1068 0x801000f2, 0x00008001, 0x00000000, 0x80100e46, 0x00008001, 0x00000000, 0x80100e46, 0x00008001,
1069 0x00000001, 0x07000036, 0x801020f2, 0x00004001, 0x00000000, 0x80100e46, 0x00008001, 0x00000000,
1070 0x0100003e, 0x30494653, 0x00000008, 0x00000010, 0x00000000, 0x54415453, 0x00000094, 0x00000006,
1071 0x00000002, 0x00000000, 0x00000004, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
1072 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1073 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
1074 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1075 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1077 static const uint32_t dxbc_big[] =
1079 0x43425844, 0xe2dff764, 0xaee92ec8, 0xefa3485b, 0x37f05d58, 0x00000001, 0x000005f4, 0x00000005,
1080 0x00000034, 0x000000ac, 0x00000234, 0x000002a0, 0x00000558, 0x46454452, 0x00000070, 0x00000000,
1081 0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c,
1082 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f,
1083 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x2e302e30,
1084 0x31303031, 0x36312e31, 0x00343833, 0x4e475349, 0x00000180, 0x0000000b, 0x00000008, 0x00000110,
1085 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000090f, 0x0000011c, 0x00000002, 0x00000000,
1086 0x00000003, 0x00000001, 0x00000607, 0x0000011c, 0x00000005, 0x00000000, 0x00000001, 0x00000002,
1087 0x00000103, 0x00000122, 0x00000000, 0x00000007, 0x00000001, 0x00000002, 0x00000404, 0x00000131,
1088 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000008, 0x0000013f, 0x00000000, 0x00000002,
1089 0x00000003, 0x00000003, 0x00000103, 0x0000014f, 0x00000000, 0x00000003, 0x00000003, 0x00000003,
1090 0x00000404, 0x0000014f, 0x00000001, 0x00000003, 0x00000003, 0x00000003, 0x00000808, 0x0000013f,
1091 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000507, 0x0000015f, 0x00000000, 0x00000009,
1092 0x00000001, 0x00000005, 0x00000101, 0x0000016e, 0x00000000, 0x0000000a, 0x00000001, 0x00000005,
1093 0x00000202, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x56530052, 0x6972505f, 0x6974696d,
1094 0x44496576, 0x5f565300, 0x74736e49, 0x65636e61, 0x53004449, 0x6c435f56, 0x69447069, 0x6e617473,
1095 0x53006563, 0x75435f56, 0x69446c6c, 0x6e617473, 0x53006563, 0x73495f56, 0x6e6f7246, 0x63614674,
1096 0x56530065, 0x6d61535f, 0x49656c70, 0x7865646e, 0xababab00, 0x4e47534f, 0x00000064, 0x00000003,
1097 0x00000008, 0x00000050, 0x00000001, 0x00000000, 0x00000002, 0x00000001, 0x00000a07, 0x00000050,
1098 0x00000005, 0x00000000, 0x00000003, 0x00000005, 0x00000e01, 0x0000005a, 0x00000000, 0x00000000,
1099 0x00000003, 0xffffffff, 0x00000e01, 0x545f5653, 0x65677261, 0x56530074, 0x7065445f, 0xab006874,
1100 0x58454853, 0x000002b0, 0x00000050, 0x000000ac, 0x0100086a, 0x04002064, 0x00101092, 0x00000000,
1101 0x00000001, 0x03001062, 0x00101062, 0x00000001, 0x03000862, 0x00101012, 0x00000002, 0x04000863,
1102 0x00101042, 0x00000002, 0x00000007, 0x04001064, 0x00101012, 0x00000003, 0x00000002, 0x04001064,
1103 0x00101042, 0x00000003, 0x00000003, 0x04001064, 0x00101082, 0x00000003, 0x00000003, 0x04001064,
1104 0x00101052, 0x00000004, 0x00000002, 0x04000863, 0x00101012, 0x00000005, 0x00000009, 0x04000863,
1105 0x00101022, 0x00000005, 0x0000000a, 0x03000065, 0x00102052, 0x00000001, 0x03000065, 0x00102012,
1106 0x00000005, 0x02000065, 0x0000c001, 0x02000068, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
1107 0x0010102a, 0x00000001, 0x0010101a, 0x00000001, 0x05000056, 0x00100022, 0x00000000, 0x0010100a,
1108 0x00000002, 0x07000000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000,
1109 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000000, 0x07000000,
1110 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010103a, 0x00000000, 0x07000000, 0x00100012,
1111 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000003, 0x07000000, 0x00100012, 0x00000000,
1112 0x0010000a, 0x00000000, 0x0010100a, 0x00000004, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
1113 0x00000000, 0x0010102a, 0x00000004, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
1114 0x0010102a, 0x00000003, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010103a,
1115 0x00000003, 0x05000056, 0x00100022, 0x00000000, 0x0010102a, 0x00000002, 0x07000000, 0x00100012,
1116 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x07000001, 0x00100022, 0x00000000,
1117 0x0010100a, 0x00000005, 0x00004001, 0x3f800000, 0x07000000, 0x00100012, 0x00000000, 0x0010001a,
1118 0x00000000, 0x0010000a, 0x00000000, 0x05000056, 0x00100022, 0x00000000, 0x0010101a, 0x00000005,
1119 0x07000000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0500001b,
1120 0x00102052, 0x00000001, 0x00100006, 0x00000000, 0x05000036, 0x00102012, 0x00000005, 0x0010000a,
1121 0x00000000, 0x04000036, 0x0000c001, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000094,
1122 0x00000014, 0x00000001, 0x00000000, 0x0000000d, 0x0000000c, 0x00000000, 0x00000001, 0x00000001,
1123 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1124 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000000,
1125 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
1126 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1128 static const uint32_t dxbc_depthge[] =
1130 0x43425844, 0x520689ae, 0xf26554e6, 0x8f1d15ed, 0xcdf56fa5, 0x00000001, 0x000002a4, 0x00000006,
1131 0x00000038, 0x000000b0, 0x000000c0, 0x0000016c, 0x000001f8, 0x00000208, 0x46454452, 0x00000070,
1132 0x00000000, 0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452,
1133 0x0000003c, 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d,
1134 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265,
1135 0x2e302e30, 0x31303031, 0x36312e31, 0x00343833, 0x4e475349, 0x00000008, 0x00000000, 0x00000008,
1136 0x4e47534f, 0x000000a4, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x00000000, 0x00000003,
1137 0x00000000, 0x0000000f, 0x00000072, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, 0x00000e01,
1138 0x00000087, 0x00000000, 0x00000000, 0x00000001, 0xffffffff, 0x00000e01, 0x00000093, 0x00000000,
1139 0x00000000, 0x00000003, 0xffffffff, 0x00000e01, 0x545f5653, 0x65677261, 0x56530074, 0x5045445f,
1140 0x72474854, 0x65746165, 0x75714572, 0x73006c61, 0x6f635f76, 0x41726576, 0x73004547, 0x74735f76,
1141 0x69636e65, 0x6665726c, 0xababab00, 0x58454853, 0x00000084, 0x00000050, 0x00000021, 0x0100086a,
1142 0x03000065, 0x001020f2, 0x00000000, 0x02000065, 0x00026001, 0x02000065, 0x0000f000, 0x02000065,
1143 0x00029001, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x40000000, 0x40400000,
1144 0x40800000, 0x04000036, 0x00026001, 0x00004001, 0x3f000000, 0x04000036, 0x0000f001, 0x00004001,
1145 0x00000003, 0x04000036, 0x00029001, 0x00004001, 0x3f333333, 0x0100003e, 0x30494653, 0x00000008,
1146 0x00000200, 0x00000000, 0x54415453, 0x00000094, 0x00000005, 0x00000000, 0x00000000, 0x00000004,
1147 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1148 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
1149 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1150 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1151 0x00000000,
1153 static const uint32_t dxbc_depthle[] =
1155 0x43425844, 0x621ee545, 0x22c68205, 0x48945607, 0xc76952a8, 0x00000001, 0x00000238, 0x00000005,
1156 0x00000034, 0x000000ac, 0x000000bc, 0x00000118, 0x0000019c, 0x46454452, 0x00000070, 0x00000000,
1157 0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c,
1158 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f,
1159 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x2e302e30,
1160 0x31303031, 0x36312e31, 0x00343833, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
1161 0x00000054, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
1162 0x0000000f, 0x00000042, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, 0x00000e01, 0x545f5653,
1163 0x65677261, 0x56530074, 0x5045445f, 0x656c4854, 0x51457373, 0x004c4155, 0x58454853, 0x0000007c,
1164 0x00000050, 0x0000001f, 0x0100086a, 0x0200005f, 0x00023001, 0x03000065, 0x001020f2, 0x00000000,
1165 0x02000065, 0x00027001, 0x02000068, 0x00000001, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
1166 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x04000056, 0x00100012, 0x00000000, 0x0002300a,
1167 0x06000000, 0x00027001, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x0100003e, 0x54415453,
1168 0x00000094, 0x00000004, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
1169 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000,
1171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1172 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1174 static const uint32_t dxbc_gs[] =
1176 0x43425844, 0xe27a1766, 0x53623db9, 0x85065db9, 0x79f2e81e, 0x00000001, 0x00000324, 0x00000005,
1177 0x00000034, 0x000000ac, 0x000000dc, 0x00000174, 0x00000288, 0x46454452, 0x00000070, 0x00000000,
1178 0x00000000, 0x00000000, 0x0000003c, 0x47530500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c,
1179 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f,
1180 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x2e302e30,
1181 0x31303031, 0x36312e31, 0x00343833, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
1182 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x7a6d6573, 0xababab00, 0x3547534f,
1183 0x00000090, 0x00000004, 0x00000008, 0x00000000, 0x00000078, 0x00000000, 0x00000001, 0x00000003,
1184 0x00000000, 0x0000000f, 0x00000000, 0x00000084, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
1185 0x0000000f, 0x00000001, 0x00000078, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
1186 0x00000001, 0x00000089, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653,
1187 0x5449534f, 0x004e4f49, 0x786d6573, 0x6d657300, 0xabab0079, 0x58454853, 0x0000010c, 0x00020050,
1188 0x00000043, 0x0100086a, 0x0400005f, 0x002010f2, 0x00000003, 0x00000000, 0x0100185d, 0x0300008f,
1189 0x00110000, 0x00000000, 0x0100085c, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065,
1190 0x001020f2, 0x00000001, 0x0300008f, 0x00110000, 0x00000001, 0x0100085c, 0x04000067, 0x001020f2,
1191 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x0200005e, 0x0000000c, 0x08000036,
1192 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x06000036,
1193 0x001020f2, 0x00000001, 0x00201e46, 0x00000000, 0x00000000, 0x03000075, 0x00110000, 0x00000000,
1194 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x41300000, 0x41400000, 0x41500000, 0x41600000,
1195 0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000001, 0x00000000, 0x03000075, 0x00110000,
1196 0x00000001, 0x0100003e, 0x54415453, 0x00000094, 0x00000007, 0x00000000, 0x00000000, 0x00000005,
1197 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1198 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1199 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000c, 0x00000000, 0x00000000,
1200 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1201 0x00000000,
1204 static const struct emit_signature_test
1206 const char *profile;
1207 const struct vkd3d_shader_code dxbc;
1208 const char *source;
1209 const char *signature;
1210 bool is_todo;
1211 } tests[] =
1214 "ps_5_0",
1215 {NULL, 0},
1216 "float4 main() : SV_Target\n"
1217 "{\n"
1218 " return float4(1.0, 2.0, 3.0, 4.0);\n"
1219 "}\n",
1220 "ps_5_0\n"
1221 ".output\n"
1222 ".param SV_Target.xyzw, o0.xyzw, float, TARGET\n",
1223 false
1226 "ps_5_0",
1227 {dxbc_minprec, sizeof(dxbc_minprec)},
1228 "min16float4 main(min10float4 x : sem0, min16int4 y : sem1, min16uint4 z : sem2) : sv_target\n"
1229 "{\n"
1230 " return x + y + z;\n"
1231 "}\n",
1232 "ps_5_0\n"
1233 ".input\n"
1234 ".param sem.xyzw, v0.xyzw, float, NONE, FIXED_8_2\n"
1235 ".param sem1.xyzw, v1.xyzw, int, NONE, INT_16\n"
1236 ".param sem2.xyzw, v2.xyzw, uint, NONE, UINT_16\n"
1237 ".output\n"
1238 ".param sv_target.xyzw, o0.xyzw, float, TARGET, FLOAT_16\n",
1239 false
1242 "ps_5_0",
1243 {NULL, 0},
1244 "void main(float4 pos : SV_POSITION, float3 color : COLOR2, uint2 color2 : COLOR5,\n"
1245 " out int3 target : sv_target1, out float target2 : SV_TaRgEt5)\n"
1246 "{\n"
1247 " float tmp = length(pos) + length(color) + length(color2);\n"
1248 " target.xyz = tmp;\n"
1249 " target2 = tmp;\n"
1250 "}\n",
1251 "ps_5_0\n"
1252 ".input\n"
1253 ".param SV_POSITION.xyzw, v0.xyzw, float, POS\n"
1254 ".param COLOR2.xyz, v1.xyz, float\n"
1255 ".param COLOR5.xy, v2.xy, uint\n"
1256 ".output\n"
1257 ".param sv_target1.xyz, o1.xyz, int, TARGET\n"
1258 ".param SV_TaRgEt5.x, o5.x, float, TARGET\n",
1259 false
1262 "ps_5_0",
1263 {NULL, 0},
1264 "void main(float4 pos : SV_Position, float3 color : COLOR2, uint2 color2 : COLOR5,\n"
1265 " out int3 target : SV_Target1, out float target2 : SV_Target5)\n"
1266 "{\n"
1267 " float tmp = pos.x + pos.w + color.y + color.z + color2.x;\n"
1268 " target.xz = tmp;\n"
1269 " target2 = tmp;\n"
1270 "}\n",
1271 "ps_5_0\n"
1272 ".input\n"
1273 ".param SV_Position.xyzw, v0.xw, float, POS\n"
1274 ".param COLOR2.xyz, v1.yz, float\n"
1275 ".param COLOR5.xy, v2.x, uint\n"
1276 ".output\n"
1277 ".param SV_Target1.xyz, o1.xz, int, TARGET\n"
1278 ".param SV_Target5.x, o5.x, float, TARGET\n",
1279 true
1282 "ps_5_0",
1283 {dxbc_big, sizeof(dxbc_big)},
1284 "void main(float4 pos : SV_Position, float3 color : COLOR2, uint2 color2 : COLOR5,\n"
1285 " float2 clip : SV_ClipDistance0, float3 clip2 : SV_ClipDistance1,\n"
1286 " float1 cull : SV_CullDistance0, float cull2 : SV_CullDistance1,\n"
1287 " uint prim : SV_PrimitiveID, uint inst : SV_InstanceID,\n"
1288 " bool front : SV_IsFrontFace0, uint sample : SV_SampleIndex,\n"
1289 " out int3 target : SV_Target1, out float target2 : SV_Target5,\n"
1290 " out float depth : SV_Depth)\n"
1291 "{\n"
1292 " float tmp = color.y + color.z + color2 + pos.x + pos.w + clip.x + clip2.x + clip2.z\n"
1293 " + cull.x + cull2 + prim + front + sample;\n"
1294 " target.xz = tmp;\n"
1295 " target2 = tmp;\n"
1296 " depth = tmp;\n"
1297 "}\n",
1298 "ps_5_0\n"
1299 ".input\n"
1300 ".param SV_Position.xyzw, v0.xw, float, POS\n"
1301 ".param COLOR2.xyz, v1.yz, float\n"
1302 ".param COLOR5.xy, v2.x, uint\n"
1303 ".param SV_PrimitiveID.z, v2.z, uint, PRIMID\n"
1304 ".param SV_InstanceID.w, v2.w, uint\n"
1305 ".param SV_ClipDistance.xy, v3.x, float, CLIPDST\n"
1306 ".param SV_CullDistance.z, v3.z, float, CULLDST\n"
1307 ".param SV_CullDistance1.w, v3.w, float, CULLDST\n"
1308 ".param SV_ClipDistance1.xyz, v4.xz, float, CLIPDST\n"
1309 ".param SV_IsFrontFace.x, v5.x, uint, FFACE\n"
1310 ".param SV_SampleIndex.y, v5.y, uint, SAMPLE\n"
1311 ".output\n"
1312 ".param SV_Target1.xyz, o1.xz, int, TARGET\n"
1313 ".param SV_Target5.x, o5.x, float, TARGET\n"
1314 ".param SV_Depth, oDepth, float, DEPTH\n",
1315 true
1318 "ps_5_0",
1319 {dxbc_depthge, sizeof(dxbc_depthge)},
1320 "float4 main(out float depth : SV_DEPTHGreaterEqual, out uint cov : sv_coverAGE,\n"
1321 " out float stref : sv_stencilref) : SV_Target\n"
1322 "{\n"
1323 " depth = 0.5;\n"
1324 " cov = 3;\n"
1325 " stref = 0.7;\n"
1326 " return float4(1.0, 2.0, 3.0, 4.0);\n"
1327 "}\n",
1328 "ps_5_0\n"
1329 ".output\n"
1330 ".param SV_Target.xyzw, o0.xyzw, float, TARGET\n"
1331 ".param SV_DEPTHGreaterEqual, oDepthGE, float, DEPTHGE\n"
1332 ".param sv_coverAGE, oMask, uint, COVERAGE\n"
1333 ".param sv_stencilref, oStencilRef, float, STENCILREF\n",
1334 false
1337 "ps_5_0",
1338 {dxbc_depthle, sizeof(dxbc_depthle)},
1339 "float4 main(out float depth : SV_DEPTHlessEQUAL, uint cov : sv_coverage) : SV_Target\n"
1340 "{\n"
1341 " depth = 0.5 + cov;\n"
1342 " return float4(1.0, 2.0, 3.0, 4.0);\n"
1343 "}\n",
1344 "ps_5_0\n"
1345 ".output\n"
1346 ".param SV_Target.xyzw, o0.xyzw, float, TARGET\n"
1347 ".param SV_DEPTHlessEQUAL, oDepthLE, float, DEPTHLE\n",
1348 false
1351 "hs_5_0",
1352 {NULL, 0},
1353 "struct input_data\n"
1354 "{\n"
1355 " float4 x : semx;\n"
1356 "};\n"
1357 "\n"
1358 "struct constant_data\n"
1359 "{\n"
1360 " float edges[4] : SV_TessFactor;\n"
1361 " float inside[2] : SV_InsideTessFactor;\n"
1362 " float4 x : semx;\n"
1363 "};\n"
1364 "\n"
1365 "struct control_point_data\n"
1366 "{\n"
1367 " float4 x : semx;\n"
1368 "};\n"
1369 "\n"
1370 "constant_data patch_constant(InputPatch<input_data, 22> ip, uint patch_id : SV_PrimitiveID)\n"
1371 "{\n"
1372 " constant_data ret;\n"
1373 " ret.edges[0] = 0.1;\n"
1374 " ret.edges[1] = 0.2;\n"
1375 " ret.edges[2] = 0.3;\n"
1376 " ret.edges[3] = 0.4;\n"
1377 " ret.inside[0] = 0.5;\n"
1378 " ret.inside[1] = 0.6;\n"
1379 " ret.x = ip[patch_id].x;\n"
1380 " return ret;\n"
1381 "}\n"
1382 "\n"
1383 "[domain(\"quad\")]\n"
1384 "[partitioning(\"integer\")]\n"
1385 "[outputtopology(\"triangle_cw\")]\n"
1386 "[outputcontrolpoints(16)]\n"
1387 "[patchconstantfunc(\"patch_constant\")]\n"
1388 "control_point_data main(InputPatch<input_data, 22> ip, uint i : SV_OutputControlPointID, \n"
1389 " uint patch_id : SV_PrimitiveID)\n"
1390 "{\n"
1391 " control_point_data ret;\n"
1392 " ret.x = ip[i].x + float4(i, patch_id, 0, 0);\n"
1393 " return ret;\n"
1394 "}\n",
1395 "hs_5_0\n"
1396 ".input\n"
1397 ".param semx.xyzw, v0.xyzw, float\n"
1398 ".output\n"
1399 ".param semx.xyzw, o0.xyzw, float\n"
1400 ".patch_constant\n"
1401 ".param SV_TessFactor.x, o0.x, float, QUADEDGE\n"
1402 ".param SV_TessFactor1.x, o1.x, float, QUADEDGE\n"
1403 ".param SV_TessFactor2.x, o2.x, float, QUADEDGE\n"
1404 ".param SV_TessFactor3.x, o3.x, float, QUADEDGE\n"
1405 ".param SV_InsideTessFactor.x, o4.x, float, QUADINT\n"
1406 ".param SV_InsideTessFactor1.x, o5.x, float, QUADINT\n"
1407 ".param semx.xyzw, o6.xyzw, float\n",
1408 false
1411 "ds_5_0",
1412 {NULL, 0},
1413 "struct constant_data\n"
1414 "{\n"
1415 " float edges[4] : SV_TessFactor;\n"
1416 " float inside[2] : SV_InsideTessFactor;\n"
1417 " float4 x : semx;\n"
1418 "};\n"
1419 "\n"
1420 "struct control_point_data\n"
1421 "{\n"
1422 " float4 x : semx;\n"
1423 "};\n"
1424 "\n"
1425 "[domain(\"quad\")]\n"
1426 "float4 main(constant_data input, float2 location : SV_DomainLocation,\n"
1427 " const OutputPatch<control_point_data, 16> patch) : SV_position\n"
1428 "{\n"
1429 " return float4(location, 3.0, 4.0) + input.x + input.edges[2] + input.inside[0] + patch[4].x;\n"
1430 "}\n",
1431 "ds_5_0\n"
1432 ".input\n"
1433 ".param semx.xyzw, vicp0.xyzw, float\n"
1434 ".output\n"
1435 ".param SV_position.xyzw, o0.xyzw, float, POS\n"
1436 ".patch_constant\n"
1437 ".param SV_TessFactor.x, vpc0, float, QUADEDGE\n"
1438 ".param SV_TessFactor1.x, vpc1, float, QUADEDGE\n"
1439 ".param SV_TessFactor2.x, vpc2.x, float, QUADEDGE\n"
1440 ".param SV_TessFactor3.x, vpc3, float, QUADEDGE\n"
1441 ".param SV_InsideTessFactor.x, vpc4.x, float, QUADINT\n"
1442 ".param SV_InsideTessFactor1.x, vpc5, float, QUADINT\n"
1443 ".param semx.xyzw, vpc6.xyzw, float\n",
1444 true
1447 "gs_5_0",
1448 {dxbc_gs, sizeof(dxbc_gs)},
1449 "struct input_data\n"
1450 "{\n"
1451 " float4 z : semz;\n"
1452 "};\n"
1453 "\n"
1454 "struct output_data\n"
1455 "{\n"
1456 " float4 pos : SV_POSITION;\n"
1457 " float4 x : semx;\n"
1458 "};\n"
1459 "struct output_data2\n"
1460 "{\n"
1461 " float4 pos : SV_POSITION;\n"
1462 " float4 y : semy;\n"
1463 "};\n"
1464 "\n"
1465 "[maxvertexcount(12)]\n"
1466 "void main(triangle input_data input[3], inout PointStream<output_data> s, inout PointStream<output_data2> s2)\n"
1467 "{\n"
1468 " output_data output;\n"
1469 " output.pos = float4(1.0, 2.0, 3.0, 4.0);\n"
1470 " output.x = input[0].z;\n"
1471 " s.Append(output);\n"
1472 " output_data2 output2;\n"
1473 " output2.pos = float4(11.0, 12.0, 13.0, 14.0);\n"
1474 " output2.y = input[1].z;\n"
1475 " s2.Append(output2);\n"
1476 "}\n",
1477 "gs_5_0\n"
1478 ".input\n"
1479 ".param semz.xyzw, v0.xyzw, float\n"
1480 ".output\n"
1481 ".param SV_POSITION.xyzw, o0.xyzw, float, POS\n"
1482 ".param semx.xyzw, o1.xyzw, float\n"
1483 ".param SV_POSITION.xyzw, o0.xyzw, float, POS, NONE, m1\n"
1484 ".param semy.xyzw, o1.xyzw, float, NONE, NONE, m1\n",
1485 false
1489 struct vkd3d_shader_hlsl_source_info hlsl_info =
1491 .type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO,
1492 .entry_point = "main",
1494 struct vkd3d_shader_compile_info compile_info =
1496 .type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
1497 .next = &hlsl_info,
1498 .source_type = VKD3D_SHADER_SOURCE_HLSL,
1499 .target_type = VKD3D_SHADER_TARGET_DXBC_TPF,
1500 .log_level = VKD3D_SHADER_LOG_NONE,
1502 struct vkd3d_shader_compile_option disassemble_options[] =
1505 .name = VKD3D_SHADER_COMPILE_OPTION_FORMATTING,
1506 .value = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES
1509 struct vkd3d_shader_compile_info disassemble_info =
1511 .type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
1512 .source_type = VKD3D_SHADER_SOURCE_DXBC_TPF,
1513 .target_type = VKD3D_SHADER_TARGET_D3D_ASM,
1514 .options = disassemble_options,
1515 .option_count = ARRAY_SIZE(disassemble_options),
1516 .log_level = VKD3D_SHADER_LOG_NONE,
1518 struct vkd3d_shader_code dxbc, disasm;
1519 unsigned int i;
1520 char *ptr;
1521 int rc;
1523 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1525 const struct emit_signature_test *test = &tests[i];
1527 vkd3d_test_push_context("%u", i);
1529 if (test->dxbc.size == 0)
1531 hlsl_info.profile = test->profile;
1532 compile_info.source.code = test->source;
1533 compile_info.source.size = strlen(test->source);
1534 rc = vkd3d_shader_compile(&compile_info, &dxbc, NULL);
1535 ok(rc == VKD3D_OK, "Cannot compile HLSL shader, rc %d.\n", rc);
1536 disassemble_info.source = dxbc;
1538 else
1540 disassemble_info.source = test->dxbc;
1543 rc = vkd3d_shader_compile(&disassemble_info, &disasm, NULL);
1544 ok(rc == VKD3D_OK, "Cannot disassemble shader, rc %d.\n", rc);
1546 ptr = strstr(disasm.code, ".text\n");
1547 ok(ptr, "Cannot find text marker in disassembled code.\n");
1548 *ptr = '\0';
1549 todo_if(test->is_todo)
1550 ok(strcmp(disasm.code, test->signature) == 0, "Unexpected signature description.\n");
1552 if (test->dxbc.size == 0)
1553 vkd3d_shader_free_shader_code(&dxbc);
1554 vkd3d_shader_free_shader_code(&disasm);
1556 vkd3d_test_pop_context();
1560 static void test_warning_options(void)
1562 struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
1563 struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
1564 struct vkd3d_shader_compile_option options[1];
1565 struct vkd3d_shader_code d3dbc;
1566 char *messages;
1567 int rc;
1569 static const char ps_source[] =
1570 "float4 main(uniform float4 u) : color\n"
1571 "{\n"
1572 " float3 x = u;\n"
1573 " return 0;\n"
1574 "}\n";
1576 hlsl_info.profile = "ps_2_0";
1578 info.next = &hlsl_info;
1579 info.source.code = ps_source;
1580 info.source.size = ARRAY_SIZE(ps_source);
1581 info.source_type = VKD3D_SHADER_SOURCE_HLSL;
1582 info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
1583 info.log_level = VKD3D_SHADER_LOG_INFO;
1585 rc = vkd3d_shader_compile(&info, &d3dbc, &messages);
1586 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
1587 ok(messages, "Expected messages.\n");
1588 vkd3d_shader_free_shader_code(&d3dbc);
1589 vkd3d_shader_free_messages(messages);
1591 info.options = options;
1592 info.option_count = ARRAY_SIZE(options);
1593 options[0].name = VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION;
1594 options[0].value = 0;
1596 rc = vkd3d_shader_compile(&info, &d3dbc, &messages);
1597 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
1598 ok(!messages, "Expected no messages.\n");
1599 vkd3d_shader_free_shader_code(&d3dbc);
1600 vkd3d_shader_free_messages(messages);
1602 options[0].value = 1;
1604 rc = vkd3d_shader_compile(&info, &d3dbc, &messages);
1605 ok(rc == VKD3D_OK, "Got rc %d.\n", rc);
1606 ok(messages, "Expected messages.\n");
1607 vkd3d_shader_free_shader_code(&d3dbc);
1608 vkd3d_shader_free_messages(messages);
1611 #ifdef HAVE_OPENGL
1612 static PFNGLSPECIALIZESHADERPROC p_glSpecializeShader;
1614 #define RENDER_TARGET_WIDTH 4
1615 #define RENDER_TARGET_HEIGHT 4
1617 struct gl_test_context
1619 EGLContext context;
1620 EGLDisplay display;
1621 GLuint fbo, backbuffer;
1624 static bool check_gl_extension(const char *extension, GLint extension_count)
1626 for (GLint i = 0; i < extension_count; ++i)
1628 if (!strcmp(extension, (const char *)glGetStringi(GL_EXTENSIONS, i)))
1629 return true;
1632 return false;
1635 static bool check_gl_extensions(void)
1637 GLint count;
1639 static const char *required_extensions[] =
1641 "GL_ARB_clip_control",
1642 "GL_ARB_compute_shader",
1643 "GL_ARB_sampler_objects",
1644 "GL_ARB_shader_image_load_store",
1645 "GL_ARB_texture_storage",
1646 "GL_ARB_internalformat_query",
1647 "GL_ARB_gl_spirv",
1650 glGetIntegerv(GL_NUM_EXTENSIONS, &count);
1652 for (unsigned int i = 0; i < ARRAY_SIZE(required_extensions); ++i)
1654 if (!check_gl_extension(required_extensions[i], count))
1655 return false;
1658 return true;
1661 static bool check_gl_client_extension(const char *extension)
1663 const char *extensions, *p;
1664 size_t len;
1666 if (!(extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)))
1667 return false;
1669 len = strlen(extension);
1670 for (;;)
1672 if (!(p = strchr(extensions, ' ')))
1673 p = &extensions[strlen(extensions)];
1674 if (p - extensions == len && !memcmp(extensions, extension, len))
1675 return true;
1676 if (!*p)
1677 break;
1678 extensions = p + 1;
1680 return false;
1683 static void debug_output(GLenum source, GLenum type, GLuint id, GLenum severity,
1684 GLsizei length, const GLchar *message, const void *userParam)
1686 if (message[length - 1] == '\n')
1687 --length;
1688 trace("%.*s\n", length, message);
1691 static bool init_gl_test_context(struct gl_test_context *test_context)
1693 PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
1694 EGLDeviceEXT *devices;
1695 EGLContext context;
1696 EGLDisplay display;
1697 EGLBoolean ret;
1698 EGLint count;
1699 GLuint vao;
1701 static const EGLint attributes[] =
1703 EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
1704 EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
1705 EGL_CONTEXT_MAJOR_VERSION, 3,
1706 EGL_CONTEXT_MINOR_VERSION, 2,
1707 EGL_NONE,
1710 if (!check_gl_client_extension("EGL_EXT_device_enumeration")
1711 || !(eglQueryDevicesEXT = (void *)eglGetProcAddress("eglQueryDevicesEXT")))
1713 skip("Failed to retrieve eglQueryDevicesEXT.\n");
1714 return false;
1717 ret = eglQueryDevicesEXT(0, NULL, &count);
1718 ok(ret, "Failed to query device count.\n");
1720 devices = calloc(count, sizeof(*devices));
1721 ret = eglQueryDevicesEXT(count, devices, &count);
1722 ok(ret, "Failed to query devices.\n");
1724 for (unsigned int i = 0; i < count; ++i)
1726 if ((display = eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, devices[i], NULL)) == EGL_NO_DISPLAY)
1728 trace("Failed to get EGL display connection for device %u.\n", i);
1729 continue;
1732 if (!eglInitialize(display, NULL, NULL))
1734 trace("Failed to initialise EGL display connection for device %u.\n", i);
1735 continue;
1738 if (!eglBindAPI(EGL_OPENGL_API))
1740 trace("Failed to bind OpenGL API for device %u.\n", i);
1741 eglTerminate(display);
1742 continue;
1745 if ((context = eglCreateContext(display, NULL, EGL_NO_CONTEXT, attributes)) == EGL_NO_CONTEXT)
1747 trace("Failed to create EGL context for device %u.\n", i);
1748 eglTerminate(display);
1749 continue;
1752 if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context))
1754 trace("Failed to make EGL context current for device %u.\n", i);
1755 eglDestroyContext(display, context);
1756 eglTerminate(display);
1757 continue;
1760 if (!check_gl_extensions())
1762 trace("Device %u lacks required extensions.\n", i);
1763 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1764 eglDestroyContext(display, context);
1765 eglTerminate(display);
1766 continue;
1769 trace("Using device %u.\n", i);
1770 test_context->display = display;
1771 test_context->context = context;
1772 break;
1775 free(devices);
1777 if (!test_context->context)
1779 skip("Failed to find a usable OpenGL device.\n");
1780 return false;
1783 trace(" GL_VENDOR: %s\n", glGetString(GL_VENDOR));
1784 trace(" GL_RENDERER: %s\n", glGetString(GL_RENDERER));
1785 trace(" GL_VERSION: %s\n", glGetString(GL_VERSION));
1787 p_glSpecializeShader = (void *)eglGetProcAddress("glSpecializeShader");
1789 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE);
1790 glDebugMessageCallback(debug_output, NULL);
1791 glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
1792 glFrontFace(GL_CW);
1793 glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
1794 glGenVertexArrays(1, &vao);
1795 glBindVertexArray(vao);
1797 glGenTextures(1, &test_context->backbuffer);
1798 glBindTexture(GL_TEXTURE_2D, test_context->backbuffer);
1799 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT);
1801 glGenFramebuffers(1, &test_context->fbo);
1802 glBindFramebuffer(GL_FRAMEBUFFER, test_context->fbo);
1803 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, test_context->backbuffer, 0);
1804 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1806 glViewport(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT);
1807 glScissor(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT);
1809 return true;
1812 static void destroy_gl_test_context(struct gl_test_context *context)
1814 EGLBoolean ret;
1816 glDeleteFramebuffers(1, &context->fbo);
1817 glDeleteTextures(1, &context->backbuffer);
1819 ret = eglMakeCurrent(context->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1820 ok(ret, "Failed to release current EGL context.\n");
1821 ret = eglDestroyContext(context->display, context->context);
1822 ok(ret, "Failed to destroy EGL context.\n");
1823 ret = eglTerminate(context->display);
1824 ok(ret, "Failed to terminate EGL display connection.\n");
1827 static void gl_draw_triangle(GLuint vs_id, GLuint fs_id)
1829 GLuint program_id = glCreateProgram();
1830 GLint status;
1832 glAttachShader(program_id, vs_id);
1833 glAttachShader(program_id, fs_id);
1834 glLinkProgram(program_id);
1835 glGetProgramiv(program_id, GL_LINK_STATUS, &status);
1836 ok(status, "Failed to link program.\n");
1838 glUseProgram(program_id);
1839 glDrawArrays(GL_TRIANGLES, 0, 3);
1841 glDeleteProgram(program_id);
1844 static void gl_get_backbuffer_color(struct gl_test_context *context,
1845 unsigned int x, unsigned int y, struct vec4 *colour)
1847 struct vec4 *data = malloc(RENDER_TARGET_WIDTH * RENDER_TARGET_HEIGHT * sizeof(struct vec4));
1849 memset(data, 0xcc, RENDER_TARGET_WIDTH * RENDER_TARGET_HEIGHT * sizeof(struct vec4));
1850 glBindTexture(GL_TEXTURE_2D, context->backbuffer);
1851 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data);
1852 *colour = data[y * RENDER_TARGET_WIDTH + x];
1853 free(data);
1856 #endif
1858 static void test_parameters(void)
1860 #ifdef HAVE_OPENGL
1861 struct vkd3d_shader_spirv_target_info spirv_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO};
1862 struct vkd3d_shader_parameter_info parameter_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO};
1863 struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
1864 struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
1865 GLuint vs_id, fs_id, spec_id, spec_value, ubo_id;
1866 struct vkd3d_shader_code vs_spirv, ps_spirv;
1867 struct vkd3d_shader_parameter1 parameter1;
1868 struct vkd3d_shader_parameter parameter;
1869 uint32_t buffer_data[2] = {0, 5};
1870 struct gl_test_context context;
1871 struct vec4 colour;
1872 char *messages;
1873 GLint status;
1874 int ret;
1876 static const char vs_code[] =
1877 "float4 main(uint id : SV_VertexID) : SV_Position\n"
1878 "{\n"
1879 " float2 coords = float2((id << 1) & 2, id & 2);\n"
1880 " return float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);\n"
1881 "}";
1883 static const char ps_code[] =
1884 "float4 main() : SV_Target\n"
1885 "{\n"
1886 " return GetRenderTargetSampleCount();\n"
1887 "}";
1889 if (!init_gl_test_context(&context))
1890 return;
1892 info.next = &hlsl_info;
1893 info.source_type = VKD3D_SHADER_SOURCE_HLSL;
1894 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
1895 info.log_level = VKD3D_SHADER_LOG_WARNING;
1897 hlsl_info.next = &spirv_info;
1898 hlsl_info.entry_point = "main";
1900 spirv_info.environment = VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5;
1902 info.source.code = vs_code;
1903 info.source.size = strlen(vs_code);
1904 hlsl_info.profile = "vs_4_0";
1905 ret = vkd3d_shader_compile(&info, &vs_spirv, &messages);
1906 ok(!ret, "Failed to compile, error %d.\n", ret);
1907 ok(!messages, "Got unexpected messages.\n");
1909 vs_id = glCreateShader(GL_VERTEX_SHADER);
1910 glShaderBinary(1, &vs_id, GL_SHADER_BINARY_FORMAT_SPIR_V, vs_spirv.code, vs_spirv.size);
1911 p_glSpecializeShader(vs_id, "main", 0, NULL, NULL);
1912 glGetShaderiv(vs_id, GL_COMPILE_STATUS, &status);
1913 ok(status, "Failed to compile vertex shader.\n");
1915 info.source.code = ps_code;
1916 info.source.size = strlen(ps_code);
1917 hlsl_info.profile = "ps_4_1";
1919 /* Immediate constant, old API. */
1921 spirv_info.parameters = &parameter;
1922 spirv_info.parameter_count = 1;
1924 parameter.name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
1925 parameter.type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
1926 parameter.data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
1927 parameter.u.immediate_constant.u.u32 = 2;
1929 ret = vkd3d_shader_compile(&info, &ps_spirv, &messages);
1930 ok(!ret, "Failed to compile, error %d.\n", ret);
1931 ok(!messages, "Got unexpected messages.\n");
1933 fs_id = glCreateShader(GL_FRAGMENT_SHADER);
1934 glShaderBinary(1, &fs_id, GL_SHADER_BINARY_FORMAT_SPIR_V, ps_spirv.code, ps_spirv.size);
1935 p_glSpecializeShader(fs_id, "main", 0, NULL, NULL);
1936 glGetShaderiv(fs_id, GL_COMPILE_STATUS, &status);
1937 ok(status, "Failed to compile fragment shader.\n");
1939 gl_draw_triangle(vs_id, fs_id);
1940 gl_get_backbuffer_color(&context, 0, 0, &colour);
1941 ok(colour.x == 2.0f, "Got colour %.8e.\n", colour.x);
1943 /* Immediate constant, new API. */
1945 spirv_info.next = &parameter_info;
1947 parameter_info.parameter_count = 1;
1948 parameter_info.parameters = &parameter1;
1950 parameter1.name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
1951 parameter1.type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
1952 parameter1.data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
1953 parameter1.u.immediate_constant.u.u32 = 3;
1955 ret = vkd3d_shader_compile(&info, &ps_spirv, &messages);
1956 ok(!ret, "Failed to compile, error %d.\n", ret);
1957 ok(!messages, "Got unexpected messages.\n");
1959 fs_id = glCreateShader(GL_FRAGMENT_SHADER);
1960 glShaderBinary(1, &fs_id, GL_SHADER_BINARY_FORMAT_SPIR_V, ps_spirv.code, ps_spirv.size);
1961 p_glSpecializeShader(fs_id, "main", 0, NULL, NULL);
1962 glGetShaderiv(fs_id, GL_COMPILE_STATUS, &status);
1963 ok(status, "Failed to compile fragment shader.\n");
1965 gl_draw_triangle(vs_id, fs_id);
1966 gl_get_backbuffer_color(&context, 0, 0, &colour);
1967 ok(colour.x == 3.0f, "Got colour %.8e.\n", colour.x);
1969 /* Specialization constant, new API. */
1971 parameter1.type = VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT;
1972 parameter1.u.specialization_constant.id = 1;
1974 ret = vkd3d_shader_compile(&info, &ps_spirv, &messages);
1975 ok(!ret, "Failed to compile, error %d.\n", ret);
1976 ok(!messages, "Got unexpected messages.\n");
1978 fs_id = glCreateShader(GL_FRAGMENT_SHADER);
1979 glShaderBinary(1, &fs_id, GL_SHADER_BINARY_FORMAT_SPIR_V, ps_spirv.code, ps_spirv.size);
1980 spec_id = 1;
1981 spec_value = 4;
1982 p_glSpecializeShader(fs_id, "main", 1, &spec_id, &spec_value);
1983 glGetShaderiv(fs_id, GL_COMPILE_STATUS, &status);
1984 ok(status, "Failed to compile fragment shader.\n");
1986 gl_draw_triangle(vs_id, fs_id);
1987 gl_get_backbuffer_color(&context, 0, 0, &colour);
1988 ok(colour.x == 4.0f, "Got colour %.8e.\n", colour.x);
1990 /* Uniform buffer, new API. */
1992 glGenBuffers(1, &ubo_id);
1993 glBindBufferBase(GL_UNIFORM_BUFFER, 2, ubo_id);
1994 glBufferData(GL_UNIFORM_BUFFER, 8, buffer_data, GL_STATIC_DRAW);
1996 parameter1.type = VKD3D_SHADER_PARAMETER_TYPE_BUFFER;
1997 parameter1.u.buffer.set = 0;
1998 parameter1.u.buffer.binding = 2;
1999 parameter1.u.buffer.offset = 4;
2001 ret = vkd3d_shader_compile(&info, &ps_spirv, &messages);
2002 ok(!ret, "Failed to compile, error %d.\n", ret);
2003 ok(!messages, "Got unexpected messages.\n");
2005 fs_id = glCreateShader(GL_FRAGMENT_SHADER);
2006 glShaderBinary(1, &fs_id, GL_SHADER_BINARY_FORMAT_SPIR_V, ps_spirv.code, ps_spirv.size);
2007 p_glSpecializeShader(fs_id, "main", 0, NULL, NULL);
2008 glGetShaderiv(fs_id, GL_COMPILE_STATUS, &status);
2009 ok(status, "Failed to compile fragment shader.\n");
2011 gl_draw_triangle(vs_id, fs_id);
2012 gl_get_backbuffer_color(&context, 0, 0, &colour);
2013 ok(colour.x == 5.0f, "Got colour %.8e.\n", colour.x);
2015 glDeleteBuffers(1, &ubo_id);
2016 destroy_gl_test_context(&context);
2017 #endif
2020 START_TEST(vkd3d_shader_api)
2022 setlocale(LC_ALL, "");
2024 run_test(test_invalid_shaders);
2025 run_test(test_vkd3d_shader_pfns);
2026 run_test(test_version);
2027 run_test(test_d3dbc);
2028 run_test(test_dxbc);
2029 run_test(test_scan_signatures);
2030 run_test(test_scan_descriptors);
2031 run_test(test_build_varying_map);
2032 run_test(test_scan_combined_resource_samplers);
2033 run_test(test_emit_signature);
2034 run_test(test_warning_options);
2035 run_test(test_parameters);